def calibrate_iswap_phase_single_pulse(device, gate_pulse, num_pulses):
    # excite qubit 1 with pi/2 pulse, perform iswap, apply pi./2 pulse to qubit 2
    phase_scan1 = Ramsey.Ramsey_process(device, qubit_id1=gate_pulse.metadata['q1'], qubit_id2=gate_pulse.metadata['q2'],
                                     process=gate_pulse)
    phase_scan2 = Ramsey.Ramsey_process(device, qubit_id1=gate_pulse.metadata['q2'], qubit_id2=gate_pulse.metadata['q1'],
                                     process=gate_pulse)
    return phase_scan1, phase_scan2, phase_scan1.fit, phase_scan2.fit
def calibrate_parametric_iswap_length_adaptive(device, gate, calibration_qubit='1', frequency_shift=0):
    scan_points = int(device.get_qubit_constant(qubit_id=gate.metadata['q1'],
                                                name='adaptive_Rabi_amplitude_scan_points'))
    # estimating coherence time
    T2_q1 = float(device.exdir_db.select_measurement_by_id(Ramsey.get_Ramsey_coherence_measurement(device, qubit_id=gate.metadata['q1']).id).metadata['T'])
    T2_q2 = float(device.exdir_db.select_measurement_by_id(Ramsey.get_Ramsey_coherence_measurement(device, qubit_id=gate.metadata['q2']).id).metadata['T'])
    #print (T2_q1.metadata)
    max_scan_length = 1/(1/T2_q1+1/T2_q2)

    if calibration_qubit == '1':
        excite = excitation_pulse.get_excitation_pulse(device=device, qubit_id=gate.metadata['q1'], rotation_angle=np.pi)
    else:
        excite = excitation_pulse.get_excitation_pulse(device=device, qubit_id=gate.metadata['q2'], rotation_angle=np.pi)

    vf_pulse = get_vf(device, gate, frequency_shift)  # = get_long_process_vf(device, gate)

    if calibration_qubit == '1':
        projector_func = lambda x: x[:, 2] - x[:, 1]
    else:
        projector_func = lambda x: x[:, 1] - x[:, 2]

    def infer_parameter_from_measurements(measurements, dataset_name, optimization_parameter_id, projector_func):
        parameter_values = measurements[-1].datasets[dataset_name].parameters[optimization_parameter_id].values
        measurement_interpolated_combined = np.zeros(parameter_values.shape)
        for measurement in measurements:
            measurement_interpolated_combined += np.interp(parameter_values,
                      measurement.datasets[dataset_name].parameters[optimization_parameter_id].values,
                      projector_func(measurement.datasets[dataset_name].data))
        return parameter_values[np.argmin(measurement_interpolated_combined)]

    repeats = 2
    pulse_length = float(get_iswap_pulse_nophase(device, gate,
                                           frequency_shift=frequency_shift, rotation_angle=np.pi).metadata['length'])
    adaptive_measurements = []
    while repeats*pulse_length < max_scan_length:
        lengths = pulse_length+np.linspace(-pulse_length/repeats, pulse_length/repeats, scan_points)

        adaptive_measurements.append(Rabi.Rabi_rect(
            device=device, qubit_id=[gate.metadata['q1'], gate.metadata['q2']],
            lengths=lengths,
            tail_length=float(gate.metadata['tail_length']),
            channel_amplitudes=two_qubit_gate_channel_amplitudes(device, gate),
            measurement_type=gate.metadata['physical_type'] + '_adaptive_calibration',
            pre_pulses=(excite, vf_pulse),
            repeats=repeats, additional_metadata={'frequency_shift': str(frequency_shift)},))
        pulse_length = infer_parameter_from_measurements(adaptive_measurements, 'resultnumbers',
                                                         optimization_parameter_id=0, projector_func=projector_func)
        repeats *= 2

    return device.exdir_db.save(measurement_type=gate.metadata['physical_type'] + '_adaptive_calibration_summary',
                         references={'gate': gate.id},
                         metadata={'frequency_shift':frequency_shift, 'length':pulse_length,
                                   'q1':gate.metadata['q1'], 'q2':gate.metadata['q2']})
