Exemple #1
0
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"]
Exemple #2
0
def pwc(model: Model, gen: Generator, instr: Instruction) -> Dict:
    """
    Solve the equation of motion (Lindblad or Schrรถdinger) for a given control
    signal and Hamiltonians.

    Parameters
    ----------
    signal: dict
        Waveform of the control signal per drive line.
    gate: str
        Identifier for one of the gates.

    Returns
    -------
    unitary
        Matrix representation of the gate.
    """
    signal = gen.generate_signals(instr)
    # Why do I get 0.0 if I print gen.resolution here?! FR
    ts = []
    if model.controllability:
        h0, hctrls = model.get_Hamiltonians()
        signals = []
        hks = []
        for key in signal:
            signals.append(signal[key]["values"])
            ts = signal[key]["ts"]
            hks.append(hctrls[key])
        signals = tf.cast(signals, tf.complex128)
        hks = tf.cast(hks, tf.complex128)
    else:
        h0 = model.get_Hamiltonian(signal)
        ts_list = [sig["ts"][1:] for sig in signal.values()]
        ts = tf.constant(tf.math.reduce_mean(ts_list, axis=0))
        hks = None
        signals = None
        if not np.all(
            tf.math.reduce_variance(ts_list, axis=0) < 1e-5 * (ts[1] - ts[0])
        ):
            raise Exception("C3Error:Something with the times happend.")
        if not np.all(
            tf.math.reduce_variance(ts[1:] - ts[:-1]) < 1e-5 * (ts[1] - ts[0])
        ):
            raise Exception("C3Error:Something with the times happend.")

    dt = tf.constant(ts[1].numpy() - ts[0].numpy(), dtype=tf.complex128)

    batch_size = tf.constant(len(h0), tf.int32)

    dUs = tf_batch_propagate(h0, hks, signals, dt, batch_size=batch_size)

    U = tf_matmul_left(tf.cast(dUs, tf.complex128))

    if model.max_excitations:
        U = model.blowup_excitations(tf_matmul_left(tf.cast(dUs, tf.complex128)))
        dUs = tf.vectorized_map(model.blowup_excitations, dUs)

    return {"U": U, "dUs": dUs, "ts": ts}
Exemple #3
0
 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
Exemple #4
0
def _get_hs_of_t_ts_controlled(
    model: Model, gen: Generator, instr: Instruction, prop_res=1
) -> Dict:
    """
    Return a Dict containing:

    - a list of

      H(t) = H_0 + sum_k c_k H_k.

    - time slices ts

    - timestep dt

    Parameters
    ----------
    prop_res : tf.float
        resolution required by the propagation method
    h0 : tf.tensor
        Drift Hamiltonian.
    hks : list of tf.tensor
        List of control Hamiltonians.
    cflds_t : array of tf.float
        Vector of control field values at time t.
    ts : float
        Length of one time slice.
    """
    Hs = []
    ts = []
    gen.resolution = prop_res * gen.resolution
    signal = gen.generate_signals(instr)
    h0, hctrls = model.get_Hamiltonians()
    signals = []
    hks = []
    for key in signal:
        signals.append(signal[key]["values"])
        ts = signal[key]["ts"]
        hks.append(hctrls[key])
    cflds = tf.cast(signals, tf.complex128)
    hks = tf.cast(hks, tf.complex128)
    for ii in range(cflds[0].shape[0]):
        cf_t = []
        for fields in cflds:
            cf_t.append(tf.cast(fields[ii], tf.complex128))
        Hs.append(sum_h0_hks(h0, hks, cf_t))

    dt = tf.constant(ts[1 * prop_res].numpy() - ts[0].numpy(), dtype=tf.complex128)
    return {"Hs": Hs, "ts": ts[::prop_res], "dt": dt}
Exemple #5
0
def rk4(model: Model, gen: Generator, instr: Instruction, init_state=None) -> Dict:
    prop_res = 2
    dim = model.tot_dim
    Hs = []
    ts = []
    dUs = []
    dict_vals = get_hs_of_t_ts(model, gen, instr, prop_res)
    Hs = dict_vals["Hs"]
    ts = dict_vals["ts"]
    dt = dict_vals["dt"]

    dUs = gen_dus_rk4(Hs, dt, dim)

    U = gen_u_rk4(Hs, dt, dim)

    if model.max_excitations:
        U = model.blowup_excitations(U)
        dUs = tf.vectorized_map(model.blowup_excitations, dUs)

    return {"U": U, "dUs": dUs, "ts": ts}
