def __init__(self, connection_info, caching_allowed=True, caching_permissions={}, auto_open=True): super(QuantumMachine, self).__init__(connection_info, caching_allowed, caching_permissions, auto_open) self.connection_info = connection_info port = "" if connection_info[ "gateway_port"] and connection_info["gateway_port"] != "": port = connection_info["gateway_port"] ip = "" if connection_info[ "gateway_ip"] and connection_info["gateway_ip"] != "": ip = connection_info["gateway_ip"] if ip != "" and port != "": self.qmm = QuantumMachinesManager(host=ip, port=port) else: self.qmm = QuantumMachinesManager() self.qmObj = None self.job = None
def __init__(self): self.qmm = QuantumMachinesManager() self.qm = None self.config = None # Qubit self.qubit_freq = 1e9 self.QB_IF_freq = 80.0e6 self.QB_LO_freq = self.qubit_freq - self.QB_IF_freq # for the mixer self.saturation_pulse_len = 50000 self.pi_pulse_len = 48 self.pi_wf = pulses.gauss(0.49, 0.0, 10.0, self.pi_pulse_len) self.pi2_wf = self.pi_wf / 2 # Readout self.res_freq = 7e9 self.RR_IF_freq = 62.5e6 self.RR_LO_up_freq = self.res_freq + self.RR_IF_freq self.RR_LO_down_freq = self.res_freq - self.RR_IF_freq self.wait_sig = 160 # minimum 32 clock cycles self.smearing_sig = 0 # multiple period self.wait_ref = 53 # minimum 32 clock cycles self.smearing_ref = 0 self.readout_pulse_len = 512 # multiple of 16 self.readout_wf = pulses.const(0.49, self.readout_pulse_len) self.theta = 0.0 # rotation of IQ plane # create config and load it self.load_config()
def optimize(): # Connects to the quantum machine through the network qmManager = QuantumMachinesManager(host='132.77.48.245') # Initial guess for the best offsets offsets = [-0.10059273, 0.1322426] DC_I = offsets[0] DC_Q = offsets[1] # Initializes the instrument inst = setinstrument(7e9 - 25e6, 250e3) try: # Using fmin function to find the best offsets to minimize the leakage xopt = fmin(power, 0.2, (qmManager, inst), maxiter=10) # If there's an error trying to use the "power" function finally: print( "An error has occurred trying to find to minimum of the power function" ) inst.close() # Closes the spectrum analyzer print(str(xopt) + " ==> " + str(power(xopt, qmManager, inst))) # Print the results # inst.span(2e8) # scanfreqamp(inst, 20, True) inst.close() # Closes the instrument
def __init__(self, connection_info): self.connection_info = connection_info port = "" if self.connection_info[ "gateway_port"] is not None and self.connection_info[ "gateway_port"] != "": port = self.connection_info["gateway_port"] ip = "" if self.connection_info[ "gateway_ip"] is not None and self.connection_info[ "gateway_ip"] != "": ip = self.connection_info["gateway_ip"] if ip != "" and port != "": self.qmm = QuantumMachinesManager(host=ip, port=port) else: self.qmm = QuantumMachinesManager() self.qmObj = None self.job = None
def _connect(self) -> QuantumMachinesManager: return QuantumMachinesManager()
def optimize(): """ This function optimizes the DC offsets of the quantum controller to minimize the leakage at 7GHz :return: Prints the ideal values of the DC offsets and correction matrix variables """ # Connects to the quantum machine through the network qmManager = QuantumMachinesManager(host='132.77.48.245') # Initial guess for the best offsets # Initial guess for correction variables corvars = [0, 1] offsets = [-0.08712208, 0.02583852] DC_I = offsets[0] DC_Q = offsets[1] # correction = calc_cmat(corvars[0], corvars[1]) # Searching parameters, range of parameters for brute force, num of step in the brute force and max iteration fmin # OFFSETS nstepbruteoffset = 20 # Num of steps in the initial brute force stage(N^2) # Range to look in the inital brute force stage rangebruteoffset = [(-0.1, 0.1), (-0.1, 0.1)] maxiterfminoffset = 100 # maximum number of iteration in the fmin stage # CORRECTION VARIABLES # Num of steps in the initial brute force stage(N^2) nstepbrutecorvars = 20 # Range to look in the inital brute force stage rangebrutecorvars = [(-0.3, 0.3), (0.6, 1.3)] maxiterfmincorvars = 100 # maximum number of iteration in the fmin stage # Try to initialize the spectrum analyzer try: # Initializes the instrument inst = setinstrument(7e9, 25e5) except Exception as e: print( "An error has occurred trying to initialize the instrument.\nThe Error:\n", e) exit() try: # The program that will run on the quantum machine with program() as prog: with infinite_loop_(): play('pulse1', 'qe1') # The configuration of the quantum program, this is a dictionary, see documentation config = setconf(DC_I, DC_Q, correction) # Open quantum machine from configuration and force execute it qm1 = qmManager.open_qm(config) job = qm1.execute(prog, forceExecution=True) offsets = brute(power, rangebruteoffset, args=(corvars, qm1, inst, 'offset'), Ns=nstepbruteoffset, finish=None) print('\n Initial guess for the offsets [DC_I, DC_Q]: ', offsets, "\n\n") # Using fmin function to find the best offsets to minimize the leakage xopt = fmin(power, offsets, (corvars, qm1, inst, 'offset'), maxiter=maxiterfminoffset) # If there's an error trying to use the "power" function except Exception as e: print("An error has occurred in the 'power' function. \nThe Error:\n", e) inst.close() # Closes the spectrum analyzer exit() # Redefine the offsets to the values we found offsets = xopt print("\nOptimal offsets [DC_I, DC_Q]: " + str(offsets) + "\n\n") # Define the spectrum analyzer frequency to the left spike frequency inst.frequency(7e9 - 25e6) try: corvars = brute(powerdiffargs, rangebrutecorvars, args=(offsets, qm1, inst), Ns=nstepbrutecorvars, finish=None) correction = calc_cmat(corvars[0], corvars[1]) print("\n Initial guess from brute force [th, k]: " + str(corvars) + "\n\n") xopt = fmin(powerdiffargs, corvars, (offsets, qm1, inst), maxiter=maxiterfmincorvars) except Exception as e: print( "An error has occurred trying to find optimal correction matrix.\nThe Error:\n", e) exit() corvars = xopt print("\nOptimal correction variables [theta, k]: " + str(corvars)) inst.close() # Closes the instrument print( "\n--------------------------------------------------------------------------------\n\n" "Final results: \n" "Offsets [DC_I, DC_Q]: " + str(offsets) + "\nCorrection variables [theta, k]: " + str(corvars) + "\n\n--------------------------------------------------------------------------------\n" )
from qm.QuantumMachinesManager import QuantumMachinesManager from qm.qua import * from qm import SimulationConfig from configuration import * # Open communication with the server. QMm = QuantumMachinesManager() # Create a quantum machine based on the configuration. QM1 = QMm.open_qm(config) with program() as prog: play('playOp', 'qe1') job = QM1.simulate(prog, SimulationConfig(int(300))) samples = job.get_simulated_samples() samples.con1.plot()
int_freq=qubit_IF, mixer=mixer_qubit) lb_qubit = LabBrick(name="lb_qubit", serial_number=25331, frequency=qubit_LO, power=15) ######################################################################################## ######################################################################################## # initialize mixer_rr, rr and the rr's LO mixer_rr = QuantumElement( name="mixer_rr", i_offset=rr_mixer_offsets["I"], q_offset=rr_mixer_offsets["Q"], gain_offset=rr_mixer_offsets["G"], phase_offset=rr_mixer_offsets["P"], ) rr = QuantumElement(name="rr", lo_freq=rr_LO, int_freq=rr_IF, mixer=mixer_rr) lb_rr = LabBrick(name="lb_rr", serial_number=25335, frequency=rr_LO, power=15) ######################################################################################## ######################################################################################## # initialize QM with the updated config file qmm = QuantumMachinesManager() qm = qmm.open_qm(config) ######################################################################################## ########################################################################################
class QuantumMachine(object): def __init__(self, connection_info): self.connection_info = connection_info port = "" if self.connection_info[ "gateway_port"] is not None and self.connection_info[ "gateway_port"] != "": port = self.connection_info["gateway_port"] ip = "" if self.connection_info[ "gateway_ip"] is not None and self.connection_info[ "gateway_ip"] != "": ip = self.connection_info["gateway_ip"] if ip != "" and port != "": self.qmm = QuantumMachinesManager(host=ip, port=port) else: self.qmm = QuantumMachinesManager() self.qmObj = None self.job = None def connect(self): """ Already connected in the constructor :return: """ pass def connected(self): """Return whether or not commands can be sent to the instrument """ try: print(self.qmObj.list_controllers()) except Exception: return False return True def close_connection(self): if self.qmObj: self.qmObj.close() def set_config(self, config): self.qmObj = self.qmm.open_qm(config) def execute_program(self, prog, duration_limit, data_limit): self.job = self.qmObj.execute(prog, duration_limit=duration_limit, data_limit=data_limit, force_execution=True) def resume(self): self.job.resume() def set_output_dc_offset_by_qe(self, element, input, offset): self.qmObj.set_output_dc_offset_by_element(element, input, offset) def set_input_dc_offset_by_qe(self, element, output, offset): self.qmObj.set_input_dc_offset_by_element(element, output, offset) def get_results(self): return self.job.get_results() def set_io_values(self, io1_value, io2_value): self.qmObj.set_io_values(io1_value, io2_value) def get_io_values(self): return self.qmObj.get_io_values() def set_mixer_correction(self, mixer, intermediate_frequency, lo_frequency, values): self.qmObj.set_mixer_correction(mixer, intermediate_frequency, lo_frequency, values) def set_intermediate_frequency(self, qe, intermediate_frequency): self.qmObj.set_intermediate_frequency(qe, intermediate_frequency) def set_digital_delay(self, qe, digital_input, delay): self.qmObj.set_digital_delay(qe, digital_input, delay) def set_digital_buffer(self, qe, digital_input, buffer): self.qmObj.set_digital_buffer(qe, digital_input, buffer)
"type": "arbitrary", "samples": gaussian_derivative_fn(0.2 * 1.9164, 0.046 * 288.5, 175, 4), }, }, "mixers": { "mixer_qubit": [ { "intermediate_frequency": int(-50e6), "lo_frequency": int(5e9), "correction": (1.0, 0.0, 0.0, 1.0), }, ], }, } qmm = QuantumMachinesManager() with program() as test1: play("drag1" * amp(0.0, 0.0, 0.0, 0.046), "qubit") with program() as test2: play("drag2", "qubit") sim_config = SimulationConfig(duration=250, include_analog_waveforms=True) job1 = qmm.simulate(config, test1, sim_config) samples1 = job1.get_simulated_samples() i_samples1, q_samples1 = samples1.con1.analog["1"], samples1.con1.analog["2"] job2 = qmm.simulate(config, test2, sim_config) samples2 = job2.get_simulated_samples()
class QuantumMachine(BaseInstrument): caching_permissions = {} def __init__(self, connection_info, caching_allowed=True, caching_permissions={}, auto_open=True): super(QuantumMachine, self).__init__(connection_info, caching_allowed, caching_permissions, auto_open) self.connection_info = connection_info port = "" if connection_info[ "gateway_port"] and connection_info["gateway_port"] != "": port = connection_info["gateway_port"] ip = "" if connection_info[ "gateway_ip"] and connection_info["gateway_ip"] != "": ip = connection_info["gateway_ip"] if ip != "" and port != "": self.qmm = QuantumMachinesManager(host=ip, port=port) else: self.qmm = QuantumMachinesManager() self.qmObj = None self.job = None def connect(self): """ Already connected in the constructor :return: """ pass def connected(self): """Return whether or not commands can be sent to the instrument """ try: print(self.qmObj.list_controllers()) except Exception: return False return True def close_connection(self): if self.qmObj: self.qmObj.close() def clear_all_job_results(self): self.qmm.clear_all_job_results() def set_config(self, config): self.qmObj = self.qmm.open_qm(config, close_other_machines=True) @requires_config def execute_program(self, prog, duration_limit=0, data_limit=0): """Create a job on the OPX to execute a program. The duration_limit and data_limit arguments specify the maximum time and data size that the job can use before getting stopped by the server. Those limits are disabled by default. """ self.job = self.qmObj.execute(prog, duration_limit=duration_limit, data_limit=data_limit, force_execution=True) @requires_config def simulate_program(self, prog, duration): """ Simulate the program on the OPX The duration parameter specifies the number of FPGA cycles of the simulation (4ns/cycle). This functions opens a matplotlib popup with the results. """ self.job = self.qmObj.simulate( prog, SimulationConfig(duration=duration, include_analog_waveforms=True)) samples = self.job.get_simulated_samples() samples.con1.plot(digital_ports=(0, )) import matplotlib.pyplot as plt plt.show() def is_paused(self): return self.job.is_paused() def resume(self): self.job.resume() @requires_config def set_output_dc_offset_by_qe(self, element, input, offset): self.qmObj.set_output_dc_offset_by_element(element, input, offset) @requires_config def set_input_dc_offset_by_qe(self, element, output, offset): self.qmObj.set_input_dc_offset_by_element(element, output, offset) @requires_config def wait_for_all_results(self, ): """Wait for the current job to be completed. """ self.job.result_handles.wait_for_all_values() @requires_config def get_results(self, path=None): return self.job.result_handles @requires_config def get_execution_report(self, path=None): return self.job.execution_report() @requires_config def set_io_values(self, io1_value, io2_value): self.qmObj.set_io_values(io1_value, io2_value) @requires_config def get_io_values(self): return self.qmObj.get_io_values() @requires_config def set_mixer_correction(self, mixer, intermediate_frequency, lo_frequency, values): self.qmObj.set_mixer_correction(mixer, intermediate_frequency, lo_frequency, values) @requires_config def set_intermediate_frequency(self, qe, intermediate_frequency): self.qmObj.set_intermediate_frequency(qe, intermediate_frequency) @requires_config def set_digital_delay(self, qe, digital_input, delay): self.qmObj.set_digital_delay(qe, digital_input, delay) @requires_config def set_digital_buffer(self, qe, digital_input, buffer): self.qmObj.set_digital_buffer(qe, digital_input, buffer)
class QMQubitConfig: def __init__(self): self.qmm = QuantumMachinesManager() self.qm = None self.config = None # Qubit self.qubit_freq = 1e9 self.QB_IF_freq = 80.0e6 self.QB_LO_freq = self.qubit_freq - self.QB_IF_freq # for the mixer self.saturation_pulse_len = 50000 self.pi_pulse_len = 48 self.pi_wf = pulses.gauss(0.49, 0.0, 10.0, self.pi_pulse_len) self.pi2_wf = self.pi_wf / 2 # Readout self.res_freq = 7e9 self.RR_IF_freq = 62.5e6 self.RR_LO_up_freq = self.res_freq + self.RR_IF_freq self.RR_LO_down_freq = self.res_freq - self.RR_IF_freq self.wait_sig = 160 # minimum 32 clock cycles self.smearing_sig = 0 # multiple period self.wait_ref = 53 # minimum 32 clock cycles self.smearing_ref = 0 self.readout_pulse_len = 512 # multiple of 16 self.readout_wf = pulses.const(0.49, self.readout_pulse_len) self.theta = 0.0 # rotation of IQ plane # create config and load it self.load_config() def set_readout_wf(self, func, args, plot=False): self.readout_wf = func(*args, self.readout_pulse_len) self.load_config() #if plot: # self.ax.plot(self.readout_wf) # plt.show() def set_pi_pulse_wf(self, func, args, plot=False): self.pi_wf = func(*args, self.pi_pulse_len) self.pi2_wf = self.pi_wf / 2 self.load_config() #if plot: # self.ax.plot(self.pi_wf) # self.ax.plot(self.pi2_wf) # plt.show() def set_theta(self, theta): self.theta = theta self.load_config() # TODO set dc offset mixers def load_config(self): opx_one = "Opx" self.config = { 'version': 1, 'controllers': { opx_one: { 'type': 'Opx', 'analog_outputs': { # sweep offset of I,Q to see which combination best suppresses LO leakage 1: { 'offset': 0 }, # I qubit 2: { 'offset': 0 }, # Q qubit 3: { 'offset': 0 }, # RR }, 'analog_inputs': { 1: { 'offset': 0 }, # Reference 2: { 'offset': 0 } # Signal }, 'digital_outputs': { 1: {} } }, }, 'elements': { 'signal': { "singleInput": { "port": (opx_one, 3), }, 'intermediate_frequency': self.RR_IF_freq, 'operations': { 'readout_sig': 'readout_pulse', 'saturation_pulse': 'readout_saturation_pulse', }, "outputs": { 'out1': (opx_one, 1), }, 'time_of_flight': 4 * self.wait_sig, 'smearing': self.smearing_sig }, 'reference': { "singleInput": { "port": (opx_one, 3), }, 'intermediate_frequency': self.RR_IF_freq, 'operations': { 'readout_ref': 'reference_pulse', }, "outputs": { 'out1': (opx_one, 2), # TODO out2? }, 'time_of_flight': 4 * self.wait_ref, 'smearing': self.smearing_ref }, 'qubit': { "mixInputs": { "I": (opx_one, 1), "Q": (opx_one, 2), "mixer": "mixer_QB", "lo_frequency": self.QB_LO_freq }, 'intermediate_frequency': self.QB_IF_freq, 'operations': { 'saturation_pulse': 'saturation_pulse', 'pi_pulse': 'pi_pulse', 'pi/2_pulse': 'pi/2_pulse', } }, }, "pulses": { 'readout_saturation_pulse': { 'operation': 'control', 'length': self.saturation_pulse_len, 'waveforms': { 'single': 'const_wf', }, }, 'saturation_pulse': { 'operation': 'control', 'length': self.saturation_pulse_len, 'waveforms': { 'I': 'const_wf', 'Q': 'zero_wf', } }, 'pi_pulse': { 'operation': 'control', 'length': self.pi_pulse_len, 'waveforms': { 'I': 'pi_wf', 'Q': 'zero_wf' }, }, 'pi/2_pulse': { 'operation': 'control', 'length': self.pi_pulse_len, 'waveforms': { 'I': 'pi/2_wf', 'Q': 'zero_wf' }, }, 'readout_pulse': { 'operation': 'measurement', 'length': self.readout_pulse_len, 'waveforms': { 'single': 'readout_wf', }, 'digital_marker': 'ON', 'integration_weights': { 'integW_Is': 'integW_Is', 'integW_Qs': 'integW_Qs' }, }, 'reference_pulse': { 'operation': 'measurement', 'length': self.readout_pulse_len, 'waveforms': { 'single': 'zero_wf', }, 'digital_marker': 'ON', 'integration_weights': { 'integW_Ir': 'integW_Ir', 'integW_Qr': 'integW_Qr', } }, }, 'waveforms': { 'zero_wf': { 'type': 'constant', 'sample': 0 }, 'const_wf': { 'type': 'constant', 'sample': 0.49 }, 'readout_wf': { 'type': 'arbitrary', 'samples': self.readout_wf.tolist() }, 'pi_wf': { 'type': 'arbitrary', 'samples': self.pi_wf.tolist() }, 'pi/2_wf': { 'type': 'arbitrary', 'samples': self.pi2_wf.tolist() } }, 'digital_waveforms': { 'ON': { 'samples': [(1, 0)] }, }, 'integration_weights': { 'integW_Is': { 'cosine': [np.cos(self.theta / 360 * np.pi)] * int(self.readout_pulse_len / 4 + self.smearing_sig), 'sine': [np.sin(self.theta / 360 * np.pi)] * int(self.readout_pulse_len / 4 + self.smearing_sig), }, 'integW_Qs': { 'cosine': [np.sin(-self.theta / 360 * np.pi)] * int(self.readout_pulse_len / 4 + self.smearing_sig), 'sine': [np.cos(self.theta / 360 * np.pi)] * int(self.readout_pulse_len / 4 + self.smearing_sig), }, 'integW_Ir': { 'cosine': [np.cos(self.theta / 360 * np.pi)] * int(self.readout_pulse_len / 4 + self.smearing_ref), 'sine': [np.sin(-self.theta / 360 * np.pi)] * int(self.readout_pulse_len / 4 + self.smearing_ref), }, 'integW_Qr': { 'cosine': [np.sin(self.theta / 360 * np.pi)] * int(self.readout_pulse_len / 4 + self.smearing_ref), 'sine': [np.cos(self.theta / 360 * np.pi)] * int(self.readout_pulse_len / 4 + self.smearing_ref), }, }, 'mixers': { 'mixer_QB': [{ 'intermediate_frequency': self.QB_IF_freq, 'lo_frequency': self.QB_LO_freq, 'correction': [1, 0, 0, 1] }], }, } self.qm = self.qmm.open_qm(self.config) # TODO make it nice def print_config(self): print(self.config)
n = declare(int) t = declare(int) with for_(n, 0, n < 10, n + 1): with for_(t, 10, t < 1000, t + 10): play("pi", "qubit") wait(t, 'qubit', 'rr') align('qubit', 'rr') measure('readout', 'rr', None, demod.full('integW1', I), demod.full('integW2', Q)) save(I, I_stream) save(Q, Q_stream) with stream_processing(): I_stream.save_all("I") Q_stream.save_all("Q") qmm = QuantumMachinesManager(host="18.193.150.71") qm = qmm.open_qm(config) job = qm.simulate(experiment, SimulationConfig(2000)) samps = job.get_simulated_samples() fig, axes = plt.subplots(4) labels = ['I_q1', 'Q_q1', 'I_rr1', 'Q_rr1'] for i in range(4): axes[i].plot(samps.con1.analog.get(str(i + 1))) axes[i].set_title(labels[i]) plt.tight_layout() plt.show()