def TEST_RTE(qubit_idx: int, platf_cfg: str, measurements: int):
    """

    """
    p = oqh.create_program('RTE', platf_cfg)

    k = oqh.create_kernel('RTE', p)
    k.prepz(qubit_idx)
    ######################
    # Parity check
    ######################
    for m in range(measurements):
        # Superposition
        k.gate('rx90', [qubit_idx])
        # CZ emulation
        k.gate('i', [qubit_idx])
        k.gate('i', [qubit_idx])
        k.gate('i', [qubit_idx])
        # Refocus
        k.gate('rx180', [qubit_idx])
        # CZ emulation
        k.gate('i', [qubit_idx])
        k.gate('i', [qubit_idx])
        k.gate('i', [qubit_idx])
        # Recovery pulse
        k.gate('rx90', [qubit_idx])
        k.measure(qubit_idx)

    p.add_kernel(k)

    p = oqh.compile(p)
    return p
Ejemplo n.º 2
0
def openql_program_from_pygsti_expList(expList,
                                       program_name: str,
                                       qubits: list,
                                       platf_cfg: str,
                                       start_idx: int = 0,
                                       recompile=True):

    p = oqh.create_program(program_name, platf_cfg)
    # N.B. program name added before compilation as it is used in a check
    p.filename = join(p.output_dir, p.name + '.qisa')
    if oqh.check_recompilation_needed(p.filename, platf_cfg, recompile):

        for i, gatestring in enumerate(expList):
            kernel_name = 'G {} {}'.format(i, gatestring)
            k = openql_kernel_from_gatestring(gatestring=gatestring,
                                              qubits=qubits,
                                              kernel_name=kernel_name,
                                              program=p)
            p.add_kernel(k)
        p = oqh.compile(p)

    p.sweep_points = np.arange(len(expList), dtype=float) + start_idx
    # FIXME: remove try-except, when we depend hardly on >=openql-0.6
    try:
        p.set_sweep_points(p.sweep_points)
    except TypeError:
        # openql-0.5 compatibility
        p.set_sweep_points(p.sweep_points, len(p.sweep_points))

    return p
Ejemplo n.º 3
0
 def test_create_kernel(self):
     curdir = os.path.dirname(__file__)
     config_fn = os.path.join(curdir, 'test_cfg_CCL.json')
     p = oqh.create_program('test_program', config_fn)
     k = oqh.create_kernel('my_kernel', p)
     # The kernels are prefixed with k_
     self.assertEqual(k.name, 'k_my_kernel')
Ejemplo n.º 4
0
def echo(times, qubit_idx: int, platf_cfg: str):
    """
    Single qubit Echo sequence.
    Writes output files to the directory specified in openql.
    Output directory is set as an attribute to the program for convenience.

    Input pars:
        times:          the list of waiting times for each Echo element
        qubit_idx:      int specifying the target qubit (starting at 0)
        platf_cfg:      filename of the platform config file
    Returns:
        p:              OpenQL Program object containing

    """
    p = oqh.create_program("echo", platf_cfg)

    for i, time in enumerate(times[:-4]):
        k = oqh.create_kernel("echo_{}".format(i), p)
        k.prepz(qubit_idx)
        # nr_clocks = int(time/20e-9/2)
        wait_nanoseconds = int(round(time/1e-9/2))
        k.gate('rx90', [qubit_idx])
        k.gate("wait", [qubit_idx], wait_nanoseconds)
        k.gate('rx180', [qubit_idx])
        k.gate("wait", [qubit_idx], wait_nanoseconds)
        k.gate('rx90', [qubit_idx])
        k.measure(qubit_idx)
        p.add_kernel(k)

    # adding the calibration points
    oqh.add_single_qubit_cal_points(p,  qubit_idx=qubit_idx)

    p = oqh.compile(p)
    return p
Ejemplo n.º 5
0
def FluxTimingCalibration(qubit_idx: int, times, platf_cfg: str,
                          flux_cw: str='fl_cw_02',
                          qubit_other_idx=0,
                          cal_points: bool=True):
    """
    A Ramsey sequence with varying waiting times `times` around a flux pulse.
    """
    p = oqh.create_program('FluxTimingCalibration', platf_cfg)

    # don't use last 4 points if calibration points are used
    if cal_points:
        times = times[:-4]
    for i_t,t in enumerate(times):
        t_nanoseconds = int(round(t/1e-9))
        k = oqh.create_kernel('pi_flux_pi_{}'.format(i_t), p)
        k.prepz(qubit_idx)
        k.gate('rx90', [qubit_idx])
        # k.gate("wait", [0, 1, 2, 3, 4, 5, 6], 0) #alignment workaround
        k.gate("wait", [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], 0) #alignment workaround
        # k.gate(flux_cw, [2, 0])
        k.gate('sf_square', [qubit_idx])
        if t_nanoseconds > 10:
            # k.gate("wait", [0, 1, 2, 3, 4, 5, 6], t_nanoseconds)
            k.gate("wait", [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], t_nanoseconds) #alignment workaround
            # k.gate("wait", [qubit_idx], t_nanoseconds)
        k.gate('rx90', [qubit_idx])
        k.measure(qubit_idx)
        p.add_kernel(k)

    if cal_points:
        oqh.add_single_qubit_cal_points(p,  qubit_idx=qubit_idx)
    p = oqh.compile(p)
    return p
Ejemplo n.º 6
0
def butterfly(qubit_idx: int, initialize: bool, platf_cfg: str):
    """
    Performs a 'butterfly' sequence on the qubit specified.
        0:  prepz (RO) -      - RO - RO
        1:  prepz (RO) - x180 - RO - RO

    Args:
        qubit_idx (int)  : index of the qubit
        initialize (bool): if True does an extra initial measurement to
            post select data.
        platf_cfg (str)  : openql config used for setup.

    """
    p = oqh.create_program('butterfly', platf_cfg)

    k = oqh.create_kernel('0', p)
    k.prepz(qubit_idx)
    if initialize:
        k.measure(qubit_idx)
    k.measure(qubit_idx)
    k.measure(qubit_idx)
    p.add_kernel(k)

    k = oqh.create_kernel('1', p)
    k.prepz(qubit_idx)
    if initialize:
        k.measure(qubit_idx)
    k.x(qubit_idx)
    k.measure(qubit_idx)
    k.measure(qubit_idx)
    p.add_kernel(k)

    p = oqh.compile(p)

    return p
Ejemplo n.º 7
0
def pulsed_spec_seq(qubit_idx: int, spec_pulse_length: float,
                    platf_cfg: str):
    """
    Sequence for pulsed spectroscopy.

    Important notes: because of the way the CCL functions this sequence is
    made by repeating multiple "spec" pulses of 20ns back to back.
    As such the spec_pulse_lenght must be a multiple of 20e-9. If
    this is not the case the spec_pulse_length will be rounded.

    """
    p = oqh.create_program("pulsed_spec_seq", platf_cfg)
    k = oqh.create_kernel("main", p)

    nr_clocks = int(spec_pulse_length/20e-9)

    for i in range(nr_clocks):
        # The spec pulse is a pulse that lasts 20ns, because of the way the VSM
        # control works. By repeating it the duration can be controlled.
        k.gate('spec', [qubit_idx])
    k.measure(qubit_idx)
    p.add_kernel(k)

    p = oqh.compile(p)
    return p
Ejemplo n.º 8
0
def randomized_benchmarking(qubit_idx: int, platf_cfg: str,
                            nr_cliffords, nr_seeds: int,
                            net_clifford: int=0, restless: bool=False,
                            program_name: str='randomized_benchmarking',
                            cal_points: bool=True,
                            double_curves: bool=False):
    '''
    Input pars:
        qubit_idx:      int specifying the target qubit (starting at 0)
        platf_cfg:      filename of the platform config file
        nr_cliffords:   list nr_cliffords for which to generate RB seqs
        nr_seeds:       int  nr_seeds for which to generate RB seqs
        net_clifford:   int index of net clifford the sequence should perform
                            0 -> Idx
                            3 -> rx180
        restless:       bool, does not initialize if restless is True
        program_name:           some string that can be used as a label.
        cal_points:     bool whether to replace the last two elements with
                        calibration points, set to False if you want
                        to measure a single element (for e.g. optimization)

        double_curves: Alternates between net clifford 0 and 3

    Returns:
        p:              OpenQL Program object

    generates a program for single qubit Clifford based randomized
    benchmarking.
    '''
    net_cliffords = [0, 3]  # Exists purely for the double curves mode
    p = oqh.create_program(program_name, platf_cfg)

    i = 0
    for seed in range(nr_seeds):
        for j, n_cl in enumerate(nr_cliffords):
            k = oqh.create_kernel('RB_{}Cl_s{}'.format(n_cl, seed), p)
            if not restless:
                k.prepz(qubit_idx)
            if cal_points and (j == (len(nr_cliffords)-4) or
                               j == (len(nr_cliffords)-3)):
                k.measure(qubit_idx)

            elif cal_points and (j == (len(nr_cliffords)-2) or
                                 j == (len(nr_cliffords)-1)):
                k.x(qubit_idx)
                k.measure(qubit_idx)
            else:
                if double_curves:
                    net_clifford = net_cliffords[i % 2]
                    i += 1
                cl_seq = rb.randomized_benchmarking_sequence(
                    n_cl, desired_net_cl=net_clifford)
                # pulse_keys = rb.decompose_clifford_seq(cl_seq)
                for cl in cl_seq:
                    k.gate('cl_{}'.format(cl), [qubit_idx])
                k.measure(qubit_idx)
            p.add_kernel(k)

    p = oqh.compile(p)
    return p
Ejemplo n.º 9
0
def FluxTimingCalibration(qubit_idx: int, times, platf_cfg: str,
                          cal_points: bool=True):
    """
    A Ramsey sequence with varying waiting times `times` around a flux pulse.
    """
    p = oqh.create_program('FluxTimingCalibration', platf_cfg)

    # don't use last 4 points if calibration points are used
    if cal_points:
        times = times[:-4]
    for t in times:
        t_nanoseconds = int(round(t/1e-9))
        k = oqh.create_kernel('pi-flux-pi', p)
        k.prepz(qubit_idx)
        k.gate('rx90', [qubit_idx])
        k.gate('fl_cw_02', [2, 0])
        if t_nanoseconds > 10:
            k.gate("wait", [qubit_idx], t_nanoseconds)
        k.gate('rx90', [qubit_idx])
        k.measure(qubit_idx)
        p.add_kernel(k)

    if cal_points:
        oqh.add_single_qubit_cal_points(p,  qubit_idx=qubit_idx)
    p = oqh.compile(p)
    return p
