-
Notifications
You must be signed in to change notification settings - Fork 11
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
Flatten entire array containers #91
Conversation
e9450ed
to
e133b9a
Compare
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 is awesome. Thanks for doing this! I tried them out in inducer/grudge#154 and they appear to work perfectly. I left some comments below, but I'm really keen to have this functionality!
arraycontext/container/traversal.py
Outdated
.. autofunction:: flatten_to_numpy | ||
.. autofunction:: unflatten_from_numpy |
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.
Maybe we should try to distinguish {flatten, unflatten}_{to,from}_numpy
from their named equivalents in meshmode.dof_array
. Though in my opinion, I think that {flatten, unflatten}_{to,from}_numpy
makes way more sense here because it's actually flattening the entire container (rather than only flattening components as is the case of meshmode.dof_array.{flatten, unflatten}_{to,from}_numpy
.
However, I am fine with just renaming these functions too. How about rec_flatten_to_numpy
and similar? rec_
because it recursively flattens?
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.
flatten_container_to_numpy
and unflatten_numpy_to_container
actually could work too.
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.
Those sound good to me! I'll wait for some more feedback, but otherwise we can rename them like that.
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.
Agree with @thomasgibson's point: We should clarify the relationship between these and the DOFArray
flatteners. Given that these do just fine without resorting to the latter, why don't we just deprecate those and define flattening generically, here? Then we wouldn't be obliged to change the name either, since it's clear that these are simply a more generic version of the former. Passing a template seems nicer anyway than passing a discretization.
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.
Agreed. One issue is that they do slightly different things:
- these flatten the whole container into one array
- the ones in
meshmode.dof_array
traverse the container and only flatten theDOFArray
s.
Not sure if anyone depends on that functionality though? So it could be safe to deprecate and point to these functions instead.
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 for spotting that! I don't think anyone is relying on the "just the DOFArray
s" aspect of those. (I'm not even sure in what scenario that would be useful.) Plus, if desired, it can be replicated with relative ease atop these new functions.
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.
Yeah, that sounds good! I'll add some deprecation warnings in there after this is in.
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 for working on this! This actually contains some interesting questions about the abstraction as a whole.
arraycontext/container/traversal.py
Outdated
.. autofunction:: flatten_to_numpy | ||
.. autofunction:: unflatten_from_numpy |
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.
Agree with @thomasgibson's point: We should clarify the relationship between these and the DOFArray
flatteners. Given that these do just fine without resorting to the latter, why don't we just deprecate those and define flattening generically, here? Then we wouldn't be obliged to change the name either, since it's clear that these are simply a more generic version of the former. Passing a template seems nicer anyway than passing a discretization.
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! I think this on a good path. A few more comments below.
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! This looks great now. Just two final wrinkles.
326cc79
to
3ccf485
Compare
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! Spotted just a few more things. I think those are it though. :)
arraycontext/container/traversal.py
Outdated
iterable = serialize_container(template_subary) | ||
except TypeError: | ||
# NOTE: the max is needed to handle device scalars with size == 0 | ||
offset += max(1, template_subary.size) |
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.
Upon thinking about it more, I don't think this is right. Device scalars report a size of 1:
>>> import numpy as np
>>> np.zeros(()).size
1
>>> a = np.zeros(())
>>> import pyopencl as cl
>>> ctx = cl.create_some_context(interactive=False)
>>> queue = cl.CommandQueue(ctx)
>>> import pyopencl.array
>>> a_dev = cl.array.to_device(queue, a)
>>> a_dev.size
1
The tests should cover device scalars and arrays that genuinely have zero size (e.g. shape=(3, 0, 4)
)
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.
Yeah, you're completely right! I removed that and added some tests in 27b894a.
A couple of wiggles there:
- for 0-sized arrays, e.g.
(18, 0)
in the test, when reshaped the strides were(0, 8)
, but the template had(8, 8)
. Not sure who's fault that is? pytato
didn't like reshaping scalars or 0-sized arrays. I'll make a small example and complain there.
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.
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.
For the first part, it seems like it's something in pyopencl
.
Hopefully inducer/compyte#36
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 looked through this PR after the latest changes and I think this looks even better. Can also confirm it works like a charm for inducer/grudge#154. I'll let @inducer have a chance to read over it but I wanted to leave my approval now. 😄
42a9a65
to
0bd1b02
Compare
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.
LGTM, aside from these final wrinkles. If you're OK with accepting all these suggestions, then this is ready to go from my end.
They look good to me! This still depends on the fixes from inducer/compyte#36 and inducer/pyopencl#514 to get the tests to pass without the added |
Those are close, too. So let's just wait on them. |
6b86fa3
to
2191fad
Compare
What's the status of this PR? Are there still issues remaining? |
The general case should work as advertised. We hit an edge case with arrays that have a 0-size in one of the axes and don't work quite yet on |
And I've been just slow to review. Sorry! |
No worries! I just wanted to make sure there wasn't a "gotcha" with this change |
Co-authored-by: Andreas Klöckner <[email protected]>
Co-authored-by: Andreas Klöckner <[email protected]>
Co-authored-by: Andreas Klöckner <[email protected]>
Co-authored-by: Andreas Klöckner <[email protected]>
2e6b650
to
b0bde7c
Compare
I wonder whether we should just |
Yeah, definitely agree with that. The EDIT: Updated the url in c50ee3e to point to the |
b0bde7c
to
c826993
Compare
Yes, sounds good to me. |
Adds two functions,
flatten
andunflatten
, that go between an array container and a 1D array (as supported by the array context).The couple of gotchas here:
serialize_container
anddeserialize_container
should not be doing anything crazy, i.e. two calls will return the components in the same order, which is the case for all the containers we have.serialiaze_container
), but that shouldn't be too much of an issue.meshmode
basically just flattenDOFArray
s and leave the rest of the array container the same.Before merging:
Point loopy back to main after Fix strides for 0-sized arrays loopy#497(xfailed the test and leaving this for later)@thomasgibson Would something like this do what you need?