def test_assemble_memory_slots_for_schedules(self): """Test assembling schedules with different memory slots.""" acquire = pulse.Acquire(5) n_memoryslots = [10, 5, 7] schedules = [] for n_memoryslot in n_memoryslots: schedule = acquire(self.backend_config.acquire(0), mem_slots=pulse.MemorySlot(n_memoryslot-1)) schedules.append(schedule) qobj = assemble(schedules, qubit_lo_freq=self.default_qubit_lo_freq, meas_lo_freq=self.default_meas_lo_freq, meas_map=[[0], [1]]) validate_qobj_against_schema(qobj) self.assertEqual(qobj.config.memory_slots, max(n_memoryslots)) self.assertEqual(qobj.experiments[0].header.memory_slots, n_memoryslots[0]) self.assertEqual(qobj.experiments[1].header.memory_slots, n_memoryslots[1]) self.assertEqual(qobj.experiments[2].header.memory_slots, n_memoryslots[2])
def freq_sweep_schedule(qbit, backend_config, drive_chan, meas_samples=1000,): dt = backend_config.dt print(f"Sampling time: {dt} ns") drive_pulse = make_drive_pulse(dt) meas_pulse = make_meas_pulse(dt, samples=meas_samples) ### Construct the acquire pulse to trigger the acquisition # Acquire pulse samples acq_cmd = pulse.Acquire(duration=meas_samples) # Find out which group of qubits need to be acquired with this qubit meas_map_idx = None for i, measure_group in enumerate(backend_config.meas_map): if qbit in measure_group: meas_map_idx = i break assert meas_map_idx is not None, f"Couldn't find qubit {qbit} in the meas_map!" ### Collect the necessary channels #drive_chan = pulse.DriveChannel(qbit) meas_chan = pulse.MeasureChannel(qbit) #acq_chan = pulse.AcquireChannel(qbit) schedule = pulse.Schedule(name='Frequency sweep') schedule += drive_pulse(drive_chan) measure_schedule = meas_pulse(meas_chan) # Trigger data acquisition, and store measured values into respective memory slots measure_schedule += acq_cmd([pulse.AcquireChannel(i) for i in backend_config.meas_map[meas_map_idx]], [pulse.MemorySlot(i) for i in backend_config.meas_map[meas_map_idx]]) # shift the start time of the schedule by some duration schedule += measure_schedule << schedule.duration schedule += drive_pulse(drive_chan)<< schedule.duration - drive_pulse.duration schedule += measure_schedule << drive_pulse.duration return schedule
def cr_drive_experiments(drive_idx, target_idx, flip_drive_qubit = False, #cr_drive_amps=np.linspace(0, 0.9, 16), #cr_drive_samples=800, #cr_drive_sigma=4, #pi_drive_samples=128, #pi_drive_sigma=16 #meas_amp = Dims/128*0.025/2 #meas_width = int(rows/128*1150/2) cr_drive_amps=np.linspace(0, 0.9, meas_width**2), cr_drive_samples=sum(label1[:] == label2[:]), cr_drive_sigma=meas_sigma, pi_drive_samples=sum((label1[:] ==1)*(label2[:] ==1)), #label1[:] ==1 and label2[:] ==1 pi_drive_sigma=cr_drive_sigma**2): """Generate schedules corresponding to CR drive experiments. Args: drive_idx (int): label of driven qubit target_idx (int): label of target qubit flip_drive_qubit (bool): whether or not to start the driven qubit in the ground or excited state cr_drive_amps (array): list of drive amplitudes to use cr_drive_samples (int): number samples for each CR drive signal cr_drive_sigma (float): standard deviation of CR Gaussian pulse pi_drive_samples (int): number samples for pi pulse on drive pi_drive_sigma (float): standard deviation of Gaussian pi pulse on drive Returns: list[Schedule]: A list of Schedule objects for each experiment """ # Construct measurement commands to be used for all schedules #meas_amp = 0.025 #meas_samples = 1200 #meas_sigma = 4 #meas_width = 1150 meas_amp = 0.025 meas_sigma = 4 ni = int(np.ceil(cols/meas_sigma)) print(ni) meas_samples = rows*ni meas_width = int(rows*ni*23/24) meas_pulse = GaussianSquare(duration=meas_samples, amp=meas_amp/np.linalg.norm(meas_amp), sigma=meas_sigma, width=meas_width) acq_sched = pulse.Acquire(meas_samples, pulse.AcquireChannel(0), pulse.MemorySlot(0)) acq_sched += pulse.Acquire(meas_samples, pulse.AcquireChannel(1), pulse.MemorySlot(1)) # create measurement schedule measure_sched = (pulse.Play(meas_pulse, pulse.MeasureChannel(0)) | pulse.Play(meas_pulse, pulse.MeasureChannel(1))| acq_sched) # Create schedule schedules = [] for ii, cr_drive_amp in enumerate(cr_drive_amps): # pulse for flipping drive qubit if desired pi_pulse = Gaussian(duration=pi_drive_samples, amp=pi_amps[drive_idx], sigma=pi_drive_sigma) # cr drive pulse cr_width = cr_drive_samples - 2*cr_drive_sigma*4 cr_rabi_pulse = GaussianSquare(duration=cr_drive_samples, amp=cr_drive_amp/np.linalg.norm(cr_drive_amp), sigma=cr_drive_sigma, width=cr_width) # add commands to schedule schedule = pulse.Schedule(name='cr_rabi_exp_amp_%s' % cr_drive_amp) #schedule = pulse.Schedule(name='cr_rabi_exp_amp_%s' % cr_drive_amp/np.linalg.norm(cr_drive_amp)) # flip drive qubit if desired if flip_drive_qubit: schedule += pulse.Play(pi_pulse, pulse.DriveChannel(drive_idx)) # do cr drive # First, get the ControlChannel index for CR drive from drive to target cr_idx = two_qubit_model.control_channel_index((drive_idx, target_idx)) schedule += pulse.Play(cr_rabi_pulse, pulse.ControlChannel(cr_idx)) << schedule.duration schedule += measure_sched << schedule.duration schedules.append(schedule) return schedules
#4.1 Constructing the schedules # list of qubits to be used throughout the notebook qubits = [0, 1] # Construct a measurement schedule and add it to an InstructionScheduleMap meas_amp = 0.025 meas_sigma = 4 ni = int(np.ceil(cols/meas_sigma)) print(ni) meas_samples = rows*ni meas_width = int(rows*ni*23/24) meas_pulse = GaussianSquare(duration=meas_samples, amp=meas_amp, sigma=meas_sigma, width=meas_width) acq_sched = pulse.Acquire(meas_samples, pulse.AcquireChannel(0), pulse.MemorySlot(0)) acq_sched += pulse.Acquire(meas_samples, pulse.AcquireChannel(1), pulse.MemorySlot(1)) measure_sched = pulse.Play(meas_pulse, pulse.MeasureChannel(0)) | pulse.Play(meas_pulse, pulse.MeasureChannel(1)) | acq_sched inst_map = pulse.InstructionScheduleMap() inst_map.add('measure', qubits, measure_sched) #Rabi schedules #recall: Rabii oscillation # The magnetic moment is thus {\displaystyle {\boldsymbol {\mu }}={\frac {\hbar }{2}}\gamma {\boldsymbol {\sigma }}}{\boldsymbol {\mu }}={\frac {\hbar }{2}}\gamma {\boldsymbol {\sigma }}. # The Hamiltonian of this system is then given by {H} =-{{\mu }}\cdot{B} =-{\frac {\hbar }{2}}\omega _{0}\sigma _{z}-{\frac {\hbar }{2}}\omega _{1}(\sigma _{x}\cos \omega t-\sigma _{y}\sin \omega t)}\mathbf {H} =-{\boldsymbol {\mu }}\cdot \mathbf {B} =-{\frac {\hbar }{2}}\omega _{0}\sigma _{z}-{\frac {\hbar }{2}}\omega _{1}(\sigma _{x}\cos \omega t-\sigma _{y}\sin \omega t) where {\displaystyle \omega _{0}=\gamma B_{0}}\omega _{0}=\gamma B_{0} and {\displaystyle \omega _{1}=\gamma B_{1}}\omega _{1}=\gamma B_{1} # Now, let the qubit be in state {\displaystyle |0\rangle }{\displaystyle |0\rangle } at time {\displaystyle t=0}t=0. Then, at time {\displaystyle t}t, the probability of it being found in state {\displaystyle |1\rangle }|1\rangle is given by {\displaystyle P_{0\to 1}(t)=\left({\frac {\omega _{1}}{\Omega }}\right)^{2}\sin ^{2}\left({\frac {\Omega t}{2}}\right)}{\displaystyle P_{0\to 1}(t)=\left({\frac {\omega _{1}}{\Omega }}\right)^{2}\sin ^{2}\left({\frac {\Omega t}{2}}\right)} where {\displaystyle \Omega ={\sqrt {(\omega -\omega _{0})^{2}+\omega _{1}^{2}}}}\Omega ={\sqrt {(\omega -\omega _{0})^{2}+\omega _{1}^{2}}} # the qubit oscillates between the {\displaystyle |0\rangle }|0\rang and {\displaystyle |1\rangle }|1\rangle states. # The maximum amplitude for oscillation is achieved at {\displaystyle \omega =\omega _{0}}\omega =\omega _{0}, which is the condition for resonance. # At resonance, the transition probability is given by {\displaystyle P_{0\to 1}(t)=\sin ^{2}\left({\frac {\omega _{1}t}{2}}\right)}{\displaystyle P_{0\to 1}(t)=\sin ^{2}\left({\frac {\omega _{1}t}{2}}\right)}
def output(data): print("We have F: ", data.F, " nT") N_delta = 2 N = int(math.log(data.T_2 * 10 ** (-6) / data.t_init) / math.log(2))-N_delta multiplier = 30 # Ramsey experiment parameters detuning_max_MHz = data.const * data.F_max * data.F_degree / (2 * math.pi) / MHz / multiplier detuning_min_MHz = data.const * data.F_min * data.F_degree / (2 * math.pi) / MHz / multiplier detuning_MHz = data.const * data.F * data.F_degree / (2 * math.pi) / MHz / multiplier delta_min_det_MHz = -0.05 - 0.02 - 0.12 - 0.22 delta_max_det_MHz = -0.05 - 0.05 - 0.05 - 0.12 - 0.20 detuning_MHz = (detuning_min_MHz+delta_min_det_MHz) + (detuning_max_MHz+delta_max_det_MHz - (detuning_min_MHz+delta_min_det_MHz))*(detuning_MHz - detuning_min_MHz)/(detuning_max_MHz-detuning_min_MHz) times = [data.t_init*2**(i) for i in range(N)] # Drive parameters # The drive amplitude for pi/2 is simply half the amplitude of the pi pulse drive_amp = pi_amp / 2 # x_90 is a concise way to say pi_over_2; i.e., an X rotation of 90 degrees with pulse.build(backend) as x90_pulse: drive_duration = get_closest_multiple_of_16(pulse.seconds_to_samples(drive_duration_sec)) drive_sigma = pulse.seconds_to_samples(drive_sigma_sec) drive_chan = pulse.drive_channel(qubit) pulse.play(pulse.Gaussian(duration=drive_duration, amp=drive_amp, sigma=drive_sigma, name='x90_pulse'), drive_chan) # create schedules for Ramsey experiment ramsey_schedules = [] ramsey_frequency = round(precise_qubit_freq + detuning_MHz * MHz, 6) # need ramsey freq in Hz for time in times: with pulse.build(backend=backend, default_alignment='sequential', name=f"det = {detuning_MHz} MHz") as ramsey_schedule: drive_chan = pulse.drive_channel(qubit) pulse.set_frequency(ramsey_frequency, drive_chan) pulse.call(x90_pulse) pulse.delay(get_closest_multiple_of_16(pulse.seconds_to_samples(time*multiplier)), drive_chan) pulse.call(x90_pulse) pulse.measure(qubits=[qubit], registers=[pulse.MemorySlot(mem_slot)]) ramsey_schedules.append(ramsey_schedule) # Execution settings num_shots = data.num_of_repetitions job = backend.run(ramsey_schedules, meas_level=1, meas_return='single', shots=num_shots) job_monitor(job) ramsey_results = job.result(timeout=120) ramsey_values = {} for i in range(len(times)): iq_data = ramsey_results.get_memory(i)[:, qubit] * scale_factor ramsey_values[times[i]]=int(round(sum(map(classify, iq_data)) / num_shots)) ''' times = [data.t_init * 2 ** (i) for i in range(N, N+N_delta)] # create schedules for Ramsey experiment ramsey_schedules = [] ramsey_frequency = round(precise_qubit_freq + detuning_MHz * MHz, 6) # need ramsey freq in Hz for time in times: with pulse.build(backend=backend, default_alignment='sequential', name=f"det = {detuning_MHz} MHz") as ramsey_schedule: drive_chan = pulse.drive_channel(qubit) pulse.set_frequency(ramsey_frequency, drive_chan) pulse.call(x90_pulse) pulse.delay(get_closest_multiple_of_16(pulse.seconds_to_samples(time * multiplier)), drive_chan) pulse.call(x90_pulse) pulse.measure(qubits=[qubit], registers=[pulse.MemorySlot(mem_slot)]) ramsey_schedules.append(ramsey_schedule) # Execution settings num_shots = data.num_of_repetitions job = backend.run(ramsey_schedules, meas_level=1, meas_return='single', shots=num_shots) job_monitor(job) ramsey_results = job.result(timeout=120) for i in range(len(times)): iq_data = ramsey_results.get_memory(i)[:, qubit] * scale_factor ramsey_values[times[i]] = int(round(sum(map(classify, iq_data)) / num_shots)) #''' print(ramsey_values) return ramsey_values #print(output(data))
def setUp(self): """Just some useful, reusable Parameters, constants, schedules.""" super().setUp() self.amp1_1 = Parameter("amp1_1") self.amp1_2 = Parameter("amp1_2") self.amp2 = Parameter("amp2") self.amp3 = Parameter("amp3") self.dur1 = Parameter("dur1") self.dur2 = Parameter("dur2") self.dur3 = Parameter("dur3") self.parametric_waveform1 = pulse.Gaussian(duration=self.dur1, amp=self.amp1_1 + self.amp1_2, sigma=self.dur1 / 4) self.parametric_waveform2 = pulse.Gaussian(duration=self.dur2, amp=self.amp2, sigma=self.dur2 / 5) self.parametric_waveform3 = pulse.Gaussian(duration=self.dur3, amp=self.amp3, sigma=self.dur3 / 6) self.ch1 = Parameter("ch1") self.ch2 = Parameter("ch2") self.ch3 = Parameter("ch3") self.d1 = pulse.DriveChannel(self.ch1) self.d2 = pulse.DriveChannel(self.ch2) self.d3 = pulse.DriveChannel(self.ch3) self.phi1 = Parameter("phi1") self.phi2 = Parameter("phi2") self.phi3 = Parameter("phi3") self.meas_dur = Parameter("meas_dur") self.mem1 = Parameter("s1") self.reg1 = Parameter("m1") self.context_dur = Parameter("context_dur") # schedule under test subroutine = pulse.ScheduleBlock(alignment_context=AlignLeft()) subroutine += pulse.ShiftPhase(self.phi1, self.d1) subroutine += pulse.Play(self.parametric_waveform1, self.d1) sched = pulse.Schedule() sched += pulse.ShiftPhase(self.phi3, self.d3) long_schedule = pulse.ScheduleBlock(alignment_context=AlignEquispaced( self.context_dur), name="long_schedule") long_schedule += subroutine long_schedule += pulse.ShiftPhase(self.phi2, self.d2) long_schedule += pulse.Play(self.parametric_waveform2, self.d2) long_schedule += pulse.Call(sched) long_schedule += pulse.Play(self.parametric_waveform3, self.d3) long_schedule += pulse.Acquire( self.meas_dur, pulse.AcquireChannel(self.ch1), mem_slot=pulse.MemorySlot(self.mem1), reg_slot=pulse.RegisterSlot(self.reg1), ) self.test_sched = long_schedule
acq_cmd = pulse.Acquire(duration=meas_samples) # In[59]: meas_pulse = pulse_lib.gaussian_square(duration=meas_samples, sigma=meas_sigma, amp=meas_amp, risefall=meas_risefall, name='measurement_pulse') measure_schedule = meas_pulse(meas_chan)<<measure_time measure_schedule += acq_cmd([pulse.AcquireChannel(i) for i in backend_config.meas_map[meas_map_idx]], [pulse.MemorySlot(i) for i in backend_config.meas_map[meas_map_idx]]) # In[64]: measure_schedule.draw(plot_range=[0,25000],channels_to_plot=[drive_chan, meas_chan], label=True, scaling=1.0) # In[65]: schedule = pulse.Schedule(name='Readout_Discrim') schedule += x_gate schedule += measure_schedule << measure_time
# Import backend configurations backend_config = backend.configuration() # Set measurement channels meas_chan = pulse.MeasureChannel(qubit) acq_chan = pulse.AcquireChannel(qubit) # Add a measurement stimulus on the measure channel pulse to trigger readout measure_schedule = pulse.Play(measurement_pulse, meas_chan) # Trigger data acquisition, and store measured values into respective memory slots measure_schedule += pulse.Acquire( measurement_pulse.duration, pulse.AcquireChannel(backend_config.meas_map[meas_map_idx][0]), pulse.MemorySlot(backend_config.meas_map[meas_map_idx][0]), ) # Run 0-1 state discrimination experiment gnd_exc_experiment_result = ground_excited_experiment( qubit, backend, num_shots_with_training, measure_schedule) # Train and classify data with Q-CTRL's discriminator gnd_exc_results = train_discriminator(gnd_exc_experiment_result, test_sample_size)[2] # Store results measurement_data.append(gnd_exc_results) silhouette_time_list.append(intercluster_distance(gnd_exc_results)) silhouette_list.append(silhouette_time_list)
#4.1 Constructing the schedules # list of qubits to be used throughout the notebook qubits = [0, 1] # Construct a measurement schedule and add it to an InstructionScheduleMap meas_amp = 0.025 meas_samples = 1200 meas_sigma = 4 meas_width = 1150 meas_pulse = GaussianSquare(duration=meas_samples, amp=meas_amp, sigma=meas_sigma, width=meas_width) acq_sched = pulse.Acquire(meas_samples, pulse.AcquireChannel(0), pulse.MemorySlot(0)) acq_sched += pulse.Acquire(meas_samples, pulse.AcquireChannel(1), pulse.MemorySlot(1)) measure_sched = pulse.Play(meas_pulse, pulse.MeasureChannel(0)) | pulse.Play( meas_pulse, pulse.MeasureChannel(1)) | acq_sched inst_map = pulse.InstructionScheduleMap() inst_map.add('measure', qubits, measure_sched) #Rabi schedules #recall: Rabii oscillation # The magnetic moment is thus {\displaystyle {\boldsymbol {\mu }}={\frac {\hbar }{2}}\gamma {\boldsymbol {\sigma }}}{\boldsymbol {\mu }}={\frac {\hbar }{2}}\gamma {\boldsymbol {\sigma }}. # The Hamiltonian of this system is then given by {H} =-{{\mu }}\cdot{B} =-{\frac {\hbar }{2}}\omega _{0}\sigma _{z}-{\frac {\hbar }{2}}\omega _{1}(\sigma _{x}\cos \omega t-\sigma _{y}\sin \omega t)}\mathbf {H} =-{\boldsymbol {\mu }}\cdot \mathbf {B} =-{\frac {\hbar }{2}}\omega _{0}\sigma _{z}-{\frac {\hbar }{2}}\omega _{1}(\sigma _{x}\cos \omega t-\sigma _{y}\sin \omega t) where {\displaystyle \omega _{0}=\gamma B_{0}}\omega _{0}=\gamma B_{0} and {\displaystyle \omega _{1}=\gamma B_{1}}\omega _{1}=\gamma B_{1} # Now, let the qubit be in state {\displaystyle |0\rangle }{\displaystyle |0\rangle } at time {\displaystyle t=0}t=0. Then, at time {\displaystyle t}t, the probability of it being found in state {\displaystyle |1\rangle }|1\rangle is given by {\displaystyle P_{0\to 1}(t)=\left({\frac {\omega _{1}}{\Omega }}\right)^{2}\sin ^{2}\left({\frac {\Omega t}{2}}\right)}{\displaystyle P_{0\to 1}(t)=\left({\frac {\omega _{1}}{\Omega }}\right)^{2}\sin ^{2}\left({\frac {\Omega t}{2}}\right)} where {\displaystyle \Omega ={\sqrt {(\omega -\omega _{0})^{2}+\omega _{1}^{2}}}}\Omega ={\sqrt {(\omega -\omega _{0})^{2}+\omega _{1}^{2}}} # the qubit oscillates between the {\displaystyle |0\rangle }|0\rang and {\displaystyle |1\rangle }|1\rangle states.
# Creare il programma di base # Start with drive pulse acting on the drive channel freq = Parameter('freq') with pulse.build(backend=backend, default_alignment='sequential', name='Frequency sweep') as sweep_sched: drive_duration = get_closest_multiple_of_16(pulse.seconds_to_samples(drive_duration_sec)) drive_sigma = pulse.seconds_to_samples(drive_sigma_sec) drive_chan = pulse.drive_channel(qubit) pulse.set_frequency(freq, drive_chan) # Drive pulse samples pulse.play(pulse.Gaussian(duration=drive_duration, sigma=drive_sigma, amp=drive_amp, name='freq_sweep_excitation_pulse'), drive_chan) # Define our measurement pulse pulse.measure(qubits=[qubit], registers=[pulse.MemorySlot(mem_slot)]) # Create the frequency settings for the sweep (MUST BE IN HZ) frequencies_Hz = frequencies_GHz*GHz schedules = [sweep_sched.assign_parameters({freq : f}, inplace=False) for f in frequencies_Hz] schedules[0].draw() #Argomento backend=backend num_shots_per_frequency = 1024 job = backend.run(schedules, meas_level=1, meas_return='avg', shots=num_shots_per_frequency)