Пример #3
0
def zgate_amplitude_ramsey(device,
                           gate,
                           lengths,
                           amplitudes,
                           target_freq_offset=100e9):
    pre_pause = float(gate.metadata['pre_pause'])
    post_pause = float(gate.metadata['post_pause'])

    class ParameterSetter:
        def __init__(self):
            self.amplitude = None
            self.length = None

        def amplitude_setter(self, amplitude):
            self.amplitude = amplitude

        def filler_func(self, length):
            self.length = length
            channel_amplitudes_ = channel_amplitudes.channel_amplitudes(
                device, **{gate.metadata['carrier_name']: self.amplitude})

            if 'pulse_type' in gate.metadata:
                if gate.metadata['pulse_type'] == 'cos':
                    frequency = float(gate.metadata['frequency'])
                    #print(frequency)
                    #print(self.length)
                    channel_pulses = [
                        (c, device.pg.sin, self.amplitude, frequency)
                        for c, a in channel_amplitudes_.metadata.items()
                    ]
                    gate_pulse = [
                        device.pg.pmulti(self.length, *tuple(channel_pulses))
                    ]
            else:
                gate_pulse = excitation_pulse.get_rect_cos_pulse_sequence(
                    device=device,
                    channel_amplitudes=channel_amplitudes_,
                    tail_length=float(gate.metadata['tail_length']),
                    length=self.length,
                    phase=0.0)

            return [device.pg.pmulti(pre_pause)
                    ] + gate_pulse + [device.pg.pmulti(post_pause)]

    setter = ParameterSetter()

    return Ramsey.Ramsey(device,
                         gate.metadata['target_qubit_id'],
                         '01',
                         (amplitudes, setter.amplitude_setter, 'amplitude'),
                         lengths=lengths,
                         target_freq_offset=target_freq_offset,
                         delay_seq_generator=setter.filler_func,
                         measurement_type='Ramsey_amplitude_scan',
                         additional_references={'gate': gate.id})
Пример #4
0
def zgate_ramsey(device, gate):
    def filler_func(length):
        channel_amplitudes_ = channel_amplitudes.channel_amplitudes(
            device, **{
                gate.metadata['carrier_name']:
                float(gate.metadata['amplitude'])
            })
        return excitation_pulse.get_rect_cos_pulse_sequence(
            device=device,
            channel_amplitudes=channel_amplitudes_,
            tail_length=float(gate.metadata['tail_length']),
            length=length,
            phase=0.0)

    return Ramsey.Ramsey_adaptive(device=device,
                                  qubit_id=gate.metadata['target_qubit_id'],
                                  set_frequency=False,
                                  delay_seq_generator=filler_func,
                                  measurement_type='Ramsey_long_process',
                                  additional_references={'gate': gate.id})
def iswap_frequency_scan(device, gate, q):
    channel_amplitudes_ = two_qubit_gate_channel_amplitudes(device, gate)
    frequency_delta = float(device.get_sample_global(name='parametric_frequency_shift_calibration_frequency_offset'))
    vf_pulse = [device.pg.pmulti(0, (gate.metadata['carrier_name'], pulses.vf, frequency_delta))]

    def filler_func(length):
        return vf_pulse + \
               excitation_pulse.get_rect_cos_pulse_sequence(device = device,
                                           channel_amplitudes = channel_amplitudes_,
                                           tail_length = float(gate.metadata['tail_length']),
                                           length = length,
                                           phase = 0.0) #+ \
               #excitation_pulse.get_rect_cos_pulse_sequence(device=device,
               #                            channel_amplitudes = channel_amplitudes_,
               #                            tail_length=float(gate.metadata['tail_length']),
               #                            length=length / 2,
               #                            phase=np.pi*float(gate.metadata['carrier_harmonic']))

    return Ramsey.Ramsey_adaptive(device=device, qubit_id=gate.metadata[q], set_frequency=False,
                           delay_seq_generator=filler_func, measurement_type='Ramsey_long_process', additional_references={'long_process': gate.id})
