def t5(): """ Like t3, but the function call does nothing """ q1 = QRegister('q1') q2 = QRegister('q2')
def t3(): """ Like t2, but with a function call """ q1 = QRegister('q1') q2 = QRegister('q2') cond_helper(q1, True)
def anotherMulti2(): qs = QRegister(3) qsub = QRegister(qs[0], qs[1]) Id(qsub) X(qs[0:2]) # equivalent to calling with qsub argument Barrier(qs) MEAS(qsub) Barrier(qs) Y(qs[0]) Y(qs[2])
def edgeTest3(): q1 = QRegister('q1') q2 = QRegister('q2') for q in [q1, q2]: init(q) echoCR(q1, q2) X(q2) Y(q2) Id(q2) X(q2)
def main(): """ The initial role of each qbit is: q0:d q1:x q2:d q3:z q4:d q5:z q6:d q7:x q8:d And the order of CNOTs is up-left-right-down """ q0 = QRegister('q0') q1 = QRegister('q1') q2 = QRegister('q2') q3 = QRegister('q3') q4 = QRegister('q4') q5 = QRegister('q5') q6 = QRegister('q6') q7 = QRegister('q7') q8 = QRegister('q8') all_qbits = [q0, q1, q2, q3, q4, q5, q6, q7, q8] role_def = dict() role_def[q0] = SyndromeRole('d', [None, None, q1, q3]) role_def[q1] = SyndromeRole('x', [None, q0, q2, q4]) role_def[q2] = SyndromeRole('d', [None, q1, None, q5]) role_def[q3] = SyndromeRole('z', [q0, None, q4, q6]) role_def[q4] = SyndromeRole('d', [q1, q3, q5, q7]) role_def[q5] = SyndromeRole('z', [q2, q4, None, q8]) role_def[q6] = SyndromeRole('d', [q3, None, q7, None]) role_def[q7] = SyndromeRole('x', [q4, q6, q8, None]) role_def[q8] = SyndromeRole('d', [q5, q7, None, None]) syndrome_cycle(all_qbits, role_def)
def t4(): """ Like t3, but the function call does nothing """ q1 = QRegister('q1') q2 = QRegister('q2') cond_helper(q1, False) X(q1) # need to do something
def anotherMulti3(): qs = QRegister(3) # create the QRegister with slicing qsub = QRegister(qs[0:2]) Id(qsub) X(qsub) Barrier(qs) MEAS(qsub) Barrier(qs) Y(qs[0]) Y(qs[2])
def t2(): """ Correct result is [ X(q1) ] """ q1 = QRegister('q1') q2 = QRegister('q2') # We're not going to reference q2 anywhere, # just to make sure that the compiler doesn't # freak out X(q1)
def RabiAmp_NQubits(qubits: qreg, amps, phase=0, measChans: qreg = None, docals=False, calRepeats=2): """ Variable amplitude Rabi nutation experiment for an arbitrary number of qubits simultaneously Parameters ---------- qubits : tuple of logical channels to implement sequence (LogicalChannel) amps : pulse amplitudes to sweep over for all qubits (iterable) phase : phase of the pulses (radians) measChans : tuple of qubits to be measured (use qubits if not specified) (LogicalChannel) docals, calRepeats: enable calibration sequences, repeated calRepeats times """ if measChans is None: measChans = qubits allChans = QRegister(qubits, measChans) for amp in amps: init(allChans) Utheta(qubits, amp=amp, phase=phase) measConcurrently(measChans) if docals: create_cal_seqs(qubits, calRepeats, measChans)
def multiQbitTest2(): qs = QRegister('q1', 'q2') Id(qs) X(qs) Barrier(qs) MEAS(qs)
def t3(): """ Expected: [X(q1), X(q1), X(q1)] """ q1 = QRegister('q1') total = 0 if total == 0: X(q1) else: Y(q1) total += 2 if total == 2: total += 2 X(q1) else: total += 1 Y(q1) if total == 4: X(q1) else: Y(q1)
def measConcurrently(listNQubits: qreg) -> pulse: '''Concurrently measure given QRegister of qubits. Note: Includes a Barrier on the input qreg to force measurements to be concurrent; QGL1 does Pulse*Pulse == PulseBlock(pulses), which is equivalent.''' qr = QRegister(listNQubits) Barrier(qr) MEAS(qr)
def anotherMulti(): qs = QRegister(2) Id(qs) X(qs) Barrier(qs) MEAS(qs) Y(qs)
def t1(): """ Correct result is [ X(q1), X(q1), X(q1) ] """ q1 = QRegister('q1') (x, y, z) = (1, 2, 3) if (x, y, z) == (1, 2, 3): X(q1) else: print('oops 1') Y(q1) (x, y, z) = (y, z, x) if (x, y, z) == (2, 3, 1): X(q1) else: print('oops 2') Y(q1) (x, y, z) = (y, z, x) if (x, y, z) == (3, 1, 2): X(q1) else: print('oops 3') Y(q1)
def t2(): """ Expected: [X(q1), X(q1), X(q1), X(q1)] """ q1 = QRegister('q1') l1 = [0, 1, 2, 3] l1 = l1[:2] + l1[2:] if l1 == [0, 1, 2, 3]: X(q1) else: Y(q1) l1 = l1[2:] + l1[:2] if l1 == [2, 3, 0, 1]: X(q1) else: Y(q1) l1 = l1[3:] + l1[:3] if l1 == [1, 2, 3, 0]: X(q1) else: Y(q1) l1 = l1[1:] + l1[:1] if l1 == [2, 3, 0, 1]: X(q1) else: Y(q1)
def CRtomo_seq(controlQ: qreg, targetQ: qreg, lengths, ph, amp=0.8, riseFall=20e-9): """ Variable length CX experiment, for Hamiltonian tomography. Parameters ---------- controlQ : logical channel for the control qubit (LogicalChannel) targetQ: logical channel for the target qubit (LogicalChannel) lengths : pulse lengths of the CR pulse to sweep over (iterable) riseFall : rise/fall time of the CR pulse (s) ph : phase of the CR pulse (rad) """ # Rather than do EdgeFactory and regular flat_top_gaussian, # define a new QGL2 stub where the QGL1 implementation does that, # so QGL2 can avoid dealing with the edge # CRchan = EdgeFactory(controlQ, targetQ) # flat_top_gaussian is an addition of 3 UTheta pulses cNt = QRegister(controlQ, targetQ) tomo_pulses = [Y90m, X90, Id] # Sequence 1 for l, tomo_pulse in product(lengths, tomo_pulses): init(cNt) Id(controlQ) flat_top_gaussian_edge(controlQ, targetQ, riseFall=riseFall, length=l, amp=amp, phase=ph, label="CR") Barrier(cNt) Id(controlQ) tomo_pulse(targetQ) MEAS(targetQ) # Sequence 2 for l, tomo_pulse in product(lengths, tomo_pulses): init(cNt) X(controlQ) flat_top_gaussian_edge(controlQ, targetQ, riseFall=riseFall, length=l, amp=amp, phase=ph, label="CR") Barrier(cNt) X(controlQ) tomo_pulse(targetQ) MEAS(targetQ) create_cal_seqs(targetQ, 2)
def PiRabi(controlQ: qreg, targetQ: qreg, lengths, riseFall=40e-9, amp=1, phase=0, calRepeats=2): """ Variable length CX experiment. Parameters ---------- controlQ : logical channel for the control qubit (LogicalChannel) targetQ: logical channel for the target qubit (LogicalChannel) lengths : pulse lengths of the CR pulse to sweep over (iterable) riseFall : rise/fall time of the CR pulse (s) amp : amplitude of the CR pulse phase : phase of the CR pulse (rad) calRepeats : number repetitions of calibration sequences (int) """ # Rather than do EdgeFactory and regular flat_top_gaussian, # define a new QGL2 stub where the QGL1 implementation does that, # so QGL2 can avoid dealing with the edge # CRchan = EdgeFactory(controlQ, targetQ) # flat_top_gaussian is an addition of 3 UTheta pulses cNt = QRegister(controlQ, targetQ) # Sequence 1: Id(control), gaussian(l), measure both for l in lengths: init(cNt) Id(controlQ) flat_top_gaussian_edge(controlQ, targetQ, riseFall, length=l, amp=amp, phase=phase) measConcurrently(cNt) # Sequence 2: X(control), gaussian(l), X(control), measure both for l in lengths: init(cNt) X(controlQ) flat_top_gaussian_edge(controlQ, targetQ, riseFall, length=l, amp=amp, phase=phase) X(controlQ) measConcurrently(cNt) # Then do calRepeats calibration sequences create_cal_seqs(cNt, calRepeats)
def runtime_break(): q1 = QRegister("q1") for ct in range(3): m = MEAS(q1) if m: X90(q1) # this should produce an error break
def classical_break(): q1 = QRegister("q1") for ct in range(3): X(q1) if ct >= 1: X90(q1) break X90(q1) Y90(q1)
def t1(): """ Correct result is [ X(q1) ] """ q1 = QRegister('q1') cond_helper(q1, False) X(q1)
def classical_continue(): q1 = QRegister("q1") for ct in range(3): X(q1) if ct >= 1: X90(q1) continue X90(q1) Y90(q1)
def SingleShotNoArg(): """ Sample 0-argument 2-segment sequence with qubit prepared in |0> and |1>, useful for single-shot fidelity measurements and kernel calibration """ qubit = QRegister(1) init(qubit) Id(qubit) MEAS(qubit) init(qubit) X(qubit) MEAS(qubit)
def t4(): """ Correct result is [ X(q1), X(q1), X(q1), Y(q1), Y(q1) ] """ q1 = QRegister('q1') # No p_list: use a_list t4_helper(q1, X, [1, 2, 3]) # p_list supplied: use it t4_helper(q1, Y, [1], [1, 2])
def main(): from pyqgl2.qreg import QRegister import pyqgl2.test_cl from pyqgl2.main import compile_function, qgl2_compile_to_hardware import numpy as np toHW = True plotPulses = True pyqgl2.test_cl.create_default_channelLibrary(toHW, True) # # To turn on verbose logging in compile_function # from pyqgl2.ast_util import NodeError # from pyqgl2.debugmsg import DebugMsg # NodeError.MUTE_ERR_LEVEL = NodeError.NODE_ERROR_NONE # DebugMsg.set_level(0) # Now compile the QGL2 to produce the function that would generate the expected sequence. # Supply the path to the QGL2, the main function in that file, and a list of the args to that function. # Can optionally supply saveOutput=True to save the qgl1.py # file, # and intermediate_output="path-to-output-file" to save # intermediate products # Pass in a QRegister NOT the real Qubit q = QRegister(1) # SPAM(q1, np.linspace(0, pi/2, 11)) # - test_basic_mins uses np.linspace(0,1,11) # Here we know the function is in the current file # You could use os.path.dirname(os.path.realpath(__file)) to find files relative to this script, # Or os.getcwd() to get files relative to where you ran from. Or always use absolute paths. resFunction = compile_function(__file__, "SPAM", (q, np.linspace(0, pi / 2, 11), 10)) # Run the QGL2. Note that the generated function takes no arguments itself sequences = resFunction() if toHW: print("Compiling sequences to hardware\n") fileNames = qgl2_compile_to_hardware(sequences, filename='SPAM/SPAM') print(f"Compiled sequences; metafile = {fileNames}") if plotPulses: from QGL.PulseSequencePlotter import plot_pulse_files # FIXME: As called, this returns a graphical object to display plot_pulse_files(fileNames) else: print("\nGenerated sequences:\n") from QGL.Scheduler import schedule scheduled_seq = schedule(sequences) from IPython.lib.pretty import pretty print(pretty(scheduled_seq))
def create_cal_seqs(qubits: qreg, numRepeats, measChans=None, waitcmp=False, delay=None): """ Helper function to create a set of calibration sequences. Parameters ---------- qubits : a QRegister of channels to calibrate numRepeats : number of times to repeat calibration sequences (int) measChans : QRegister of channels to measure; default is to use qubits waitcmp = True if the sequence contains branching; default False delay: optional time between state preparation and measurement (s) """ # Allows supplying a tuple as is usually done in QGL1 qubitreg = QRegister(qubits) # QGL2 will warn here: # warning: parameter [measChans] overwritten by assignment if measChans is None: measChans = qubitreg # Make all combinations for qubit calibration states for n qubits and repeat # Assuming numRepeats=2 and qubits are q1, q2 # Produces 2 ^ #qubits * numRepeats sequences of Id, X, MEAS, # something like # [[Id(q1)*Id(q2), M(q1)*M(q2)], [Id(q1)*Id(q2), M(q1)*M(q2)], # [Id(q1)*X(q2), M(q1)*M(q2)], [Id(q1)*X(q2), M(q1)*M(q2)], # [X(q1)*Id(q2), M(q1)*M(q2)], [X(q1)*Id(q2), M(q1)*M(q2)], # [X(q1)*X(q2), M(q1)*M(q2)], [X(q1)*X(q2), M(q1)*M(q2)]] # Calibrate using Id and X pulses calSet = [Id, X] for pulseSet in product(calSet, repeat=len(qubitreg)): # Repeat each calibration numRepeats times for _ in range(numRepeats): init(qubitreg) for pulse, qubit in zip(pulseSet, qubitreg): pulse(qubit) if delay: # Add optional delay before measurement Id(qubitreg(0), length=delay) Barrier(measChans) MEAS(measChans) # If branching do wait if waitcmp: qwait(kind='CMP')
def EchoCRAmp(controlQ: qreg, targetQ: qreg, amps, riseFall=40e-9, length=50e-9, phase=0, calRepeats=2): """ Variable amplitude CX experiment, with echo pulse sandwiched between two CR opposite-phase pulses. Parameters ---------- controlQ : logical channel for the control qubit (LogicalChannel) targetQ: logical channel for the target qubit (LogicalChannel) amps : pulse amplitudes of the CR pulse to sweep over (iterable) riseFall : rise/fall time of the CR pulse (s) length : duration of each of the two flat parts of the CR pulse (s) phase : phase of the CR pulse (rad) calRepeats : number of repetitions of readout calibrations for each 2-qubit state """ cNt = QRegister(controlQ, targetQ) # Sequence 1 for a in amps: init(cNt) Id(controlQ) echoCR(controlQ, targetQ, length=length, phase=phase, riseFall=riseFall, amp=a) Id(controlQ) measConcurrently(cNt) # Sequence 2 for a in amps: init(cNt) X(controlQ) echoCR(controlQ, targetQ, length=length, phase=phase, riseFall=riseFall, amp=a) X(controlQ) measConcurrently(cNt) # Then do calRepeats calibration sequences create_cal_seqs(cNt, calRepeats)
def EchoCRPhase(controlQ: qreg, targetQ: qreg, phases, riseFall=40e-9, amp=1, length=100e-9, calRepeats=2, canc_amp=0, canc_phase=np.pi/2): """ Variable phase CX experiment, with echo pulse sandwiched between two CR opposite-phase pulses. Parameters ---------- controlQ : logical channel for the control qubit (LogicalChannel) targetQ : logical channel for the cross-resonance pulse (LogicalChannel) phases : pulse phases of the CR pulse to sweep over (iterable) riseFall : rise/fall time of the CR pulse (s) amp : amplitude of the CR pulse length : duration of each of the two flat parts of the CR pulse (s) calRepeats : number of repetitions of readout calibrations for each 2-qubit state """ # Original: # seqs = [[Id(controlQ)] + echoCR(controlQ, targetQ, length=length, phase=ph, riseFall=riseFall) + [X90(targetQ)*Id(controlQ), MEAS(targetQ)*MEAS(controlQ)] \ # for ph in phases]+[[X(controlQ)] + echoCR(controlQ, targetQ, length=length, phase= ph, riseFall = riseFall) + [X90(targetQ)*X(controlQ), MEAS(targetQ)*MEAS(controlQ)] \ # for ph in phases]+create_cal_seqs((targetQ,controlQ), calRepeats, measChans=(targetQ,controlQ)) cNt = QRegister(controlQ, targetQ) # Sequence 1 for ph in phases: init(cNt) Id(controlQ) echoCR(controlQ, targetQ, length=length, phase=ph, riseFall=riseFall, canc_amp=canc_amp, canc_phase=canc_phase) Barrier(cNt) X90(targetQ) Id(controlQ) measConcurrently(cNt) # Sequence 2 for ph in phases: init(cNt) X(controlQ) echoCR(controlQ, targetQ, length=length, phase=ph, riseFall=riseFall, canc_amp=canc_amp, canc_phase=canc_phase) Barrier(cNt) X90(targetQ) X(controlQ) measConcurrently(cNt) # Then do calRepeats calibration sequences create_cal_seqs(cNt, calRepeats)
def t3(): """ Correct result is X(q1) """ q1 = QRegister('q1') a = 1 for i in range(5): a += 1 if a == 6: X(q1) else: Y(q1) print('T3 a = %d' % a)
def TwoQubitRB(q1: qreg, q2: qreg, seqs, add_cals=True): """ Two qubit randomized benchmarking using 90 and 180 single qubit generators and ZX90 Parameters ---------- q1,q2 : logical channels to implement sequence (LogicalChannel) seqs : list of lists of Clifford group integers """ # Original: # seqsBis = [] # for seq in seqs: # seqsBis.append(reduce(operator.add, [clifford_seq(c, q1, q2) for c in seq])) # # Add the measurement to all sequences # for seq in seqsBis: # seq.append(MEAS(q1, q2)) # # Tack on the calibration sequences # if add_cals: # seqsBis += create_cal_seqs((q1,q2), 2) # axis_descriptor = [{ # 'name': 'length', # 'unit': None, # 'points': list(map(len, seqs)), # 'partition': 1 # }] # metafile = compile_to_hardware(seqsBis, 'RB/RB', axis_descriptor = axis_descriptor, suffix = suffix, extra_meta = {'sequences':seqs}) bothQs = QRegister(q1, q2) for seq in seqs: init(bothQs) for c in seq: clifford_seq(c, q2, q1) measConcurrently(bothQs) # Tack on the calibration sequences if add_cals: create_cal_seqs((q1, q2), 2)
def EchoCRLen(controlQ: qreg, targetQ: qreg, lengths, riseFall=40e-9, amp=1, phase=0, calRepeats=2, canc_amp=0, canc_phase=np.pi/2): """ Variable length CX experiment, with echo pulse sandwiched between two CR opposite-phase pulses. Parameters ---------- controlQ : logical channel for the control qubit (LogicalChannel) targetQ: logical channel for the target qubit (LogicalChannel) lengths : pulse lengths of the CR pulse to sweep over (iterable) riseFall : rise/fall time of the CR pulse (s) amp : amplitude of the CR pulse phase : phase of the CR pulse (rad) calRepeats : number of repetitions of readout calibrations for each 2-qubit state """ # Original: # seqs = [[Id(controlQ)] + echoCR(controlQ, targetQ, length=l, phase=phase, riseFall=riseFall) + [Id(controlQ), MEAS(targetQ)*MEAS(controlQ)] \ # for l in lengths]+ [[X(controlQ)] + echoCR(controlQ, targetQ, length=l, phase= phase, riseFall=riseFall) + [X(controlQ), MEAS(targetQ)*MEAS(controlQ)] \ # for l in lengths] + create_cal_seqs((targetQ,controlQ), calRepeats, measChans=(targetQ,controlQ)) cNt = QRegister(controlQ, targetQ) # Sequence1: for l in lengths: init(cNt) Id(controlQ) echoCR(controlQ, targetQ, length=l, phase=phase, amp=amp, riseFall=riseFall, canc_amp=canc_amp, canc_phase=canc_phase) Id(controlQ) measConcurrently(cNt) # Sequence 2 for l in lengths: init(cNt) X(controlQ) echoCR(controlQ, targetQ, length=l, phase=phase, amp=amp, riseFall=riseFall, canc_amp=canc_amp, canc_phase=canc_phase) X(controlQ) measConcurrently(cNt) # Then do calRepeats calibration sequences create_cal_seqs(cNt, calRepeats)