コード例 #1
0
def purity_CZ_seq(q0, q1, RO_target='all'):
    """
    Creates the |00> + |11> Bell state and does a partial tomography in
    order to determine the purity of both qubits.
    """

    filename = join(base_qasm_path, 'purity_CZ_seq.qasm')
    qasm_file = mopen(filename, mode='w')
    qasm_file.writelines('qubit {} \nqubit {} \n'.format(q0, q1))

    tomo_list = ['mX90', 'mY90', 'I']

    for p_pulse in tomo_list:
        # Create a Bell state:  |00> + |11>
        qasm_file.writelines('\ninit_all\n')
        qasm_file.writelines('mY90 {} | Y90 {} \n'.format(q0, q1))
        qasm_file.writelines('CZ {} {} \n'.format(q0, q1))
        qasm_file.writelines('mY90 {}\n'.format(q1))

        # Perform pulses to measure the purity of both qubits
        qasm_file.writelines('{} {} | {} {}\n'.format(p_pulse, q0, p_pulse,
                                                      q1))
        if RO_target == 'all':
            qasm_file.writelines('RO {} | RO {} \n'.format(q0, q1))
        else:
            qasm_file.writelines('RO {} \n'.format(RO_target))

    qasm_file.close()
    return qasm_file
コード例 #2
0
def butterfly(qubit_name, initialize=False):
    """
    Initialize adds an exta measurement before state preparation to allow
    initialization by post-selection

    The duration of the RO + depletion is specified in the definition of RO
    """
    filename = join(base_qasm_path, 'butterfly_init_{}.qasm'.format(initialize))
    qasm_file = mopen(filename, mode='w')
    qasm_file.writelines('qubit {} \n'.format(qubit_name))
    if initialize:
        qasm_file.writelines('\ninit_all\n')
        qasm_file.writelines('RO {}  \n'.format(qubit_name))
        qasm_file.writelines('RO {}  \n'.format(qubit_name))
        qasm_file.writelines('RO {}  \n'.format(qubit_name))

        qasm_file.writelines('\ninit_all\n')
        qasm_file.writelines('RO {}  \n'.format(qubit_name))
        qasm_file.writelines('X180 {}  \n'.format(qubit_name))
        qasm_file.writelines('RO {}  \n'.format(qubit_name))
        qasm_file.writelines('RO {}  \n'.format(qubit_name))
    else:
        qasm_file.writelines('\ninit_all\n')
        qasm_file.writelines('RO {}  \n'.format(qubit_name))
        qasm_file.writelines('RO {}  \n'.format(qubit_name))

        qasm_file.writelines('\ninit_all\n')
        qasm_file.writelines('X180 {}  \n'.format(qubit_name))
        qasm_file.writelines('RO {}  \n'.format(qubit_name))
        qasm_file.writelines('RO {}  \n'.format(qubit_name))
    qasm_file.close()
    return qasm_file
コード例 #3
0
def purity_N_CZ_seq(q0: str, q1: str, N: int, RO_target: str = 'all'):
    """
    Creates the |00> + |11> Bell state and does a partial tomography in
    order to determine the purity of both qubits.
    """

    filename = join(base_qasm_path, 'purity_{}_CZ_seq.qasm'.format(N))
    qasm_file = mopen(filename, mode='w')
    qasm_file.writelines('qubit {} \nqubit {} \n'.format(q0, q1))

    tomo_list = ['mX90', 'mY90', 'I']

    for i, p_pulse in enumerate(tomo_list):
        # Create a Bell state:  |00> + |11>
        qasm_file.writelines('\ninit_all\n')
        qasm_file.writelines('qwg_trigger_{} {}\n'.format(0, q0))
        qasm_file.writelines('mY90 {} | Y90 {} \n'.format(q0, q1))
        for n in range(N):
            qasm_file.writelines('dummy_CZ {} {} \n'.format(q0, q1))
        qasm_file.writelines('mY90 {}\n'.format(q1))

        # Perform pulses to measure the purity of both qubits
        qasm_file.writelines('{} {} | {} {}\n'.format(p_pulse, q0, p_pulse,
                                                      q1))
        if RO_target == 'all':
            qasm_file.writelines('RO {} | RO {} \n'.format(q0, q1))
        else:
            qasm_file.writelines('RO {} \n'.format(RO_target))

    qasm_file.close()
    return qasm_file
コード例 #4
0
def AllXY(qubit_name, double_points=False):
    pulse_combinations = [['I', 'I'], ['X180', 'X180'], ['Y180', 'Y180'],
                          ['X180', 'Y180'], ['Y180', 'X180'],
                          ['X90', 'I'], ['Y90', 'I'], ['X90', 'Y90'],
                          ['Y90', 'X90'], ['X90', 'Y180'], ['Y90', 'X180'],
                          ['X180', 'Y90'], ['Y180', 'X90'], ['X90', 'X180'],
                          ['X180', 'X90'], ['Y90', 'Y180'], ['Y180', 'Y90'],
                          ['X180', 'I'], ['Y180', 'I'], ['X90', 'X90'],
                          ['Y90', 'Y90']]
    if double_points:
        pulse_combinations = [val for val in pulse_combinations
                              for _ in (0, 1)]

    filename = join(base_qasm_path, 'AllXY.qasm')
    qasm_file = mopen(filename, mode='w')
    qasm_file.writelines('qubit {} \n'.format(qubit_name))

    for pulse_comb in pulse_combinations:
        qasm_file.writelines('\ninit_all\n')
        if pulse_comb[0] != 'I':
            qasm_file.writelines('{} {}\n'.format(pulse_comb[0], qubit_name))
        if pulse_comb[1] != 'I':
            qasm_file.writelines('{} {}\n'.format(pulse_comb[1], qubit_name))
        qasm_file.writelines('RO {}  \n'.format(qubit_name))
    qasm_file.close()
    return qasm_file
コード例 #5
0
def CZ_restless_state_cycling(q0: str, q1: str, N: int=1):
    """
    Implements a circuit that performs a permutation over all computational
    states.

    Expected operation:
        U (|00>) -> |01>
        U (|01>) -> |11>
        U (|10>) -> |00>
        U (|11>) -> |10>

    Args:
        q0 (str): name of qubit q0
        q1 (str): name of qubit q1
        N  (int): number of times to apply U
    """
    filename = join(base_qasm_path, 'CZ_state_cycling_light.qasm')
    qasm_file = mopen(filename, mode='w')
    qasm_file.writelines('qubit {} \nqubit {} \n'.format(q0, q1))

    U = ''
    U += 'Y90 {} | mY90 {}\n'.format(q0, q1)
    U += 'CZ {} {}\n'.format(q0, q1)
    U += 'Y90 {} | Y90 {}\n'.format(q0, q1)
    U += 'CZ {} {}\n'.format(q0, q1)
    U += 'Y90 {} | Y90 {}\n'.format(q0, q1)

    for n in range(N):
        qasm_file.writelines(U)
    qasm_file.writelines('RO {}\n'.format(q0))
コード例 #6
0
    def test_qasm_function_with_function_arg(self):
        ext_op_dict = deepcopy(self.operation_dict)

        def Rx_codeword(amp, min_amp=-.5, max_amp=0.5):
            """
            maps an amp to a codeword, defining a function like this
            is NOT the responsibility of the qasm compiler
            """
            amp = float(amp)
            codeword = int((amp-min_amp)/(max_amp - min_amp) * 127)
            return 'Trigger {:07b}, 2 , \n'.format(codeword)

        ext_op_dict['Rx'] = {
            self.qubit_name: {'instruction': Rx_codeword,
                              'duration': 2}}
        filename = join(self.base_qasm_path, 'argument.qasm')
        qasm_file = mopen(filename, mode='w')
        qasm_file.writelines('qubit {} \n'.format(self.qubit_name))
        # test wait argument
        qasm_file.writelines('I {} 12\n'.format(
                             self.qubit_name))
        qasm_file.writelines('I {} 4\n'.format(
                             self.qubit_name))
        qasm_file.close()
        qta.qasm_to_asm(qasm_file.name, ext_op_dict)
コード例 #7
0
    def test_qasm_function_with_function_arg(self):
        ext_op_dict = deepcopy(self.operation_dict)

        def Rx_codeword(amp, min_amp=-.5, max_amp=0.5):
            """
            maps an amp to a codeword, defining a function like this
            is NOT the responsibility of the qasm compiler
            """
            amp = float(amp)
            codeword = int((amp - min_amp) / (max_amp - min_amp) * 127)
            return 'Trigger {:07b}, 2 \n'.format(codeword)

        ext_op_dict['Rx'] = {
            self.qubit_name: {
                'instruction': Rx_codeword,
                'duration': 2
            }
        }
        filename = join(self.base_qasm_path, 'argument.qasm')
        qasm_file = mopen(filename, mode='w')
        qasm_file.writelines('qubit {} \n'.format(self.qubit_name))
        # test wait argument
        qasm_file.writelines('I {} 12\n'.format(self.qubit_name))
        qasm_file.writelines('I {} 4\n'.format(self.qubit_name))
        qasm_file.close()
        qta.qasm_to_asm(qasm_file.name, ext_op_dict)