Пример #6
0
def benchmarking_pi2_multi(device,
                           qubit_ids,
                           *params,
                           interleaver=None,
                           two_qubit_gate=None,
                           max_pulses=None,
                           pause_length=0,
                           random_sequence_num=1,
                           seq_lengths_num=400):
    channel_amplitudes_ = {}
    pi2_pulses = {}
    generators = {}
    if max_pulses is None:
        max_pulses = []
        for qubit_id in qubit_ids:
            coherence_measurement = Ramsey.get_Ramsey_coherence_measurement(
                device, qubit_id)
            T2 = float(coherence_measurement.metadata['T'])
            pi2_pulses[qubit_id] = excitation_pulse.get_excitation_pulse(
                device, qubit_id, np.pi / 2.)
            pi2_pulse_length = float(pi2_pulses[qubit_id].metadata['length'])
            max_pulses.append(T2 / pi2_pulse_length)

        if two_qubit_gate is not None:
            max_pulses = np.asarray(max_pulses) / 3.

        max_pulses = min(max_pulses)

    for qubit_id in qubit_ids:
        pi2_pulses[qubit_id] = excitation_pulse.get_excitation_pulse(
            device, qubit_id, np.pi / 2.)
        channel_amplitudes_[qubit_id] = channel_amplitudes.channel_amplitudes(
            device.exdir_db.select_measurement_by_id(
                pi2_pulses[qubit_id].references['channel_amplitudes']))

    seq_lengths = np.asarray(
        np.round(np.linspace(0, max_pulses, seq_lengths_num)), int)

    def get_pulse_seq_z(z_phase, qubit_id):
        pg = device.pg
        z_pulse = [(c, vz, z_phase)
                   for c, a in channel_amplitudes_[qubit_id].items()]
        sequence_z = [pg.pmulti(0, *tuple(z_pulse))]
        return sequence_z

    def tensor_product(unitary, qubit_id):
        U = [[1]]
        for i in qubit_ids:
            U = np.kron(U, np.identity(2) if i != qubit_id else unitary)
        return U

    qubit_readout_pulse, readout_device = calibrated_readout.get_calibrated_measurer(
        device, qubit_ids)

    generators = {}
    for qubit_id in qubit_ids:
        HZ = {
            'H_' + qubit_id: {
                'pulses':
                get_pulse_seq_z(np.pi / 2, qubit_id) +
                pi2_pulses[qubit_id].get_pulse_sequence(np.pi) +
                get_pulse_seq_z(np.pi / 2, qubit_id),
                'unitary':
                np.sqrt(0.5) * tensor_product([[1, 1], [1, -1]], qubit_id),
                'price':
                1.0
            },
            'Z_' + qubit_id: {
                'pulses': get_pulse_seq_z(np.pi, qubit_id),
                'unitary': tensor_product([[1, 0], [0, -1]], qubit_id),
                'price': 0.1
            },
            'Z/2_' + qubit_id: {
                'pulses': get_pulse_seq_z(np.pi / 2, qubit_id),
                'unitary': tensor_product([[1, 0], [0, 1j]], qubit_id),
                'price': 0.1
            },
            '-Z/2_' + qubit_id: {
                'pulses': get_pulse_seq_z(-np.pi / 2., qubit_id),
                'unitary': tensor_product([[1, 0], [0, -1j]], qubit_id),
                'price': 0.1
            },
            'I_' + qubit_id: {
                'pulses': [],
                'unitary': tensor_product([[1, 0], [0, 1]], qubit_id),
                'price': 0.1
            }
        }
        generators[qubit_id] = HZ

    if len(qubit_ids) == 2:
        HZ_group = clifford.two_qubit_clifford(
            *tuple([g for g in generators.values()]),
            plus_op_parallel=device.pg.parallel,
            cphase=two_qubit_gate)
    elif len(qubit_ids) == 1:
        HZ_group = clifford.generate_group(generators[qubit_ids[0]])
    else:
        raise ValueError('More than two qubits are unsupported')

    print('group length:', len(HZ_group))

    ro_seq = [
        device.pg.pmulti(pause_length)
    ] + device.trigger_readout_seq + qubit_readout_pulse.get_pulse_sequence()
    pi2_bench = interleaved_benchmarking.interleaved_benchmarking(
        readout_device,
        set_seq=lambda x: device.pg.set_seq(device.pre_pulses + x + ro_seq),
        interleavers=HZ_group)

    pi2_bench.random_sequence_num = random_sequence_num
    random_sequence_ids = np.arange(random_sequence_num)

    references = {('pi2_pulse', qubit_id): pi2_pulses[qubit_id].id
                  for qubit_id in qubit_ids}

    pi2_bench.prepare_random_interleaving_sequences()

    ### search db for previous version of the interleaver measurement
    found = False
    try:
        clifford_bench = device.exdir_db.select_measurement(
            measurement_type='clifford_bench',
            metadata={'qubit_ids': ','.join(qubit_ids)},
            references_that=references)
        found = True
    except IndexError:
        pass

    if random_sequence_num > 1:
        params = tuple([(random_sequence_ids,
                         pi2_bench.set_interleaved_sequence,
                         'Random sequence id', '')] + [p for p in params])

    if (not found) or (interleaver is None):
        measurement_name = [m for m in pi2_bench.get_points().keys()][0]
        fitter_arguments = (measurement_name, exp.exp_fitter(), 0,
                            np.arange(len(params)).tolist())

        clifford_bench = device.sweeper.sweep_fit_dataset_1d_onfly(
            pi2_bench,
            (seq_lengths, pi2_bench.set_sequence_length_and_regenerate,
             'Gate number', ''),
            *params,
            fitter_arguments=fitter_arguments,
            measurement_type='clifford_bench',
            metadata={'qubit_ids': ','.join(qubit_ids)},
            shuffle=True,
            references=references)

    ## interleaver measurement is found, bench "interleaver" gate
    references['Clifford-bench'] = clifford_bench.id
    if interleaver is not None:
        if 'references' in interleaver:
            references.update(interleaver['references'])

        pi2_bench.set_target_pulse(interleaver)

        measurement_name = [m for m in pi2_bench.get_points().keys()][0]
        fitter_arguments = (measurement_name, exp.exp_fitter(), 0,
                            np.arange(len(params)).tolist())

        interleaved_bench = device.sweeper.sweep_fit_dataset_1d_onfly(
            pi2_bench,
            (seq_lengths, pi2_bench.set_sequence_length_and_regenerate,
             'Gate number', ''),
            *params,
            fitter_arguments=fitter_arguments,
            measurement_type='interleaved_bench',
            metadata={'qubit_ids': ','.join(qubit_ids)},
            shuffle=True,
            references=references)

        return interleaved_bench

    return clifford_bench
