mirror of https://github.com/Qiskit/qiskit.git
many corrections to compile circuits.
add new test example test16_obj.py. update teleport_obj and rippleadd_obj examples. major changes to _circuit and _mapping. add print statement to compile_circuits() in _quantumprogram. minor bug in _qasmparser.py.
This commit is contained in:
parent
7a3ff0765f
commit
8d1ae2a497
|
@ -15,7 +15,9 @@ import os
|
|||
sys.path.append(os.path.join(os.path.dirname(__file__), '../..'))
|
||||
from qiskit import QuantumProgram
|
||||
|
||||
n = 4
|
||||
import Qconfig
|
||||
|
||||
n = 3
|
||||
|
||||
QPS_SPECS = {
|
||||
"name": "Program",
|
||||
|
@ -46,28 +48,6 @@ cout = QP_program.quantum_registers("cout")
|
|||
ans = QP_program.classical_registers("ans")
|
||||
|
||||
|
||||
def print_2x8(layout):
|
||||
"""Print a 2x8 layout."""
|
||||
rev_layout = {b: a for a, b in layout.items()}
|
||||
print("")
|
||||
for i in range(8):
|
||||
qubit = ("q", i)
|
||||
if qubit in rev_layout:
|
||||
print("%s[%d] " % (rev_layout[qubit][0], rev_layout[qubit][1]),
|
||||
end="")
|
||||
else:
|
||||
print("XXXX ", end="")
|
||||
print("")
|
||||
for i in range(8, 16):
|
||||
qubit = ("q", i)
|
||||
if qubit in rev_layout:
|
||||
print("%s[%d] " % (rev_layout[qubit][0], rev_layout[qubit][1]),
|
||||
end="")
|
||||
else:
|
||||
print("XXXX ", end="")
|
||||
print("")
|
||||
|
||||
|
||||
def majority(p, a, b, c):
|
||||
"""Majority gate."""
|
||||
p.cx(c, b)
|
||||
|
@ -101,121 +81,24 @@ for j in range(n):
|
|||
qc.measure(b[j], ans[j]) # Measure the output register
|
||||
qc.measure(cout[0], ans[n])
|
||||
|
||||
######################################################################
|
||||
# Work in progress to map the QuantumCircuit to the 2x8 device
|
||||
######################################################################
|
||||
|
||||
print("QuantumCircuit OPENQASM")
|
||||
print("-----------------------")
|
||||
print(qc.qasm())
|
||||
|
||||
######################################################################
|
||||
# First pass: expand subroutines to a basis of 1 and 2 qubit gates.
|
||||
######################################################################
|
||||
|
||||
source, C = QP_program.unroller_code(qc)
|
||||
|
||||
print("Unrolled OPENQASM to [u1, u2, u3, cx] basis")
|
||||
print("-------------------------------------------")
|
||||
print(C.qasm(qeflag=True))
|
||||
|
||||
print("")
|
||||
print("size = %d" % C.size())
|
||||
print("depth = %d" % C.depth())
|
||||
print("width = %d" % C.width())
|
||||
print("bits = %d" % C.num_cbits())
|
||||
print("factors = %d" % C.num_tensor_factors())
|
||||
|
||||
######################################################################
|
||||
# Second pass: choose a layout on the coupling graph and add SWAPs.
|
||||
######################################################################
|
||||
|
||||
# This is the 2 by 8 array of 16 qubits
|
||||
couplingdict = {0: [1, 8], 1: [2, 9], 2: [3, 10], 3: [4, 11], 4: [5, 12],
|
||||
# 2x8 array
|
||||
coupling_map = {0: [1, 8], 1: [2, 9], 2: [3, 10], 3: [4, 11], 4: [5, 12],
|
||||
5: [6, 13], 6: [7, 14], 7: [15], 8: [9], 9: [10], 10: [11],
|
||||
11: [12], 12: [13], 13: [14], 14: [15]}
|
||||
|
||||
result = QP_program.set_api(Qconfig.APItoken, Qconfig.config["url"])
|
||||
if not result:
|
||||
print("Error setting API")
|
||||
sys.exit(1)
|
||||
|
||||
# QP_program.compile(couplingdict)
|
||||
# First version: not compiled
|
||||
result = QP_program.execute(device='simulator', coupling_map=None, shots=1024)
|
||||
# print(result["compiled_circuits"][0]["qasm"])
|
||||
print(result["compiled_circuits"][0]["result"]["data"]["counts"])
|
||||
|
||||
coupling = QP_program.mapper.Coupling(couplingdict)
|
||||
C_mapped, layout = QP_program.mapper.swap_mapper(C, coupling)
|
||||
# Second version: compiled to 2x8 array coupling graph
|
||||
result = QP_program.execute(device='simulator', coupling_map=coupling_map, shots=1024)
|
||||
# print(result["compiled_circuits"][0]["qasm"])
|
||||
print(result["compiled_circuits"][0]["result"]["data"]["counts"])
|
||||
|
||||
print("")
|
||||
print("Initial qubit positions on 2x8 layout")
|
||||
print("-------------------------------------------")
|
||||
print_2x8(layout)
|
||||
|
||||
print("")
|
||||
print("Inserted SWAP gates for 2x8 layout")
|
||||
print("-------------------------------------------")
|
||||
print(C_mapped.qasm(qeflag=True))
|
||||
|
||||
print("")
|
||||
print("size = %d" % C_mapped.size())
|
||||
print("depth = %d" % C_mapped.depth())
|
||||
print("width = %d" % C_mapped.width())
|
||||
print("bits = %d" % C_mapped.num_cbits())
|
||||
print("factors = %d" % C_mapped.num_tensor_factors())
|
||||
|
||||
######################################################################
|
||||
# Third pass: expand SWAP subroutines and adjust cx gate orientations.
|
||||
######################################################################
|
||||
|
||||
|
||||
source, C_mapped_unrolled = QP_program.unroller_code(C_mapped)
|
||||
|
||||
C_directions = QP_program.mapper.direction_mapper(C_mapped_unrolled, coupling)
|
||||
|
||||
print("")
|
||||
print("Changed CNOT directions")
|
||||
print("-------------------------------------------")
|
||||
print(C_directions.qasm(qeflag=True))
|
||||
|
||||
print("")
|
||||
print("size = %d" % C_directions.size())
|
||||
print("depth = %d" % C_directions.depth())
|
||||
print("width = %d" % C_directions.width())
|
||||
print("bits = %d" % C_directions.num_cbits())
|
||||
print("factors = %d" % C_directions.num_tensor_factors())
|
||||
|
||||
######################################################################
|
||||
# Fourth pass: collect runs of cx gates and cancel them.
|
||||
######################################################################
|
||||
# We assume there are no double edges in the connectivity graph, so
|
||||
# we don't need to check the direction of the cx gates in a run.
|
||||
runs = C_directions.collect_runs(["cx"])
|
||||
for r in runs:
|
||||
if len(r) % 2 == 0:
|
||||
for n in r:
|
||||
C_directions._remove_op_node(n)
|
||||
else:
|
||||
for j in range(len(r) - 1):
|
||||
C_directions._remove_op_node(r[j])
|
||||
|
||||
print("")
|
||||
print("Cancelled redundant CNOT gates")
|
||||
print("-------------------------------------------")
|
||||
print(C_directions.qasm(qeflag=True))
|
||||
|
||||
print("")
|
||||
print("size = %d" % C_directions.size())
|
||||
print("depth = %d" % C_directions.depth())
|
||||
print("width = %d" % C_directions.width())
|
||||
print("bits = %d" % C_directions.num_cbits())
|
||||
print("factors = %d" % C_directions.num_tensor_factors())
|
||||
|
||||
######################################################################
|
||||
# Fifth pass: expand single qubit gates to u1, u2, u3 and simplify.
|
||||
######################################################################
|
||||
|
||||
source, C_directions_unrolled = QP_program.unroller_code(C_directions)
|
||||
|
||||
runs = C_directions_unrolled.collect_runs(["u1", "u2", "u3"])
|
||||
print(runs)
|
||||
|
||||
# TODO: complete this pass
|
||||
# TODO: add Circuit method to tally each type of gate so we can see costs
|
||||
# TODO: test on examples using simulator
|
||||
|
||||
# TODO: simple unit tests for qasm, mapper, unroller, circuit
|
||||
# Both versions should give the same distribution
|
||||
|
|
|
@ -15,6 +15,8 @@ import os
|
|||
sys.path.append(os.path.join(os.path.dirname(__file__), '../..'))
|
||||
from qiskit import QuantumProgram
|
||||
|
||||
import Qconfig
|
||||
|
||||
QPS_SPECS = {
|
||||
"name": "Program",
|
||||
"circuits": [{
|
||||
|
@ -54,56 +56,28 @@ qc.z(q[2]).c_if(c0, 1)
|
|||
qc.x(q[2]).c_if(c1, 1)
|
||||
qc.measure(q[2], c2[0])
|
||||
|
||||
######################################################################
|
||||
# qx5qv2 coupling
|
||||
coupling_map = {0: [1, 2],
|
||||
1: [2],
|
||||
2: [],
|
||||
3: [2, 4],
|
||||
4: [2]}
|
||||
|
||||
print("QuantumCircuit OPENQASM")
|
||||
print("-----------------------")
|
||||
print(qc.qasm())
|
||||
# Experiment does not support feedback, so we use the simulator
|
||||
|
||||
QASM, C = QP_program.unroller_code(qc)
|
||||
result = QP_program.set_api(Qconfig.APItoken, Qconfig.config["url"])
|
||||
if not result:
|
||||
print("Error setting API")
|
||||
sys.exit(1)
|
||||
|
||||
print("")
|
||||
print("size = %d" % C.size())
|
||||
print("depth = %d" % C.depth())
|
||||
print("width = %d" % C.width())
|
||||
print("bits = %d" % C.num_cbits())
|
||||
print("factors = %d" % C.num_tensor_factors())
|
||||
# First version: not compiled
|
||||
result = QP_program.execute(device='simulator', coupling_map=None, shots=1024)
|
||||
# print(result["compiled_circuits"][0]["qasm"])
|
||||
print(result["compiled_circuits"][0]["result"]["data"]["counts"])
|
||||
|
||||
print("")
|
||||
print("Unrolled OPENQASM")
|
||||
print("-----------------------")
|
||||
print(QASM)
|
||||
# Second version: compiled to 2x8 array coupling graph
|
||||
result = QP_program.execute(device='simulator', coupling_map=coupling_map, shots=1024)
|
||||
# print(result["compiled_circuits"][0]["qasm"])
|
||||
print(result["compiled_circuits"][0]["result"]["data"]["counts"])
|
||||
|
||||
# This is the 2 by 8
|
||||
couplingdict = {0: [1, 8], 1: [2, 9], 2: [3, 10], 3: [4, 11], 4: [5, 12],
|
||||
5: [6, 13], 6: [7, 14], 7: [15], 8: [9], 9: [10], 10: [11],
|
||||
11: [12], 12: [13], 13: [14], 14: [15]}
|
||||
|
||||
coupling = QP_program.mapper.Coupling(couplingdict)
|
||||
print("")
|
||||
print("2x8 coupling graph = \n%s" % coupling)
|
||||
|
||||
C_mapped, layout = QP_program.mapper.swap_mapper(C, coupling)
|
||||
rev_layout = {b: a for a, b in layout.items()}
|
||||
|
||||
print("")
|
||||
print("2x8 layout:")
|
||||
for i in range(8):
|
||||
qubit = ("q", i)
|
||||
if qubit in rev_layout:
|
||||
print("%s[%d] " % (rev_layout[qubit][0], rev_layout[qubit][1]), end="")
|
||||
else:
|
||||
print("XXXX ", end="")
|
||||
print("")
|
||||
for i in range(8, 16):
|
||||
qubit = ("q", i)
|
||||
if qubit in rev_layout:
|
||||
print("%s[%d] " % (rev_layout[qubit][0], rev_layout[qubit][1]), end="")
|
||||
else:
|
||||
print("XXXX ", end="")
|
||||
print("")
|
||||
|
||||
print("")
|
||||
print("Mapped OPENQASM")
|
||||
print("-----------------------")
|
||||
print(C_mapped.qasm(qeflag=True))
|
||||
# Both versions should give the same distribution
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
"""
|
||||
Ripple adder example based on OPENQASM example.
|
||||
|
||||
Author: Andrew Cross
|
||||
Jesus Perez <jesusper@us.ibm.com>
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
# We don't know from where the user is running the example,
|
||||
# so we need a relative position from this file path.
|
||||
# TODO: Relative imports for intra-package imports are highly discouraged.
|
||||
# http://stackoverflow.com/a/7506006
|
||||
sys.path.append(os.path.join(os.path.dirname(__file__), '../..'))
|
||||
from qiskit import QuantumProgram
|
||||
|
||||
import Qconfig
|
||||
|
||||
|
||||
def swap(qc, q0, q1):
|
||||
"""Swap gate."""
|
||||
qc.cx(q0, q1)
|
||||
qc.cx(q1, q0)
|
||||
qc.cx(q0, q1)
|
||||
|
||||
n = 3
|
||||
|
||||
QPS_SPECS = {
|
||||
"name": "Program",
|
||||
"circuits": [{
|
||||
"name": "test16",
|
||||
"quantum_registers": [
|
||||
{"name": "q",
|
||||
"size": n},
|
||||
{"name": "r",
|
||||
"size": n}
|
||||
],
|
||||
"classical_registers": [
|
||||
{"name": "ans",
|
||||
"size": 2*n},
|
||||
]}]
|
||||
}
|
||||
|
||||
QP_program = QuantumProgram(specs=QPS_SPECS)
|
||||
qc = QP_program.circuit("test16")
|
||||
q = QP_program.quantum_registers("q")
|
||||
r = QP_program.quantum_registers("r")
|
||||
ans = QP_program.classical_registers("ans")
|
||||
|
||||
qc.x(q[0]) # Set input q = 1...0000
|
||||
|
||||
swap(qc, q[0], q[n-1])
|
||||
swap(qc, q[n-1], r[n-1])
|
||||
|
||||
for j in range(n):
|
||||
qc.measure(q[j], ans[j])
|
||||
qc.measure(r[j], ans[j+n])
|
||||
|
||||
# 2x8 array
|
||||
coupling_map = {0: [1, 8], 1: [2, 9], 2: [3, 10], 3: [4, 11], 4: [5, 12],
|
||||
5: [6, 13], 6: [7, 14], 7: [15], 8: [9], 9: [10], 10: [11],
|
||||
11: [12], 12: [13], 13: [14], 14: [15]}
|
||||
|
||||
result = QP_program.set_api(Qconfig.APItoken, Qconfig.config["url"])
|
||||
if not result:
|
||||
print("Error setting API")
|
||||
sys.exit(1)
|
||||
|
||||
# First version: not compiled
|
||||
result = QP_program.execute(device='simulator', coupling_map=None, shots=1024)
|
||||
# print(result["compiled_circuits"][0]["qasm"])
|
||||
print(result["compiled_circuits"][0]["result"]["data"]["counts"])
|
||||
|
||||
# Second version: compiled to 2x8 array coupling graph
|
||||
result = QP_program.execute(device='simulator', coupling_map=coupling_map, shots=1024)
|
||||
# print(result["compiled_circuits"][0]["qasm"])
|
||||
print(result["compiled_circuits"][0]["result"]["data"]["counts"])
|
||||
|
||||
# Both versions should give the same distribution
|
|
@ -236,10 +236,13 @@ class QuantumProgram(object):
|
|||
for circuit in circuits:
|
||||
qasm_source, circuit_unrolled = self.unroller_code(circuit)
|
||||
if coupling_map:
|
||||
print("pre-mapping properties: %s"
|
||||
% circuit_unrolled.property_summary())
|
||||
# Insert swap gates
|
||||
coupling = self.mapper.Coupling(coupling_map)
|
||||
circuit_unrolled, final_layout = self.mapper.swap_mapper(
|
||||
circuit_unrolled, coupling)
|
||||
print("layout: %s" % final_layout)
|
||||
# Expand swaps
|
||||
qasm_source, circuit_unrolled = self.unroller_code(
|
||||
circuit_unrolled)
|
||||
|
@ -251,6 +254,8 @@ class QuantumProgram(object):
|
|||
# Simplify single qubit gates
|
||||
circuit_unrolled = mapper.optimize_1q_gates(circuit_unrolled)
|
||||
qasm_source = circuit_unrolled.qasm(qeflag=True)
|
||||
print("post-mapping properties: %s"
|
||||
% circuit_unrolled.property_summary())
|
||||
qasm_circuits.append({'qasm': qasm_source})
|
||||
unrolled_circuits.append({'circuit_unrolled': circuit_unrolled})
|
||||
return qasm_circuits, unrolled_circuits
|
||||
|
|
|
@ -1251,3 +1251,13 @@ class Circuit:
|
|||
else:
|
||||
op_dict[name] += 1
|
||||
return op_dict
|
||||
|
||||
def property_summary(self):
|
||||
"""Return a dictionary of circuit properties."""
|
||||
summary = {"size": self.size(),
|
||||
"depth": self.depth(),
|
||||
"width": self.width(),
|
||||
"bits": self.num_cbits(),
|
||||
"factors": self.num_tensor_factors(),
|
||||
"operations": self.count_ops()}
|
||||
return summary
|
||||
|
|
|
@ -12,6 +12,14 @@ from qiskit import QISKitException
|
|||
from qiskit.qasm import Qasm
|
||||
import qiskit.unroll as unroll
|
||||
|
||||
# Notes:
|
||||
# Measurements may occur and be followed by swaps that result in repeated
|
||||
# measurement of the same qubit. Near-term experiments cannot implement
|
||||
# these circuits, so we may need to modify the algorithm.
|
||||
# It can happen that a swap in a deeper layer can be removed by permuting
|
||||
# qubits in the layout. We don't do this.
|
||||
# It can happen that initial swaps can be removed or partly simplified
|
||||
# because the initial state is zero. We don't do this.
|
||||
|
||||
def layer_permutation(layer_partition, layout, qubit_subset, coupling, trials):
|
||||
"""Find a swap circuit that implements a permutation for this layer.
|
||||
|
@ -19,7 +27,7 @@ def layer_permutation(layer_partition, layout, qubit_subset, coupling, trials):
|
|||
The goal is to swap qubits such that qubits in the same two qubit gates
|
||||
are adjacent.
|
||||
|
||||
Based on Sergey Bravyi's MATLAB code.
|
||||
Based on Sergey Bravyi's algorithm.
|
||||
|
||||
The layer_partition is a list of (qu)bit lists and each qubit is a
|
||||
tuple (qreg, index).
|
||||
|
@ -30,12 +38,13 @@ def layer_permutation(layer_partition, layout, qubit_subset, coupling, trials):
|
|||
The coupling is a CouplingGraph.
|
||||
TRIALS is the number of attempts the randomized algorithm makes.
|
||||
|
||||
Returns: success_flag, best_circ, best_d, best_layout
|
||||
Returns: success_flag, best_circ, best_d, best_layout, trivial_flag
|
||||
|
||||
If success_flag is True, then best_circ contains an OPENQASM string with
|
||||
the swap circuit, best_d contains the depth of the swap circuit, and
|
||||
best_layout contains the new positions of the data qubits after the
|
||||
swap circuit has been applied.
|
||||
swap circuit has been applied. The trivial_flag is set if the layer
|
||||
has no multi-qubit gates.
|
||||
"""
|
||||
rev_layout = {b: a for a, b in layout.items()}
|
||||
gates = []
|
||||
|
@ -45,6 +54,12 @@ def layer_permutation(layer_partition, layout, qubit_subset, coupling, trials):
|
|||
elif len(layer) == 2:
|
||||
gates.append(tuple(layer))
|
||||
|
||||
# Can we already apply the gates?
|
||||
dist = sum([coupling.distance(layout[g[0]],
|
||||
layout[g[1]]) for g in gates])
|
||||
if dist == len(gates):
|
||||
return True, "", 0, layout, len(gates) == 0
|
||||
|
||||
# Begin loop over trials of randomized algorithm
|
||||
n = coupling.size()
|
||||
best_d = sys.maxsize # initialize best depth
|
||||
|
@ -54,7 +69,7 @@ def layer_permutation(layer_partition, layout, qubit_subset, coupling, trials):
|
|||
|
||||
trial_layout = copy.deepcopy(layout)
|
||||
rev_trial_layout = copy.deepcopy(rev_layout)
|
||||
trial_circ = ""
|
||||
trial_circ = "" # circuit produced in this trial
|
||||
|
||||
# Compute Sergey's randomized distance
|
||||
xi = {}
|
||||
|
@ -67,8 +82,9 @@ def layer_permutation(layer_partition, layout, qubit_subset, coupling, trials):
|
|||
xi[j][i] = xi[i][j]
|
||||
|
||||
# Loop over depths d up to a max depth of 2n+1
|
||||
for d in range(1, 2 * n + 1):
|
||||
circ = ""
|
||||
d = 1
|
||||
circ = "" # circuit for this swap slice
|
||||
while d < 2*n+1:
|
||||
# Set of available qubits
|
||||
qubit_set = set(qubit_subset)
|
||||
# While there are still qubits available
|
||||
|
@ -120,9 +136,12 @@ def layer_permutation(layer_partition, layout, qubit_subset, coupling, trials):
|
|||
# If all gates can be applied now, we are finished
|
||||
# Otherwise we need to consider a deeper swap circuit
|
||||
if dist == len(gates):
|
||||
trial_circ = circ
|
||||
trial_circ += circ
|
||||
break
|
||||
|
||||
# Increment the depth
|
||||
d += 1
|
||||
|
||||
# Either we have succeeded at some depth d < dmax or failed
|
||||
dist = sum([coupling.distance(trial_layout[g[0]],
|
||||
trial_layout[g[1]]) for g in gates])
|
||||
|
@ -133,9 +152,9 @@ def layer_permutation(layer_partition, layout, qubit_subset, coupling, trials):
|
|||
best_d = min(best_d, d)
|
||||
|
||||
if best_circ is None:
|
||||
return False, None, None, None
|
||||
return False, None, None, None, False
|
||||
else:
|
||||
return True, best_circ, best_d, best_layout
|
||||
return True, best_circ, best_d, best_layout, False
|
||||
|
||||
|
||||
def direction_mapper(circuit_graph, coupling_graph, verbose=False):
|
||||
|
@ -193,7 +212,7 @@ def direction_mapper(circuit_graph, coupling_graph, verbose=False):
|
|||
|
||||
def swap_mapper(circuit_graph, coupling_graph,
|
||||
initial_layout=None,
|
||||
basis="cx,u1,u2,u3", verbose=False):
|
||||
basis="cx,u1,u2,u3,id", verbose=False):
|
||||
"""Map a Circuit onto a CouplingGraph using swap gates.
|
||||
|
||||
circuit_graph = input Circuit
|
||||
|
@ -232,7 +251,7 @@ def swap_mapper(circuit_graph, coupling_graph,
|
|||
"in input Circuit" % (k[0], k[1]))
|
||||
if v not in coup_qubits:
|
||||
raise QISKitException("initial_layout qubit %s[%d] not " +
|
||||
" in input CouplingGraph" % (k[0], k[1]))
|
||||
" in input CouplingGraph" % (v[0], v[1]))
|
||||
else:
|
||||
# Supply a default layout
|
||||
qubit_subset = coupling_graph.get_qubits()
|
||||
|
@ -243,20 +262,27 @@ def swap_mapper(circuit_graph, coupling_graph,
|
|||
# Find swap circuit to preceed to each layer of input circuit
|
||||
layout = copy.deepcopy(initial_layout)
|
||||
openqasm_output = ""
|
||||
first_layer = True
|
||||
first_layer = True # True until first layer is output
|
||||
first_swapping_layer = True # True until first swap layer is output
|
||||
# Iterate over layers
|
||||
for i in range(len(layerlist)):
|
||||
success_flag, best_circ, best_d, best_layout \
|
||||
# Attempt to find a permutation for this layer
|
||||
success_flag, best_circ, best_d, best_layout, trivial_flag \
|
||||
= layer_permutation(layerlist[i]["partition"], layout,
|
||||
qubit_subset, coupling_graph, 20)
|
||||
# If this fails, try one gate at a time in this layer
|
||||
if not success_flag:
|
||||
if verbose:
|
||||
print("swap_mapper: failed, layer %d, " % i,
|
||||
" contention? retrying sequentially")
|
||||
" retrying sequentially")
|
||||
serial_layerlist = layerlist[i]["graph"].serial_layers()
|
||||
# Go through each gate in the layer
|
||||
for j in range(len(serial_layerlist)):
|
||||
success_flag, best_circ, best_d, best_layout \
|
||||
success_flag, best_circ, best_d, best_layout, trivial_flag \
|
||||
= layer_permutation(serial_layerlist[j]["partition"],
|
||||
layout, qubit_subset, coupling_graph, 20)
|
||||
layout, qubit_subset, coupling_graph,
|
||||
20)
|
||||
# Give up if we fail again
|
||||
if not success_flag:
|
||||
raise QISKitException("swap_mapper failed: " +
|
||||
"layer %d, sublayer %d" % (i, j) +
|
||||
|
@ -265,42 +291,77 @@ def swap_mapper(circuit_graph, coupling_graph,
|
|||
no_decls=True,
|
||||
aliases=layout))
|
||||
else:
|
||||
# Update the qubit positions each iteration
|
||||
layout = best_layout
|
||||
if first_layer:
|
||||
initial_layout = layout
|
||||
openqasm_output += circuit_graph.qasm(add_swap=True,
|
||||
decls_only=True,
|
||||
aliases=layout)
|
||||
openqasm_output += serial_layerlist[j]["graph"].qasm(
|
||||
no_decls=True,
|
||||
aliases=layout)
|
||||
first_layer = False
|
||||
if best_d == 0:
|
||||
# Output qasm without swaps
|
||||
if first_layer:
|
||||
openqasm_output += circuit_graph.qasm(
|
||||
add_swap=True,
|
||||
decls_only=True,
|
||||
aliases=layout)
|
||||
first_layer = False
|
||||
if not trivial_flag and first_swapping_layer:
|
||||
initial_layout = layout
|
||||
first_swapping_layer = False
|
||||
else:
|
||||
if verbose:
|
||||
print("swap_mapper: layer %d (%d), depth %d"
|
||||
% (i, j, best_d))
|
||||
if best_circ != "":
|
||||
openqasm_output += best_circ
|
||||
# Output qasm with swaps
|
||||
if first_layer:
|
||||
openqasm_output += circuit_graph.qasm(
|
||||
add_swap=True,
|
||||
decls_only=True,
|
||||
aliases=layout)
|
||||
first_layer = False
|
||||
initial_layout = layout
|
||||
first_swapping_layer = False
|
||||
else:
|
||||
if not first_swapping_layer:
|
||||
if verbose:
|
||||
print("swap_mapper: layer %d (%d), depth %d"
|
||||
% (i, j, best_d))
|
||||
openqasm_output += best_circ
|
||||
else:
|
||||
initial_layout = layout
|
||||
first_swapping_layer = False
|
||||
openqasm_output += serial_layerlist[j]["graph"].qasm(
|
||||
no_decls=True,
|
||||
aliases=layout)
|
||||
no_decls=True,
|
||||
aliases=layout)
|
||||
else:
|
||||
# Update the qubit positions each iteration
|
||||
layout = best_layout
|
||||
if first_layer:
|
||||
initial_layout = layout
|
||||
openqasm_output += circuit_graph.qasm(add_swap=True,
|
||||
decls_only=True,
|
||||
aliases=layout)
|
||||
openqasm_output += layerlist[i]["graph"].qasm(no_decls=True,
|
||||
aliases=layout)
|
||||
first_layer = False
|
||||
if best_d == 0:
|
||||
# Output qasm without swaps
|
||||
if first_layer:
|
||||
openqasm_output += circuit_graph.qasm(
|
||||
add_swap=True,
|
||||
decls_only=True,
|
||||
aliases=layout)
|
||||
first_layer = False
|
||||
if not trivial_flag and first_swapping_layer:
|
||||
initial_layout = layout
|
||||
first_swapping_layer = False
|
||||
else:
|
||||
if verbose:
|
||||
print("swap_mapper: layer %s, depth %d" % (i, best_d))
|
||||
if best_circ != "":
|
||||
openqasm_output += best_circ
|
||||
openqasm_output += layerlist[i]["graph"].qasm(no_decls=True,
|
||||
aliases=layout)
|
||||
# Output qasm with swaps
|
||||
if first_layer:
|
||||
openqasm_output += circuit_graph.qasm(
|
||||
add_swap=True,
|
||||
decls_only=True,
|
||||
aliases=layout)
|
||||
first_layer = False
|
||||
initial_layout = layout
|
||||
first_swapping_layer = False
|
||||
else:
|
||||
if not first_swapping_layer:
|
||||
if verbose:
|
||||
print("swap_mapper: layer %d, depth %d"
|
||||
% (i, best_d))
|
||||
openqasm_output += best_circ
|
||||
else:
|
||||
initial_layout = layout
|
||||
first_swapping_layer = False
|
||||
openqasm_output += layerlist[i]["graph"].qasm(
|
||||
no_decls=True,
|
||||
aliases=layout)
|
||||
# Parse openqasm_output into Circuit object
|
||||
basis += ",swap"
|
||||
ast = Qasm(data=openqasm_output).parse()
|
||||
|
|
|
@ -475,7 +475,7 @@ class QasmParser(object):
|
|||
'''
|
||||
if program[2] != '}':
|
||||
raise QasmException("Missing '}' in gate definition; received'"
|
||||
+ str(pprogram[2].value) + "'")
|
||||
+ str(program[2].value) + "'")
|
||||
program[0] = node.GateBody(None)
|
||||
|
||||
def p_gate_body_1(self, program):
|
||||
|
|
Loading…
Reference in New Issue