def test_delay_control_channel(self): """Test Delay on ControlChannel""" control_ch = self.config.control([0, 1])[0] pulse = Waveform(np.full(10, 0.1)) # should pass as is an append sched = Delay(self.delay_time, control_ch) + Play(pulse, control_ch) self.assertIsInstance(sched, Schedule) # should fail due to overlap with self.assertRaises(PulseError): sched = Delay(self.delay_time, control_ch) | Play( pulse, control_ch) self.assertIsInstance(sched, Schedule)
def test_delay_drive_channel(self): """Test Delay on DriveChannel""" drive_ch = self.config.drive(0) pulse = Waveform(np.full(10, 0.1)) # should pass as is an append sched = Delay(self.delay_time, drive_ch) + Play(pulse, drive_ch) self.assertIsInstance(sched, Schedule) pulse_instr = sched.instructions[-1] # assert last instruction is pulse self.assertIsInstance(pulse_instr[1], Play) # assert pulse is scheduled at time 10 self.assertEqual(pulse_instr[0], 10) # should fail due to overlap with self.assertRaises(PulseError): sched = Delay(self.delay_time, drive_ch) | Play(pulse, drive_ch)
def test_add(self): """Test add, and that errors are raised when expected.""" sched = Schedule() sched.append(Play(Waveform(np.ones(5)), DriveChannel(0))) inst_map = InstructionScheduleMap() inst_map.add('u1', 1, sched) inst_map.add('u1', 0, sched) self.assertIn('u1', inst_map.instructions) self.assertEqual(inst_map.qubits_with_instruction('u1'), [0, 1]) self.assertTrue('u1' in inst_map.qubit_instructions(0)) with self.assertRaises(PulseError): inst_map.add('u1', (), sched) with self.assertRaises(PulseError): inst_map.add('u1', 1, "not a schedule")
def _1Q_schedule(self, total_samples=100, amp=1., num_acquires=1): """Creates a schedule for a single qubit. Args: total_samples (int): number of samples in the drive pulse amp (complex): amplitude of drive pulse num_acquires (int): number of acquire instructions to include in the schedule Returns: schedule (pulse schedule): """ schedule = Schedule() schedule |= Play(Waveform(amp * np.ones(total_samples)), DriveChannel(0)) for _ in range(num_acquires): schedule |= Acquire(total_samples, AcquireChannel(0), MemorySlot(0)) << schedule.duration return schedule
def _1Q_constant_sched(self, total_samples, amp=1.): """Creates a runnable schedule for 1Q with a constant drive pulse of a given length. Args: total_samples (int): length of pulse amp (float): amplitude of constant pulse (can be complex) Returns: schedule (pulse schedule): schedule with a drive pulse followed by an acquire """ # set up constant pulse for doing a pi pulse drive_pulse = Waveform(amp * np.ones(total_samples)) schedule = Schedule() schedule |= Play(drive_pulse, DriveChannel(0)) schedule |= Acquire(total_samples, AcquireChannel(0), MemorySlot(0)) << schedule.duration return schedule
def test_uneven_pulse_length(self): """Test conversion when length of pulses on a schedule is uneven.""" schedule = Schedule() schedule |= Play(Waveform(np.ones(10)), DriveChannel(0)) schedule += Play(Constant(20, 1), DriveChannel(1)) converter = InstructionToSignals(dt=0.1, carriers=[2.0, 3.0]) signals = converter.get_signals(schedule) self.assertTrue(signals[0].duration == 20) self.assertTrue(signals[1].duration == 20) self.assertAllClose(signals[0]._samples, np.append(np.ones(10), np.zeros(10))) self.assertAllClose(signals[1]._samples, np.ones(20)) self.assertTrue(signals[0].carrier_freq == 2.0) self.assertTrue(signals[1].carrier_freq == 3.0)
def model_and_pi_schedule(): """Return a simple model and schedule for pulse simulation""" # construct model model = duffing_system_model(dim_oscillators=2, oscillator_freqs=[5.0], anharm_freqs=[0], drive_strengths=[0.01], coupling_dict={}, dt=1.0) # note: parameters set so that area under curve is 1/4 sample_pulse = Waveform(np.ones(50)) # construct schedule schedule = Schedule(name='test_sched') schedule |= Play(sample_pulse, DriveChannel(0)) schedule += Acquire(10, AcquireChannel(0), MemorySlot(0)) << schedule.duration return model, schedule
def _2Q_constant_sched(self, total_samples, amp=1., u_idx=0): """Creates a runnable schedule with a single pulse on a U channel for two qubits. Args: total_samples (int): length of pulse amp (float): amplitude of constant pulse (can be complex) u_idx (int): index of U channel Returns: schedule (pulse schedule): schedule with a drive pulse followed by an acquire """ # set up constant pulse for doing a pi pulse drive_pulse = Waveform(amp * np.ones(total_samples)) schedule = Schedule() schedule |= Play(drive_pulse, ControlChannel(u_idx)) schedule |= Acquire(total_samples, AcquireChannel(0), MemorySlot(0)) << total_samples schedule |= Acquire(total_samples, AcquireChannel(1), MemorySlot(1)) << total_samples return schedule
def my_test_par_sched_two(x, y, z): result = Play(Waveform(np.array([x, y, z]), name="sample"), self.config.drive(0)) return 5, result
def my_test_par_sched_one(x, y, z): result = Play(Waveform(np.array([x, y, z]), name='sample'), self.config.drive(0)) return 0, result
def test_shift_phase(self): """Test ShiftPhase command.""" omega_0 = 1.123 r = 1. system_model = self._system_model_1Q(omega_0, r) # run a schedule in which a shifted phase causes a pulse to cancel itself. # Also do it in multiple phase shifts to test accumulation sched = Schedule() amp1 = 0.12 sched += Play(Waveform([amp1]), DriveChannel(0)) phi1 = 0.12374 * np.pi sched += ShiftPhase(phi1, DriveChannel(0)) amp2 = 0.492 sched += Play(Waveform([amp2]), DriveChannel(0)) phi2 = 0.5839 * np.pi sched += ShiftPhase(phi2, DriveChannel(0)) amp3 = 0.12 + 0.21 * 1j sched += Play(Waveform([amp3]), DriveChannel(0)) sched |= Acquire(1, AcquireChannel(0), MemorySlot(0)) << sched.duration y0 = np.array([1., 0]) pulse_sim = PulseSimulator(system_model=system_model, initial_state=y0) qobj = assemble([sched], backend=pulse_sim, meas_level=2, meas_return='single', meas_map=[[0]], qubit_lo_freq=[omega_0], memory_slots=2, shots=1) results = pulse_sim.run(qobj).result() pulse_sim_yf = results.get_statevector() #run independent simulation samples = np.array([[amp1], [amp2 * np.exp(1j * phi1)], [amp3 * np.exp(1j * (phi1 + phi2))]]) indep_yf = simulate_1q_model(y0, omega_0, r, np.array([omega_0]), samples, 1.) self.assertGreaterEqual(state_fidelity(pulse_sim_yf, indep_yf), 1 - (10**-5)) # run another schedule with only a single shift phase to verify sched = Schedule() amp1 = 0.12 sched += Play(Waveform([amp1]), DriveChannel(0)) phi1 = 0.12374 * np.pi sched += ShiftPhase(phi1, DriveChannel(0)) amp2 = 0.492 sched += Play(Waveform([amp2]), DriveChannel(0)) sched |= Acquire(1, AcquireChannel(0), MemorySlot(0)) << sched.duration qobj = assemble([sched], backend=pulse_sim, meas_level=2, meas_return='single', meas_map=[[0]], qubit_lo_freq=[omega_0], memory_slots=2, shots=1) results = pulse_sim.run(qobj).result() pulse_sim_yf = results.get_statevector() #run independent simulation samples = np.array([[amp1], [amp2 * np.exp(1j * phi1)]]) indep_yf = simulate_1q_model(y0, omega_0, r, np.array([omega_0]), samples, 1.) self.assertGreaterEqual(state_fidelity(pulse_sim_yf, indep_yf), 1 - (10**-5))
def test_delay_instruction(self): """Test for delay instruction.""" # construct system model specifically for this hamiltonian = {} hamiltonian['h_str'] = ['0.5*r*X0||D0', '0.5*r*Y0||D1'] hamiltonian['vars'] = {'r': np.pi} hamiltonian['qub'] = {'0': 2} ham_model = HamiltonianModel.from_dict(hamiltonian) u_channel_lo = [] subsystem_list = [0] dt = 1. system_model = PulseSystemModel(hamiltonian=ham_model, u_channel_lo=u_channel_lo, subsystem_list=subsystem_list, dt=dt) # construct a schedule that should result in a unitary -Z if delays are correctly handled # i.e. do a pi rotation about x, sandwiched by pi/2 rotations about y in opposite directions # so that the x rotation is transformed into a z rotation. # if delays are not handled correctly this process should fail sched = Schedule() sched += Play(Waveform([0.5]), DriveChannel(1)) sched += Delay(1, DriveChannel(1)) sched += Play(Waveform([-0.5]), DriveChannel(1)) sched += Delay(1, DriveChannel(0)) sched += Play(Waveform([1.]), DriveChannel(0)) sched |= Acquire(1, AcquireChannel(0), MemorySlot(0)) << sched.duration # Result of schedule should be the unitary -1j*Z, so check rotation of an X eigenstate pulse_sim = PulseSimulator(system_model=system_model, initial_state=np.array([1., 1.]) / np.sqrt(2)) qobj = assemble([sched], backend=pulse_sim, meas_level=2, meas_return='single', meas_map=[[0]], qubit_lo_freq=[0., 0.], memory_slots=2, shots=1) results = pulse_sim.run(qobj).result() statevector = results.get_statevector() expected_vector = np.array([-1j, 1j]) / np.sqrt(2) self.assertGreaterEqual(state_fidelity(statevector, expected_vector), 1 - (10**-5)) # verify validity of simulation when no delays included sched = Schedule() sched += Play(Waveform([0.5]), DriveChannel(1)) sched += Play(Waveform([-0.5]), DriveChannel(1)) sched += Play(Waveform([1.]), DriveChannel(0)) sched |= Acquire(1, AcquireChannel(0), MemorySlot(0)) << sched.duration qobj = assemble([sched], backend=pulse_sim, meas_level=2, meas_return='single', meas_map=[[0]], qubit_lo_freq=[0., 0.], memory_slots=2, shots=1) results = pulse_sim.run(qobj).result() statevector = results.get_statevector() U = expm(1j * np.pi * self.Y / 4) @ expm(-1j * np.pi * (self.Y / 4 + self.X / 2)) expected_vector = U @ np.array([1., 1.]) / np.sqrt(2) self.assertGreaterEqual(state_fidelity(statevector, expected_vector), 1 - (10**-5))
def test_2Q_exchange(self): r"""Test a more complicated 2q simulation""" q_freqs = [5., 5.1] r = 0.02 j = 0.02 total_samples = 25 hamiltonian = {} hamiltonian['h_str'] = [ '2*np.pi*v0*0.5*Z0', '2*np.pi*v1*0.5*Z1', '2*np.pi*r*0.5*X0||D0', '2*np.pi*r*0.5*X1||D1', '2*np.pi*j*0.5*I0*I1', '2*np.pi*j*0.5*X0*X1', '2*np.pi*j*0.5*Y0*Y1', '2*np.pi*j*0.5*Z0*Z1' ] hamiltonian['vars'] = { 'v0': q_freqs[0], 'v1': q_freqs[1], 'r': r, 'j': j } hamiltonian['qub'] = {'0': 2, '1': 2} ham_model = HamiltonianModel.from_dict(hamiltonian) # set the U0 to have frequency of drive channel 0 u_channel_lo = [] subsystem_list = [0, 1] dt = 1. system_model = PulseSystemModel(hamiltonian=ham_model, u_channel_lo=u_channel_lo, subsystem_list=subsystem_list, dt=dt) # try some random schedule schedule = Schedule() drive_pulse = Waveform(np.ones(total_samples)) schedule += Play(drive_pulse, DriveChannel(0)) schedule |= Play(drive_pulse, DriveChannel(1)) << 2 * total_samples schedule |= Acquire(total_samples, AcquireChannel(0), MemorySlot(0)) << 3 * total_samples schedule |= Acquire(total_samples, AcquireChannel(1), MemorySlot(1)) << 3 * total_samples y0 = np.array([1., 0., 0., 0.]) pulse_sim = PulseSimulator(system_model=system_model, initial_state=y0, seed=9000) qobj = assemble([schedule], backend=pulse_sim, meas_level=2, meas_return='single', meas_map=[[0]], qubit_lo_freq=q_freqs, memory_slots=2, shots=1000) result = pulse_sim.run(qobj).result() pulse_sim_yf = result.get_statevector() # set up and run independent simulation d0_samps = np.concatenate( (np.ones(total_samples), np.zeros(2 * total_samples))) d1_samps = np.concatenate( (np.zeros(2 * total_samples), np.ones(total_samples))) samples = np.array([d0_samps, d1_samps]).transpose() q_freqs = np.array(q_freqs) yf = simulate_2q_exchange_model(y0, q_freqs, r, j, q_freqs, samples, 1.) # Check fidelity of statevectors self.assertGreaterEqual(state_fidelity(pulse_sim_yf, yf), 1 - (10**-5))
def generate_schedule(pulse_seq, backend, draw_progs): D0 = [] D1 = [] for i, a in enumerate(pulse_seq): if len(pulse_seq[0]) == 2: # D0.append(complex(a[0], a[1])) D0.append(complex(a[0], a[1])) elif len(pulse_seq[0]) == 4: D0.append(complex(a[0], a[1])) D1.append(complex(a[2], a[3])) else: D0.append(a[0]) # if len(pulse_seq[0]) == 2: # # D0.append(complex(a[0], a[1])) # D0.append(complex(a[0], a[1])) # D1.append(complex(a[2], a[3])) # else: # D0.append(a[0]) # D0.append(a[0]) # D1.append(complex(a[2], a[3])) q1 = 0 q2 = 1 drive_chan1 = pulse.DriveChannel(q1) meas_chan1 = pulse.MeasureChannel(q1) acq_chan1 = pulse.AcquireChannel(q1) con_chan1 = pulse.ControlChannel(q1) drive_chan2 = pulse.DriveChannel(q2) meas_chan2 = pulse.MeasureChannel(q2) acq_chan2 = pulse.AcquireChannel(q2) con_chan2 = pulse.ControlChannel(q2) schedule = pulse.Schedule(name='sigmax') # init_x = backend.defaults().instruction_schedule_map.get('x', [1]) # def_seq = init_x.instructions[0] # def_seq = def_seq[1].pulse.get_waveform().samples # init_x = backend.defaults().instruction_schedule_map.get('x').data # schedule += Play(Waveform(def_seq), drive_chan2) # schedule += init_x later = schedule.duration # schedule += def_cx << later # if len(subsystem_list) == 1: # schedule += Play(SamplePulse(pulse_seqs[0]), drive_chan1) << later # else: # schedule += Play(SamplePulse(pulse_seqs[0]), con_chan1) << later # schedule += Play(SamplePulse(pulse_seqs[1]), con_chan2) << later # schedule += Play(SamplePulse(pulse_seqs[2]), drive_chan1) << later # schedule += Play(SamplePulse(pulse_seqs[3]), drive_chan2) schedule += Play(Waveform(D0), drive_chan1) << later # schedule.duration if len(pulse_seq[0]) == 4: schedule += Play(Waveform(D1), drive_chan2) << later # schedule.duration schedule += measure_all(backend) << schedule.duration if draw_progs: schedule.draw(plot_range=[0, len(D0)]) return schedule
def generate_qiskit_program(pulse_seq, backend, default_seq=None, derotate_flag=False, draw_progs=False): D0 = [] D1 = [] if default_seq: D0 = default_seq else: for i, a in enumerate(pulse_seq): if derotate_flag: amp2 = derotate(a[1], i, backend) amp1 = derotate(a[0], i, backend) D0.append(complex(amp1, amp2)) else: if len(pulse_seq[0]) == 2: # D0.append(complex(a[0], a[1])) D0.append(complex(a[0], a[1])) elif len(pulse_seq[0]) == 4: D0.append(complex(a[0], a[1])) D1.append(complex(a[2], a[3])) else: D0.append(a[0]) # if len(pulse_seq[0]) == 2: # # D0.append(complex(a[0], a[1])) # D0.append(complex(a[0], a[1])) # D1.append(complex(a[2], a[3])) # else: # D0.append(a[0]) # D0.append(a[0]) # D1.append(complex(a[2], a[3])) q1 = 0 q2 = 1 drive_chan1 = pulse.DriveChannel(q1) meas_chan1 = pulse.MeasureChannel(q1) acq_chan1 = pulse.AcquireChannel(q1) con_chan1 = pulse.ControlChannel(q1) drive_chan2 = pulse.DriveChannel(q2) meas_chan2 = pulse.MeasureChannel(q2) acq_chan2 = pulse.AcquireChannel(q2) con_chan2 = pulse.ControlChannel(q2) schedule = pulse.Schedule(name='sigmax') # init_x = backend.defaults().instruction_schedule_map.get('x', [1]) # def_seq = init_x.instructions[0] # def_seq = def_seq[1].pulse.get_waveform().samples # init_x = backend.defaults().instruction_schedule_map.get('x').data # schedule += Play(Waveform(def_seq), drive_chan2) # schedule += init_x later = schedule.duration # schedule += def_cx << later # if len(subsystem_list) == 1: # schedule += Play(SamplePulse(pulse_seqs[0]), drive_chan1) << later # else: # schedule += Play(SamplePulse(pulse_seqs[0]), con_chan1) << later # schedule += Play(SamplePulse(pulse_seqs[1]), con_chan2) << later # schedule += Play(SamplePulse(pulse_seqs[2]), drive_chan1) << later # schedule += Play(SamplePulse(pulse_seqs[3]), drive_chan2) schedule += Play(Waveform(D0), drive_chan1) << later # schedule.duration if len(pulse_seq[0]) == 4: schedule += Play(Waveform(D1), drive_chan2) << later # schedule.duration schedule += measure_all(backend) << schedule.duration from qiskit import assemble if draw_progs: schedule.draw(plot_range=[0, len(D0)]) num_shots = 1024 qoc_test_program = assemble( schedule, backend=backend, meas_level=2, meas_return='single', # qubit_lo_freq=backend.defaults().qubit_freq_est, shots=num_shots, ) # schedule_los=schedule_frequencies) return qoc_test_program