def test_checkpoints(self, backend):
        """Test history checkpoints work when creating and deleting modes."""
        eng, q = sf.Engine(2)
        alice, bob = q

        # define some gates
        D = ops.Dgate(0.5)
        BS = ops.BSgate(2 * np.pi, np.pi / 2)
        R = ops.Rgate(np.pi)

        with eng:
            D | alice
            BS | (alice, bob)
            ops.Del | alice
            R | bob
            charlie, = ops.New(1)
            BS | (bob, charlie)
            ops.MeasureX | bob
            ops.Del | bob
            D.H | charlie
            ops.MeasureX | charlie

        eng.optimize()
        eng.run(backend)

        assert not alice.active
        assert charlie.active

        # check that reset_queue() restores the latest RegRef checkpoint
        # (created by eng.run() above)
        eng.reset_queue()

        assert not alice.active
        assert charlie.active

        with eng:
            diana, = ops.New(1)
            ops.Del | charlie

        assert not charlie.active
        assert diana.active
        eng.reset_queue()
        assert charlie.active
        assert not diana.active

        eng.reset()

        new_reg = eng.register
        # original number of modes
        assert len(new_reg) == len(q)

        # the regrefs are reset as well
        assert np.all([r.val is None for r in new_reg])
Exemple #2
0
 def test_create(self, prog):
     """test creating a mode"""
     q = prog.register
     assert prog.num_subsystems == 2
     new_q, = ops.New(1)
     assert new_q.active
     assert prog.num_subsystems == 3
Exemple #3
0
 def test_create_locked(self, prog):
     """No new modes can be created in a locked Program."""
     prog.lock()
     with pytest.raises(
         CircuitError, match="The Program is locked, no new subsystems can be created"
     ):
         ops.New(1)
Exemple #4
0
    def test_checkpoints(self, setup_eng, tol):
        """Test history checkpoints work when creating and deleting modes."""
        eng, q = setup_eng(2)
        alice, bob = q

        # define some gates
        D = ops.Dgate(0.5)
        BS = ops.BSgate(2 * np.pi, np.pi / 2)
        R = ops.Rgate(np.pi)

        with eng:
            D | alice
            BS | (alice, bob)
            ops.Del | alice
            R | bob
            charlie, = ops.New(1)
            BS | (bob, charlie)
            ops.MeasureX | bob
            ops.Del | bob
            D.H | charlie
            ops.MeasureX | charlie

        eng.optimize()
        state = eng.run()

        # state norm must be invariant
        if isinstance(eng.backend, BaseFock):
            assert np.allclose(state.trace(), 1, atol=tol, rtol=0)

        def check_reg(self, expected_n=None):
            """Compare Engine.register with the mode list returned by the backend.
            They should always be in agreement after Engine.run(), Engine.reset_queue()
            and Engine.reset().
            """
            rr = eng.register
            modes = eng.backend.get_modes()
            # number of elements
            assert len(rr) == len(modes)

            if expected_n is not None:
                assert len(rr) == expected_n

            # check indices match
            assert np.all([r.ind for r in rr] == modes)
            # activity
            assert np.all([r.active for r in rr])

        # check that reset() works
        check_reg(1)
        eng.reset()

        new_reg = eng.register
        # original number of modes
        assert len(new_reg) == len(q)

        # the regrefs are reset as well
        assert np.all([r.val is None for r in new_reg])
        check_reg(2)
Exemple #5
0
    def test_print_commands(self, eng, prog):
        """Program.print and Engine.print_applied return correct strings."""
        prog = sf.Program(2)

        # store the result of the print command in list res
        res = []
        # use a print function that simply appends the operation
        # name to the results list
        print_fn = lambda x: res.append(x.__str__())

        # prog should now be empty
        prog.print(print_fn)
        assert res == []

        # define some gates
        D = ops.Dgate(0.5)
        BS = ops.BSgate(2 * np.pi, np.pi / 2)
        R = ops.Rgate(np.pi)

        with prog.context as q:
            alice, bob = q
            D | alice
            BS | (alice, bob)
            ops.Del | alice
            R | bob
            charlie, = ops.New(1)
            BS | (bob, charlie)
            ops.MeasureX | bob
            ops.Dgate(bob.par).H | charlie
            ops.Del | bob
            ops.MeasureX | charlie

        res = []
        prog.print(print_fn)

        expected = [
            "Dgate(0.5, 0) | (q[0])",
            "BSgate(6.283, 1.571) | (q[0], q[1])",
            "Del | (q[0])",
            "Rgate(3.142) | (q[1])",
            "New(1)",
            "BSgate(6.283, 1.571) | (q[1], q[2])",
            "MeasureX | (q[1])",
            "Dgate(q1, 0).H | (q[2])",
            "Del | (q[1])",
            "MeasureX | (q[2])",
        ]

        assert res == expected

        # NOTE optimization can change gate order
        result = eng.run(prog, compile_options={'optimize': False})
        res = []
        eng.print_applied(print_fn)
        assert res == ["Run 0:"] + expected
    def test_print_commands(self, backend):
        """Test print_queue and print_applied returns correct strings."""
        eng, q = sf.Engine(2)

        # define some gates
        D = ops.Dgate(0.5)
        BS = ops.BSgate(2 * np.pi, np.pi / 2)
        R = ops.Rgate(np.pi)

        # get register references
        alice, bob = q

        with eng:
            D | alice
            BS | (alice, bob)
            ops.Del | alice
            R | bob
            charlie, = ops.New(1)
            BS | (bob, charlie)
            ops.MeasureX | bob
            ops.Dgate(bob).H | charlie
            ops.Del | bob
            ops.MeasureX | charlie

        res = []
        print_fn = lambda x: res.append(x.__str__())
        eng.print_queue(print_fn)

        expected = [
            "Dgate(0.5, 0) | (q[0])",
            "BSgate(6.283, 1.571) | (q[0], q[1])",
            "Del | (q[0])",
            "Rgate(3.142) | (q[1])",
            "New(1) ",
            "BSgate(6.283, 1.571) | (q[1], q[2])",
            "MeasureX | (q[1])",
            "Dgate(RR(q[1]), 0).H | (q[2])",
            "Del | (q[1])",
            "MeasureX | (q[2])",
        ]

        assert res == expected
        state = eng.run(backend)

        # queue should now be empty
        res = []
        eng.print_queue(print_fn)
        assert res == []

        # print_applied should now not be empty
        res = []
        eng.print_applied(print_fn)
        assert res == ["Run 0:"] + expected
