dwave-cloud-client
dwave-cloud-client copied to clipboard
Active Qubit definitions are not handled properly when h is sent as a list - impacts reverse annealing
here are some code snippets that work and doesn't work lets initialize stuff:
con = Client(endpoint=url, token=token, permissive_ssl=True)
solver = con.get_solver(solver_name)
h = [0] * 2048
J = {(1, 5): -1, (0, 5): -1, (1, 4): -1, (0, 4): -1}
anneal_schedule = [[0, 1], [0.2, 0.8], [8.2, 0.8], [8.4, 1.0]]
here if I send in an empty dict for h, and define the active qubits to be the qubits used in J, its all good
initial = []
activeQ = {i for k in J for i in k}
for i in range(solver.properties['num_qubits']):
if i in activeQ:
initial.append(1)
else:
initial.append(3)
solsnp = solver.sample_ising({},J,
initial_state=initial,
num_reads=1,
anneal_schedule=anneal_schedule)
print solsnp.energies
---> [-4.0]
Now if I change my h submission into a [0]*2048, I get the following error, which is possibly due to creating a h -dict from the 0 h list that turns all activatable qubits active
initial = []
activeQ = {i for k in J for i in k}
for i in range(solver.properties['num_qubits']):
if i in activeQ:
initial.append(1)
else:
initial.append(3)
solsnp = solver.sample_ising(h,J,
initial_state=initial,
num_reads=1,
anneal_schedule=anneal_schedule)
print solsnp.energies
----->
Traceback (most recent call last):
File "/home/iozfidan/jupyter/sapitests/tests.py", line 82, in <module>
print solsnp.energies
File "/home/iozfidan/miniconda3/envs/dxf_dev/lib/python2.7/site-packages/dwave/cloud/computation.py", line 485, in energies
return self.result()['energies']
File "/home/iozfidan/miniconda3/envs/dxf_dev/lib/python2.7/site-packages/dwave/cloud/computation.py", line 454, in result
self._load_result()
File "/home/iozfidan/miniconda3/envs/dxf_dev/lib/python2.7/site-packages/dwave/cloud/computation.py", line 621, in _load_result
raise self.error
dwave.cloud.exceptions.SolverFailureError: initial_state must be specified for all active qubits
I can prove the above statement by replacing the definition of activeQ to include all alive qubits
activeQ = solver.properties['qubits']
for i in range(solver.properties['num_qubits']):
if i in activeQ:
initial.append(1)
else:
initial.append(3)
solsnp = solver.sample_ising(h,J,
initial_state=initial,
num_reads=1,
anneal_schedule=anneal_schedule)
print solsnp.energies
---> [-4.0]
This is actually a bug. even when h is sent in as a dict it is still not handled properly.
[Just to first document the discussion we had offline.]
All qubits referenced in h
or J
are declared active.
If you supply [0] * 2048
for h
, all 2048 qubits will be active, that's the expected behaviour. But as we concluded previously, it's probably not most intuitive. That's why we said we'll switch to (or at least strongly prefer) the dict
definition for both h
and J
).
I'm investigating your last comment (dict bug).
example:
h={848: 0, 709: 0, 587: 0, 717: 0, 590: 0, 720: 0, 334: 0, 342: 0}
J={(720, 848): -2, (709, 717): -2, (587, 590): -2, (342, 334): -2}
initial_state = [3]*2048
for q in [720, 709, 587, 717, 590, 848, 334, 342]:
initial_state[q]=1
gives
SolverFailureError: initial_state must be specified for all active qubits
the only way to not receive an error is if I define initial states as
initial_state = [3]*2048
for q in solver.properties['qubits']: initial_state[q] = 1
Yes, I'm getting the same error.
The problem is SAPI downstream expects 3s for inactive qubits in initial_state
, and we're trying to abstract inactive qubits away from users. initial_state
(or any other solver-specific parameter) is not modified by the client. And in general it would be hard to modify it, unless we declare initial_state
is uniquely named and a general solver param.
That being said, I don't see any other way of moving forward.
We'll have to handle initial_state
with special care, treat it as a unique unicorn... And open a pandora box of specialized parameters pre/post-processing.