-
Notifications
You must be signed in to change notification settings - Fork 191
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
Fix result representation for TDM programs #493
Conversation
Codecov Report
@@ Coverage Diff @@
## master #493 +/- ##
=======================================
Coverage 97.85% 97.85%
=======================================
Files 70 70
Lines 7313 7313
=======================================
Hits 7156 7156
Misses 157 157
Continue to review full report at Codecov.
|
strawberryfields/api/result.py
Outdated
return "<Result: spatial_modes={}, shots={}, timebins={} contains state={}>".format( | ||
modes, shots, timebins, self._is_stateful |
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.
Think this would be good to keep the order from the shape. Let me know if the change in order was deliberate though!
return "<Result: spatial_modes={}, shots={}, timebins={} contains state={}>".format( | |
modes, shots, timebins, self._is_stateful | |
return "<Result: shots={}, spatial_modes={}, timebins={} contains state={}>".format( | |
shots, modes, timebins, self._is_stateful |
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 also think this looks nicer to be honest. I just kept the same form as the current repr (for GBS samples) which starts with modes, and then shots. I might just update it in both places if you also think that makes more sense.
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.
Hmm, think it's good to keep the shape order. As for changing for GBS, not quite sure if that would cause any troubles somewhere (don't think so) 🤔.
strawberryfields/api/result.py
Outdated
shots, modes = self.samples.shape | ||
try: | ||
shots, modes = self.samples.shape | ||
except ValueError: |
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.
Think this would work fine for now actually! 💯 Would be great to add a test though.
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.
Thanks @antalszava. I've added a test now! You were a bit too quick (and I maybe tagged you for a review a bit too quickly). 😆
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.
Hi @thisac the fix is looking great! A test might be nice and then I think it should be good to go.
result = Result(samples) | ||
print(result) | ||
out, err = capfd.readouterr() | ||
assert "spatial_modes=3" in out |
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.
💯 Might be cool to check the order (not too important though).
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 this is fine (since the order isn't actually that important I would say).
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! 💯
Co-authored-by: antalszava <antalszava@gmail.com>
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.
Thanks @thisac - just a small comment regarding the existing try-except logic
Result: 3 subsystems | ||
state: <GaussianState: num_modes=3, pure=True, hbar=2> | ||
samples: [[0, 0, 0]] | ||
<Result: shots=1, num_modes=3, contains state=True> |
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.
Good catch, was this accidentally out of date?
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.
Yes it was, not sure why.
strawberryfields/api/result.py
Outdated
modes, shots, self._is_stateful | ||
try: | ||
shots, modes = self.samples.shape | ||
except ValueError: |
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'm wondering if there is something better we can catch here than a ValueError
, since this exception class is a very common class that could be raised for a whole different host of (unforseen) reasons.
I'm thinking checking the number of dimensions on the samples should be sufficient, e.g.,
def __repr__(self):
if self.samples.ndim == 2:
shots, modes = self.samples.shape
return "<Result: shots={}, num_modes={}, contains state={}>".format(shots, modes, self._is_stateful)
if self.samples.ndim == 3:
shots, modes, timebins = self.samples.shape
return "<Result: shots={}, spatial_modes={}, timebins={} contains state={}>".format(
shots, modes, timebins, self._is_stateful
)
return "<Result: contains state={}>"
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.
This has a couple of advantages from what I can see:
-
It is explicit
-
It avoids catching
ValueError
exceptions, which are too general -
If there are changes in the future, it will not break printing; it will gracefully fail without attempting to print sample information.
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.
Thanks @josh146. I think this is a good solution as well. Updated it to follow your logic above and added a test.
strawberryfields/engine.py
Outdated
[strawberryfields.api.Result, None]: the job result if successful, and | ||
``None`` otherwise | ||
``None`` otherwise |
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.
Typically we do not indent continuation lines in the returns statement, it will cause Sphinx to render the block incorrectly. Only continuation lines in the Args:
section need to be indented.
Moreover, it's a bit weird that there are square brakets here; it should look like this:
strawberryfields.api.Result, None: the job result if successful or ``None`` otherwise
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.
Oh, I didn't actually know. Fixed now!
Co-authored-by: Josh Izaac <josh146@gmail.com>
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 great! 💯
def test_unkown_shape_print(self, stateful, capfd): | ||
"""Test that printing a result object with samples with an unknown shape | ||
provides the correct output.""" |
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.
Nice!
Co-authored-by: Josh Izaac <josh146@gmail.com>
Context:
Currently the representation of the
Result
object doesn't work for TDM programs due to the samples having dimension 3 (shots, spatial modes, timebins) instead of 2.Description of the Change:
Quick fix that assumes that it's a TDM program if the samples dim is 3, and thus prints the correct representation.
Benefits:
Just writing
eng.run(tdm_prog)
orres = eng.run(tdm_prog); print(res)
works, and actually prints something useful.Possible Drawbacks:
Might not be the nicest solution, but since
Result
doesn't know what type of program the samples are from, I think this works well for now. Might need to be revisited later with some further changes to theResult
class (incorporating e.g. where the results are from).Related GitHub Issues:
None