Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@jgosmann
Copy link
Collaborator

@jgosmann jgosmann commented Sep 20, 2017

Motivation and context:
As noted in #1358 trying to inspect the default arguments has two problems:

  • It prevents the usage of the (*args, **kwargs) idiom to write a wrapper for solvers.
  • The solvers don't specify the actual RNG being used as default argument, but None and retrieve np.random later. So the RNG state was not saved anyways when relying on the default arguments (but I believe the builder always sets the rng argument, so that this bug did not ocurr in practice).

Instead of inspecting the defaults, E is assumed to be always None by default (any other default would seem quite weird to me) and rng is set to np.random if None.

By setting the RNG explicitly, all cached solvers will depend on the RNG state. This means that decoders are only reused if the RNG state matches even though the solver might be independent of the RNG. Unfortunately, there is no way to know whether the solver will use the RNG and this issue did exist before.

Fixes #1358.

Interactions with other PRs:
none

How has this been tested?
Unit tests still pass. I did not test the original issue reported in #1358, but as the failing code was completely removed, it should be resolved. Not sure if we should add a regression test. It seems weird to write a test that tests that the code isn't doing certain things and it seems unlikely that #1358 is reintroduced. I also did not add a test for the hashing of the RNG state because it seems to be quite awkward to test (without gaining much). But I could probably be swayed to add tests.

How long should this take to review?

  • Quick (less than 40 lines changed or changes are straightforward)

Types of changes:

  • Bug fix (non-breaking change which fixes an issue)

Checklist:

  • I have read the CONTRIBUTING.rst document.
  • [n/a] I have updated the documentation accordingly.
  • I have included a changelog entry.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

nengo/cache.py Outdated
if E is None and 'E' in args:
E = defaults[args.index('E')]
if rng is None:
rng = np.random
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can I ask if there's a reason to specify the default this way rather than in the arg list? I know putting mutable things as a default can be problematic, but in this case np.random is mutable but also global so it would be the same were it mutated.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am just following what's done in solvers.py, but I was wondering the same thing.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I say change it both places 👍

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can do! Tagging @hunse who changed it to what it is now in 63c2104 in case we overlooked something.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did I change this... that's a good question! It might have been so that all the solvers would have the same default rng=None, whether they actually use an rng or not, and maybe I thought it kept the function signature a bit cleaner, too. But I'm fine making the change suggested here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed in both places. :)

@jgosmann jgosmann self-assigned this Sep 22, 2017
jgosmann added a commit that referenced this pull request Sep 26, 2017
The np.random object is mutable, but also global. Thus, the idiom with
a default of None is not required. See
#1359 (comment)
for further discussion.
@jgosmann jgosmann removed their assignment Sep 26, 2017
Copy link
Member

@tbekolay tbekolay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for changing all the solvers! 🌈

@tbekolay tbekolay requested a review from AllenHW October 5, 2017 19:06
Copy link
Contributor

@Seanny123 Seanny123 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Setting the rng in the argument freaked me out a little, because of this Python gotchya for mutable arguments, but I now understand that np.random is not mutable in any significant way so it's not a problem.

The np.random object is mutable, but also global.
Thus, the idiom with a default of None is not required.
See #1359 for further discussion.
@tbekolay tbekolay force-pushed the fix-cache-arg-inspect branch from 6ff3aa6 to 87faf37 Compare October 25, 2017 19:58
@tbekolay tbekolay merged commit 87faf37 into master Oct 25, 2017
@tbekolay tbekolay deleted the fix-cache-arg-inspect branch October 25, 2017 20:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

Custom solver __call__ must have default arguments

5 participants