Пример #7
0
def benchmarking_pi2(device,
                     qubit_id,
                     *params,
                     pause_length=0,
                     random_sequence_num=1,
                     seq_lengths_num=400):
    coherence_measurement = Ramsey.get_Ramsey_coherence_measurement(
        device, qubit_id)
    T2 = float(coherence_measurement.metadata['T'])
    pi2_pulse = excitation_pulse.get_excitation_pulse(device, qubit_id,
                                                      np.pi / 2.)
    pi2_pulse_length = float(pi2_pulse.metadata['length'])
    channel_amplitudes_ = channel_amplitudes.channel_amplitudes(
        device.exdir_db.select_measurement_by_id(
            pi2_pulse.references['channel_amplitudes']))
    max_pulses = T2 / pi2_pulse_length
    seq_lengths = np.asarray(
        np.round(np.linspace(0, max_pulses, seq_lengths_num)), int)

    def get_pulse_seq_z(z_phase):
        pg = device.pg
        z_pulse = [(c, vz, z_phase) for c, a in channel_amplitudes_.items()]
        sequence_z = [pg.pmulti(0, *tuple(z_pulse))]
        return sequence_z

    qubit_readout_pulse, readout_device = calibrated_readout.get_calibrated_measurer(
        device, [qubit_id])
    HZ = {
        'H': {
            'pulses':
            get_pulse_seq_z(np.pi / 2) + pi2_pulse.get_pulse_sequence(np.pi) +
            get_pulse_seq_z(np.pi / 2),
            'unitary':
            np.sqrt(0.5) * np.asarray([[1, 1], [1, -1]]),
            'price':
            1.0
        },
        'Z': {
            'pulses': get_pulse_seq_z(np.pi),
            'unitary': np.asarray([[1, 0], [0, -1]]),
            'price': 0.1
        },
        'Z/2': {
            'pulses': get_pulse_seq_z(np.pi / 2),
            'unitary': np.asarray([[1, 0], [0, 1j]]),
            'price': 0.1
        },
        '-Z/2': {
            'pulses': get_pulse_seq_z(-np.pi / 2.),
            'unitary': np.asarray([[1, 0], [0, -1j]]),
            'price': 0.1
        },
        'I': {
            'pulses': [],
            'unitary': np.asarray([[1, 0], [0, 1]]),
            'price': 0.1
        }
    }

    HZ_group = clifford.generate_group(HZ)

    ro_seq = [
        device.pg.pmulti(pause_length)
    ] + device.trigger_readout_seq + qubit_readout_pulse.get_pulse_sequence()
    pi2_bench = interleaved_benchmarking.interleaved_benchmarking(
        readout_device,
        set_seq=lambda x: device.pg.set_seq(device.pre_pulses + x + ro_seq))

    pi2_bench.interleavers = HZ_group

    pi2_bench.random_sequence_num = random_sequence_num
    random_sequence_ids = np.arange(random_sequence_num)

    pi2_bench.prepare_random_interleaving_sequences()
    clifford_bench = device.sweeper.sweep(
        pi2_bench, (seq_lengths, pi2_bench.set_sequence_length_and_regenerate,
                    'Gate number', ''),
        *params, (random_sequence_ids, pi2_bench.set_interleaved_sequence,
                  'Random sequence id', ''),
        shuffle=True,
        measurement_type='pi2_bench',
        metadata={'qubit_id': qubit_id},
        references={'pi2_pulse': pi2_pulse.id})
    return clifford_bench
