def test_sensitivity() -> None: """Test sensitivity analysis with 1D sweeps on 2 variables""" with open(OPT_CONFIG_FILE_NAME, "r") as cfg_file: cfg = hjson.load(cfg_file) cfg.pop("optim_type") exp = Experiment() exp.read_config(cfg.pop("exp_cfg")) # test error handling for estimator with pytest.raises(NotImplementedError): opt = Sensitivity(**cfg, pmap=exp.pmap) cfg.pop("estimator") # test error handling for estimator_list with pytest.raises(NotImplementedError): opt = Sensitivity(**cfg, pmap=exp.pmap) cfg.pop("estimator_list") opt = Sensitivity(**cfg, pmap=exp.pmap) opt.set_exp(exp) opt.set_created_by(OPT_CONFIG_FILE_NAME) opt.run() for index, val in enumerate(SWEEP_PARAM_NAMES): # This decomposition of opt.sweep_end into the actual_param_end only makes # sense when you look at how opt.sweep_end structures the sweep endings actual_param_end = opt.sweep_end[index][val]["params"][0] np.testing.assert_almost_equal(actual_param_end, DESIRED_SWEEP_END_PARAMS[index])
def test_create_c1() -> None: with open("test/c1.cfg", "r") as cfg_file: cfg = hjson.load(cfg_file) cfg.pop("optim_type") cfg.pop("gateset_opt_map") cfg.pop("opt_gates") exp = Experiment(prop_method=cfg.pop("propagation_method", None)) exp.read_config(cfg.pop("exp_cfg")) OptimalControl(**cfg, pmap=exp.pmap)
def test_create_c3() -> None: with open("test/c3.cfg", "r") as cfg_file: cfg = hjson.load(cfg_file) cfg.pop("optim_type") cfg.pop("exp_opt_map") exp = Experiment() exp.read_config(cfg.pop("exp_cfg")) assert isinstance(ModelLearning(**cfg, pmap=exp.pmap), ModelLearning)
def test_calibration_cmaes() -> None: """Create a C2 style Optimizer object and run calibration with a mock_ORBIT function. Check if the goal in the optimizer correctly reflects the constant goal returned by the mock_ORBIT. """ with open(OPT_CONFIG_FILE_NAME, "r") as cfg_file: cfg = hjson.load(cfg_file) pmap = ParameterMap() pmap.read_config(cfg.pop("instructions")) pmap.set_opt_map( [[tuple(par) for par in pset] for pset in cfg.pop("gateset_opt_map")] ) exp = Experiment(pmap=pmap) algo_options = cfg.pop("options") run_name = cfg.pop("run_name") opt = Calibration( dir_path=LOGDIR, run_name=run_name, eval_func=mock_ORBIT, pmap=pmap, exp_right=exp, algorithm=algorithms.cmaes, options=algo_options, ) opt.run() assert opt.current_best_goal == RESULT_VAL
def test_model_learning() -> None: with open(OPT_CONFIG_FILE_NAME, "r") as cfg_file: cfg = hjson.load(cfg_file) cfg.pop("optim_type") exp = Experiment() exp.read_config(cfg.pop("exp_cfg")) exp.pmap.set_opt_map([[tuple(par) for par in pset] for pset in cfg.pop("exp_opt_map")]) opt = ModelLearning(**cfg, pmap=exp.pmap) opt.set_exp(exp) opt.set_created_by(OPT_CONFIG_FILE_NAME) opt.run() np.testing.assert_allclose(opt.current_best_params, DESIRED_PARAMS, rtol=RELATIVE_TOLERANCE)
def test_save_and_load(): exp.compute_propagators() propagators = exp.propagators cfg_str = hjson.dumpsJSON(exp.asdict(), default=hjson_encode) cfg_dct = hjson.loads(cfg_str, object_pairs_hook=hjson_decode) exp2 = Experiment() exp2.from_dict(cfg_dct) exp2.compute_propagators() for k in propagators: np.testing.assert_allclose(exp2.propagators[k], propagators[k])
""" testing module for QASM instructions """ import pytest from c3.experiment import Experiment exp = Experiment() exp.load_quick_setup("test/quickstart.hjson") exp.enable_qasm() sequence = [ { "name": "rx90p", "qubits": [0] }, { "name": "VZ", "qubits": [0], "params": [0.123] }, { "name": "VZ", "qubits": [1], "params": [2.31] }, ] exp.set_opt_gates(["rx90p[0]"]) exp.compute_propagators()
def run_experiment(self, experiment: QasmQobjExperiment) -> Dict[str, Any]: """Run an experiment (circuit) and return a single experiment result Parameters ---------- experiment : QasmQobjExperiment experiment from qobj experiments list Returns ------- Dict[str, Any] A result dictionary which looks something like:: { "name": name of this experiment (obtained from qobj.experiment header) "seed": random seed used for simulation "shots": number of shots used in the simulation "data": { "counts": {'0x9: 5, ...}, "memory": ['0x9', '0xF', '0x1D', ..., '0x9'] }, "status": status string for the simulation "success": boolean "time_taken": simulation time of this single experiment } Raises ------ C3QiskitError If an error occured """ start = time.time() # setup C3 Experiment exp = Experiment() exp.quick_setup(self._device_config) pmap = exp.pmap model = pmap.model # noqa # initialise parameters self._number_of_qubits = len(pmap.model.subsystems) if self._number_of_qubits != experiment.config.n_qubits: raise C3QiskitError( "Number of qubits in Circuit & Device dont match") shots = self._shots # noqa # TODO (Check) Assume all qubits have same Hilbert dims self._number_of_levels = pmap.model.dims[0] # Validate the dimension of initial statevector if set self._validate_initial_statevector() # TODO set simulator seed, check qiskit python qasm simulator # qiskit-terra/qiskit/providers/basicaer/qasm_simulator.py seed_simulator = 2441129 # convert qasm instruction set to c3 sequence sequence = get_sequence(experiment.instructions, self._number_of_qubits) # noqa # TODO get_init_ground_state(), get_gates(), evaluate(), process() # generate shots style readout with no SPAM # TODO a sophisticated readout/measurement routine # TODO generate state labels using get_labels() # TODO create results dict and remove empty states counts = {} # type: ignore # flipping state labels to match qiskit style qubit indexing convention # default is to flip labels to qiskit style, use disable_flip_labels() if self._flip_labels: counts = flip_labels(counts) end = time.time() exp_result = { "name": experiment.header.name, "header": experiment.header.to_dict(), "shots": self._shots, "seed": seed_simulator, "status": "DONE", "success": True, "data": { "counts": counts }, "time_taken": (end - start), } return exp_result
def run_experiment(self, experiment: QasmQobjExperiment) -> Dict[str, Any]: """Run an experiment (circuit) and return a single experiment result Parameters ---------- experiment : QasmQobjExperiment experiment from qobj experiments list Returns ------- Dict[str, Any] A result dictionary which looks something like:: { "name": name of this experiment (obtained from qobj.experiment header) "seed": random seed used for simulation "shots": number of shots used in the simulation "data": { "counts": {'0x9': 5, ...}, "memory": ['0x9', '0xF', '0x1D', ..., '0x9'] }, "status": status string for the simulation "success": boolean "time_taken": simulation time of this single experiment } Raises ------ C3QiskitError If an error occured """ start = time.time() # setup C3 Experiment exp = Experiment() exp.quick_setup(self._device_config) pmap = exp.pmap # initialise parameters self._number_of_qubits = len(pmap.model.subsystems) if self._number_of_qubits != experiment.config.n_qubits: raise C3QiskitError( "Number of qubits in Circuit & Device dont match") shots = self._shots # TODO (Check) Assume all qubits have same Hilbert dims self._number_of_levels = pmap.model.dims[0] # Validate the dimension of initial statevector if set self._validate_initial_statevector() # TODO set simulator seed, check qiskit python qasm simulator # qiskit-terra/qiskit/providers/basicaer/qasm_simulator.py seed_simulator = 2441129 # convert qasm instruction set to c3 sequence sequence = get_sequence(experiment.instructions, self._number_of_qubits) # unique operations gate_keys = list(set(sequence)) perfect_gates = exp.get_perfect_gates(gate_keys) # initialise state psi_init = get_init_ground_state(self._number_of_qubits, self._number_of_levels) psi_t = psi_init.numpy() pop_t = exp.populations(psi_t, False) # compute final state for gate in sequence: psi_t = np.matmul(perfect_gates[gate], psi_t) pops = exp.populations(psi_t, False) pop_t = np.append(pop_t, pops, axis=1) # generate shots style readout with no SPAM # TODO a more sophisticated readout/measurement routine shots_data = (np.round(pop_t.T[-1] * shots)).astype("int32") # generate state labels output_labels = self.get_labels() # create results dict counts = dict(zip(output_labels, shots_data)) # keep only non-zero states counts = dict(filter(lambda elem: elem[1] != 0, counts.items())) # flipping state labels to match qiskit style qubit indexing convention # default is to flip labels to qiskit style, use disable_flip_labels() if self._flip_labels: counts = flip_labels(counts) end = time.time() exp_result = { "name": experiment.header.name, "header": experiment.header.to_dict(), "shots": self._shots, "seed": seed_simulator, "status": "DONE", "success": True, "data": { "counts": counts }, "time_taken": (end - start), } return exp_result
single_q_gates = [QId_q1, rx90p_q1, Y90p_q1, X90m_q1, Y90m_q1] Y90p_q2 = copy.deepcopy(rx90p_q2) Y90p_q2.name = "ry90p" X90m_q2 = copy.deepcopy(rx90p_q2) X90m_q2.name = "rx90m" Y90m_q2 = copy.deepcopy(rx90p_q2) Y90m_q2.name = "ry90m" Y90p_q2.comps["d2"]["gauss"].params["xy_angle"].set_value(0.5 * np.pi) X90m_q2.comps["d2"]["gauss"].params["xy_angle"].set_value(np.pi) Y90m_q2.comps["d2"]["gauss"].params["xy_angle"].set_value(1.5 * np.pi) single_q_gates.extend([QId_q2, rx90p_q2, Y90p_q2, X90m_q2, Y90m_q2]) pmap = Pmap(single_q_gates, generator, model) exp = Exp(pmap) generator.devices["AWG"].enable_drag_2() exp.set_opt_gates(["rx90p[0]"]) gateset_opt_map = [ [ ("rx90p[0]", "d1", "gauss", "amp"), ], [ ("rx90p[0]", "d1", "gauss", "freq_offset"), ], [ ("rx90p[0]", "d1", "gauss", "xy_angle"), ],
def run_experiment(self, experiment: QasmQobjExperiment) -> Dict[str, Any]: """Run an experiment (circuit) and return a single experiment result Parameters ---------- experiment : QasmQobjExperiment experiment from qobj experiments list Returns ------- Dict[str, Any] A result dictionary which looks something like:: { "name": name of this experiment (obtained from qobj.experiment header) "seed": random seed used for simulation "shots": number of shots used in the simulation "data": { "counts": {'0x9: 5, ...}, "memory": ['0x9', '0xF', '0x1D', ..., '0x9'] }, "status": status string for the simulation "success": boolean "time_taken": simulation time of this single experiment } Raises ------ C3QiskitError If an error occured """ start = time.time() # setup C3 Experiment exp = Experiment() exp.quick_setup(self._device_config) pmap = exp.pmap model = pmap.model # initialise parameters # TODO get n_qubits from device config and raise error if mismatch self._number_of_qubits = experiment.config.n_qubits # TODO ensure number of quantum and classical bits is same shots = self._shots # TODO get number of hilbert dimensions from device config self._number_of_levels = 2 # Validate the dimension of initial statevector if set self._validate_initial_statevector() # TODO set simulator seed, check qiskit python qasm simulator # qiskit-terra/qiskit/providers/basicaer/qasm_simulator.py seed_simulator = 2441129 # TODO check for user-defined perfect and physics based sim # TODO resolve use of evaluate(), process() in Experiment, possibly extend # TODO implement get_perfect_gates() in Experiment # unitaries = exp.get_perfect_gates() exp.get_gates() dUs = exp.dUs # convert qasm instruction set to c3 sequence sequence = get_sequence(experiment.instructions) # TODO Implement extracting n_qubits and n_levels from device # create initial state for qubits and levels psi_init = get_init_ground_state(self._number_of_qubits, self._number_of_levels) psi_t = psi_init.numpy() pop_t = exp.populations(psi_t, model.lindbladian) # simulate sequence for gate in sequence: for du in dUs[gate]: psi_t = np.matmul(du.numpy(), psi_t) pops = exp.populations(psi_t, model.lindbladian) pop_t = np.append(pop_t, pops, axis=1) # generate shots style readout with no SPAM # TODO a more sophisticated readout/measurement routine shots_data = (np.round(pop_t.T[-1] * shots)).astype("int32") # generate state labels # TODO use n_qubits and n_levels labels = [ hex(i) for i in range( 0, pow(self._number_of_qubits, self._number_of_levels)) ] # create results dict counts = dict(zip(labels, shots_data)) # keep only non-zero states counts = dict(filter(lambda elem: elem[1] != 0, counts.items())) end = time.time() exp_result = { "name": experiment.header.name, "header": experiment.header.to_dict(), "shots": self._shots, "seed": seed_simulator, "status": "DONE", "success": True, "data": { "counts": counts }, "time_taken": (end - start), } return exp_result
def run_cfg(cfg, opt_config_filename, debug=False): """Execute an optimization problem described in the cfg file. Parameters ---------- cfg : Dict[str, Union[str, int, float]] Configuration file containing optimization options and information needed to completely setup the system and optimization problem. debug : bool, optional Skip running the actual optimization, by default False """ optim_type = cfg.pop("optim_type") optim_lib = { "C1": OptimalControl, "C2": Calibration, "C3": ModelLearning, "C3_confirm": ModelLearning, "confirm": ModelLearning, "SET": Sensitivity, } if not optim_type in optim_lib: raise Exception("C3:ERROR:Unknown optimization type specified.") tf_utils.tf_setup() with tf.device("/CPU:0"): model = None gen = None exp = None prop_meth = cfg.pop("propagation_method", None) if "model" in cfg: model = Model() model.read_config(cfg.pop("model")) if "generator" in cfg: gen = Generator() gen.read_config(cfg.pop("generator")) if "instructions" in cfg: pmap = ParameterMap(model=model, generator=gen) pmap.read_config(cfg.pop("instructions")) exp = Experiment(pmap, prop_method=prop_meth) if "exp_cfg" in cfg: exp = Experiment(prop_method=prop_meth) exp.read_config(cfg.pop("exp_cfg")) if exp is None: print( "C3:STATUS: No instructions specified. Performing quick setup." ) exp = Experiment(prop_method=prop_meth) exp.quick_setup(cfg) exp.set_opt_gates(cfg.pop("opt_gates", None)) if "gateset_opt_map" in cfg: exp.pmap.set_opt_map([[tuple(par) for par in pset] for pset in cfg.pop("gateset_opt_map")]) if "exp_opt_map" in cfg: exp.pmap.set_opt_map([[tuple(par) for par in pset] for pset in cfg.pop("exp_opt_map")]) opt = optim_lib[optim_type](**cfg, pmap=exp.pmap) opt.set_exp(exp) opt.set_created_by(opt_config_filename) if "initial_point" in cfg: initial_points = cfg["initial_point"] if isinstance(initial_points, str): initial_points = [initial_points] elif isinstance(initial_points, list): pass else: raise Warning( "initial_point has to be a path or a list of paths.") for init_point in initial_points: try: opt.load_best(init_point) print("C3:STATUS:Loading initial point from : " f"{os.path.abspath(init_point)}") except FileNotFoundError as fnfe: raise Exception( f"C3:ERROR:No initial point found at " f"{os.path.abspath(init_point)}. ") from fnfe if optim_type == "C1": if "adjust_exp" in cfg: try: adjust_exp = cfg["adjust_exp"] opt.load_model_parameters(adjust_exp) print("C3:STATUS:Loading experimental values from : " f"{os.path.abspath(adjust_exp)}") except FileNotFoundError as fnfe: raise Exception( f"C3:ERROR:No experimental values found at " f"{os.path.abspath(adjust_exp)} " "Continuing with default.") from fnfe if not debug: opt.run()
copy.deepcopy(gauss_env_single), "d2", name="gaussd2_2", options={ "delay": Quantity(1e-9), "trigger_comp": ("d1", "gaussd1_2"), "t_final_cut": Quantity(0.9 * t_final), }, ) instr.add_component(carr, "d1") instr.add_component(carr_2, "d2") instr_dict_str = hjson.dumpsJSON(instr.asdict(), default=hjson_encode) pmap = ParameterMap(model=model, generator=generator, instructions=[instr]) exp = Experiment(pmap) with open("test/instruction.pickle", "rb") as filename: test_data = pickle.load(filename) @pytest.mark.integration def test_extended_pulse(): instr_it = instr gen_signal = generator.generate_signals(instr_it) ts = gen_signal["d1"]["ts"] np.testing.assert_allclose( ts, test_data["signal"]["d1"]["ts"], atol=1e-9 * np.max(test_data["signal"]["d1"]["ts"]),
} carr = pulse.Carrier(name="carrier", desc="Frequency of the local oscillator", params=carrier_parameters) RX90p = gates.Instruction(name="RX90p", t_start=0.0, t_end=t_final, channels=["d1"]) RX90p.add_component(gauss_env_single, "d1") RX90p.add_component(carr, "d1") pmap = Pmap([RX90p], generator, model) exp = Exp(pmap) pmap2 = Pmap([RX90p], generator2, model) exp2 = Exp(pmap2) exp.set_opt_gates(["RX90p"]) gateset_opt_map = [ [ ("RX90p", "d1", "gauss", "amp"), ], [ ("RX90p", "d1", "gauss", "freq_offset"), ], [ ("RX90p", "d1", "gauss", "xy_angle"),
optim_type = cfg["optim_type"] tf_utils.tf_setup() with tf.device("/CPU:0"): model = None gen = None if "model" in cfg: model = Model() model.read_config(cfg["model"]) if "generator" in cfg: gen = Generator() gen.read_config(cfg["generator"]) if "instructions" in cfg: pmap = ParameterMap(model=model, generator=gen) pmap.read_config(cfg["instructions"]) exp = Experiment(pmap) else: print( "C3:STATUS: No instructions specified. Performing quick setup." ) exp = Experiment() exp.quick_setup(opt_config) if optim_type == "C1": opt = parsers.create_c1_opt(opt_config, exp) if cfg["include_model"]: opt.include_model() elif optim_type == "C2": eval_func = cfg["eval_func"] opt = parsers.create_c2_opt(opt_config, eval_func) elif optim_type == "C3" or optim_type == "C3_confirm":
def two_qubits() -> float: """script for setting up two qubits and optimising a simple gate Returns ------- float result of optimisation run """ qubit_lvls = 3 freq_q1 = 5e9 * 2 * np.pi anhar_q1 = -210e6 * 2 * np.pi t1_q1 = 27e-6 t2star_q1 = 39e-6 qubit_temp = 50e-3 q1 = chip.Qubit(name="Q1", desc="Qubit 1", freq=Qty(value=freq_q1, min=4.995e9 * 2 * np.pi, max=5.005e9 * 2 * np.pi, unit='Hz 2pi'), anhar=Qty(value=anhar_q1, min=-380e6 * 2 * np.pi, max=-120e6 * 2 * np.pi, unit='Hz 2pi'), hilbert_dim=qubit_lvls, t1=Qty(value=t1_q1, min=1e-6, max=90e-6, unit='s'), t2star=Qty(value=t2star_q1, min=10e-6, max=90e-3, unit='s'), temp=Qty(value=qubit_temp, min=0.0, max=0.12, unit='K')) freq_q2 = 5.6e9 * 2 * np.pi anhar_q2 = -240e6 * 2 * np.pi t1_q2 = 23e-6 t2star_q2 = 31e-6 q2 = chip.Qubit(name="Q2", desc="Qubit 2", freq=Qty(value=freq_q2, min=5.595e9 * 2 * np.pi, max=5.605e9 * 2 * np.pi, unit='Hz 2pi'), anhar=Qty(value=anhar_q2, min=-380e6 * 2 * np.pi, max=-120e6 * 2 * np.pi, unit='Hz 2pi'), hilbert_dim=qubit_lvls, t1=Qty(value=t1_q2, min=1e-6, max=90e-6, unit='s'), t2star=Qty(value=t2star_q2, min=10e-6, max=90e-6, unit='s'), temp=Qty(value=qubit_temp, min=0.0, max=0.12, unit='K')) coupling_strength = 20e6 * 2 * np.pi q1q2 = chip.Coupling(name="Q1-Q2", desc="coupling", comment="Coupling qubit 1 to qubit 2", connected=["Q1", "Q2"], strength=Qty(value=coupling_strength, min=-1 * 1e3 * 2 * np.pi, max=200e6 * 2 * np.pi, unit='Hz 2pi'), hamiltonian_func=hamiltonians.int_XX) drive = chip.Drive(name="d1", desc="Drive 1", comment="Drive line 1 on qubit 1", connected=["Q1"], hamiltonian_func=hamiltonians.x_drive) drive2 = chip.Drive(name="d2", desc="Drive 2", comment="Drive line 2 on qubit 2", connected=["Q2"], hamiltonian_func=hamiltonians.x_drive) m00_q1 = 0.97 # Prop to read qubit 1 state 0 as 0 m01_q1 = 0.04 # Prop to read qubit 1 state 0 as 1 m00_q2 = 0.96 # Prop to read qubit 2 state 0 as 0 m01_q2 = 0.05 # Prop to read qubit 2 state 0 as 1 one_zeros = np.array([0] * qubit_lvls) zero_ones = np.array([1] * qubit_lvls) one_zeros[0] = 1 zero_ones[0] = 0 val1 = one_zeros * m00_q1 + zero_ones * m01_q1 val2 = one_zeros * m00_q2 + zero_ones * m01_q2 min = one_zeros * 0.8 + zero_ones * 0.0 max = one_zeros * 1.0 + zero_ones * 0.2 confusion_row1 = Qty(value=val1, min=min, max=max, unit="") confusion_row2 = Qty(value=val2, min=min, max=max, unit="") conf_matrix = tasks.ConfusionMatrix(Q1=confusion_row1, Q2=confusion_row2) init_temp = 50e-3 init_ground = tasks.InitialiseGround( init_temp=Qty(value=init_temp, min=-0.001, max=0.22, unit='K')) model = Mdl( [q1, q2], # Individual, self-contained components [drive, drive2, q1q2], # Interactions between components [conf_matrix, init_ground] # SPAM processing ) model.set_lindbladian(False) model.set_dressed(True) sim_res = 100e9 # Resolution for numerical simulation awg_res = 2e9 # Realistic, limited resolution of an AWG lo = devices.LO(name='lo', resolution=sim_res) awg = devices.AWG(name='awg', resolution=awg_res) mixer = devices.Mixer(name='mixer') resp = devices.Response(name='resp', rise_time=Qty(value=0.3e-9, min=0.05e-9, max=0.6e-9, unit='s'), resolution=sim_res) dig_to_an = devices.Digital_to_Analog(name="dac", resolution=sim_res) v2hz = 1e9 v_to_hz = devices.Volts_to_Hertz(name='v_to_hz', V_to_Hz=Qty(value=v2hz, min=0.9e9, max=1.1e9, unit='Hz 2pi/V')) generator = Gnr([lo, awg, mixer, v_to_hz, dig_to_an, resp]) import c3.signal.gates as gates gateset = gates.GateSet() t_final = 7e-9 # Time for single qubit gates sideband = 50e6 * 2 * np.pi gauss_params_single = { 'amp': Qty(value=0.5, min=0.4, max=0.6, unit="V"), 't_final': Qty(value=t_final, min=0.5 * t_final, max=1.5 * t_final, unit="s"), 'sigma': Qty(value=t_final / 4, min=t_final / 8, max=t_final / 2, unit="s"), 'xy_angle': Qty(value=0.0, min=-0.5 * np.pi, max=2.5 * np.pi, unit='rad'), 'freq_offset': Qty(value=-sideband - 3e6 * 2 * np.pi, min=-56 * 1e6 * 2 * np.pi, max=-52 * 1e6 * 2 * np.pi, unit='Hz 2pi'), 'delta': Qty(value=-1, min=-5, max=3, unit="") } gauss_env_single = pulse.Envelope( name="gauss", desc="Gaussian comp for single-qubit gates", params=gauss_params_single, shape=envelopes.gaussian_nonorm) nodrive_env = pulse.Envelope(name="no_drive", params={ 't_final': Qty(value=t_final, min=0.5 * t_final, max=1.5 * t_final, unit="s") }, shape=envelopes.no_drive) lo_freq_q1 = 5e9 * 2 * np.pi + sideband carrier_parameters = { 'freq': Qty(value=lo_freq_q1, min=4.5e9 * 2 * np.pi, max=6e9 * 2 * np.pi, unit='Hz 2pi'), 'framechange': Qty(value=0.0, min=-np.pi, max=3 * np.pi, unit='rad') } carr = pulse.Carrier(name="carrier", desc="Frequency of the local oscillator", params=carrier_parameters) lo_freq_q2 = 5.6e9 * 2 * np.pi + sideband carr_2 = copy.deepcopy(carr) carr_2.params['freq'].set_value(lo_freq_q2) X90p_q1 = gates.Instruction(name="X90p", t_start=0.0, t_end=t_final, channels=["d1"]) X90p_q2 = gates.Instruction(name="X90p", t_start=0.0, t_end=t_final, channels=["d2"]) QId_q1 = gates.Instruction(name="Id", t_start=0.0, t_end=t_final, channels=["d1"]) QId_q2 = gates.Instruction(name="Id", t_start=0.0, t_end=t_final, channels=["d2"]) X90p_q1.add_component(gauss_env_single, "d1") X90p_q1.add_component(carr, "d1") QId_q1.add_component(nodrive_env, "d1") QId_q1.add_component(copy.deepcopy(carr), "d1") X90p_q2.add_component(copy.deepcopy(gauss_env_single), "d2") X90p_q2.add_component(carr_2, "d2") QId_q2.add_component(copy.deepcopy(nodrive_env), "d2") QId_q2.add_component(copy.deepcopy(carr_2), "d2") QId_q1.comps['d1']['carrier'].params['framechange'].set_value( (-sideband * t_final) % (2 * np.pi)) QId_q2.comps['d2']['carrier'].params['framechange'].set_value( (-sideband * t_final) % (2 * np.pi)) Y90p_q1 = copy.deepcopy(X90p_q1) Y90p_q1.name = "Y90p" X90m_q1 = copy.deepcopy(X90p_q1) X90m_q1.name = "X90m" Y90m_q1 = copy.deepcopy(X90p_q1) Y90m_q1.name = "Y90m" Y90p_q1.comps['d1']['gauss'].params['xy_angle'].set_value(0.5 * np.pi) X90m_q1.comps['d1']['gauss'].params['xy_angle'].set_value(np.pi) Y90m_q1.comps['d1']['gauss'].params['xy_angle'].set_value(1.5 * np.pi) Q1_gates = [QId_q1, X90p_q1, Y90p_q1, X90m_q1, Y90m_q1] Y90p_q2 = copy.deepcopy(X90p_q2) Y90p_q2.name = "Y90p" X90m_q2 = copy.deepcopy(X90p_q2) X90m_q2.name = "X90m" Y90m_q2 = copy.deepcopy(X90p_q2) Y90m_q2.name = "Y90m" Y90p_q2.comps['d2']['gauss'].params['xy_angle'].set_value(0.5 * np.pi) X90m_q2.comps['d2']['gauss'].params['xy_angle'].set_value(np.pi) Y90m_q2.comps['d2']['gauss'].params['xy_angle'].set_value(1.5 * np.pi) Q2_gates = [QId_q2, X90p_q2, Y90p_q2, X90m_q2, Y90m_q2] all_1q_gates_comb = [] for g1 in Q1_gates: for g2 in Q2_gates: g = gates.Instruction(name="NONE", t_start=0.0, t_end=t_final, channels=[]) g.name = g1.name + ":" + g2.name channels = [] channels.extend(g1.comps.keys()) channels.extend(g2.comps.keys()) for chan in channels: g.comps[chan] = {} if chan in g1.comps: g.comps[chan].update(g1.comps[chan]) if chan in g2.comps: g.comps[chan].update(g2.comps[chan]) all_1q_gates_comb.append(g) for gate in all_1q_gates_comb: gateset.add_instruction(gate) exp = Exp(model=model, generator=generator, gateset=gateset) exp.opt_gates = ['X90p:Id', 'Id:Id'] gates = exp.get_gates() psi_init = [[0] * 9] psi_init[0][0] = 1 init_state = tf.transpose(tf.constant(psi_init, tf.complex128)) barely_a_seq = ['X90p:Id'] barely_a_seq * 10 generator.devices['awg'].enable_drag_2() opt_gates = ["X90p:Id"] gateset_opt_map = [[ ("X90p:Id", "d1", "gauss", "amp"), ], [ ("X90p:Id", "d1", "gauss", "freq_offset"), ], [ ("X90p:Id", "d1", "gauss", "xy_angle"), ], [ ("X90p:Id", "d1", "gauss", "delta"), ]] opt = C1(dir_path="/tmp/c3log/", fid_func=fidelities.average_infid_set, fid_subspace=["Q1", "Q2"], gateset_opt_map=gateset_opt_map, opt_gates=opt_gates, algorithm=algorithms.lbfgs, options={"maxfun": 10}, run_name="better_X90") opt.set_exp(exp) opt.optimize_controls() return (opt.current_best_goal)
""" testing module quick setup class """ import pytest from c3.experiment import Experiment exp = Experiment() exp.quick_setup("test/quickstart.hjson") pmap = exp.pmap model = pmap.model generator = pmap.generator @pytest.mark.integration def test_exp_quick_setup_freqs() -> None: """ Test the quick setup. """ qubit_freq = model.subsystems["Q1"].params["freq"].get_value() gate = pmap.instructions["X90p:Id"] carrier_freq = gate.comps["d1"]["carrier"].params["freq"].get_value() offset = gate.comps["d1"]["gaussian"].params["freq_offset"].get_value() assert qubit_freq == carrier_freq + offset
name="instr2", t_start=0.0, t_end=cphase_time, channels=["Qubit2"], ) instr1.add_component(copy.deepcopy(flux_env), "Qubit1") instr1.add_component(copy.deepcopy(carr_q1), "Qubit1") instr2.add_component(flux_env, "Qubit2") instr2.add_component(carr_q1, "Qubit2") # ### MAKE EXPERIMENT parameter_map = ParameterMap(instructions=[instr1, instr2], model=model, generator=generator) exp = Experiment(pmap=parameter_map) exp.use_control_fields = False exp.stop_partial_propagator_gradient = False test_data = {} with open("test/transmon_expanded.pickle", "rb") as filename: data = pickle.load(filename) gen_signal1 = generator.generate_signals(instr1) gen_signal2 = generator.generate_signals(instr2) @pytest.mark.integration def test_signals(): test_data["signal_q1"] = gen_signal1["Qubit1"] test_data["signal_q2"] = gen_signal2["Qubit2"]
g = gates.Instruction(name="NONE", t_start=0.0, t_end=t_final, channels=[]) g.name = g1.name + ":" + g2.name channels: List[str] = [] channels.extend(g1.comps.keys()) channels.extend(g2.comps.keys()) for chan in channels: g.comps[chan] = {} if chan in g1.comps: g.comps[chan].update(g1.comps[chan]) if chan in g2.comps: g.comps[chan].update(g2.comps[chan]) all_1q_gates_comb.append(g) pmap = Pmap(all_1q_gates_comb, generator, model) exp = Exp(pmap) generator.devices["AWG"].enable_drag_2() exp.set_opt_gates(["X90p:Id"]) gateset_opt_map = [ [ ("X90p:Id", "d1", "gauss", "amp"), ], [ ("X90p:Id", "d1", "gauss", "freq_offset"), ], [ ("X90p:Id", "d1", "gauss", "xy_angle"), ],
optim_type = cfg["optim_type"] tf_utils.tf_setup() with tf.device("/CPU:0"): model = None gen = None if "model" in cfg: model = Model() model.read_config(cfg["model"]) if "generator" in cfg: gen = Generator() gen.read_config(cfg["generator"]) if "instructions" in cfg: pmap = ParameterMap(model=model, generator=gen) pmap.read_config(cfg["instructions"]) exp = Experiment(pmap) if "exp_cfg" in cfg: exp = Experiment() exp.read_config(cfg["exp_cfg"]) else: print( "C3:STATUS: No instructions specified. Performing quick setup." ) exp = Experiment() exp.quick_setup(opt_config) if optim_type == "C1": opt = parsers.create_c1_opt(opt_config, exp) if cfg.pop("include_model", False): opt.include_model() elif optim_type == "C2":