def test_error_multi_acquire(self): """Test that an error is raised if multiple acquires occur on the same channel.""" acquire = pulse.Acquire(5) sched = pulse.Schedule(name='fake_experiment') sched = sched.insert(0, self.short_pulse(self.device.drives[0])) sched = sched.insert( 4, acquire(self.device.acquires[0], self.device.memoryslots[0])) sched = sched.insert( 10, acquire(self.device.acquires[0], self.device.memoryslots[0])) with self.assertRaises(PulseError): align_measures([sched], self.cmd_def)
def test_error_post_acquire_pulse(self): """Test that an error is raised if a pulse occurs on a channel after an acquire.""" sched = pulse.Schedule(name='fake_experiment') sched = sched.insert(0, Play(self.short_pulse, self.config.drive(0))) sched = sched.insert(4, Acquire(5, self.config.acquire(0), MemorySlot(0))) # No error with separate channel sched = sched.insert(10, Play(self.short_pulse, self.config.drive(1))) align_measures([sched], self.inst_map) sched = sched.insert(10, Play(self.short_pulse, self.config.drive(0))) with self.assertRaises(PulseError): align_measures([sched], self.inst_map)
def test_error_post_acquire_pulse(self): """Test that an error is raised if a pulse occurs on a channel after an acquire.""" acquire = pulse.Acquire(5) sched = pulse.Schedule(name='fake_experiment') sched = sched.insert(0, self.short_pulse(self.device.drives[0])) sched = sched.insert( 4, acquire(self.device.acquires[0], self.device.memoryslots[0])) # No error with separate channel sched = sched.insert(10, self.short_pulse(self.device.drives[1])) align_measures([sched], self.cmd_def) sched = sched.insert(10, self.short_pulse(self.device.drives[0])) with self.assertRaises(PulseError): align_measures([sched], self.cmd_def)
def test_multi_acquire(self): """Test that an error is raised if multiple acquires occur on the same channel.""" sched = pulse.Schedule(name='fake_experiment') sched = sched.insert(0, Play(self.short_pulse, self.config.drive(0))) sched = sched.insert(4, Acquire(5, self.config.acquire(0), MemorySlot(0))) sched = sched.insert(10, Acquire(5, self.config.acquire(0), MemorySlot(0))) with self.assertRaises(PulseError): align_measures([sched], self.inst_map) # Test for measure channel sched = pulse.Schedule(name='fake_experiment') sched = sched.insert(10, Play(self.short_pulse, self.config.measure(0))) sched = sched.insert(30, Play(self.short_pulse, self.config.measure(0))) with self.assertRaises(PulseError): align_measures([sched], self.inst_map) # Test both using inst_map sched = pulse.Schedule() sched += self.inst_map.get('measure', (0, 1)) align_measures([sched], align_time=50) sched += self.inst_map.get('measure', (0, 1)) with self.assertRaises(PulseError): align_measures([sched], align_time=50)
def test_multi_acquire(self): """Test that an error is raised if multiple acquires occur on the same channel.""" acquire = pulse.Acquire(5) sched = pulse.Schedule(name='fake_experiment') sched = sched.insert(0, self.short_pulse(self.device.drives[0])) sched = sched.insert( 4, acquire(self.device.acquires[0], self.device.memoryslots[0])) sched = sched.insert( 10, acquire(self.device.acquires[0], self.device.memoryslots[0])) with self.assertRaises(PulseError): align_measures([sched], self.cmd_def) # Test for measure channel sched = pulse.Schedule(name='fake_experiment') sched = sched.insert(10, self.short_pulse(self.device.measures[0])) sched = sched.insert(30, self.short_pulse(self.device.measures[0])) with self.assertRaises(PulseError): align_measures([sched], self.cmd_def) # Test both using cmd_def sched = pulse.Schedule() sched += self.cmd_def.get('measure', (0, 1)) align_measures([sched], align_time=50) sched += self.cmd_def.get('measure', (0, 1)) with self.assertRaises(PulseError): align_measures([sched], align_time=50)
def test_align_post_u3(self): """Test that acquires are scheduled no sooner than the duration of the longest X gate. """ acquire = pulse.Acquire(5) sched = pulse.Schedule(name='fake_experiment') sched = sched.insert(0, self.short_pulse(self.config.drive(0))) sched = sched.insert(1, acquire(self.config.acquire(0), MemorySlot(0))) sched = align_measures([sched], self.cmd_def)[0] for time, inst in sched.instructions: if isinstance(inst, AcquireInstruction): self.assertEqual(time, 4) sched = align_measures([sched], self.cmd_def, max_calibration_duration=10)[0] for time, inst in sched.instructions: if isinstance(inst, AcquireInstruction): self.assertEqual(time, 10)
def test_align_measures(self): """Test that one acquire is delayed to match the time of the later acquire.""" acquire = pulse.Acquire(5) sched = pulse.Schedule(name='fake_experiment') sched = sched.insert(0, self.short_pulse(self.device.drives[0])) sched = sched.insert( 1, acquire(self.device.acquires[0], self.device.memoryslots[0])) sched = sched.insert( 10, acquire(self.device.acquires[1], self.device.memoryslots[1])) sched = align_measures([sched], self.cmd_def)[0] for time, inst in sched.instructions: if isinstance(inst, AcquireInstruction): self.assertEqual(time, 10) sched = align_measures([sched], self.cmd_def, align_time=20)[0] for time, inst in sched.instructions: if isinstance(inst, AcquireInstruction): self.assertEqual(time, 20)
def test_align_measures(self): """Test that one acquire is delayed to match the time of the later acquire.""" acquire = pulse.Acquire(5) sched = pulse.Schedule(name='fake_experiment') sched = sched.insert(0, self.short_pulse(self.config.drive(0))) sched = sched.insert(1, acquire(self.config.acquire(0), MemorySlot(0))) sched = sched.insert(10, acquire(self.config.acquire(1), MemorySlot(1))) sched = sched.insert(10, self.short_pulse(self.config.measure(0))) sched = sched.insert(10, self.short_pulse(self.config.measure(1))) sched = align_measures([sched], self.cmd_def)[0] for time, inst in sched.instructions: if isinstance(inst, AcquireInstruction): self.assertEqual(time, 10) sched = align_measures([sched], self.cmd_def, align_time=20)[0] for time, inst in sched.instructions: if isinstance(inst, AcquireInstruction): self.assertEqual(time, 20) if isinstance(inst.channels[0], MeasureChannel): self.assertEqual(time, 20)
def test_align_across_schedules(self): """Test that acquires are aligned together across multiple schedules.""" acquire = pulse.Acquire(5) sched1 = pulse.Schedule(name='fake_experiment') sched1 = sched1.insert(0, self.short_pulse(self.config.drive(0))) sched1 = sched1.insert(10, acquire(self.config.acquire(0), MemorySlot(0))) sched2 = pulse.Schedule(name='fake_experiment') sched2 = sched2.insert(3, self.short_pulse(self.config.drive(0))) sched2 = sched2.insert(25, acquire(self.config.acquire(0), MemorySlot(0))) schedules = align_measures([sched1, sched2], self.cmd_def) for time, inst in schedules[0].instructions: if isinstance(inst, AcquireInstruction): self.assertEqual(time, 25) for time, inst in schedules[0].instructions: if isinstance(inst, AcquireInstruction): self.assertEqual(time, 25)
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