-
Notifications
You must be signed in to change notification settings - Fork 53
API for variable number of returns in linalg #95
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
Comments
I don't understand the technical details of that pytorch issue. Does it mean that any API that raises an exception is potentially problematic? |
Yes, because checking for the exception will cause a cross-device synchronization, which PyTorch tries very hard to avoid. In PyTorch we also have cases where error checking occurs exclusively on the CPU to avoid this issue. We intend to keep np.linalg-like error checking behavior (with a warning that it causes cross-device synchronization) but also offer This thought was also motivated by functions that return different number of tensors depending on their input args. For example, in NumPy linalg.svd can return a variable number of tensors. There are various ways this could be designed, but I would like to suggest that functions always return the same type, and it'd be nice if they were designed to be forward-compatible. For example, to accommodate returning yet another function from linalg.svd would be easy if the object returned from svd only allowed access to its tensor elements by name. Another option would be to always return a tuple that contains only the requested tensors, but I think this is a confusing and potentially dangerous UX. |
Now that there are a number of PRs up for linear algebra functions, it looks to me like the issues with variable number of returned values, order of returns, and transposes within the array even for matches shapes are pretty painful:
Some of the linalg functions that are still to be done (e.g.,
This would have some advantages:
Disadvantages:
And what it doesn't solve:
Overall, I'd still lean towards not returning custom objects. The future extensibility is be the most compelling reason to consider it though.
I agree, not a fan of this option. |
Didn't think of this before, but at least there's now a natural Python way for the "return custom objects" option - using dataclasses. All you'd need is:
Usage pattern if you just want a single returned array in the rest of your code:
and if you want them all, just carry around the object, or unpack:
That is more verbose, but there's an upside to that as well. For example for
which is probably more confusing than:
|
Which I think y'all decided was a sane idea @mruberry: pytorch/pytorch#46187. |
Comment copied from gh-18:
That's a bit nicer static typing wise, but clunkier API wise ( |
I re-read pytorch/pytorch#46187, and PyTorch deviated on purpose from NumPy in the new design by always return a tuple with the max number of elements if there's a boolean keyword to control number of returns in NumPy (e.g., The conclusion from that issue was that indeed dataclasses would be desirable long-term. |
Still discussing, PyTorch may change the above to the NumPy-compatible behaviour. |
@rgommers I believe we've addressed this issue in recently merged PRs. Notably, only return namedtuples when namedtuples are necessary (i.e., multiple return arrays); otherwise, just return an array. If libraries want to return other info (e.g., error info), they can expose a different API. So, I believe we can close this. |
Yep, yay for There's only one function left with a def unique(x, /, *, return_counts=False, return_index=False, return_inverse=False): but there's little we can do about that one. Thanks for the suggestion @mruberry! |
Feedback from @mruberry: it may be nice to support always returning the same type from functions like Cholesky, with tensors accessed by names. That way frameworks could return additional tensors and there wouldn't be BC-compatibility issues if more tensor returns are added later. This suggestion, however, comes from a place of "it'd be nice if people wanted to use this API", as opposed to the perspective of, "this API is a lowest common denominator only intended for library writers."
cholesky
always return a single array, so I thought it'd be fine - but the comment may be related to pytorch/pytorch#47608 (desire to return an error code rather than raise aRuntimeError
for failures). Forqr
,svd
and perhaps some more functions there's the related issue of different returns based on keywords. Using a class to stuff all return values in is a common design pattern for, e.g.,scipy.optimize
. I'm not convinced it's a good idea for the linalg functions here, but worth considering at least.The text was updated successfully, but these errors were encountered: