def assemble_circuits(circuits, run_config, qobj_id, qobj_header): """Assembles a list of circuits into a qobj that can be run on the backend. Args: circuits (list[QuantumCircuit]): 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()) qubit_sizes = [] memory_slot_sizes = [] for circ in circuits: num_qubits = 0 memory_slots = 0 for qreg in circ.qregs: num_qubits += qreg.size for creg in circ.cregs: memory_slots += creg.size qubit_sizes.append(num_qubits) memory_slot_sizes.append(memory_slots) qobj_config.memory_slots = max(memory_slot_sizes) qobj_config.n_qubits = max(qubit_sizes) experiments = parallel_map(_assemble_circuit, circuits) return QasmQobj(qobj_id=qobj_id, config=qobj_config, experiments=experiments, header=qobj_header)
def assemble_circuits(circuits: List[QuantumCircuit], run_config: RunConfig, qobj_id: int, qobj_header: QobjHeader) -> QasmQobj: """Assembles a list of circuits into a qobj that can be run on the backend. Args: circuits: circuit(s) to assemble run_config: configuration of the runtime environment qobj_id: identifier for the generated qobj qobj_header: header to pass to the results Returns: The qobj to be run on the backends """ qobj_config = QasmQobjConfig() if run_config: qobj_config = QasmQobjConfig(**run_config.to_dict()) qubit_sizes = [] memory_slot_sizes = [] for circ in circuits: num_qubits = 0 memory_slots = 0 for qreg in circ.qregs: num_qubits += qreg.size for creg in circ.cregs: memory_slots += creg.size qubit_sizes.append(num_qubits) memory_slot_sizes.append(memory_slots) qobj_config.memory_slots = max(memory_slot_sizes) qobj_config.n_qubits = max(qubit_sizes) experiments_and_pulse_libs = parallel_map(_assemble_circuit, circuits, [run_config]) experiments = [] pulse_library = {} for exp, lib in experiments_and_pulse_libs: experiments.append(exp) if lib: pulse_library.update(lib) if pulse_library: qobj_config.pulse_library = [ PulseLibraryItem(name=name, samples=samples) for name, samples in pulse_library.items() ] experiments, calibrations = _extract_common_calibrations(experiments) if calibrations and calibrations.gates: qobj_config.calibrations = calibrations return QasmQobj(qobj_id=qobj_id, config=qobj_config, experiments=experiments, header=qobj_header)
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 assemble_circuits(circuits: List[QuantumCircuit], run_config: RunConfig, qobj_id: int, qobj_header: QobjHeader) -> QasmQobj: """Assembles a list of circuits into a qobj that can be run on the backend. Args: circuits: circuit(s) to assemble run_config: configuration of the runtime environment qobj_id: identifier for the generated qobj qobj_header: header to pass to the results Returns: The qobj to be run on the backends """ # assemble the circuit experiments experiments_and_pulse_libs = parallel_map(_assemble_circuit, circuits, [run_config]) experiments = [] pulse_library = {} for exp, lib in experiments_and_pulse_libs: experiments.append(exp) if lib: pulse_library.update(lib) # extract common calibrations experiments, calibrations = _extract_common_calibrations(experiments) # configure LO freqs per circuit lo_converter = converters.LoConfigConverter(QasmQobjExperimentConfig, **run_config.to_dict()) experiments = _configure_experiment_los(experiments, lo_converter, run_config) qobj_config = QasmQobjConfig() if run_config: qobj_config_dict = run_config.to_dict() # remove LO ranges, not needed in qobj qobj_config_dict.pop("qubit_lo_range", None) qobj_config_dict.pop("meas_lo_range", None) # convert LO frequencies to GHz, if they exist if "qubit_lo_freq" in qobj_config_dict: qobj_config_dict["qubit_lo_freq"] = [ freq / 1e9 for freq in qobj_config_dict["qubit_lo_freq"] ] if "meas_lo_freq" in qobj_config_dict: qobj_config_dict["meas_lo_freq"] = [ freq / 1e9 for freq in qobj_config_dict["meas_lo_freq"] ] # override default los if single ``schedule_los`` entry set schedule_los = qobj_config_dict.pop("schedule_los", []) if len(schedule_los) == 1: lo_dict = schedule_los[0] q_los = lo_converter.get_qubit_los(lo_dict) # Hz -> GHz if q_los: qobj_config_dict["qubit_lo_freq"] = [ freq / 1e9 for freq in q_los ] m_los = lo_converter.get_meas_los(lo_dict) if m_los: qobj_config_dict["meas_lo_freq"] = [ freq / 1e9 for freq in m_los ] qobj_config = QasmQobjConfig(**qobj_config_dict) qubit_sizes = [] memory_slot_sizes = [] for circ in circuits: num_qubits = 0 memory_slots = 0 for qreg in circ.qregs: num_qubits += qreg.size for creg in circ.cregs: memory_slots += creg.size qubit_sizes.append(num_qubits) memory_slot_sizes.append(memory_slots) qobj_config.memory_slots = max(memory_slot_sizes) qobj_config.n_qubits = max(qubit_sizes) if pulse_library: qobj_config.pulse_library = [ PulseLibraryItem(name=name, samples=samples) for name, samples in pulse_library.items() ] if calibrations and calibrations.gates: qobj_config.calibrations = calibrations return QasmQobj(qobj_id=qobj_id, config=qobj_config, experiments=experiments, header=qobj_header)
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 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)