Exemplo n.º 1
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.

    qubit_idx can also be a list, then the corresponding set of measurements is triggered.
    """
    platf = Platform('OpenQL_Platform', platf_cfg)
    p = Program(pname="CW_RO_sequence",
                nqubits=platf.get_qubit_number(),
                p=platf)

    k = Kernel("main", p=platf)
    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)
    with suppress_stdout():
        p.compile(verbose=False)
    # attribute get's added to program to help finding the output files
    p.output_dir = ql.get_output_dir()
    p.filename = join(p.output_dir, p.name + '.qisa')
    return p
Exemplo n.º 2
0
def create_program(pname: str, platf_cfg: str, nregisters: int = 0):
    """
    Wrapper around the constructor of openQL "Program" class.

    Args:
        pname       (str) : Name of the program
        platf_cfg   (str) : location of the platform configuration used to
            construct the OpenQL Platform used.
        nregisters  (int) : the number of classical registers required in
            the program.

    In addition to instantiating the Program, this function
        - creates a Platform based on the "platf_cfg" filename.
        - Adds the platform as an attribute  "p.platf"
        - Adds the output_dir as an attribute "p.output_dir"

    """
    platf = Platform('OpenQL_Platform', platf_cfg)
    nqubits = platf.get_qubit_number()
    p = Program(pname, platf, nqubits, nregisters)

    p.platf = platf
    p.output_dir = ql.get_option('output_dir')
    p.nqubits = platf.get_qubit_number()
    p.nregisters = nregisters
    return p
Exemplo n.º 3
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

    '''
    platf = Platform('OpenQL_Platform', platf_cfg)
    p = Program(pname=program_name, nqubits=platf.get_qubit_number(), p=platf)
    k = Kernel("yX", p=platf)
    k.prepz(qubit_idx)
    k.gate('ry90', qubit_idx)
    k.gate('rx180', qubit_idx)
    k.measure(qubit_idx)
    p.add_kernel(k)

    k = Kernel("xY", p=platf)
    k.prepz(qubit_idx)
    k.gate('rx90', qubit_idx)
    k.gate('ry180', qubit_idx)
    k.measure(qubit_idx)
    p.add_kernel(k)

    with suppress_stdout():
        p.compile(verbose=False)
    # attribute get's added to program to help finding the output files
    p.output_dir = ql.get_output_dir()
    p.filename = join(p.output_dir, p.name + '.qisa')
    return p
Exemplo n.º 4
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.

    """
    platf = Platform('OpenQL_Platform', platf_cfg)
    p = Program(pname="pulsed_spec_seq",
                nqubits=platf.get_qubit_number(),
                p=platf)
    k = Kernel("main", p=platf)

    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)
    with suppress_stdout():
        p.compile(verbose=False)
    # attribute get's added to program to help finding the output files
    p.output_dir = ql.get_output_dir()
    p.filename = join(p.output_dir, p.name + '.qisa')
    return p
Exemplo n.º 5
0
def openql_program_from_pygsti_expList(pygsti_gateset, program_name: str,
                                       qubits: list,
                                       platf_cfg: str,
                                       start_idx:int=0,
                                       recompile=True):
    platf = Platform('OpenQL_Platform', platf_cfg)
    p = Program(pname=program_name,
                nqubits=platf.get_qubit_number(),
                p=platf)
    p.output_dir = ql.get_output_dir()
    p.filename = join(p.output_dir, p.name + '.qisa')
    if oqh.check_recompilation_needed(p.filename, platf_cfg, recompile):

        for i, gatestring in enumerate(pygsti_gateset):
            kernel_name = 'G {} {}'.format(i, gatestring)
            k = openql_kernel_from_gatestring(
                gatestring=gatestring, qubits=qubits,
                kernel_name=kernel_name, platf=platf)
            p.add_kernel(k)
        with suppress_stdout():
            p.compile()

    p.sweep_points = np.arange(len(pygsti_gateset), dtype=float)+ start_idx
    p.set_sweep_points(p.sweep_points, len(p.sweep_points))

    return p
Exemplo n.º 6
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')
    platf = Platform('OpenQL_Platform', platf_cfg)
    p = Program(pname="ef_rabi_seq", nqubits=platf.get_qubit_number(), p=platf)
    # 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 = Kernel("ef_A{}".format(amp), p=platf)
        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 = add_single_qubit_cal_points(p, platf=platf, qubit_idx=q0)
    with suppress_stdout():
        p.compile()
    # attribute get's added to program to help finding the output files
    p.output_dir = ql.get_output_dir()
    p.filename = join(p.output_dir, p.name + '.qisa')

    if add_single_qubit_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])
    p.set_sweep_points(p.sweep_points, len(p.sweep_points))
    return p
