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 qgl2_compile_to_hardware(seqs, filename, suffix=''): ''' Custom compile_to_hardware for QGL2 ''' from QGL.Compiler import compile_to_hardware from QGL.Scheduler import schedule scheduled_seq = schedule(seqs) return compile_to_hardware([scheduled_seq], filename, suffix)
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 qgl2_compile_to_hardware(seqs, filename, suffix='', axis_descriptor=None, extra_meta=None, tdm_seq=False): ''' Custom compile_to_hardware for QGL2 ''' from QGL.Compiler import compile_to_hardware from QGL.Scheduler import schedule scheduled_seq = schedule(seqs) return compile_to_hardware([scheduled_seq], filename, suffix=suffix, axis_descriptor=axis_descriptor, extra_meta=extra_meta, tdm_seq=tdm_seq)
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 # This tries to produce graphics to display 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") # Axis Descriptor generator functions here # This is ugly; they're method dependent, but I can't do them in the QGL2 itself # Additionally, each uses values from the args to the function # So here we make those arguments be constants so we can use them twice # without rewriting the values hahnSpacings = np.linspace(0, 5e-6, 11) tCalR = 2 # calRepeats cpmgNumPulses = [0, 2, 4, 6] cpmgSpacing = 500e-9 def getHahnAxisDesc(pulseSpacings, calRepeats): return [ delay_descriptor(2 * pulseSpacings), cal_descriptor(('qubit', ), calRepeats) ] def getCPMGAxisDesc(pulseSpacing, numPulses, calRepeats): return [ # NOTE: numPulses is not a numpy array, so cannot multiply by a float # But thankfully, np.array(np.array) = np.array so this is always a good move here. delay_descriptor(pulseSpacing * np.array(numPulses)), cal_descriptor(('qubit', ), calRepeats) ] # FIXME: See issue #44: Must supply all args to qgl2main for now # for func, args, label, axisDesc in [("HahnEcho", (q1, hahnSpacings), "Echo", getHahnAxisDesc(hahnSpacings, tCalR)), # ("CPMG", (q1, cpmgNumPulses, cpmgSpacing), "CPMG", getCPMGAxisDesc(cpmgSpacing, cpmgNumPulses, tCalR)), # ]: for func, args, label, axisDesc in [ ("HahnEcho", (q1, hahnSpacings, 0, tCalR), "Echo", getHahnAxisDesc(hahnSpacings, tCalR)), ("CPMG", (q1, cpmgNumPulses, cpmgSpacing, tCalR), "CPMG", getCPMGAxisDesc(cpmgSpacing, cpmgNumPulses, tCalR)), ]: 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, filename=f'{label}/{label}', axis_descriptor=axisDesc) 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 main(): from pyqgl2.qreg import QRegister import pyqgl2.test_cl from pyqgl2.main import compile_function, qgl2_compile_to_hardware 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") q2 = QRegister("q2") # Axis Descriptor generator functions here # This is ugly; they're method dependent, but I can't do them in the QGL2 itself # Additionally, each uses values from the args to the function # So here we make those arguments be constants so we can use them twice # without rewriting the values pirlengths = np.linspace(0, 4e-6, 11) # Lengths arg to PiRabi eclLengths = np.linspace(0, 2e-6, 11) # Lengths arg to EchoCRLen trisefall = 40e-9 # riseFall arg for many tamp = 1 # amp arg for many t2amp = 0.8 # amp arg for CRTomo tphase = 0 # phase arg for many tcalr = 2 # calRepeats arg for many ecpPhases = np.linspace(0, np.pi/2, 11) # phases arg for EchoCRPhase ecaAmps = np.linspace(0, 5e-6, 11) # amps arg for echoCRAmp crtLengths = np.linspace(0, 2e-6, 11) # lengths arg for CRtomo_seq def getPRAxisDesc(lengths, calRepeats): return [ delay_descriptor(np.concatenate((lengths, lengths))), # Hard code there are 2 qubits cal_descriptor(('c', 't'), calRepeats) ] def getECLAxisDesc(lengths, calRepeats): return [ delay_descriptor(np.concatenate((lengths, lengths))), # Hard code there are 2 qubits cal_descriptor(('controlQ', 'targetQ'), calRepeats) ] def getECPAxisDesc(phases, calRepeats): return [ { 'name': 'phase', 'unit': 'radians', 'points': list(phases)+list(phases), 'partition': 1 }, cal_descriptor(('controlQ', 'targetQ'), calRepeats) ] def getECAAxisDesc(amps, calRepeats): return [ { 'name': 'amplitude', 'unit': None, 'points': list(amps)+list(amps), 'partition': 1 }, cal_descriptor(('controlQ', 'targetQ'), calRepeats) ] def getCRtAxisDesc(lengths): return [ delay_descriptor(np.concatenate((np.repeat(lengths,3), np.repeat(lengths,3)))), cal_descriptor(('targetQ',), 2) ] # FIXME: See issue #44: Must supply all args to qgl2main for now # for func, args, label, axisDesc in [("PiRabi", (q1, q2, pirlengths), "PiRabi", getPRAxisDesc(pirlengths, tcalr)), # ("EchoCRLen", (q1, q2, np.linspace(0, 2e-6, 11)), "EchoCR", getECLAxisDesc(eclLengths, tcalr)), # ("EchoCRPhase", (q1, q2, np.linspace(0, np.pi/2, 11)), "EchoCR", getECPAxisDesc(ecpPhases, tcalr)), # ("EchoCRAmp", (q1, q2, np.linspace(0, 5e-6, 11)), "EchoCR", getECAAxisDesc(ecaAmps, tcalr)), # FIXME: Right values? # ("CRtomo_seq", (q1, q2, np.linspace(0, 2e-6, 11), 0), "CR", getCRtAxisDesc(crtLengths)) # FIXME: Right values? # ]: for func, args, label, axisDesc in [("PiRabi", (q1, q2, pirlengths, trisefall,tamp,tphase,tcalr), "PiRabi", getPRAxisDesc(pirlengths, tcalr)), ("EchoCRLen", (q1, q2, eclLengths, trisefall, tamp, tphase, tcalr, 0, np.pi/2), "EchoCR", getECLAxisDesc(eclLengths, tcalr)), ("EchoCRPhase", (q1, q2, ecpPhases, trisefall,tamp,100e-9,tcalr,0,np.pi/2), "EchoCR", getECPAxisDesc(ecpPhases, tcalr)), ("EchoCRAmp", (q1, q2, ecaAmps, trisefall,50e-9,tphase,tcalr), "EchoCR", getECAAxisDesc(ecaAmps, tcalr)), # FIXME: Right values? ("CRtomo_seq", (q1, q2, crtLengths, 0, t2amp,20e-9), "CR", getCRtAxisDesc(crtLengths)) # FIXME: Right values? ]: 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, filename=f'{label}/{label}', axis_descriptor=axisDesc) 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 main(): from pyqgl2.qreg import QRegister import pyqgl2.test_cl from pyqgl2.main import compile_function, qgl2_compile_to_hardware toHW = True plotPulses = False # Don't try creating graphics objects suffix = False # change generated filename to include qbit name 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 qbitName = "q1" q1 = QRegister(qbitName) # FIXME: See issue #44: Must supply all args to qgl2main for now # InversionRecovery(q1, np.linspace(0, 5e-6, 11)) # Ramsey(q1, np.linspace(0, 5e-6, 11)) irDelays = np.linspace(0, 5e-6, 11) rSpacings = np.linspace(0, 5e-6, 11) tCalR = 2 def irAD(delays, calRepeats): return [ delay_descriptor(delays), cal_descriptor(('qubit',), calRepeats) ] def rAD(pulseSpacings, calRepeats): return [ delay_descriptor(pulseSpacings), cal_descriptor(('qubit',), calRepeats) ] # for func, args, label, axisDesc in [("InversionRecovery", (q1, irDelays), "T1", irAD(irDelays, tCalR)), # ("Ramsey", (q1, rSpacings), "Ramsey", rAD(rSpacings, tCalR)) # ]: for func, args, label, axisDesc in [("InversionRecovery", (q1, irDelays, tCalR), "T1", irAD(irDelays, tCalR)), ("Ramsey", (q1, rSpacings, 0, tCalR), "Ramsey", rAD(rSpacings, tCalR)) ]: 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") # Generate proper filenames; for these, it isn't just the label Ramsey # T1T2 QGL functions take a suffix boolean default false. If true, then append to label "_qubit.label"; ie "_q1" if suffix: label = label + f"_{qbitName}" fileNames = qgl2_compile_to_hardware(seq, filename=f'{label}/{label}', axis_descriptor=axisDesc) 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 main(): from pyqgl2.qreg import QRegister import pyqgl2.test_cl from pyqgl2.main import compile_function, qgl2_compile_to_hardware import numpy as np import QGL.PulseShapes 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") q2 = QRegister("q2") qr = QRegister(q1, q2) rAmpAmps = np.linspace(0, 1, 1) rWidthWidths = np.linspace(0, 5e-6, 11) ranqAmps = np.linspace(0, 5e-6, 11) tCalR = 2 rAmpPiAmps = np.linspace(0, 1, 11) def getRAmpAD(amps): return [{ 'name': 'amplitude', 'unit': None, 'points': list(amps), 'partition': 1 }] def getRWidthAD(widths): return [delay_descriptor(widths)] def getRAmpNQAD(qubits, amps, calRepeats): return [{ 'name': 'amplitude', 'unit': None, 'points': list(amps), 'partition': 1 }, cal_descriptor(qubits, calRepeats)] def getRAmpPiAD(amps): return [{ 'name': 'amplitude', 'unit': None, 'points': list(amps), 'partition': 1 }] # FIXME: See issue #44: Must supply all args to qgl2main for now # for func, args, label, axisDec in [("RabiAmp", (q1, rAmpAmps), "Rabi", getRAmpAD(rAmpAmps)), # ("RabiWidth", (q1, rWidthWidths), "Rabi", getRWidthAD(rWidthWidths)), # ("RabiAmpPi", (q1, q2, rAmpPiAmps), "Rabi", getRAmpPiAD(rAmpPiAmps)), # ("SingleShow", (q1,), "SingleShot", None), # ("PulsedSpec", (q1,), "Spec", None), # ("RabiAmp_NQubits", (qr,ranqAmps), "Rabi", getRAmpNQAD(qr, ranqAmps, tCalR)), # ("Swap", (q1, np.linspace(0, 5e-6, 11), "Swap", None), # ]: for func, args, label, axisDesc in [ ("RabiAmp", (q1, rAmpAmps, 0), "Rabi", getRAmpAD(rAmpAmps)), ("RabiWidth", (q1, rWidthWidths, 1, 0, QGL.PulseShapes.tanh), "Rabi", getRWidthAD(rWidthWidths)), ("RabiAmpPi", (q1, q2, rAmpPiAmps, 0), "Rabi", getRAmpPiAD(rAmpPiAmps)), ("SingleShot", (q1, ), "SingleShot", None), ("PulsedSpec", (q1, True), "Spec", None), ("RabiAmp_NQubits", (qr, ranqAmps, 0, qr, False, tCalR), "Rabi", getRAmpNQAD(qr, ranqAmps, tCalR)), ("Swap", (q1, np.linspace(0, 5e-6, 11), q2), "Swap", None) ]: 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") # To get verbose logging including showing the compiled sequences: # QGL.Compiler.set_log_level() fileNames = qgl2_compile_to_hardware(seq, filename=f'{label}/{label}', axis_descriptor=axisDesc) 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 main(): from pyqgl2.qreg import QRegister import pyqgl2.test_cl from pyqgl2.main import compile_function, qgl2_compile_to_hardware import numpy as np import random 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") q2 = QRegister("q2") qr = QRegister(q1, q2) # FIXME: See issue #44: Must supply all args to qgl2main for now # Functions here have some extra code to run before running the compiled QGL2, # so define functions for those; random number seeding def beforeSingleRB(): np.random.seed(20152606) # set seed for create_RB_seqs() random.seed(20152606) # set seed for random.choice() # SingleQubitRB(q1, create_RB_seqs(1, 2**np.arange(1,7))) # The original unit test had this comment: """ Fails on APS1, APS2, and Tek7000 due to: File "QGL/PatternUtils.py", line 129, in add_gate_pulses if has_gate(chan) and not pulse.isZero and not (chan.gate_chan AttributeError: 'CompositePulse' object has no attribute 'isZero' """ def beforeTwoRB(): np.random.seed(20152606) # set seed for create_RB_seqs() # TwoQubitRB(q2, q1, create_RB_seqs(2, [2, 4, 8, 16, 32], repeats=16)) def beforeSimRBAC(): np.random.seed(20151709) # set seed for create_RB_seqs #seqs1 = create_RB_seqs(1, 2**np.arange(1,7)) #seqs2 = create_RB_seqs(1, 2**np.arange(1,7)) # SimultaneousRB_AC((q1, q2), (seqs1, seqs2)) def beforeSingleRBAC(): np.random.seed(20152606) # set seed for create_RB_seqs # SingleQubitRB_AC(q1,create_RB_seqs(1, 2**np.arange(1,7))) # FIXME: Add test of SingleQubitRB_DiAC sqCSeqs = create_RB_seqs(1, 2**np.arange(1,7)) tqCSeqs = create_RB_seqs(2, [2, 4, 8, 16, 32], repeats=16) simCSeqs = (sqCSeqs, sqCSeqs) tAddCals = True def getSingleQubitRBAD(seqs, add_cals): ad = [{ 'name': 'length', 'unit': None, 'points': list(map(len, seqs)), 'partition': 1 }] if add_cals: ad.append(cal_descriptor(('qubit',), 2)) return ad def getTwoQubitRBAD(seqs, add_cals): axis_descriptor = [{ 'name': 'length', 'unit': None, 'points': list(map(len, seqs)), 'partition': 1 }] if add_cals: axis_descriptor.append(cal_descriptor(('q1', 'q2'), 2)) return axis_descriptor def getSingleQubitRBAC_AD(seqs, add_cals): axis_descriptor = [{ 'name': 'length', 'unit': None, 'points': list(map(len, seqs)), 'partition': 1 }] if add_cals: axis_descriptor.append(cal_descriptor(('qubit',), 2)) return axis_descriptor def getSimRBACAD(seqs, add_cals, qubits): axis_descriptor = [{ 'name': 'length', 'unit': None, 'points': list(map(len, seqs)), 'partition': 1 }] if add_cals: axis_descriptor.append(cal_descriptor((qubits), 2)) return axis_descriptor # FIXME: SingleQubitIRB_AC filenames are more complex # FIXME: SingleQubitRBT has complex suffix it should pass to compile_to_hardware # for func, args, label, beforeFunc, axisDesc, cseqs in [("SingleQubitRB", (q1, sqCSeqs), "RB", beforeSingleRB, getSingleQubitRBAD(sqCSeqs, tAddCals), sqCSeqs), # ("TwoQubitRB", (q1, q2, tqCSeqs), "RB", beforeTwoRB, getTwoQubitRBAD(tqCSeqs, tAddCals), tqCSeqs), # ("SingleQubitRB_AC", (q1,sqCSeqs), "RB", beforeSingleRBAC, getSingleQubitRBAC_AD(sqCSeqs, tAddCals), sqCSeqs), # ("SimultaneousRB_AC", (qr, simCSeqs), "RB", beforeSimRBAC, getSimRBACAD(simCSeqs, tAddCals, qr), simCSeqs), # ("SingleQubitIRB_AC", (q1,''), "RB", None, None, None), # Comment says this next one relies on a specific file, so don't bother running # ("SingleQubitRBT", (q1,'', fixmePulse), "RBT", None, None, None), # ]: for func, args, label, beforeFunc, axisDesc, cseqs in [("SingleQubitRB", (q1, sqCSeqs, False, tAddCals), "RB", beforeSingleRB, getSingleQubitRBAD(sqCSeqs, tAddCals), sqCSeqs), ("TwoQubitRB", (q1, q2, tqCSeqs, tAddCals), "RB", beforeTwoRB, getTwoQubitRBAD(tqCSeqs, tAddCals), tqCSeqs), ("SingleQubitRB_AC", (q1,sqCSeqs, False, tAddCals), "RB", beforeSingleRBAC, getSingleQubitRBAC_AD(sqCSeqs, tAddCals), sqCSeqs), # Warning: This next one is slow.... ("SimultaneousRB_AC", (qr, simCSeqs, tAddCals), "RB", beforeSimRBAC, getSimRBACAD(simCSeqs, tAddCals, qr), simCSeqs), # This next one relies on a file of sequence strings, which I don't have # ("SingleQubitIRB_AC", (q1,None), "RB", None, None, None), # Comment says this next one relies on a specific file, so don't bother running # # ("SingleQubitRBT", (q1,'', fixmePulse, True), "RBT", None, None, None), ]: print(f"\nRun {func}...") # This is typically setting random seed if beforeFunc is not None: beforeFunc() # 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: import QGL print(f"Compiling {func} sequences to hardware\n") # QGL.Compiler.set_log_level() em = None if cseqs: em = {'sequences':cseqs} fileNames = qgl2_compile_to_hardware(seq, filename=f'{label}/{label}', axis_descriptor=axisDesc, extra_meta = em) 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))
sequences = resFunction() # In verbose mode, turn on DEBUG python logging for the QGL Compiler if opts.verbose: import logging from QGL.Compiler import set_log_level # Note this acts on QGL.Compiler at DEBUG by default # Could specify other levels, loggers set_log_level() # Now we have a QGL1 list of sequences we can act on if opts.tohw: print("Compiling sequences to hardware\n") fileNames = qgl2_compile_to_hardware(sequences, opts.prefix, opts.suffix) print(fileNames) if opts.showplot: 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)) if opts.verbose: print("Memory usage: {} MB".format(process.memory_info().rss // (1 << 20)))