def get_gate_calibration(device, gate, recalibrate=True, force_recalibration=False, rotation_angle=None):
    frequency_rounding = float(device.get_sample_global(name='frequency_rounding'))
    channel_amplitudes_ = two_qubit_gate_channel_amplitudes(device, gate)

    T2_q1 = float(device.exdir_db.select_measurement_by_id(Ramsey.get_Ramsey_coherence_measurement(device, qubit_id=gate.metadata['q1']).id).metadata['T'])
    T2_q2 = float(device.exdir_db.select_measurement_by_id(Ramsey.get_Ramsey_coherence_measurement(device, qubit_id=gate.metadata['q2']).id).metadata['T'])
    #print (T2_q1.metadata)
    T2 = 1/(1/T2_q1+1/T2_q2)

    gate_nophase = get_iswap_pulse_nophase(device, gate, frequency_shift = 0)
    expected_frequency = float(device.exdir_db.select_measurement(measurement_type='fit_dataset_1d', references_that={'fit_source': gate_nophase.references['Rabi_rect']}).metadata['f'])

    iteration = 0
    best_frequency = 0
    periods = 1
    max_iterations = 1

    while iteration < max_iterations:  # loop exit condition: frequency scan has points closer than frequency_rounding
        #coherence_time = float(device.exdir_db.select_measurement_by_id(gate_noshift.references['Rabi_rect']).metadata['decay'])
        length = float(gate_nophase.metadata['length'])
        try:
            q1_excitation_pulse = excitation_pulse.get_excitation_pulse(device, qubit_id='1', rotation_angle=np.pi)
            frequency_shift_scan_ = device.exdir_db.select_measurement(measurement_type='frequency_shift_scan',
                                                        references_that = {'parametric_pulse': gate_nophase.id,
                                                                           'excitation_pulse': q1_excitation_pulse.id})
        except IndexError as e:
            scan_points = int(device.get_sample_global(name='adaptive_Rabi_amplitude_scan_points'))*3
            frequency_shift_scan_ = frequency_shift_scan(device, gate, gate_nophase, (np.linspace(-np.sqrt(periods)/(length), np.sqrt(periods)/(length), scan_points)+best_frequency))

        frequency_shift_scan_delta = frequency_shift_scan_.datasets['resultnumbers'].parameters[0].values[1] - \
                                     frequency_shift_scan_.datasets['resultnumbers'].parameters[0].values[0]

        target = frequency_shift_scan_.datasets['resultnumbers'].data[:, 1] - frequency_shift_scan_.datasets['resultnumbers'].data[:, 2]
        best_frequency = frequency_shift_scan_.datasets['resultnumbers'].parameters[0].values[np.argmin(target)]
        best_frequency = frequency_rounding*np.round(best_frequency/frequency_rounding)

        periods = 1+(4**iteration-1)*2
        gate_nophase = get_iswap_pulse_nophase(device, gate, frequency_shift=best_frequency, rotation_angle=np.pi*periods+np.pi/16., expected_frequency=expected_frequency)
        expected_frequency = float(device.exdir_db.select_measurement(measurement_type='fit_dataset_1d', references_that={'fit_source': gate_nophase.references['Rabi_rect']}).metadata['f'])
        iteration += 1
        if frequency_shift_scan_delta < frequency_rounding or float(gate_nophase.metadata['length']) > T2:
            break

    #gate_nophase = get_iswap_pulse_nophase(device, gate, frequency_shift=best_frequency, rotation_angle=np.pi,
    #                                  expected_frequency=expected_frequency)
    length_calibration = get_parametric_iswap_length_adaptive_calibration(device, gate, frequency_shift=best_frequency, recalibrate=recalibrate,
                                                     force_recalibration=force_recalibration)

    gate_nophase = ParametricTwoQubitGate(device, q1=gate.metadata['q1'], q2=gate.metadata['q2'], phase_q1=np.nan,
                           phase_q2=np.nan, rotation_angle=rotation_angle, length=length_calibration.metadata['length'],
                           tail_length=gate.metadata['tail_length'], channel_amplitudes=channel_amplitudes_.id,
                           Rabi_rect_measurement=gate_nophase.references['Rabi_rect'], gate_settings=gate.id,
                           frequency_shift=best_frequency, carrier_name=gate.metadata['carrier_name'],
                           carrier_harmonic=gate.metadata['carrier_harmonic'])

    try:
        references = {'process': gate_nophase.id}
        metadata_scan1 = {'q1': gate.metadata['q1'],
                          'q2': gate.metadata['q2']}
        metadata_scan2 = {'q1': gate.metadata['q2'],
                          'q2': gate.metadata['q1']}
        phase_scan1 = device.exdir_db.select_measurement(measurement_type='Ramsey_process', metadata=metadata_scan1, references_that=references)
        phase_scan2 = device.exdir_db.select_measurement(measurement_type='Ramsey_process', metadata=metadata_scan2, references_that=references)
        phase_scan1_fit = device.exdir_db.select_measurement(measurement_type='fit_dataset_1d', references_that={'fit_source': phase_scan1.id})
        phase_scan2_fit = device.exdir_db.select_measurement(measurement_type='fit_dataset_1d', references_that={'fit_source': phase_scan2.id})
    except IndexError as e:
        traceback.print_exc()
        if not recalibrate:
            raise
        phase_scan1, phase_scan2, phase_scan1_fit, phase_scan2_fit = calibrate_iswap_phase_single_pulse(device, gate_nophase, 1)

    # we want -np.pi/2. phase from iSWAP; exchange qubits since phase is applied after iSWAP
    phase_q2 = -float(phase_scan1_fit.metadata['phi']) - np.pi/2.
    phase_q1 = -float(phase_scan2_fit.metadata['phi']) - np.pi/2.

    gate_with_phase = ParametricTwoQubitGate(device,
                                  q1=gate.metadata['q1'],
                                  q2=gate.metadata['q2'],
                                  phase_q1=phase_q1,
                                  phase_q2=phase_q2,
                                  rotation_angle = rotation_angle,
                                  length=gate_nophase.metadata['length'],
                                  tail_length=gate.metadata['tail_length'],
                                  channel_amplitudes=channel_amplitudes_.id,
                                  Rabi_rect_measurement=gate_nophase.id,
                                  phase_scan_q1=phase_scan1.id,
                                  phase_scan_q2=phase_scan2.id,
                                  gate_settings=gate.id,
                                  frequency_shift=best_frequency,
                                  carrier_name=gate.metadata['carrier_name'],
                                  carrier_harmonic=gate.metadata['carrier_harmonic'])
    return gate_with_phase