Exemplo n.º 1
0
    def test_qp_request_encodes_offset(self):
        """Test `offset` is stored in problem data."""

        solver = get_structured_solver()
        linear, quadratic = generate_const_ising_problem(solver, h=1, j=-1)

        # default offset is zero
        request = encode_problem_as_qp(solver, linear, quadratic)
        self.assertEqual(request['offset'], 0)

        # test explicit offset
        offset = 2.0
        request = encode_problem_as_qp(solver, linear, quadratic, offset)
        self.assertEqual(request['offset'], offset)
Exemplo n.º 2
0
    def setUpClass(cls):
        """Configure attributes required (used) by ProblemResourcesBaseTests."""

        with Client(**config) as client:
            cls.token = config['token']
            cls.api = Problems.from_client_config(client)

            # submit and solve an Ising problem as a fixture
            solver = client.get_solver(qpu=True)
            cls.solver_id = solver.id
            edge = next(iter(solver.edges))
            cls.linear = {}
            cls.quadratic = {edge: 1.0}
            qp = encode_problem_as_qp(solver, cls.linear, cls.quadratic)
            cls.problem_data = models.ProblemData.parse_obj(qp)
            cls.problem_type = constants.ProblemType.ISING
            cls.params = dict(num_reads=100)
            future = solver.sample_ising(cls.linear, cls.quadratic,
                                         **cls.params)
            resolved = future.result()
            cls.problem_id = future.id
            cls.problem_label = future.label

            # double-check
            assert future.remote_status == constants.ProblemStatus.COMPLETED.value
Exemplo n.º 3
0
    def test_qp_request_encoding_all_qubits(self):
        """Test biases and coupling strengths are properly encoded (base64 little-endian doubles)."""

        solver = get_structured_solver()
        linear, quadratic = generate_const_ising_problem(solver, h=1, j=-1)
        request = encode_problem_as_qp(solver, linear, quadratic)
        self.assertEqual(request['format'], 'qp')
        self.assertEqual(request['lin'],  self.encode_doubles([1, 1, 1, 1]))
        self.assertEqual(request['quad'], self.encode_doubles([-1, -1, -1, -1]))
Exemplo n.º 4
0
 def problem_data(self,
                  solver: StructuredSolver = None,
                  problem: Tuple[dict, dict] = None) -> dict:
     if solver is None:
         solver = self.solver
     if problem is None:
         problem = self.problem
     linear, quadratic = problem
     return encode_problem_as_qp(solver, linear, quadratic)
Exemplo n.º 5
0
    def test_qp_request_encoding_all_qubits(self):
        """Test biases and coupling strengths are properly encoded (base64 little-endian doubles)."""

        solver = get_structured_solver()
        linear = {index: 1 for index in solver.nodes}
        quadratic = {key: -1 for key in solver.undirected_edges}
        request = encode_problem_as_qp(solver, linear, quadratic)
        self.assertEqual(request['format'], 'qp')
        self.assertEqual(request['lin'], self.encode_doubles([1, 1, 1, 1]))
        self.assertEqual(request['quad'], self.encode_doubles([-1, -1, -1,
                                                               -1]))
Exemplo n.º 6
0
    def test_qp_request_encoding_undirected_biases(self):
        """Quadratic terms are correctly encoded when given as undirected biases."""

        solver = get_structured_solver()
        linear = {}
        quadratic = {(0,3): -1, (3,0): -1}
        request = encode_problem_as_qp(solver, linear, quadratic, undirected_biases=True)
        self.assertEqual(request['format'], 'qp')
        # [0, NaN, NaN, 0]
        self.assertEqual(request['lin'],  self.encode_doubles([0, self.nan, self.nan, 0]))
        # [-1]
        self.assertEqual(request['quad'], self.encode_doubles([-1]))
Exemplo n.º 7
0
    def test_qp_request_encoding_sub_qubits_implicit_couplings(self):
        """Couplings should be zero for active qubits, if not specified."""

        solver = get_structured_solver()
        linear = {0: 0, 3: 0}
        quadratic = {}
        request = encode_problem_as_qp(solver, linear, quadratic)
        self.assertEqual(request['format'], 'qp')
        # [0, NaN, NaN, 0]
        self.assertEqual(request['lin'],  self.encode_doubles([0, self.nan, self.nan, 0]))
        # [0]
        self.assertEqual(request['quad'], self.encode_doubles([0]))
