def test_pre_measure_eng(self, tol): """Test that the pre_measure method operates as expected by initializing the engine correctly""" dev = qml.device("strawberryfields.gbs", wires=4, cutoff_dim=3) prog = Program(4) op1 = GraphEmbed(0.1767767 * np.ones((4, 4)), mean_photon_per_mode=0.25) prog.append(op1, prog.register) dev.prog = prog dev.pre_measure() assert dev.eng.backend_name == "gaussian" assert dev.eng.backend_options == {"cutoff_dim": 3}
def test_free_par_str(self): """Test a FreeParameter with some transformations converts properly""" prog = Program(2) r, alpha = prog.params('r', 'alpha') with prog.context as q: ops.Sgate(r) | q[0] ops.Zgate(3 * pf.log(-alpha)) | q[1] bb = io.to_blackbird(prog) assert bb.operations[0] == {"op": "Sgate", "modes": [0], "args": ['{r}', 0.0], "kwargs": {}} assert bb.operations[1] == {"op": "Zgate", "modes": [1], "args": ['3*log(-{alpha})'], "kwargs": {}}
def test_measured_par_str(self): """Test a MeasuredParameter with some transformations converts properly""" prog = Program(2) with prog.context as q: ops.Sgate(0.43) | q[0] ops.MeasureX | q[0] ops.Zgate(2 * pf.sin(q[0].par)) | q[1] bb = io.to_blackbird(prog) expected = {"op": "Zgate", "modes": [1], "args": ["2*sin(q0)"], "kwargs": {}} assert bb.operations[-1] == expected
def test_two_mode_gate(self): """Test two mode gate converts""" sf_prog = Program(4) with sf_prog.context as q: ops.BSgate(0.54, -0.324) | (q[3], q[0]) xir_prog = io.to_xir(sf_prog) expected = [("BSgate", [0.54, -0.324], (3, 0))] assert [(stmt.name, stmt.params, stmt.wires) for stmt in xir_prog.statements] == expected
def test_regref_no_func_str(self): """Test a regreftransform with no function string raises exception""" prog = Program(2) with prog.context as q: ops.Sgate(0.43) | q[0] ops.MeasureX | q[0] ops.Zgate(ops.RR(q[0], lambda x: 2 * x)) | q[1] with pytest.raises(ValueError, match="not supported by Blackbird"): io.to_blackbird(prog)
def test_gate_arg(self): """Test gate with argument converts""" # create a test program sf_prog = Program(2) with sf_prog.context as q: ops.Sgate(0.54, 0.324) | q[1] xir_prog = io.to_xir(sf_prog) expected = [("Sgate", [0.54, 0.324], (1,))] assert [(stmt.name, stmt.params, stmt.wires) for stmt in xir_prog.statements] == expected
def test_gate_noarg(self): """Test gate with no argument converts""" # create a test program sf_prog = Program(1) with sf_prog.context as q: ops.Vac | q[0] xir_prog = io.to_xir(sf_prog) expected = [("Vacuum", [], (0,))] assert [(stmt.name, stmt.params, stmt.wires) for stmt in xir_prog.statements] == expected
def test_measure_noarg(self): """Test measurement with no argument converts""" # create a test program prog = Program(1) with prog.context as q: ops.MeasureFock() | q[0] bb = io.to_blackbird(prog) expected = {"op": "MeasureFock", "modes": [0], "args": [], "kwargs": {}} assert bb.operations[0] == expected
def test_measure_arg_postselect(self): """Test measurement with argument and postselection converts""" # create a test program sf_prog = Program(1) with sf_prog.context as q: ops.MeasureHomodyne(0.43, select=0.543) | q[0] xir_prog = io.to_xir(sf_prog) expected = [("MeasureHomodyne", {"phi": 0.43, "select": 0.543}, (0,))] assert [(stmt.name, stmt.params, stmt.wires) for stmt in xir_prog.statements] == expected # repeat with kwargs only sf_prog = Program(1) with sf_prog.context as q: ops.MeasureHomodyne(phi=0.43, select=0.543) | q[0] xir_prog = io.to_xir(sf_prog) assert [(stmt.name, stmt.params, stmt.wires) for stmt in xir_prog.statements] == expected
def test_free_par_str(self): """Test a FreeParameter with some transformations converts properly""" sf_prog = Program(2) r, alpha = sf_prog.params("r", "alpha") with sf_prog.context as q: ops.Sgate(r) | q[0] ops.Zgate(3 * pf.log(-alpha)) | q[1] xir_prog = io.to_xir(sf_prog) expected = [("Sgate", ["r", 0.0], (0,)), ("Zgate", ["3*log(-alpha)"], (1,))] assert [(stmt.name, stmt.params, stmt.wires) for stmt in xir_prog.statements] == expected
def test_measure_arg(self): """Test measurement with argument converts""" # create a test program sf_prog = Program(1) with sf_prog.context as q: ops.MeasureHomodyne(0.43) | q[0] xir_prog = io.to_xir(sf_prog) expected = [("MeasureHomodyne", {"phi": 0.43}, (0,))] assert [(stmt.name, stmt.params, stmt.wires) for stmt in xir_prog.statements] == expected
def test_gate_arg(self): """Test gate with argument converts""" # create a test program prog = Program(2) with prog.context as q: ops.Sgate(0.54, 0.324) | q[1] bb = io.to_blackbird(prog) expected = {"op": "Sgate", "modes": [1], "args": [0.54, 0.324], "kwargs": {}} assert bb.operations[0] == expected
def test_measure_darkcounts(self): """Test measurement with dark counts""" # create a test program sf_prog = Program(1) with sf_prog.context as q: ops.MeasureFock(dark_counts=2) | q[0] xir_prog = io.to_xir(sf_prog) expected = [("MeasureFock", {"dark_counts": [2]}, (0,))] assert [(stmt.name, stmt.params, stmt.wires) for stmt in xir_prog.statements] == expected
def test_measure_postselect(self): """Test measurement with postselection""" # create a test program sf_prog = Program(1) with sf_prog.context as q: ops.MeasureFock(select=2) | q[0] xir_prog = io.to_xir(sf_prog) expected = [("MeasureFock", {"select": [2]}, (0,))] assert [(stmt.name, stmt.params, stmt.wires) for stmt in xir_prog.statements] == expected
def test_gate_noarg(self): """Test gate with no argument converts""" # create a test program prog = Program(1) with prog.context as q: ops.Vac | q[0] bb = io.to_blackbird(prog) expected = {"op": "Vacuum", "modes": [0], "args": [], "kwargs": {}} assert bb.operations[0] == expected
def test_exceptions(self, state): """Test exceptions raised if state prep used on invalid modes""" G = state() prog = Program(2) with prog.context: # all states act on a single mode with pytest.raises(ValueError): G.__or__([0, 1]) # can't repeat the same index with pytest.raises(RegRefError): ops.All(G).__or__([0, 0])
def test_pre_measure_state_and_samples(self, tol): """Test that the pre_measure method operates as expected in analytic mode by generating the correct output state and not generating samples""" dev = qml.device("strawberryfields.gbs", wires=4, cutoff_dim=3) prog = Program(4) op1 = GraphEmbed(0.1767767 * np.ones((4, 4)), mean_photon_per_mode=0.25) prog.append(op1, prog.register) dev.prog = prog dev.pre_measure() assert np.allclose(dev.state.displacement(), np.zeros(4)) assert np.allclose(dev.state.cov(), target_cov, atol=tol) assert dev.samples.size == 0
def test_measure_noarg(self): """Test measurement with no argument converts""" # create a test program sf_prog = Program(1) with sf_prog.context as q: ops.MeasureFock() | q[0] xir_prog = io.to_xir(sf_prog) # note that measurement parameters are always dicts expected = [("MeasureFock", {}, (0,))] assert [(stmt.name, stmt.params, stmt.wires) for stmt in xir_prog.statements] == expected
def test_create_delete_multiple_modes(self): """test creating and deleting multiple modes""" prog = Program(3) with prog.context as (alice, bob, charlie): edward, frank, grace = ops.New(3) ops.Del | (alice, grace) # register should only return the active subsystems q = prog.register assert len(q) == prog.num_subsystems assert len(q) == 4 # Program.reg_refs contains all the regrefs, active and inactive assert len(prog.reg_refs) == 6
def test_decomposition_operation_not_compiled(self): """Test decomposition operation""" # create a test program sf_prog = Program(4) with sf_prog.context as q: ops.Interferometer(U) | q xir_prog = io.to_xir(sf_prog) assert xir_prog.statements[0].name == "Interferometer" param = np.array(xir_prog.statements[0].params) assert np.allclose(param[0], U) assert xir_prog.statements[0].wires == (0, 1, 2, 3)
def test_gate_kwarg(self): """Test gate with keyword argument converts""" # create a test program sf_prog = Program(2) with sf_prog.context as q: ops.Dgate(r=np.abs(0.54 + 0.324j), phi=np.angle(0.54 + 0.324j)) | q[0] xir_prog = io.to_xir(sf_prog) # Note: due to how SF stores quantum commands with the Parameter class, # all kwargs get converted to positional args internally. expected = [("Dgate", [np.abs(0.54 + 0.324j), np.angle(0.54 + 0.324j)], (0,))] assert [(stmt.name, stmt.params, stmt.wires) for stmt in xir_prog.statements] == expected
def test_decomposition_operation_compiled(self): """Test decomposition operation gets decomposed if compiled""" # create a test program prog = Program(1) with prog.context as q: ops.Pgate(0.43) | q[0] bb = io.to_blackbird(prog) expected = {"op": "Pgate", "modes": [0], "args": [0.43], "kwargs": {}} assert bb.operations[0] == expected bb = io.to_blackbird(prog.compile(compiler="gaussian")) assert bb.operations[0]["op"] == "Sgate" assert bb.operations[1]["op"] == "Rgate"
def test_pre_measure_state_and_samples_non_analytic(self, tol): """Test that the pre_measure method operates as expected in non-analytic mode by generating the correct output state and samples of the right shape""" dev = qml.device("strawberryfields.gbs", wires=4, cutoff_dim=3, analytic=False, shots=2) prog = Program(4) op1 = GraphEmbed(0.1767767 * np.ones((4, 4)), mean_photon_per_mode=0.25) op2 = MeasureFock() prog.append(op1, prog.register) prog.append(op2, prog.register) dev.prog = prog dev.pre_measure() assert np.allclose(dev.state.displacement(), np.zeros(4)) assert np.allclose(dev.state.cov(), target_cov, atol=tol) assert dev.samples.shape == (2, 4)
def test_metadata(self): """Test metadata correctly converts""" # create a test program prog = Program(4, name="test_program") bb = io.to_blackbird(prog) assert bb.name == "test_program" assert bb.version == "1.0" assert bb.target["name"] is None bb = io.to_blackbird(prog.compile(compiler="gaussian")) assert bb.name == "test_program" assert bb.version == "1.0" assert bb.target["name"] == "gaussian"
def test_complex_symbolic(self, gate): """Test that passing a complex value to symbolic parameter of a gate that previously accepted complex parameters raises an error. An example here is testing heterodyne measurements. """ with pytest.raises(ValueError, match="cannot be complex"): prog = Program(1) with prog.context as q: ops.MeasureHD | q[0] gate(q[0].par) | q eng = Engine("gaussian") res = eng.run(prog)
def test_merge_regrefs(): """Test merging two gates with regref parameters.""" prog = Program(2) with prog.context as q: ops.MeasureX | q[0] D = ops.Dgate(q[0]) F = ops.Dgate(q[0], 0.1) # gates that are the inverse of each other merged = D.merge(D.H) assert merged is None # gates that have different parameters with pytest.raises(MergeFailure, match="Don't know how to merge these gates."): F.merge(D.H)
def test_two_mode_gate(self): """Test two mode gate converts""" prog = Program(4) with prog.context as q: ops.BSgate(0.54, -0.324) | (q[3], q[0]) bb = io.to_blackbird(prog) expected = { "op": "BSgate", "modes": [3, 0], "args": [0.54, -0.324], "kwargs": {}, } assert bb.operations[0] == expected
def test_dispatch_one_mode_gates(self, gate): """test one mode gates automatically add to the queue""" prog = Program(2) G = gate(a) if G.ns == 2: pytest.skip("test only for 1 mode gates.") with prog.context: G | 0 ops.All(G) | (0, 1) assert len(prog) == 3 assert all(cmd.op == G for cmd in prog.circuit) assert prog.circuit[0].reg[0].ind == 0 assert prog.circuit[1].reg[0].ind == 0 assert prog.circuit[2].reg[0].ind == 1
def test_decomposition_operation_not_compiled(self): """Test decomposition operation""" # create a test program prog = Program(4) with prog.context as q: ops.Interferometer(U) | q bb = io.to_blackbird(prog) expected = { "op": "Interferometer", "modes": [0, 1, 2, 3], "args": [U], "kwargs": {}, } assert bb.operations[0] == expected
def test_decomposition_operation_compiled(self): """Test decomposition operation gets decomposed if compiled""" # create a test program sf_prog = Program(1) with sf_prog.context as q: ops.Pgate(0.43) | q[0] xir_prog = io.to_xir(sf_prog) expected = [("Pgate", [0.43], (0,))] assert [(stmt.name, stmt.params, stmt.wires) for stmt in xir_prog.statements] == expected xir_prog = io.to_xir(sf_prog.compile(compiler="gaussian")) assert xir_prog.statements[0].name == "Sgate" assert xir_prog.statements[1].name == "Rgate"