def test_submit_full_problem(self): """Submit a problem with all supported coefficients set.""" with Client(**config) as client: solver = client.get_solver() linear, quad = generate_random_ising_problem(solver) self._submit_and_check(solver, linear, quad)
def test_problem_label(self): """Problem label is set.""" with Client(**config) as client: solver = client.get_solver() linear, quad = generate_random_ising_problem(solver) self._submit_and_check(solver, linear, quad, label="test")
def test_cancel_batch(self): """Submit batch of problems, then cancel them.""" with Client(**config) as client: solver = client.get_solver() linear, quad = generate_random_ising_problem(solver) max_num_reads = max( solver.properties.get('num_reads_range', [1, 100])) result_list = [] for _ in range(1000): results = solver.sample_ising(linear, quad, num_reads=max_num_reads) result_list.append([results, linear, quad]) [r[0].cancel() for r in result_list] for results, linear, quad in result_list: # Responses must be canceled or correct try: # Did we get the right number of samples? self.assertEqual(max_num_reads, sum(results.occurrences)) # Make sure the number of occurrences and energies are all correct for energy, state in zip(results.energies, results.samples): self.assertAlmostEqual( energy, evaluate_ising(linear, quad, state)) except CanceledFutureError: pass
def test_wait_many(self): """Submit a batch of problems then use `wait_multiple` to wait on all of them.""" with Client(**config) as client: solver = client.get_solver() linear, quad = generate_random_ising_problem(solver) result_list = [] for _ in range(100): results = solver.sample_ising(linear, quad, num_reads=40) result_list.append([results, linear, quad]) dwave.cloud.computation.Future.wait_multiple( [f[0] for f in result_list]) for results, _, _ in result_list: self.assertTrue(results.done()) for results, linear, quad in result_list: # Did we get the right number of samples? self.assertEqual(40, sum(results.occurrences)) # Make sure the number of occurrences and energies are all correct for energy, state in zip(results.energies, results.samples): self.assertAlmostEqual(energy, evaluate_ising(linear, quad, state))
def test_submit_linear_problem(self): """Submit a problem with all the linear terms populated.""" with Client(**config) as client: solver = client.get_solver() linear, quad = generate_random_ising_problem(solver) self._submit_and_check(solver, linear, {})
def sample(*, config_file, profile, endpoint, region, client_type, solver_def, biases, couplings, random_problem, num_reads, label, sampling_params, verbose, json_output, output): """Submit Ising-formulated problem and return samples.""" # we'll limit max line len in non-verbose mode maxlen = None if verbose else 120 # parse params (TODO: move to click validator) params = {} if sampling_params is not None: try: params = json.loads(sampling_params) assert isinstance(params, dict) except: raise CLIError("sampling parameters required as JSON-encoded " "map of param names to values", code=99) if num_reads is not None: params.update(num_reads=num_reads) if label: params.update(label=label) # TODO: add other params, like timeout? config = dict( config_file=config_file, profile=profile, endpoint=endpoint, region=region, client=client_type, solver=solver_def) client, solver = _get_client_solver(config, output) if random_problem: linear, quadratic = generate_random_ising_problem(solver) else: try: linear = ast.literal_eval(biases) if biases else {} if isinstance(linear, Sequence): linear = dict(enumerate(linear)) except Exception as e: raise CLIError(f"Invalid biases: {e}", code=99) try: quadratic = ast.literal_eval(couplings) if couplings else {} except Exception as e: raise CLIError(f"Invalid couplings: {e}", code=99) output("Using qubit biases: {linear}", linear=list(linear.items()), maxlen=maxlen) output("Using qubit couplings: {quadratic}", quadratic=list(quadratic.items()), maxlen=maxlen) output("Sampling parameters: {sampling_params}", sampling_params=params) response = _sample( solver, problem=(linear, quadratic), params=params, output=output) if verbose: output("Result: {response!r}", response=response.result()) output("Samples: {samples!r}", samples=response.samples, maxlen=maxlen) output("Occurrences: {num_occurrences!r}", num_occurrences=response.num_occurrences, maxlen=maxlen) output("Energies: {energies!r}", energies=response.energies, maxlen=maxlen)
def test_generate_random_ising_problem(self): class MockSolver(object): nodes = [0, 1, 3] undirected_edges = {(0, 1), (1, 3), (0, 4)} properties = dict(h_range=[2, 2], j_range=[-1, -1]) mock_solver = MockSolver() lin, quad = generate_random_ising_problem(mock_solver) self.assertDictEqual(lin, {0: 2.0, 1: 2.0, 3: 2.0}) self.assertDictEqual(quad, {(0, 1): -1.0, (1, 3): -1.0, (0, 4): -1.0})
def test_generate_random_ising_problem_with_user_constrained_ranges(self): class MockSolver(object): nodes = [0, 1, 3] undirected_edges = {(0, 1), (1, 3), (0, 4)} properties = dict(h_range=[2, 2], j_range=[-1, -1]) mock_solver = MockSolver() lin, quad = generate_random_ising_problem(mock_solver, h_range=[0,0], j_range=[1,1]) self.assertDictEqual(lin, {0: 0.0, 1: 0.0, 3: 0.0}) self.assertDictEqual(quad, {(0, 1): 1.0, (1, 3): 1.0, (0, 4): 1.0})
def test_generate_random_ising_problem_default_solver_ranges(self): class MockSolver(object): nodes = [0, 1, 3] undirected_edges = {(0, 1), (1, 3), (0, 4)} properties = {} mock_solver = MockSolver() lin, quad = generate_random_ising_problem(mock_solver) for q, v in lin.items(): self.assertTrue(v >= -1 and v <= 1) for e, v in quad.items(): self.assertTrue(v >= -1 and v <= 1)
def test_submit_extra_qubit(self): """Submit a defective problem with an unsupported variable.""" with Client(**config) as client: solver = client.get_solver() # Build a linear problem and add a variable that shouldn't exist linear, quad = generate_random_ising_problem(solver) linear[max(solver.nodes) + 1] = 1 with self.assertRaises(ValueError): results = solver.sample_ising(linear, quad) results.samples
def test_submit_partial_problem(self): """Submit a problem with only some of the terms set.""" with Client(**config) as client: solver = client.get_solver() # Build a linear problem, then remove half the qubits linear, quad = generate_random_ising_problem(solver) nodes = list(solver.nodes) for index in nodes[0:len(nodes)//2]: del linear[index] quad = {key: value for key, value in quad.items() if index not in key} self._submit_and_check(solver, linear, quad)
def test_submit_bqm_problem(self): """Submit a problem with all supported coefficients set.""" with Client(**config) as client: solver = client.get_solver() linear, quad = generate_random_ising_problem(solver) bqm = dimod.BinaryQuadraticModel.from_ising(linear, quad) results = solver.sample_bqm(bqm, num_reads=100) # Did we get the right number of samples? self.assertEqual(100, sum(results.occurrences)) # Make sure the number of occurrences and energies are all correct for energy, state in zip(results.energies, results.samples): self.assertAlmostEqual(energy, evaluate_ising(linear, quad, state))
def test_submit_immediate_error_reply(self): """Handle an (obvious) error on problem submission.""" with Client('endpoint', 'token') as client: client.session = mock.Mock() client.session.post = lambda a, _: choose_reply( a, { 'endpoint/problems/': '[%s]' % immediate_error_reply( 400, "Missing parameter 'num_reads' in problem JSON") }) solver = Solver(client, solver_data('abc123')) linear, quad = generate_random_ising_problem(solver) results = solver.sample_ising(linear, quad) with self.assertRaises(SolverFailureError): results.samples
def test_as_completed(self): """Submit a batch of problems then use `as_completed` to iterate over all of them.""" with Client(**config) as client: solver = client.get_solver() linear, quad = generate_random_ising_problem(solver) # Sample the solution 100x40 times computations = [solver.sample_ising(linear, quad, num_reads=40) for _ in range(100)] # Go over computations, one by one, as they're done and check they're OK for computation in dwave.cloud.computation.Future.as_completed(computations): self.assertTrue(computation.done()) self.assertEqual(40, sum(computation.occurrences)) for energy, state in zip(computation.energies, computation.samples): self.assertAlmostEqual(energy, evaluate_ising(linear, quad, state))
def test_submit_batch(self): """Submit batch of problems.""" with Client(**config) as client: solver = client.get_solver() result_list = [] for _ in range(100): linear, quad = generate_random_ising_problem(solver) results = solver.sample_ising(linear, quad, num_reads=10) result_list.append([results, linear, quad]) for results, linear, quad in result_list: # Did we get the right number of samples? self.assertEqual(10, sum(results.occurrences)) # Make sure the number of occurrences and energies are all correct for energy, state in zip(results.energies, results.samples): self.assertAlmostEqual(energy, evaluate_ising(linear, quad, state))
def test_submit_bqm_qubo_problem(self): """Submit a QUBO BQM with all supported coefficients set.""" with Client(**config) as client: solver = client.get_solver() _, quad = generate_random_ising_problem(solver) offset = 5 # sample qubo as bqm bqm = dimod.BinaryQuadraticModel.from_qubo(quad, offset) response = solver.sample_bqm(bqm, num_reads=100) sampleset = response.sampleset # Did we get the right number of samples? self.assertEqual(100, sum(response.num_occurrences)) # Make sure the number of occurrences and energies are all correct numpy.testing.assert_array_almost_equal(bqm.energies(sampleset), sampleset.record.energy)
def sample(config_file, profile, solver_name, biases, couplings, random_problem, num_reads, verbose): """Submit Ising-formulated problem and return samples.""" # TODO: de-dup wrt ping def echo(s, maxlen=100): click.echo(s if verbose else strtrunc(s, maxlen)) try: client = Client.from_config(config_file=config_file, profile=profile) except Exception as e: click.echo("Invalid configuration: {}".format(e)) return 1 if config_file: echo("Using configuration file: {}".format(config_file)) if profile: echo("Using profile: {}".format(profile)) echo("Using endpoint: {}".format(client.endpoint)) try: solvers = client.get_solvers() except SolverAuthenticationError: click.echo("Authentication error. Check credentials in your configuration file.") return 1 except (InvalidAPIResponseError, UnsupportedSolverError): click.echo("Invalid or unexpected API response.") return 2 if solver_name and solver_name in solvers: solver = solvers[solver_name] else: try: solver = client.get_solver() except (ValueError, KeyError): if solvers: _, solver = next(iter(solvers.items())) else: click.echo("No solvers available.") return 1 echo("Using solver: {}".format(solver.id)) if random_problem: linear, quadratic = generate_random_ising_problem(solver) else: try: linear = ast.literal_eval(biases) if biases else [] except Exception as e: click.echo("Invalid biases: {}".format(e)) try: quadratic = ast.literal_eval(couplings) if couplings else {} except Exception as e: click.echo("Invalid couplings: {}".format(e)) echo("Using qubit biases: {!r}".format(linear)) echo("Using qubit couplings: {!r}".format(quadratic)) echo("Number of samples: {}".format(num_reads)) try: result = solver.sample_ising(linear, quadratic, num_reads=num_reads).result() except Exception as e: click.echo(e) return 2 if verbose: click.echo("Result: {!r}".format(result)) echo("Samples: {!r}".format(result['samples'])) echo("Occurrences: {!r}".format(result['occurrences'])) echo("Energies: {!r}".format(result['energies']))
def sample(config_file, profile, solver_def, biases, couplings, random_problem, num_reads, verbose): """Submit Ising-formulated problem and return samples.""" # TODO: de-dup wrt ping def echo(s, maxlen=100): click.echo(s if verbose else strtrunc(s, maxlen)) try: client = Client.from_config(config_file=config_file, profile=profile, solver=solver_def) except Exception as e: click.echo("Invalid configuration: {}".format(e)) return 1 if config_file: echo("Using configuration file: {}".format(config_file)) if profile: echo("Using profile: {}".format(profile)) echo("Using endpoint: {}".format(client.endpoint)) try: solver = client.get_solver() except SolverAuthenticationError: click.echo( "Authentication error. Check credentials in your configuration file." ) return 1 except (InvalidAPIResponseError, UnsupportedSolverError): click.echo("Invalid or unexpected API response.") return 2 except SolverNotFoundError: click.echo("Solver with the specified features does not exist.") return 3 echo("Using solver: {}".format(solver.id)) if random_problem: linear, quadratic = generate_random_ising_problem(solver) else: try: linear = ast.literal_eval(biases) if biases else [] except Exception as e: click.echo("Invalid biases: {}".format(e)) try: quadratic = ast.literal_eval(couplings) if couplings else {} except Exception as e: click.echo("Invalid couplings: {}".format(e)) echo("Using qubit biases: {!r}".format(linear)) echo("Using qubit couplings: {!r}".format(quadratic)) echo("Number of samples: {}".format(num_reads)) try: result = solver.sample_ising(linear, quadratic, num_reads=num_reads) result.result() except Exception as e: click.echo(e) return 4 if verbose: click.echo("Result: {!r}".format(result)) echo("Samples: {!r}".format(result.samples)) echo("Occurrences: {!r}".format(result.occurrences)) echo("Energies: {!r}".format(result.energies))