def test_snapshot_instruction_from_dict(self): """Test snapshot instruction from dict.""" expected_qobj = QasmQobj( qobj_id='12345', header=QobjHeader(), config=QasmQobjConfig(shots=1024, memory_slots=2, max_credits=10), experiments=[ QasmQobjExperiment(instructions=[ QasmQobjInstruction(name='u1', qubits=[1], params=[0.4]), QasmQobjInstruction(name='u2', qubits=[1], params=[0.4, 0.2]), QasmQobjInstruction(name='snapshot', qubits=[1], snapshot_type='statevector', label='my_snap') ]) ] ) qobj_dict = { 'qobj_id': '12345', 'type': 'QASM', 'schema_version': '1.1.0', 'header': {}, 'config': {'max_credits': 10, 'memory_slots': 2, 'shots': 1024}, 'experiments': [ {'instructions': [ {'name': 'u1', 'params': [0.4], 'qubits': [1]}, {'name': 'u2', 'params': [0.4, 0.2], 'qubits': [1]}, {'name': 'snapshot', 'qubits': [1], 'snapshot_type': 'statevector', 'label': 'my_snap'} ]} ], } self.assertEqual(expected_qobj, QasmQobj.from_dict(qobj_dict))
def setUp(self): self.valid_qobj = QasmQobj( qobj_id='12345', header=QobjHeader(), config=QasmQobjConfig(shots=1024, memory_slots=2, max_credits=10), experiments=[ QasmQobjExperiment(instructions=[ QasmQobjInstruction(name='u1', qubits=[1], params=[0.4]), QasmQobjInstruction(name='u2', qubits=[1], params=[0.4, 0.2]) ]) ] ) self.valid_dict = { 'qobj_id': '12345', 'type': 'QASM', 'schema_version': '1.1.0', 'header': {}, 'config': {'max_credits': 10, 'memory_slots': 2, 'shots': 1024}, 'experiments': [ {'instructions': [ {'name': 'u1', 'params': [0.4], 'qubits': [1]}, {'name': 'u2', 'params': [0.4, 0.2], 'qubits': [1]} ]} ], } self.bad_qobj = copy.deepcopy(self.valid_qobj) self.bad_qobj.experiments = []
def test_from_dict_per_class(self): """Test Qobj and its subclass representations given a dictionary.""" test_parameters = { QasmQobj: (self.valid_qobj, self.valid_dict), QasmQobjConfig: (QasmQobjConfig(shots=1, memory_slots=2), { 'shots': 1, 'memory_slots': 2 }), QasmQobjExperiment: (QasmQobjExperiment(instructions=[ QasmQobjInstruction(name='u1', qubits=[1], params=[0.4]) ]), { 'instructions': [{ 'name': 'u1', 'qubits': [1], 'params': [0.4] }] }), QasmQobjInstruction: (QasmQobjInstruction(name='u1', qubits=[1], params=[0.4]), { 'name': 'u1', 'qubits': [1], 'params': [0.4] }) } for qobj_class, (qobj_item, expected_dict) in test_parameters.items(): with self.subTest(msg=str(qobj_class)): self.assertEqual(qobj_item, qobj_class.from_dict(expected_dict))
def test_snapshot_instruction_to_dict(self): """Test snapshot instruction to dict.""" valid_qobj = QasmQobj( qobj_id="12345", header=QobjHeader(), config=QasmQobjConfig(shots=1024, memory_slots=2, max_credits=10), experiments=[ QasmQobjExperiment(instructions=[ QasmQobjInstruction(name="u1", qubits=[1], params=[0.4]), QasmQobjInstruction( name="u2", qubits=[1], params=[0.4, 0.2]), QasmQobjInstruction( name="snapshot", qubits=[1], snapshot_type="statevector", label="my_snap", ), ]) ], ) res = valid_qobj.to_dict() expected_dict = { "qobj_id": "12345", "type": "QASM", "schema_version": "1.3.0", "header": {}, "config": { "max_credits": 10, "memory_slots": 2, "shots": 1024 }, "experiments": [{ "instructions": [ { "name": "u1", "params": [0.4], "qubits": [1] }, { "name": "u2", "params": [0.4, 0.2], "qubits": [1] }, { "name": "snapshot", "qubits": [1], "snapshot_type": "statevector", "label": "my_snap", }, ], "config": {}, "header": {}, }], } self.assertEqual(expected_dict, res)
def measure_instr(qubits, memory, registers=None): """Create a multi-qubit measure instruction""" if len(qubits) != len(memory): raise ValueError("Number of qubits does not match number of memory") if registers is None: return QasmQobjInstruction(name='measure', qubits=qubits, memory=memory) # Case where we also measure to registers if len(qubits) != len(registers): raise ValueError("Number of qubits does not match number of registers") return QasmQobjInstruction(name='measure', qubits=qubits, memory=memory, register=registers)
def save_inst(num_qubits): """Return n-qubit save statevector inst""" return QasmQobjInstruction( name=f"save_{state}", qubits=list(range(num_qubits)), label=f"{state}", snapshot_type="single")
def assemble(self): """Assemble a QasmQobjInstruction for snapshot_expectation_value.""" return QasmQobjInstruction(name=self.name, params=[x.tolist() for x in self.params], snapshot_type=self.snapshot_type, qubits=list(range(self.num_qubits)), label=self.label)
def snapshot_instr(snapshot_type, label, qubits=None, params=None): """Create a snapshot qobj item. Args: snapshot_type (str): the snapshot type identifier label (str): the snapshot label string qubits (list[int]): qubits snapshot applies to (optional) params (custom): optional parameters for special snapshot types. See additional information. Returns: QasmQobjInstruction: The qobj item for the snapshot instruction. Additional Information: Snapshot types: "statevector" -- returns the current statevector for each shot "memory" -- returns the current memory hex-string for each shot "register" -- returns the current register hex-string for each shot "probabilities" -- returns the measurement outcome probabilities averaged over all shots, but conditioned on the current memory value. This requires the qubits field to be set. "expval_pauli" -- returns the expectation value of an operator averaged over all shots, but conditioned on the current memory value. This requires the qubits field to be set and the params field to be set. "expval_matrix" -- same as expval_pauli but with different params Pauli expectation value params: These are a list of terms [complex_coeff, pauli_str] where string is in little endian: pauli_str CBA applies Pauli A to qubits[0], B to qubits[1] and C to qubits[2]. Example for op 0.5 XX + 0.7 IZ we have [[0.5, 'XX'], [0.7, 'IZ']] Matrix expectation value params: TODO """ warnings.warn( 'This function is deprecated and will be removed in a future release.' ' Use the snapshot circuit instructions in' ' `qiskit.provider.aer.extensions` instead.', DeprecationWarning) snap = { "name": "snapshot", "snapshot_type": snapshot_type, "label": str(label) } if qubits is not None: snap["qubits"] = list(qubits) if params is not None: snap["params"] = params # Check if single-matrix expectation value if snapshot_type in ["expval", "expval_matrix"] and \ isinstance(params, np.ndarray): snap["name"] = "expval_matrix" snap["params"] = [[1.0, qubits, params]] # TODO: implicit conversion for Pauli expval params return QasmQobjInstruction(**snap)
def setUp(self): super().setUp() self.valid_qobj = QasmQobj( qobj_id="12345", header=QobjHeader(), config=QasmQobjConfig(shots=1024, memory_slots=2, max_credits=10), experiments=[ QasmQobjExperiment(instructions=[ QasmQobjInstruction(name="u1", qubits=[1], params=[0.4]), QasmQobjInstruction( name="u2", qubits=[1], params=[0.4, 0.2]), ]) ], ) self.valid_dict = { "qobj_id": "12345", "type": "QASM", "schema_version": "1.2.0", "header": {}, "config": { "max_credits": 10, "memory_slots": 2, "shots": 1024 }, "experiments": [{ "instructions": [ { "name": "u1", "params": [0.4], "qubits": [1] }, { "name": "u2", "params": [0.4, 0.2], "qubits": [1] }, ] }], } self.bad_qobj = copy.deepcopy(self.valid_qobj) self.bad_qobj.experiments = []
def measure_instr(qubits, memory, registers=None): """Create a multi-qubit measure instruction""" warnings.warn( 'This function is deprecated and will be removed in a future release.', DeprecationWarning) if len(qubits) != len(memory): raise ValueError("Number of qubits does not match number of memory") if registers is None: return QasmQobjInstruction(name='measure', qubits=qubits, memory=memory) # Case where we also measure to registers if len(qubits) != len(registers): raise ValueError("Number of qubits does not match number of registers") return QasmQobjInstruction(name='measure', qubits=qubits, memory=memory, register=registers)
def __init__(self): qobj_id = "test_id" config = QasmQobjConfig(shots=1024, memory_slots=1) header = QobjHeader(backend_name=FakeQasmSimulator().name()) experiments = [ QasmQobjExperiment( instructions=[QasmQobjInstruction(name="barrier", qubits=[1])], header=QobjExperimentHeader(), config=QasmQobjExperimentConfig(seed=123456), ) ] super().__init__(qobj_id=qobj_id, config=config, experiments=experiments, header=header)
def new_fake_qobj(): """Create fake `Qobj` and backend instances.""" backend = FakeQasmSimulator() return QasmQobj( qobj_id='test-id', config=QasmQobjConfig(shots=1024, memory_slots=1, max_credits=100), header=QobjHeader(backend_name=backend.name()), experiments=[ QasmQobjExperiment( instructions=[QasmQobjInstruction(name='barrier', qubits=[1])], header=QobjExperimentHeader(), config=QasmQobjExperimentConfig(seed_simulator=123456)) ])
def test_map_measurements(self): counts = Counter() counts.update({'0000': 10}) counts.update({'0101': 3}) counts.update({'1111': 7}) counts.update({'0101': 5}) counts.update({'1110': 1}) counts.update({'1000': 2}) # move to 01 -> 10 qasm_experiment = QasmQobjExperiment(instructions=[ QasmQobjInstruction(name='measure', qubits=[0], memory=[1]), QasmQobjInstruction(name='measure', qubits=[2], memory=[0]) ]) new_counts = map_measurements(counts, qasm_experiment) self.assertIn('00', new_counts) self.assertIn('10', new_counts) self.assertIn('11', new_counts) self.assertEqual(new_counts['00'], 10 + 3 + 5) self.assertEqual(new_counts['11'], 7 + 1) self.assertEqual(new_counts['10'], 2)
def test_from_dict_per_class(self): """Test Qobj and its subclass representations given a dictionary.""" test_parameters = { QasmQobj: (self.valid_qobj, self.valid_dict), QasmQobjConfig: ( QasmQobjConfig(shots=1, memory_slots=2), { "shots": 1, "memory_slots": 2 }, ), QasmQobjExperiment: ( QasmQobjExperiment(instructions=[ QasmQobjInstruction(name="u1", qubits=[1], params=[0.4]) ]), { "instructions": [{ "name": "u1", "qubits": [1], "params": [0.4] }] }, ), QasmQobjInstruction: ( QasmQobjInstruction(name="u1", qubits=[1], params=[0.4]), { "name": "u1", "qubits": [1], "params": [0.4] }, ), } for qobj_class, (qobj_item, expected_dict) in test_parameters.items(): with self.subTest(msg=str(qobj_class)): self.assertEqual(qobj_item, qobj_class.from_dict(expected_dict))
def unitary_instr(mat, qubits, label=None): """Create a unitary gate QasmQobjInstruction. Args: mat (matrix_like): an n-qubit unitary matrix qubits (list[int]): qubits to apply the matrix to. label (str): optional string label for the untiary matrix Returns: QasmQobjInstruction: The qobj item for the unitary instruction. Raises: ValueError: if the input matrix is not unitary Additional Information: Qubit Ordering: The n-qubit matrix is ordered in little-endian with respect to the qubits in the label string. For example. If M is a tensor product of single qubit matrices `M = kron(M_(n-1), ..., M_1, M_0)` then `M_0` is applied to `qubits[0]`, `M_1` to `qubits[1]` etc. Label string: The string label is used for identifying the matrix in a noise model so that noise may be applied to the implementation of this matrix. """ warnings.warn( 'This function is deprecated and will be removed in a future release.', DeprecationWarning) array = np.array(mat, dtype=complex) dim = 2**len(qubits) if array.shape not in [(dim, dim), (1, dim)]: raise ValueError("Invalid") instruction = { "name": "unitary", "qubits": list(qubits), "params": [np.array(mat, dtype=complex)] } if label is not None: instruction["label"] = str(label) return QasmQobjInstruction(**instruction)
def reset_instr(qubits): """Create a multi-qubit reset instruction""" return QasmQobjInstruction(name='reset', qubits=qubits)
def _assemble_circuit( circuit: QuantumCircuit, run_config: RunConfig ) -> Tuple[QasmQobjExperiment, Optional[PulseLibrary]]: """Assemble one circuit. Args: circuit: circuit to assemble run_config: configuration of the runtime environment Returns: One experiment for the QasmQobj, and pulse library for pulse gates (which could be None) Raises: QiskitError: when the circuit has unit other than 'dt'. """ if circuit.unit != "dt": raise QiskitError( "Unable to assemble circuit with unit '{}', which must be 'dt'.". format(circuit.unit)) # header data num_qubits = 0 memory_slots = 0 qubit_labels = [] clbit_labels = [] qreg_sizes = [] creg_sizes = [] for qreg in circuit.qregs: qreg_sizes.append([qreg.name, qreg.size]) for j in range(qreg.size): qubit_labels.append([qreg.name, j]) num_qubits += qreg.size for creg in circuit.cregs: creg_sizes.append([creg.name, creg.size]) for j in range(creg.size): clbit_labels.append([creg.name, j]) memory_slots += creg.size qubit_indices = {qubit: idx for idx, qubit in enumerate(circuit.qubits)} clbit_indices = {clbit: idx for idx, clbit in enumerate(circuit.clbits)} # TODO: why do we need creq_sizes and qreg_sizes in header # TODO: we need to rethink memory_slots as they are tied to classical bit metadata = circuit.metadata if metadata is None: metadata = {} header = QobjExperimentHeader( qubit_labels=qubit_labels, n_qubits=num_qubits, qreg_sizes=qreg_sizes, clbit_labels=clbit_labels, memory_slots=memory_slots, creg_sizes=creg_sizes, name=circuit.name, global_phase=float(circuit.global_phase), metadata=metadata, ) # TODO: why do we need n_qubits and memory_slots in both the header and the config config = QasmQobjExperimentConfig(n_qubits=num_qubits, memory_slots=memory_slots) calibrations, pulse_library = _assemble_pulse_gates(circuit, run_config) if calibrations: config.calibrations = calibrations # Convert conditionals from QASM-style (creg ?= int) to qobj-style # (register_bit ?= 1), by assuming device has unlimited register slots # (supported only for simulators). Map all measures to a register matching # their clbit_index, create a new register slot for every conditional gate # and add a bfunc to map the creg=val mask onto the gating register bit. is_conditional_experiment = any(op.condition for (op, qargs, cargs) in circuit.data) max_conditional_idx = 0 instructions = [] for op_context in circuit.data: instruction = op_context[0].assemble() # Add register attributes to the instruction qargs = op_context[1] cargs = op_context[2] if qargs: instruction.qubits = [qubit_indices[qubit] for qubit in qargs] if cargs: instruction.memory = [clbit_indices[clbit] for clbit in cargs] # If the experiment has conditional instructions, assume every # measurement result may be needed for a conditional gate. if instruction.name == "measure" and is_conditional_experiment: instruction.register = [ clbit_indices[clbit] for clbit in cargs ] # To convert to a qobj-style conditional, insert a bfunc prior # to the conditional instruction to map the creg ?= val condition # onto a gating register bit. if hasattr(instruction, "_condition"): ctrl_reg, ctrl_val = instruction._condition mask = 0 val = 0 if isinstance(ctrl_reg, Clbit): mask = 1 << clbit_indices[ctrl_reg] val = (ctrl_val & 1) << clbit_indices[ctrl_reg] else: for clbit in clbit_indices: if clbit in ctrl_reg: mask |= 1 << clbit_indices[clbit] val |= ((ctrl_val >> list(ctrl_reg).index(clbit)) & 1) << clbit_indices[clbit] conditional_reg_idx = memory_slots + max_conditional_idx conversion_bfunc = QasmQobjInstruction( name="bfunc", mask="0x%X" % mask, relation="==", val="0x%X" % val, register=conditional_reg_idx, ) instructions.append(conversion_bfunc) instruction.conditional = conditional_reg_idx max_conditional_idx += 1 # Delete condition attribute now that we have replaced it with # the conditional and bfunc del instruction._condition instructions.append(instruction) return ( QasmQobjExperiment(instructions=instructions, header=header, config=config), pulse_library, )
def iden_instr(qubit): """Create a barrier QasmQobjInstruction.""" warnings.warn( 'This function is deprecated and will be removed in a future release.', DeprecationWarning) return QasmQobjInstruction(name='id', qubits=[qubit])
def execute_one_qasm(self, buffer, program): qobjStr = self.qobj_compiler.translate(program) import json from qiskit import Aer from qiskit.qobj import (QasmQobj, QobjHeader, QasmQobjInstruction, QasmQobjExperiment, QasmQobjExperimentConfig, QobjExperimentHeader, QasmQobjConfig) qobj_json = json.loads(qobjStr) # Create the Experiments using qiskit data structures exps = [ QasmQobjExperiment( config=QasmQobjExperimentConfig( memory_slots=e['config']['memory_slots'], n_qubits=e['config']['n_qubits']), header=QobjExperimentHeader( clbit_labels=e['header']['clbit_labels'], creg_sizes=e['header']['creg_sizes'], memory_slots=e['header']['memory_slots'], n_qubits=e['header']['n_qubits'], name=e['header']['name'], qreg_sizes=e['header']['qreg_sizes'], qubit_labels=e['header']['qubit_labels']), instructions=[ QasmQobjInstruction( name=i['name'], qubits=i['qubits'], params=(i['params'] if 'params' in i else [])) if i['name'] != 'measure' else QasmQobjInstruction( name=i['name'], qubits=i['qubits'], memory=i['memory']) for i in e['instructions'] ]) for e in qobj_json['qObject']['experiments'] ] qobj = QasmQobj( qobj_id=qobj_json['qObject']['qobj_id'], header=QobjHeader(), config=QasmQobjConfig( shots=self.shots, memory_slots=qobj_json['qObject']['config']['memory_slots']), experiments=exps, shots=self.shots) measures = {} for i in exps[0].instructions: if i.name == "measure": measures[i.memory[0]] = i.qubits[0] backend = Aer.get_backend('qasm_simulator') if self.noise_model is not None: job_sim = backend.run(qobj, noise_model=self.noise_model) else: job_sim = backend.run(qobj) sim_result = job_sim.result() for b, c in sim_result.get_counts().items(): bitstring = b if len(b) < buffer.size(): tmp = ['0' for i in range(buffer.size())] for bit_loc, qubit in measures.items(): tmp[len(tmp) - 1 - qubit] = list(b)[bit_loc] bitstring = ''.join(tmp) buffer.appendMeasurement(bitstring, c)
def assemble_circuits(circuits, qobj_id=None, qobj_header=None, run_config=None): """Assembles a list of circuits into a qobj which can be run on the backend. Args: circuits (list[QuantumCircuits]): circuit(s) to assemble qobj_id (int): identifier for the generated qobj qobj_header (QobjHeader): header to pass to the results run_config (RunConfig): configuration of the runtime environment Returns: QasmQobj: the Qobj to be run on the backends """ qobj_config = QasmQobjConfig() if run_config: qobj_config = QasmQobjConfig(**run_config.to_dict()) # Pack everything into the Qobj experiments = [] max_n_qubits = 0 max_memory_slots = 0 for circuit in circuits: # header stuff n_qubits = 0 memory_slots = 0 qubit_labels = [] clbit_labels = [] qreg_sizes = [] creg_sizes = [] for qreg in circuit.qregs: qreg_sizes.append([qreg.name, qreg.size]) for j in range(qreg.size): qubit_labels.append([qreg.name, j]) n_qubits += qreg.size for creg in circuit.cregs: creg_sizes.append([creg.name, creg.size]) for j in range(creg.size): clbit_labels.append([creg.name, j]) memory_slots += creg.size # TODO: why do we need creq_sizes and qreg_sizes in header # TODO: we need to rethink memory_slots as they are tied to classical bit experimentheader = QobjExperimentHeader(qubit_labels=qubit_labels, n_qubits=n_qubits, qreg_sizes=qreg_sizes, clbit_labels=clbit_labels, memory_slots=memory_slots, creg_sizes=creg_sizes, name=circuit.name) # TODO: why do we need n_qubits and memory_slots in both the header and the config experimentconfig = QasmQobjExperimentConfig(n_qubits=n_qubits, memory_slots=memory_slots) # Convert conditionals from QASM-style (creg ?= int) to qobj-style # (register_bit ?= 1), by assuming device has unlimited register slots # (supported only for simulators). Map all measures to a register matching # their clbit_index, create a new register slot for every conditional gate # and add a bfunc to map the creg=val mask onto the gating register bit. is_conditional_experiment = any(op.control for (op, qargs, cargs) in circuit.data) max_conditional_idx = 0 instructions = [] for op_context in circuit.data: op = op_context[0] qargs = op_context[1] cargs = op_context[2] current_instruction = QasmQobjInstruction(name=op.name) if qargs: qubit_indices = [ qubit_labels.index([qubit[0].name, qubit[1]]) for qubit in qargs ] current_instruction.qubits = qubit_indices if cargs: clbit_indices = [ clbit_labels.index([clbit[0].name, clbit[1]]) for clbit in cargs ] current_instruction.memory = clbit_indices # If the experiment has conditional instructions, assume every # measurement result may be needed for a conditional gate. if op.name == "measure" and is_conditional_experiment: current_instruction.register = clbit_indices if op.params: # Evalute Sympy parameters params = [ x.evalf() if hasattr(x, 'evalf') else x for x in op.params ] params = [ sympy.matrix2numpy(x, dtype=complex) if isinstance( x, sympy.Matrix) else x for x in params ] current_instruction.params = params # TODO: I really dont like this for snapshot. I also think we should change # type to snap_type if op.name == 'snapshot': current_instruction.label = str(op.params[0]) current_instruction.snapshot_type = str(op.params[1]) if op.name == 'unitary': if op._label: current_instruction.label = op._label if op.control: # To convert to a qobj-style conditional, insert a bfunc prior # to the conditional instruction to map the creg ?= val condition # onto a gating register bit. mask = 0 val = 0 for clbit in clbit_labels: if clbit[0] == op.control[0].name: mask |= (1 << clbit_labels.index(clbit)) val |= (((op.control[1] >> clbit[1]) & 1) << clbit_labels.index(clbit)) conditional_reg_idx = memory_slots + max_conditional_idx conversion_bfunc = QasmQobjInstruction( name='bfunc', mask="0x%X" % mask, relation='==', val="0x%X" % val, register=conditional_reg_idx) instructions.append(conversion_bfunc) current_instruction.conditional = conditional_reg_idx max_conditional_idx += 1 instructions.append(current_instruction) experiments.append( QasmQobjExperiment(instructions=instructions, header=experimentheader, config=experimentconfig)) if n_qubits > max_n_qubits: max_n_qubits = n_qubits if memory_slots > max_memory_slots: max_memory_slots = memory_slots qobj_config.memory_slots = max_memory_slots qobj_config.n_qubits = max_n_qubits return QasmQobj(qobj_id=qobj_id, config=qobj_config, experiments=experiments, header=qobj_header)
def iden_instr(qubit): """Create a barrier QasmQobjInstruction.""" return QasmQobjInstruction(name='id', qubits=[qubit])
def _assemble_circuit(circuit): # header stuff num_qubits = 0 memory_slots = 0 qubit_labels = [] clbit_labels = [] qreg_sizes = [] creg_sizes = [] for qreg in circuit.qregs: qreg_sizes.append([qreg.name, qreg.size]) for j in range(qreg.size): qubit_labels.append([qreg.name, j]) num_qubits += qreg.size for creg in circuit.cregs: creg_sizes.append([creg.name, creg.size]) for j in range(creg.size): clbit_labels.append([creg.name, j]) memory_slots += creg.size # TODO: why do we need creq_sizes and qreg_sizes in header # TODO: we need to rethink memory_slots as they are tied to classical bit header = QobjExperimentHeader(qubit_labels=qubit_labels, n_qubits=num_qubits, qreg_sizes=qreg_sizes, clbit_labels=clbit_labels, memory_slots=memory_slots, creg_sizes=creg_sizes, name=circuit.name, global_phase=circuit.global_phase) # TODO: why do we need n_qubits and memory_slots in both the header and the config config = QasmQobjExperimentConfig(n_qubits=num_qubits, memory_slots=memory_slots) # Convert conditionals from QASM-style (creg ?= int) to qobj-style # (register_bit ?= 1), by assuming device has unlimited register slots # (supported only for simulators). Map all measures to a register matching # their clbit_index, create a new register slot for every conditional gate # and add a bfunc to map the creg=val mask onto the gating register bit. is_conditional_experiment = any(op.condition for (op, qargs, cargs) in circuit.data) max_conditional_idx = 0 instructions = [] for op_context in circuit.data: instruction = op_context[0].assemble() # Add register attributes to the instruction qargs = op_context[1] cargs = op_context[2] if qargs: qubit_indices = [ qubit_labels.index([qubit.register.name, qubit.index]) for qubit in qargs ] instruction.qubits = qubit_indices if cargs: clbit_indices = [ clbit_labels.index([clbit.register.name, clbit.index]) for clbit in cargs ] instruction.memory = clbit_indices # If the experiment has conditional instructions, assume every # measurement result may be needed for a conditional gate. if instruction.name == "measure" and is_conditional_experiment: instruction.register = clbit_indices # To convert to a qobj-style conditional, insert a bfunc prior # to the conditional instruction to map the creg ?= val condition # onto a gating register bit. if hasattr(instruction, '_condition'): ctrl_reg, ctrl_val = instruction._condition mask = 0 val = 0 for clbit in clbit_labels: if clbit[0] == ctrl_reg.name: mask |= (1 << clbit_labels.index(clbit)) val |= (((ctrl_val >> clbit[1]) & 1) << clbit_labels.index(clbit)) conditional_reg_idx = memory_slots + max_conditional_idx conversion_bfunc = QasmQobjInstruction( name='bfunc', mask="0x%X" % mask, relation='==', val="0x%X" % val, register=conditional_reg_idx) instructions.append(conversion_bfunc) instruction.conditional = conditional_reg_idx max_conditional_idx += 1 # Delete condition attribute now that we have replaced it with # the conditional and bfuc del instruction._condition instructions.append(instruction) return QasmQobjExperiment(instructions=instructions, header=header, config=config)
def barrier_instr(num_qubits): """Create a barrier QasmQobjInstruction.""" warnings.warn( 'This function is deprecated and will be removed in a future release.', DeprecationWarning) return QasmQobjInstruction(name='barrier', qubits=list(range(num_qubits)))
def test_gate_calibrations_to_dict(self): """Test gate calibrations to dict.""" pulse_library = [PulseLibraryItem(name='test', samples=[1j, 1j])] valid_qobj = QasmQobj( qobj_id='12345', header=QobjHeader(), config=QasmQobjConfig(shots=1024, memory_slots=2, max_credits=10, pulse_library=pulse_library), experiments=[ QasmQobjExperiment( instructions=[ QasmQobjInstruction(name='u1', qubits=[1], params=[0.4]) ], config=QasmQobjConfig( calibrations=QasmExperimentCalibrations(gates=[ GateCalibration(name='u1', qubits=[1], params=[0.4], instructions=[]) ]))) ]) res = valid_qobj.to_dict(validate=True) expected_dict = { 'qobj_id': '12345', 'type': 'QASM', 'schema_version': '1.3.0', 'header': {}, 'config': { 'max_credits': 10, 'memory_slots': 2, 'shots': 1024, 'pulse_library': [{ 'name': 'test', 'samples': [1j, 1j] }] }, 'experiments': [{ 'instructions': [{ 'name': 'u1', 'params': [0.4], 'qubits': [1] }], 'config': { 'calibrations': { 'gates': [{ 'name': 'u1', 'qubits': [1], 'params': [0.4], 'instructions': [] }] } }, 'header': {} }], } self.assertEqual(expected_dict, res)
def assemble_circuits(circuits, run_config=None, qobj_header=None, qobj_id=None): """Assembles a list of circuits into a qobj which can be run on the backend. Args: circuits (list[QuantumCircuits] or QuantumCircuit): circuits to assemble run_config (RunConfig): RunConfig object qobj_header (QobjHeader): header to pass to the results qobj_id (int): identifier for the generated qobj Returns: QasmQobj: the Qobj to be run on the backends """ qobj_header = qobj_header or QobjHeader() run_config = run_config or RunConfig() if isinstance(circuits, QuantumCircuit): circuits = [circuits] userconfig = QasmQobjConfig(**run_config.to_dict()) experiments = [] max_n_qubits = 0 max_memory_slots = 0 for circuit in circuits: # header stuff n_qubits = 0 memory_slots = 0 qubit_labels = [] clbit_labels = [] qreg_sizes = [] creg_sizes = [] for qreg in circuit.qregs: qreg_sizes.append([qreg.name, qreg.size]) for j in range(qreg.size): qubit_labels.append([qreg.name, j]) n_qubits += qreg.size for creg in circuit.cregs: creg_sizes.append([creg.name, creg.size]) for j in range(creg.size): clbit_labels.append([creg.name, j]) memory_slots += creg.size # TODO: why do we need creq_sizes and qreg_sizes in header # TODO: we need to rethink memory_slots as they are tied to classical bit experimentheader = QobjExperimentHeader(qubit_labels=qubit_labels, n_qubits=n_qubits, qreg_sizes=qreg_sizes, clbit_labels=clbit_labels, memory_slots=memory_slots, creg_sizes=creg_sizes, name=circuit.name) # TODO: why do we need n_qubits and memory_slots in both the header and the config experimentconfig = QasmQobjExperimentConfig(n_qubits=n_qubits, memory_slots=memory_slots) instructions = [] for op_context in circuit.data: op = op_context[0] qargs = op_context[1] cargs = op_context[2] current_instruction = QasmQobjInstruction(name=op.name) if qargs: qubit_indices = [qubit_labels.index([qubit[0].name, qubit[1]]) for qubit in qargs] current_instruction.qubits = qubit_indices if cargs: clbit_indices = [clbit_labels.index([clbit[0].name, clbit[1]]) for clbit in cargs] current_instruction.memory = clbit_indices if op.params: params = list(map(lambda x: x.evalf(), op.params)) params = [sympy.matrix2numpy(x, dtype=complex) if isinstance(x, sympy.Matrix) else x for x in params] if len(params) == 1 and isinstance(params[0], numpy.ndarray): # TODO: Aer expects list of rows for unitary instruction params; # change to matrix in Aer. params = params[0] current_instruction.params = params # TODO: I really dont like this for snapshot. I also think we should change # type to snap_type if op.name == "snapshot": current_instruction.label = str(op.params[0]) current_instruction.type = str(op.params[1]) if op.name == 'unitary': if op._label: current_instruction.label = op._label if op.control: mask = 0 for clbit in clbit_labels: if clbit[0] == op.control[0].name: mask |= (1 << clbit_labels.index(clbit)) current_instruction.conditional = QobjConditional(mask="0x%X" % mask, type='equals', val="0x%X" % op.control[1]) instructions.append(current_instruction) experiments.append(QasmQobjExperiment(instructions=instructions, header=experimentheader, config=experimentconfig)) if n_qubits > max_n_qubits: max_n_qubits = n_qubits if memory_slots > max_memory_slots: max_memory_slots = memory_slots userconfig.memory_slots = max_memory_slots userconfig.n_qubits = max_n_qubits return QasmQobj(qobj_id=qobj_id or str(uuid.uuid4()), config=userconfig, experiments=experiments, header=qobj_header)
def reset_instr(qubits): """Create a multi-qubit reset instruction""" warnings.warn( 'This function is deprecated and will be removed in a future release.', DeprecationWarning) return QasmQobjInstruction(name='reset', qubits=qubits)
def test_gate_calibrations_to_dict(self): """Test gate calibrations to dict.""" pulse_library = [PulseLibraryItem(name="test", samples=[1j, 1j])] valid_qobj = QasmQobj( qobj_id="12345", header=QobjHeader(), config=QasmQobjConfig(shots=1024, memory_slots=2, max_credits=10, pulse_library=pulse_library), experiments=[ QasmQobjExperiment( instructions=[ QasmQobjInstruction(name="u1", qubits=[1], params=[0.4]) ], config=QasmQobjConfig( calibrations=QasmExperimentCalibrations(gates=[ GateCalibration(name="u1", qubits=[1], params=[0.4], instructions=[]) ])), ) ], ) res = valid_qobj.to_dict() expected_dict = { "qobj_id": "12345", "type": "QASM", "schema_version": "1.3.0", "header": {}, "config": { "max_credits": 10, "memory_slots": 2, "shots": 1024, "pulse_library": [{ "name": "test", "samples": [1j, 1j] }], }, "experiments": [{ "instructions": [{ "name": "u1", "params": [0.4], "qubits": [1] }], "config": { "calibrations": { "gates": [{ "name": "u1", "qubits": [1], "params": [0.4], "instructions": [] }] } }, "header": {}, }], } self.assertEqual(expected_dict, res)
def assemble_circuits(circuits, qobj_id=None, qobj_header=None, run_config=None): """Assembles a list of circuits into a qobj which can be run on the backend. Args: circuits (list[QuantumCircuits]): circuit(s) to assemble qobj_id (int): identifier for the generated qobj qobj_header (QobjHeader): header to pass to the results run_config (RunConfig): configuration of the runtime environment Returns: QasmQobj: the Qobj to be run on the backends """ qobj_config = QasmQobjConfig() if run_config: qobj_config = QasmQobjConfig(**run_config.to_dict()) # Pack everything into the Qobj experiments = [] max_n_qubits = 0 max_memory_slots = 0 for circuit in circuits: # header stuff n_qubits = 0 memory_slots = 0 qubit_labels = [] clbit_labels = [] qreg_sizes = [] creg_sizes = [] for qreg in circuit.qregs: qreg_sizes.append([qreg.name, qreg.size]) for j in range(qreg.size): qubit_labels.append([qreg.name, j]) n_qubits += qreg.size for creg in circuit.cregs: creg_sizes.append([creg.name, creg.size]) for j in range(creg.size): clbit_labels.append([creg.name, j]) memory_slots += creg.size # TODO: why do we need creq_sizes and qreg_sizes in header # TODO: we need to rethink memory_slots as they are tied to classical bit experimentheader = QobjExperimentHeader(qubit_labels=qubit_labels, n_qubits=n_qubits, qreg_sizes=qreg_sizes, clbit_labels=clbit_labels, memory_slots=memory_slots, creg_sizes=creg_sizes, name=circuit.name) # TODO: why do we need n_qubits and memory_slots in both the header and the config experimentconfig = QasmQobjExperimentConfig(n_qubits=n_qubits, memory_slots=memory_slots) # Convert conditionals from QASM-style (creg ?= int) to qobj-style # (register_bit ?= 1), by assuming device has unlimited register slots # (supported only for simulators). Map all measures to a register matching # their clbit_index, create a new register slot for every conditional gate # and add a bfunc to map the creg=val mask onto the gating register bit. is_conditional_experiment = any(op.control for (op, qargs, cargs) in circuit.data) max_conditional_idx = 0 instructions = [] for op_context in circuit.data: instruction = op_context[0].assemble() # Add register attributes to the instruction qargs = op_context[1] cargs = op_context[2] if qargs: qubit_indices = [ qubit_labels.index([qubit[0].name, qubit[1]]) for qubit in qargs ] instruction.qubits = qubit_indices if cargs: clbit_indices = [ clbit_labels.index([clbit[0].name, clbit[1]]) for clbit in cargs ] instruction.memory = clbit_indices # If the experiment has conditional instructions, assume every # measurement result may be needed for a conditional gate. if instruction.name == "measure" and is_conditional_experiment: instruction.register = clbit_indices # To convert to a qobj-style conditional, insert a bfunc prior # to the conditional instruction to map the creg ?= val condition # onto a gating register bit. if hasattr(instruction, '_control'): ctrl_reg, ctrl_val = instruction._control mask = 0 val = 0 for clbit in clbit_labels: if clbit[0] == ctrl_reg.name: mask |= (1 << clbit_labels.index(clbit)) val |= (((ctrl_val >> clbit[1]) & 1) << clbit_labels.index(clbit)) conditional_reg_idx = memory_slots + max_conditional_idx conversion_bfunc = QasmQobjInstruction( name='bfunc', mask="0x%X" % mask, relation='==', val="0x%X" % val, register=conditional_reg_idx) instructions.append(conversion_bfunc) instruction.conditional = conditional_reg_idx max_conditional_idx += 1 # Delete control attribute now that we have replaced it with # the conditional and bfuc del instruction._control instructions.append(instruction) experiments.append( QasmQobjExperiment(instructions=instructions, header=experimentheader, config=experimentconfig)) if n_qubits > max_n_qubits: max_n_qubits = n_qubits if memory_slots > max_memory_slots: max_memory_slots = memory_slots qobj_config.memory_slots = max_memory_slots qobj_config.n_qubits = max_n_qubits return QasmQobj(qobj_id=qobj_id, config=qobj_config, experiments=experiments, header=qobj_header)
def barrier_instr(num_qubits): """Create a barrier QasmQobjInstruction.""" return QasmQobjInstruction(name='barrier', qubits=list(range(num_qubits)))