def test_tasks() -> None: """Task creation is tested separately in the absence of Von Neumann eqn""" model = Model() model.read_config("test/test_model_spam.cfg") pmap = ParameterMap(model=model, generator=gen) pmap.read_config("test/instructions.cfg") assert list(model.tasks.keys()) == ["init_ground", "conf_matrix", "meas_rescale"]
def from_dict(self, cfg: Dict) -> None: """ Load experiment from dictionary """ model = Model() model.fromdict(cfg["model"]) generator = Generator() generator.fromdict(cfg["generator"]) pmap = ParameterMap(model=model, generator=generator) pmap.fromdict(cfg["instructions"]) if "options" in cfg: for k, v in cfg["options"].items(): self.__dict__[k] = v self.pmap = pmap
def get_xtalk_pmap() -> ParameterMap: xtalk = Crosstalk( name="crosstalk", channels=["TC1", "TC2"], crosstalk_matrix=Quantity( value=[[1, 0], [0, 1]], min_val=[[0, 0], [0, 0]], max_val=[[1, 1], [1, 1]], unit="", ), ) gen = Generator(devices={"crosstalk": xtalk}) pmap = ParameterMap(generator=gen) pmap.set_opt_map([[["crosstalk", "crosstalk_matrix"]]]) return pmap
def read_config(self, filepath: str) -> None: """ Load a file and parse it to create a Model object. Parameters ---------- filepath : str Location of the configuration file """ with open(filepath, "r") as cfg_file: cfg = hjson.loads(cfg_file.read()) model = Model() model.fromdict(cfg["model"]) generator = Generator() generator.fromdict(cfg["generator"]) pmap = ParameterMap(model=model, generator=generator) pmap.fromdict(cfg["instructions"]) self.pmap = pmap
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
max = one_zeros * 1.0 + zero_ones * 0.2 confusion_row1 = Quantity(value=val1, min_val=min, max_val=max, unit="") confusion_row2 = Quantity(value=val2, min_val=min, max_val=max, unit="") conf_matrix = ConfusionMatrix(Q1=confusion_row1, Q2=confusion_row2) init_temp = 50e-3 init_ground = InitialiseGround(init_temp=Quantity( value=init_temp, min_val=-0.001, max_val=0.22, unit="K")) model = Model( [q1, q2], # Individual, self-contained components [drive, drive2, q1q2], # Interactions between components [conf_matrix, init_ground], # SPAM processing ) pmap = ParameterMap(model=model) model.set_dressed(False) hdrift, hks = model.get_Hamiltonians() @pytest.mark.unit def test_model_eigenfrequencies_1() -> None: "Eigenfrequency of qubit 1" assert hdrift[3, 3] - hdrift[0, 0] == freq_q1 * 2 * np.pi @pytest.mark.unit def test_model_eigenfrequencies_2() -> None: "Eigenfrequency of qubit 2" assert hdrift[1, 1] - hdrift[0, 0] == freq_q2 * 2 * np.pi
import numpy as np import pytest from c3.c3objs import Quantity from c3.libraries.envelopes import envelopes from c3.signal.gates import Instruction from c3.signal.pulse import Envelope, Carrier from c3.model import Model from c3.generator.generator import Generator from c3.parametermap import ParameterMap from c3.experiment import Experiment as Exp model = Model() model.read_config("test/test_model.cfg") gen = Generator() gen.read_config("test/generator.cfg") pmap = ParameterMap(model=model, generator=gen) pmap.read_config("test/instructions.cfg") @pytest.mark.unit def test_name_collision() -> None: broken_model = Model() with pytest.raises(KeyError): broken_model.read_config("test/test_model_breaking.cfg") @pytest.mark.unit def test_subsystems() -> None: assert list(model.subsystems.keys()) == ["Q1", "Q2", "Q3", "Q4", "Q5", "Q6"]
instr2 = Instruction( 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():
def test_save_and_load(): global instr, pmap instr = Instruction() instr.from_dict(hjson.loads(instr_dict_str, object_pairs_hook=hjson_decode)) pmap = ParameterMap(model=model, generator=generator, instructions=[instr]) test_extended_pulse()
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()
instr.add_component(copy.deepcopy(gauss_env_single), "d2", name="gaussd2_1") instr.add_component( 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,
def setup_pmap() -> ParameterMap: t_final = 7e-9 # Time for single qubit gates sideband = 50e6 lo_freq = 5e9 + sideband # ### MAKE GATESET gauss_params_single = { "amp": Quantity(value=0.45, min_val=0.4, max_val=0.6, unit="V"), "t_final": Quantity(value=t_final, min_val=0.5 * t_final, max_val=1.5 * t_final, unit="s"), "sigma": Quantity(value=t_final / 4, min_val=t_final / 8, max_val=t_final / 2, unit="s"), "xy_angle": Quantity(value=0.0, min_val=-0.5 * np.pi, max_val=2.5 * np.pi, unit="rad"), "freq_offset": Quantity(value=-sideband - 0.5e6, min_val=-53 * 1e6, max_val=-47 * 1e6, unit="Hz 2pi"), "delta": Quantity(value=-1, min_val=-5, max_val=3, unit=""), } gauss_env_single = Envelope( name="gauss", desc="Gaussian comp for single-qubit gates", params=gauss_params_single, shape=envelopes.gaussian_nonorm, ) nodrive_env = Envelope( name="no_drive", params={ "t_final": Quantity(value=t_final, min_val=0.5 * t_final, max_val=1.5 * t_final, unit="s") }, shape=envelopes.no_drive, ) carrier_parameters = { "freq": Quantity(value=lo_freq, min_val=4.5e9, max_val=6e9, unit="Hz 2pi"), "framechange": Quantity(value=0.0, min_val=-np.pi, max_val=3 * np.pi, unit="rad"), } carr = Carrier( name="carrier", desc="Frequency of the local oscillator", params=carrier_parameters, ) RX90p = Instruction(name="RX90p", t_start=0.0, t_end=t_final, channels=["d1"]) QId = Instruction(name="Id", t_start=0.0, t_end=t_final, channels=["d1"]) RX90p.add_component(gauss_env_single, "d1") RX90p.add_component(carr, "d1") QId.add_component(nodrive_env, "d1") QId.add_component(copy.deepcopy(carr), "d1") QId.comps["d1"]["carrier"].params["framechange"].set_value( (-sideband * t_final) % (2 * np.pi)) RY90p = copy.deepcopy(RX90p) RY90p.name = "RY90p" RX90m = copy.deepcopy(RX90p) RX90m.name = "RX90m" RY90m = copy.deepcopy(RX90p) RY90m.name = "RY90m" RY90p.comps["d1"]["gauss"].params["xy_angle"].set_value(0.5 * np.pi) RX90m.comps["d1"]["gauss"].params["xy_angle"].set_value(np.pi) RY90m.comps["d1"]["gauss"].params["xy_angle"].set_value(1.5 * np.pi) parameter_map = ParameterMap( instructions=[QId, RX90p, RY90p, RX90m, RY90m]) gateset_opt_map = [ [ ("RX90p", "d1", "gauss", "amp"), ("RY90p", "d1", "gauss", "amp"), ("RX90m", "d1", "gauss", "amp"), ("RY90m", "d1", "gauss", "amp"), ], [ ("RX90p", "d1", "gauss", "delta"), ("RY90p", "d1", "gauss", "delta"), ("RX90m", "d1", "gauss", "delta"), ("RY90m", "d1", "gauss", "delta"), ], [ ("RX90p", "d1", "gauss", "freq_offset"), ("RY90p", "d1", "gauss", "freq_offset"), ("RX90m", "d1", "gauss", "freq_offset"), ("RY90m", "d1", "gauss", "freq_offset"), ], [("Id", "d1", "carrier", "framechange")], ] parameter_map.set_opt_map(gateset_opt_map) return parameter_map
raise Exception(f"Config {opt_config} is invalid.") 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"]
def quick_setup(self, filepath: str) -> None: """ Load a quick setup file and create all necessary components. Parameters ---------- filepath : str Location of the configuration file """ with open(filepath, "r") as cfg_file: cfg = hjson.loads(cfg_file.read()) model = Model() model.read_config(cfg["model"]) gen = Generator() gen.read_config(cfg["generator"]) single_gate_time = cfg["single_qubit_gate_time"] v2hz = cfg["v2hz"] instructions = [] sideband = cfg.pop("sideband", None) for gate_name, props in cfg["single_qubit_gates"].items(): target_qubit = model.subsystems[props["target_qubit"]] instr = Instruction( name=gate_name, t_start=0.0, t_end=single_gate_time, channels=[target_qubit.drive_line], ) instr.quick_setup( target_qubit.drive_line, target_qubit.params["freq"].get_value() / 2 / np.pi, single_gate_time, v2hz, sideband, ) instructions.append(instr) for gate_name, props in cfg["two_qubit_gates"].items(): qubit_1 = model.subsystems[props["qubit_1"]] qubit_2 = model.subsystems[props["qubit_2"]] instr = Instruction( name=gate_name, t_start=0.0, t_end=props["gate_time"], channels=[qubit_1.drive_line, qubit_2.drive_line], ) instr.quick_setup( qubit_1.drive_line, qubit_1.params["freq"].get_value() / 2 / np.pi, props["gate_time"], v2hz, sideband, ) instr.quick_setup( qubit_2.drive_line, qubit_2.params["freq"].get_value() / 2 / np.pi, props["gate_time"], v2hz, sideband, ) instructions.append(instr) self.pmap = ParameterMap(instructions, generator=gen, model=model)
def setup_pmap() -> ParameterMap: t_final = 7e-9 # Time for single qubit gates sideband = 50e6 lo_freq = 5e9 + sideband # ### MAKE GATESET gauss_params_single = { 'amp': Quantity(value=0.45, min_val=0.4, max_val=0.6, unit="V"), 't_final': Quantity(value=t_final, min_val=0.5 * t_final, max_val=1.5 * t_final, unit="s"), 'sigma': Quantity(value=t_final / 4, min_val=t_final / 8, max_val=t_final / 2, unit="s"), 'xy_angle': Quantity(value=0.0, min_val=-0.5 * np.pi, max_val=2.5 * np.pi, unit='rad'), 'freq_offset': Quantity(value=-sideband - 0.5e6, min_val=-53 * 1e6, max_val=-47 * 1e6, unit='Hz 2pi'), 'delta': Quantity(value=-1, min_val=-5, max_val=3, unit="") } gauss_env_single = Envelope(name="gauss", desc="Gaussian comp for single-qubit gates", params=gauss_params_single, shape=envelopes.gaussian_nonorm) nodrive_env = Envelope(name="no_drive", params={ 't_final': Quantity(value=t_final, min_val=0.5 * t_final, max_val=1.5 * t_final, unit="s") }, shape=envelopes.no_drive) carrier_parameters = { 'freq': Quantity(value=lo_freq, min_val=4.5e9, max_val=6e9, unit='Hz 2pi'), 'framechange': Quantity(value=0.0, min_val=-np.pi, max_val=3 * np.pi, unit='rad') } carr = Carrier(name="carrier", desc="Frequency of the local oscillator", params=carrier_parameters) X90p = Instruction(name="X90p", t_start=0.0, t_end=t_final, channels=["d1"]) QId = Instruction(name="Id", t_start=0.0, t_end=t_final, channels=["d1"]) X90p.add_component(gauss_env_single, "d1") X90p.add_component(carr, "d1") QId.add_component(nodrive_env, "d1") QId.add_component(copy.deepcopy(carr), "d1") QId.comps['d1']['carrier'].params['framechange'].set_value( (-sideband * t_final) % (2 * np.pi)) Y90p = copy.deepcopy(X90p) Y90p.name = "Y90p" X90m = copy.deepcopy(X90p) X90m.name = "X90m" Y90m = copy.deepcopy(X90p) Y90m.name = "Y90m" Y90p.comps['d1']['gauss'].params['xy_angle'].set_value(0.5 * np.pi) X90m.comps['d1']['gauss'].params['xy_angle'].set_value(np.pi) Y90m.comps['d1']['gauss'].params['xy_angle'].set_value(1.5 * np.pi) parameter_map = ParameterMap(instructions=[QId, X90p, Y90p, X90m, Y90m]) gateset_opt_map = [[("X90p", "d1", "gauss", "amp"), ("Y90p", "d1", "gauss", "amp"), ("X90m", "d1", "gauss", "amp"), ("Y90m", "d1", "gauss", "amp")], [("X90p", "d1", "gauss", "delta"), ("Y90p", "d1", "gauss", "delta"), ("X90m", "d1", "gauss", "delta"), ("Y90m", "d1", "gauss", "delta")], [("X90p", "d1", "gauss", "freq_offset"), ("Y90p", "d1", "gauss", "freq_offset"), ("X90m", "d1", "gauss", "freq_offset"), ("Y90m", "d1", "gauss", "freq_offset")], [("Id", "d1", "carrier", "framechange")]] parameter_map.set_opt_map(gateset_opt_map) return parameter_map
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: 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"), ], [
def quick_setup(self, cfg) -> None: """ Load a quick setup cfg and create all necessary components. Parameters ---------- cfg : Dict Configuration options """ model = Model() model.read_config(cfg["model"]) gen = Generator() gen.read_config(cfg["generator"]) single_gate_time = cfg["single_qubit_gate_time"] v2hz = cfg["v2hz"] instructions = [] sideband = cfg.pop("sideband", None) for gate_name, props in cfg["single_qubit_gates"].items(): target_qubit = model.subsystems[props["qubits"]] instr = Instruction( name=props["name"], targets=[model.names.index(props["qubits"])], t_start=0.0, t_end=single_gate_time, channels=[target_qubit.drive_line], ) instr.quick_setup( target_qubit.drive_line, target_qubit.params["freq"].get_value() / 2 / np.pi, single_gate_time, v2hz, sideband, ) instructions.append(instr) for gate_name, props in cfg["two_qubit_gates"].items(): qubit_1 = model.subsystems[props["qubit_1"]] qubit_2 = model.subsystems[props["qubit_2"]] instr = Instruction( name=gate_name, targets=[ model.names.index(props["qubit_1"]), model.names.index(props["qubit_2"]), ], t_start=0.0, t_end=props["gate_time"], channels=[qubit_1.drive_line, qubit_2.drive_line], ) instr.quick_setup( qubit_1.drive_line, qubit_1.params["freq"].get_value() / 2 / np.pi, props["gate_time"], v2hz, sideband, ) instr.quick_setup( qubit_2.drive_line, qubit_2.params["freq"].get_value() / 2 / np.pi, props["gate_time"], v2hz, sideband, ) instructions.append(instr) self.pmap = ParameterMap(instructions, generator=gen, model=model)