Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
ORNL Quantum Computing Institute
xacc
Commits
d02da5ca
Commit
d02da5ca
authored
Apr 07, 2019
by
Mccaskey, Alex
Browse files
adding persistable interface, making Function persistable, minor updates to observable
Signed-off-by:
Alex McCaskey
<
mccaskeyaj@ornl.gov
>
parent
5f39537c
Pipeline
#46610
failed with stages
in 6 minutes and 38 seconds
Changes
14
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
python/compiler/PyXACCVisitor.hpp
View file @
d02da5ca
...
...
@@ -31,7 +31,11 @@ public:
PyXACCVisitor
()
{
pyxaccStr
+=
"@qpu()
\n
def foo(buffer):
\n
"
;
}
void
visit
(
IRGenerator
&
irg
)
{
pyxaccStr
+=
" "
+
irg
.
name
()
+
"()
\n
"
;
pyxaccStr
+=
" "
+
irg
.
name
()
+
"(buffer"
;
for
(
auto
&
kv
:
irg
.
getOptions
())
{
pyxaccStr
+=
","
+
kv
.
first
+
"="
+
kv
.
second
.
toString
();
}
pyxaccStr
+=
")
\n
"
;
}
/**
* Visit hadamard gates
...
...
quantum/aqc/ir/DWFunction.hpp
View file @
d02da5ca
...
...
@@ -193,6 +193,13 @@ const int nRequiredBits() const override {
return
weights
;
}
void
persist
(
std
::
ostream
&
outStream
)
override
{
}
void
load
(
std
::
istream
&
inStream
)
override
{
}
InstructionParameter
getParameter
(
const
int
idx
)
const
override
{
return
parameters
[
idx
];
}
...
...
quantum/gate/ir/GateFunction.cpp
View file @
d02da5ca
...
...
@@ -3,6 +3,7 @@
#include <ctype.h>
#include <memory>
#include <string>
#include "Function.hpp"
#include "InstructionIterator.hpp"
#include "IRToGraphVisitor.hpp"
#include "IRGenerator.hpp"
...
...
@@ -10,6 +11,13 @@
#include "Graph.hpp"
#include "JsonVisitor.hpp"
#define RAPIDJSON_HAS_STDSTRING 1
#include "rapidjson/document.h"
#include "rapidjson/prettywriter.h"
using
namespace
rapidjson
;
namespace
xacc
{
namespace
quantum
{
...
...
@@ -19,16 +27,138 @@ void GateFunction::mapBits(std::vector<int> bitMap) {
}
}
void
GateFunction
::
persist
(
std
::
ostream
&
outStream
)
{
JsonVisitor
<
PrettyWriter
<
StringBuffer
>
,
StringBuffer
>
visitor
(
shared_from_this
());
outStream
<<
visitor
.
write
();
}
// {
// "kernels": [
// {
// "function": "foo",
// "instructions": [
// {
// "gate": "H",
// "enabled": true,
// "qubits": [
// 1
// ]
// },
// {
// "gate": "CNOT",
// "enabled": true,
// "qubits": [
// 0,
// 1
// ]
// }
// ]
// }
// ]
// }
void
GateFunction
::
load
(
std
::
istream
&
inStream
)
{
std
::
vector
<
std
::
string
>
irGeneratorNames
;
auto
irgens
=
xacc
::
getRegisteredIds
<
xacc
::
IRGenerator
>
();
for
(
auto
&
irg
:
irgens
)
{
irGeneratorNames
.
push_back
(
irg
);
}
auto
provider
=
xacc
::
getService
<
IRProvider
>
(
"gate"
);
std
::
string
json
(
std
::
istreambuf_iterator
<
char
>
(
inStream
),
{});
// std::cout << "JSON: " << json << "\n";
Document
doc
;
doc
.
Parse
(
json
);
auto
&
kernel
=
doc
[
"kernels"
].
GetArray
()[
0
];
functionName
=
kernel
[
"function"
].
GetString
();
auto
instructionsArray
=
kernel
[
"instructions"
].
GetArray
();
for
(
int
i
=
0
;
i
<
instructionsArray
.
Size
();
i
++
)
{
auto
&
inst
=
instructionsArray
[
i
];
auto
gname
=
inst
[
"gate"
].
GetString
();
bool
isAnIRG
=
false
;
if
(
std
::
find
(
irGeneratorNames
.
begin
(),
irGeneratorNames
.
end
(),
gname
)
!=
irGeneratorNames
.
end
())
{
// this is an IRG
isAnIRG
=
true
;
}
std
::
vector
<
int
>
qbits
;
auto
bitsArray
=
inst
[
"qubits"
].
GetArray
();
for
(
int
k
=
0
;
k
<
bitsArray
.
Size
();
k
++
)
{
qbits
.
push_back
(
bitsArray
[
k
].
GetInt
());
}
std
::
vector
<
InstructionParameter
>
local_parameters
;
auto
&
paramsArray
=
inst
[
"parameters"
];
for
(
int
k
=
0
;
k
<
paramsArray
.
Size
();
k
++
)
{
auto
&
value
=
paramsArray
[
k
];
if
(
value
.
IsInt
())
{
local_parameters
.
push_back
(
InstructionParameter
(
value
.
GetInt
()));
}
else
if
(
value
.
IsDouble
())
{
local_parameters
.
push_back
(
InstructionParameter
(
value
.
GetDouble
()));
}
else
{
local_parameters
.
push_back
(
InstructionParameter
(
value
.
GetString
()));
}
}
std
::
shared_ptr
<
Instruction
>
instToAdd
;
if
(
!
isAnIRG
)
{
instToAdd
=
provider
->
createInstruction
(
gname
,
qbits
,
local_parameters
);
}
else
{
instToAdd
=
xacc
::
getService
<
IRGenerator
>
(
gname
);
}
auto
&
optionsObj
=
inst
[
"options"
];
for
(
auto
itr
=
optionsObj
.
MemberBegin
();
itr
!=
optionsObj
.
MemberEnd
();
++
itr
)
{
auto
&
value
=
optionsObj
[
itr
->
name
.
GetString
()];
if
(
value
.
IsInt
())
{
instToAdd
->
setOption
(
itr
->
name
.
GetString
(),
InstructionParameter
(
value
.
GetInt
()));
}
else
if
(
value
.
IsDouble
())
{
instToAdd
->
setOption
(
itr
->
name
.
GetString
(),
InstructionParameter
(
value
.
GetDouble
()));
}
else
{
instToAdd
->
setOption
(
itr
->
name
.
GetString
(),
InstructionParameter
(
value
.
GetString
()));
}
}
if
(
!
inst
[
"enabled"
].
GetBool
())
{
instToAdd
->
disable
();
}
addInstruction
(
instToAdd
);
}
}
void
GateFunction
::
expandIRGenerators
(
std
::
map
<
std
::
string
,
InstructionParameter
>
irGenMap
)
{
std
::
list
<
InstPtr
>
newinsts
;
for
(
int
idx
=
0
;
idx
<
nInstructions
();
idx
++
)
{
auto
inst
=
getInstruction
(
idx
);
auto
irg
=
std
::
dynamic_pointer_cast
<
IRGenerator
>
(
inst
);
if
(
irg
)
{
auto
evaluated
=
irg
->
generate
(
irGenMap
);
replaceInstruction
(
idx
,
evaluated
);
// replaceInstruction(idx, evaluated);
for
(
auto
i
:
evaluated
->
getInstructions
())
{
newinsts
.
push_back
(
i
);
}
}
else
{
newinsts
.
push_back
(
inst
);
}
}
instructions
.
clear
();
for
(
auto
i
:
newinsts
)
{
addInstruction
(
i
);
}
}
bool
GateFunction
::
hasIRGenerators
()
{
...
...
@@ -36,7 +166,7 @@ bool GateFunction::hasIRGenerators() {
auto
inst
=
getInstruction
(
idx
);
auto
irg
=
std
::
dynamic_pointer_cast
<
IRGenerator
>
(
inst
);
if
(
irg
)
{
return
true
;
return
true
;
}
}
return
false
;
...
...
@@ -410,11 +540,11 @@ GateFunction::operator()(const std::vector<double> ¶ms) {
}
const
int
GateFunction
::
depth
()
{
return
toGraph
()
->
depth
()
-
2
;
}
const
std
::
string
GateFunction
::
persistGraph
()
{
std
::
stringstream
s
;
toGraph
()
->
write
(
s
);
return
s
.
str
();
}
const
std
::
string
GateFunction
::
persistGraph
()
{
std
::
stringstream
s
;
toGraph
()
->
write
(
s
);
return
s
.
str
();
}
std
::
shared_ptr
<
Graph
>
GateFunction
::
toGraph
()
{
...
...
quantum/gate/ir/GateFunction.hpp
View file @
d02da5ca
...
...
@@ -72,6 +72,9 @@ public:
return
0
;
}
void
persist
(
std
::
ostream
&
outStream
)
override
;
void
load
(
std
::
istream
&
inStream
)
override
;
InstPtr
getInstruction
(
const
int
idx
)
override
;
std
::
list
<
InstPtr
>
getInstructions
()
override
;
...
...
quantum/gate/ir/GateIR.cpp
View file @
d02da5ca
...
...
@@ -56,13 +56,6 @@ void GateIR::persist(std::ostream &outStream) {
JsonVisitor
<
PrettyWriter
<
StringBuffer
>
,
StringBuffer
>
visitor
(
kernels
);
outStream
<<
visitor
.
write
();
// StringBuffer sb;
// PrettyWriter<StringBuffer> writer(sb);
//
// serializeJson(writer);
//
// outStream << sb.GetString();
return
;
}
...
...
quantum/gate/ir/GateIR.hpp
View file @
d02da5ca
...
...
@@ -29,7 +29,7 @@ public:
*/
GateIR
()
{}
virtual
const
int
maxBit
()
{
const
int
maxBit
()
override
{
int
maxBit
=
0
;
for
(
auto
k
:
kernels
)
{
for
(
auto
inst
:
k
->
getInstructions
())
{
...
...
@@ -47,13 +47,13 @@ public:
* Add a quantum function to this intermediate representation.
* @param kernel
*/
virtual
void
addKernel
(
std
::
shared_ptr
<
Function
>
kernel
)
{
void
addKernel
(
std
::
shared_ptr
<
Function
>
kernel
)
override
{
kernels
.
push_back
(
kernel
);
}
virtual
const
int
numberOfKernels
()
{
return
kernels
.
size
();
}
virtual
std
::
shared_ptr
<
Function
>
getKernel
(
const
std
::
string
&
name
)
{
std
::
shared_ptr
<
Function
>
getKernel
(
const
std
::
string
&
name
)
override
{
std
::
shared_ptr
<
Function
>
ret
;
for
(
auto
f
:
kernels
)
{
if
(
f
->
name
()
==
name
)
{
...
...
@@ -66,13 +66,13 @@ public:
return
ret
;
}
virtual
bool
kernelExists
(
const
std
::
string
&
name
)
{
bool
kernelExists
(
const
std
::
string
&
name
)
override
{
return
std
::
any_of
(
kernels
.
cbegin
(),
kernels
.
cend
(),
[
=
](
std
::
shared_ptr
<
Function
>
i
)
{
return
i
->
name
()
==
name
;
});
}
virtual
void
mapBits
(
std
::
vector
<
int
>
bitMap
)
{
void
mapBits
(
std
::
vector
<
int
>
bitMap
)
override
{
for
(
auto
k
:
kernels
)
{
k
->
mapBits
(
bitMap
);
}
...
...
@@ -83,8 +83,8 @@ public:
* intermediate representation
* @return
*/
virtual
std
::
string
toAssemblyString
(
const
std
::
string
&
kernelName
,
const
std
::
string
&
accBufferVarName
);
std
::
string
toAssemblyString
(
const
std
::
string
&
kernelName
,
const
std
::
string
&
accBufferVarName
)
override
;
/**
* Persist this IR instance to the given
...
...
@@ -92,7 +92,7 @@ public:
*
* @param outStream
*/
virtual
void
persist
(
std
::
ostream
&
outStream
);
void
persist
(
std
::
ostream
&
outStream
)
override
;
/**
* Create this IR instance from the given input
...
...
@@ -100,9 +100,9 @@ public:
*
* @param inStream
*/
virtual
void
load
(
std
::
istream
&
inStream
);
void
load
(
std
::
istream
&
inStream
)
override
;
virtual
std
::
vector
<
std
::
shared_ptr
<
Function
>>
getKernels
()
{
std
::
vector
<
std
::
shared_ptr
<
Function
>>
getKernels
()
override
{
return
kernels
;
}
...
...
quantum/gate/ir/tests/GateFunctionTester.cpp
View file @
d02da5ca
...
...
@@ -222,6 +222,35 @@ TEST(GateFunctionTester, checkParameterInsertion) {
"Rx(0.5 * psi) qreg3
\n
Rx(1 * phi) qreg4
\n
Ry(1 * theta) qreg2
\n
"
);
}
TEST
(
GateFunctionTester
,
checkPersistLoad
)
{
auto
f
=
std
::
make_shared
<
GateFunction
>
(
"foo"
);
auto
h
=
std
::
make_shared
<
Hadamard
>
(
1
);
auto
cn1
=
std
::
make_shared
<
CNOT
>
(
0
,
1
);
auto
rz
=
std
::
make_shared
<
Rz
>
(
0
,
3.1415
);
auto
rz2
=
std
::
make_shared
<
Rz
>
(
std
::
vector
<
int
>
{
1
});
xacc
::
InstructionParameter
p
(
"phi"
);
rz2
->
setParameter
(
0
,
p
);
h
->
setOption
(
"key1"
,
3.3
);
f
->
addInstruction
(
h
);
f
->
addInstruction
(
cn1
);
f
->
addInstruction
(
rz
);
f
->
addInstruction
(
rz2
);
std
::
stringstream
ss
;
f
->
persist
(
ss
);
std
::
cout
<<
ss
.
str
()
<<
"
\n
"
;
std
::
istringstream
iss
(
ss
.
str
());
auto
newF
=
std
::
make_shared
<
GateFunction
>
(
"new"
);
newF
->
load
(
iss
);
std
::
cout
<<
"HELLO: "
<<
newF
->
toString
()
<<
"
\n
"
;
}
TEST
(
GateFunctionTester
,
checkGenerateGraph
)
{
auto
f
=
std
::
make_shared
<
GateFunction
>
(
"foo"
);
...
...
quantum/gate/observable/PauliOperator.hpp
View file @
d02da5ca
...
...
@@ -295,6 +295,7 @@ public:
eval
(
const
std
::
map
<
std
::
string
,
std
::
complex
<
double
>>
varToValMap
);
bool
isClose
(
PauliOperator
&
other
);
int
nQubits
();
const
int
nBits
()
override
{
return
nQubits
();}
PauliOperator
&
operator
+=
(
const
PauliOperator
&
v
)
noexcept
;
PauliOperator
&
operator
-=
(
const
PauliOperator
&
v
)
noexcept
;
...
...
quantum/gate/utils/JsonVisitor.cpp
View file @
d02da5ca
...
...
@@ -27,97 +27,243 @@ using Writer = PrettyWriter<StringBuffer>;
/**
* FIXME write this
*/
template
<
class
W
,
class
B
>
JsonVisitor
<
W
,
B
>::
JsonVisitor
(
std
::
shared_ptr
<
xacc
::
Function
>
f
)
:
buffer
(
std
::
make_shared
<
B
>
()),
writer
(
std
::
make_shared
<
W
>
(
*
buffer
.
get
())),
functions
{
f
}
{}
template
<
class
W
,
class
B
>
JsonVisitor
<
W
,
B
>::
JsonVisitor
(
std
::
vector
<
std
::
shared_ptr
<
xacc
::
Function
>>
fs
)
:
buffer
(
std
::
make_shared
<
B
>
()),
writer
(
std
::
make_shared
<
W
>
(
*
buffer
.
get
())),
functions
(
fs
)
{}
template
<
class
W
,
class
B
>
std
::
string
JsonVisitor
<
W
,
B
>::
write
()
{
template
<
class
W
,
class
B
>
JsonVisitor
<
W
,
B
>::
JsonVisitor
(
std
::
shared_ptr
<
xacc
::
Function
>
f
)
:
buffer
(
std
::
make_shared
<
B
>
()),
writer
(
std
::
make_shared
<
W
>
(
*
buffer
.
get
())),
functions
{
f
}
{}
template
<
class
W
,
class
B
>
JsonVisitor
<
W
,
B
>::
JsonVisitor
(
std
::
vector
<
std
::
shared_ptr
<
xacc
::
Function
>>
fs
)
:
buffer
(
std
::
make_shared
<
B
>
()),
writer
(
std
::
make_shared
<
W
>
(
*
buffer
.
get
())),
functions
(
fs
)
{}
template
<
class
W
,
class
B
>
std
::
string
JsonVisitor
<
W
,
B
>::
write
()
{
writer
->
StartObject
();
writer
->
String
(
"kernels"
);
writer
->
StartArray
();
for
(
auto
f
:
functions
)
{
// This is a Function, start it as an Object
writer
->
StartObject
();
writer
->
String
(
"kernels"
);
writer
->
StartArray
();
for
(
auto
f
:
functions
)
{
// This is a Function, start it as an Object
writer
->
StartObject
();
writer
->
String
(
"function"
);
writer
->
String
(
f
->
name
());
// All functions have instructions, start
// that array here.
writer
->
String
(
"instructions"
);
writer
->
StartArray
();
writer
->
String
(
"function"
);
writer
->
String
(
f
->
name
());
topLevelInstructionIterator
=
std
::
make_shared
<
xacc
::
InstructionIterator
>
(
f
);
while
(
topLevelInstructionIterator
->
hasNext
())
{
// Get the next node in the tree
auto
nextInst
=
topLevelInstructionIterator
->
next
();
nextInst
->
accept
(
this
);
}
// End Instructions
writer
->
EndArray
();
// All functions have instructions, start
// that array here.
writer
->
String
(
"instructions"
);
writer
->
StartArray
();
// End Function
writer
->
EndObject
();
topLevelInstructionIterator
=
std
::
make_shared
<
xacc
::
InstructionIterator
>
(
f
);
while
(
topLevelInstructionIterator
->
hasNext
())
{
// Get the next node in the tree
auto
nextInst
=
topLevelInstructionIterator
->
next
();
nextInst
->
accept
(
this
);
}
// End Instructions
writer
->
EndArray
();
writer
->
EndObject
();
return
buffer
->
GetString
();
}
template
<
class
W
,
class
B
>
void
JsonVisitor
<
W
,
B
>::
visit
(
Rz
&
rz
)
{
baseGateInst
(
dynamic_cast
<
GateInstruction
&>
(
rz
),
false
);
writer
->
String
(
"angle"
);
auto
p
=
rz
.
getParameter
(
0
);
switch
(
p
.
which
())
{
case
0
:
writer
->
Int
(
p
.
as
<
int
>
());
break
;
case
1
:
writer
->
Double
(
p
.
as
<
double
>
());
break
;
case
2
:
writer
->
String
(
p
.
as
<
std
::
string
>
());
break
;
default:
xacc
::
error
(
"Invalid InstructionParameter: "
+
p
.
toString
());
}
// End Function
writer
->
EndObject
();
}
template
<
class
W
,
class
B
>
void
JsonVisitor
<
W
,
B
>::
visit
(
Rx
&
rx
)
{
baseGateInst
(
dynamic_cast
<
GateInstruction
&>
(
rx
),
false
);
writer
->
String
(
"angle"
);
auto
p
=
rx
.
getParameter
(
0
);
switch
(
p
.
which
())
{
case
0
:
writer
->
Int
(
p
.
as
<
int
>
());
break
;
case
1
:
writer
->
Double
(
p
.
as
<
double
>
());
break
;
case
2
:
writer
->
String
(
p
.
as
<
std
::
string
>
());
break
;
default:
xacc
::
error
(
"Invalid InstructionParameter: "
+
p
.
toString
());
}
writer
->
EndObject
();
writer
->
EndArray
();
writer
->
EndObject
();
return
buffer
->
GetString
();
}
template
<
class
W
,
class
B
>
void
JsonVisitor
<
W
,
B
>::
visit
(
Rz
&
rz
)
{
baseGateInst
(
dynamic_cast
<
GateInstruction
&>
(
rz
));
// writer->String("angle");
// auto p = rz.getParameter(0);
// switch (p.which()) {
// case 0:
// writer->Int(p.as<int>());
// break;
// case 1:
// writer->Double(p.as<double>());
// break;
// case 2:
// writer->String(p.as<std::string>());
// break;
// default:
// xacc::error("Invalid InstructionParameter: " + p.toString());
// }
// writer->EndObject();
}
template
<
class
W
,
class
B
>
void
JsonVisitor
<
W
,
B
>::
visit
(
Rx
&
rx
)
{
baseGateInst
(
dynamic_cast
<
GateInstruction
&>
(
rx
));
// writer->String("angle");
// auto p = rx.getParameter(0);
// switch (p.which()) {
// case 0:
// writer->Int(p.as<int>());
// break;
// case 1:
// writer->Double(p.as<double>());
// break;
// case 2:
// writer->String(p.as<std::string>());
// break;
// default:
// xacc::error("Invalid InstructionParameter: " + p.toString());
// }
// writer->EndObject();
}
template
<
class
W
,
class
B
>
void
JsonVisitor
<
W
,
B
>::
visit
(
Ry
&
ry
)
{
baseGateInst
(
dynamic_cast
<
GateInstruction
&>
(
ry
));
// writer->String("angle");
// auto p = ry.getParameter(0);
// switch (p.which()) {
// case 0:
// writer->Int(p.as<int>());
// break;
// case 1:
// writer->Double(p.as<double>());
// break;
// case 2:
// writer->String(p.as<std::string>());
// break;
// default:
// xacc::error("Invalid InstructionParameter: " + p.toString());
// }
// writer->EndObject();
}
template
<
class
W
,
class
B
>
void
JsonVisitor
<
W
,
B
>::
visit
(
CPhase
&
cp
)
{
baseGateInst
(
dynamic_cast
<
GateInstruction
&>
(
cp
));
// writer->String("angle");
// auto p = cp.getParameter(0);
// switch (p.which()) {
// case 0:
// writer->Int(p.as<int>());
// break;
// case 1:
// writer->Double(p.as<double>());
// break;
// case 2:
// writer->String(p.as<std::string>());
// break;
// default:
// xacc::error("Invalid InstructionParameter: " + p.toString());
// }
// writer->EndObject();
}
template
<
class
W
,
class
B
>
void
JsonVisitor
<
W
,
B
>::
visit
(
ConditionalFunction
&
cn
)
{
writer
->
StartObject
();
writer
->
String
(
"conditional_function"
);
writer
->
String
(
cn
.
name
());
writer
->
String
(
"conditional_qubit"
);
writer
->
Int
(
cn
.
getConditionalQubit
());
writer
->
String
(
"instructions"
);
writer
->
StartArray
();
auto
cnAsPtr
=
std
::
make_shared
<
ConditionalFunction
>
(
cn
);
int
nInsts
=
cnAsPtr
->
nInstructions
();
xacc
::
InstructionIterator
it
(
cnAsPtr
);
it
.
next
();
while
(
it
.
hasNext
())
{
// Get the next node in the tree
auto
nextInst
=
it
.
next
();
nextInst
->
accept
(
this
);
}
template
<
class
W
,
class
B
>
void
JsonVisitor
<
W
,
B
>::
visit
(
Ry
&
ry
)
{
baseGateInst
(
dynamic_cast
<
GateInstruction
&>
(
ry
),
false
);
writer
->
String
(
"angle"
);
auto
p
=
ry
.
getParameter
(
0
);
// End Instructions
writer
->
EndArray
();
writer
->
EndObject
();
// Move the Top Level Iterator past these instructions that were in
// the conditional function
for
(
int
i
=
0
;
i
<
nInsts
;
i
++
)
topLevelInstructionIterator
->
next
();
}
template
<
class
W
,
class
B
>
void
JsonVisitor
<
W
,
B
>::
visit
(
Measure
&
cn
)
{
baseGateInst
(
dynamic_cast
<
GateInstruction
&>
(
cn
));
// writer->String("classicalBitIdx");
// writer->Int(cn.getClassicalBitIndex());
// writer->EndObject();
}