Ejemplo n.º 10
0
def FastFeedbackControl(latency, qubit_idx: int, platf_cfg: str):
    """
    Single qubit sequence to test fast feedback control (fast conditional
    execution).
    Writes output files to the directory specified in openql.
    Output directory is set as an attribute to the program for convenience.

    Input pars:
        latency:        the waiting time between measurement and the feedback
                          pulse, which should be longer than the feedback
                          latency.
        feedback:       if apply
        qubit_idx:      int specifying the target qubit (starting at 0)
        platf_cfg:      filename of the platform config file
    Returns:
        p:              OpenQL Program object containing


    """
    p = oqh.create_program("FastFeedbackControl", platf_cfg)

    k = oqh.create_kernel("FastFdbkCtrl_nofb", p)
    k.prepz(qubit_idx)
    k.gate('rx90', [qubit_idx])
    # k.gate('rx180', [qubit_idx])
    k.measure(qubit_idx)
    wait_nanoseconds = int(round(latency/1e-9))
    k.gate("wait", [qubit_idx], wait_nanoseconds)
    k.gate("i", [qubit_idx])
    k.measure(qubit_idx)

    p.add_kernel(k)

    k = oqh.create_kernel("FastFdbkCtrl_fb0", p)
    k.prepz(qubit_idx)
    k.gate('rx90', [qubit_idx])
    # k.gate('rx180', [qubit_idx])
    k.measure(qubit_idx)
    wait_nanoseconds = int(round(latency/1e-9))
    k.gate("wait", [qubit_idx], wait_nanoseconds)
    k.gate('C0rx180', [qubit_idx])  # fast feedback control here
    k.measure(qubit_idx)
    p.add_kernel(k)

    k = oqh.create_kernel("FastFdbkCtrl_fb1", p)
    k.prepz(qubit_idx)
    k.gate('rx90', [qubit_idx])
    # k.gate('rx180', [qubit_idx])
    k.measure(qubit_idx)
    wait_nanoseconds = int(round(latency/1e-9))
    k.gate("wait", [qubit_idx], wait_nanoseconds)
    k.gate('C1rx180', [qubit_idx])  # fast feedback control here
    k.measure(qubit_idx)
    p.add_kernel(k)

    # adding the calibration points
    oqh.add_single_qubit_cal_points(p,  qubit_idx=qubit_idx)

    p = oqh.compile(p)
    return p
Ejemplo n.º 11
0
def complex_Ramsey(times, qubit_idx: int, platf_cfg: str):
    """
    Single qubit Ramsey sequence.
    Writes output files to the directory specified in openql.
    Output directory is set as an attribute to the program for convenience.

    Input pars:
        times:          the list of waiting times for each Ramsey element
        qubit_idx:      int specifying the target qubit (starting at 0)
        platf_cfg:      filename of the platform config file
    Returns:
        p:              OpenQL Program object containing

    """
    p = oqh.create_program("complex_Ramsey", platf_cfg)

    prerotations = ['rx90', 'rym90']
    timeloop = times[:-4][::2]
    for i, time in enumerate(timeloop):
        for rot in prerotations:
            k = oqh.create_kernel("Ramsey_" + rot + "_{}".format(i), p)
            k.prepz(qubit_idx)
            wait_nanoseconds = int(round(time / 1e-9))
            k.gate('rx90', [qubit_idx])
            k.gate("wait", [qubit_idx], wait_nanoseconds)
            k.gate(rot, [qubit_idx])
            k.measure(qubit_idx)
            p.add_kernel(k)

    # adding the calibration points
    oqh.add_single_qubit_cal_points(p, qubit_idx=qubit_idx)

    p = oqh.compile(p)
    return p
Ejemplo n.º 12
0
def motzoi_XY(qubit_idx: int, platf_cfg: str,
              program_name: str='motzoi_XY'):
    '''
    Sequence used for calibrating the motzoi parameter.
    Consists of yX and xY

    Beware that the elements alternate, if you want to measure both Xy and Yx
    at each motzoi you need repeating motzoi parameters. This was chosen
    to be more easily compatible with standard detector functions and sweep pts

    '''
    p = oqh.create_program(program_name, platf_cfg)

    k = oqh.create_kernel("yX", p)
    k.prepz(qubit_idx)
    k.gate('ry90', [qubit_idx])
    k.gate('rx180', [qubit_idx])
    k.measure(qubit_idx)
    p.add_kernel(k)

    k = oqh.create_kernel("xY", p)
    k.prepz(qubit_idx)
    k.gate('rx90', [qubit_idx])
    k.gate('ry180', [qubit_idx])
    k.measure(qubit_idx)
    p.add_kernel(k)

    p = oqh.compile(p)
    return p
