def create_from_backend(cls, backend: BaseBackend): """Initialize a class with backend information provided by provider. Args: backend: Backend object. Returns: OpenPulseBackendInfo: New configured instance. """ configuration = backend.configuration() defaults = backend.defaults() # load name name = backend.name() # load cycle time dt = configuration.dt # load frequencies chan_freqs = dict() chan_freqs.update({ pulse.DriveChannel(qind): freq for qind, freq in enumerate(defaults.qubit_freq_est) }) chan_freqs.update({ pulse.MeasureChannel(qind): freq for qind, freq in enumerate(defaults.meas_freq_est) }) for qind, u_lo_mappers in enumerate(configuration.u_channel_lo): temp_val = .0 + .0j for u_lo_mapper in u_lo_mappers: temp_val += defaults.qubit_freq_est[ u_lo_mapper.q] * u_lo_mapper.scale chan_freqs[pulse.ControlChannel(qind)] = temp_val.real # load qubit channel mapping qubit_channel_map = defaultdict(list) for qind in range(configuration.n_qubits): qubit_channel_map[qind].append(configuration.drive(qubit=qind)) qubit_channel_map[qind].append(configuration.measure(qubit=qind)) for tind in range(configuration.n_qubits): try: qubit_channel_map[qind].extend( configuration.control(qubits=(qind, tind))) except BackendConfigurationError: pass return OpenPulseBackendInfo(name=name, dt=dt, channel_frequency_map=chan_freqs, qubit_channel_map=qubit_channel_map)
def create_rb_experiment(rb_seed_circs: List[QuantumCircuit], control: int, target: int, backend: BaseBackend, cnot_sched_control_target: Schedule = None, cnot_sched_target_control: Schedule = None, shots: int = 1024)\ -> Tuple[List[PulseQobj], List[List[QuantumCircuit]]]: """ Create randomized benchmark qobj. Args: rb_seed_circs: RB circuits. control: index of control qubit. target: index of target qubit. backend: Target quantum system. cnot_sched_control_target: Schedule of CX(control, target) cnot_sched_target_control: Schedule of CX(target, control) shots: Number of shots. """ back_defaults = backend.defaults() rb_inst_map = deepcopy(back_defaults.instruction_schedule_map) # update circuit instruction map if cnot_sched_control_target is not None and cnot_sched_target_control is not None: rb_inst_map.add('cx', qubits=(control, target), schedule=cnot_sched_control_target) rb_inst_map.add('cx', qubits=(target, control), schedule=cnot_sched_target_control) pulse_qobjs = [] transpiled_circs = [] for rb_seed_circ in rb_seed_circs: # transpile rb_seed_circ_transpiled = qiskit.transpile(rb_seed_circ, backend, optimization_level=0) transpiled_circs.append(rb_seed_circ_transpiled) # schedule rb_seed_sched = qiskit.schedule(rb_seed_circ_transpiled, backend, inst_map=rb_inst_map) # create pulse qobj pulse_qobjs.append( qiskit.assemble(rb_seed_sched, backend, meas_level=2, shots=shots)) return pulse_qobjs, transpiled_circs
def from_backend(cls, backend: BaseBackend): """Construct an :class:`InstructionDurations` object from the backend. Args: backend: backend from which durations (gate lengths) and dt are extracted. Returns: InstructionDurations: The InstructionDurations constructed from backend. Raises: TranspilerError: If dt and dtm is different in the backend. """ # All durations in seconds in gate_length instruction_durations = [] for gate, insts in backend.properties()._gates.items(): for qubits, props in insts.items(): if 'gate_length' in props: gate_length = props['gate_length'][ 0] # Throw away datetime at index 1 instruction_durations.append( (gate, qubits, gate_length, 's')) try: dt = backend.configuration().dt # pylint: disable=invalid-name except AttributeError: dt = None # TODO: backend.properties() should tell us durations of measurements # TODO: Remove the following lines after that try: dtm = backend.configuration().dtm if dtm != dt: raise TranspilerError("dtm != dt case is not supported.") inst_map = backend.defaults().instruction_schedule_map all_qubits = tuple(range(backend.configuration().num_qubits)) meas_duration = inst_map.get('measure', all_qubits).duration for q in all_qubits: instruction_durations.append( ('measure', [q], meas_duration, 'dt')) except AttributeError: pass return InstructionDurations(instruction_durations, dt=dt)
def create_qpt_experiment(target_circuits: List[QuantumCircuit], control: int, target: int, backend: BaseBackend, mit_readout: bool = True, inst_map: InstructionScheduleMap = None, basis_gate: List[str] = None, sanity_check: bool = False, shots: int = 2048, return_schedule=False)\ -> Tuple[Union[PulseQobj, Schedule], List[List[QuantumCircuit]], List[str]]: """ Create circuits and schedules for QPT. Args: target_circuits: List of target circuits for QPT experiment. control: index of control qubit. target: index of target qubit. backend: Target quantum system. mit_readout: If use readout mitigation. inst_map: instruction mapping object. basis_gate: basis gates. sanity_check: check memory slot mapping of generated qobj. shots: Number of shots. return_schedule: set ``True`` when return schedule object instead of qobj. Returns: Qobj, Schedules, Quantum circuits, Measurement labels Additional Information: Bit ordering is little endian as a convention of computational science community, as the rest of qiskit does. When you measure the CR process tomography of q0 and q1, you will observe XZ (ZX) interaction when q0 (q1) is control qubit. """ qubits = sorted([control, target]) back_config = backend.configuration() back_defaults = backend.defaults() if inst_map is None: inst_map = back_defaults.circuit_instruction_map if basis_gate is None: basis_gate = back_config.basis_gates if isinstance(target_circuits, QuantumCircuit): target_circuits = [target_circuits] exp_circs = [] # create the measurement circuits for error mitigation, optional qr = target_circuits[0].qregs[0] if mit_readout: meas_circs, meas_labels = mit.complete_meas_cal(qubit_list=qubits, qr=qr, circlabel='mcal') exp_circs.extend(meas_circs) else: meas_labels = [] # create qpt circuit qpt_qcs_list = [] for target_circuit in target_circuits: # extract quantum registers from target circuit qr = target_circuit.qregs[0] qr0 = qr[qubits[0]] qr1 = qr[qubits[1]] qpt_qcs = tomo.process_tomography_circuits(target_circuit, measured_qubits=[qr0, qr1]) qpt_qcs_list.append(qpt_qcs) exp_circs.extend(qpt_qcs) # transpile exp_circs = qiskit.transpile(exp_circs, backend, basis_gates=basis_gate) # schedule with measure alignment exp_scheds = align_measures(qiskit.schedule(exp_circs, backend=backend, inst_map=inst_map), inst_map=inst_map) if return_schedule: return exp_scheds, qpt_qcs_list, meas_labels # assemble pulse qobj qobj = qiskit.assemble(exp_scheds, backend=backend, meas_level=2, shots=shots) # sanity check if sanity_check: for experiment in qobj.experiments: for inst in experiment.instructions: if inst.name == 'acquire': memory_slot_map = inst.memory_slot if memory_slot_map[qubits[0]] != __reserved_registers[0] or \ memory_slot_map[qubits[0]] != __reserved_registers[1]: warnings.warn('Wrong memory slots are assigned. ' 'QPT fitter may return invalid result.') assert len(qobj.experiments) <= back_config.max_experiments return qobj, qpt_qcs_list, meas_labels