コード例 #8
0
def extract_required_operations(qasm_filepath):
        """
        Args:
            qasm_filepath: (str) location of the qasm file to read
        returns:
            list containing of all the used operations with args
        """
        filename = splitext(basename(qasm_filepath))[0]
        asm_filepath = join(base_asm_path, filename+'.asm')
        asm_file = mopen(asm_filepath, mode='w')
        asm_file.writelines(preamble)

        qubits = []  # the qubits that were defined
        operations = []
        with open(qasm_filepath) as qasm_file:
            for line in qasm_file:
                # Make lines interpretable
                line = line.split('#', 1)[0]  # remove comments
                line = line.strip(' \t\n\r')  # remove whitespace
                if (len(line) == 0):  # skip empty line and comment
                    continue
                elts = line.split()
                # special command: a line that defines a qubit
                if elts[0] == 'qubit':
                    qubits.append(elts[1])
                elif line not in operations:
                    operations.append(line)
        return operations
コード例 #9
0
def extract_required_operations(qasm_filepath):
    """
        Args:
            qasm_filepath: (str) location of the qasm file to read
        returns:
            list containing of all the used operations with args
        """
    filename = splitext(basename(qasm_filepath))[0]
    asm_filepath = join(base_asm_path, filename + '.asm')
    asm_file = mopen(asm_filepath, mode='w')
    asm_file.writelines(preamble)

    qubits = []  # the qubits that were defined
    operations = []
    with open(qasm_filepath) as qasm_file:
        for line in qasm_file:
            # Make lines interpretable
            line = line.split('#', 1)[0]  # remove comments
            line = line.strip(' \t\n\r')  # remove whitespace
            if (len(line) == 0):  # skip empty line and comment
                continue
            elts = line.split()
            # special command: a line that defines a qubit
            if elts[0] == 'qubit':
                qubits.append(elts[1])
            elif line not in operations:
                operations.append(line)
    return operations
コード例 #10
0
 def test_empty_qasm_file(self):
     filename = join(self.base_qasm_path, 'empty.qasm')
     qasm_file = mopen(filename, mode='w')
     qasm_file.writelines('qubit {} \n'.format(self.qubit_name))
     qasm_file.close()
     asm_file = qta.qasm_to_asm(qasm_file.name, self.operation_dict)
     asm = Assembler.Assembler(asm_file.name)
     instructions = asm.convert_to_instructions()
コード例 #11
0
 def test_empty_qasm_file(self):
     filename = join(self.base_qasm_path, 'empty.qasm')
     qasm_file = mopen(filename, mode='w')
     qasm_file.writelines('qubit {} \n'.format(self.qubit_name))
     qasm_file.close()
     asm_file = qta.qasm_to_asm(qasm_file.name, self.operation_dict)
     asm = Assembler.Assembler(asm_file.name)
     instructions = asm.convert_to_instructions()
コード例 #12
0
 def test_invalid_command(self):
     filename = join(self.base_qasm_path, 'invalid_command.qasm')
     qasm_file = mopen(filename, mode='w')
     qasm_file.writelines('qubit {} \n'.format(self.qubit_name))
     qasm_file.writelines('Xbla {}     # invalid cmd\n'.format(
         self.qubit_name))
     qasm_file.close()
     with self.assertRaises(ValueError):
         qta.qasm_to_asm(qasm_file.name, self.operation_dict)
コード例 #13
0
 def test_invalid_command(self):
     filename = join(self.base_qasm_path, 'invalid_command.qasm')
     qasm_file = mopen(filename, mode='w')
     qasm_file.writelines('qubit {} \n'.format(self.qubit_name))
     qasm_file.writelines('Xbla {}     # invalid cmd\n'.format(
                          self.qubit_name))
     qasm_file.close()
     with self.assertRaises(ValueError):
         qta.qasm_to_asm(qasm_file.name, self.operation_dict)
コード例 #14
0
def randomized_benchmarking(qubit_name, nr_cliffords, nr_seeds,
                            net_clifford=0, restless=False,
                            label='randomized_benchmarking',
                            cal_points=True,
                            double_curves=True):
    '''
    Input pars:
        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 corresponds to Identity and 3 corresponds to X180
        restless:      bool, does not initialize if restless is True
        label:           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:
        qasm_file

    generates a qasm file for single qubit Clifford based randomized
    benchmarking.
    '''
    net_cliffords = [0, 3]  # Exists purely for the double curves mode
    filename = join(base_qasm_path, label+'.qasm')
    qasm_file = mopen(filename, mode='w')
    qasm_file.writelines('qubit {} \n'.format(qubit_name))
    i = 0
    for seed in range(nr_seeds):
        for j, n_cl in enumerate(nr_cliffords):
            if not restless:
                qasm_file.writelines('init_all  \n')
            if cal_points and (j == (len(nr_cliffords)-4) or
                               j == (len(nr_cliffords)-3)):
                qasm_file.writelines('RO {}  \n'.format(qubit_name))
            elif cal_points and (j == (len(nr_cliffords)-2) or
                                 j == (len(nr_cliffords)-1)):
                qasm_file.writelines('X180 {} \n'.format(qubit_name))
                qasm_file.writelines('RO {}  \n'.format(qubit_name))
            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 pulse in pulse_keys:
                    if pulse != 'I':
                        qasm_file.writelines('{} {}\n'.format(
                            pulse, qubit_name))
                qasm_file.writelines('RO {}  \n'.format(qubit_name))
    qasm_file.close()
    return qasm_file
コード例 #15
0
def two_qubit_tomo_cardinal(cardinal,
                            q0,
                            q1,
                            RO_target='all'):
    '''
    Cardinal tomography for two qubits.

    Args:
        cardinal        (int) : index of prep gate
        q0, q1          (str) : target qubits for the sequence
        RO_target       (str) : target for the RO, can be a qubit name or 'all'
    '''
    tomo_pulses = ['I ', 'X180 ', 'Y90 ', 'mY90 ', 'X90 ', 'mX90 ']
    tomo_list_q0 = []
    tomo_list_q1 = []
    for tp in tomo_pulses:
        tomo_list_q0 += [tp + q0 + '\n']
        tomo_list_q1 += [tp + q1 + '\n']

    prep_index_q0 = int(cardinal % len(tomo_list_q0))
    prep_index_q1 = int(((cardinal - prep_index_q0) / len(tomo_list_q0) %
                         len(tomo_list_q1)))

    prep_pulse_q0 = tomo_list_q0[prep_index_q0]
    prep_pulse_q1 = tomo_list_q1[prep_index_q1]

    filename = join(base_qasm_path, 'two_qubit_tomo_cardinal.qasm')
    qasm_file = mopen(filename, mode='w')
    qasm_file.writelines('qubit {} \nqubit {} \n'.format(q0, q1))

    # Tomography pulses
    for p_q1 in tomo_list_q1:
        for p_q0 in tomo_list_q0:
            qasm_file.writelines('\ninit_all\n')
            qasm_file.writelines(prep_pulse_q0)
            qasm_file.writelines(prep_pulse_q1)
            qasm_file.writelines(p_q0)
            qasm_file.writelines(p_q1)
            qasm_file.writelines('RO ' + RO_target + '  \n')
    cal_pulses = []
    # every calibration point is repeated 7 times. This is copied from the
    # script for Tektronix driven qubits. I do not know if this repetition
    # is important or even necessary here.
    for seq in cal_points_2Q:
        cal_pulses += [[seq[0].format(q0) +
                        seq[1].format(q1) +
                        'RO {} \n'.format(RO_target)]]

    for seq in cal_pulses:
        qasm_file.writelines('\ninit_all\n')
        for p in seq:
            qasm_file.writelines(p)

    qasm_file.close()
    return qasm_file
コード例 #16
0
def single_elt_on(qubit_name):
    filename = join(base_qasm_path, 'single_elt_on.qasm')
    qasm_file = mopen(filename, mode='w')
    qasm_file.writelines('qubit {} \n'.format(qubit_name))
    # On
    qasm_file.writelines('\ninit_all\n')
    qasm_file.writelines('X180 {}     # On \n'.format(qubit_name))
    qasm_file.writelines('RO {}  \n'.format(qubit_name))

    qasm_file.close()
    return qasm_file