Ejemplo n.º 13
0
def pulsed_spec_seq_v2(qubit_idx: int, spec_pulse_length: float,
                       platf_cfg: str, trigger_idx: int):
    """
    Sequence for pulsed spectroscopy, similar to old version. Difference is that
    this one triggers the 0th trigger port of the CCLight and usus the zeroth
    wave output on the AWG (currently hardcoded, should be improved)

    """
    p = oqh.create_program("pulsed_spec_seq_v2", platf_cfg)
    k = oqh.create_kernel("main", p)

    nr_clocks = int(spec_pulse_length/20e-9)

    for i in range(nr_clocks):
        # The spec pulse is a pulse that lasts 20ns, because of the way the VSM
        # control works. By repeating it the duration can be controlled.
        k.gate('spec', [trigger_idx])
    if trigger_idx != qubit_idx:
        k.wait([trigger_idx, qubit_idx], 0)

    k.measure(qubit_idx)
    p.add_kernel(k)

    p = oqh.compile(p)
    return p
Ejemplo n.º 14
0
def RTE(qubit_idx: int, sequence_type: str, platf_cfg: str,
        net_gate: str, feedback=False):
    """
    Creates a sequence for the rounds to event (RTE) experiment

    Args:
        qubit_idx             (int) :
        sequence_type ['echo'|'pi'] :
        net_gate         ['i'|'pi'] :
        feedback             (bool) : if last measurement == 1, then apply
            an extra pi-pulse. N.B. more options for fast feedback should be
            added.

    N.B. there is some hardcoded stuff in here (such as rest times).
    It should be better documented what this is and what it does.
    """
    p = oqh.create_program('RTE', platf_cfg)

    k = oqh.create_kernel('RTE', p)
    if sequence_type == 'echo':
        k.gate('rx90', [qubit_idx])
        k.gate('i', [qubit_idx])
        k.gate('i', [qubit_idx])
        k.gate('i', [qubit_idx])
        #k.gate('i', [qubit_idx])
        k.gate('rx180', [qubit_idx])
        k.gate('i', [qubit_idx])
        k.gate('i', [qubit_idx])
        k.gate('i', [qubit_idx])
        #k.gate('i', [qubit_idx])
        if net_gate == 'pi':
            k.gate('rxm90', [qubit_idx])
        elif net_gate == 'i':
            k.gate('rx90', [qubit_idx])
        else:
            raise ValueError('net_gate ({})should be "i" or "pi"'.format(
                net_gate))
        if feedback:
            k.gate("wait", [qubit_idx], 20)
            k.gate('C1rx180', [qubit_idx])
    elif sequence_type == 'pi':
        if net_gate == 'pi':
            k.gate('rx180', [qubit_idx])
        elif net_gate == 'i':
            pass
        else:
            raise ValueError('net_gate ({})should be "i" or "pi"'.format(
                net_gate))
        if feedback:
            k.gate("wait", [qubit_idx], 20)
            k.gate('C1rx180', [qubit_idx])
    else:
        raise ValueError('sequence_type ({})should be "echo" or "pi"'.format(
            sequence_type))
    k.measure(qubit_idx)
    p.add_kernel(k)

    p = oqh.compile(p)
    return p
Ejemplo n.º 15
0
def T1(qubit_idx: int,
       platf_cfg: str,
       times: list,
       nr_cz_instead_of_idle_time: list = None,
       qb_cz_idx: int = None,
       nr_flux_dance: float = None,
       wait_time_after_flux_dance: float = 0):
    """
    Single qubit T1 sequence.
    Writes output files to the directory specified in openql.
    Output directory is set as an attribute to the program for convenience.

    Input pars:
        times:          the list of waiting times for each T1 element
        qubit_idx:      int specifying the target qubit (starting at 0)
        platf_cfg:      filename of the platform config file
    Returns:
        p:              OpenQL Program object containing


    """
    p = oqh.create_program('T1', platf_cfg)

    for i, time in enumerate(times[:-4]):
        k = oqh.create_kernel('T1_{}'.format(i), p)
        k.prepz(qubit_idx)

        if nr_flux_dance:
            for _ in range(int(nr_flux_dance)):
                for step in [1, 2, 3, 4]:
                    # if refocusing:
                    #     k.gate(f'flux-dance-{step}-refocus', [0])
                    # else:
                    k.gate(f'flux-dance-{step}', [0])
                k.gate("wait", [], 0)  # alignment
            k.gate("wait", [], wait_time_after_flux_dance)

        k.gate('rx180', [qubit_idx])

        if nr_cz_instead_of_idle_time is not None:
            for n in range(nr_cz_instead_of_idle_time[i]):
                k.gate("cz", [qubit_idx, qb_cz_idx])
            k.gate("wait", [], 0)  # alignment
            k.gate("wait", [], wait_time_after_flux_dance)
        else:
            wait_nanoseconds = int(round(time / 1e-9))
            k.gate("wait", [qubit_idx], wait_nanoseconds)

        k.measure(qubit_idx)
        p.add_kernel(k)

    # adding the calibration points
    oqh.add_single_qubit_cal_points(p, qubit_idx=qubit_idx)

    p = oqh.compile(p)
    return p
Ejemplo n.º 16
0
def ef_rabi_seq(q0: int,
                amps: list,
                platf_cfg: str,
                recovery_pulse: bool = True,
                add_cal_points: bool = True):
    """
    Sequence used to calibrate pulses for 2nd excited state (ef/12 transition)

    Timing of the sequence:
    q0:   --   X180 -- X12 -- (X180) -- RO

    Args:
        q0      (str): name of the addressed qubit
        amps   (list): amps for the two state pulse, note that these are only
            used to label the kernels. Load the pulse in the LutMan
        recovery_pulse (bool): if True adds a recovery pulse to enhance
            contrast in the measured signal.
    """
    if len(amps) > 18:
        raise ValueError('Only 18 free codewords available for amp pulses')

    p = oqh.create_program("ef_rabi_seq", platf_cfg)
    # These angles correspond to special pi/2 pulses in the lutman
    for i, amp in enumerate(amps):
        # cw_idx corresponds to special hardcoded pulses in the lutman
        cw_idx = i + 9

        k = oqh.create_kernel("ef_A{}".format(int(abs(1000 * amp))), p)
        k.prepz(q0)
        k.gate('rx180', [q0])
        k.gate('cw_{:02}'.format(cw_idx), [q0])
        if recovery_pulse:
            k.gate('rx180', [q0])
        k.measure(q0)
        p.add_kernel(k)
    if add_cal_points:
        p = oqh.add_single_qubit_cal_points(p, qubit_idx=q0)

    p = oqh.compile(p)

    if add_cal_points:
        cal_pts_idx = [
            amps[-1] + .1, amps[-1] + .15, amps[-1] + .2, amps[-1] + .25
        ]
    else:
        cal_pts_idx = []

    p.sweep_points = np.concatenate([amps, cal_pts_idx])
    # FIXME: remove try-except, when we depend hardly on >=openql-0.6
    try:
        p.set_sweep_points(p.sweep_points)
    except TypeError:
        # openql-0.5 compatibility
        p.set_sweep_points(p.sweep_points, len(p.sweep_points))
    return p
Ejemplo n.º 17
0
def single_elt_on(qubit_idx: int, platf_cfg: str):
    p = oqh.create_program('single_elt_on', platf_cfg)

    k = oqh.create_kernel('main', p)

    k.prepz(qubit_idx)
    k.x(qubit_idx)
    k.measure(qubit_idx)
    p.add_kernel(k)

    p = oqh.compile(p)
    return p
Ejemplo n.º 18
0
def spin_lock_echo(times, qubit_idx: int, platf_cfg: str):
    """
    Single qubit Echo sequence.
    Writes output files to the directory specified in openql.
    Output directory is set as an attribute to the program for convenience.

    Input pars:
        times:          the list of waiting times for each Echo element
        qubit_idx:      int specifying the target qubit (starting at 0)
        platf_cfg:      filename of the platform config file
    Returns:
        p:              OpenQL Program object containing

    """
    p = oqh.create_program("spin_lock_echo", platf_cfg)

    for i, time in enumerate(times[:-4]):

        k = oqh.create_kernel("spin_lock_echo{}".format(i), p)
        k.prepz(qubit_idx)
        # nr_clocks = int(time/20e-9/2)
        square_us_cycles = np.floor(time / 1e-6).astype(int)
        square_ns_cycles = np.round(
            (time % 1e-6) / mw_gate_duration).astype(int)
        wait_nanoseconds = 1
        # print("square_us_cycles", square_us_cycles)
        # print("square_us_cycles", square_ns_cycles)
        k.gate('rYm90', [qubit_idx])
        k.gate("wait", [qubit_idx], wait_nanoseconds)
        k.gate('rx180', [qubit_idx])
        k.gate("wait", [qubit_idx], wait_nanoseconds)
        for suc in range(square_us_cycles):
            k.gate('cw_10',
                   [qubit_idx])  # make sure that the square pulse lasts 1us
        for snc in range(square_ns_cycles):
            k.gate('cw_11', [
                qubit_idx
            ])  # make sure that the square pulse lasts mw_gate_duration ns
        k.gate("wait", [qubit_idx], wait_nanoseconds)
        k.gate('rx180', [qubit_idx])
        k.gate("wait", [qubit_idx], wait_nanoseconds)
        k.gate('rYm90', [qubit_idx])
        k.measure(qubit_idx)
        p.add_kernel(k)

    # adding the calibration points
    oqh.add_single_qubit_cal_points(p, qubit_idx=qubit_idx)

    p = oqh.compile(p)
    return p
Ejemplo n.º 19
0
    def test_compile(self):
        """
        Only tests the compile helper by compiling an empty file.
        """
        curdir = os.path.dirname(__file__)
        config_fn = os.path.join(curdir, 'test_cfg_CCL.json')
        p = oqh.create_program('test_program', config_fn)
        k = oqh.create_kernel('test_kernel', p)
        p.add_kernel(k)
        p = oqh.compile(p)
        fn_split = os.path.split(p.filename)

        self.assertEqual(fn_split[0], ql.get_option('output_dir'))
        self.assertEqual(fn_split[1], 'test_program.qisa')
