def test_anotherMulti2(self): q1 = QubitFactory('q1') q2 = QubitFactory('q2') q3 = QubitFactory('q3') #q1: Id, X, MEAS, <barrier>, Y, <barrier> # q2: Id, X, MEAS, <barrier> ?Id? # q3: <barrier>, Y, <barrier> expected = [ Id(q1), Id(q2), X(q1), X(q2), Barrier(q1, q2, q3), MEAS(q1), MEAS(q2), Barrier(q1, q2, q3), Y(q1), Y(q3) ] resFunction = compile_function("test/code/multi.py", "anotherMulti2") seqs = resFunction() seqs = testable_sequence(seqs) assertPulseSequenceEqual(self, seqs, expected) resFunction = compile_function("test/code/multi.py", "anotherMulti3") seqs = resFunction() seqs = testable_sequence(seqs) assertPulseSequenceEqual(self, seqs, expected)
def test_RabiAmpPi(self): q1 = QubitFactory('q1') q2 = QubitFactory('q2') qr1 = QRegister(q1) qr2 = QRegister(q2) amps = np.linspace(0, 1, 11) phase = 0 resFunction = compile_function( "src/python/qgl2/basic_sequences/Rabi.py", "RabiAmpPi", (qr1, qr2, amps, phase)) seqs = resFunction() seqs = testable_sequence(seqs) expectedseq = [] for amp in amps: expectedseq += [ qwait(channels=(q1, q2)), X(q2), Utheta(q1, amp=amp, phase=phase), X(q2), MEAS(q2) ] assertPulseSequenceEqual(self, seqs, expectedseq)
def test_SPAM(self): q = QubitFactory('q1') qr = QRegister('q1') angleSweep = np.linspace(0, pi / 2, 11) maxSpamBlocks = 10 expectedseq = [] def spam_seqs(angle, q, maxSpamBlocks): thisseq = [] for rep in range(maxSpamBlocks): thisseq += [qwait(channels=(q, )), Y90(q)] innerseq = [] for _ in range(rep): innerseq += [ X(q), U(q, phase=pi / 2 + angle), X(q), U(q, phase=pi / 2 + angle) ] thisseq += innerseq thisseq += [X90(q), MEAS(q)] return thisseq for angle in angleSweep: expectedseq += [qwait(channels=(q, )), Id(q), MEAS(q)] expectedseq += spam_seqs(angle, q, maxSpamBlocks) expectedseq += [qwait(channels=(q, )), X(q), MEAS(q)] resFunction = compile_function( "src/python/qgl2/basic_sequences/SPAM.py", "SPAM", (qr, angleSweep, maxSpamBlocks)) seqs = resFunction() seqs = testable_sequence(seqs) assertPulseSequenceEqual(self, seqs, expectedseq)
def test_Ramsey(self): q = QubitFactory('q1') qr = QRegister('q1') delays = np.arange(100e-9, 10e-6, 100e-9) TPPIFreq = 1e6 calRepeats = 2 expectedseq = [] # Create the phases for the TPPI phases = 2 * pi * TPPIFreq * delays # Create the basic Ramsey sequence for d, phase in zip(delays, phases): expectedseq += [ qwait(channels=(q, )), X90(q), Id(q, d), U90(q, phase=phase), MEAS(q) ] # Add calibration cal = get_cal_seqs_1qubit(q, calRepeats) expectedseq += cal expectedseq = testable_sequence(expectedseq) resFunction = compile_function( "src/python/qgl2/basic_sequences/T1T2.py", "Ramsey", (qr, delays, TPPIFreq, calRepeats)) seqs = resFunction() seqs = testable_sequence(seqs) assertPulseSequenceEqual(self, seqs, expectedseq)
def test_FlipFlop(self): qubit = QubitFactory('q1') qr = QRegister('q1') dragParamSweep = np.linspace(0, 1, 11) maxNumFFs = 10 def addFFSeqs(dragParam, maxNumFFs, qubit): ffs = [] for rep in range(maxNumFFs): ffs += [ qwait(channels=(qubit, )), X90(qubit, dragScaling=dragParam) ] for _ in range(rep): ffs += [ X90(qubit, dragScaling=dragParam), X90m(qubit, dragScaling=dragParam) ] ffs += [Y90(qubit, dragScaling=dragParam), MEAS(qubit)] return ffs expectedseq = [] for dragParam in dragParamSweep: expectedseq += [qwait(channels=(qubit, )), Id(qubit), MEAS(qubit)] expectedseq += addFFSeqs(dragParam, maxNumFFs, qubit) expectedseq += [qwait(channels=(qubit, )), X(qubit), MEAS(qubit)] resFunction = compile_function( "src/python/qgl2/basic_sequences/FlipFlop.py", "FlipFlop", (qr, dragParamSweep, maxNumFFs)) seqs = resFunction() seqs = testable_sequence(seqs) assertPulseSequenceEqual(self, seqs, expectedseq)
def test_HahnEcho(self): q = QubitFactory('q1') qr = QRegister('q1') steps = 11 pulseSpacings = np.linspace(0, 5e-6, steps) periods = 0 calRepeats = 2 expectedseq = [] for k in range(len(pulseSpacings)): expectedseq += [ qwait(channels=(q, )), X90(q), Id(q, pulseSpacings[k]), Y(q), Id(q, pulseSpacings[k]), U90(q, phase=2 * pi * periods / len(pulseSpacings) * k), MEAS(q) ] # Add calibration cal = get_cal_seqs_1qubit(q, calRepeats) expectedseq += cal expectedseq = testable_sequence(expectedseq) resFunction = compile_function( "src/python/qgl2/basic_sequences/Decoupling.py", "HahnEcho", (qr, pulseSpacings, periods, calRepeats)) seqs = resFunction() seqs = testable_sequence(seqs) # import ipdb; ipdb.set_trace() assertPulseSequenceEqual(self, seqs, expectedseq)
def test_tomo(self): resFunction = compile_function("test/code/tomo.py", "main") seqs = resFunction() expectedseq = self.tomo_result() assertPulseSequenceEqual(self, seqs, expectedseq)
def RabiWidth(qubit, widths, amp=1, phase=0, shapeFun=QGL.PulseShapes.tanh, showPlot=False): """ Variable pulse width Rabi nutation experiment. Parameters ---------- qubit : logical channel to implement sequence (LogicalChannel) widths : pulse widths to sweep over (iterable) phase : phase of the pulse (radians, default = 0) shapeFun : shape of pulse (function, default = PulseShapes.tanh) showPlot : whether to plot (boolean) """ resFunction = compile_function( os.path.relpath(__file__), "doRabiWidth" (qubit, widths, amp, phase, shapeFun) ) seqs = resFunction() return seqs fileNames = qgl2_compile_to_hardware(seqs, "Rabi/Rabi") print(fileNames) if showPlot: plot_pulse_files(fileNames)
def RabiAmp_NQubitsq1(qubits, amps, phase=0, showPlot=False, measChans=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) showPlot : whether to plot (boolean) measChans : tuble of qubits to be measured (LogicalChannel) docals, calRepeats: enable calibration sequences, repeated calRepeats times """ if measChans is None: measChans = qubits resFunction = compile_function( os.path.relpath(__file__), "doRabiWidth", (qubits, amps, phase, measChans, docals, calRepeats) ) seqs = resFunction() return seqs fileNames = qgl2_compile_to_hardware(seqs, "Rabi/Rabi") print(fileNames) if showPlot: plot_pulse_files(fileNames)
def test_Swap(self): q = QubitFactory('q1') mq = QubitFactory('q2') qr = QRegister(q) mqr = QRegister(mq) delays = np.linspace(0, 5e-6, 11) expectedseq = [] for d in delays: expectedseq += [ qwait(channels=(q, mq)), X(q), X(mq), Id(mq, length=d), Barrier(q, mq), MEAS(q), MEAS(mq) ] # Add calibration cal_seqs = get_cal_seqs_2qubits(q, mq, 2) expectedseq += cal_seqs expectedseq = testable_sequence(expectedseq) resFunction = compile_function( "src/python/qgl2/basic_sequences/Rabi.py", "Swap", (qr, delays, mqr)) seqs = resFunction() seqs = testable_sequence(seqs) assertPulseSequenceEqual(self, seqs, expectedseq)
def test_RabiAmp_NQubits(self): q1 = QubitFactory('q1') q2 = QubitFactory('q2') qr = QRegister(q1, q2) amps = np.linspace(0, 5e-6, 11) p = 0 docals = False calRepeats = 2 expectedseq = [] for a in amps: expectedseq += [ qwait(channels=(q1, q2)), Utheta(q1, amp=a, phase=p), Utheta(q2, amp=a, phase=p), Barrier(q1, q2), MEAS(q1), MEAS(q2) ] if docals: # Add calibration cal_seqs = get_cal_seqs_2qubits(q1, q2, calRepeats) expectedseq += cal_seqs expectedseq = testable_sequence(expectedseq) resFunction = compile_function( "src/python/qgl2/basic_sequences/Rabi.py", "RabiAmp_NQubits", (qr, amps, p, None, docals, calRepeats)) seqs = resFunction() seqs = testable_sequence(seqs) assertPulseSequenceEqual(self, seqs, expectedseq)
def test_reset4(self): resFunction = compile_function("test/code/reset.py", "reset4") seqs = resFunction() expectedseq = self.reset_result(CmpGt, 1) expectedseq = match_labels(expectedseq, seqs) assertPulseSequenceEqual(self, seqs, expectedseq)
def test_90_3(self): q1 = QubitFactory('q1') resFunction = compile_function('test/code/bugs/90.py', 't3') seqs = resFunction() seqs = testable_sequence(seqs) expected_seq = [ X(q1) ] assertPulseSequenceEqual(self, seqs, expected_seq)
def test_doSimple(self): q2 = QubitFactory('q2') expected = [X(q2), MEAS(q2)] resFunction = compile_function("test/code/multi.py", "doSimple") seqs = resFunction() seqs = testable_sequence(seqs) assertPulseSequenceEqual(self, seqs, expected)
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 = False 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 QRegister(s) NOT real Qubits q1 = QRegister("q1") # FIXME: See issue #44: Must supply all args to qgl2main for now # for func, args, label in [("HahnEcho", (q1, np.linspace(0, 5e-6, 11)), "HahnEcho"), # ("CPMG", (q1, [0, 2, 4, 5], 500e-9), "CPMG"), # ]: for func, args, label in [ ("HahnEcho", (q1, np.linspace(0, 5e-6, 11), 0, 2), "HahnEcho"), ("CPMG", (q1, [0, 2, 4, 6], 500e-9, 2), "CPMG"), ]: print(f"\nRun {func}...") # 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. resFunc = compile_function(__file__, func, args) # Run the QGL2. Note that the generated function takes no arguments itself seq = resFunc() if toHW: print(f"Compiling {func} sequences to hardware\n") fileNames = qgl2_compile_to_hardware(seq, f'{label}/{label}') 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(f"\nGenerated {func} sequences:\n") from QGL.Scheduler import schedule scheduled_seq = schedule(seq) from IPython.lib.pretty import pretty print(pretty(scheduled_seq))
def test_syn_0(self): """ This is just a basic test to see whether the preprocessor accepts the simple syndrome code """ resFunction = compile_function('test/code/syndrome/syndrome.py', 'main') self.assertTrue(resFunction)
def test_PiRabi(self): controlQ = QubitFactory('q1') targetQ = QubitFactory('q2') controlQR = QRegister('q1') targetQR = QRegister('q2') qr = QRegister('q1', 'q2') edge = EdgeFactory(controlQ, targetQ) lengths = np.linspace(0, 4e-6, 11) riseFall = 40e-9 amp = 1 phase = 0 calRepeats = 2 expected_seq = [] # Seq1 for l in lengths: expected_seq += [ qwait(channels=(controlQ, targetQ)), Id(controlQ), flat_top_gaussian(edge, riseFall, length=l, amp=amp, phase=phase), Barrier(controlQ, targetQ), MEAS(controlQ), MEAS(targetQ) ] # Seq2 for l in lengths: expected_seq += [ qwait(channels=(controlQ, targetQ)), X(controlQ), flat_top_gaussian(edge, riseFall, length=l, amp=amp, phase=phase), X(controlQ), Barrier(controlQ, targetQ), MEAS(controlQ), MEAS(targetQ) ] # Add calibration calseq = get_cal_seqs_2qubits(controlQ, targetQ, calRepeats) expected_seq += calseq expected_seq = testable_sequence(expected_seq) resFunction = compile_function( "src/python/qgl2/basic_sequences/CR.py", "PiRabi", (controlQR, targetQR, lengths, riseFall, amp, phase, calRepeats)) seqs = resFunction() seqs = testable_sequence(seqs) self.maxDiff = None assertPulseSequenceEqual(self, seqs, expected_seq)
def test_scope2(self): resFunction = compile_function("test/code/scope.py", "C") seqs = resFunction() q1 = QubitFactory('q1') expectedseq = [Xtheta(q1, amp=1), Ytheta(q1, amp=0)] assertPulseSequenceEqual(self, seqs, expectedseq)
def test_84_1(self): q1 = QubitFactory('q1') resFunction = compile_function('test/code/bugs/84.py', 't1') seqs = resFunction() seqs = testable_sequence(seqs) expected_seq = [ X(q1) ] # print('\n'.join([str(x) for x in seqs])) assertPulseSequenceEqual(self, seqs, expected_seq)
def test_main2_tuple(self): q1 = QubitFactory('q1') amps = [1, 2, 3, 4, 5] expectedseq = [Utheta(q1, amp=a, phase=0.5) for a in amps] # tuple input for toplevel_bindings resFunction = compile_function("test/code/toplevel_binding.py", "main2", (amps, 0.5)) seqs = resFunction() self.assertEqual(seqs, expectedseq)
def test_main1_tuple_arange(self): q1 = QubitFactory('q1') amps = np.arange(5) expectedseq = [Xtheta(q1, amp=a) for a in amps] # tuple input for toplevel_bindings resFunction = compile_function("test/code/toplevel_binding.py", "main1", (amps, )) seqs = resFunction() self.assertEqual(seqs, expectedseq)
def test_main1_dict(self): q1 = QubitFactory('q1') amps = [1, 2, 3, 4, 5] expectedseq = [Xtheta(q1, amp=a) for a in amps] # dictionary input for toplevel_bindings resFunction = compile_function("test/code/toplevel_binding.py", "main1", {"amps": amps}) seqs = resFunction() self.assertEqual(seqs, expectedseq)
def test_edgeTest(self): q1 = QubitFactory('q1') q2 = QubitFactory('q2') expected = [qwait(channels=(q1, q2)), X(q1), X(q2), echoCR(q1, q2)] expected = testable_sequence(expected) resFunction = compile_function("test/code/edge.py", "edgeTest") seqs = resFunction() seqs = testable_sequence(seqs) assertPulseSequenceEqual(self, seqs, expected)
def test_cnotcrTest(self): q1 = QubitFactory('q1') q2 = QubitFactory('q2') expected = [qwait(channels=(q1, q2)), CNOT(q1, q2)] expected = testable_sequence(expected) resFunction = compile_function("test/code/edge.py", "cnotcrTest") seqs = resFunction() seqs = testable_sequence(seqs) self.maxDiff = None assertPulseSequenceEqual(self, seqs, expected)
def test_PulsedSpec(self): q1 = QubitFactory('q1') qr = QRegister(q1) resFunction = compile_function( "src/python/qgl2/basic_sequences/Rabi.py", "PulsedSpec", (qr, True)) seqs = resFunction() seqs = testable_sequence(seqs) expectedseq = [qwait(channels=(q1, )), X(q1), MEAS(q1)] assertPulseSequenceEqual(self, seqs, expectedseq)
def test_SingleQubitRB(self): q1 = QubitFactory('q1') qr = QRegister(q1) np.random.seed(20152606) # set seed for create_RB_seqs() random.seed(20152606) # set seed for random.choice() # Range below should be 1,7 but that takes too long; use 1,2 so it's quick rbseqs = create_RB_seqs(1, 2**np.arange(1, 2)) purity = True add_cals = True # Try copying in the basic QGL1 code # Can't do it directly since that code doesn't return the # sequence # This isn't quite right; this is before adding the Waits for example expectedseq = [] def testSingleQubitRB(qubit, rbseqs, purit=False, add_cal=True): from QGL.Cliffords import clifford_seq from QGL.BasicSequences.helpers import create_cal_seqs from functools import reduce import operator seqsBis = [] op = [Id(qubit, length=0), Y90m(qubit), X90(qubit)] for ct in range(3 if purit else 1): for seq in rbseqs: seqsBis.append( reduce(operator.add, [clifford_seq(c, qubit) for c in seq])) #append tomography pulse to measure purity seqsBis[-1].append(op[ct]) #append measurement seqsBis[-1].append(MEAS(qubit)) #Tack on the calibration sequences if add_cal: seqsBis += create_cal_seqs((qubit, ), 2) return seqsBis expectedseq = testSingleQubitRB(q1, rbseqs, purity, add_cals) # Must reset the seeds because QGL1 used the prior values, to ensure QGL2 gets same values np.random.seed(20152606) # set seed for create_RB_seqs() random.seed(20152606) # set seed for random.choice() resFunction = compile_function("src/python/qgl2/basic_sequences/RB.py", "SingleQubitRB", (qr, rbseqs, purity, add_cals)) seqs = resFunction() seqs = testable_sequence(seqs) # Run testable on the QGL1 to flatten the sequence of sequences expectedseq = testable_sequence(expectedseq) # Strip out the QGL2 Waits and Barriers that QGL1 doesn't have seqs = stripWaitBarrier(seqs) # self.maxDiff = None assertPulseSequenceEqual(self, seqs, expectedseq)
def test_main3b(self): # QReference input q1 = QubitFactory('q1') qr = QRegister('q1', 'q2') amps = range(5) expectedseq = [Xtheta(q1, amp=a) for a in amps] # tuple input for toplevel_bindings resFunction = compile_function("test/code/toplevel_binding.py", "main3", (qr[0], amps)) seqs = resFunction() self.assertEqual(seqs, expectedseq)
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 test_SingleQubitRB_AC(self): q1 = QubitFactory('q1') q2 = QubitFactory('q2') qr1 = QRegister(q1) qr2 = QRegister(q2) np.random.seed(20152606) # set seed for create_RB_seqs() rbseqs = create_RB_seqs(1, 2**np.arange(1, 7)) add_cals = True purity = False # Try copying in the basic QGL1 code # Can't do it directly since that code doesn't return the # sequence # This isn't quite right; this is before adding the Waits for example expectedseq = [] def testSingleQubitRB_AC(qubit, seqs, purit=False, add_cal=True): from QGL.PulsePrimitives import AC, MEAS, Id, Y90m, X90 from QGL.BasicSequences.helpers import create_cal_seqs from functools import reduce import operator seqsBis = [] op = [Id(qubit, length=0), Y90m(qubit), X90(qubit)] for ct in range(3 if purit else 1): for seq in seqs: seqsBis.append([AC(qubit, c) for c in seq]) # append tomography pulse to measure purity seqsBis[-1].append(op[ct]) # append measurement seqsBis[-1].append(MEAS(qubit)) # Tack on the calibration sequences if add_cals: seqsBis += create_cal_seqs((qubit, ), 2) return seqsBis expectedseq = testSingleQubitRB_AC(q1, rbseqs, purity, add_cals) # Must reset the seeds because QGL1 used the prior values, to ensure QGL2 gets same values np.random.seed(20152606) # set seed for create_RB_seqs() resFunction = compile_function("src/python/qgl2/basic_sequences/RB.py", "SingleQubitRB_AC", (qr1, rbseqs, purity, add_cals)) seqs = resFunction() seqs = testable_sequence(seqs) # Run testable on the QGL1 to flatten the sequence of sequences expectedseq = testable_sequence(expectedseq) # Strip out the QGL2 Waits and Barriers that QGL1 doesn't have # Note that if you want to see the real sequence, don't do this seqs = stripWaitBarrier(seqs) # self.maxDiff = None assertPulseSequenceEqual(self, seqs, expectedseq)
def test_classical_break(self): resFunction = compile_function("test/code/loops.py", "classical_break") seqs = resFunction() q1 = QubitFactory('q1') expectedseq = [ X(q1), # start of ct == 0 Y90(q1), X(q1), # start of ct == 1 X90(q1) # then break ] assertPulseSequenceEqual(self, seqs, expectedseq)