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
8584913b
Commit
8584913b
authored
Jan 24, 2017
by
Mccaskey, Alex
Browse files
Fixed the way levels were set on quantum circuit graph, added persist method to IR
parent
0f06731a
Changes
6
Hide whitespace changes
Inline
Side-by-side
quantum/gate/scaffold/tests/ScaffoldCompilerTester.cpp
View file @
8584913b
...
...
@@ -59,11 +59,11 @@ BOOST_AUTO_TEST_CASE(checkSimpleCompile) {
BOOST_VERIFY
(
graphir
);
// The above code should produce a graph
// with
3
nodes (initial qubits state, Hadamard, and CNot),
// with
4
nodes (initial qubits state, Hadamard, and CNot
, sink final state
),
// with 3 edges (q0 lifeline to H, q0 lifeline from H to CNot,
// and q1 lifeline to CNot)
BOOST_VERIFY
(
graphir
->
order
()
==
3
);
BOOST_VERIFY
(
graphir
->
size
()
==
3
);
BOOST_VERIFY
(
graphir
->
order
()
==
4
);
BOOST_VERIFY
(
graphir
->
size
()
==
5
);
}
...
...
@@ -73,26 +73,21 @@ BOOST_AUTO_TEST_CASE(checkAnotherSimpleCompile) {
auto
compiler
=
qci
::
common
::
AbstractFactory
::
createAndCast
<
xacc
::
ICompiler
>
(
"compiler"
,
"scaffold"
);
BOOST_VERIFY
(
compiler
);
const
std
::
string
src
(
"__qpu__ t
hreeBitQFT
() {
\n
"
const
std
::
string
src
(
"__qpu__ t
eleport
() {
\n
"
" qbit q[3];
\n
"
" H(q[0]);
\n
"
" T(q[0]);
\n
"
" Rz(q[1],3.1415 / 4.0);
\n
"
" CNOT(q[1], q[0]);
\n
"
" Rz(q[1], -1.0 * 3.1415 / 4.0);
\n
"
" CNOT(q[1], q[0]);
\n
"
" Rz(q[0], 3.1415 / 8.0);
\n
"
" Rz(q[2], 3.1415 / 8.0);
\n
"
" CNOT(q[2], q[0]);
\n
"
" Rz(q[2], -1.0 * 3.1415 / 4.0);
\n
"
" CNOT(q[2], q[0]);
\n
"
" cbit c[2];
\n
"
" H(q[1]);
\n
"
" T(q[1]);
\n
"
" Rz(q[2],3.1415 / 4.0);
\n
"
" CNOT(q[2], q[1]);
\n
"
" Rz(q[2], -1.0 * 3.1415 / 4.0);
\n
"
" CNOT(q[1],q[2]);
\n
"
" CNOT(q[0],q[1]);
\n
"
" H(q[0]);
\n
"
" MeasZ(q[0]);
\n
"
" MeasZ(q[1]);
\n
"
" // Cz
\n
"
" H(q[2]);
\n
"
" CNOT(q[2], q[1]);
\n
"
" H(q[2]);
\n
"
" // CX = CNOT
\n
"
" CNOT(q[2], q[0]);
\n
"
"}
\n
"
);
auto
ir
=
compiler
->
compile
(
src
);
...
...
@@ -100,6 +95,8 @@ BOOST_AUTO_TEST_CASE(checkAnotherSimpleCompile) {
auto
graphir
=
std
::
dynamic_pointer_cast
<
xacc
::
GraphIR
<
GraphType
>>
(
ir
);
BOOST_VERIFY
(
graphir
);
// Scaffold decomposes Rz into H and T gates.
BOOST_VERIFY
(
graphir
->
order
()
>
1400
);
// I drew this out on paper, we should have 12
// nodes and 17 edges...
BOOST_VERIFY
(
graphir
->
order
()
==
12
);
BOOST_VERIFY
(
graphir
->
size
()
==
17
);
}
quantum/gate/utils/QasmToGraph.hpp
View file @
8584913b
...
...
@@ -42,32 +42,59 @@ namespace quantum {
using
boost
::
assign
::
map_list_of
;
/**
* Enumeration of gates we support
*/
enum
SupportedGates
{
H
,
CNot
,
C_Z
,
C_X
,
Measure
,
X
,
Y
,
Z
,
T
,
S
,
ZZ
,
SS
,
Swap
,
Toffoli
,
InitialState
H
,
CNot
,
C_Z
,
C_X
,
Measure
,
X
,
Y
,
Z
,
T
,
S
,
ZZ
,
SS
,
Swap
,
Toffoli
,
InitialState
,
FinalState
};
/**
* Create a string to SupportedGates mapping
*/
const
boost
::
unordered_map
<
std
::
string
,
SupportedGates
>
strToGate
=
map_list_of
(
"h"
,
H
)(
"cnot"
,
CNot
)(
"c_z"
,
C_Z
)(
"c_x"
,
C_X
)(
"measure"
,
Measure
)(
"x"
,
X
)(
"y"
,
Y
)(
"z"
,
Z
)(
"t"
,
T
)(
"s"
,
S
)(
"zz"
,
ZZ
)(
"ss"
,
SS
)(
"swap"
,
Swap
)(
"toffoli"
,
Toffoli
);
/**
* Create a SupportedGates to string mapping
*/
const
boost
::
unordered_map
<
SupportedGates
,
std
::
string
>
gateToStr
=
map_list_of
(
H
,
"h"
)(
CNot
,
"cnot"
)(
C_Z
,
"c_z"
)(
C_X
,
"c_x"
)(
Measure
,
"measure"
)(
X
,
"x"
)(
Y
,
"y"
)(
Z
,
"z"
)(
T
,
"t"
)(
S
,
"s"
)(
ZZ
,
"zz"
)(
SS
,
"ss"
)(
Swap
,
"swap"
)(
Toffoli
,
"toffoli"
);
/**
* Params - gate name, layer (ie time sequence), vertex id,
* qubit ids that gate acts on
* CircuitNode subclasses QCIVertex to provide the following
* parameters in the given order:
*
* Parameters: Gate, Layer (ie time sequence), Gate Vertex Id,
* Qubit Ids that the gate acts on
*/
class
CircuitNode
:
public
qci
::
common
::
QCIVertex
<
SupportedGates
,
int
,
int
,
std
::
vector
<
int
>>
{};
class
CircuitNode
:
public
qci
::
common
::
QCIVertex
<
SupportedGates
,
int
,
int
,
std
::
vector
<
int
>>
{
};
/**
* The QasmToGraph class provides a static
* utility method that maps a flat qasm string
* to a QCI Common Graph data structure.
*/
class
QasmToGraph
{
public:
/**
* Create a Graph data structure that models a quantum
* circuit from the provided qasm string.
*
* @param flatQasmStr The qasm to be converted to a Graph.
* @return graph Graph modeling a quantum circuit.
*/
static
qci
::
common
::
Graph
<
CircuitNode
>
getCircuitGraph
(
const
std
::
string
&
flatQasmStr
)
{
// Local Declarations
using
namespace
qci
::
common
;
Graph
<
CircuitNode
>
graph
;
std
::
map
<
std
::
string
,
int
>
qubitVarNameToId
;
...
...
@@ -76,7 +103,7 @@ public:
std
::
regex
newLineDelim
(
"
\n
"
),
spaceDelim
(
" "
);
std
::
regex
qubitDeclarations
(
"
\\
s*qubit
\\
s*
\\
w+"
);
std
::
sregex_token_iterator
first
{
flatQasmStr
.
begin
(),
flatQasmStr
.
end
(),
newLineDelim
,
-
1
},
last
;
int
nQubits
=
0
,
qbitId
=
0
,
layer
=
1
,
gateId
=
1
;
int
nQubits
=
0
,
qbitId
=
0
,
layer
=
0
,
gateId
=
1
;
qasmLines
=
{
first
,
last
};
// Let's now loop over the qubit declarations,
...
...
@@ -93,12 +120,11 @@ public:
qbitId
++
;
}
// Set the number of qubits
nQubits
=
qubitVarNameToId
.
size
();
std
::
cout
<<
"Number of Qubits is "
<<
nQubits
<<
std
::
endl
;
// Fill the Graph...
// First create a starting node for the initial
// wave function - it should have nQubits outgoing
// edges
...
...
@@ -107,31 +133,39 @@ public:
std
::
vector
<
CircuitNode
>
gateOperations
;
for
(
auto
line
:
qasmLines
)
{
// If this is a gate line...
if
(
!
boost
::
contains
(
line
,
"qubit"
))
{
std
::
sregex_token_iterator
first
{
line
.
begin
(),
line
.
end
(),
spaceDelim
,
-
1
},
last
;
std
::
vector
<
std
::
string
>
gateCommand
=
{
first
,
last
};
// If we have a > 2 qubit gate, make a new layer
if
(
boost
::
contains
(
gateCommand
[
1
],
","
))
{
layer
++
;
}
if
(
!
boost
::
contains
(
line
,
"qubit"
)
&&
!
boost
::
contains
(
line
,
"cbit"
))
{
// Create a new CircuitNode
CircuitNode
node
;
// Split the current qasm command at the spaces
std
::
sregex_token_iterator
first
{
line
.
begin
(),
line
.
end
(),
spaceDelim
,
-
1
},
last
;
std
::
vector
<
std
::
string
>
gateCommand
=
{
first
,
last
};
// Set the gate as a lowercase gate name string
auto
g
=
boost
::
to_lower_copy
(
gateCommand
[
0
]);
boost
::
trim
(
g
);
if
(
g
==
"measz"
)
g
=
"measure"
;
auto
s
=
strToGate
.
at
(
g
);
std
::
get
<
0
>
(
node
.
properties
)
=
s
;
// If not a 2 qubit gate, and if the acting
// qubit is different than the last one, then
// keep the layer the same, otherwise increment
if
(
incrementLayer
(
gateCommand
,
qubitVarNameToId
,
gateOperations
,
layer
))
{
layer
++
;
}
// Set the current layer
std
::
get
<
1
>
(
node
.
properties
)
=
layer
;
// Set the gate vertex id
std
::
get
<
2
>
(
node
.
properties
)
=
gateId
;
gateId
++
;
// Set the qubits this gate acts on
std
::
vector
<
int
>
actingQubits
;
if
(
!
boost
::
contains
(
gateCommand
[
1
],
","
))
{
actingQubits
.
push_back
(
qubitVarNameToId
[
gateCommand
[
1
]]);
...
...
@@ -146,11 +180,16 @@ public:
// Set the acting qubits
std
::
get
<
3
>
(
node
.
properties
)
=
actingQubits
;
// Add this gate to the local vector
// and to the graph
gateOperations
.
push_back
(
node
);
graph
.
addVertex
(
node
);
}
}
// Add a final layer for the graph sink
graph
.
addVertex
(
SupportedGates
::
FinalState
,
layer
+
1
,
gateId
,
allQbitIds
);
// Set how many layers are in this circuit
int
maxLayer
=
layer
;
...
...
@@ -163,11 +202,7 @@ public:
std
::
cout
<<
"
\t
Acting Qubits: "
;
std
::
vector
<
int
>
qubits
=
std
::
get
<
3
>
(
cn
.
properties
);
for
(
auto
v
:
qubits
)
{
if
(
!
(
v
==
*
qubits
.
end
()))
{
std
::
cout
<<
v
<<
", "
;
}
else
{
std
::
cout
<<
v
;
}
std
::
cout
<<
v
<<
", "
;
}
std
::
cout
<<
"
\n\n
"
;
}
...
...
@@ -178,19 +213,8 @@ public:
for
(
int
i
=
0
;
i
<
nQubits
;
i
++
)
{
qubitToCurrentGateId
[
i
]
=
0
;
}
// std::vector<CircuitNode> layerOneGates;
// std::copy_if(gateOperations.begin(), gateOperations.end(),
// std::back_inserter(layerOneGates),
// [](const CircuitNode& c) {return std::get<1>(c.properties) == 1;});
// for (auto i : layerOneGates) {
// std::vector<int> actingQubits = std::get<3>(i.properties);
// for (auto qubit : actingQubits) {
// graph.addEdge(0, std::get<2>(i.properties));
// qubitToCurrentGateId[qubit] = std::get<2>(i.properties);
// }
// }
int
currentLayer
=
1
;
int
currentLayer
=
0
;
while
(
currentLayer
<=
maxLayer
)
{
std
::
vector
<
CircuitNode
>
currentLayerGates
;
std
::
copy_if
(
gateOperations
.
begin
(),
gateOperations
.
end
(),
...
...
@@ -209,13 +233,78 @@ public:
currentLayer
++
;
}
// Add a graph sink - ie a final node representing
// the final system state
int
counter
=
0
;
// Walk the list downward, skip first node since is
// the graph sink
for
(
int
i
=
gateOperations
.
size
()
-
1
;
i
>=
0
;
i
--
)
{
auto
gate
=
gateOperations
[
i
];
int
currentGateId
=
std
::
get
<
2
>
(
gate
.
properties
);
int
nQubitsActing
=
std
::
get
<
3
>
(
gate
.
properties
).
size
();
int
gateDegree
=
graph
.
degree
(
currentGateId
);
for
(
int
j
=
gateDegree
;
j
<
2
*
nQubitsActing
;
j
++
)
{
graph
.
addEdge
(
gateId
,
gateId
);
counter
++
;
}
// Then we can go through and assign edges
// to all vertices
// Break early if we can...
if
(
counter
==
nQubits
)
break
;
}
return
graph
;
}
private:
/**
* This method determines if a new layer should be added to the circuit.
*
* @param gateCommand
* @param qubitVarNameToId
* @param gates
* @param currentLayer
* @return
*/
static
bool
incrementLayer
(
const
std
::
vector
<
std
::
string
>&
gateCommand
,
std
::
map
<
std
::
string
,
int
>&
qubitVarNameToId
,
const
std
::
vector
<
CircuitNode
>&
gates
,
const
int
&
currentLayer
)
{
bool
oneQubitGate
=
!
boost
::
contains
(
gateCommand
[
1
],
","
),
noGateAtQOnL
=
true
;
auto
g
=
boost
::
to_lower_copy
(
gateCommand
[
0
]);
boost
::
trim
(
g
);
if
(
g
==
"measz"
)
g
=
"measure"
;
std
::
vector
<
CircuitNode
>
thisLayerGates
;
std
::
copy_if
(
gates
.
begin
(),
gates
.
end
(),
std
::
back_inserter
(
thisLayerGates
),
[
&
](
const
CircuitNode
&
c
)
{
return
std
::
get
<
1
>
(
c
.
properties
)
==
currentLayer
;});
for
(
auto
layerGate
:
thisLayerGates
)
{
std
::
vector
<
int
>
qubits
=
std
::
get
<
3
>
(
layerGate
.
properties
);
for
(
auto
q
:
qubits
)
{
if
(
qubitVarNameToId
[
gateCommand
[
1
]]
==
q
)
{
noGateAtQOnL
=
false
;
}
}
}
if
(
!
oneQubitGate
)
{
return
true
;
}
else
if
(
!
noGateAtQOnL
)
{
return
true
;
}
else
if
(
!
gates
.
empty
()
&&
(
gateToStr
.
at
(
std
::
get
<
0
>
(
gates
[
gates
.
size
()
-
1
].
properties
))
==
"measure"
)
&&
g
!=
"measure"
)
{
return
true
;
}
return
false
;
}
};
}
}
...
...
xacc/compiler/GraphIR.hpp
View file @
8584913b
...
...
@@ -31,7 +31,7 @@
#ifndef QUANTUM_GRAPHIR_HPP_
#define QUANTUM_GRAPHIR_HPP_
#include "
Compiler
.hpp"
#include "
IR
.hpp"
#include "Graph.hpp"
namespace
xacc
{
...
...
@@ -61,6 +61,10 @@ public:
return
""
;
}
virtual
void
persist
(
std
::
ostream
&
outStream
)
{
}
};
}
...
...
xacc/compiler/IR.hpp
View file @
8584913b
...
...
@@ -32,6 +32,7 @@
#define XACC_COMPILER_IR_HPP_
#include "AbstractFactory.hpp"
#include <ostream>
namespace
xacc
{
...
...
@@ -41,6 +42,7 @@ namespace xacc {
class
IR
{
public:
virtual
std
::
string
toString
()
=
0
;
virtual
void
persist
(
std
::
ostream
&
outStream
)
=
0
;
virtual
~
IR
()
{}
};
...
...
xacc/tests/CompilerTester.cpp
View file @
8584913b
...
...
@@ -41,6 +41,7 @@ public:
FakeIR
()
{
}
virtual
std
::
string
toString
()
{
return
std
::
string
();}
virtual
void
persist
(
std
::
ostream
&
stream
)
{}
};
class
FakeCompiler
:
public
Compiler
<
FakeCompiler
>
{
friend
Compiler
<
FakeCompiler
>
;
...
...
xacc/tests/ProgramTester.cpp
View file @
8584913b
...
...
@@ -53,7 +53,9 @@ public:
FakeIR
()
{
}
virtual
std
::
string
toString
()
{
return
std
::
string
();}
virtual
void
persist
(
std
::
ostream
&
stream
)
{}
};
class
DummyCompiler
:
public
Compiler
<
DummyCompiler
>
{
public:
virtual
std
::
shared_ptr
<
IR
>
compile
()
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment