Ejemplo n.º 1
0
    def test_generate_cqasm_with_entangle_algorithm(self):
        q = QuantumRegister(2)
        b = ClassicalRegister(2)
        circuit = QuantumCircuit(q, b)

        circuit.h(q[0])
        circuit.cx(q[0], q[1])
        circuit.measure(q[0], b[0])
        circuit.measure(q[1], b[1])

        backend = QuantumInspireBackend(Mock(), Mock())
        # transpiling the circuits using the transpiler_config
        new_circuits = transpile(circuit, backend)
        run_config = RunConfig(shots=1024, max_credits=10, memory=False)
        # assembling the circuits into a qobj to be run on the backend
        qiskit_job = assemble(new_circuits,
                              backend,
                              run_config=run_config.to_dict())

        experiment = qiskit_job.experiments[0]
        result = backend._generate_cqasm(experiment)
        expected = "version 1.0\n" \
                   "# cQASM generated by QI backend for Qiskit\n" \
                   "qubits 2\n" \
                   "H q[0]\n" \
                   "CNOT q[0], q[1]\n"
        self.assertEqual(result, expected)
Ejemplo n.º 2
0
    def load_qobj_from_cache(self, circuits, chunk, run_config=None):
        self.try_loading_cache_from_file()

        if self.try_reusing_qobjs and self.qobjs is not None and len(self.qobjs) > 0 and len(self.qobjs) <= chunk:
            self.mappings.insert(chunk, self.mappings[0])
            self.qobjs.insert(chunk, copy.deepcopy(self.qobjs[0]))

        for circ_num, input_circuit in enumerate(circuits):

            # If there are too few experiments in the cache, try reusing the first experiment.
            # Only do this for the first chunk. Subsequent chunks should rely on these copies
            # through the deepcopy above.
            if self.try_reusing_qobjs and chunk == 0 and circ_num > 0 and len(self.qobjs[chunk].experiments) <= \
                    circ_num:
                self.qobjs[0].experiments.insert(circ_num, copy.deepcopy(self.qobjs[0].experiments[0]))
                self.mappings[0].insert(circ_num, self.mappings[0][0])

            # Unroll circuit in case of composite gates
            raw_gates = []
            for gate in input_circuit.data:
                if isinstance(gate, CompositeGate): raw_gates += gate.instruction_list()
                else: raw_gates += [gate]
            self.qobjs[chunk].experiments[circ_num].header.name = input_circuit.name
            for gate_num, compiled_gate in enumerate(self.qobjs[chunk].experiments[circ_num].instructions):
                if not hasattr(compiled_gate, 'params') or len(compiled_gate.params) < 1: continue
                if compiled_gate.name == 'snapshot': continue
                cache_index = self.mappings[chunk][circ_num][gate_num]
                (uncompiled_gate, regs, _) = raw_gates[cache_index]

                # Need the 'getattr' wrapper because measure has no 'params' field and breaks this.
                if not len(getattr(compiled_gate, 'params', [])) == len(getattr(uncompiled_gate, 'params', [])) or \
                    not compiled_gate.name == uncompiled_gate.name:
                    raise AquaError('Gate mismatch at gate {0} ({1}, {2} params) of circuit against gate {3} ({4}, '
                                    '{5} params) of cached qobj'.format(cache_index,
                                                                 uncompiled_gate.name,
                                                                 len(uncompiled_gate.params),
                                                                 gate_num,
                                                                 compiled_gate.name,
                                                                 len(compiled_gate.params)))
                compiled_gate.params = np.array(uncompiled_gate.params, dtype=float).tolist()
        exec_qobj = copy.copy(self.qobjs[chunk])
        if self.skip_qobj_deepcopy: exec_qobj.experiments = self.qobjs[chunk].experiments[0:len(circuits)]
        else: exec_qobj.experiments = copy.deepcopy(self.qobjs[chunk].experiments[0:len(circuits)])

        if run_config is None:
            run_config = RunConfig(shots=1024, max_credits=10, memory=False)
        exec_qobj.config = QasmQobjConfig(**run_config.to_dict())
        exec_qobj.config.memory_slots = max(experiment.config.memory_slots for experiment in exec_qobj.experiments)
        exec_qobj.config.n_qubits = max(experiment.config.n_qubits for experiment in exec_qobj.experiments)
        return exec_qobj
Ejemplo n.º 3
0
def _assemble_pulse_gates(
    circuit: QuantumCircuit, run_config: RunConfig
) -> Tuple[Optional[QasmExperimentCalibrations], Optional[PulseLibrary]]:
    """Assemble and return the circuit calibrations and associated pulse library, if there are any.
    The calibrations themselves may reference the pulse library which is returned as a dict.

    Args:
        circuit: circuit which may have pulse calibrations
        run_config: configuration of the runtime environment

    Returns:
        The calibrations and pulse library, if there are any
    """
    if not circuit.calibrations:
        return None, None
    if not hasattr(run_config, "parametric_pulses"):
        run_config.parametric_pulses = []
    calibrations = []
    pulse_library = {}
    for gate, cals in circuit.calibrations.items():
        for (qubits, params), schedule in cals.items():
            qobj_instructions, _ = _assemble_schedule(
                schedule,
                converters.InstructionToQobjConverter(PulseQobjInstruction),
                run_config,
                pulse_library,
            )
            calibrations.append(
                GateCalibration(str(gate), list(qubits), list(params),
                                qobj_instructions))
    return QasmExperimentCalibrations(gates=calibrations), pulse_library
Ejemplo n.º 4
0
def _parse_circuit_args(parameter_binds, backend, meas_level, meas_return,
                        parametric_pulses, **run_config):
    """Build a circuit RunConfig replacing unset arguments with defaults derived from the `backend`.
    See `assemble` for more information on the required arguments.

    Returns:
        RunConfig: a run config, which is a standardized object that configures the qobj
            and determines the runtime environment.
    """
    parameter_binds = parameter_binds or []
    # create run configuration and populate
    run_config_dict = dict(parameter_binds=parameter_binds, **run_config)
    if backend:
        run_config_dict['parametric_pulses'] = getattr(backend.configuration(),
                                                       'parametric_pulses', [])
    if parametric_pulses:
        run_config_dict['parametric_pulses'] = parametric_pulses

    if meas_level:
        run_config_dict['meas_level'] = meas_level
        # only enable `meas_return` if `meas_level` isn't classified
        if meas_level != MeasLevel.CLASSIFIED:
            run_config_dict['meas_return'] = meas_return

    run_config = RunConfig(
        **{k: v
           for k, v in run_config_dict.items() if v is not None})

    return run_config
Ejemplo n.º 5
0
    def test_disassemble_single_schedule(self):
        """Test disassembling a single schedule.
        """
        d0 = pulse.DriveChannel(0)
        d1 = pulse.DriveChannel(1)
        with pulse.build(self.backend) as sched:
            with pulse.align_right():
                pulse.play(pulse.library.Constant(10, 1.0), d0)
                pulse.set_phase(1.0, d0)
                pulse.shift_phase(3.11, d0)
                pulse.set_frequency(1e9, d0)
                pulse.shift_frequency(1e7, d0)
                pulse.delay(20, d0)
                pulse.delay(10, d1)
                pulse.play(pulse.library.Constant(8, 0.1), d1)
                pulse.measure_all()

        qobj = assemble(sched, backend=self.backend, shots=2000)
        scheds, run_config_out, _ = disassemble(qobj)
        run_config_out = RunConfig(**run_config_out)
        self.assertEqual(run_config_out.memory_slots, 2)
        self.assertEqual(run_config_out.shots, 2000)
        self.assertEqual(run_config_out.memory, False)
        self.assertEqual(run_config_out.meas_level, 2)
        self.assertEqual(run_config_out.meas_lo_freq,
                         self.backend.defaults().meas_freq_est)
        self.assertEqual(run_config_out.qubit_lo_freq,
                         self.backend.defaults().qubit_freq_est)
        self.assertEqual(run_config_out.rep_time, 99)
        self.assertEqual(len(scheds), 1)
        self.assertEqual(scheds[0], sched)
Ejemplo n.º 6
0
    def test_disassemble_schedule_los(self):
        """Test disassembling schedule los."""
        d0 = pulse.DriveChannel(0)
        m0 = pulse.MeasureChannel(0)
        d1 = pulse.DriveChannel(1)
        m1 = pulse.MeasureChannel(1)

        sched0 = pulse.Schedule()
        sched1 = pulse.Schedule()

        schedule_los = [{
            d0: 4.5e9,
            d1: 5e9,
            m0: 6e9,
            m1: 7e9
        }, {
            d0: 5e9,
            d1: 4.5e9,
            m0: 7e9,
            m1: 6e9
        }]
        qobj = assemble([sched0, sched1],
                        backend=self.backend,
                        schedule_los=schedule_los)
        _, run_config_out, _ = disassemble(qobj)
        run_config_out = RunConfig(**run_config_out)

        self.assertEqual(run_config_out.schedule_los, schedule_los)
Ejemplo n.º 7
0
    def test_disassemble_multiple_circuits(self):
        """Test disassembling multiple circuits, all should have the same config.
        """
        qr0 = QuantumRegister(2, name='q0')
        qc0 = ClassicalRegister(2, name='c0')
        circ0 = QuantumCircuit(qr0, qc0, name='circ0')
        circ0.h(qr0[0])
        circ0.cx(qr0[0], qr0[1])
        circ0.measure(qr0, qc0)

        qr1 = QuantumRegister(3, name='q1')
        qc1 = ClassicalRegister(3, name='c1')
        circ1 = QuantumCircuit(qr1, qc1, name='circ0')
        circ1.h(qr1[0])
        circ1.cx(qr1[0], qr1[1])
        circ1.cx(qr1[0], qr1[2])
        circ1.measure(qr1, qc1)

        qobj = assemble([circ0, circ1], shots=100, memory=False, seed=6)
        circuits, run_config_out, headers = disassemble(qobj)
        run_config_out = RunConfig(**run_config_out)
        self.assertEqual(run_config_out.n_qubits, 3)
        self.assertEqual(run_config_out.memory_slots, 3)
        self.assertEqual(run_config_out.shots, 100)
        self.assertEqual(run_config_out.memory, False)
        self.assertEqual(run_config_out.seed, 6)
        self.assertEqual(len(circuits), 2)
        for circuit in circuits:
            self.assertIn(circuit, [circ0, circ1])
        self.assertEqual({}, headers)
def assemble_schedules(schedules: List[Union[pulse.ScheduleComponent,
                                             Tuple[int,
                                                   pulse.ScheduleComponent]]],
                       qobj_id: int, qobj_header: qobj.QobjHeader,
                       run_config: RunConfig) -> qobj.PulseQobj:
    """Assembles a list of schedules into a qobj that can be run on the backend.

    Args:
        schedules: Schedules to assemble.
        qobj_id: Identifier for the generated qobj.
        qobj_header: Header to pass to the results.
        run_config: Configuration of the runtime environment.

    Returns:
        The Qobj to be run on the backends.

    Raises:
        QiskitError: when frequency settings are not supplied.
    """
    if not hasattr(run_config, 'qubit_lo_freq'):
        raise QiskitError('qubit_lo_freq must be supplied.')
    if not hasattr(run_config, 'meas_lo_freq'):
        raise QiskitError('meas_lo_freq must be supplied.')

    lo_converter = converters.LoConfigConverter(qobj.PulseQobjExperimentConfig,
                                                **run_config.to_dict())
    experiments, experiment_config = _assemble_experiments(
        schedules, lo_converter, run_config)
    qobj_config = _assemble_config(lo_converter, experiment_config, run_config)

    return qobj.PulseQobj(experiments=experiments,
                          qobj_id=qobj_id,
                          header=qobj_header,
                          config=qobj_config)
Ejemplo n.º 9
0
    def test_disassemble_single_circuit(self):
        """Test disassembling a single circuit."""
        qr = QuantumRegister(2, name="q")
        cr = ClassicalRegister(2, name="c")
        circ = QuantumCircuit(qr, cr, name="circ")
        circ.h(qr[0])
        circ.cx(qr[0], qr[1])
        circ.measure(qr, cr)

        qubit_lo_freq = [5e9, 5e9]
        meas_lo_freq = [6.7e9, 6.7e9]
        qobj = assemble(
            circ,
            shots=2000,
            memory=True,
            qubit_lo_freq=qubit_lo_freq,
            meas_lo_freq=meas_lo_freq,
        )
        circuits, run_config_out, headers = disassemble(qobj)
        run_config_out = RunConfig(**run_config_out)
        self.assertEqual(run_config_out.n_qubits, 2)
        self.assertEqual(run_config_out.memory_slots, 2)
        self.assertEqual(run_config_out.shots, 2000)
        self.assertEqual(run_config_out.memory, True)
        self.assertEqual(run_config_out.qubit_lo_freq, qubit_lo_freq)
        self.assertEqual(run_config_out.meas_lo_freq, meas_lo_freq)
        self.assertEqual(len(circuits), 1)
        self.assertEqual(circuits[0], circ)
        self.assertEqual({}, headers)
Ejemplo n.º 10
0
def _assemble_config(
    lo_converter: converters.LoConfigConverter,
    experiment_config: Dict[str, Any],
    run_config: RunConfig,
) -> qobj.PulseQobjConfig:
    """Assembles the QobjConfiguration from experimental config and runtime config.

    Args:
        lo_converter: The configured frequency converter and validator.
        experiment_config: Schedules to assemble.
        run_config: Configuration of the runtime environment.

    Returns:
        The assembled PulseQobjConfig.
    """
    qobj_config = run_config.to_dict()
    qobj_config.update(experiment_config)

    # Run config not needed in qobj config
    qobj_config.pop("meas_map", None)
    qobj_config.pop("qubit_lo_range", None)
    qobj_config.pop("meas_lo_range", None)

    # convert enums to serialized values
    meas_return = qobj_config.get("meas_return", "avg")
    if isinstance(meas_return, qobj_utils.MeasReturnType):
        qobj_config["meas_return"] = meas_return.value

    meas_level = qobj_config.get("meas_level", 2)
    if isinstance(meas_level, qobj_utils.MeasLevel):
        qobj_config["meas_level"] = meas_level.value

    # convert LO frequencies to GHz
    qobj_config["qubit_lo_freq"] = [
        freq / 1e9 for freq in qobj_config["qubit_lo_freq"]
    ]
    qobj_config["meas_lo_freq"] = [
        freq / 1e9 for freq in qobj_config["meas_lo_freq"]
    ]

    # override defaults if single entry for ``schedule_los``
    schedule_los = qobj_config.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["qubit_lo_freq"] = [freq / 1e9 for freq in q_los]
        m_los = lo_converter.get_meas_los(lo_dict)
        if m_los:
            qobj_config["meas_lo_freq"] = [freq / 1e9 for freq in m_los]

    return qobj.PulseQobjConfig(**qobj_config)
Ejemplo n.º 11
0
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_config(lo_converter: converters.LoConfigConverter,
                     experiment_config: Dict[str, Any],
                     run_config: RunConfig) -> qobj.PulseQobjConfig:
    """Assembles the QobjConfiguration from experimental config and runtime config.

    Args:
        lo_converter: The configured frequency converter and validator.
        experiment_config: Schedules to assemble.
        run_config: Configuration of the runtime environment.

    Returns:
        The assembled PulseQobjConfig.
    """
    qobj_config = run_config.to_dict()
    qobj_config.update(experiment_config)

    # Run config not needed in qobj config
    qobj_config.pop('meas_map', None)
    qobj_config.pop('qubit_lo_range', None)
    qobj_config.pop('meas_lo_range', None)

    # convert enums to serialized values
    meas_return = qobj_config.get('meas_return', 'avg')
    if isinstance(meas_return, qobj_utils.MeasReturnType):
        qobj_config['meas_return'] = meas_return.value

    meas_level = qobj_config.get('meas_level', 2)
    if isinstance(meas_level, qobj_utils.MeasLevel):
        qobj_config['meas_level'] = meas_level.value

    # convert lo frequencies to Hz
    qobj_config['qubit_lo_freq'] = [
        freq / 1e9 for freq in qobj_config['qubit_lo_freq']
    ]
    qobj_config['meas_lo_freq'] = [
        freq / 1e9 for freq in qobj_config['meas_lo_freq']
    ]

    # frequency sweep config
    schedule_los = qobj_config.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['qubit_lo_freq'] = [freq / 1e9 for freq in q_los]
        m_los = lo_converter.get_meas_los(lo_dict)
        if m_los:
            qobj_config['meas_lo_freq'] = [freq / 1e9 for freq in m_los]

    return qobj.PulseQobjConfig(**qobj_config)
Ejemplo n.º 13
0
 def test_circuit_with_bit_conditional_1(self):
     """Verify disassemble handles conditional on a single bit."""
     qr = QuantumRegister(2)
     cr = ClassicalRegister(2)
     qc = QuantumCircuit(qr, cr)
     qc.h(qr[0]).c_if(cr[1], True)
     qobj = assemble(qc)
     circuits, run_config_out, header = disassemble(qobj)
     run_config_out = RunConfig(**run_config_out)
     self.assertEqual(run_config_out.n_qubits, 2)
     self.assertEqual(run_config_out.memory_slots, 2)
     self.assertEqual(len(circuits), 1)
     self.assertEqual(circuits[0], qc)
     self.assertEqual({}, header)
Ejemplo n.º 14
0
 def test_circuit_with_simple_conditional(self):
     """Verify disassemble handles a simple conditional on the only bits."""
     qr = QuantumRegister(1)
     cr = ClassicalRegister(1)
     qc = QuantumCircuit(qr, cr)
     qc.h(qr[0]).c_if(cr, 1)
     qobj = assemble(qc)
     circuits, run_config_out, header = disassemble(qobj)
     run_config_out = RunConfig(**run_config_out)
     self.assertEqual(run_config_out.n_qubits, 1)
     self.assertEqual(run_config_out.memory_slots, 1)
     self.assertEqual(len(circuits), 1)
     self.assertEqual(circuits[0], qc)
     self.assertEqual({}, header)
Ejemplo n.º 15
0
    def test_disassemble_initialize(self):
        """Test disassembling a circuit with an initialize."""
        q = QuantumRegister(2, name="q")
        circ = QuantumCircuit(q, name="circ")
        circ.initialize([1 / np.sqrt(2), 0, 0, 1 / np.sqrt(2)], q[:])

        qobj = assemble(circ)
        circuits, run_config_out, header = disassemble(qobj)
        run_config_out = RunConfig(**run_config_out)
        self.assertEqual(run_config_out.n_qubits, 2)
        self.assertEqual(run_config_out.memory_slots, 0)
        self.assertEqual(len(circuits), 1)
        self.assertEqual(circuits[0], circ)
        self.assertEqual({}, header)
Ejemplo n.º 16
0
 def test_circuit_with_mcx(self):
     """Verify disassemble handles mcx gate - #6271."""
     qr = QuantumRegister(5)
     cr = ClassicalRegister(5)
     qc = QuantumCircuit(qr, cr)
     qc.mcx([0, 1, 2], 4)
     qobj = assemble(qc)
     circuits, run_config_out, header = disassemble(qobj)
     run_config_out = RunConfig(**run_config_out)
     self.assertEqual(run_config_out.n_qubits, 5)
     self.assertEqual(run_config_out.memory_slots, 5)
     self.assertEqual(len(circuits), 1)
     self.assertEqual(circuits[0], qc)
     self.assertEqual({}, header)
Ejemplo n.º 17
0
 def test_opaque_instruction(self):
     """Test the disassembler handles opaque instructions correctly."""
     opaque_inst = Instruction(name="my_inst", num_qubits=4, num_clbits=2, params=[0.5, 0.4])
     q = QuantumRegister(6, name="q")
     c = ClassicalRegister(4, name="c")
     circ = QuantumCircuit(q, c, name="circ")
     circ.append(opaque_inst, [q[0], q[2], q[5], q[3]], [c[3], c[0]])
     qobj = assemble(circ)
     circuits, run_config_out, header = disassemble(qobj)
     run_config_out = RunConfig(**run_config_out)
     self.assertEqual(run_config_out.n_qubits, 6)
     self.assertEqual(run_config_out.memory_slots, 4)
     self.assertEqual(len(circuits), 1)
     self.assertEqual(circuits[0], circ)
     self.assertEqual({}, header)
Ejemplo n.º 18
0
def _parse_circuit_args(parameter_binds, **run_config):
    """Build a circuit RunConfig replacing unset arguments with defaults derived from the `backend`.
    See `assemble` for more information on the required arguments.

    Returns:
        RunConfig: a run config, which is a standardized object that configures the qobj
            and determines the runtime environment.
    """
    parameter_binds = parameter_binds or []

    # create run configuration and populate
    run_config_dict = dict(parameter_binds=parameter_binds, **run_config)
    run_config = RunConfig(**{k: v for k, v in run_config_dict.items() if v is not None})

    return run_config
Ejemplo n.º 19
0
 def test_circuit_with_conditionals(self):
     """Verify disassemble sets conditionals correctly."""
     qr = QuantumRegister(2)
     cr1 = ClassicalRegister(1)
     cr2 = ClassicalRegister(2)
     qc = QuantumCircuit(qr, cr1, cr2)
     qc.measure(qr[0], cr1)  # Measure not required for a later conditional
     qc.measure(qr[1], cr2[1])  # Measure required for a later conditional
     qc.h(qr[1]).c_if(cr2, 3)
     qobj = assemble(qc)
     circuits, run_config_out, header = disassemble(qobj)
     run_config_out = RunConfig(**run_config_out)
     self.assertEqual(run_config_out.n_qubits, 2)
     self.assertEqual(run_config_out.memory_slots, 3)
     self.assertEqual(len(circuits), 1)
     self.assertEqual(circuits[0], qc)
     self.assertEqual({}, header)
Ejemplo n.º 20
0
    def test_disassemble_no_run_config(self):
        """Test disassembling with no run_config, relying on default."""
        qr = QuantumRegister(2, name="q")
        qc = ClassicalRegister(2, name="c")
        circ = QuantumCircuit(qr, qc, name="circ")
        circ.h(qr[0])
        circ.cx(qr[0], qr[1])
        circ.measure(qr, qc)

        qobj = assemble(circ)
        circuits, run_config_out, headers = disassemble(qobj)
        run_config_out = RunConfig(**run_config_out)
        self.assertEqual(run_config_out.n_qubits, 2)
        self.assertEqual(run_config_out.memory_slots, 2)
        self.assertEqual(len(circuits), 1)
        self.assertEqual(circuits[0], circ)
        self.assertEqual({}, headers)
Ejemplo n.º 21
0
 def test_disassemble_isometry(self):
     """Test disassembling a circuit with an isometry."""
     q = QuantumRegister(2, name="q")
     circ = QuantumCircuit(q, name="circ")
     circ.iso(qi.random_unitary(4).data, circ.qubits, [])
     qobj = assemble(circ)
     circuits, run_config_out, header = disassemble(qobj)
     run_config_out = RunConfig(**run_config_out)
     self.assertEqual(run_config_out.n_qubits, 2)
     self.assertEqual(run_config_out.memory_slots, 0)
     self.assertEqual(len(circuits), 1)
     # params array
     assert_allclose(circuits[0]._data[0][0].params[0], circ._data[0][0].params[0])
     # all other data
     self.assertEqual(circuits[0]._data[0][0].params[1:], circ._data[0][0].params[1:])
     self.assertEqual(circuits[0]._data[0][1:], circ._data[0][1:])
     self.assertEqual(circuits[0]._data[1:], circ._data[1:])
     self.assertEqual({}, header)
Ejemplo n.º 22
0
 def test_circuit_with_single_bit_conditions(self):
     """Verify disassemble handles a simple conditional on a single bit of a register."""
     # This circuit would fail to perfectly round-trip if 'cr' below had only one bit in it.
     # This is because the format of QasmQobj is insufficient to disambiguate single-bit
     # conditions from conditions on registers with only one bit. Since single-bit conditions are
     # mostly a hack for the QasmQobj format at all, `disassemble` always prefers to return the
     # register if it can.  It would also fail if registers overlap.
     qr = QuantumRegister(1)
     cr = ClassicalRegister(2)
     qc = QuantumCircuit(qr, cr)
     qc.h(qr[0]).c_if(cr[0], 1)
     qobj = assemble(qc)
     circuits, run_config_out, header = disassemble(qobj)
     run_config_out = RunConfig(**run_config_out)
     self.assertEqual(run_config_out.n_qubits, len(qr))
     self.assertEqual(run_config_out.memory_slots, len(cr))
     self.assertEqual(len(circuits), 1)
     self.assertEqual(circuits[0], qc)
     self.assertEqual({}, header)
Ejemplo n.º 23
0
    def test_disassemble_single_circuit(self):
        """Test assembling a single circuit.
        """
        qr = QuantumRegister(2, name='q')
        cr = ClassicalRegister(2, name='c')
        circ = QuantumCircuit(qr, cr, name='circ')
        circ.h(qr[0])
        circ.cx(qr[0], qr[1])
        circ.measure(qr, cr)

        qobj = assemble(circ, shots=2000, memory=True)
        circuits, run_config_out, headers = disassemble(qobj)
        run_config_out = RunConfig(**run_config_out)
        self.assertEqual(run_config_out.n_qubits, 2)
        self.assertEqual(run_config_out.memory_slots, 2)
        self.assertEqual(run_config_out.shots, 2000)
        self.assertEqual(run_config_out.memory, True)
        self.assertEqual(len(circuits), 1)
        self.assertEqual(circuits[0], circ)
        self.assertEqual({}, headers)
Ejemplo n.º 24
0
    def test_disassemble_multiple_schedules(self):
        """Test disassembling multiple schedules, all should have the same config.
        """
        d0 = pulse.DriveChannel(0)
        d1 = pulse.DriveChannel(1)
        with pulse.build(self.backend) as sched0:
            with pulse.align_right():
                pulse.play(pulse.library.Constant(10, 1.0), d0)
                pulse.set_phase(1.0, d0)
                pulse.shift_phase(3.11, d0)
                pulse.set_frequency(1e9, d0)
                pulse.shift_frequency(1e7, d0)
                pulse.delay(20, d0)
                pulse.delay(10, d1)
                pulse.play(pulse.library.Constant(8, 0.1), d1)
                pulse.measure_all()

        with pulse.build(self.backend) as sched1:
            with pulse.align_right():
                pulse.play(pulse.library.Constant(8, 0.1), d0)
                pulse.play(pulse.library.Waveform([0., 1.]), d1)
                pulse.set_phase(1.1, d0)
                pulse.shift_phase(3.5, d0)
                pulse.set_frequency(2e9, d0)
                pulse.shift_frequency(3e7, d1)
                pulse.delay(20, d1)
                pulse.delay(10, d0)
                pulse.play(pulse.library.Constant(8, 0.4), d1)
                pulse.measure_all()

        qobj = assemble([sched0, sched1], backend=self.backend, shots=2000)
        scheds, run_config_out, _ = disassemble(qobj)
        run_config_out = RunConfig(**run_config_out)
        self.assertEqual(run_config_out.memory_slots, 2)
        self.assertEqual(run_config_out.shots, 2000)
        self.assertEqual(run_config_out.memory, False)
        self.assertEqual(len(scheds), 2)
        self.assertEqual(scheds[0], sched0)
        self.assertEqual(scheds[1], sched1)
Ejemplo n.º 25
0
    def test_multiple_conditionals_multiple_registers(self):
        """Verify disassemble handles multiple conditionals and registers."""
        qr = QuantumRegister(3)
        cr1 = ClassicalRegister(3)
        cr2 = ClassicalRegister(5)
        cr3 = ClassicalRegister(6)
        cr4 = ClassicalRegister(1)

        qc = QuantumCircuit(qr, cr1, cr2, cr3, cr4)
        qc.x(qr[1])
        qc.h(qr)
        qc.cx(qr[1], qr[0]).c_if(cr3, 14)
        qc.ccx(qr[0], qr[2], qr[1]).c_if(cr4, 1)
        qc.h(qr).c_if(cr1, 3)
        qobj = assemble(qc)
        circuits, run_config_out, header = disassemble(qobj)
        run_config_out = RunConfig(**run_config_out)
        self.assertEqual(run_config_out.n_qubits, 3)
        self.assertEqual(run_config_out.memory_slots, 15)
        self.assertEqual(len(circuits), 1)
        self.assertEqual(circuits[0], qc)
        self.assertEqual({}, header)
def _assemble_experiments(
    schedules: List[Union[pulse.ScheduleComponent,
                          Tuple[int, pulse.ScheduleComponent]]],
    lo_converter: converters.LoConfigConverter, run_config: RunConfig
) -> Tuple[List[qobj.PulseQobjExperiment], Dict[str, Any]]:
    """Assembles a list of schedules into PulseQobjExperiments, and returns related metadata that
    will be assembled into the Qobj configuration.

    Args:
        schedules: Schedules to assemble.
        lo_converter: The configured frequency converter and validator.
        run_config: Configuration of the runtime environment.

    Returns:
        The list of assembled experiments, and the dictionary of related experiment config.

    Raises:
        QiskitError: when frequency settings are not compatible with the experiments.
    """
    freq_configs = [
        lo_converter(lo_dict)
        for lo_dict in getattr(run_config, 'schedule_los', [])
    ]

    if len(schedules) > 1 and len(freq_configs) not in [0, 1, len(schedules)]:
        raise QiskitError(
            'Invalid frequency setting is specified. If the frequency is specified, '
            'it should be configured the same for all schedules, configured for each '
            'schedule, or a list of frequencies should be provided for a single '
            'frequency sweep schedule.')

    instruction_converter = getattr(run_config, 'instruction_converter',
                                    converters.InstructionToQobjConverter)
    instruction_converter = instruction_converter(qobj.PulseQobjInstruction,
                                                  **run_config.to_dict())

    schedules = [
        sched if isinstance(sched, pulse.Schedule) else pulse.Schedule(sched)
        for sched in schedules
    ]
    compressed_schedules = transforms.compress_pulses(schedules)

    user_pulselib = {}
    experiments = []
    for idx, schedule in enumerate(compressed_schedules):
        qobj_instructions, max_memory_slot = _assemble_instructions(
            schedule, instruction_converter, run_config, user_pulselib)

        # TODO: add other experimental header items (see circuit assembler)
        qobj_experiment_header = qobj.QobjExperimentHeader(
            memory_slots=max_memory_slot + 1,  # Memory slots are 0 indexed
            name=schedule.name or 'Experiment-%d' % idx)

        experiment = qobj.PulseQobjExperiment(header=qobj_experiment_header,
                                              instructions=qobj_instructions)
        if freq_configs:
            # This handles the cases where one frequency setting applies to all experiments and
            # where each experiment has a different frequency
            freq_idx = idx if len(freq_configs) != 1 else 0
            experiment.config = freq_configs[freq_idx]

        experiments.append(experiment)

    # Frequency sweep
    if freq_configs and len(experiments) == 1:
        experiment = experiments[0]
        experiments = []
        for freq_config in freq_configs:
            experiments.append(
                qobj.PulseQobjExperiment(header=experiment.header,
                                         instructions=experiment.instructions,
                                         config=freq_config))

    # Top level Qobj configuration
    experiment_config = {
        'pulse_library': [
            qobj.PulseLibraryItem(name=name, samples=samples)
            for name, samples in user_pulselib.items()
        ],
        'memory_slots':
        max([exp.header.memory_slots for exp in experiments])
    }

    return experiments, experiment_config
Ejemplo n.º 27
0
    def __init__(self,
                 backend,
                 shots=1024,
                 seed_simulator=None,
                 max_credits=10,
                 basis_gates=None,
                 coupling_map=None,
                 initial_layout=None,
                 pass_manager=None,
                 seed_transpiler=None,
                 backend_options=None,
                 noise_model=None,
                 timeout=None,
                 wait=5,
                 circuit_caching=True,
                 cache_file=None,
                 skip_qobj_deepcopy=True,
                 skip_qobj_validation=True,
                 measurement_error_mitigation_cls=None,
                 cals_matrix_refresh_period=30):
        """Constructor.

        Args:
            backend (BaseBackend): instance of selected backend
            shots (int, optional): number of repetitions of each circuit, for sampling
            seed_simulator (int, optional): random seed for simulators
            max_credits (int, optional): maximum credits to use
            basis_gates (list[str], optional): list of basis gate names supported by the
                                                target. Default: ['u1','u2','u3','cx','id']
            coupling_map (list[list]): coupling map (perhaps custom) to target in mapping
            initial_layout (dict, optional): initial layout of qubits in mapping
            pass_manager (PassManager, optional): pass manager to handle how to compile the circuits
            seed_transpiler (int, optional): the random seed for circuit mapper
            backend_options (dict, optional): all running options for backend, please refer to the provider.
            noise_model (qiskit.provider.aer.noise.noise_model.NoiseModel, optional): noise model for simulator
            timeout (float, optional): seconds to wait for job. If None, wait indefinitely.
            wait (float, optional): seconds between queries to result
            circuit_caching (bool, optional): USe CircuitCache when calling compile_and_run_circuits
            cache_file(str, optional): filename into which to store the cache as a pickle file
            skip_qobj_deepcopy (bool, optional): Reuses the same qobj object over and over to avoid deepcopying
            skip_qobj_validation (bool, optional): Bypass Qobj validation to decrease submission time
            measurement_error_mitigation_cls (callable, optional): the approach to mitigate measurement error,
                                                                CompleteMeasFitter or TensoredMeasFitter
            cals_matrix_refresh_period (int): how long to refresh the calibration matrix in measurement mitigation,
                                                  unit in minutes
        """
        self._backend = backend
        # setup run config
        run_config = RunConfig(shots=shots, max_credits=max_credits)
        if seed_simulator:
            run_config.seed_simulator = seed_simulator

        if getattr(run_config, 'shots', None) is not None:
            if self.is_statevector and run_config.shots != 1:
                logger.info(
                    "statevector backend only works with shot=1, change "
                    "shots from {} to 1.".format(run_config.shots))
                run_config.shots = 1

        self._run_config = run_config

        # setup backend config
        basis_gates = basis_gates or backend.configuration().basis_gates
        coupling_map = coupling_map or getattr(backend.configuration(),
                                               'coupling_map', None)
        self._backend_config = {
            'basis_gates': basis_gates,
            'coupling_map': coupling_map
        }

        # setup noise config
        noise_config = None
        if noise_model is not None:
            if is_aer_provider(self._backend):
                if not self.is_statevector:
                    noise_config = noise_model
                else:
                    logger.info(
                        "The noise model can be only used with Aer qasm simulator. "
                        "Change it to None.")
            else:
                logger.info(
                    "The noise model can be only used with Qiskit Aer. "
                    "Please install it.")
        self._noise_config = {} if noise_config is None else {
            'noise_model': noise_config
        }

        # setup compile config
        if initial_layout is not None and not isinstance(
                initial_layout, Layout):
            initial_layout = Layout(initial_layout)
        self._compile_config = {
            'pass_manager': pass_manager,
            'initial_layout': initial_layout,
            'seed_transpiler': seed_transpiler
        }

        # setup job config
        self._qjob_config = {'timeout': timeout} if self.is_local \
            else {'timeout': timeout, 'wait': wait}

        # setup backend options for run
        self._backend_options = {}
        if is_ibmq_provider(self._backend):
            logger.info(
                "backend_options can not used with the backends in IBMQ provider."
            )
        else:
            self._backend_options = {} if backend_options is None \
                else {'backend_options': backend_options}

        self._shared_circuits = False
        self._circuit_summary = False
        self._circuit_cache = CircuitCache(
            skip_qobj_deepcopy=skip_qobj_deepcopy,
            cache_file=cache_file) if circuit_caching else None
        self._skip_qobj_validation = skip_qobj_validation

        self._measurement_error_mitigation_cls = None
        if self.is_statevector:
            if measurement_error_mitigation_cls is not None:
                logger.info(
                    "Measurement error mitigation does not work with statevector simulation, disable it."
                )
        else:
            self._measurement_error_mitigation_cls = measurement_error_mitigation_cls
        self._measurement_error_mitigation_fitter = None
        self._measurement_error_mitigation_method = 'least_squares'
        self._cals_matrix_refresh_period = cals_matrix_refresh_period
        self._prev_timestamp = 0

        if self._measurement_error_mitigation_cls is not None:
            logger.info(
                "The measurement error mitigation is enable. "
                "It will automatically submit an additional job to help calibrate the result of other jobs. "
                "The current approach will submit a job with 2^N circuits to build the calibration matrix, "
                "where N is the number of measured qubits. "
                "Furthermore, Aqua will re-use the calibration matrix for {} minutes "
                "and re-build it after that.".format(
                    self._cals_matrix_refresh_period))

        logger.info(self)
Ejemplo n.º 28
0
def _parse_pulse_args(backend, qubit_lo_freq, meas_lo_freq, qubit_lo_range,
                      meas_lo_range, schedule_los, meas_level, meas_return,
                      meas_map, memory_slot_size, rep_time, **run_config):
    """Build a pulse RunConfig replacing unset arguments with defaults derived from the `backend`.
    See `assemble` for more information on the required arguments.

    Returns:
        RunConfig: a run config, which is a standardized object that configures the qobj
            and determines the runtime environment.
    """
    # grab relevant info from backend if it exists
    backend_config = None
    backend_default = None
    if backend:
        backend_config = backend.configuration()
        # TODO : Remove usage of config.defaults when backend.defaults() is updated.
        try:
            backend_default = backend.defaults()
        except (ModelValidationError, AttributeError):
            from collections import namedtuple
            backend_config_defaults = getattr(backend_config, 'defaults', {})
            BackendDefault = namedtuple('BackendDefault',
                                        ('qubit_freq_est', 'meas_freq_est'))
            backend_default = BackendDefault(
                qubit_freq_est=backend_config_defaults.get('qubit_freq_est'),
                meas_freq_est=backend_config_defaults.get('meas_freq_est'))

    meas_map = meas_map or getattr(backend_config, 'meas_map', None)

    schedule_los = schedule_los or []
    if isinstance(schedule_los, (LoConfig, dict)):
        schedule_los = [schedule_los]

    # Convert to LoConfig if lo configuration supplied as dictionary
    schedule_los = [
        lo_config if isinstance(lo_config, LoConfig) else LoConfig(lo_config)
        for lo_config in schedule_los
    ]

    qubit_lo_freq = qubit_lo_freq or getattr(backend_default, 'qubit_freq_est',
                                             None)
    meas_lo_freq = meas_lo_freq or getattr(backend_default, 'meas_freq_est',
                                           None)

    qubit_lo_range = qubit_lo_range or getattr(backend_config,
                                               'qubit_lo_range', None)
    meas_lo_range = meas_lo_range or getattr(backend_config, 'meas_lo_range',
                                             None)

    rep_time = rep_time or getattr(backend_config, 'rep_times', None)
    if isinstance(rep_time, list):
        rep_time = rep_time[0]

    # create run configuration and populate
    run_config_dict = dict(qubit_lo_freq=qubit_lo_freq,
                           meas_lo_freq=meas_lo_freq,
                           qubit_lo_range=qubit_lo_range,
                           meas_lo_range=meas_lo_range,
                           schedule_los=schedule_los,
                           meas_level=meas_level,
                           meas_return=meas_return,
                           meas_map=meas_map,
                           memory_slot_size=memory_slot_size,
                           rep_time=rep_time,
                           **run_config)
    run_config = RunConfig(
        **{k: v
           for k, v in run_config_dict.items() if v is not None})

    return run_config
Ejemplo n.º 29
0
    def __init__(
        self,
        backend,
        # run config
        shots: Optional[int] = None,
        seed_simulator: Optional[int] = None,
        max_credits: int = 10,
        # backend properties
        basis_gates: Optional[List[str]] = None,
        coupling_map=None,
        # transpile
        initial_layout=None,
        pass_manager=None,
        bound_pass_manager=None,
        seed_transpiler: Optional[int] = None,
        optimization_level: Optional[int] = None,
        # simulation
        backend_options: Optional[Dict] = None,
        noise_model=None,
        # job
        timeout: Optional[float] = None,
        wait: float = 5.0,
        # others
        skip_qobj_validation: bool = True,
        measurement_error_mitigation_cls: Optional[Callable] = None,
        cals_matrix_refresh_period: int = 30,
        measurement_error_mitigation_shots: Optional[int] = None,
        job_callback: Optional[Callable] = None,
        mit_pattern: Optional[List[List[int]]] = None,
        max_job_retries: int = 50,
    ) -> None:
        """
        Quantum Instance holds a Qiskit Terra backend as well as configuration for circuit
        transpilation and execution. When provided to an Aqua algorithm the algorithm will
        execute the circuits it needs to run using the instance.

        Args:
            backend (Union['Backend', 'BaseBackend']): Instance of selected backend
            shots: Number of repetitions of each circuit, for sampling. If None, the shots are
                extracted from the backend. If the backend has none set, the default is 1024.
            seed_simulator: Random seed for simulators
            max_credits: Maximum credits to use
            basis_gates: List of basis gate names supported by the
                target. Defaults to basis gates of the backend.
            coupling_map (Optional[Union['CouplingMap', List[List]]]):
                Coupling map (perhaps custom) to target in mapping
            initial_layout (Optional[Union['Layout', Dict, List]]):
                Initial layout of qubits in mapping
            pass_manager (Optional['PassManager']): Pass manager to handle how to compile the circuits.
                To run only this pass manager and not the ``bound_pass_manager``, call the
                :meth:`~qiskit.utils.QuantumInstance.transpile` method with the argument
                ``pass_manager=quantum_instance.unbound_pass_manager``.
            bound_pass_manager (Optional['PassManager']): A second pass manager to apply on bound
                circuits only, that is, circuits without any free parameters. To only run this pass
                manager and not ``pass_manager`` call the
                :meth:`~qiskit.utils.QuantumInstance.transpile` method with the argument
                ``pass_manager=quantum_instance.bound_pass_manager``.
                manager should also be run.
            seed_transpiler: The random seed for circuit mapper
            optimization_level: How much optimization to perform on the circuits.
                Higher levels generate more optimized circuits, at the expense of longer
                transpilation time.
            backend_options: All running options for backend, please refer
                to the provider of the backend for information as to what options it supports.
            noise_model (Optional['NoiseModel']): noise model for simulator
            timeout: Seconds to wait for job. If None, wait indefinitely.
            wait: Seconds between queries for job result
            skip_qobj_validation: Bypass Qobj validation to decrease circuit
                processing time during submission to backend.
            measurement_error_mitigation_cls: The approach to mitigate
                measurement errors. The classes :class:`~qiskit.utils.mitigation.CompleteMeasFitter`
                or :class:`~qiskit.utils.mitigation.TensoredMeasFitter` from the
                :mod:`qiskit.utils.mitigation` module can be used here as exact values, not
                instances. ``TensoredMeasFitter`` doesn't support the ``subset_fitter`` method.
            cals_matrix_refresh_period: How often to refresh the calibration
                matrix in measurement mitigation. in minutes
            measurement_error_mitigation_shots: The number of shots number for
                building calibration matrix. If None, the main `shots` parameter value is used.
            job_callback: Optional user supplied callback which can be used
                to monitor job progress as jobs are submitted for processing by an Aqua algorithm.
                The callback is provided the following arguments: `job_id, job_status,
                queue_position, job`
            mit_pattern: Qubits on which to perform the TensoredMeasFitter
                measurement correction, divided to groups according to tensors.
                If `None` and `qr` is given then assumed to be performed over the entire
                `qr` as one group (default `None`).
            max_job_retries(int): positive non-zero number of trials for the job set (-1 for
                infinite trials) (default: 50)

        Raises:
            QiskitError: the shots exceeds the maximum number of shots
            QiskitError: set noise model but the backend does not support that
            QiskitError: set backend_options but the backend does not support that
        """
        self._backend = backend
        self._backend_interface_version = _get_backend_interface_version(self._backend)
        self._pass_manager = pass_manager
        self._bound_pass_manager = bound_pass_manager

        # if the shots are none, try to get them from the backend
        if shots is None:
            from qiskit.providers.basebackend import BaseBackend  # pylint: disable=cyclic-import
            from qiskit.providers.backend import Backend  # pylint: disable=cyclic-import

            if isinstance(backend, (BaseBackend, Backend)):
                if hasattr(backend, "options"):  # should always be true for V1
                    backend_shots = backend.options.get("shots", 1024)
                    if shots != backend_shots:
                        logger.info(
                            "Overwriting the number of shots in the quantum instance with "
                            "the settings from the backend."
                        )
                    shots = backend_shots

        # safeguard if shots are still not set
        if shots is None:
            shots = 1024

        # pylint: disable=cyclic-import
        from qiskit.assembler.run_config import RunConfig

        run_config = RunConfig(shots=shots, max_credits=max_credits)
        if seed_simulator is not None:
            run_config.seed_simulator = seed_simulator

        self._run_config = run_config

        # setup backend config
        if self._backend_interface_version <= 1:
            basis_gates = basis_gates or backend.configuration().basis_gates
            coupling_map = coupling_map or getattr(backend.configuration(), "coupling_map", None)
            self._backend_config = {"basis_gates": basis_gates, "coupling_map": coupling_map}
        else:
            self._backend_config = {}

        # setup compile config
        self._compile_config = {
            "initial_layout": initial_layout,
            "seed_transpiler": seed_transpiler,
            "optimization_level": optimization_level,
        }

        # setup job config
        self._qjob_config = (
            {"timeout": timeout} if self.is_local else {"timeout": timeout, "wait": wait}
        )

        # setup noise config
        self._noise_config = {}
        if noise_model is not None:
            if is_simulator_backend(self._backend) and not is_basicaer_provider(self._backend):
                self._noise_config = {"noise_model": noise_model}
            else:
                raise QiskitError(
                    "The noise model is not supported "
                    "on the selected backend {} ({}) "
                    "only certain backends, such as Aer qasm simulator "
                    "support noise.".format(self.backend_name, _get_backend_provider(self._backend))
                )

        # setup backend options for run
        self._backend_options = {}
        if backend_options is not None:
            if support_backend_options(self._backend):
                self._backend_options = {"backend_options": backend_options}
            else:
                raise QiskitError(
                    "backend_options can not used with the backends in IBMQ provider."
                )

        # setup measurement error mitigation
        self._meas_error_mitigation_cls = None
        if self.is_statevector:
            if measurement_error_mitigation_cls is not None:
                raise QiskitError(
                    "Measurement error mitigation does not work with the statevector simulation."
                )
        else:
            self._meas_error_mitigation_cls = measurement_error_mitigation_cls
        self._meas_error_mitigation_fitters: Dict[str, Tuple[np.ndarray, float]] = {}
        # TODO: support different fitting method in error mitigation?
        self._meas_error_mitigation_method = "least_squares"
        self._cals_matrix_refresh_period = cals_matrix_refresh_period
        self._meas_error_mitigation_shots = measurement_error_mitigation_shots
        self._mit_pattern = mit_pattern

        if self._meas_error_mitigation_cls is not None:
            logger.info(
                "The measurement error mitigation is enabled. "
                "It will automatically submit an additional job to help "
                "calibrate the result of other jobs. "
                "The current approach will submit a job with 2^N circuits "
                "to build the calibration matrix, "
                "where N is the number of measured qubits. "
                "Furthermore, Aqua will re-use the calibration matrix for %s minutes "
                "and re-build it after that.",
                self._cals_matrix_refresh_period,
            )

        # setup others
        if is_ibmq_provider(self._backend):
            if skip_qobj_validation:
                logger.info(
                    "skip_qobj_validation was set True but this setting is not "
                    "supported by IBMQ provider and has been ignored."
                )
                skip_qobj_validation = False
        self._skip_qobj_validation = skip_qobj_validation
        self._circuit_summary = False
        self._job_callback = job_callback
        self._time_taken = 0.0
        self._max_job_retries = max_job_retries
        logger.info(self)
Ejemplo n.º 30
0
def _parse_pulse_args(backend, qubit_lo_freq, meas_lo_freq, qubit_lo_range,
                      meas_lo_range, schedule_los, meas_level, meas_return,
                      meas_map, memory_slot_size, rep_time, parametric_pulses,
                      **run_config):
    """Build a pulse RunConfig replacing unset arguments with defaults derived from the `backend`.
    See `assemble` for more information on the required arguments.

    Returns:
        RunConfig: a run config, which is a standardized object that configures the qobj
            and determines the runtime environment.
    Raises:
        SchemaValidationError: If the given meas_level is not allowed for the given `backend`.
    """
    # grab relevant info from backend if it exists
    backend_config = None
    backend_default = None
    if backend:
        backend_default = backend.defaults()
        backend_config = backend.configuration()

        if meas_level not in getattr(backend_config, 'meas_levels',
                                     [MeasLevel.CLASSIFIED]):
            raise SchemaValidationError((
                'meas_level = {} not supported for backend {}, only {} is supported'
            ).format(meas_level, backend_config.backend_name,
                     backend_config.meas_levels))

    meas_map = meas_map or getattr(backend_config, 'meas_map', None)

    schedule_los = schedule_los or []
    if isinstance(schedule_los, (LoConfig, dict)):
        schedule_los = [schedule_los]

    # Convert to LoConfig if LO configuration supplied as dictionary
    schedule_los = [
        lo_config if isinstance(lo_config, LoConfig) else LoConfig(lo_config)
        for lo_config in schedule_los
    ]

    if not qubit_lo_freq and hasattr(backend_default, 'qubit_freq_est'):
        qubit_lo_freq = backend_default.qubit_freq_est
    if not meas_lo_freq and hasattr(backend_default, 'meas_freq_est'):
        meas_lo_freq = backend_default.meas_freq_est

    qubit_lo_range = qubit_lo_range or getattr(backend_config,
                                               'qubit_lo_range', None)
    meas_lo_range = meas_lo_range or getattr(backend_config, 'meas_lo_range',
                                             None)

    dynamic_reprate_enabled = getattr(backend_config,
                                      'dynamic_reprate_enabled', False)

    rep_time = rep_time or getattr(backend_config, 'rep_times', None)
    if rep_time:
        if dynamic_reprate_enabled:
            warnings.warn(
                "Dynamic rep rates are supported on this backend. 'rep_delay' will be "
                "used instead of 'rep_time'.", RuntimeWarning)
        if isinstance(rep_time, list):
            rep_time = rep_time[0]
        rep_time = int(rep_time * 1e6)  # convert sec to μs

    parametric_pulses = parametric_pulses or getattr(backend_config,
                                                     'parametric_pulses', [])

    # create run configuration and populate
    run_config_dict = dict(qubit_lo_freq=qubit_lo_freq,
                           meas_lo_freq=meas_lo_freq,
                           qubit_lo_range=qubit_lo_range,
                           meas_lo_range=meas_lo_range,
                           schedule_los=schedule_los,
                           meas_level=meas_level,
                           meas_return=meas_return,
                           meas_map=meas_map,
                           memory_slot_size=memory_slot_size,
                           rep_time=rep_time,
                           parametric_pulses=parametric_pulses,
                           **run_config)
    run_config = RunConfig(
        **{k: v
           for k, v in run_config_dict.items() if v is not None})

    return run_config