45
45
# ==============================================================================
46
46
47
47
48
- class OpenQASMBackend (BasicEngine ):
48
+ class OpenQASMBackend (BasicEngine ): # pylint: disable=too-many-instance-attributes
49
49
"""
50
- Engine to convert ProjectQ commands to OpenQASM format (either string or
51
- file)
50
+ Engine to convert ProjectQ commands to OpenQASM format (either string or file)
52
51
"""
53
52
54
53
def __init__ (
55
54
self ,
56
- collate = True ,
57
55
collate_callback = None ,
58
- qubit_callback = lambda qubit_id : 'q{}' .format ( qubit_id ) ,
59
- bit_callback = lambda qubit_id : 'c{}' .format ( qubit_id ) ,
56
+ qubit_callback = 'q{}' .format ,
57
+ bit_callback = 'c{}' .format ,
60
58
qubit_id_mapping_redux = True ,
61
59
):
62
60
"""
63
61
Initialize an OpenQASMBackend object.
64
62
65
- Contrary to OpenQASM, ProjectQ does not impose the restriction that a
66
- programm must start with qubit/bit allocations and end with some
67
- measurements.
63
+ Contrary to OpenQASM, ProjectQ does not impose the restriction that a programm must start with qubit/bit
64
+ allocations and end with some measurements.
68
65
69
- The user can configure what happens each time a FlushGate() is
70
- encountered by setting the `collate` and `collate_func` arguments to
71
- an OpenQASMBackend constructor,
66
+ The user can configure what happens each time a FlushGate() is encountered by setting the `collate` and
67
+ `collate_func` arguments to an OpenQASMBackend constructor,
72
68
73
69
Args:
74
70
output (list,file):
75
- collate (bool): If True, simply append commands to the exisiting
76
- file/string list when a FlushGate is received. If False, you
77
- need to specify `collate_callback` arguments as well.
78
- collate (function): Only has an effect if `collate` is False. Each
79
- time a FlushGate is received, this callback function will be
80
- called.
71
+ collate (function): Each time a FlushGate is received, this callback function will be called. If let
72
+ unspecified, the commands are appended to the existing file/string.
81
73
Function signature: Callable[[Sequence[str]], None]
82
- qubit_callback (function): Callback function called upon create of
83
- each qubit to generate a name for the qubit.
74
+ qubit_callback (function): Callback function called upon create of each qubit to generate a name for the
75
+ qubit.
84
76
Function signature: Callable[[int], str]
85
- bit_callback (function): Callback function called upon create of
86
- each qubit to generate a name for the qubit.
77
+ bit_callback (function): Callback function called upon create of each qubit to generate a name for the
78
+ qubit.
87
79
Function signature: Callable[[int], str]
88
- qubit_id_mapping_redux (bool): If True, try to allocate new Qubit
89
- IDs to the next available qreg/creg (if any), otherwise create
90
- a new qreg/creg. If False, simply create a new qreg/creg for
91
- each new Qubit ID
80
+ qubit_id_mapping_redux (bool): If True, try to allocate new Qubit IDs to the next available qreg/creg (if
81
+ any), otherwise create a new qreg/creg. If False, simply create a new qreg/creg for each new Qubit ID
92
82
"""
93
83
super ().__init__ ()
94
- self ._collate = collate
95
- self ._collate_callback = None if collate else collate_callback
84
+ self ._collate_callback = collate_callback
96
85
self ._gen_qubit_name = qubit_callback
97
86
self ._gen_bit_name = bit_callback
98
87
self ._qubit_id_mapping_redux = qubit_id_mapping_redux
@@ -107,6 +96,9 @@ def __init__(
107
96
108
97
@property
109
98
def qasm (self ):
99
+ """
100
+ Access to the QASM representation of the circuit.
101
+ """
110
102
return self ._output
111
103
112
104
def is_available (self , cmd ):
@@ -150,8 +142,7 @@ def is_available(self, cmd):
150
142
return False
151
143
if not self .is_last_engine :
152
144
return self .next_engine .is_available (cmd )
153
- else :
154
- return True
145
+ return True
155
146
156
147
def receive (self , command_list ):
157
148
"""
@@ -170,12 +161,11 @@ def receive(self, command_list):
170
161
if not self .is_last_engine :
171
162
self .send (command_list )
172
163
173
- def _store (self , cmd ):
164
+ def _store (self , cmd ): # pylint: disable=too-many-branches,too-many-statements
174
165
"""
175
166
Temporarily store the command cmd.
176
167
177
- Translates the command and stores it the _openqasm_circuit attribute
178
- (self._openqasm_circuit)
168
+ Translates the command and stores it the _openqasm_circuit attribute (self._openqasm_circuit)
179
169
180
170
Args:
181
171
cmd: Command to store
@@ -223,9 +213,8 @@ def _format_angle(angle):
223
213
if gate == Allocate :
224
214
add = True
225
215
226
- # Perform qubit index reduction if possible. This typically means
227
- # that existing qubit keep their indices between FlushGates but
228
- # that qubit indices of deallocated qubit may be reused.
216
+ # Perform qubit index reduction if possible. This typically means that existing qubit keep their indices
217
+ # between FlushGates but that qubit indices of deallocated qubit may be reused.
229
218
if self ._qubit_id_mapping_redux and self ._available_indices :
230
219
add = False
231
220
index = self ._available_indices .pop ()
@@ -263,8 +252,8 @@ def _format_angle(angle):
263
252
264
253
try :
265
254
self ._output .append ('{} {};' .format (_ccontrolled_gates_func [gate ], ',' .join (controls + targets )))
266
- except KeyError :
267
- raise RuntimeError ('Unable to perform {} gate with n=2 control qubits' .format (gate ))
255
+ except KeyError as err :
256
+ raise RuntimeError ('Unable to perform {} gate with n=2 control qubits' .format (gate )) from err
268
257
269
258
elif n_controls == 1 :
270
259
target_qureg = [self ._qreg_dict [qb .id ] for qureg in cmd .qubits for qb in qureg ]
@@ -300,8 +289,8 @@ def _format_angle(angle):
300
289
_controlled_gates_func [gate ], self ._qreg_dict [cmd .control_qubits [0 ].id ], * target_qureg
301
290
)
302
291
)
303
- except KeyError :
304
- raise RuntimeError ('Unable to perform {} gate with n=1 control qubits' .format (gate ))
292
+ except KeyError as err :
293
+ raise RuntimeError ('Unable to perform {} gate with n=1 control qubits' .format (gate )) from err
305
294
else :
306
295
target_qureg = [self ._qreg_dict [qb .id ] for qureg in cmd .qubits for qb in qureg ]
307
296
if isinstance (gate , Ph ):
@@ -323,7 +312,7 @@ def _reset_after_flush(self):
323
312
"""
324
313
Reset the internal quantum circuit after a FlushGate
325
314
"""
326
- if self ._collate :
315
+ if not self ._collate_callback :
327
316
self ._output .append ('# ' + '=' * 80 )
328
317
else :
329
318
self ._collate_callback (deepcopy (self ._output ))
0 commit comments