def test_rare_cases(): reg = Register.square(4) seq = Sequence(reg, Chadoq2) var = seq.declare_variable("var") wf = BlackmanWaveform(100, var) with pytest.warns(UserWarning, match="Calls to methods of parametrized " "objects"): s = encode(wf.draw()) with pytest.warns(UserWarning, match="not encode a Sequence"): wf_ = Sequence.deserialize(s) var._assign(-10) with pytest.raises(ValueError, match="No value assigned"): wf_.build() var_ = wf_._variables["var"] var_._assign(-10) with patch('matplotlib.pyplot.show'): wf_.build() rotated_reg = parametrize(Register.rotate)(reg, var) with pytest.raises(NotImplementedError): encode(rotated_reg)
def test_dephasing(): np.random.seed(123) reg = Register.from_coordinates([(0, 0)], prefix="q") seq = Sequence(reg, Chadoq2) seq.declare_channel("ch0", "rydberg_global") duration = 2500 pulse = Pulse.ConstantPulse(duration, np.pi, 0.0 * 2 * np.pi, 0) seq.add(pulse, "ch0") sim = Simulation(seq, sampling_rate=0.01, config=SimConfig(noise="dephasing")) assert sim.run().sample_final_state() == Counter({"0": 595, "1": 405}) assert len(sim._collapse_ops) != 0 with pytest.warns(UserWarning, match="first-order"): reg = Register.from_coordinates([(0, 0), (0, 10)], prefix="q") seq2 = Sequence(reg, Chadoq2) seq2.declare_channel("ch0", "rydberg_global") duration = 2500 pulse = Pulse.ConstantPulse(duration, np.pi, 0.0 * 2 * np.pi, 0) seq2.add(pulse, "ch0") sim = Simulation( seq2, sampling_rate=0.01, config=SimConfig(noise="dephasing", dephasing_prob=0.5), )
def test_build(): reg_ = Register.rectangle(2, 1, prefix="q") sb = Sequence(reg_, device) var = sb.declare_variable("var") targ_var = sb.declare_variable("targ_var", size=2, dtype=int) sb.declare_channel("ch1", "rydberg_local") sb.declare_channel("ch2", "raman_local") sb.target_index(targ_var[0], "ch2") sb.target_index(targ_var[1], "ch1") wf = BlackmanWaveform(var * 100, np.pi) pls = Pulse.ConstantDetuning(wf, var, var) sb.add(pls, "ch1") sb.delay(var * 50, "ch1") sb.align("ch2", "ch1") sb.phase_shift_index(var, targ_var[0]) pls2 = Pulse.ConstantPulse(var * 100, var, var, 0) sb.add(pls2, "ch2") sb.measure() with pytest.warns(UserWarning, match="No declared variables"): sb.build(t=100, var=2, targ_var=reg_.find_indices(["q1", "q0"])) with pytest.raises(TypeError, match="Did not receive values for"): sb.build(var=2) seq = sb.build(var=2, targ_var=reg_.find_indices(["q1", "q0"])) assert seq._schedule["ch2"][-1].tf == 500 assert seq.current_phase_ref("q1") == 2.0 assert seq.current_phase_ref("q0") == 0.0 assert seq._measurement == "ground-rydberg" s = sb.serialize() sb_ = Sequence.deserialize(s) assert str(sb) == str(sb_) s2 = sb_.serialize() sb_2 = Sequence.deserialize(s2) assert str(sb) == str(sb_2)
def test_rare_cases(): reg = Register.square(4) seq = Sequence(reg, Chadoq2) var = seq.declare_variable("var") wf = BlackmanWaveform(var * 100 // 10, var) with pytest.raises( ValueError, match="Serialization of calls to parametrized objects" ): s = encode(wf.draw()) s = encode(wf) with pytest.raises(ValueError, match="not encode a Sequence"): wf_ = Sequence.deserialize(s) wf_ = decode(s) seq._variables["var"]._assign(-10) with pytest.raises(ValueError, match="No value assigned"): wf_.build() var_ = wf_._variables["var"] var_._assign(10) assert wf_.build() == BlackmanWaveform(100, 10) with pytest.warns(UserWarning, match="Serialization of 'getattr'"): draw_func = wf_.draw with patch("matplotlib.pyplot.show"): with pytest.warns( UserWarning, match="Calls to methods of parametrized objects" ): draw_func().build() rotated_reg = parametrize(Register.rotate)(reg, var) with pytest.raises(NotImplementedError): encode(rotated_reg)
def test_building_basis_and_projection_operators(): # All three levels: sim = Simulation(seq, sampling_rate=0.01) assert sim.basis_name == 'all' assert sim.dim == 3 assert sim.basis == { 'r': qutip.basis(3, 0), 'g': qutip.basis(3, 1), 'h': qutip.basis(3, 2) } assert (sim.op_matrix['sigma_rr'] == qutip.basis(3, 0) * qutip.basis(3, 0).dag()) assert (sim.op_matrix['sigma_gr'] == qutip.basis(3, 1) * qutip.basis(3, 0).dag()) assert (sim.op_matrix['sigma_hg'] == qutip.basis(3, 2) * qutip.basis(3, 1).dag()) # Check local operator building method: with pytest.raises(ValueError, match="Duplicate atom"): sim._build_operator('sigma_gg', "target", "target") # Global ground-rydberg seq2 = Sequence(reg, Chadoq2) seq2.declare_channel('global', 'rydberg_global') seq2.add(pi, 'global') sim2 = Simulation(seq2, sampling_rate=0.01) assert sim2.basis_name == 'ground-rydberg' assert sim2.dim == 2 assert sim2.basis == {'r': qutip.basis(2, 0), 'g': qutip.basis(2, 1)} assert (sim2.op_matrix['sigma_rr'] == qutip.basis(2, 0) * qutip.basis(2, 0).dag()) assert (sim2.op_matrix['sigma_gr'] == qutip.basis(2, 1) * qutip.basis(2, 0).dag()) # Digital seq2b = Sequence(reg, Chadoq2) seq2b.declare_channel('local', 'raman_local', 'target') seq2b.add(pi, 'local') sim2b = Simulation(seq2b, sampling_rate=0.01) assert sim2b.basis_name == 'digital' assert sim2b.dim == 2 assert sim2b.basis == {'g': qutip.basis(2, 0), 'h': qutip.basis(2, 1)} assert (sim2b.op_matrix['sigma_gg'] == qutip.basis(2, 0) * qutip.basis(2, 0).dag()) assert (sim2b.op_matrix['sigma_hg'] == qutip.basis(2, 1) * qutip.basis(2, 0).dag()) # Local ground-rydberg seq2c = Sequence(reg, Chadoq2) seq2c.declare_channel('local_ryd', 'rydberg_local', 'target') seq2c.add(pi, 'local_ryd') sim2c = Simulation(seq2c, sampling_rate=0.01) assert sim2c.basis_name == 'ground-rydberg' assert sim2c.dim == 2 assert sim2c.basis == {'r': qutip.basis(2, 0), 'g': qutip.basis(2, 1)} assert (sim2c.op_matrix['sigma_rr'] == qutip.basis(2, 0) * qutip.basis(2, 0).dag()) assert (sim2c.op_matrix['sigma_gr'] == qutip.basis(2, 1) * qutip.basis(2, 0).dag())
def test_config_slm_mask(): reg_s = Register({"q0": (0, 0), "q1": (10, 10), "q2": (-10, -10)}) seq_s = Sequence(reg_s, device) with pytest.raises(TypeError, match="must be castable to set"): seq_s.config_slm_mask(0) with pytest.raises(TypeError, match="must be castable to set"): seq_s.config_slm_mask((0)) with pytest.raises(ValueError, match="exist in the register"): seq_s.config_slm_mask("q0") with pytest.raises(ValueError, match="exist in the register"): seq_s.config_slm_mask(["q3"]) with pytest.raises(ValueError, match="exist in the register"): seq_s.config_slm_mask(("q3", )) with pytest.raises(ValueError, match="exist in the register"): seq_s.config_slm_mask({"q3"}) with pytest.raises(ValueError, match="exist in the register"): seq_s.config_slm_mask([0]) with pytest.raises(ValueError, match="exist in the register"): seq_s.config_slm_mask((0, )) with pytest.raises(ValueError, match="exist in the register"): seq_s.config_slm_mask({0}) targets_s = ["q0", "q2"] seq_s.config_slm_mask(targets_s) assert seq_s._slm_mask_targets == {"q0", "q2"} with pytest.raises(ValueError, match="configured only once"): seq_s.config_slm_mask(targets_s) reg_i = Register({0: (0, 0), 1: (10, 10), 2: (-10, -10)}) seq_i = Sequence(reg_i, device) with pytest.raises(TypeError, match="must be castable to set"): seq_i.config_slm_mask(0) with pytest.raises(TypeError, match="must be castable to set"): seq_i.config_slm_mask((0)) with pytest.raises(ValueError, match="exist in the register"): seq_i.config_slm_mask("q0") with pytest.raises(ValueError, match="exist in the register"): seq_i.config_slm_mask([3]) with pytest.raises(ValueError, match="exist in the register"): seq_i.config_slm_mask((3, )) with pytest.raises(ValueError, match="exist in the register"): seq_i.config_slm_mask({3}) with pytest.raises(ValueError, match="exist in the register"): seq_i.config_slm_mask(["0"]) with pytest.raises(ValueError, match="exist in the register"): seq_i.config_slm_mask(("0", )) with pytest.raises(ValueError, match="exist in the register"): seq_i.config_slm_mask({"0"}) targets_i = [0, 2] seq_i.config_slm_mask(targets_i) assert seq_i._slm_mask_targets == {0, 2} with pytest.raises(ValueError, match="configured only once"): seq_i.config_slm_mask(targets_i)
def test_init(): fake_device = PasqalDevice("fake", 2, 10, 10, 1, Chadoq2._channels) with pytest.raises(ValueError, match='imported from pasqal.devices'): Sequence(reg, fake_device) seq = Sequence(reg, device) assert seq.qubit_info == reg.qubits assert seq.declared_channels == {} assert seq.available_channels.keys() == device.channels.keys()
def test_init(): with pytest.raises(TypeError, match="must be of type 'Device'"): Sequence(reg, Device) fake_device = Device("fake", 2, 70, 100, 100, 1, Chadoq2._channels) with pytest.warns(UserWarning, match="imported from 'pulser.devices'"): Sequence(reg, fake_device) seq = Sequence(reg, device) assert seq.qubit_info == reg.qubits assert seq.declared_channels == {} assert seq.available_channels.keys() == device.channels.keys()
def test_empty_sequences(): seq = Sequence(reg, MockDevice) with pytest.raises(ValueError, match="no declared channels"): Simulation(seq) seq.declare_channel("ch0", "mw_global") with pytest.raises(ValueError, match="No instructions given"): Simulation(seq) seq = Sequence(reg, MockDevice) seq.declare_channel("test", "rydberg_local", "target") seq.declare_channel("test2", "rydberg_global") with pytest.raises(ValueError, match="No instructions given"): Simulation(seq)
def test_mappable_register(): layout = RegisterLayout([[0, 0], [1, 1], [1, 0], [0, 1]]) mapp_reg = layout.make_mappable_register(2) new_mapp_reg = encode_decode(mapp_reg) assert new_mapp_reg.layout == layout assert new_mapp_reg.qubit_ids == ("q0", "q1") seq = Sequence(mapp_reg, MockDevice) assert seq.is_register_mappable() mapped_seq = seq.build(qubits={"q0": 2, "q1": 1}) assert not mapped_seq.is_register_mappable() new_mapped_seq = Sequence.deserialize(mapped_seq.serialize()) assert not new_mapped_seq.is_register_mappable()
def test_expect(): with pytest.raises(TypeError, match="must be a list"): results.expect("bad_observable") with pytest.raises(TypeError, match="Incompatible type"): results.expect(["bad_observable"]) with pytest.raises(ValueError, match="Incompatible shape"): results.expect([np.array(3)]) reg_single = Register.from_coordinates([(0, 0)], prefix="q") seq_single = Sequence(reg_single, Chadoq2) seq_single.declare_channel("ryd", "rydberg_global") seq_single.add(pi, "ryd") sim_single = Simulation(seq_single) results_single = sim_single.run() op = [qutip.basis(2, 0).proj()] exp = results_single.expect(op)[0] assert np.isclose(exp[-1], 1) assert len(exp) == duration + 1 # +1 for the final instant np.testing.assert_almost_equal( results_single._calc_pseudo_density(-1).full(), np.array([[1, 0], [0, 0]]), ) config = SimConfig(noise="SPAM", eta=0) sim_single.set_config(config) sim_single.evaluation_times = "Minimal" results_single = sim_single.run() exp = results_single.expect(op)[0] assert len(exp) == 2 assert isinstance(results_single, CoherentResults) assert results_single._meas_errors == { "epsilon": config.epsilon, "epsilon_prime": config.epsilon_prime, } # Probability of measuring 1 = probability of false positive assert np.isclose(exp[0], config.epsilon) # Probability of measuring 1 = 1 - probability of false negative assert np.isclose(exp[-1], 1 - config.epsilon_prime) np.testing.assert_almost_equal( results_single._calc_pseudo_density(-1).full(), np.array([[1 - config.epsilon_prime, 0], [0, config.epsilon_prime]]), ) seq3dim = Sequence(reg, Chadoq2) seq3dim.declare_channel("ryd", "rydberg_global") seq3dim.declare_channel("ram", "raman_local", initial_target="A") seq3dim.add(pi, "ram") seq3dim.add(pi, "ryd") sim3dim = Simulation(seq3dim) exp3dim = sim3dim.run().expect( [qutip.tensor(qutip.basis(3, 0).proj(), qutip.qeye(3))]) assert np.isclose(exp3dim[0][-1], 1.89690200e-14)
def test_target(): seq = Sequence(reg, device) seq.declare_channel('ch0', 'raman_local', initial_target='q1') seq.declare_channel('ch1', 'rydberg_global') with pytest.raises(ValueError, match='name of a declared channel'): seq.target('q0', 'ch2') with pytest.raises(ValueError, match='qubits have to belong'): seq.target(0, 'ch0') seq.target('0', 'ch1') with pytest.raises(ValueError, match="Can only choose target of 'Local'"): seq.target('q3', 'ch1') with pytest.raises(ValueError, match="can target at most 1 qubits"): seq.target(['q1', 'q5'], 'ch0') assert seq._schedule['ch0'][-1] == _TimeSlot('target', -1, 0, {'q1'}) seq.target('q4', 'ch0') retarget_t = seq.declared_channels['ch0'].retarget_time assert seq._schedule['ch0'][-1] == _TimeSlot('target', 0, retarget_t, {'q4'}) with pytest.warns(UserWarning): seq.target('q4', 'ch0') seq.target('q20', 'ch0') assert seq._schedule['ch0'][-1] == _TimeSlot('target', retarget_t, 2 * retarget_t, {'q20'}) seq.delay(216, 'ch0') seq.target('q2', 'ch0') ti = 2 * retarget_t + 216 tf = ti + 16 assert seq._schedule['ch0'][-1] == _TimeSlot('target', ti, tf, {'q2'}) seq.delay(220, 'ch0') seq.target('q1', 'ch0') ti = tf + 220 tf = ti assert seq._schedule['ch0'][-1] == _TimeSlot('target', ti, tf, {'q1'}) seq.delay(100, 'ch0') seq.target('q10', 'ch0') ti = tf + 100 tf = ti + 120 assert seq._schedule['ch0'][-1] == _TimeSlot('target', ti, tf, {'q10'}) seq2 = Sequence(reg, MockDevice) seq2.declare_channel('ch0', 'raman_local', initial_target={'q1', 'q10'}) seq2.phase_shift(1, 'q2') with pytest.raises(ValueError, match="qubits with different phase"): seq2.target({'q3', 'q1', 'q2'}, 'ch0')
def test_mask_two_pulses(): """Similar to test_mask_equals_remove, but with more pulses afterwards. Three global pulses act on a three qubit register, with one qubit masked during the first pulse. """ reg_three = Register({"q0": (0, 0), "q1": (10, 10), "q2": (-10, -10)}) reg_two = Register({"q0": (0, 0), "q1": (10, 10)}) pulse = Pulse.ConstantPulse(100, 10, 0, 0) no_pulse = Pulse.ConstantPulse(100, 0, 0, 0) for channel_type in ["mw_global", "rydberg_global", "raman_global"]: # Masked simulation seq_masked = Sequence(reg_three, MockDevice) seq_masked.declare_channel("ch_masked", channel_type) masked_qubits = ["q2"] seq_masked.config_slm_mask(masked_qubits) seq_masked.add(pulse, "ch_masked") # First pulse: masked seq_masked.add(pulse, "ch_masked") # Second pulse: unmasked seq_masked.add(pulse, "ch_masked") # Third pulse: unmasked sim_masked = Simulation(seq_masked) # Unmasked simulation on full register seq_three = Sequence(reg_three, MockDevice) seq_three.declare_channel("ch_three", channel_type) seq_three.add(no_pulse, "ch_three") seq_three.add(pulse, "ch_three") seq_three.add(pulse, "ch_three") sim_three = Simulation(seq_three) # Unmasked simulation on reduced register seq_two = Sequence(reg_two, MockDevice) seq_two.declare_channel("ch_two", channel_type) seq_two.add(pulse, "ch_two") seq_two.add(no_pulse, "ch_two") seq_two.add(no_pulse, "ch_two") sim_two = Simulation(seq_two) ti = seq_masked._slm_mask_time[0] tf = seq_masked._slm_mask_time[1] for t in sim_masked.sampling_times: ham_masked = sim_masked.get_hamiltonian(t) ham_three = sim_three.get_hamiltonian(t) ham_two = sim_two.get_hamiltonian(t) if ti <= t <= tf: assert ham_masked == qutip.tensor(ham_two, qutip.qeye(2)) else: assert ham_masked == ham_three
def test_target(): seq = Sequence(reg, device) seq.declare_channel("ch0", "raman_local", initial_target="q1") seq.declare_channel("ch1", "rydberg_global") with pytest.raises(ValueError, match="name of a declared channel"): seq.target("q0", "ch2") with pytest.raises(ValueError, match="ids have to be qubit ids"): seq.target(0, "ch0") with pytest.raises(ValueError, match="ids have to be qubit ids"): seq.target("0", "ch0") with pytest.raises(ValueError, match="Can only choose target of 'Local'"): seq.target("q3", "ch1") with pytest.raises(ValueError, match="can target at most 1 qubits"): seq.target(["q1", "q5"], "ch0") assert seq._schedule["ch0"][-1] == _TimeSlot("target", -1, 0, {"q1"}) seq.target("q4", "ch0") retarget_t = seq.declared_channels["ch0"].min_retarget_interval assert seq._schedule["ch0"][-1] == _TimeSlot("target", 0, retarget_t, {"q4"}) seq.target("q4", "ch0") # targets the same qubit seq.target("q20", "ch0") assert seq._schedule["ch0"][-1] == _TimeSlot("target", retarget_t, 2 * retarget_t, {"q20"}) seq.delay(216, "ch0") seq.target("q2", "ch0") ti = 2 * retarget_t + 216 tf = ti + 16 assert seq._schedule["ch0"][-1] == _TimeSlot("target", ti, tf, {"q2"}) seq.delay(220, "ch0") seq.target("q1", "ch0") ti = tf + 220 tf = ti assert seq._schedule["ch0"][-1] == _TimeSlot("target", ti, tf, {"q1"}) seq.delay(100, "ch0") seq.target("q10", "ch0") ti = tf + 100 tf = ti + 120 assert seq._schedule["ch0"][-1] == _TimeSlot("target", ti, tf, {"q10"}) seq2 = Sequence(reg, MockDevice) seq2.declare_channel("ch0", "raman_local", initial_target={"q1", "q10"}) seq2.phase_shift(1, "q2") with pytest.raises(ValueError, match="qubits with different phase"): seq2.target({"q3", "q1", "q2"}, "ch0")
def test_get_xy_hamiltonian(): simple_reg = Register.from_coordinates([[0, 10], [10, 0], [0, 0]], prefix="atom") detun = 1.0 amp = 3.0 rise = Pulse.ConstantPulse(1500, amp, detun, 0.0) simple_seq = Sequence(simple_reg, MockDevice) simple_seq.declare_channel("ch0", "mw_global") simple_seq.set_magnetic_field(0, 1.0, 0.0) simple_seq.add(rise, "ch0") assert np.isclose(np.linalg.norm(simple_seq.magnetic_field[0:2]), 1) simple_sim = Simulation(simple_seq, sampling_rate=0.03) with pytest.raises(ValueError, match="less than or equal to the sequence duration"): simple_sim.get_hamiltonian(1650) with pytest.raises(ValueError, match="greater than or equal to 0"): simple_sim.get_hamiltonian(-10) # Constant detuning, so |ud><du| term is C_3/r^3 - 2*detuning for any time simple_ham = simple_sim.get_hamiltonian(143) assert simple_ham[1, 2] == 0.5 * MockDevice.interaction_coeff_xy / 10**3 assert (np.abs(simple_ham[1, 4] - (-2 * 0.5 * MockDevice.interaction_coeff_xy / 10**3)) < 1e-10) assert simple_ham[0, 1] == 0.5 * amp assert simple_ham[3, 3] == -2 * detun
def test_noisy_xy(): np.random.seed(15092021) simple_reg = Register.square(2, prefix="atom") detun = 1.0 amp = 3.0 rise = Pulse.ConstantPulse(1500, amp, detun, 0.0) simple_seq = Sequence(simple_reg, MockDevice) simple_seq.declare_channel("ch0", "mw_global") simple_seq.add(rise, "ch0") sim = Simulation(simple_seq, sampling_rate=0.01) with pytest.raises(NotImplementedError, match="mode 'XY' does not support simulation of"): sim.set_config(SimConfig(("SPAM", "doppler"))) sim.set_config(SimConfig("SPAM", eta=0.4)) assert sim._bad_atoms == { "atom0": True, "atom1": False, "atom2": True, "atom3": False, } with pytest.raises(NotImplementedError, match="simulation of noise types: amplitude"): sim.add_config(SimConfig("amplitude"))
def test_phase(): seq = Sequence(reg, device) seq.declare_channel('ch0', 'raman_local', initial_target='q0') seq.phase_shift(-1, 'q0', 'q1') with pytest.raises(ValueError, match="id of a qubit declared"): seq.current_phase_ref(0, 'digital') with pytest.raises(ValueError, match="targets the given 'basis'"): seq.current_phase_ref('q1', 'ground-rydberg') with pytest.raises(ValueError, match="No declared channel targets"): seq.phase_shift(1, 'q3', basis='hyperfine') assert seq.current_phase_ref('q0', 'digital') == 2 * np.pi - 1 with pytest.warns(UserWarning): seq.phase_shift(0, 'q0') seq.phase_shift(-8 * np.pi, 'q1') with pytest.raises(ValueError, match='targets have to be qubit ids'): seq.phase_shift(np.pi, 'q1', 'q4', 'q100') seq.declare_channel('ch1', 'rydberg_global') seq.phase_shift(1, *seq._qids, basis='ground-rydberg') for q in seq.qubit_info: assert seq.current_phase_ref(q, 'ground-rydberg') == 1 seq.phase_shift(1, *seq._qids) assert seq.current_phase_ref('q1', 'digital') == 0 assert seq.current_phase_ref('q10', 'digital') == 1
def test_config(): np.random.seed(123) reg = Register.from_coordinates([(0, 0), (0, 5)], prefix="q") seq = Sequence(reg, Chadoq2) seq.declare_channel("ch0", "rydberg_global") duration = 2500 pulse = Pulse.ConstantPulse(duration, np.pi, 0.0 * 2 * np.pi, 0) seq.add(pulse, "ch0") sim = Simulation(seq, config=SimConfig(noise="SPAM")) sim.reset_config() assert sim.config == SimConfig() sim.show_config() with pytest.raises(ValueError, match="not a valid"): sim.set_config("bad_config") clean_ham = sim.get_hamiltonian(123) new_cfg = SimConfig(noise="doppler", temperature=10000) sim.set_config(new_cfg) assert sim.config == new_cfg noisy_ham = sim.get_hamiltonian(123) assert (noisy_ham[0, 0] != clean_ham[0, 0] and noisy_ham[3, 3] == clean_ham[3, 3]) sim.set_config(SimConfig(noise="amplitude")) noisy_amp_ham = sim.get_hamiltonian(123) assert (noisy_amp_ham[0, 0] == clean_ham[0, 0] and noisy_amp_ham[0, 1] != clean_ham[0, 1])
def test_multiple_index_targets(): test_device = Device( name="test_device", dimensions=2, rydberg_level=70, max_atom_num=100, max_radial_distance=50, min_atom_distance=4, _channels=(( "raman_local", Raman.Local(2 * np.pi * 20, 2 * np.pi * 10, max_targets=2), ), ), ) seq = Sequence(reg, test_device) var_array = seq.declare_variable("var_array", size=2, dtype=int) seq.declare_channel("ch0", "raman_local") seq.target_index([0, 1], channel="ch0") assert seq._last("ch0").targets == {"q0", "q1"} seq.target_index(var_array, channel="ch0") built_seq = seq.build(var_array=[1, 2]) assert built_seq._last("ch0").targets == {"q1", "q2"} seq.target_index(var_array + 1, channel="ch0") built_seq = seq.build(var_array=[1, 2]) assert built_seq._last("ch0").targets == {"q2", "q3"}
def test_support(): seq = Sequence(Register.square(2), Chadoq2) var = seq.declare_variable("var") obj_dict = BlackmanWaveform.from_max_val(1, var)._to_dict() del obj_dict["__module__"] with pytest.raises(TypeError, match="Invalid 'obj_dict'."): validate_serialization(obj_dict) obj_dict["__module__"] = "pulser.fake" with pytest.raises( SerializationError, match="No serialization support for module 'pulser.fake'.", ): validate_serialization(obj_dict) wf_obj_dict = obj_dict["__args__"][0] wf_obj_dict["__submodule__"] = "RampWaveform" with pytest.raises( SerializationError, match="No serialization support for attributes of " "'pulser.waveforms.RampWaveform'", ): validate_serialization(wf_obj_dict) del wf_obj_dict["__submodule__"] with pytest.raises( SerializationError, match="No serialization support for 'pulser.waveforms.from_max_val'", ): validate_serialization(wf_obj_dict)
def test_phase(): seq = Sequence(reg, device) seq.declare_channel("ch0", "raman_local", initial_target="q0") seq.phase_shift(-1, "q0", "q1") with pytest.raises(ValueError, match="id of a qubit declared"): seq.current_phase_ref(0, "digital") with pytest.raises(ValueError, match="targets the given 'basis'"): seq.current_phase_ref("q1", "ground-rydberg") with pytest.raises(ValueError, match="No declared channel targets"): seq.phase_shift(1, "q3", basis="hyperfine") assert seq.current_phase_ref("q0", "digital") == 2 * np.pi - 1 # Phase shifts of 0 seq.phase_shift(0, "q0") seq.phase_shift(-8 * np.pi, "q1") assert seq.current_phase_ref("q0", "digital") == 2 * np.pi - 1 assert seq.current_phase_ref("q1", "digital") == 2 * np.pi - 1 with pytest.raises(ValueError, match="ids have to be qubit ids"): seq.phase_shift(np.pi, "q1", "q4", "q100") seq.declare_channel("ch1", "rydberg_global") seq.phase_shift(1, *seq._qids, basis="ground-rydberg") for q in seq.qubit_info: assert seq.current_phase_ref(q, "ground-rydberg") == 1 seq.phase_shift(1, *seq._qids) assert seq.current_phase_ref("q1", "digital") == 0 assert seq.current_phase_ref("q10", "digital") == 1
def test_single_atom_simulation(): one_reg = Register.from_coordinates([(0, 0)], 'atom') one_seq = Sequence(one_reg, Chadoq2) one_seq.declare_channel('ch0', 'rydberg_global') one_seq.add(Pulse.ConstantDetuning(ConstantWaveform(16, 1.), 1., 0), 'ch0') one_sim = Simulation(seq) one_res = one_sim.run() assert (one_res._size == one_sim._size)
def test_empty_sequences(): seq = Sequence(reg, Chadoq2) with pytest.raises(ValueError, match='no declared channels'): Simulation(seq) with pytest.raises(ValueError, match='No instructions given'): seq.declare_channel('test', 'rydberg_local', 'target') seq.declare_channel("test2", "rydberg_global") Simulation(seq)
def test_screen(): sb = Sequence(reg, device) sb.declare_channel("ch1", "rydberg_global") assert sb.current_phase_ref(4, basis="ground-rydberg") == 0 var = sb.declare_variable("var") sb.delay(var, "ch1") with pytest.raises(RuntimeError, match="can't be called in parametrized"): sb.current_phase_ref(4, basis="ground-rydberg")
def test_mask_equals_remove(): """Check that masking is equivalent to removing the masked qubits. A global pulse acting on three qubits of which one is masked, should be equivalent to acting on a register with only the two unmasked qubits. """ reg_three = Register({"q0": (0, 0), "q1": (10, 10), "q2": (-10, -10)}) reg_two = Register({"q0": (0, 0), "q1": (10, 10)}) pulse = Pulse.ConstantPulse(100, 10, 0, 0) local_pulse = Pulse.ConstantPulse(200, 10, 0, 0) for channel_type in ["mw_global", "rydberg_global", "raman_global"]: # Masked simulation seq_masked = Sequence(reg_three, MockDevice) if channel_type == "mw_global": seq_masked.set_magnetic_field(0, 1.0, 0.0) else: # Add a local channel acting on a masked qubit (has no effect) seq_masked.declare_channel( "local", channel_type[:-len("global")] + "local", initial_target="q2", ) seq_masked.add(local_pulse, "local") seq_masked.declare_channel("ch_masked", channel_type) masked_qubits = ["q2"] seq_masked.config_slm_mask(masked_qubits) seq_masked.add(pulse, "ch_masked") sim_masked = Simulation(seq_masked) # Simulation on reduced register seq_two = Sequence(reg_two, MockDevice) if channel_type == "mw_global": seq_two.set_magnetic_field(0, 1.0, 0.0) seq_two.declare_channel("ch_two", channel_type) if channel_type != "mw_global": seq_two.delay(local_pulse.duration, "ch_two") seq_two.add(pulse, "ch_two") sim_two = Simulation(seq_two) # Check equality for t in sim_two.sampling_times: ham_masked = sim_masked.get_hamiltonian(t) ham_two = sim_two.get_hamiltonian(t) assert ham_masked == qutip.tensor(ham_two, qutip.qeye(2))
def test_parametrized_channel_initial_target(): sb = Sequence(reg, device) var = sb.declare_variable("var") sb.declare_channel("ch1", "rydberg_local") sb.target_index(var, "ch1") sb.declare_channel("ch0", "raman_local", initial_target=0) assert sb._calls[-1].name == "declare_channel" assert sb._to_build_calls[-1].name == "target" assert sb._to_build_calls[-1].args == (0, "ch0")
def test_register_from_layout(): layout = RegisterLayout([[0, 0], [1, 1], [1, 0], [0, 1]]) reg = layout.define_register(1, 0) assert reg == Register({"q0": [0, 1], "q1": [0, 0]}) seq = Sequence(reg, device=MockDevice) new_reg = encode_decode(seq).register assert reg == new_reg assert new_reg.layout == layout assert new_reg._layout_info.trap_ids == (1, 0)
def test_magnetic_field(): seq = Sequence(reg, MockDevice) with pytest.raises( AttributeError, match="only defined when the sequence " "is in 'XY Mode'.", ): seq.magnetic_field seq.declare_channel("ch0", "mw_global") # seq in XY mode # mag field is the default assert np.all(seq.magnetic_field == np.array((0.0, 0.0, 30.0))) seq.set_magnetic_field(bx=1.0, by=-1.0, bz=0.5) assert np.all(seq.magnetic_field == np.array((1.0, -1.0, 0.5))) with pytest.raises(ValueError, match="magnitude greater than 0"): seq.set_magnetic_field(bz=0.0) assert seq._empty_sequence seq.add(Pulse.ConstantPulse(100, 1, 1, 0), "ch0") assert not seq._empty_sequence with pytest.raises(ValueError, match="can only be set on an empty seq"): seq.set_magnetic_field(1.0, 0.0, 0.0) seq2 = Sequence(reg, MockDevice) seq2.declare_channel("ch0", "rydberg_global") # not in XY mode with pytest.raises(ValueError, match="can only be set in 'XY Mode'."): seq2.set_magnetic_field(1.0, 0.0, 0.0) seq3 = Sequence(reg, MockDevice) seq3.set_magnetic_field(1.0, 0.0, 0.0) # sets seq to XY mode assert set(seq3.available_channels) == {"mw_global"} seq3.declare_channel("ch0", "mw_global") # Does not change to default assert np.all(seq3.magnetic_field == np.array((1.0, 0.0, 0.0))) var = seq3.declare_variable("var") # Sequence is marked as non-empty when parametrized too seq3.add(Pulse.ConstantPulse(100, var, 1, 0), "ch0") assert seq3.is_parametrized() with pytest.raises(ValueError, match="can only be set on an empty seq"): seq3.set_magnetic_field() seq3_str = seq3.serialize() seq3_ = Sequence.deserialize(seq3_str) assert seq3_._in_xy assert str(seq3) == str(seq3_) assert np.all(seq3_.magnetic_field == np.array((1.0, 0.0, 0.0)))
def test_delay(): seq = Sequence(reg, device) seq.declare_channel('ch0', 'raman_local') with pytest.raises(ValueError, match='Use the name of a declared channel'): seq.delay(1e3, 'ch01') with pytest.raises(ValueError, match='channel has no target'): seq.delay(100, 'ch0') seq.target('q19', 'ch0') seq.delay(388, 'ch0') assert seq._last('ch0') == _TimeSlot('delay', 0, 388, {'q19'})
def test_measure(): pulse = Pulse.ConstantPulse(500, 2, -10, 0, post_phase_shift=np.pi) seq = Sequence(reg, MockDevice) seq.declare_channel("ch0", "rydberg_global") assert "XY" in MockDevice.supported_bases with pytest.raises(ValueError, match="not supported"): seq.measure(basis="XY") seq.measure() with pytest.raises(RuntimeError, match="already been measured"): seq.measure(basis="digital") with pytest.raises(RuntimeError, match="Nothing more can be added."): seq.add(pulse, "ch0") seq = Sequence(reg, MockDevice) seq.declare_channel("ch0", "mw_global") assert "digital" in MockDevice.supported_bases with pytest.raises(ValueError, match="not supported"): seq.measure(basis="digital") seq.measure(basis="XY")