Exemplo n.º 7
0
def create_program(pname: str, platf_cfg: str, nregisters: int = 32):
    """
    Wrapper around the constructor of openQL "Program" class.

    Args:
        pname       (str) : Name of the program
        platf_cfg   (str) : location of the platform configuration used to
            construct the OpenQL Platform used.
        nregisters  (int) : the number of classical registers required in
            the program.

    In addition to instantiating the Program, this function
        - creates a Platform based on the "platf_cfg" filename.
        - Adds the platform as an attribute  "p.platf"
        - Adds the output_dir as an attribute "p.output_dir"

    """

    # create OpenQL Program object see https://openql.readthedocs.io/en/latest/api/Program.html
    if 1:  # FIXME: workaround for OpenQL 0.8.1.dev4 re-setting option
        ql.set_option('output_dir', output_dir)

    platf = Platform('OpenQL_Platform', platf_cfg)
    nqubits = platf.get_qubit_number()
    p = Program(pname, platf, nqubits, nregisters)

    # add information to the Program object (FIXME: better create new type, seems to duplicate qubit_count and creg_count)
    p.platf = platf
    p.output_dir = output_dir
    p.nqubits = platf.get_qubit_number()
    p.nregisters = nregisters

    # detect OpenQL backend ('eqasm_compiler') used by inspecting platf_cfg
    p.eqasm_compiler = ''
    with open(platf_cfg) as f:
        for line in f:
            if 'eqasm_compiler' in line:
                m = re.search('"eqasm_compiler" *: *"(.*?)"', line)
                p.eqasm_compiler = m.group(1)
                break
    if p.eqasm_compiler == '':
        logging.error(f"key 'eqasm_compiler' not found in file '{platf_cfg}'")

    # determine extension of generated file
    #if p.eqasm_compiler == 'eqasm_backend_cc':
    if 1:  # FIXME: workaround for OpenQL 0.8.1.dev4 resetting values
        ext = '.vq1asm'  # CC
    else:
        ext = '.qisa'  # CC-light, QCC

    # add filename to help finding the output files. NB: file is created by calling compile()
    p.filename = join(p.output_dir, p.name + ext)
    return p
Exemplo n.º 8
0
def RTE(qubit_idx: int,
        sequence_type: str,
        platf_cfg: str,
        net_gate: str,
        feedback=False):
    """
    """
    platf = Platform('OpenQL_Platform', platf_cfg)
    p = Program(pname="RTE", nqubits=platf.get_qubit_number(), p=platf)

    k = Kernel('RTE', p=platf)
    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('Crx180', 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('Crx180', qubit_idx)
    else:
        raise ValueError(
            'sequence_type ({})should be "echo" or "pi"'.format(sequence_type))
    k.measure(qubit_idx)
    p.add_kernel(k)

    with suppress_stdout():
        p.compile(verbose=False)
    # attribute get's added to program to help finding the output files
    p.output_dir = ql.get_output_dir()
    p.filename = join(p.output_dir, p.name + '.qisa')
    return p
Exemplo n.º 9
0
def flipping(qubit_idx: int,
             number_of_flips,
             platf_cfg: str,
             equator: bool = False,
             cal_points: bool = True):
    """
    Generates a flipping sequence that performs multiple pi-pulses
    Basic sequence:
        - (X)^n - 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
    """
    platf = Platform('OpenQL_Platform', platf_cfg)
    p = Program(pname="Flipping", nqubits=platf.get_qubit_number(), p=platf)

    for i, n in enumerate(number_of_flips):
        k = Kernel("Flipping_" + str(i), p=platf)
        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)):
            k.x(qubit_idx)
            k.measure(qubit_idx)
        else:
            if equator:
                k.gate('rx90', qubit_idx)
            for j in range(n):
                k.x(qubit_idx)
            k.measure(qubit_idx)
        p.add_kernel(k)

    with suppress_stdout():
        p.compile(verbose=False)
    # attribute get's added to program to help finding the output files
    p.output_dir = ql.get_output_dir()
    p.filename = join(p.output_dir, p.name + '.qisa')
    return p
