Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
ORNL Quantum Computing Institute
xacc
Commits
1f97ecdb
Commit
1f97ecdb
authored
Aug 24, 2017
by
Mccaskey, Alex
Browse files
Added ir transformation to handle ibm cnot connectivity
parent
ce69d956
Changes
8
Hide whitespace changes
Inline
Side-by-side
impls/ibm/IBMAccelerator.cpp
View file @
1f97ecdb
...
...
@@ -40,6 +40,7 @@
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
#include "IBMAccelerator.hpp"
#include "IBMIRTransformation.hpp"
using
namespace
utility
;
using
namespace
web
;
...
...
@@ -96,6 +97,30 @@ bool IBMAccelerator::isValidBufferSize(const int NBits) {
return
NBits
>
0
&&
NBits
<
31
;
}
std
::
vector
<
std
::
shared_ptr
<
IRTransformation
>>
IBMAccelerator
::
getIRTransformations
()
{
std
::
vector
<
std
::
shared_ptr
<
IRTransformation
>>
transformations
;
std
::
string
backendName
=
"ibmqx_qasm_simulator"
;
if
(
xacc
::
optionExists
(
"ibm-backend"
))
{
backendName
=
xacc
::
getOption
(
"ibm-backend"
);
}
if
(
!
availableBackends
.
count
(
backendName
))
{
XACCError
(
backendName
+
" is not available."
);
}
auto
backend
=
availableBackends
[
backendName
];
if
(
!
backend
.
couplers
.
empty
())
{
auto
transform
=
std
::
make_shared
<
IBMIRTransformation
>
(
backend
.
couplers
);
transformations
.
push_back
(
transform
);
}
return
transformations
;
}
void
IBMAccelerator
::
initialize
()
{
std
::
string
jsonStr
=
""
,
apiKey
=
""
;
auto
options
=
RuntimeOptions
::
instance
();
...
...
@@ -143,7 +168,7 @@ void IBMAccelerator::initialize() {
if
(
!
isSimulator
)
{
auto
couplers
=
b
[
"couplingMap"
].
GetArray
();
for
(
int
j
=
0
;
j
<
couplers
.
Size
();
j
++
)
{
backend
.
edge
s
.
push_back
(
backend
.
coupler
s
.
push_back
(
std
::
make_pair
(
couplers
[
j
][
0
].
GetInt
(),
couplers
[
j
][
1
].
GetInt
()));
}
...
...
@@ -286,7 +311,6 @@ void IBMAccelerator::execute(std::shared_ptr<AcceleratorBuffer> buffer,
}
std
::
shared_ptr
<
AcceleratorGraph
>
IBMAccelerator
::
getAcceleratorConnectivity
()
{
auto
options
=
RuntimeOptions
::
instance
();
std
::
string
backendName
=
"ibmqx_qasm_simulator"
;
if
(
xacc
::
optionExists
(
"ibm-backend"
))
{
...
...
@@ -300,8 +324,8 @@ std::shared_ptr<AcceleratorGraph> IBMAccelerator::getAcceleratorConnectivity() {
auto
backend
=
availableBackends
[
backendName
];
auto
graph
=
std
::
make_shared
<
AcceleratorGraph
>
(
backend
.
nQubits
);
if
(
!
backend
.
edge
s
.
empty
())
{
for
(
auto
es
:
backend
.
edge
s
)
{
if
(
!
backend
.
coupler
s
.
empty
())
{
for
(
auto
es
:
backend
.
coupler
s
)
{
graph
->
addEdge
(
es
.
first
,
es
.
second
);
}
}
else
{
...
...
impls/ibm/IBMAccelerator.hpp
View file @
1f97ecdb
...
...
@@ -53,7 +53,7 @@ struct IBMBackend {
std
::
string
name
;
std
::
string
description
;
int
nQubits
;
std
::
vector
<
std
::
pair
<
int
,
int
>>
edge
s
;
std
::
vector
<
std
::
pair
<
int
,
int
>>
coupler
s
;
};
/**
...
...
@@ -117,10 +117,7 @@ public:
* so return an empty list, for now.
* @return
*/
virtual
std
::
vector
<
std
::
shared_ptr
<
IRTransformation
>>
getIRTransformations
()
{
std
::
vector
<
std
::
shared_ptr
<
IRTransformation
>>
v
;
return
v
;
}
virtual
std
::
vector
<
std
::
shared_ptr
<
IRTransformation
>>
getIRTransformations
();
/**
* Return all relevant IBMAccelerator runtime options.
...
...
impls/ibm/IBMIRTransformation.cpp
0 → 100644
View file @
1f97ecdb
#include "IBMIRTransformation.hpp"
namespace
xacc
{
namespace
quantum
{
std
::
shared_ptr
<
IR
>
IBMIRTransformation
::
transform
(
std
::
shared_ptr
<
IR
>
ir
)
{
XACCInfo
(
"Executing IBM IR Transformation - Modifying CNOT connectivity."
);
auto
newir
=
std
::
make_shared
<
GateQIR
>
();
for
(
auto
kernel
:
ir
->
getKernels
())
{
currentKernelInstructionIdx
=
0
;
InstructionIterator
it
(
kernel
);
while
(
it
.
hasNext
())
{
// Get the next node in the tree
auto
nextInst
=
it
.
next
();
if
(
!
nextInst
->
isComposite
()
&&
nextInst
->
isEnabled
())
{
nextInst
->
accept
(
this
);
if
(
!
nextInst
->
isEnabled
()
&&
"CNOT"
==
nextInst
->
getName
())
{
kernel
->
removeInstruction
(
currentKernelInstructionIdx
);
int
count
=
0
;
for
(
auto
inst
:
newInstructions
)
{
kernel
->
insertInstruction
(
currentKernelInstructionIdx
+
count
,
inst
);
count
++
;
}
currentKernelInstructionIdx
+=
count
-
1
;
}
newInstructions
.
clear
();
currentKernelInstructionIdx
++
;
}
}
newir
->
addKernel
(
kernel
);
}
return
newir
;
}
void
IBMIRTransformation
::
visit
(
CNOT
&
cnot
)
{
auto
source
=
cnot
.
bits
()[
0
];
auto
target
=
cnot
.
bits
()[
1
];
if
(
!
isCouplingAvailable
(
source
,
target
))
{
auto
gateRegistry
=
GateInstructionRegistry
::
instance
();
// Disable this cnot
cnot
.
disable
();
// Here I know that this cnot is at
// the currentKernelInstructionIdx, so I want
// to insert 2 Hadamards, a reversed cnot, then 2 hadamards
auto
h0
=
gateRegistry
->
create
(
"H"
,
std
::
vector
<
int
>
{
source
});
auto
h1
=
gateRegistry
->
create
(
"H"
,
std
::
vector
<
int
>
{
target
});
auto
revCnot
=
gateRegistry
->
create
(
"CNOT"
,
std
::
vector
<
int
>
{
target
,
source
});
newInstructions
.
push_back
(
h0
);
newInstructions
.
push_back
(
h1
);
newInstructions
.
push_back
(
revCnot
);
newInstructions
.
push_back
(
h0
);
newInstructions
.
push_back
(
h1
);
}
}
bool
IBMIRTransformation
::
isCouplingAvailable
(
const
int
src
,
const
int
tgt
)
{
return
tgt
==
_couplers
[
src
].
first
||
tgt
==
_couplers
[
src
].
second
;
}
}
}
quantum/gate/ir/transformations/SwapInsertion
IRTransformation.hpp
→
impls/ibm/IBM
IRTransformation.hpp
View file @
1f97ecdb
#ifndef QUANTUM_GATE_
IR_TRANSFORMATIONS_SWAPINSERTIONIRTRANSFORMATION
_HPP_
#define QUANTUM_GATE_
IR_TRANSFORMATIONS_SWAPINSERTIONIRTRANSFORMATION
_HPP_
#ifndef QUANTUM_GATE_
ACCELERATORS_IBMIRTransformation
_HPP_
#define QUANTUM_GATE_
ACCELERATORS_IBMIRTransformation
_HPP_
#include "Accelerator.hpp"
#include "IRTransformation.hpp"
#include "GateQIR.hpp"
#include "CNOT.hpp"
namespace
xacc
{
namespace
quantum
{
class
SwapInsertionIRTransformation
:
public
IRTransformation
{
class
IBMIRTransformation
:
public
IRTransformation
,
public
BaseInstructionVisitor
,
public
InstructionVisitor
<
CNOT
>
{
protected:
std
::
shared_ptr
<
AcceleratorGraph
>
graph
;
std
::
vector
<
std
::
pair
<
int
,
int
>>
_couplers
;
int
currentKernelInstructionIdx
;
std
::
vector
<
std
::
shared_ptr
<
Instruction
>>
newInstructions
;
bool
isCouplingAvailable
(
const
int
src
,
const
int
tgt
);
public:
SwapInsertionIRTransformation
(
std
::
shared_ptr
<
AcceleratorGraph
>
g
)
:
graph
(
g
)
{}
IBMIRTransformation
(
std
::
vector
<
std
::
pair
<
int
,
int
>>
couplers
)
:
_couplers
(
couplers
),
currentKernelInstructionIdx
(
0
)
{
}
virtual
std
::
shared_ptr
<
IR
>
transform
(
std
::
shared_ptr
<
IR
>
ir
);
void
visit
(
CNOT
&
cnot
);
virtual
const
std
::
string
name
()
const
{
return
"
swap-inser
tion"
;
return
"
ibm-ir-transforma
tion
s
"
;
}
virtual
const
std
::
string
description
()
const
{
...
...
impls/ibm/tests/IBMIRTransformationTester.cpp
0 → 100644
View file @
1f97ecdb
/***********************************************************************************
* Copyright (c) 2016, UT-Battelle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the xacc nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Contributors:
* Initial API and implementation - Alex McCaskey
*
**********************************************************************************/
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE SwapInsertionIRTransformationTester
#include <boost/test/included/unit_test.hpp>
#include "IBMIRTransformation.hpp"
using
namespace
xacc
;
using
namespace
xacc
::
quantum
;
BOOST_AUTO_TEST_CASE
(
checkCreation
)
{
std
::
vector
<
std
::
pair
<
int
,
int
>>
couplers
{{
0
,
1
},{
0
,
2
},{
1
,
2
},{
2
,
3
},{
2
,
4
},{
3
,
4
}};
IBMIRTransformation
t
(
couplers
);
auto
f
=
std
::
make_shared
<
GateFunction
>
(
"foo"
);
auto
x
=
std
::
make_shared
<
X
>
(
0
);
auto
h
=
std
::
make_shared
<
Hadamard
>
(
1
);
auto
cn0
=
std
::
make_shared
<
CNOT
>
(
1
,
2
);
auto
cn1
=
std
::
make_shared
<
CNOT
>
(
2
,
3
);
auto
h2
=
std
::
make_shared
<
Hadamard
>
(
0
);
auto
m0
=
std
::
make_shared
<
Measure
>
(
0
,
0
);
auto
m1
=
std
::
make_shared
<
Measure
>
(
1
,
1
);
auto
m2
=
std
::
make_shared
<
Measure
>
(
2
,
2
);
auto
cn2
=
std
::
make_shared
<
CNOT
>
(
2
,
0
);
f
->
addInstruction
(
x
);
f
->
addInstruction
(
h
);
f
->
addInstruction
(
cn0
);
f
->
addInstruction
(
cn1
);
f
->
addInstruction
(
h2
);
f
->
addInstruction
(
cn2
);
f
->
addInstruction
(
m0
);
f
->
addInstruction
(
m1
);
f
->
addInstruction
(
m2
);
auto
ir
=
std
::
make_shared
<
GateQIR
>
();
ir
->
addKernel
(
f
);
auto
newir
=
t
.
transform
(
ir
);
std
::
stringstream
ss
;
newir
->
persist
(
ss
);
const
std
::
string
expected
=
R"expected({
"kernels": [
{
"function": "foo",
"instructions": [
{
"gate": "X",
"enabled": true,
"qubits": [
0
]
},
{
"gate": "H",
"enabled": true,
"qubits": [
1
]
},
{
"gate": "CNOT",
"enabled": true,
"qubits": [
1,
2
]
},
{
"gate": "H",
"enabled": true,
"qubits": [
2
]
},
{
"gate": "H",
"enabled": true,
"qubits": [
3
]
},
{
"gate": "CNOT",
"enabled": true,
"qubits": [
3,
2
]
},
{
"gate": "H",
"enabled": true,
"qubits": [
2
]
},
{
"gate": "H",
"enabled": true,
"qubits": [
3
]
},
{
"gate": "H",
"enabled": true,
"qubits": [
0
]
},
{
"gate": "H",
"enabled": true,
"qubits": [
2
]
},
{
"gate": "H",
"enabled": true,
"qubits": [
0
]
},
{
"gate": "CNOT",
"enabled": true,
"qubits": [
0,
2
]
},
{
"gate": "H",
"enabled": true,
"qubits": [
2
]
},
{
"gate": "H",
"enabled": true,
"qubits": [
0
]
},
{
"gate": "Measure",
"enabled": true,
"qubits": [
0
],
"classicalBitIdx": 0
},
{
"gate": "Measure",
"enabled": true,
"qubits": [
1
],
"classicalBitIdx": 1
},
{
"gate": "Measure",
"enabled": true,
"qubits": [
2
],
"classicalBitIdx": 2
}
]
}
]
})expected"
;
BOOST_VERIFY
(
expected
==
ss
.
str
());
}
impls/simple-simulator/SimpleAcceleratorVisitor.hpp
View file @
1f97ecdb
...
...
@@ -325,8 +325,8 @@ public:
std
::
stringstream
ss
;
ss
<<
rZGate
.
getParameter
(
0
);
double
angle
=
std
::
stod
(
ss
.
str
());
//boost::get<double>(rZGate.getParameter(0));
auto
matElement11
=
std
::
exp
(
-
1.0
*
i
*
angle
);
auto
matElement12
=
std
::
exp
(
i
*
angle
);
auto
matElement11
=
std
::
exp
(
-
0.5
*
i
*
angle
);
auto
matElement12
=
std
::
exp
(
0.5
*
i
*
angle
);
Eigen
::
MatrixXcd
rz
(
2
,
2
);
rz
<<
matElement11
,
0.0
,
0.0
,
matElement12
;
...
...
quantum/gate/ir/GateFunction.hpp
View file @
1f97ecdb
...
...
@@ -78,6 +78,10 @@ public:
functionName
(
name
),
parameters
(
params
)
{
}
GateFunction
(
const
GateFunction
&
other
)
:
functionName
(
other
.
functionName
),
parameters
(
other
.
parameters
)
{
}
virtual
const
int
nInstructions
()
{
return
instructions
.
size
();
}
...
...
quantum/gate/ir/transformations/SwapInsertionIRTransformation.cpp
deleted
100644 → 0
View file @
ce69d956
#include "SwapInsertionIRTransformation.hpp"
namespace
xacc
{
namespace
quantum
{
std
::
shared_ptr
<
IR
>
SwapInsertionIRTransformation
::
transform
(
std
::
shared_ptr
<
IR
>
ir
)
{
auto
newir
=
std
::
make_shared
<
GateQIR
>
();
for
(
auto
kernel
:
ir
->
getKernels
())
{
for
(
auto
inst
:
kernel
->
getInstructions
())
{
auto
qbits
=
inst
->
bits
();
// If we have 2 qubit gate that does not have a corresponding
// connection in the hardware, then we need to add swaps
if
(
qbits
.
size
()
==
2
&&
!
graph
->
edgeExists
(
qbits
[
0
],
qbits
[
1
]))
{
std
::
vector
<
int
>
paths
;
std
::
vector
<
double
>
distances
;
graph
->
computeShortestPath
(
qbits
[
0
],
distances
,
paths
);
}
}
}
}
}
}
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