Exemple #6
0
def _get_hs_of_t_ts(
    model: Model, gen: Generator, instr: Instruction, prop_res=1
) -> Dict:
    """
    Return a Dict containing:

    - a list of

      H(t) = H_0 + sum_k c_k H_k.

    - time slices ts

    - timestep dt

    Parameters
    ----------
    prop_res : tf.float
        resolution required by the propagation method
    h0 : tf.tensor
        Drift Hamiltonian.
    hks : list of tf.tensor
        List of control Hamiltonians.
    cflds_t : array of tf.float
        Vector of control field values at time t.
    ts : float
        Length of one time slice.
    """
    Hs = []
    ts = []
    gen.resolution = prop_res * gen.resolution
    signal = gen.generate_signals(instr)
    Hs = model.get_Hamiltonian(signal)
    ts_list = [sig["ts"][1:] for sig in signal.values()]
    ts = tf.constant(tf.math.reduce_mean(ts_list, axis=0))
    if not np.all(tf.math.reduce_variance(ts_list, axis=0) < 1e-5 * (ts[1] - ts[0])):
        raise Exception("C3Error:Something with the times happend.")
    if not np.all(tf.math.reduce_variance(ts[1:] - ts[:-1]) < 1e-5 * (ts[1] - ts[0])):
        raise Exception("C3Error:Something with the times happend.")

    dt = tf.constant(ts[1 * prop_res].numpy() - ts[0].numpy(), dtype=tf.complex128)
    return {"Hs": Hs, "ts": ts[::prop_res], "dt": dt}
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 = 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(
    [S],  # Individual, self-contained components
    [drive],  # Interactions between components
    [conf_matrix, init_ground],  # SPAM processing
)

model.set_dressed(False)

hdrift, hks = model.get_Hamiltonians()


@pytest.mark.unit
def test_SNAIL_eigenfrequencies_1() -> None:
    "Eigenfrequency of SNAIL"
    assert (hdrift[1, 1] - hdrift[0, 0] == freq_S * 2 * np.pi
            )  # for the 0.2dev version, comment out the 2 pi

Exemple #8
0
def test_name_collision() -> None:
    broken_model = Model()
    with pytest.raises(KeyError):
        broken_model.read_config("test/test_model_breaking.cfg")
Exemple #9
0
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"]