コード例 #17
0
def Ramsey(qubit_name, times, clock_cycle=5e-9,
           artificial_detuning=4,
           cal_points=True):
    '''
    Ramsey sequence for a single qubit.
    Input pars:
        times:               array of times between (start of) pulses (s)
        pulse_pars:          dict containing the pulse parameters
        RO_pars:             dict containing the RO parameters
        artificial_detuning: int,  float or None;
            if int: number of wiggles
            if float: artificial_detuning in (Hz)
            if None: adds no artificial detuning
                implemented using phase of the second pi/2 pulse (R90_phi),
                if None it will use X90 as the recovery pulse
        cal_points:          whether to use calibration points or not
    '''
    # if int interpret artificial detuning as desired nr of wiggles
    if isinstance(artificial_detuning, int):
        phases = (360*np.arange(len(times))/(len(times)-4*cal_points) *
                  artificial_detuning % 360)
    # if float interpret it as artificial detuning in Hz
    elif isinstance(artificial_detuning, float):
        phases = (artificial_detuning*times % 1)*360
    elif artificial_detuning is None:
        phases = np.zeros(len(times))

    clocks = np.round(times/clock_cycle)
    filename = join(base_qasm_path, 'Ramsey.qasm')
    qasm_file = mopen(filename, mode='w')
    qasm_file.writelines('qubit {} \n'.format(qubit_name))
    for i, cl in enumerate(clocks):
        qasm_file.writelines('\ninit_all\n')
        if cal_points and (i == (len(clocks)-4) or
                           i == (len(clocks)-3)):
            qasm_file.writelines('RO {}  \n'.format(qubit_name))
        elif cal_points and (i == (len(clocks)-2) or
                             i == (len(clocks)-1)):
            qasm_file.writelines('X180 {} \n'.format(qubit_name))
            qasm_file.writelines('RO {}  \n'.format(qubit_name))

        else:
            qasm_file.writelines('X90 {}     \n'.format(
                                 qubit_name))
            qasm_file.writelines('I {} {:d} \n'.format(qubit_name, int(cl)))
            if artificial_detuning is not None:
                qasm_file.writelines('R90_phi {} {}\n'.format(
                    qubit_name, phases[i]))
            else:
                qasm_file.writelines('X90 {}     \n'.format(
                                     qubit_name))
            qasm_file.writelines('RO {}  \n'.format(qubit_name))
    qasm_file.close()
    return qasm_file
コード例 #18
0
    def test_qasm_function_with_string_format_arg(self):
        ext_op_dict = deepcopy(self.operation_dict)

        filename = join(self.base_qasm_path, 'argument.qasm')
        qasm_file = mopen(filename, mode='w')
        qasm_file.writelines('qubit {} \n'.format(self.qubit_name))
        # test wait argument
        qasm_file.writelines('I {} 12\n'.format(self.qubit_name))
        qasm_file.writelines('I {} 4\n'.format(self.qubit_name))
        qasm_file.close()
        qta.qasm_to_asm(qasm_file.name, ext_op_dict)
コード例 #19
0
def Rabi(qubit_name, amps, n=1):
    filename = join(base_qasm_path, 'Rabi_{}.qasm'.format(n))
    qasm_file = mopen(filename, mode='w')
    qasm_file.writelines('qubit {} \n'.format(qubit_name))
    for amp in amps:
        qasm_file.writelines('\ninit_all\n')
        for i in range(n):
            qasm_file.writelines('Rx {} {} \n'.format(qubit_name, amp))
        qasm_file.writelines('RO {}  \n'.format(qubit_name))
    qasm_file.close()
    return qasm_file
コード例 #20
0
def chevron_block_seq(q0_name, q1_name, no_of_points,
                      excite_q1=False, wait_after_trigger=40e-9,
                      wait_during_flux=400e-9, clock_cycle=1e-9,
                      RO_target='all', mw_pulse_duration=40e-9,
                      cal_points=True):
    '''
    Sequence for measuring a block of a chevron, i.e. using different codewords
    for different pulse lengths.

    Args:
        q0, q1        (str): names of the addressed qubits.
                             q0 is the pulse that experiences the flux pulse.
        RO_target     (str): can be q0, q1, or 'all'
        excite_q1    (bool): choose whether to excite q1, thus choosing
                             between the |01> <-> |10> and the |11> <-> |20>
                             swap.
        wait_after_trigger (float): delay time in seconds after sending the
                             trigger for the flux pulse
        clock_cycle (float): period of the internal AWG clock
        wait_time     (int): wait time between triggering QWG and RO
        cal_points   (bool): whether to use calibration points or not
    '''
    filename = join(base_qasm_path, 'chevron_block_seq.qasm')
    qasm_file = mopen(filename, mode='w')
    qasm_file.writelines('qubit {} \nqubit {} \n'.format(q0_name, q1_name))

    for i in range(no_of_points):
        qasm_file.writelines('\ninit_all\n')

        qasm_file.writelines('QWG trigger {}\n'.format(i))
        if excite_q1:
            wait_after_trigger -= mw_pulse_duration
        qasm_file.writelines(
            'I {}\n'.format(int(wait_after_trigger//clock_cycle)))
        qasm_file.writelines('X180 {}\n'.format(q0_name))
        if excite_q1:
            qasm_file.writelines('X180 {}\n'.format(q1_name))
        qasm_file.writelines(
            'I {}\n'.format(int(wait_during_flux//clock_cycle)))
        if excite_q1:
            # q0 is rotated to ground-state to have better contrast
            # (|0> and |2> instead of |1> and |2>)
            qasm_file.writelines('X180 {}\n'.format(q0_name))
        qasm_file.writelines('RO {} \n'.format(RO_target))

    if cal_points:
        # Add calibration pulses
        cal_pulses = []
        for seq in cal_points_2Q:
            cal_pulses += [[seq[0], seq[1], 'RO ' + RO_target + '\n']]

    qasm_file.close()
    return qasm_file
コード例 #21
0
    def test_too_many_args_command(self):
        filename = join(self.base_qasm_path, 'too_many_args.qasm')
        qasm_file = mopen(filename, mode='w')
        qasm_file.writelines('qubit {} \n'.format(self.qubit_name))
        # leaving out the \n prevents the line from breaking
        qasm_file.writelines('X180 {}'.format(self.qubit_name))
        qasm_file.writelines('X180 {}'.format(self.qubit_name))
        qasm_file.writelines('Y180 {}'.format(self.qubit_name))

        qasm_file.close()
        with self.assertRaises(ValueError):
            qta.qasm_to_asm(qasm_file.name, self.operation_dict)
コード例 #22
0
    def test_qasm_function_with_string_format_arg(self):
        ext_op_dict = deepcopy(self.operation_dict)

        filename = join(self.base_qasm_path, 'argument.qasm')
        qasm_file = mopen(filename, mode='w')
        qasm_file.writelines('qubit {} \n'.format(self.qubit_name))
        # test wait argument
        qasm_file.writelines('I {} 12\n'.format(
                             self.qubit_name))
        qasm_file.writelines('I {} 4\n'.format(
                             self.qubit_name))
        qasm_file.close()
        qta.qasm_to_asm(qasm_file.name, ext_op_dict)
コード例 #23
0
def SWAPN(q0_name,
          q1_name,
          nr_pulses: list,
          excite_q1=False,
          RO_target='all',
          cal_points=True):
    '''
    Args:
        q0, q1        (str): names of the addressed qubits.
                             q0 is the pulse that experiences the flux pulse.
        RO_target     (str): can be q0, q1, or 'all'
        excite_q1    (bool): choose whether to excite q1, thus choosing
                             between the |01> <-> |10> and the |11> <-> |20>
                             swap.
        cal_points   (bool): whether to use calibration points or not
    '''
    filename = join(base_qasm_path, 'chevron_block_seq.qasm')
    qasm_file = mopen(filename, mode='w')
    qasm_file.writelines('qubit {} \nqubit {} \n'.format(q0_name, q1_name))

    for i, N in enumerate(nr_pulses):
        qasm_file.writelines('\ninit_all\n')
        qasm_file.writelines('QWG_trigger_{} {}\n'.format(i, q0_name))
        qasm_file.writelines('X180 {}\n'.format(q0_name))
        if excite_q1:
            qasm_file.writelines('X180 {}\n'.format(q1_name))
        for n in range(N):
            qasm_file.writelines('square {} \n'.format(q0_name))

        if excite_q1:
            # q0 is rotated to ground-state to have better contrast
            # (|0> and |2> instead of |1> and |2>)
            qasm_file.writelines('X180 {}\n'.format(q0_name))
        qasm_file.writelines('RO {} \n'.format(RO_target))

    if cal_points:
        # Add calibration pulses
        cal_pulses = []
        for seq in cal_points_2Q:
            cal_pulses += [[
                seq[0].format(q0_name) + seq[1].format(q1_name) +
                'RO {} \n'.format(RO_target)
            ]]
    for seq in cal_pulses:
        qasm_file.writelines('\ninit_all\n')
        for p in seq:
            qasm_file.writelines(p)
    qasm_file.close()
    return qasm_file
コード例 #24
0
def CZ_calibration_seq(q0, q1, RO_target='all',
                       CZ_disabled=False,
                       cases=('no_excitation', 'excitation'),
                       wait_after_trigger=40e-9,
                       wait_during_flux=280e-9,
                       clock_cycle=1e-9,
                       mw_pulse_duration=40e-9):
    '''
    Sequence used to calibrate flux pulses for CZ gates.

    Timing of the sequence:
    q0:   --   X90  C-Phase  Rphi90   --      RO
    q1: (X180)  --     --       --   (X180)    RO

    Args:
        q0, q1      (str): names of the addressed qubits
        RO_target   (str): can be q0, q1, or 'all'
        CZ_disabled (bool): disable CZ gate
        excitations (bool/str): can be True, False, or 'both_cases'
        clock_cycle (float): period of the internal AWG clock
        wait_time   (int): wait time in seconds after triggering the flux
    '''

    filename = join(base_qasm_path, 'CZ_calibration_seq.qasm')
    qasm_file = mopen(filename, mode='w')
    qasm_file.writelines('qubit {} \nqubit {} \n'.format(q0, q1))

    for case in cases:
        qasm_file.writelines('\ninit_all\n')
        qasm_file.writelines('QWG trigger\n')
        waitTime = wait_after_trigger
        if case == 'excitation':
            # Decrease wait time because there is an additional pulse
            waitTime -= mw_pulse_duration
        qasm_file.writelines(
            'I {}\n'.format(int(waitTime//clock_cycle)))
        if case == 'excitation':
            qasm_file.writelines('X180 {}\n'.format(q1))
        qasm_file.writelines('X90 {}\n'.format(q0))
        qasm_file.writelines(
            'I {}\n'.format(int(wait_during_flux//clock_cycle)))
        qasm_file.writelines('Rphi90 {}\n'.format(q0))
        if case == 'excitation':
            qasm_file.writelines('X180 {}\n'.format(q1))

        qasm_file.writelines('RO {}  \n'.format(RO_target))

    qasm_file.close()
    return qasm_file
コード例 #25
0
    def test_too_many_args_command(self):
        filename = join(self.base_qasm_path, 'too_many_args.qasm')
        qasm_file = mopen(filename, mode='w')
        qasm_file.writelines('qubit {} \n'.format(self.qubit_name))
        # leaving out the \n prevents the line from breaking
        qasm_file.writelines('X180 {}'.format(
                             self.qubit_name))
        qasm_file.writelines('X180 {}'.format(
                             self.qubit_name))
        qasm_file.writelines('Y180 {}'.format(
                             self.qubit_name))

        qasm_file.close()
        with self.assertRaises(ValueError):
            qta.qasm_to_asm(qasm_file.name, self.operation_dict)
コード例 #26
0
def two_qubit_off_on(q0, q1, RO_target='all'):
    '''
    off_on sequence on two qubits.

    Args:
        q0, q1      (str) : target qubits for the sequence
        RO_target   (str) : target for the RO, can be a qubit name or 'all'
    '''
    filename = join(base_qasm_path, 'two_qubit_off_on.qasm')
    qasm_file = mopen(filename, mode='w')
    qasm_file.writelines('qubit {} \nqubit {} \n'.format(q0, q1))

    # off - off
    qasm_file.writelines('\ninit_all\n')
    if RO_target == 'all':
        qasm_file.writelines('RO {} | RO {} \n'.format(q0, q1))
    else:
        qasm_file.writelines('RO {}  \n'.format(RO_target))

    # on - off
    qasm_file.writelines('\ninit_all\n')
    qasm_file.writelines('X180 {}\n'.format(q0))
    if RO_target == 'all':
        qasm_file.writelines('RO {} | RO {} \n'.format(q0, q1))
    else:
        qasm_file.writelines('RO {}  \n'.format(RO_target))

    # off - on
    qasm_file.writelines('\ninit_all\n')
    qasm_file.writelines('X180 {}\n'.format(q1))
    if RO_target == 'all':
        qasm_file.writelines('RO {} | RO {} \n'.format(q0, q1))
    else:
        qasm_file.writelines('RO {}  \n'.format(RO_target))

    # on - on
    qasm_file.writelines('\ninit_all\n')
    qasm_file.writelines('X180 {}\n'.format(q0))
    qasm_file.writelines('X180 {}\n'.format(q1))
    if RO_target == 'all':
        qasm_file.writelines('RO {} | RO {} \n'.format(q0, q1))
    else:
        qasm_file.writelines('RO {}  \n'.format(RO_target))

    qasm_file.close()
    return qasm_file
コード例 #27
0
def CZ_calibration_seq(q0,
                       q1,
                       RO_target='all',
                       vary_single_q_phase=True,
                       cases=('no_excitation', 'excitation')):
    '''
    Sequence used to calibrate flux pulses for CZ gates.

    Timing of the sequence:
    q0:   X90  C-Phase  Rphi90    RO
    q1: (X180)    --    (X180)    RO

    Args:
        q0, q1      (str): names of the addressed qubits
        RO_target   (str): can be q0, q1, or 'all'
        excitations (bool/str): can be True, False, or 'both_cases'
    '''

    filename = join(base_qasm_path, 'CZ_calibration_seq.qasm')
    qasm_file = mopen(filename, mode='w')
    qasm_file.writelines('qubit {} \nqubit {} \n'.format(q0, q1))

    for case in cases:
        qasm_file.writelines('\ninit_all\n')
        if case == 'excitation':
            qasm_file.writelines('X180 {} | '.format(q1))
        qasm_file.writelines('X90 {}\n'.format(q0))

        # temporary workaround to deal with limitation in the QASM config
        # qasm_file.writelines('CZ {} \n'.format(q0))
        qasm_file.writelines('CZ {} {}\n'.format(q0, q1))
        if case == 'excitation':
            qasm_file.writelines('X180 {} | '.format(q1))
        if vary_single_q_phase:
            qasm_file.writelines('Rphi90 {}\n'.format(q0))
        else:
            qasm_file.writelines('mX90 {}\n'.format(q0))
        if 'RO_target' == 'all':
            qasm_file.writelines('RO {} | RO {} \n'.format(q0, q1))
        else:
            qasm_file.writelines('RO {}  \n'.format(RO_target))
    qasm_file.close()
    return qasm_file
コード例 #28
0
def MotzoiXY(qubit_name, motzois, cal_points=True):
    '''
    Sequence used for calibrating the motzoi parameter.
    Consists of Xy and Yx

    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

    Input pars:
        motzois:             array of motzoi parameters
        pulse_pars:          dict containing the pulse parameters
        RO_pars:             dict containing the RO parameters
        cal_points:          if True, replaces the last 2*4 segments with
                             calibration points
    '''
    filename = join(base_qasm_path, 'Motzoi_XY.qasm')
    qasm_file = mopen(filename, mode='w')
    qasm_file.writelines('qubit {} \n'.format(qubit_name))
    for i, motzoi in enumerate(motzois):
        qasm_file.writelines('\ninit_all\n')
        if cal_points and (i == (len(motzois)-4) or
                           i == (len(motzois)-3)):
            qasm_file.writelines('RO {}  \n'.format(qubit_name))
        elif cal_points and (i == (len(motzois)-2) or
                             i == (len(motzois)-1)):
            qasm_file.writelines('X180 {} \n'.format(qubit_name))
            qasm_file.writelines('RO {}  \n'.format(qubit_name))
        if i % 2:
            qasm_file.writelines(
                'X180_Motz {} {} \n'.format(qubit_name, motzoi))
            qasm_file.writelines(
                'Y90_Motz {} {} \n'.format(qubit_name, motzoi))
            qasm_file.writelines('RO {}  \n'.format(qubit_name))
        else:
            qasm_file.writelines(
                'Y180_Motz {} {} \n'.format(qubit_name, motzoi))
            qasm_file.writelines(
                'X90_Motz {} {} \n'.format(qubit_name, motzoi))
            qasm_file.writelines('RO {}  \n'.format(qubit_name))
    qasm_file.close()
    return qasm_file
コード例 #29
0
def two_elt_MotzoiXY(qubit_name):
    '''
    Sequence used for calibrating the motzoi parameter.
    Consists of Xy and Yx

    needs to reload the points for every data point.
    '''
    filename = join(base_qasm_path, 'Motzoi_XY.qasm')
    qasm_file = mopen(filename, mode='w')
    qasm_file.writelines('qubit {} \n'.format(qubit_name))
    qasm_file.writelines('\ninit_all\n')
    qasm_file.writelines('X180 {} \n'.format(qubit_name))
    qasm_file.writelines('Y90 {} \n'.format(qubit_name))
    qasm_file.writelines('RO {}  \n'.format(qubit_name))

    qasm_file.writelines('\ninit_all\n')
    qasm_file.writelines('Y180 {} \n'.format(qubit_name))
    qasm_file.writelines('X90 {} \n'.format(qubit_name))
    qasm_file.writelines('RO {}  \n'.format(qubit_name))

    qasm_file.close()
    return qasm_file
コード例 #30
0
def ramZ_flux_latency(q0_name, wait_after_flux=20):
    """
    Sequence designed to calibrate the delay between the
    QWG_trigger and the start of the flux pulse

    Consists of a single point. Intended to change the latency parameter
    in the configuration that is used in compilation.
    """
    filename = join(base_qasm_path, 'RamZ_latency_seq.qasm')
    qasm_file = mopen(filename, mode='w')
    qasm_file.writelines('qubit {} \n'.format(q0_name))

    # simultaneous MW and flux pulse
    qasm_file.writelines('\ninit_all\n')
    qasm_file.writelines('X90 {} \n'.format(q0_name))
    qasm_file.writelines('square {}\n'.format(q0_name))
    qasm_file.writelines('I {}\n'.format(wait_after_flux))
    qasm_file.writelines('X90 {}\n'.format(q0_name))
    qasm_file.writelines('RO {} \n'.format(q0_name))

    qasm_file.close()
    return qasm_file
コード例 #31
0
def chevron_seq(fluxing_qubit: str, spectator_qubit: str,
                excite_q1: bool=False, RO_target='all'):
    '''
    Single chevron sequence that does a swap on |01> <-> |10> or |11> <-> |20>.

    Args:
        fluxing_qubit (str): name of the qubit that is fluxed/
        spectator qubit (str): name of the qubit with which the fluxing
                            qubit interacts.
        RO_target   (str): can be q0, q1, or 'all'
        excite_q1   (bool): choose whether to excite q1, thus choosing
                            between the |01> <-> |10> and the |11> <-> |20>
                            swap.
    '''
    filename = join(base_qasm_path, 'chevron_seq.qasm')
    qasm_file = mopen(filename, mode='w')
    qasm_file.writelines('qubit {} \nqubit {} \n'.format(fluxing_qubit,
                                                         spectator_qubit))

    qasm_file.writelines('\ninit_all\n')
    if excite_q1:
        qasm_file.writelines('X180 {} | X180 {}\n'.format(fluxing_qubit,
                                                          spectator_qubit))
    else:
        qasm_file.writelines('X180 {}\n'.format(fluxing_qubit))
    qasm_file.writelines('square {}\n'.format(fluxing_qubit))
    if excite_q1:
        # fluxing_qubit is rotated to ground-state to have better contrast
        # (|0> and |2> instead of |1> and |2>)
        qasm_file.writelines('X180 {}\n'.format(fluxing_qubit))
    if RO_target == 'all':
        qasm_file.writelines('RO {} | RO {}\n'.format(fluxing_qubit,
                                                      spectator_qubit))
    else:
        qasm_file.writelines('RO {} \n'.format(RO_target))

    qasm_file.close()
    return qasm_file
コード例 #32
0
def flipping_seq(qubit_name, number_of_flips, clock_cycle=5e-9,
                 equator=False, cal_points=True):
    filename = join(base_qasm_path, 'Flipping.qasm')
    qasm_file = mopen(filename, mode='w')
    qasm_file.writelines('qubit {} \n'.format(qubit_name))
    for i, n in enumerate(number_of_flips):
        qasm_file.writelines('\ninit_all\n')
        if cal_points and (i == (len(number_of_flips)-4) or
                           i == (len(number_of_flips)-3)):
            qasm_file.writelines('RO {}  \n'.format(qubit_name))
        elif cal_points and (i == (len(number_of_flips)-2) or
                             i == (len(number_of_flips)-1)):
            qasm_file.writelines('X180 {} \n'.format(qubit_name))
            qasm_file.writelines('RO {}  \n'.format(qubit_name))
        else:
            if equator:
                qasm_file.writelines('X90 {} \n'.format(qubit_name))
            for j in range(n):
                qasm_file.writelines('X180 {} \n'.format(
                                     qubit_name))
            qasm_file.writelines('RO {}  \n'.format(qubit_name))
    qasm_file.close()
    return qasm_file
コード例 #33
0
def T1(qubit_name, times, clock_cycle=5e-9,
       cal_points=True):
    #
    clocks = np.round(times/clock_cycle)
    filename = join(base_qasm_path, 'T1.qasm')
    qasm_file = mopen(filename, mode='w')
    qasm_file.writelines('qubit {} \n'.format(qubit_name))
    for i, cl in enumerate(clocks):
        qasm_file.writelines('\ninit_all\n')
        if cal_points and (i == (len(clocks)-4) or
                           i == (len(clocks)-3)):
            qasm_file.writelines('RO {}  \n'.format(qubit_name))
        elif cal_points and (i == (len(clocks)-2) or
                             i == (len(clocks)-1)):
            qasm_file.writelines('X180 {} \n'.format(qubit_name))
            qasm_file.writelines('RO {}  \n'.format(qubit_name))
        else:
            qasm_file.writelines('X180 {}     # exciting pi pulse\n'.format(
                                 qubit_name))
            qasm_file.writelines('I {} {:d} \n'.format(qubit_name, int(cl)))
            qasm_file.writelines('RO {}  \n'.format(qubit_name))
    qasm_file.close()
    return qasm_file
コード例 #34
0
def grover_tomo_seq(q0_name,
                    q1_name,
                    omega,
                    RO_target='all',
                    precompiled_flux=True):
    '''
    Writes the QASM sequence to take a state tomography of the output state
    of Grover's algorithm on two qubits.
    Sequence:
        q0: G0 -       - mY90 -    - mY90  - RO
                 CZ_ij          CZ
        q1: G1 -       - mY90 -    - mY90  - RO
    where (ij) is the binary representation of omega.
    G0 and G1 are Y90 or Y90, depending on the (ij).

    Args:
        q0_name, q1_name (string):
                Names of the qubits to which the sequence is applied.
        omega (int):
                Deterines which (ij) for the CZ_ij.
        RO_target (string):
                Readout target. Can be a qubit name or 'all'.
        precompiled_flux (bool):
                Determies if the full waveform for the flux pulses is
                precompiled, thus only needing one trigger at the start,
                or if every flux pulse should be triggered individually.

    Returns:
        qasm_file: a reference to the new QASM file object.
    '''
    if not precompiled_flux:
        raise NotImplementedError('Currently only precompiled flux pulses '
                                  'are supported.')

    tomo_pulses = ['I ', 'X180 ', 'Y90 ', 'mY90 ', 'X90 ', 'mX90 ']
    tomo_list_q0 = []
    tomo_list_q1 = []
    for tp in tomo_pulses:
        tomo_list_q0 += [tp + q0_name]
        tomo_list_q1 += [tp + q1_name]

    if omega == 0:
        G0 = 'Y90'
        G1 = 'Y90'
    elif omega == 1:
        G0 = 'Y90'
        G1 = 'mY90'
    elif omega == 2:
        G0 = 'mY90'
        G1 = 'Y90'
    elif omega == 3:
        G0 = 'mY90'
        G1 = 'mY90'
    else:
        raise ValueError('omega must be in [0, 3]')

    if RO_target == 'all':
        RO_line = 'RO {} | RO {}\n'.format(q0_name, q1_name)
    else:
        RO_line = 'RO {} \n'.format(RO_target)

    filename = join(base_qasm_path, 'Grover_tomo_seq.qasm')
    qasm_file = mopen(filename, mode='w')
    qasm_file.writelines('qubit {} \n'.format(q0_name))
    qasm_file.writelines('qubit {} \n'.format(q1_name))

    for p_q1 in tomo_list_q1:
        for p_q0 in tomo_list_q0:
            qasm_file.writelines('\ninit_all\n')
            qasm_file.writelines('{} {} | {} {}\n'.format(
                G0, q0_name, G1, q1_name))
            qasm_file.writelines('grover_CZ {} {}\n'.format(q0_name, q1_name))
            qasm_file.writelines('Y90 {} | Y90 {}\n'.format(q0_name, q1_name))
            qasm_file.writelines('cz {} {}\n'.format(q0_name, q1_name))
            qasm_file.writelines('Y90 {} | Y90 {}\n'.format(q0_name, q1_name))

            qasm_file.writelines('{} | {}\n'.format(p_q1, p_q0))
            qasm_file.writelines(RO_line)

    # Add calibration pulses
    cal_pulses = []
    # every calibration point is repeated 7 times. This is copied from the
    # script for Tektronix driven qubits. I do not know if this repetition
    # is important or even necessary here.
    for seq in cal_points_2Q:
        cal_pulses += [[
            seq[0].format(q0_name), seq[1].format(q1_name), RO_line
        ]] * 7

    for seq in cal_pulses:
        qasm_file.writelines('\ninit_all\n')
        for p in seq:
            qasm_file.writelines(p)

    qasm_file.close()
    return qasm_file
コード例 #35
0
def two_qubit_AllXY(q0, q1, RO_target='all',
                    sequence_type='sequential',
                    replace_q1_pulses_X180=False,
                    double_points=False):
    """
    AllXY sequence on two qubits.
    Has the option of replacing pulses on q1 with pi pulses

    Args:
        q0, q1         (str) : target qubits for the sequence
        RO_target      (str) : target for the RO, can be a qubit name or 'all'
        sequence_type  (str) : sequential | interleaved | simultaneous | sandwiched
                              q0|q0|q1|q1   q0|q1|q0|q1   q01|q01      q1|q0|q0|q1
                            N.B.!  simultaneous is currently not possible!
            describes the order of the AllXY pulses
        replace_q1_pulses_X180 (bool) : if True replaces all pulses on q1 with
            X180 pulses.

        double_points (bool) : if True measures each point in the AllXY twice
    """

    pulse_combinations = [['I', 'I'], ['X180', 'X180'], ['Y180', 'Y180'],
                          ['X180', 'Y180'], ['Y180', 'X180'],
                          ['X90', 'I'], ['Y90', 'I'], ['X90', 'Y90'],
                          ['Y90', 'X90'], ['X90', 'Y180'], ['Y90', 'X180'],
                          ['X180', 'Y90'], ['Y180', 'X90'], ['X90', 'X180'],
                          ['X180', 'X90'], ['Y90', 'Y180'], ['Y180', 'Y90'],
                          ['X180', 'I'], ['Y180', 'I'], ['X90', 'X90'],
                          ['Y90', 'Y90']]

    pulse_combinations_tiled = pulse_combinations + pulse_combinations
    if double_points:
        pulse_combinations = [val for val in pulse_combinations
                              for _ in (0, 1)]

    if replace_q1_pulses_X180:
        pulse_combinations_q1 = ['X180' for val in pulse_combinations]

    pulse_combinations_q0 = pulse_combinations
    pulse_combinations_q1 = pulse_combinations_tiled


    filename = join(base_qasm_path, 'two_qubit_AllXY.qasm')
    qasm_file = mopen(filename, mode='w')
    qasm_file.writelines('qubit {} \nqubit {} \n'.format(q0, q1))

    for pulse_comb_q0, pulse_comb_q1 in zip(pulse_combinations_q0,
                                            pulse_combinations_q1):
        qasm_file.writelines('\ninit_all\n')
        if sequence_type == 'interleaved':
            qasm_file.writelines('{} {}\n'.format(pulse_comb_q0[0], q0) +
                                 '{} {}\n'.format(pulse_comb_q1[0], q1) +
                                 '{} {}\n'.format(pulse_comb_q0[1], q0) +
                                 '{} {}\n'.format(pulse_comb_q1[1], q1))
        elif sequence_type == 'sandwiched':
            qasm_file.writelines('{} {}\n'.format(pulse_comb_q1[0], q1) +
                                 '{} {}\n'.format(pulse_comb_q0[0], q0) +
                                 '{} {}\n'.format(pulse_comb_q0[1], q0) +
                                 '{} {}\n'.format(pulse_comb_q1[1], q1))
        elif sequence_type == 'sequential':
            qasm_file.writelines('{} {}\n'.format(pulse_comb_q0[0], q0) +
                                 '{} {}\n'.format(pulse_comb_q0[1], q0) +
                                 '{} {}\n'.format(pulse_comb_q1[0], q1) +
                                 '{} {}\n'.format(pulse_comb_q1[1], q1))
        elif sequence_type == 'simultaneous':
            qasm_file.writelines('{} {} |'.format(pulse_comb_q0[0], q0) +
                                 '{} {}\n'.format(pulse_comb_q1[0], q1) +
                                 '{} {} |'.format(pulse_comb_q0[1], q0) +
                                 '{} {}\n'.format(pulse_comb_q1[1], q1))
        else:
            raise ValueError("sequence_type {} ".format(sequence_type) +
                             "['interleaved', 'simultaneous', " +
                             "'sequential', 'sandwiched']")
        qasm_file.writelines('RO {}  \n'.format(RO_target))

    qasm_file.close()
    return qasm_file
コード例 #36
0
def CZ_state_cycling_light(q0: str, q1: str, N: int=1):
    """
    Implements a circuit that performs a permutation over all computational
    states. This light version performs this experiment for all 4 possible
    input states.

    Expected operation:
        U (|00>) -> |01>
        U (|01>) -> |11>
        U (|10>) -> |00>
        U (|11>) -> |10>

    Args:
        q0 (str): name of qubit q0
        q1 (str): name of qubit q1
        N  (int): number of times to apply U
    """
    filename = join(base_qasm_path, 'CZ_state_cycling_light.qasm')
    qasm_file = mopen(filename, mode='w')
    qasm_file.writelines('qubit {} \nqubit {} \n'.format(q0, q1))

    U = ''
    U += 'Y90 {} | mY90 {}\n'.format(q0, q1)
    U += 'CZ {} {}\n'.format(q0, q1)
    U += 'Y90 {} | Y90 {}\n'.format(q0, q1)
    U += 'CZ {} {}\n'.format(q0, q1)
    U += 'Y90 {} | Y90 {}\n'.format(q0, q1)

    # Input |00>
    qasm_file.writelines('init_all \n')
    qasm_file.writelines('qwg_trigger_0 {}\n'.format(q0))
    for n in range(N):
        qasm_file.writelines(U)
    qasm_file.writelines('RO {}\n'.format(q0))

    # Input |01>
    qasm_file.writelines('init_all \n')
    qasm_file.writelines('qwg_trigger_0 {}\n'.format(q0))
    qasm_file.writelines('X180 {}\n'.format(q0))
    for n in range(N):
        qasm_file.writelines(U)
    qasm_file.writelines('RO {}\n'.format(q0))

    # Input |10>
    qasm_file.writelines('init_all \n')
    qasm_file.writelines('qwg_trigger_0 {}\n'.format(q0))
    qasm_file.writelines('X180 {}\n'.format(q1))
    for n in range(N):
        qasm_file.writelines(U)
    qasm_file.writelines('RO {}\n'.format(q0))

    # Input |11>
    qasm_file.writelines('init_all \n')
    qasm_file.writelines('qwg_trigger_0 {}\n'.format(q0))
    qasm_file.writelines('X180 {} | X180 {}\n'.format(q0, q1))
    for n in range(N):
        qasm_file.writelines(U)
    qasm_file.writelines('RO {}\n'.format(q0))

    qasm_file.close()
    return qasm_file
コード例 #37
0
def two_qubit_tomo_bell(bell_state, q0, q1,
                        wait_after_trigger=10e-9, wait_during_flux=260e-9,
                        clock_cycle=1e-9,
                        single_qubit_compiled_phase=False,
                        RO_target='all'):
    '''
    Two qubit bell state tomography.

    Args:
        bell_state      (int): index of prepared bell state
        q0, q1          (str): names of the target qubits
        wait_after_trigger (float): delay time in seconds after sending the
                                    trigger for the flux pulse
        clock_cycle     (float): period of the internal AWG clock
        wait_during_flux (int): wait time during the flux pulse
        single_qubit_compiled_phase (bool): wether to do single qubit phase
            correction in the recovery pulse
        RO_target   (str): can be q0, q1, or 'all'
    '''
    tomo_pulses = ['I ', 'X180 ', 'Y90 ', 'mY90 ', 'X90 ', 'mX90 ']
    tomo_list_q0 = []
    tomo_list_q1 = []
    for tp in tomo_pulses:
        tomo_list_q0 += [tp + q0 + '\n']
        tomo_list_q1 += [tp + q1 + '\n']

    tomo_list_q0[0] = 'I 20\n'
    tomo_list_q1[0] = 'I 20\n'

    # Choose a bell state and set the corresponding preparation pulses
    if bell_state % 10 == 0:  # |Phi_m>=|00>-|11>
        prep_pulse_q0 = 'Y90 {}\n'.format(q0)
        prep_pulse_q1 = 'Y90 {}\n'.format(q1)
    elif bell_state % 10 == 1:  # |Phi_p>=|00>+|11>
        prep_pulse_q0 = 'mY90 {}\n'.format(q0)
        prep_pulse_q1 = 'Y90 {}\n'.format(q1)
    elif bell_state % 10 == 2:  # |Psi_m>=|01>-|10>
        prep_pulse_q0 = 'Y90 {}\n'.format(q0)
        prep_pulse_q1 = 'mY90 {}\n'.format(q1)
    elif bell_state % 10 == 3:  # |Psi_p>=|01>+|10>
        prep_pulse_q0 = 'mY90 {}\n'.format(q0)
        prep_pulse_q1 = 'mY90 {}\n'.format(q1)
    else:
        raise ValueError('Bell state {} is not defined.'.format(bell_state))

    # Recovery pulse is the same for all Bell states
    if single_qubit_compiled_phase == False:
        after_pulse = 'mY90 {}\n'.format(q1)
    else:
        after_pulse = 'recmY90 {}\n'.format(q1)

    # Disable preparation pulse on one or the other qubit for debugging
    if bell_state//10 == 1:
        prep_pulse_q1 = 'I 20'
    elif bell_state//10 == 2:
        prep_pulse_q0 = 'I 20'

    # Define compensation pulses
    # FIXME: needs to be added
    print('Warning: not using compensation pulses.')

    # Write tomo sequence

    filename = join(base_qasm_path, 'two_qubit_tomo_bell.qasm')
    qasm_file = mopen(filename, mode='w')
    qasm_file.writelines('qubit {} \nqubit {} \n'.format(q0, q1))

    for p_q1 in tomo_list_q1:
        for p_q0 in tomo_list_q0:
            qasm_file.writelines('\ninit_all\n')
            qasm_file.writelines('QWG trigger\n')
            qasm_file.writelines(
                'I {}\n'.format(int(wait_after_trigger//clock_cycle)))
            qasm_file.writelines(prep_pulse_q0)
            qasm_file.writelines(prep_pulse_q1)
            qasm_file.writelines(
                'I {}\n'.format(int(wait_during_flux//clock_cycle)))
            qasm_file.writelines(after_pulse)
            qasm_file.writelines(p_q1)
            qasm_file.writelines(p_q0)
            qasm_file.writelines('RO ' + RO_target + '  \n')

    # Add calibration pulses
    cal_pulses = []
    # every calibration point is repeated 7 times. This is copied from the
    # script for Tektronix driven qubits. I do not know if this repetition
    # is important or even necessary here.
    for seq in cal_points_2Q:
        cal_pulses += [[seq[0].format(q0), seq[1].format(q1), 'RO ' + RO_target + '\n']] * 7

    for seq in cal_pulses:
        qasm_file.writelines('\ninit_all\n')
        for p in seq:
            qasm_file.writelines(p)

    qasm_file.close()
    return qasm_file
コード例 #38
0
def grover_test_tomo_seq(q0_name,
                         q1_name,
                         omega,
                         RO_target='all',
                         precompiled_flux=True):
    '''
    Test sequence to debug Grover's algorithm.
    '''
    if not precompiled_flux:
        raise NotImplementedError('Currently only precompiled flux pulses '
                                  'are supported.')

    tomo_pulses = ['I ', 'X180 ', 'Y90 ', 'mY90 ', 'X90 ', 'mX90 ']
    tomo_list_q0 = []
    tomo_list_q1 = []
    for tp in tomo_pulses:
        tomo_list_q0 += [tp + q0_name]
        tomo_list_q1 += [tp + q1_name]

    if omega == 0:
        G0 = 'Y90'
        G1 = 'Y90'
    elif omega == 1:
        G0 = 'Y90'
        G1 = 'mY90'
    elif omega == 2:
        G0 = 'mY90'
        G1 = 'Y90'
    elif omega == 3:
        G0 = 'mY90'
        G1 = 'mY90'
    else:
        raise ValueError('omega must be in [0, 3]')

    if RO_target == 'all':
        RO_line = 'RO {} | RO {}\n'.format(q0_name, q1_name)
    else:
        RO_line = 'RO {} \n'.format(RO_target)

    filename = join(base_qasm_path, 'Grover_tomo_seq.qasm')
    qasm_file = mopen(filename, mode='w')
    qasm_file.writelines('qubit {} \n'.format(q0_name))
    qasm_file.writelines('qubit {} \n'.format(q1_name))

    for p_q1 in tomo_list_q1:
        for p_q0 in tomo_list_q0:
            qasm_file.writelines('\ninit_all\n')
            qasm_file.writelines('{} {} | {} {}\n'.format(
                G0, q0_name, G1, q1_name))
            qasm_file.writelines('grover_cz {} {}\n'.format(q0_name, q1_name))
            qasm_file.writelines('Y90 {} | Y90 {}\n'.format(q0_name, q1_name))
            qasm_file.writelines('cz {} {}\n'.format(q0_name, q1_name))
            # qasm_file.writelines('Y90 {} | Y90 {}\n'.format(q0_name,
            # q1_name))
            qasm_file.writelines('{} | {}\n'.format(p_q1, p_q0))
            qasm_file.writelines(RO_line)

    # Add calibration pulses
    cal_pulses = []
    # every calibration point is repeated 7 times. This is copied from the
    # script for Tektronix driven qubits. I do not know if this repetition
    # is important or even necessary here.
    for seq in cal_points_2Q:
        cal_pulses += [[
            seq[0].format(q0_name), seq[1].format(q1_name), RO_line
        ]] * 7

    for seq in cal_pulses:
        qasm_file.writelines('\ninit_all\n')
        for p in seq:
            qasm_file.writelines(p)

    qasm_file.close()
    return qasm_file
コード例 #39
0
def CZ_fast_calibration_seq(q0_name: str, q1_name: str, no_of_points: int,
                            cal_points: bool=True,
                            RO_target: str='all',
                            CZ_disabled: bool=False,
                            cases=('no_excitation', 'excitation'),
                            wait_after_trigger=40e-9,
                            wait_during_flux=280e-9,
                            clock_cycle=1e-9,
                            mw_pulse_duration=40e-9):
    '''
    Sequence used to (numerically) calibrate CZ gate, including single qubit
    phase corrections.
    Repeats the sequence below 'no_of_points' times, giving a new trigger
    instruction
        QWG trigger 'i'
    every time, where 'i' is the number of iteration (starting at 0).

    Timing of the sequence:
    q0:   --   mX90  C-Phase  X90   --      RO
    q1: (X180)  --     --       --   (X180)    RO

    Args:
        q0, q1      (str): names of the addressed qubits
        RO_target   (str): can be q0, q1, or 'all'
        CZ_disabled (bool): disable CZ gate
        excitations (bool/str): can be True, False, or 'both_cases'
        clock_cycle (float): period of the internal AWG clock
        wait_time   (int): wait time in seconds after triggering the flux
    '''
    filename = join(base_qasm_path, 'CZ_fast_calibration_seq.qasm')
    qasm_file = mopen(filename, mode='w')
    qasm_file.writelines('qubit {} \nqubit {} \n'.format(q0_name, q1_name))

    for i in range(no_of_points):

        if cal_points and (i == no_of_points - 4 or i == no_of_points - 3):
            # Calibration point for |0>
            qasm_file.writelines('\ninit_all\n')
            qasm_file.writelines('RO {}  \n'.format(RO_target))
            pass
        elif cal_points and (i == no_of_points - 2 or i == no_of_points - 1):
            # Calibration point for |1>
            qasm_file.writelines('\ninit_all\n')
            qasm_file.writelines('X180 {} \n'.format(q0_name))
            qasm_file.writelines('X180 {} \n'.format(q1_name))
            qasm_file.writelines('RO {}  \n'.format(RO_target))
        else:
            for case in cases:
                qasm_file.writelines('\ninit_all\n')
                qasm_file.writelines('QWG_trigger_{}\n'.format(i))
                waitTime = wait_after_trigger
                if case == 'excitation':
                    # Decrease wait time because there is an additional pulse
                    waitTime -= mw_pulse_duration
                qasm_file.writelines(
                    'I {}\n'.format(int(waitTime//clock_cycle)))
                if case == 'excitation':
                    qasm_file.writelines('X180 {}\n'.format(q1_name))
                qasm_file.writelines('mX90 {}\n'.format(q0_name))
                qasm_file.writelines(
                    'I {}\n'.format(int(wait_during_flux//clock_cycle)))
                qasm_file.writelines('X90 {}\n'.format(q0_name))
                if case == 'excitation':
                    qasm_file.writelines('X180 {}\n'.format(q1_name))

                qasm_file.writelines('RO {}  \n'.format(RO_target))

    qasm_file.close()
    return qasm_file
コード例 #40
0
def two_qubit_tomo_bell(bell_state, q0, q1, RO_target='all'):
    '''
    Two qubit bell state tomography.

    Args:
        bell_state      (int): index of prepared bell state
                        0 : |00>-|11>
                        1 : |00>+|11>
                        2 : |01>-|10>
                        3 : |01>+|10>
        q0, q1          (str): names of the target qubits
        RO_target   (str): can be q0, q1, or 'all'
    '''

    if RO_target == 'all':
        # This is a bit of a hack as RO all qubits is the same instruction
        # as any specific qubit
        RO_target = q0

    tomo_pulses = ['I ', 'X180 ', 'Y90 ', 'mY90 ', 'X90 ', 'mX90 ']
    tomo_list_q0 = []
    tomo_list_q1 = []
    for tp in tomo_pulses:
        tomo_list_q0 += [tp + q0]
        tomo_list_q1 += [tp + q1]

    tomo_list_q0[0] = 'I {}'.format(q0)
    tomo_list_q1[0] = 'I {}'.format(q1)

    # Choose a bell state and set the corresponding preparation pulses
    if bell_state % 10 == 0:  # |Phi_m>=|00>-|11>
        prep_pulse_q0 = 'Y90 {}'.format(q0)
        prep_pulse_q1 = 'Y90 {}'.format(q1)
    elif bell_state % 10 == 1:  # |Phi_p>=|00>+|11>
        prep_pulse_q0 = 'mY90 {}'.format(q0)
        prep_pulse_q1 = 'Y90 {}'.format(q1)
    elif bell_state % 10 == 2:  # |Psi_m>=|01>-|10>
        prep_pulse_q0 = 'Y90 {}'.format(q0)
        prep_pulse_q1 = 'mY90 {}'.format(q1)
    elif bell_state % 10 == 3:  # |Psi_p>=|01>+|10>
        prep_pulse_q0 = 'mY90 {}'.format(q0)
        prep_pulse_q1 = 'mY90 {}'.format(q1)
    else:
        raise ValueError('Bell state {} is not defined.'.format(bell_state))

    after_pulse = 'mY90 {}\n'.format(q1)

    # Disable preparation pulse on one or the other qubit for debugging
    if bell_state // 10 == 1:
        prep_pulse_q1 = 'I {}'.format(q0)
    elif bell_state // 10 == 2:
        prep_pulse_q0 = 'I {}'.format(q1)

    # Write tomo sequence

    filename = join(base_qasm_path, 'two_qubit_tomo_bell.qasm')
    qasm_file = mopen(filename, mode='w')
    qasm_file.writelines('qubit {} \nqubit {} \n'.format(q0, q1))

    for p_q1 in tomo_list_q1:
        for p_q0 in tomo_list_q0:
            qasm_file.writelines('\ninit_all\n')
            qasm_file.writelines('{} | {} \n'.format(prep_pulse_q0,
                                                     prep_pulse_q1))
            qasm_file.writelines('CZ {} {} \n'.format(q0, q1))
            qasm_file.writelines(after_pulse)
            qasm_file.writelines('{} | {}\n'.format(p_q1, p_q0))
            qasm_file.writelines('RO ' + RO_target + '  \n')

    # Add calibration pulses
    cal_pulses = []
    # every calibration point is repeated 7 times. This is copied from the
    # script for Tektronix driven qubits. I do not know if this repetition
    # is important or even necessary here.
    for seq in cal_points_2Q:
        cal_pulses += [[
            seq[0].format(q0), seq[1].format(q1), 'RO ' + RO_target + '\n'
        ]] * 7

    for seq in cal_pulses:
        qasm_file.writelines('\ninit_all\n')
        for p in seq:
            qasm_file.writelines(p)

    qasm_file.close()
    return qasm_file
コード例 #41
0
def qasm_to_asm(qasm_filepath, operation_dict):
    """
    Args:
        qasm_filepath: (str) location of the qasm file to convert

        operation_dict: (dict) dictionary containing info required for
            conversion.
            *keys*  correspond to qasm commands
            *items* contain dicts with the reuired information.
            every item should contain the following entries:
                instruction: (str) or (fun) that defines the translation
                    from qasm to microcode/assembly
                duration: (int) length of operation expressed in clock cycles
                prepare_function: (str) str that refers to function used to
                    prepare the operation
                prepare_function_kwargs: (dict) containing arguments that get
                    passed to the prepare function

    returns:
        asm_file suitable for CBox Assembler, intended to be compatible
        with the central controller in the future.
    """
    filename = splitext(basename(qasm_filepath))[0]
    asm_filepath = join(base_asm_path, filename + '.qumis')
    asm_file = mopen(asm_filepath, mode='w')
    asm_file.writelines(preamble)

    with open(qasm_filepath) as qasm_file:
        qubits = []  # the qubits that were defined
        for line in qasm_file:
            # Make lines interpretable
            line = line.split('#', 1)[0]  # remove comments
            line = line.split('map', 1)[0]  # remove mapping info if supplied
            line = line.strip(' \t\n\r')  # remove whitespace
            if (len(line) == 0):  # skip empty line and comment
                continue
            elts = line.split()
            # for single qubit gates that have an argument
            if len(elts) > 1:
                base_op = elts[0] + ' ' + elts[1]

            # Interpret qasm elements
            commands = list(operation_dict.keys()) + ['qubit']
            if elts[0] == 'qubit':
                qubits.append(elts[1])

            elif (line in commands):
                instruction = operation_dict[line]['instruction']
                asm_file.writelines(instruction)
            # two qubit operation or operation with arg
            elif base_op in commands:
                # single qubit op with argument
                if 'instruction' in operation_dict[base_op].keys():
                    base_ins = operation_dict[base_op]['instruction']
                    # string formatting is a constraint now but maybe we can
                    # come up with something smarter
                    if isinstance(base_ins, str):
                        instruction = base_ins.format(elts[2])
                    else:
                        instruction = base_ins(elts[2])
                else:  # no support yet for multi qubit ops with arguments
                    raise NotImplementedError(
                        'Multi qubit ops with args: "{}"'.format(line))
                asm_file.writelines(instruction)
            # Identity is a special instruction that is supported as a wait
            elif elts[0] == 'I' or elts[0] == 'Idx':
                clock_waits = int(int(elts[1]) // 5)
                instruction = 'wait {} \n'.format(clock_waits)
                asm_file.writelines(instruction)
            else:
                raise ValueError(
                    'Command "{}" not recognized, must be in {}'.format(
                        elts[0], commands))

    asm_file.writelines(ending)
    asm_file.close()
    return asm_file
コード例 #42
0
def qasm_to_asm(qasm_filepath, operation_dict):
    """
    Args:
        qasm_filepath: (str) location of the qasm file to convert

        operation_dict: (dict) dictionary containing info required for
            conversion.
            *keys*  correspond to qasm commands
            *items* contain dicts with the reuired information.
            every item should contain the following entries:
                instruction: (str) or (fun) that defines the translation
                    from qasm to microcode/assembly
                duration: (int) length of operation expressed in clock cycles
                prepare_function: (str) str that refers to function used to
                    prepare the operation
                prepare_function_kwargs: (dict) containing arguments that get
                    passed to the prepare function

    returns:
        asm_file suitable for CBox Assembler, intended to be compatible
        with the central controller in the future.
    """
    filename = splitext(basename(qasm_filepath))[0]
    asm_filepath = join(base_asm_path, filename+'.qumis')
    asm_file = mopen(asm_filepath, mode='w')
    asm_file.writelines(preamble)

    with open(qasm_filepath) as qasm_file:
        qubits = []  # the qubits that were defined
        for line in qasm_file:
            # Make lines interpretable
            line = line.split('#', 1)[0]  # remove comments
            line = line.strip(' \t\n\r')  # remove whitespace
            if (len(line) == 0):  # skip empty line and comment
                continue
            elts = line.split()
            # for single qubit gates that have an argument
            if len(elts) > 1:
                base_op = elts[0]+' '+elts[1]

            # Interpret qasm elements
            commands = list(operation_dict.keys()) + ['qubit']
            if elts[0] == 'qubit':
                qubits.append(elts[1])

            elif (line in commands):
                instruction = operation_dict[line]['instruction']
                asm_file.writelines(instruction)
            # two qubit operation or operation with arg
            elif base_op in commands:
                # single qubit op with argument
                if 'instruction' in operation_dict[base_op].keys():
                    base_ins = operation_dict[base_op]['instruction']
                    # string formatting is a constraint now but maybe we can
                    # come up with something smarter
                    if isinstance(base_ins, str):
                        instruction = base_ins.format(elts[2])
                    else:
                        instruction = base_ins(elts[2])
                else:  # no support yet for multi qubit ops with arguments
                    raise NotImplementedError(
                        'Multi qubit ops with args: "{}"'.format(line))
                asm_file.writelines(instruction)
            else:
                raise ValueError(
                    'Command "{}" not recognized, must be in {}'.format(
                        elts[0], commands))

    asm_file.writelines(ending)
    asm_file.close()
    return asm_file
コード例 #43
0
def grover_test_seq(q0_name,
                    q1_name,
                    RO_target='all',
                    precompiled_flux=True,
                    cal_points: bool = True):
    '''
    Writes the QASM sequence for Grover's algorithm on two qubits.
    Sequence:
        q0: G0 -       - mY90 -    - mY90  - RO
                 CZ_ij          CZ
        q1: G1 -       - mY90 -    - mY90  - RO
    whit all combinations of (ij) = omega.
    G0 and G1 are Y90 or Y90, depending on the (ij).

    Args:
        q0_name, q1_name (string):
                Names of the qubits to which the sequence is applied.
        RO_target (string):
                Readout target. Can be a qubit name or 'all'.
        precompiled_flux (bool):
                Determies if the full waveform for the flux pulses is
                precompiled, thus only needing one trigger at the start,
                or if every flux pulse should be triggered individually.
        cal_points (bool):
                Whether to add calibration points.

    Returns:
        qasm_file: a reference to the new QASM file object.
    '''
    if not precompiled_flux:
        raise NotImplementedError('Currently only precompiled flux pulses '
                                  'are supported.')

    filename = join(base_qasm_path, 'Grover_seq.qasm')
    qasm_file = mopen(filename, mode='w')
    qasm_file.writelines('qubit {} \n'.format(q0_name))
    qasm_file.writelines('qubit {} \n'.format(q1_name))

    if RO_target == 'all':
        RO_line = 'RO {} | RO {}\n'.format(q0_name, q1_name)
    else:
        RO_line = 'RO {} \n'.format(RO_target)

    for G0 in ['Y90', 'mY90']:
        for G1 in ['Y90', 'mY90']:
            qasm_file.writelines('\ninit_all\n')
            qasm_file.writelines('{} {} | {} {}\n'.format(
                G0, q0_name, G1, q1_name))
            qasm_file.writelines('grover_CZ {} {}\n'.format(q0_name, q1_name))
            qasm_file.writelines('Y90 {} | Y90 {}\n'.format(q0_name, q1_name))
            # qasm_file.writelines('cz {} {}\n'.format(q0_name, q1_name))
            # qasm_file.writelines('Y90 {} | Y90 {}\n'.format(q0_name,
            #                                                   q1_name))

            qasm_file.writelines(RO_line)

    # Add calibration points
    if cal_points:
        cal_pulses = []
        for seq in cal_points_2Q:
            cal_pulses += [[
                seq[0].format(q0_name), seq[1].format(q1_name), RO_line
            ]]

        for seq in cal_pulses:
            qasm_file.writelines('\ninit_all\n')
            for p in seq:
                qasm_file.writelines(p)

    qasm_file.close()
    return qasm_file