Beispiel #1
0
    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
Beispiel #2
0
    def test_measure_noarg(self):
        """Test measurement with no argument converts"""
        # create a test program
        prog = Program(1)

        with prog.context as q:
            ops.Measure | q[0]

        bb = io.to_blackbird(prog)
        expected = {"op": "MeasureFock", "modes": [0], "args": [], "kwargs": {}}

        assert bb.operations[0] == expected
Beispiel #3
0
    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
Beispiel #4
0
    def test_tdm_program(self):
        prog = TDMProgram(2)

        with prog.context([1, 2], [3, 4], [5, 6]) as (p, q):
            ops.Sgate(0.7, 0) | q[1]
            ops.BSgate(p[0]) | (q[0], q[1])
            ops.Rgate(p[1]) | q[1]
            ops.MeasureHomodyne(p[2]) | q[0]

        bb = io.to_blackbird(prog)

        assert bb.operations[0] == {
            'kwargs': {},
            'args': [0.7, 0],
            'op': 'Sgate',
            'modes': [1]
        }
        assert bb.operations[1] == {
            'kwargs': {},
            'args': ['p0', 0.0],
            'op': 'BSgate',
            'modes': [0, 1]
        }
        assert bb.operations[2] == {
            'kwargs': {},
            'args': ['p1'],
            'op': 'Rgate',
            'modes': [1]
        }
        assert bb.operations[3] == {
            'kwargs': {
                'phi': 'p2'
            },
            'args': [],
            'op': 'MeasureHomodyne',
            'modes': [0]
        }

        assert bb.programtype == {
            'name': 'tdm',
            'options': {
                'temporal_modes': 2
            }
        }
        assert list(bb._var.keys()) == ["p0", "p1", "p2"]
        assert np.all(bb._var["p0"] == np.array([[1, 2]]))
        assert np.all(bb._var["p1"] == np.array([[3, 4]]))
        assert np.all(bb._var["p2"] == np.array([[5, 6]]))
        assert bb.modes == [0, 1]
    def test_tdm_program(self):
        """Test TDM program converts properly"""
        prog = TDMProgram(2)

        with prog.context([1, 2], [3, 4], [5, 6]) as (p, q):
            ops.Sgate(0.7, 0) | q[1]
            ops.BSgate(p[0]) | (q[0], q[1])
            ops.Rgate(p[1]) | q[1]
            ops.MeasureHomodyne(p[2]) | q[0]

        bb = io.to_blackbird(prog)

        assert bb.operations[0] == {
            "kwargs": {},
            "args": [0.7, 0],
            "op": "Sgate",
            "modes": [1]
        }
        assert bb.operations[1] == {
            "kwargs": {},
            "args": ["p0", 0.0],
            "op": "BSgate",
            "modes": [0, 1],
        }
        assert bb.operations[2] == {
            "kwargs": {},
            "args": ["p1"],
            "op": "Rgate",
            "modes": [1]
        }
        assert bb.operations[3] == {
            "kwargs": {},
            "args": ["p2"],
            "op": "MeasureHomodyne",
            "modes": [0],
        }

        assert bb.programtype == {
            "name": "tdm",
            "options": {
                "temporal_modes": 2
            }
        }
        assert list(bb._var.keys()) == ["p0", "p1", "p2"]
        assert np.all(bb._var["p0"] == np.array([[1, 2]]))
        assert np.all(bb._var["p1"] == np.array([[3, 4]]))
        assert np.all(bb._var["p2"] == np.array([[5, 6]]))
        assert bb.modes == {0, 1}
Beispiel #6
0
    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
Beispiel #7
0
    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
Beispiel #8
0
    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_measure_arg(self):
        """Test measurement with argument converts"""
        # create a test program
        prog = Program(1)

        with prog.context as q:
            ops.MeasureHomodyne(0.43) | q[0]

        bb = io.to_blackbird(prog)
        expected = {
            "op": "MeasureHomodyne",
            "modes": [0],
            "args": [],
            "kwargs": {"phi": 0.43},
        }

        assert bb.operations[0] == expected
    def test_measure_darkcounts(self):
        """Test measurement with dark counts"""
        # create a test program
        prog = Program(1)

        with prog.context as q:
            ops.MeasureFock(dark_counts=2) | q[0]

        bb = io.to_blackbird(prog)
        expected = {
            "op": "MeasureFock",
            "modes": [0],
            "args": [],
            "kwargs": {"dark_counts": [2]},
        }

        assert bb.operations[0] == expected
    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)
        assert bb.operations[-1]["op"] == "Zgate"
        assert bb.operations[-1]["modes"] == [1]

        assert isinstance(bb.operations[-1]["args"][0],
                          blackbird.RegRefTransform)
        assert bb.operations[-1]["args"][0].func_str == "2*sin(q0)"
        assert bb.operations[-1]["args"][0].regrefs == [0]

        assert bb.operations[-1]["kwargs"] == {}
    def test_gate_kwarg(self):
        """Test gate with keyword argument converts"""
        # create a test program
        prog = Program(2)

        with prog.context as q:
            ops.Dgate(np.abs(0.54 + 0.324j), np.angle(0.54 + 0.324j)) | q[1]

        bb = io.to_blackbird(prog)
        # Note: due to how SF stores quantum commands with the Parameter class,
        # all kwargs get converted to positional args internally.
        expected = {
            "op": "Dgate",
            "modes": [1],
            "args": [np.abs(0.54 + 0.324j), np.angle(0.54 + 0.324j)],
            "kwargs": {},
        }

        assert bb.operations[0] == expected
Beispiel #13
0
    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": {}
        }
Beispiel #14
0
    def create_job(self,
                   target: str,
                   program: Program,
                   run_options: dict = None) -> Job:
        """Creates a job with the given circuit.

        Args:
            target (str): the target device
            program (strawberryfields.Program): the quantum circuit
            run_options (Dict[str, Any]): Runtime arguments for the program execution.
                If provided, overrides the value stored in the given ``program``.

        Returns:
            strawberryfields.api.Job: the created job
        """
        # Serialize a blackbird circuit for network transmission
        bb = to_blackbird(program)
        bb._target["name"] = target
        bb._target["options"] = run_options

        circuit = bb.serialize()

        path = "/jobs"
        response = requests.post(self._url(path),
                                 headers=self._headers,
                                 json={"circuit": circuit})
        if response.status_code == 201:
            job_id = response.json()["id"]
            if self._verbose:
                self.log.info("Job %s was successfully submitted.", job_id)
            return Job(
                id_=job_id,
                status=JobStatus(response.json()["status"]),
                connection=self,
            )
        raise RequestFailedError("Failed to create job: {}".format(
            self._format_error_message(response)))
Beispiel #15
0
    def run_async(self,
                  program: Program,
                  *,
                  compile_options=None,
                  recompile=False,
                  **kwargs) -> xcc.Job:
        """Runs a non-blocking remote job.

        In the non-blocking mode, a ``xcc.Job`` object is returned immediately, and the user can
        manually refresh the status and check for updated results of the job.

        Args:
            program (strawberryfields.Program): the quantum circuit
            compile_options (None, Dict[str, Any]): keyword arguments for :meth:`.Program.compile`
            recompile (bool): Specifies if ``program`` should be recompiled
                using ``compile_options``, or if not provided, the default compilation options.

        Keyword Args:
            shots (Optional[int]): The number of shots for which to run the job. If this
                argument is not provided, the shots are derived from the given ``program``.

        Returns:
            xcc.Job: the created remote job
        """
        # get the specific chip to submit the program to
        compile_options = compile_options or {}
        kwargs.update(self._backend_options)

        device = self.device
        compiler_name = compile_options.get("compiler",
                                            device.default_compiler)

        program_is_compiled = program.compile_info is not None

        if program_is_compiled and not recompile:
            # error handling for program compilation:
            # program was compiled but recompilation was not allowed by the
            # user

            if program.compile_info and (
                    program.compile_info[0].target != device.target
                    or program.compile_info[0]._spec != device._spec):
                compile_target = program.compile_info[0].target
                # program was compiled for a different device
                raise ValueError("Cannot use program compiled with "
                                 f"{compile_target} for target {self.target}. "
                                 'Pass the "recompile=True" keyword argument '
                                 f"to compile with {compiler_name}.")

        if not program_is_compiled:
            # program is not compiled
            msg = f"Compiling program for device {device.target} using compiler {compiler_name}."
            self.log.info(msg)
            program = program.compile(device=device, **compile_options)

        elif recompile:
            # recompiling program
            if compile_options:
                msg = f"Recompiling program for device {device.target} using the specified compiler options: {compile_options}."
            else:
                msg = f"Recompiling program for device {device.target} using compiler {compiler_name}."

            self.log.info(msg)
            program = program.compile(device=device, **compile_options)

        elif program.compile_info[1][0] == "X":
            # validating program
            msg = (
                f"Program previously compiled for {device.target} using {program.compile_info[1]}. "
                f"Validating program against the Xstrict compiler.")
            self.log.info(msg)
            program = program.compile(device=device, compiler="Xstrict")

        # Update and filter the run options if provided.
        # Forwarding the boolean `crop` run option to the hardware will result in undesired
        # behaviour as og-tdm also uses that keyword arg, hence it is removed.
        temp_run_options = {**program.run_options, **kwargs}
        skip_run_keys = ["crop"]
        run_options = {
            key: temp_run_options[key]
            for key in temp_run_options.keys() - skip_run_keys
        }

        if "shots" not in run_options:
            raise ValueError("Number of shots must be specified.")

        # Serialize a Blackbird circuit for network transmission
        bb = to_blackbird(program)
        bb._target["options"] = run_options
        circuit = bb.serialize()

        connection = self.connection

        job = xcc.Job.submit(
            connection=connection,
            name=program.name,
            target=self.target,
            circuit=circuit,
            language=f"blackbird:{bb.version}",
        )

        return job