Exemplo n.º 8
0
    def test_qp_request_encoding_sub_qubits_implicit_biases(self):
        """Biases don't have to be specified for qubits to be active."""

        solver = get_structured_solver()
        linear = {}
        quadratic = {(0,3): -1}
        request = encode_problem_as_qp(solver, linear, quadratic)
        self.assertEqual(request['format'], 'qp')
        # [0, NaN, NaN, 0]
        self.assertEqual(request['lin'],  self.encode_doubles([0, self.nan, self.nan, 0]))
        # [-1]
        self.assertEqual(request['quad'], self.encode_doubles([-1]))
Exemplo n.º 9
0
    def test_qp_request_encoding_missing_qubits(self):
        """Qubits don't have to be specified with biases only, but also with couplings."""

        solver = get_structured_solver()
        linear = {}
        quadratic = {(0, 1): -1}
        request = encode_problem_as_qp(solver, linear, quadratic)
        self.assertEqual(request['format'], 'qp')
        # [0, 0, NaN, NaN]
        self.assertEqual(request['lin'],  self.encode_doubles([0, 0, self.nan, self.nan]))
        # [-1]
        self.assertEqual(request['quad'], self.encode_doubles([-1]))
Exemplo n.º 10
0
    def test_qp_request_encoding_sub_qubits(self):
        """Inactive qubits should be encoded as NaNs. Inactive couplers should be omitted."""

        solver = get_structured_solver()
        linear = {0: 1, 1: 1}
        quadratic = {(0, 1): -1}
        request = encode_problem_as_qp(solver, linear, quadratic)
        self.assertEqual(request['format'], 'qp')
        # [1, 1, NaN, NaN]
        self.assertEqual(request['lin'],  self.encode_doubles([1, 1, self.nan, self.nan]))
        # [-1]
        self.assertEqual(request['quad'], self.encode_doubles([-1]))
Exemplo n.º 11
0
    def test_qp_request_encoding_sub_qubits(self):
        """Inactive qubits should be encoded as NaNs. Inactive couplers should be omitted."""

        solver = get_structured_solver()
        linear = {index: 1 for index in sorted(list(solver.nodes))[:2]}
        quadratic = {
            key: -1
            for key in sorted(list(solver.undirected_edges))[:1]
        }
        request = encode_problem_as_qp(solver, linear, quadratic)
        self.assertEqual(request['format'], 'qp')
        # [1, 1, NaN, NaN]
        self.assertEqual(request['lin'],
                         self.encode_doubles([1, 1, self.nan, self.nan]))
        # [-1]
        self.assertEqual(request['quad'], self.encode_doubles([-1]))
Exemplo n.º 12
0
    def _sample(self, type_, linear, quadratic, params):
        """Internal method for `sample_ising` and `sample_qubo`.

        Args:
            linear (list/dict):
                Linear terms of the model.

            quadratic (dict[(int, int), float]):
                Quadratic terms of the model.

            **params:
                Parameters for the sampling method, solver-specific.

        Returns:
            :class:`Future`
        """
        # Check the problem
        if not self.check_problem(linear, quadratic):
            raise InvalidProblemError("Problem graph incompatible with solver.")

        # Mix the new parameters with the default parameters
        combined_params = dict(self._params)
        combined_params.update(params)

        # Check the parameters before submitting
        for key in combined_params:
            if key not in self.parameters and not key.startswith('x_'):
                raise KeyError("{} is not a parameter of this solver.".format(key))

        # transform some of the parameters in-place
        self._format_params(type_, combined_params)

        body = json.dumps({
            'solver': self.id,
            'data': encode_problem_as_qp(self, linear, quadratic),
            'type': type_,
            'params': combined_params
        })
        logger.trace("Encoded sample request: %s", body)

        future = Future(solver=self, id_=None, return_matrix=self.return_matrix)

        logger.debug("Submitting new problem to: %s", self.id)
        self.client._submit(body, future)
        return future
