-
Notifications
You must be signed in to change notification settings - Fork 65
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature expansion and bug-fix #537
Conversation
Hi @AndyZzzZzzZzz looks like you accidentally included some extra files, including your whole virtual environment, in the commit. |
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #537 +/- ##
==========================================
- Coverage 89.66% 86.83% -2.84%
==========================================
Files 24 24
Lines 1761 1777 +16
==========================================
- Hits 1579 1543 -36
- Misses 182 234 +52 ☔ View full report in Codecov by Sentry. |
please add me and @jackraymond to reviewer |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Add a release note, see dimod readme example
- tips for writing commits 😃
- Main concern is
sample
method should not consume args for the substitute sampler. - Careful with tests due to exact solver.
tests/test_mock_sampler.py
Outdated
custom_sampler = CustomSampler() | ||
|
||
# Create a simple BQM | ||
bqm = dimod.BQM({'a': -1, 'b': -1}, {('a', 'b'): -1}, 0.0, vartype='SPIN') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At this problem size, the exact solver would be triggered. should override the default exact_solver_cutoff
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another option is to return two samples (num_reads=2) and check the second sample. This might be simpler.
tests/test_mock_sampler.py
Outdated
# Check that the sample returned is as expected from the custom sampler | ||
expected_sample = {'a': 1, 'b': 1} | ||
self.assertEqual(ss.first.sample, expected_sample) | ||
self.assertEqual(ss.first.energy, bqm.energy(expected_sample)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these assertions will pass because they coincide with exact solver's solution
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be useful if the bqm is defined so that the unique solution to the bqm is a ground state. I am not sure this is true for your Hamiltonian. If greedy initial state is (-1,-1) then flipping either spin yields energy zero and steepest descent will return the answer, but it is not a ground state.
Furthermore, define your constant sampler to return an excited state, that way it is guaranteed to conflict with both ExactSolver and SteepestDescentSolver defaults.
I've recommended code changes to achieve these things.
self.assertEqual(ss.first.sample, expected_sample) | ||
self.assertEqual(ss.first.energy, bqm.energy(expected_sample)) | ||
|
||
def test_mocking_sampler_params(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will review after the comment on whether sample
should consume kwargs
for the substitute sampler has been addressed
dwave/.DS_Store
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😛
dwave/system/testing.py
Outdated
@@ -366,7 +397,7 @@ def sample(self, bqm, **kwargs): | |||
if pair[1]!=3],dtype=float), | |||
[pair[0] for pair in initial_state if pair[1]!=3]) | |||
|
|||
ss = SteepestDescentSampler().sample(bqm, **substitute_kwargs) | |||
ss = self.substitute_sampler.sample(bqm, **substitute_kwargs) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to document that for the first sample the substitution is ignored unless self.exact_solver_cutoff=0; i.e. for small problems the first sample is always a ground state. See comment in tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good overall. One issue in the tests to address.
tests/test_mock_sampler.py
Outdated
custom_sampler = CustomSampler() | ||
|
||
# Create a simple BQM | ||
bqm = dimod.BQM({'a': -1, 'b': -1}, {('a', 'b'): -1}, 0.0, vartype='SPIN') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another option is to return two samples (num_reads=2) and check the second sample. This might be simpler.
tests/test_mock_sampler.py
Outdated
# Check that the sample returned is as expected from the custom sampler | ||
expected_sample = {'a': 1, 'b': 1} | ||
self.assertEqual(ss.first.sample, expected_sample) | ||
self.assertEqual(ss.first.energy, bqm.energy(expected_sample)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be useful if the bqm is defined so that the unique solution to the bqm is a ground state. I am not sure this is true for your Hamiltonian. If greedy initial state is (-1,-1) then flipping either spin yields energy zero and steepest descent will return the answer, but it is not a ground state.
Furthermore, define your constant sampler to return an excited state, that way it is guaranteed to conflict with both ExactSolver and SteepestDescentSolver defaults.
I've recommended code changes to achieve these things.
Co-authored-by: Jack Raymond <[email protected]>
Co-authored-by: Jack Raymond <[email protected]>
Co-authored-by: Jack Raymond <[email protected]>
Co-authored-by: Jack Raymond <[email protected]>
`sample` method. This allows users to configure the substitute sampler | ||
with specific parameters like `num_reads`, `initial_state`, or other | ||
sampler-specific options. If not provided, an empty dictionary is used | ||
by default. | ||
|
||
exact_solver_cutoff (int, optional, default=:attr:`EXACT_SOLVER_CUTOFF_DEFAULT`): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think, it would make sense that if substitute_sampler is provided then this setting is ignored and the substitute sampler is applied for all samples. We can add this clarification (afer code modification).
dwave/system/testing.py
Outdated
EXACT_SOLVER_CUTOFF_DEFAULT = 16 | ||
|
||
def __init__(self, | ||
nodelist=None, edgelist=None, properties=None, | ||
broken_nodes=None, broken_edges=None, | ||
topology_type=None, topology_shape=None, | ||
parameter_warnings=True, | ||
substitute_sampler=None, | ||
substitute_kwargs=None, | ||
exact_solver_cutoff=EXACT_SOLVER_CUTOFF_DEFAULT, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change this to None. See also comment on docstrings
if substitute_sampler is None:
substitute_sampler = SteepestDescentSampler()
if exact_solver_cutoff is None:
exact_solver_cutoff = EXACT_SOLVER_CUTOFF_DEFAULT
elif exact_solver_cutoff is None:
exact_solver_cutoff = 0 # Always use substitute_sampler, never ExactSolver()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me.
Someone @kevin should check my minor changes to test_mock_sampler.py just pushed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tests/test_mock_sampler.py
Outdated
# use SteepestDescentSampler() | ||
ss = sampler.sample(bqm, num_reads=2) | ||
self.assertEqual(sampler.exact_solver_cutoff, 0) | ||
self.assertEqual(ss.record.sample.shape, (1,2), 'Unique sample expected') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
self.assertEqual(ss.record.sample.shape, (1,2), 'Unique sample expected') | |
self.assertEqual(ss.aggregate().record.sample.shape, (1,2), 'Unique sample expected') |
self.assertEqual(ss.record.sample.shape, (1,2), 'Unique sample expected') |
covered by other test cases
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@randomir could you take another look? This should be the draft_final_final; @jackraymond and I approve.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
kwargs
overwrite order should be fixed, but generally the code looks good (minus a few nits below).
P.S. since this PR organically extends the idea of exact solver fallback, that's fine, but the switching logic is becoming to look ugly and inelegant, so I think we should generalize it (in a follow-up PR; I'll make an issue).
Co-authored-by: Radomir Stevanovic <[email protected]>
Change plain text to Sphinx style for documentation Co-authored-by: Radomir Stevanovic <[email protected]>
Co-authored-by: Radomir Stevanovic <[email protected]>
I'm happy to merge this; would you like to take a final look, @arcondello? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems reasonable to me
* WIP - added the option to switch sampler and relevant testing codes * removed the flux biases code * changed the initialization of mocking sampler from init to body * simplified substitude_kwargs * Fix num_qubits bug; raise mocked_parameters and dimod_sampler to class variable status * Add missing property. Make substitute_kwargs a class variable. * Minor corrections * Revert change to support virtual graph composite * num_qubits for pegasus fixed * moved class attributes to instance attributes * updated tests for mock dwave sampler * Revert "updated tests for mock dwave sampler" This reverts commit 89ade5f. * created a local dictionary substitue_kwargs to ensure each instance of mock sampler has its own copies * updated gitignore * Update BQM definition to simplify variable weights Co-authored-by: Jack Raymond <[email protected]> * Replace single-read sample with num_reads=2 in MockDWaveSampler test Co-authored-by: Jack Raymond <[email protected]> * Update test to validate second sample state in MockDWaveSampler Co-authored-by: Jack Raymond <[email protected]> * Remove redundant energy check in MockDWaveSampler test Co-authored-by: Jack Raymond <[email protected]> * Removed redundant comments * Polished formatting and removed changes in .gitignore * Renamed CustomSampler to ConstantSampler in test cases * Updated documentation of MockDWaveSampler * Bugfix: substitute sampler not working as expected * Removed files * Changed shortcircuit to None identity check * Modified None identity check slightly * Add ss.info.update * Added documentation for new parameters * Move comments to documentation * Update exact_solver_cutoff along with its documentation * Correct errors related to misnaming subtitute_* as mock_* * Delete duplicate file accidentally pushed * Add note on return of ascent sampler * Update dwave/system/testing.py Co-authored-by: Radomir Stevanovic <[email protected]> * Update dwave/system/testing.py Change plain text to Sphinx style for documentation Co-authored-by: Radomir Stevanovic <[email protected]> * Update dwave/system/testing.py Co-authored-by: Radomir Stevanovic <[email protected]> * Fixed indentation * Updated comment * Added subtests in TestMockSampler * Modified comments * Minor adjustment for assert statement * Added test for kwargs overwrite in TestMockDWaveSampler --------- Co-authored-by: Andy Zhang <[email protected]> Co-authored-by: Jack Raymond <[email protected]> Co-authored-by: Kevin Chern <[email protected]> Co-authored-by: Radomir Stevanovic <[email protected]>
Feature Expansion:
MockDWaveSampler
intesting.py
.SteepestDescentSampler
.mocking_sampler_params
if the user decides to use a different sampler.Tests:
test_mock_sampler.py
:Bug Fixes:
mock_parameters
,substitute_sampler
, andsubstitute_kwargs
from class attributes to instance attributes to ensure instance independence.substitute_kwarg
in thesample
function to ensure that each sample gets its own copy.