Exemple #7
0
    def test_subsystems(self, setup_eng, tol):
        """Check that the backend keeps in sync with the program when creating and deleting modes."""
        null = sf.Program(2)  # empty program
        eng, prog = setup_eng(2)

        # define some gates
        D = ops.Dgate(0.5)
        BS = ops.BSgate(2 * np.pi, np.pi / 2)
        R = ops.Rgate(np.pi)

        with prog.context as q:
            alice, bob = q
            D | alice
            BS | (alice, bob)
            ops.Del | alice
            R | bob
            charlie, = ops.New(1)
            BS | (bob, charlie)
            ops.MeasureX | bob
            ops.Del | bob
            D.H | charlie
            ops.MeasureX | charlie

        def check_reg(p, expected_n=None):
            """Compare Program.register with the mode list returned by the backend.
            They should always be in agreement after Engine.run() and Engine.reset().
            """
            rr = p.register
            modes = eng.backend.get_modes()
            # number of elements
            assert len(rr) == len(modes)

            if expected_n is not None:
                assert len(rr) == expected_n

            # check indices match
            assert np.all([r.ind for r in rr] == modes)
            # activity
            assert np.all([r.active for r in rr])

        state = eng.run(null)
        check_reg(null, 2)
        state = eng.run(prog).state
        check_reg(prog, 1)

        # state norm must be invariant
        if isinstance(eng.backend, BaseFock):
            assert np.allclose(state.trace(), 1, atol=tol, rtol=0)

        # check that reset() works
        eng.reset()
        # the regrefs are reset as well
        assert np.all([r.val is None for r in prog.register])
Exemple #8
0
    def test_print_commands(self, eng, prog):
        """Program.print and Engine.print_applied return correct strings."""
        prog = sf.Program(2)
        res = []
        print_fn = lambda x: res.append(x.__str__())

        # prog should now be empty
        prog.print(print_fn)
        assert res == []

        # define some gates
        D = ops.Dgate(0.5)
        BS = ops.BSgate(2 * np.pi, np.pi / 2)
        R = ops.Rgate(np.pi)

        with prog.context as q:
            alice, bob = q
            D | alice
            BS | (alice, bob)
            ops.Del | alice
            R | bob
            charlie, = ops.New(1)
            BS | (bob, charlie)
            ops.MeasureX | bob
            ops.Dgate(bob).H | charlie
            ops.Del | bob
            ops.MeasureX | charlie

        res = []
        prog.print(print_fn)

        expected = [
            "Dgate(0.5, 0) | (q[0])",
            "BSgate(6.283, 1.571) | (q[0], q[1])",
            "Del | (q[0])",
            "Rgate(3.142) | (q[1])",
            "New(1)",
            "BSgate(6.283, 1.571) | (q[1], q[2])",
            "MeasureX | (q[1])",
            "Dgate(RR(q[1]), 0).H | (q[2])",
            "Del | (q[1])",
            "MeasureX | (q[2])",
        ]

        assert res == expected

        state = eng.run(
            prog, compile=False
        )  # FIXME optimization can change gate order, however this is not a good way of avoiding it
        res = []
        eng.print_applied(print_fn)
        assert res == ["Run 0:"] + expected
Exemple #9
0
    def test_create_delete_multiple_modes(self):
        """test creating and deleting multiple modes"""
        prog = sf.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_create_delete_multiple_modes(self):
        """test creating and deleting multiple modes"""
        eng, (alice, bob, charlie) = sf.Engine(3)

        with eng:
            edward, frank, grace = ops.New(3)
            ops.Del | (alice, grace)

        # register should only return the active subsystems
        q = eng.register
        assert len(q) == eng.num_subsystems
        assert len(q) == 4
        # Engine.reg_refs contains all the regrefs, active and inactive
        assert len(eng.reg_refs) == 6
Exemple #11
0
 def test_parent_program(self):
     """Continuing one program with another."""
     D = ops.Dgate(0.5)
     prog = sf.Program(3)
     with prog.context as q:
         D | q[1]
         ops.Del | q[0]
     cont = sf.Program(prog)
     with cont.context as q:
         D | q[0]
         r = ops.New(1)
         D | r
     assert cont.can_follow(prog)
     assert prog.reg_refs == cont.init_reg_refs
     assert prog.unused_indices == cont.init_unused_indices
Exemple #12
0
 def test_create_non_positive_integer(self, prog):
     """number of new modes must be a positive integer"""
     with pytest.raises(ValueError, match='is not a positive integer'):
         ops.New(-2)
     with pytest.raises(ValueError, match='is not a positive integer'):
         ops.New(1.5)
Exemple #13
0
 def test_create_outside_program_context(self):
     """New() must be only called inside a Program context."""
     with pytest.raises(
             RuntimeError,
             match='can only be called inside a Program context'):
         ops.New()
 def test_create(self, eng):
     """test creating a mode"""
     q = eng.register
     new_q, = ops.New(1)
     assert new_q.active