Exemplo n.º 13
0
    def _sample(self, type_, linear, quadratic, offset, params,
                label=None, undirected_biases=False):
        """Internal method for `sample_ising`, `sample_qubo` and `sample_bqm`.

        Args:
            linear (list/dict):
                Linear terms of the model.

            quadratic (dict[(int, int), float]):
                Quadratic terms of the model.

            offset (number):
                Constant offset applied to the model.

            params (dict):
                Parameters for the sampling method, solver-specific.

            label (str, optional):
                Problem label.

            undirected_biases (boolean, default=False):
                Are (quadratic) biases specified on undirected edges? For
                triangular or symmetric matrix of quadratic biases set it to
                ``True``.

        Returns:
            :class:`~dwave.cloud.computation.Future`
        """

        # Check the problem
        if not self.check_problem(linear, quadratic):
            raise ProblemStructureError(
                f"Problem graph incompatible with {self.id} solver")

        # Mix the new parameters with the default parameters
        combined_params = dict(self._params)
        combined_params.update(params)

        # Check the parameters before submitting
        for key in combined_params:
            if key not in self.parameters and not key.startswith('x_'):
                raise KeyError("{} is not a parameter of this solver.".format(key))

        # transform some of the parameters in-place
        self._format_params(type_, combined_params)

        body_dict = {
            'solver': self.id,
            'data': encode_problem_as_qp(self, linear, quadratic, offset,
                                         undirected_biases=undirected_biases),
            'type': type_,
            'params': combined_params
        }
        if label is not None:
            body_dict['label'] = label
        body_data = json.dumps(body_dict)
        logger.trace("Encoded sample request: %s", body_data)

        body = Present(result=body_data)
        computation = Future(solver=self, id_=None, return_matrix=self.return_matrix)

        # XXX: offset is carried on Future until implemented in SAPI
        computation._offset = offset

        logger.debug("Submitting new problem to: %s", self.id)
        self.client._submit(body, computation)

        return computation
Exemplo n.º 14
0
    def _sample(self,
                type_,
                linear,
                quadratic,
                params,
                undirected_biases=False):
        """Internal method for `sample_ising`, `sample_qubo` and `sample_bqm`.

        Args:
            linear (list/dict):
                Linear terms of the model.

            quadratic (dict[(int, int), float]):
                Quadratic terms of the model.

            params (dict):
                Parameters for the sampling method, solver-specific.

            undirected_biases (boolean, default=False):
                Are (quadratic) biases specified on undirected edges? For
                triangular or symmetric matrix of quadratic biases set it to
                ``True``.

        Returns:
            :class:`Future`
        """

        args = dict(type_=type_,
                    linear=linear,
                    quadratic=quadratic,
                    params=params)
        dispatch_event('before_sample', obj=self, args=args)

        # Check the problem
        if not self.check_problem(linear, quadratic):
            raise InvalidProblemError(
                "Problem graph incompatible with solver.")

        # Mix the new parameters with the default parameters
        combined_params = dict(self._params)
        combined_params.update(params)

        # Check the parameters before submitting
        for key in combined_params:
            if key not in self.parameters and not key.startswith('x_'):
                raise KeyError(
                    "{} is not a parameter of this solver.".format(key))

        # transform some of the parameters in-place
        self._format_params(type_, combined_params)

        body_data = json.dumps({
            'solver':
            self.id,
            'data':
            encode_problem_as_qp(self,
                                 linear,
                                 quadratic,
                                 undirected_biases=undirected_biases),
            'type':
            type_,
            'params':
            combined_params
        })
        logger.trace("Encoded sample request: %s", body_data)

        body = Present(result=body_data)
        computation = Future(solver=self,
                             id_=None,
                             return_matrix=self.return_matrix)

        logger.debug("Submitting new problem to: %s", self.id)
        self.client._submit(body, computation)

        dispatch_event('after_sample',
                       obj=self,
                       args=args,
                       return_value=computation)

        return computation