Exemple #10
0
def create_experiment():
    lindblad = False
    dressed = True
    qubit_lvls = 3
    freq_q1 = 5e9 * 2 * np.pi
    freq_q2 = 5.6e9 * 2 * np.pi
    anhar_q1 = -210e6 * 2 * np.pi
    anhar_q2 = -240e6 * 2 * np.pi
    coupling_strength = 20e6 * 2 * np.pi
    t1_q1 = 27e-6
    t1_q2 = 23e-6
    t2star_q1 = 39e-6
    t2star_q2 = 31e-6
    init_temp = 0
    qubit_temp = 0
    t_final = 7e-9  # Time for single qubit gates
    sim_res = 100e9
    awg_res = 2e9
    sideband = 50e6 * 2 * np.pi
    lo_freq_q1 = 5e9 * 2 * np.pi + sideband
    lo_freq_q2 = 5.6e9 * 2 * np.pi + sideband

    # ### MAKE MODEL
    q1 = chip.Qubit(
        name="Q1",
        desc="Qubit 1",
        freq=Qty(
            value=freq_q1,
            min_val=4.995e9 * 2 * np.pi,
            max_val=5.005e9 * 2 * np.pi,
            unit="Hz 2pi",
        ),
        anhar=Qty(
            value=anhar_q1,
            min_val=-380e6 * 2 * np.pi,
            max_val=-120e6 * 2 * np.pi,
            unit="Hz 2pi",
        ),
        hilbert_dim=qubit_lvls,
        t1=Qty(value=t1_q1, min_val=1e-6, max_val=90e-6, unit="s"),
        t2star=Qty(value=t2star_q1, min_val=10e-6, max_val=90e-6, unit="s"),
        temp=Qty(value=qubit_temp, min_val=0.0, max_val=0.12, unit="K"),
    )
    q2 = chip.Qubit(
        name="Q2",
        desc="Qubit 2",
        freq=Qty(
            value=freq_q2,
            min_val=5.595e9 * 2 * np.pi,
            max_val=5.605e9 * 2 * np.pi,
            unit="Hz 2pi",
        ),
        anhar=Qty(
            value=anhar_q2,
            min_val=-380e6 * 2 * np.pi,
            max_val=-120e6 * 2 * np.pi,
            unit="Hz 2pi",
        ),
        hilbert_dim=qubit_lvls,
        t1=Qty(value=t1_q2, min_val=1e-6, max_val=90e-6, unit="s"),
        t2star=Qty(value=t2star_q2, min_val=10e-6, max_val=90e-6, unit="s"),
        temp=Qty(value=qubit_temp, min_val=0.0, max_val=0.12, unit="K"),
    )

    q1q2 = chip.Coupling(
        name="Q1-Q2",
        desc="coupling",
        comment="Coupling qubit 1 to qubit 2",
        connected=["Q1", "Q2"],
        strength=Qty(
            value=coupling_strength,
            min_val=-1 * 1e3 * 2 * np.pi,
            max_val=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,
    )
    phys_components = [q1, q2]
    line_components = [drive, drive2, q1q2]

    init_ground = tasks.InitialiseGround(
        init_temp=Qty(value=init_temp, min_val=-0.001, max_val=0.22, unit="K"))
    task_list = [init_ground]
    model = Mdl(phys_components, line_components, task_list)
    model.set_lindbladian(lindblad)
    model.set_dressed(dressed)

    # ### MAKE GENERATOR
    generator = Gnr(
        devices={
            "LO":
            devices.LO(name="lo", resolution=sim_res, outputs=1),
            "AWG":
            devices.AWG(name="awg", resolution=awg_res, outputs=1),
            "DigitalToAnalog":
            devices.DigitalToAnalog(name="dac",
                                    resolution=sim_res,
                                    inputs=1,
                                    outputs=1),
            "Response":
            devices.Response(
                name="resp",
                rise_time=Qty(value=0.3e-9,
                              min_val=0.05e-9,
                              max_val=0.6e-9,
                              unit="s"),
                resolution=sim_res,
                inputs=1,
                outputs=1,
            ),
            "Mixer":
            devices.Mixer(name="mixer", inputs=2, outputs=1),
            "VoltsToHertz":
            devices.VoltsToHertz(
                name="v_to_hz",
                V_to_Hz=Qty(value=1e9,
                            min_val=0.9e9,
                            max_val=1.1e9,
                            unit="Hz/V"),
                inputs=1,
                outputs=1,
            ),
        },
        chains={
            "d1": {
                "LO": [],
                "AWG": [],
                "DigitalToAnalog": ["AWG"],
                "Response": ["DigitalToAnalog"],
                "Mixer": ["LO", "Response"],
                "VoltsToHertz": ["Mixer"],
            },
            "d2": {
                "LO": [],
                "AWG": [],
                "DigitalToAnalog": ["AWG"],
                "Response": ["DigitalToAnalog"],
                "Mixer": ["LO", "Response"],
                "VoltsToHertz": ["Mixer"],
            },
        },
    )
    generator.devices["awg"].enable_drag_2()

    # ### MAKE GATESET
    gateset = gates.GateSet()
    gauss_params_single = {
        "amp":
        Qty(value=0.45, min_val=0.4, max_val=0.6, unit="V"),
        "t_final":
        Qty(value=t_final,
            min_val=0.5 * t_final,
            max_val=1.5 * t_final,
            unit="s"),
        "sigma":
        Qty(value=t_final / 4,
            min_val=t_final / 8,
            max_val=t_final / 2,
            unit="s"),
        "xy_angle":
        Qty(value=0.0, min_val=-0.5 * np.pi, max_val=2.5 * np.pi, unit="rad"),
        "freq_offset":
        Qty(
            value=-sideband - 0.5e6 * 2 * np.pi,
            min_val=-53 * 1e6 * 2 * np.pi,
            max_val=-47 * 1e6 * 2 * np.pi,
            unit="Hz 2pi",
        ),
        "delta":
        Qty(value=-1, min_val=-5, max_val=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_val=0.5 * t_final,
                max_val=1.5 * t_final,
                unit="s")
        },
        shape=envelopes.no_drive,
    )
    carrier_parameters = {
        "freq":
        Qty(
            value=lo_freq_q1,
            min_val=4.5e9 * 2 * np.pi,
            max_val=6e9 * 2 * np.pi,
            unit="Hz 2pi",
        ),
        "framechange":
        Qty(value=0.0, min_val=-np.pi, max_val=3 * np.pi, unit="rad"),
    }
    carr = pulse.Carrier(
        name="carrier",
        desc="Frequency of the local oscillator",
        params=carrier_parameters,
    )
    carr_2 = copy.deepcopy(carr)
    carr_2.params["freq"].set_value(lo_freq_q2)

    RX90p_q1 = gates.Instruction(name="RX90p",
                                 t_start=0.0,
                                 t_end=t_final,
                                 channels=["d1"])
    RX90p_q2 = gates.Instruction(name="RX90p",
                                 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"])

    RX90p_q1.add_component(gauss_env_single, "d1")
    RX90p_q1.add_component(carr, "d1")
    QId_q1.add_component(nodrive_env, "d1")
    QId_q1.add_component(copy.deepcopy(carr), "d1")
    QId_q1.comps["d1"]["carrier"].params["framechange"].set_value(
        (-sideband * t_final) % (2 * np.pi))
    Y90p_q1 = copy.deepcopy(RX90p_q1)
    Y90p_q1.name = "RY90p"
    X90m_q1 = copy.deepcopy(RX90p_q1)
    X90m_q1.name = "RX90m"
    Y90m_q1 = copy.deepcopy(RX90p_q1)
    Y90m_q1.name = "RY90m"
    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, RX90p_q1, Y90p_q1, X90m_q1, Y90m_q1]

    RX90p_q2.add_component(copy.deepcopy(gauss_env_single), "d2")
    RX90p_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_q2.comps["d2"]["carrier"].params["framechange"].set_value(
        (-sideband * t_final) % (2 * np.pi))
    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)
    Q2_gates = [QId_q2, RX90p_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)

    # ### MAKE EXPERIMENT
    exp = Exp(model=model, generator=generator, gateset=gateset)
    return exp