Ejemplo n.º 20
0
def AllXY(qubit_idx: int, platf_cfg: str, double_points: bool = True):
    """
    Single qubit AllXY sequence.
    Writes output files to the directory specified in openql.
    Output directory is set as an attribute to the program for convenience.

    Input pars:
        qubit_idx:      int specifying the target qubit (starting at 0)
        platf_cfg:      filename of the platform config file
        double_points:  if true repeats every element twice
    Returns:
        p:              OpenQL Program object containing


    """
    p = oqh.create_program("AllXY", platf_cfg)

    allXY = [['i', 'i'], ['rx180', 'rx180'], ['ry180', 'ry180'],
             ['rx180', 'ry180'], ['ry180', 'rx180'], ['rx90', 'i'],
             ['ry90', 'i'], ['rx90', 'ry90'], ['ry90', 'rx90'],
             ['rx90', 'ry180'], ['ry90', 'rx180'], ['rx180', 'ry90'],
             ['ry180', 'rx90'], ['rx90', 'rx180'], ['rx180', 'rx90'],
             ['ry90', 'ry180'], ['ry180', 'ry90'], ['rx180', 'i'],
             ['ry180', 'i'], ['rx90', 'rx90'], ['ry90', 'ry90']]

    # this should be implicit
    # FIXME: remove try-except, when we depend hard on >=openql-0.6
    try:
        p.set_sweep_points(np.arange(len(allXY), dtype=float))
    except TypeError:
        # openql-0.5 compatibility
        p.set_sweep_points(np.arange(len(allXY), dtype=float), len(allXY))

    for i, xy in enumerate(allXY):
        if double_points:
            js = 2
        else:
            js = 1
        for j in range(js):
            k = oqh.create_kernel(
                "AllXY_{}".format(i + j // 2), p
            )  # FIXME: generates 2 identical kernel names if js=2. This does work, but is still undesirable
            k.prepz(qubit_idx)
            k.gate(xy[0], [qubit_idx])
            k.gate(xy[1], [qubit_idx])
            k.measure(qubit_idx)
            p.add_kernel(k)

    p = oqh.compile(p)
    return p
Ejemplo n.º 21
0
def Depletion(time, qubit_idx: int, platf_cfg: str, double_points: bool):
    """
    Input pars:
        times:          the list of waiting times for each ALLXY element
        qubit_idx:      int specifying the target qubit (starting at 0)
        platf_cfg:      filename of the platform config file
    Returns:
        p:              OpenQL Program object containing
    """

    allXY = [['i', 'i'], ['rx180', 'rx180'], ['ry180', 'ry180'],
             ['rx180', 'ry180'], ['ry180', 'rx180'], ['rx90', 'i'],
             ['ry90', 'i'], ['rx90', 'ry90'], ['ry90', 'rx90'],
             ['rx90', 'ry180'], ['ry90', 'rx180'], ['rx180', 'ry90'],
             ['ry180', 'rx90'], ['rx90', 'rx180'], ['rx180', 'rx90'],
             ['ry90', 'ry180'], ['ry180', 'ry90'], ['rx180', 'i'],
             ['ry180', 'i'], ['rx90', 'rx90'], ['ry90', 'ry90']]

    p = oqh.create_program('Depletion', platf_cfg)

    try:
        p.set_sweep_points(np.arange(len(allXY), dtype=float))
    except TypeError:
        # openql-0.5 compatibility
        p.set_sweep_points(np.arange(len(allXY), dtype=float), len(allXY))

    if double_points:
        js = 2
    else:
        js = 1

    for i, xy in enumerate(allXY):
        for j in range(js):
            k = oqh.create_kernel('Depletion_{}_{}'.format(i, j), p)
            # Prepare qubit
            k.prepz(qubit_idx)
            # Initial measurement
            k.measure(qubit_idx)
            # Wait time
            wait_nanoseconds = int(round(time / 1e-9))
            k.gate("wait", [qubit_idx], wait_nanoseconds)
            # AllXY pulse
            k.gate(xy[0], [qubit_idx])
            k.gate(xy[1], [qubit_idx])
            # Final measurement
            k.measure(qubit_idx)
            p.add_kernel(k)

    p = oqh.compile(p)
    return p
Ejemplo n.º 22
0
def CW_tone(qubit_idx: int, platf_cfg: str):
    """
    Sequence to generate an "always on" pulse or "ContinuousWave" (CW) tone.
    This is a sequence that goes a bit against the paradigm of openql.
    """
    p = oqh.create_program('CW_tone', platf_cfg)

    k = oqh.create_kernel("Main", p)
    for i in range(40):
        k.gate('square', [qubit_idx])
    p.add_kernel(k)

    p = oqh.compile(p)
    return p
Ejemplo n.º 23
0
def pulsed_spec_seq_marked(qubit_idx: int,
                           spec_pulse_length: float,
                           platf_cfg: str,
                           trigger_idx: int,
                           trigger_idx_2: int = None,
                           wait_time_ns: int = 0,
                           cc: str = 'CCL'):
    """
    Sequence for pulsed spectroscopy, similar to old version. Difference is that
    this one triggers the 0th trigger port of the CCLight and uses the zeroth
    wave output on the AWG (currently hardcoded, should be improved)
    FIXME: comment outdated
    """
    p = oqh.create_program("pulsed_spec_seq_marked", platf_cfg)
    k = oqh.create_kernel("main", p)

    nr_clocks = int(spec_pulse_length / 20e-9)
    print('Adding {} [ns] to spec seq'.format(wait_time_ns))
    if cc.upper() == 'CCL':
        spec_instr = 'spec'
    elif cc.upper() == 'QCC':
        spec_instr = 'sf_square'
    elif cc.lower() == 'cc':
        spec_instr = 'spec'
    else:
        raise ValueError('CC type not understood: {}'.format(cc))

    # k.prepz(qubit_idx)
    for i in range(nr_clocks):
        # The spec pulse is a pulse that lasts 20ns, because of the way the VSM
        # control works. By repeating it the duration can be controlled.
        k.gate(spec_instr, [trigger_idx])
        if trigger_idx_2 is not None:
            k.gate(spec_instr, [trigger_idx_2])
            k.wait([trigger_idx, trigger_idx_2], 0)

    if trigger_idx != qubit_idx:
        k.wait([trigger_idx, qubit_idx], 0)
        if trigger_idx_2 is not None:
            k.wait([trigger_idx_2], 0)
    k.wait([qubit_idx], wait_time_ns)
    k.measure(qubit_idx)
    p.add_kernel(k)

    p = oqh.compile(p)
    return p
Ejemplo n.º 24
0
def vsm_timing_cal_sequence(qubit_idx: int, platf_cfg: str):
    """
    A sequence for calibrating the VSM timing delay.

    The marker idx is a qubit number for which a dummy pulse is played.
    This can be used as a reference.

    """
    p = oqh.create_program('vsm_timing_cal_sequence', platf_cfg)

    k = oqh.create_kernel("Main", p)
    k.prepz(qubit_idx)  # to ensure enough separation in timing
    k.gate('spec', [qubit_idx])
    p.add_kernel(k)

    p = oqh.compile(p)
    return p
Ejemplo n.º 25
0
def CPMG_SO(orders, tauN: int, qubit_idx: int, platf_cfg: str):
    """
    Single qubit CPMG sequence.
    Writes output files to the directory specified in openql.
    Output directory is set as an attribute to the program for convenience.

    Input pars:
        times:          the list of waiting times for each Echo element
        qubit_idx:      int specifying the target qubit (starting at 0)
        platf_cfg:      filename of the platform config file
    Returns:
        p:              OpenQL Program object containing

    """
    p = oqh.create_program("CPMG_SO", platf_cfg)

    for i, order in enumerate(orders[:-4]):

        k = oqh.create_kernel("CPMG_SO_{}".format(i), p)
        k.prepz(qubit_idx)
        # nr_clocks = int(time/20e-9/2)

        wait_nanoseconds = int(round((tauN / 1e-9) / 2))
        k.gate('rx90', [qubit_idx])
        k.gate("wait", [qubit_idx], wait_nanoseconds)
        for j in range(order - 1):
            k.gate('ry180', [qubit_idx])
            k.gate("wait", [qubit_idx], 2 * wait_nanoseconds)
        k.gate('ry180', [qubit_idx])
        k.gate("wait", [qubit_idx], wait_nanoseconds)
        # angle = (i*40)%360
        # cw_idx = angle//20 + 9
        # if angle == 0:
        k.gate('rx90', [qubit_idx])
        # else:
        #     k.gate('cw_{:02}'.format(cw_idx), [qubit_idx])

        k.measure(qubit_idx)
        p.add_kernel(k)

    # adding the calibration points
    oqh.add_single_qubit_cal_points(p, qubit_idx=qubit_idx)

    p = oqh.compile(p)
    return p
Ejemplo n.º 26
0
def T1_second_excited_state(times, qubit_idx: int, platf_cfg: str):
    """
    Single qubit T1 sequence for the second excited states.
    Writes output files to the directory specified in openql.
    Output directory is set as an attribute to the program for convenience.

    Input pars:
        times:          the list of waiting times for each T1 element
        qubit_idx:      int specifying the target qubit (starting at 0)
        platf_cfg:      filename of the platform config file
    Returns:
        p:              OpenQL Program object containing


    """
    p = oqh.create_program("T1_2nd_exc", platf_cfg)

    for i, time in enumerate(times):
        for j in range(2):
            k = oqh.create_kernel("T1_2nd_exc_{}_{}".format(i, j), p)
            k.prepz(qubit_idx)
            wait_nanoseconds = int(round(time / 1e-9))
            k.gate('rx180', [qubit_idx])
            k.gate('rx12', [qubit_idx])
            k.gate("wait", [qubit_idx], wait_nanoseconds)
            if j == 1:
                k.gate('rx180', [qubit_idx])
            k.measure(qubit_idx)
            p.add_kernel(k)

    # adding the calibration points
    oqh.add_single_qubit_cal_points(p,
                                    qubit_idx=qubit_idx,
                                    f_state_cal_pts=True)

    dt = times[1] - times[0]
    sweep_points = np.concatenate(
        [np.repeat(times, 2), times[-1] + dt * np.arange(6) + dt])
    # attribute get's added to program to help finding the output files
    p.sweep_points = sweep_points

    p = oqh.compile(p)
    return p
Ejemplo n.º 27
0
def off_on(qubit_idx: int, pulse_comb: str, initialize: bool, platf_cfg: str):
    """
    Performs an 'off_on' sequence on the qubit specified.
        off: (RO) - prepz -      - RO
        on:  (RO) - prepz - x180 - RO
    Args:
        qubit_idx (int) :
        pulse_comb (str): What pulses to play valid options are
            "off", "on", "off_on"
        initialize (bool): if True does an extra initial measurement to
            post select data.
        platf_cfg (str) : filepath of OpenQL platform config file

    Pulses can be optionally enabled by putting 'off', respectively 'on' in
    the pulse_comb string.
    """
    p = oqh.create_program('off_on', platf_cfg)

    # # Off
    if 'off' in pulse_comb.lower():
        k = oqh.create_kernel("off", p)
        k.prepz(qubit_idx)
        if initialize:
            k.measure(qubit_idx)
        k.measure(qubit_idx)
        p.add_kernel(k)

    if 'on' in pulse_comb.lower():
        k = oqh.create_kernel("on", p)
        k.prepz(qubit_idx)
        if initialize:
            k.measure(qubit_idx)
        k.gate('rx180', [qubit_idx])
        k.measure(qubit_idx)
        p.add_kernel(k)

    if ('on' not in pulse_comb.lower()) and ('off' not in pulse_comb.lower()):
        raise ValueError()

    p = oqh.compile(p)
    return p
Ejemplo n.º 28
0
def CW_RO_sequence(qubit_idx: int, platf_cfg: str):
    """
    A sequence that performs readout back to back without initialization.
    The separation of the readout triggers is done by specifying the duration
    of the readout parameter in the configuration file used for compilation.

    args:
        qubit_idx (int/list) :  the qubit(s) to be read out, can be either an
            int or a list of integers.
        platf_cfg (str)     :
    """
    p = oqh.create_program('CW_RO_sequence', platf_cfg=platf_cfg)

    k = oqh.create_kernel("main", p)
    if not hasattr(qubit_idx, "__iter__"):
        qubit_idx = [qubit_idx]
    k.gate('wait', qubit_idx, 0)
    for qi in qubit_idx:
        k.measure(qi)
    k.gate('wait', qubit_idx, 0)
    p.add_kernel(k)
    p = oqh.compile(p)
    return p
Ejemplo n.º 29
0
def FluxTimingCalibration_2q(q0, q1, buffer_time1, times, platf_cfg: str):
    """
    A Ramsey sequence with varying waiting times `times` around a flux pulse.

    N.B. this function is not consistent with "FluxTimingCalibration".
    This should be fixed
    """
    p = oqh.create_program("FluxTimingCalibration_2q", platf_cfg)

    buffer_nanoseconds1 = int(round(buffer_time1/1e-9))

    for t in times:

        t_nanoseconds = int(round(t/1e-9))
        k = oqh.create_kernel("pi-flux-pi", p)
        k.prepz(q0)
        k.prepz(q1)

        k.gate('rx180', [q0])
        k.gate('rx180', [q1])

        if buffer_nanoseconds1 > 10:
            k.gate("wait", [2, 0], buffer_nanoseconds1)
        k.gate('fl_cw_02', [2, 0])
        if t_nanoseconds > 10:
            k.gate("wait", [2, 0], t_nanoseconds)
        #k.gate('rx180', [q0])
        #k.gate('rx180', [q1])
        k.gate("wait", [2, 0], 1)
        k.measure(q0)
        k.gate("wait", [2, 0], 1)

        p.add_kernel(k)

    p = oqh.compile(p)
    return p
Ejemplo n.º 30
0
def flipping(qubit_idx: int, number_of_flips, platf_cfg: str,
             equator: bool=False, cal_points: bool=True,
             ax: str='x', angle: str='180'):
    """
    Generates a flipping sequence that performs multiple pi-pulses
    Basic sequence:
        - (X)^n - RO
        or
        - (Y)^n - RO
        or
        - (X90)^2n - RO
        or
        - (Y90)^2n - RO


    Input pars:
        qubit_idx:      int specifying the target qubit (starting at 0)
        number_of_flips: array of ints specifying the sweep points
        platf_cfg:      filename of the platform config file
        equator:        if True add an extra pi/2 pulse at the end to
                        make the state end at the equator.
        cal_points:     replaces last 4 points by calibration points

    Returns:
        p:              OpenQL Program object
    """
    p = oqh.create_program("flipping", platf_cfg)

    for i, n in enumerate(number_of_flips):
        k = oqh.create_kernel('flipping_{}'.format(i), p)
        k.prepz(qubit_idx)
        if cal_points and (i == (len(number_of_flips)-4) or
                           i == (len(number_of_flips)-3)):
            k.measure(qubit_idx)
        elif cal_points and (i == (len(number_of_flips)-2) or
                             i == (len(number_of_flips)-1)):
            if ax == 'y':
                k.y(qubit_idx)
            else:
                k.x(qubit_idx)
            k.measure(qubit_idx)
        else:
            if equator:
                if ax == 'y':
                    k.gate('ry90', [qubit_idx])
                else:
                    k.gate('rx90', [qubit_idx])
            for j in range(n):
                if ax == 'y' and angle == '90':
                    k.gate('ry90', [qubit_idx])
                    k.gate('ry90', [qubit_idx])
                elif ax == 'y' and angle == '180':
                    k.y(qubit_idx)
                elif angle == '90':
                    k.gate('rx90', [qubit_idx])
                    k.gate('rx90', [qubit_idx])
                else:
                    k.x(qubit_idx)
            k.measure(qubit_idx)
        p.add_kernel(k)

    p = oqh.compile(p)
    return p