Exemplo n.º 10
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


    """
    platf = Platform('OpenQL_Platform', platf_cfg)
    p = Program(pname="AllXY", nqubits=platf.get_qubit_number(), p=platf)

    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
    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 = Kernel("AllXY_" + str(i + j / 2), p=platf)
            k.prepz(qubit_idx)
            k.gate(xy[0], qubit_idx)
            k.gate(xy[1], qubit_idx)
            k.measure(qubit_idx)
            p.add_kernel(k)

    with suppress_stdout():
        p.compile(verbose=False)
    # attribute get's added to program to help finding the output files
    p.output_dir = ql.get_output_dir()
    p.filename = join(p.output_dir, p.name + '.qisa')
    return p
Exemplo n.º 11
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


    """
    platf = Platform('OpenQL_Platform', platf_cfg)
    p = Program(pname="T1_2nd_exc", nqubits=platf.get_qubit_number(), p=platf)
    for i, time in enumerate(times):
        for j in range(2):
            k = Kernel("T1_2nd_exc_{}_{}".format(i, j), p=platf)
            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
    add_single_qubit_cal_points(p,
                                platf=platf,
                                qubit_idx=qubit_idx,
                                f_state_cal_pts=True)

    with suppress_stdout():
        p.compile(verbose=False)

    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.output_dir = ql.get_output_dir()
    p.filename = join(p.output_dir, p.name + '.qisa')
    return p
Exemplo n.º 12
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.
    """
    platf = Platform('OpenQL_Platform', platf_cfg)
    p = Program(pname="OffOn_RO_sequence",
                nqubits=platf.get_qubit_number(),
                p=platf)
    # # Off
    if 'off' in pulse_comb.lower():
        k = Kernel("off", p=platf)
        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 = Kernel("on", p=platf)
        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()

    with suppress_stdout():
        p.compile(verbose=False)
    # attribute get's added to program to help finding the output files
    p.output_dir = ql.get_output_dir()
    p.filename = join(p.output_dir, p.name + '.qisa')
    return p
Exemplo n.º 13
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.
    """
    platf = Platform('OpenQL_Platform', platf_cfg)
    p = Program(pname="CW_tone", nqubits=platf.get_qubit_number(), p=platf)

    k = Kernel("main", p=platf)
    for i in range(40):
        k.gate('square', qubit_idx)
    p.add_kernel(k)
    with suppress_stdout():
        p.compile(verbose=False)
    p.output_dir = ql.get_output_dir()
    p.filename = join(p.output_dir, p.name + '.qisa')
    return p
Exemplo n.º 14
0
def single_elt_on(qubit_idx: int, platf_cfg: str):
    platf = Platform('OpenQL_Platform', platf_cfg)
    p = Program(pname="Single_elt_on",
                nqubits=platf.get_qubit_number(),
                p=platf)
    k = Kernel("main", p=platf)
    k.prepz(qubit_idx)
    k.x(qubit_idx)
    k.measure(qubit_idx)
    p.add_kernel(k)

    with suppress_stdout():
        p.compile(verbose=False)
    # attribute get's added to program to help finding the output files
    p.output_dir = ql.get_output_dir()
    p.filename = join(p.output_dir, p.name + '.qisa')
    return p
Exemplo n.º 15
0
def FluxTimingCalibration_2q(q0, q1, buffer_time1, times, platf_cfg: str):
    """
    A Ramsey sequence with varying waiting times `times` around a flux pulse.
    """
    platf = Platform('OpenQL_Platform', platf_cfg)
    p = Program(pname="FluxTimingCalibration2q",
                nqubits=platf.get_qubit_number(),
                p=platf)

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

    for t in times:

        t_nanoseconds = int(round(t / 1e-9))

        k = Kernel("pifluxpi", p=platf)
        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)

    with suppress_stdout():
        p.compile(verbose=False)
    # attribute get's added to program to help finding the output files
    p.output_dir = ql.get_output_dir()
    p.filename = join(p.output_dir, p.name + '.qisa')
    return p
Exemplo n.º 16
0
def create_program(pname: str, platf_cfg: str, nregisters: int=32):
    """
    Wrapper around the constructor of openQL "Program" class.

    Args:
        pname       (str) : Name of the program
        platf_cfg   (str) : location of the platform configuration used to
            construct the OpenQL Platform used.
        nregisters  (int) : the number of classical registers required in
            the program.

    In addition to instantiating the Program, this function
        - creates a Platform based on the "platf_cfg" filename.
        - Adds the platform as an attribute  "p.platf"
        - Adds the output_dir as an attribute "p.output_dir"

    """
    platf = Platform('OpenQL_Platform', platf_cfg)
    nqubits = platf.get_qubit_number()
    p = Program(pname,
                platf,
                nqubits,
                nregisters)

    p.platf = platf
    p.output_dir = ql.get_option('output_dir')
    p.nqubits = platf.get_qubit_number()
    p.nregisters = nregisters

    # detect OpenQL backend ('eqasm_compiler') used
    p.eqasm_compiler = ''
    with open(platf_cfg) as f:
        for line in f:
            if 'eqasm_compiler' in line:
                m = re.search('"eqasm_compiler" *: *"(.*?)"', line)
                p.eqasm_compiler = m.group(1)
                break
    if p.eqasm_compiler == '':
        logging.error(f"key 'eqasm_compiler' not found in file '{platf_cfg}'")

    return p
Exemplo n.º 17
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

    """
    platf = Platform('OpenQL_Platform', platf_cfg)
    p = Program(pname="echo", nqubits=platf.get_qubit_number(), p=platf)

    for i, time in enumerate(times[:-4]):
        k = Kernel("echo_" + str(i), p=platf)
        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
    add_single_qubit_cal_points(p, platf=platf, qubit_idx=qubit_idx)

    with suppress_stdout():
        p.compile(verbose=False)
    # attribute get's added to program to help finding the output files
    p.output_dir = ql.get_output_dir()
    p.filename = join(p.output_dir, p.name + '.qisa')
    return p
Exemplo n.º 18
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.

    """
    platf = Platform('OpenQL_Platform', platf_cfg)
    p = Program(pname="Butterfly", nqubits=platf.get_qubit_number(), p=platf)

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

    k = Kernel('1', p=platf)
    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)

    with suppress_stdout():
        p.compile(verbose=False)
    # attribute get's added to program to help finding the output files
    p.output_dir = ql.get_output_dir()
    p.filename = join(p.output_dir, p.name + '.qisa')
    return p
Exemplo n.º 19
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.

    """
    platf = Platform('OpenQL_Platform', platf_cfg)
    p = Program(pname="vsm_timing_cal_sequence",
                nqubits=platf.get_qubit_number(),
                p=platf)

    k = Kernel("main", p=platf)
    k.prepz(qubit_idx)  # to ensure enough separation in timing
    k.gate('spec', qubit_idx)
    p.add_kernel(k)
    with suppress_stdout():
        p.compile(verbose=False)
    # attribute get's added to program to help finding the output files
    p.output_dir = ql.get_output_dir()
    p.filename = join(p.output_dir, p.name + '.qisa')
    return p
Exemplo n.º 20
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.
    """
    platf = Platform('OpenQL_Platform', platf_cfg)
    p = Program(pname="FluxTimingCalibration",
                nqubits=platf.get_qubit_number(),
                p=platf)

    # 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 = Kernel("pifluxpi", p=platf)
        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:
        add_single_qubit_cal_points(p, platf=platf, qubit_idx=qubit_idx)

    with suppress_stdout():
        p.compile(verbose=False)
    # attribute get's added to program to help finding the output files
    p.output_dir = ql.get_output_dir()
    p.filename = join(p.output_dir, p.name + '.qisa')
    return p
Exemplo n.º 21
0
def FastFeedbackControl(lantecy, 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:
        lantecy:        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


    """
    platf = Platform('OpenQL_Platform', platf_cfg)
    p = Program(pname="FastFdbkCtrl",
                nqubits=platf.get_qubit_number(),
                p=platf)

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

    p.add_kernel(k)

    k = Kernel("FastFdbkCtrl_fb0", p=platf)
    k.prepz(qubit_idx)
    k.gate('rx90', qubit_idx)
    # k.gate('rx180', qubit_idx)
    k.measure(qubit_idx)
    wait_nanoseconds = int(round(lantecy / 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 = Kernel("FastFdbkCtrl_fb1", p=platf)
    k.prepz(qubit_idx)
    k.gate('rx90', qubit_idx)
    # k.gate('rx180', qubit_idx)
    k.measure(qubit_idx)
    wait_nanoseconds = int(round(lantecy / 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
    add_single_qubit_cal_points(p, platf=platf, qubit_idx=qubit_idx)

    with suppress_stdout():
        p.compile(verbose=False)
    # attribute get's added to program to help finding the output files
    p.output_dir = ql.get_output_dir()
    p.filename = join(p.output_dir, p.name + '.qisa')
    return p
Exemplo n.º 22
0
def idle_error_rate_seq(nr_of_idle_gates,
                        states: list,
                        gate_duration_ns: int,
                        echo: bool,
                        qubit_idx: int,
                        platf_cfg: str,
                        post_select=True):
    """
    Sequence to perform the idle_error_rate_sequence.
    Virtually identical to a T1 experiment (Z-basis)
                        or a ramsey/echo experiment (X-basis)

    Input pars:
        nr_of_idle_gates : list of integers specifying the number of idle gates
            corresponding to each data point.
        gate_duration_ns : integer specifying the duration of the wait gate.
        states  :       list of states to prepare
        qubit_idx:      int specifying the target qubit (starting at 0)
        platf_cfg:      filename of the platform config file
    Returns:
        p:              OpenQL Program object containing


    """
    allowed_states = ['0', '1', '+']
    platf = Platform('OpenQL_Platform', platf_cfg)
    p = Program(pname="idle_error_rate",
                nqubits=platf.get_qubit_number(),
                p=platf)
    sweep_points = []
    for N in nr_of_idle_gates:
        for state in states:
            if state not in allowed_states:
                raise ValueError('State must be in {}'.format(allowed_states))
            k = Kernel("idle_prep{}_N{}".format(state, N), p=platf)
            # 1. Preparing in the right basis
            k.prepz(qubit_idx)
            if post_select:
                # adds an initialization measurement used to post-select
                k.measure(qubit_idx)
            if state == '1':
                k.gate('rx180', qubit_idx)
            elif state == '+':
                k.gate('rym90', qubit_idx)
            # 2. The "waiting" gates
            wait_nanoseconds = N * gate_duration_ns
            if state == '+' and echo:
                k.gate("wait", [qubit_idx], wait_nanoseconds // 2)
                k.gate('rx180', qubit_idx)
                k.gate("wait", [qubit_idx], wait_nanoseconds // 2)
            else:
                k.gate("wait", [qubit_idx], wait_nanoseconds)
            # 3. Reading out in the proper basis
            if state == '+' and echo:
                k.gate('rym90', qubit_idx)
            elif state == '+':
                k.gate('ry90', qubit_idx)
            k.measure(qubit_idx)
            p.add_kernel(k)
        sweep_points.append(N)

    p.set_sweep_points(sweep_points, num_sweep_points=len(sweep_points))
    p.sweep_points = sweep_points
    with suppress_stdout():
        p.compile(verbose=False)
    # attribute get's added to program to help finding the output files
    p.output_dir = ql.get_output_dir()
    p.filename = join(p.output_dir, p.name + '.qisa')
    return p
Exemplo n.º 23
0
def randomized_benchmarking(qubits: list,
                            platf_cfg: str,
                            nr_cliffords,
                            nr_seeds: int,
                            net_cliffords: list = [0],
                            max_clifford_idx: int = 11520,
                            initialize: bool = True,
                            interleaving_cliffords=[None],
                            program_name: str = 'randomized_benchmarking',
                            cal_points: bool = True,
                            f_state_cal_pts: bool = True,
                            recompile: bool = True):
    '''
    Input pars:
        qubits:         list of ints specifying qubit indices.
                        based on the length this function detects if it should
                        generate a single or two qubit RB sequence.
        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_cliffords:  list of ints index of net clifford the sequence
                        should perform. See examples below on how to use this.
                            0 -> Idx
                            3 -> rx180
                            3*24+3 -> {rx180 q0 | rx180 q1}

        initialize:     if True initializes qubits to 0, disable for restless
            tuning
        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)

        recompile:      True -> compiles the program,
                        'as needed' -> compares program to timestamp of config
                            and existence, if required recompile.
                        False -> compares program to timestamp of config.
                            if compilation is required raises a ValueError

                        If the program is more recent than the config
                        it returns an empty OpenQL program object with
                        the intended filename that can be used to upload the
                        previously compiled file.

    Returns:
        p:              OpenQL Program object

    ***************************************************************************
    Examples:
        1. Single qubit randomized benchmarking:

            p = cl_oql.randomized_benchmarking(
                qubits=[0],

                nr_cliffords=[2, 4, 8, 16, 32, 128, 512, 1024],
                nr_seeds=1,  # for CCL memory reasons
                platf_cfg=qubit.cfg_openql_platform_fn(),
                program_name='RB_{}'.format(i))

        2. Two qubit simultaneous randomized benchmarking:

            p = cl_oql.randomized_benchmarking(
                qubits=[0, 1],          # simultaneous RB on both qubits
                max_clifford_idx = 576, # to ensure only SQ Cliffords are drawn

                nr_cliffords=[2, 4, 8, 16, 32, 128, 512, 1024],
                nr_seeds=1,  # for CCL memory reasons
                platf_cfg=qubit.cfg_openql_platform_fn(),
                program_name='RB_{}'.format(i))

        3. Single qubit interleaved randomized benchmarking:
            p = cl_oql.randomized_benchmarking(
                qubits=[0],
                interleaving_cliffords=[None, 0, 16, 3],
                cal_points=False # relevant here because of data binning

                nr_cliffords=[2, 4, 8, 16, 32, 128, 512, 1024],
                nr_seeds=1,
                platf_cfg=qubit.cfg_openql_platform_fn(),
                program_name='Interleaved_RB_s{}_int{}_ncl{}_{}'.format(i))

    '''
    platf = Platform('OpenQL_Platform', platf_cfg)
    p = Program(pname=program_name, nqubits=platf.get_qubit_number(), p=platf)

    # attribute get's added to program to help finding the output files
    p.output_dir = ql.get_output_dir()
    p.filename = join(p.output_dir, p.name + '.qisa')

    if not oqh.check_recompilation_needed(
            program_fn=p.filename, platf_cfg=platf_cfg, recompile=recompile):
        return p

    if len(qubits) == 1:
        qubit_map = {'q0': qubits[0]}
        number_of_qubits = 1
        Cl = SingleQubitClifford
    elif len(qubits) == 2:
        qubit_map = {'q0': qubits[0], 'q1': qubits[1]}
        number_of_qubits = 2
        Cl = TwoQubitClifford
    else:
        raise NotImplementedError()

    for seed in range(nr_seeds):
        for j, n_cl in enumerate(nr_cliffords):
            for interleaving_cl in interleaving_cliffords:
                for net_clifford in net_cliffords:
                    k = Kernel('RB_{}Cl_s{}_net{}_inter{}'.format(
                        n_cl, seed, net_clifford, interleaving_cl),
                               p=platf)
                    if initialize:
                        for qubit_idx in qubit_map.values():
                            k.prepz(qubit_idx)

                    cl_seq = rb.randomized_benchmarking_sequence(
                        n_cl,
                        number_of_qubits=number_of_qubits,
                        desired_net_cl=net_clifford,
                        max_clifford_idx=max_clifford_idx,
                        interleaving_cl=interleaving_cl)
                    for cl in cl_seq:
                        gates = Cl(cl).gate_decomposition
                        for g, q in gates:
                            if isinstance(q, str):
                                k.gate(g, qubit_map[q])
                            elif isinstance(q, list):
                                # proper codeword
                                k.gate(g, [qubit_map[q[0]], qubit_map[q[1]]])

                    # This hack is required to align multiplexed RO in openQL..
                    k.gate("wait", list(qubit_map.values()), 0)
                    for qubit_idx in qubit_map.values():
                        k.measure(qubit_idx)
                    k.gate("wait", list(qubit_map.values()), 0)
                    p.add_kernel(k)

        if cal_points:
            if number_of_qubits == 1:
                p = add_single_qubit_cal_points(
                    p,
                    platf=platf,
                    qubit_idx=qubits[0],
                    f_state_cal_pts=f_state_cal_pts)
            elif number_of_qubits == 2:

                if f_state_cal_pts:
                    combinations = ['00', '01', '10', '11', '02', '20', '22']
                else:
                    combinations = ['00', '01', '10', '11']
                p = add_multi_q_cal_points(p,
                                           platf=platf,
                                           qubits=qubits,
                                           combinations=combinations)

    with suppress_stdout():
        p.compile(verbose=False)

    return p
Exemplo n.º 24
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
    platf = Platform('OpenQL_Platform', platf_cfg)
    p = Program(pname=program_name, nqubits=platf.get_qubit_number(), p=platf)

    i = 0
    for seed in range(nr_seeds):
        for j, n_cl in enumerate(nr_cliffords):
            k = Kernel('RB_{}Cl_s{}'.format(n_cl, seed), p=platf)
            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)
    with suppress_stdout():
        p.compile(verbose=False)
    # attribute get's added to program to help finding the output files
    p.output_dir = ql.get_output_dir()
    p.filename = join(p.output_dir, p.name + '.qisa')
    return p