Exemple #11
0
zero_ones[0] = 0
val1 = one_zeros * m00_q1 + zero_ones * m01_q1
val2 = one_zeros * m00_q2 + zero_ones * m01_q2
min_val = one_zeros * 0.8 + zero_ones * 0.0
max_val = one_zeros * 1.0 + zero_ones * 0.2
confusion_row1 = Qty(value=val1, min_val=min_val, max_val=max_val, unit="")
confusion_row2 = Qty(value=val2, min_val=min_val, max_val=max_val, 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_val=-0.001, max_val=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

generator = Gnr(
    devices={
        "LO":
        devices.LO(name="lo", resolution=sim_res, outputs=1),
        "AWG":
        devices.AWG(name="awg", resolution=awg_res, outputs=1),
    # t2star=Qty(value=t2star_tc, min_val=1e-6, max_val=90e-6, unit="s"),
    # temp=Qty(value=init_temp, min_val=0.0, max_val=0.12, unit="K"),
)

q1q2 = Coupling(
    name="Q1-Q2",
    connected=["Qubit1", "Qubit2"],
    strength=Qty(value=coupling_strength,
                 min_val=0 * 1e4,
                 max_val=200e6,
                 unit="Hz 2pi"),
    hamiltonian_func=hamiltonians.int_XX,
)

model = Model(subsystems=[q1, q2],
              couplings=[q1q2],
              max_excitations=cut_excitations)
model.set_lindbladian(False)
model.set_dressed(True)
model.set_FR(True)

# ### MAKE GENERATOR
lo = devices.LO(name="lo", resolution=sim_res)
awg = devices.AWG(name="awg", resolution=awg_res)
dig_to_an = devices.DigitalToAnalog(name="dac", resolution=sim_res)
resp = devices.ResponseFFT(
    name="resp",
    rise_time=Qty(value=0.3e-9, min_val=0.05e-9, max_val=0.6e-9, unit="s"),
    resolution=sim_res,
)
mixer = devices.Mixer(name="mixer")
def create_experiment():
    lindblad = False
    dressed = True
    qubit_lvls = 3
    freq = 5e9
    anhar = -210e6
    init_temp = 0
    qubit_temp = 0
    t_final = 7e-9  # Time for single qubit gates
    sim_res = 100e9
    awg_res = 2e9
    sideband = 50e6
    lo_freq = 5e9 + sideband

    # ### MAKE MODEL
    q1 = chip.Qubit(
        name="Q1",
        desc="Qubit 1",
        freq=Qty(
            value=freq,
            min_val=4.995e9,
            max_val=5.005e9,
            unit="Hz 2pi",
        ),
        anhar=Qty(
            value=anhar,
            min_val=-380e6,
            max_val=-120e6,
            unit="Hz 2pi",
        ),
        hilbert_dim=qubit_lvls,
        temp=Qty(value=qubit_temp, min_val=0.0, max_val=0.12, unit="K"),
    )

    drive = chip.Drive(
        name="d1",
        desc="Drive 1",
        comment="Drive line 1 on qubit 1",
        connected=["Q1"],
        hamiltonian_func=hamiltonians.x_drive,
    )
    phys_components = [q1]
    line_components = [drive]

    init_ground = tasks.InitialiseGround(
        init_temp=Qty(value=init_temp, min_val=-0.001, max_val=0.22, unit="K"))
    task_list = [init_ground]
    model = Mdl(phys_components, line_components, task_list)
    model.set_lindbladian(lindblad)
    model.set_dressed(dressed)

    # ### MAKE GENERATOR
    generator = Gnr(
        devices={
            "LO":
            devices.LO(name="lo", resolution=sim_res, outputs=1),
            "AWG":
            devices.AWG(name="awg", resolution=awg_res, outputs=1),
            "DigitalToAnalog":
            devices.DigitalToAnalog(name="dac",
                                    resolution=sim_res,
                                    inputs=1,
                                    outputs=1),
            "Response":
            devices.Response(
                name="resp",
                rise_time=Qty(value=0.3e-9,
                              min_val=0.05e-9,
                              max_val=0.6e-9,
                              unit="s"),
                resolution=sim_res,
                inputs=1,
                outputs=1,
            ),
            "Mixer":
            devices.Mixer(name="mixer", inputs=2, outputs=1),
            "VoltsToHertz":
            devices.VoltsToHertz(
                name="v_to_hz",
                V_to_Hz=Qty(value=1e9,
                            min_val=0.9e9,
                            max_val=1.1e9,
                            unit="Hz/V"),
                inputs=1,
                outputs=1,
            ),
        },
        chains={
            "d1": {
                "LO": [],
                "AWG": [],
                "DigitalToAnalog": ["AWG"],
                "Response": ["DigitalToAnalog"],
                "Mixer": ["LO", "Response"],
                "VoltsToHertz": ["Mixer"],
            }
        },
    )
    generator.devices["AWG"].enable_drag_2()

    # ### MAKE GATESET
    gauss_params_single = {
        "amp":
        Qty(value=0.45, min_val=0.4, max_val=0.6, unit="V"),
        "t_final":
        Qty(value=t_final,
            min_val=0.5 * t_final,
            max_val=1.5 * t_final,
            unit="s"),
        "sigma":
        Qty(value=t_final / 4,
            min_val=t_final / 8,
            max_val=t_final / 2,
            unit="s"),
        "xy_angle":
        Qty(value=0.0, min_val=-0.5 * np.pi, max_val=2.5 * np.pi, unit="rad"),
        "freq_offset":
        Qty(
            value=-sideband - 0.5e6,
            min_val=-60 * 1e6,
            max_val=-40 * 1e6,
            unit="Hz 2pi",
        ),
        "delta":
        Qty(value=-1, min_val=-5, max_val=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_val=0.5 * t_final,
                max_val=1.5 * t_final,
                unit="s")
        },
        shape=envelopes.no_drive,
    )
    carrier_parameters = {
        "freq":
        Qty(
            value=lo_freq,
            min_val=4.5e9,
            max_val=6e9,
            unit="Hz 2pi",
        ),
        "framechange":
        Qty(value=0.0, min_val=-np.pi, max_val=3 * np.pi, unit="rad"),
    }
    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"],
                              targets=[0])
    QId = gates.Instruction(name="id",
                            t_start=0.0,
                            t_end=t_final,
                            channels=["d1"],
                            targets=[0])

    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 = PMap(instructions=[QId, rx90p, ry90p, rx90m, ry90m],
                         model=model,
                         generator=generator)

    # ### MAKE EXPERIMENT
    exp = Exp(pmap=parameter_map)
    return exp
Exemple #14
0
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()
Exemple #15
0
    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)
Exemple #16
0
drive_q2 = chip.Drive(
    name="Q2",
    desc="Drive on Q2",
    connected=["Qubit2"],
    hamiltonian_func=hamiltonians.x_drive,
)
flux = chip.Drive(
    name="TC",
    desc="Flux drive/control on tunable couler",
    connected=["TCQubit"],
    hamiltonian_func=hamiltonians.z_drive,
)
phys_components = [tc_at, q1, q2]
line_components = [q1tc, q2tc, q1q2, drive_q1, drive_q2, flux]

model = Mdl(phys_components, line_components, [])
model.set_lindbladian(lindblad)
model.set_dressed(dressed)

# ### MAKE GENERATOR
lo = devices.LO(name="lo", resolution=sim_res)
awg = devices.AWG(name="awg", resolution=awg_res)
dig_to_an = devices.DigitalToAnalog(name="dac", resolution=sim_res)
resp = devices.Response(
    name="resp",
    rise_time=Qty(value=0.3e-9, min_val=0.05e-9, max_val=0.6e-9, unit="s"),
    resolution=sim_res,
)
mixer = devices.Mixer(name="mixer")
fluxbias = devices.FluxTuning(
    name="fluxbias",