Skip to content
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

GDP-3: Duck Storages #28

Merged
merged 23 commits into from
Nov 11, 2021
Merged

GDP-3: Duck Storages #28

merged 23 commits into from
Nov 11, 2021

Conversation

gronerl
Copy link
Contributor

@gronerl gronerl commented May 26, 2020

No description provided.

docs/GDPs/gdp-duck-storage.rst Outdated Show resolved Hide resolved
docs/GDPs/gdp-duck-storage.rst Outdated Show resolved Hide resolved
docs/GDPs/gdp-duck-storage.rst Outdated Show resolved Hide resolved
docs/GDPs/gdp-duck-storage.rst Outdated Show resolved Hide resolved
docs/GDPs/gdp-duck-storage.rst Outdated Show resolved Hide resolved
docs/GDPs/gdp-duck-storage.rst Outdated Show resolved Hide resolved
docs/GDPs/gdp-duck-storage.rst Outdated Show resolved Hide resolved
docs/GDPs/gdp-duck-storage.rst Outdated Show resolved Hide resolved
docs/GDPs/gdp-duck-storage.rst Outdated Show resolved Hide resolved
docs/GDPs/gdp-duck-storage.rst Outdated Show resolved Hide resolved
@gronerl gronerl force-pushed the gdp-duck-storage branch 2 times, most recently from 12209d8 to e0c2c5c Compare June 15, 2020 16:03
@gronerl gronerl marked this pull request as ready for review June 23, 2020 23:49
docs/GDPs/gdp-0003-duck-storage.rst Outdated Show resolved Hide resolved
docs/GDPs/gdp-0003-duck-storage.rst Outdated Show resolved Hide resolved
docs/GDPs/gdp-0003-duck-storage.rst Outdated Show resolved Hide resolved
docs/GDPs/gdp-0003-duck-storage.rst Outdated Show resolved Hide resolved
docs/GDPs/gdp-0003-duck-storage.rst Outdated Show resolved Hide resolved
docs/GDPs/gdp-0003-duck-storage.rst Outdated Show resolved Hide resolved
docs/GDPs/gdp-0003-duck-storage.rst Outdated Show resolved Hide resolved
docs/GDPs/gdp-0003-duck-storage.rst Outdated Show resolved Hide resolved
docs/GDPs/gdp-0003-duck-storage.rst Outdated Show resolved Hide resolved
docs/GDPs/gdp-0003-duck-storage.rst Outdated Show resolved Hide resolved
@gronerl
Copy link
Contributor Author

gronerl commented Jun 26, 2020

I addressed some of your comments @mcgibbon . Regarding the domain, I think there should be a discussion on the terminology and semantics, also including what you mentioned regarding cell vs edge values, but also for the stencil interface etc, not only the storage.

@havogt havogt added this to Backlog in GridTools via automation Aug 5, 2020
@havogt havogt moved this from Backlog to To Do in GridTools Aug 5, 2020
@havogt havogt moved this from To Do to In Progress in GridTools Aug 18, 2020
@mbianco mbianco moved this from In Progress to To Do in GridTools Sep 2, 2020
@gronerl gronerl moved this from To Do to In Progress in GridTools Sep 15, 2020
@mbianco mbianco moved this from In Progress to Done in GridTools Oct 14, 2020
Copy link

@mcgibbon mcgibbon left a comment

Choose a reason for hiding this comment

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

Looks good! My comments are mostly stylistic, or asking for clarification on some options. The code ideas are all solid.

Comment on lines 78 to 83
Finally, without internally keeping information about the semantic meaning of dimensions, e.g. the
best layout and proper broadcasting for the resulting storage can not be determined. Further,
implementations would depend on the availability of a library implementing the operations for a
given device. We have already observed performance problems when using cupy on AMD hardware. For
future hardware, these libraries might be entirely unavailable. Therefore, we will not commit to
supporting such operations.

Choose a reason for hiding this comment

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

I agree this appears to be necessary. This in particular should be communicated to users.

Comment on lines 88 to 89
The implementation of this GDP breaks the integration with external libraries which require a NumPy
`ndarray` subclass. Further, we propose some API changes like renaming or repurposing of keyword

Choose a reason for hiding this comment

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

Could you add here a short description of how to migrate such codes? e.g. indicate what attribute name is guaranteed to be an ndarray subclass which provides access to the storage memory?

Comment on lines 96 to 98


Detailed Description

Choose a reason for hiding this comment

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

Suggested change
Detailed Description
Detailed Description

Comment on lines 126 to 127
meaning is the same as in the NumPy :code:`__array_interface__` and the
:code:`__cuda_array_interface__`:

Choose a reason for hiding this comment

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

A hyperlink to numpy/cupy documentation would be helpful here.

+ :code:`"data": Tuple[int, bool]`
+ :code:`"strides": Tuple[int, ...]`

In Addition, the following optional keys can be contained:

Choose a reason for hiding this comment

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

Suggested change
In Addition, the following optional keys can be contained:
In addition, the following optional keys can be contained:

the respective dimension, which can be used to denote asymmetric halos. It defaults to no halo,
i.e. :code:`(0, 0, 0)`. (See also Section :ref:`domain_and_halo`)

:code:`layout: Optional[Sequence[int]]`

Choose a reason for hiding this comment

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

nit: layout is a slightly overloaded term, we're using it already to indicate the number of ranks along edges of a tile face. Could this be named stride_order or something similar?

Choose a reason for hiding this comment

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

When using as_storage, is this derived by default from the array passed as input? If so, can you describe that here? Also, what is the interplay between this and the dims argument, if only one is given?

Comment on lines 456 to 457
The rationale behind this is that in this way, storages allocated with :code:`defaults` set to a
backend will always get optimal performance, while :code:`defaults` set to :code:`"F"` or

Choose a reason for hiding this comment

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

This sounds like it disagrees somewhat with the last paragraph of the introduction.

Comment on lines 460 to 463
:code:`managed: Optional[str]`
:code:`None`, :code:`"gt4py"` or :code:`"cuda"`. It only has effect if :code:`device="gpu"` and
it specifies whether the synchronization between the host and device buffers is not done
(:code:`None`), GT4Py (:code:`"gt4py"`) or CUDA (:code:`"cuda"`). It defaults to :code:`"gt4py"`

Choose a reason for hiding this comment

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

What's the difference in behavior between None and cuda? It could be worth having a short description of what GT4Py and CUDA management are.

Comment on lines 465 to 471
The values of parameters which are not explicitly defined by the user will be inferred from the
first alternative source where the parameter is defined in the following search order:

1. The provided :code:`defaults` parameter set.
2. The provided :code:`data` or :code:`device_data` parameters.
3. A fallback default value specified above. The only case where this is not available is
:code:`shape`, in which case an exception is raised.

Choose a reason for hiding this comment

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

This part about inferring parameters should probably be written at the start of this section. Which parameters can be derived from data/device_data, and how are they derived?

Internally holds a reference to a `CuPy <https://cupy.chainer.org/>`_ `ndarray`. This storage
does not have a CPU buffer.

:code:`SoftwareManagedGPUStorage`

Choose a reason for hiding this comment

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

nit: The previous name of ExplicitlyManaged was good for this object, I think. "Software" reads like an external binary running on the host system outside of Python. It contrasts well with CUDAManagedGPUStorage.

mcgibbon pushed a commit to ai2cm/fv3gfs-util that referenced this pull request Nov 10, 2020
Accessing `.storage` on a quantity which was initialized with a numpy or cupy array and a gt4py_backend value currently causes `view` to become out of sync with the underlying data of the quantity, since the data is re-allocated in creating the storage but the view is unchanged and retains a reference to the old data. This PR updates the routine which re-allocates the data to also update the view.

This is a work-around to deal with not being able to initialize gt4py storages from existing numpy or cupy arrays. We should be able to remove the work-around after GDP-3 (GridTools/gt4py#28) is merged.
Comment on lines 136 to 137
+ :code:`"acquire": Optional[Callable[[], Any]]` Is called on all objects that are passed to a
stencil, before running computations. It can be used to trigger a copy to the respective device.
Copy link

Choose a reason for hiding this comment

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

I just realized I got mixed up to think that acquire was an argument passed to stencil, not one passed to storage. I would suggest this re-wording to make it clearer:

Suggested change
+ :code:`"acquire": Optional[Callable[[], Any]]` Is called on all objects that are passed to a
stencil, before running computations. It can be used to trigger a copy to the respective device.
+ :code: The `"acquire": Optional[Callable[[], Any]]` method of each object passed to a
stencil is called before running computations. It can be used to trigger a copy to the respective device.

Knowing that, does the acquire function need any information about the device the stencil is about to be run on?

@havogt
Copy link
Contributor

havogt commented Sep 28, 2021

@gronerl or @egparedes can you summarize what led to decision to close it, then we can merge it as declined.

@gronerl
Copy link
Contributor Author

gronerl commented Nov 3, 2021

After this GDP and its reference implementation have not gained any traction for roughly a year, and after more discussions offline, we propose to decline this GDP.
The main points why this GDP is not the right way for storages are as follows.

The original motivation for this GDP was that moving away from the design where storages are subclasses of np.ndarray. The GDP proposed to make this change so that one-sided changes to coupled host/device buffers managed by GT4Py storages can be more reliably tracked, since functionality is not handled by the parent class. This issue is indeed solved by the GDP. However, it just moves the problem to a new one: The changes that can now be tracked will often require the allocation of a new buffer, for which performance optimal allocation can not be guaranteed based on the information available.

Resolving this in any way leads to a storage that is either severely limited in functionality, which prompts users to escape to different frameworks anyways (as is the case with the old storages), or that performance may be severely impacted depending on the exact use of the storages, which is not transparent to the user. In other cases the behavior may be unintuitive (broadcasting, slicing). Overall it seems impossible to find a solution that is a good trade off for a substantial share of all use cases.

Instead, we currently propose to pursue a "No Storage" approach in the future. The idea there would be that gt4py provides utilities that allocate buffers which have desireable properties for stencils, yet the framework will not provide any methods on the buffers, i.e. it is up to the user to fill values in the allocated memory, implement ufuncs if desired etc.

However, a generic interface like the __gt_data_interface__ proposed in this GDP is still assumed to be necessary.

Please, raise objections to declining this GDP until Nov 10, 2021.

@ofuhrer
Copy link
Contributor

ofuhrer commented Nov 4, 2021

@mcgibbon Thoughts?

@mcgibbon
Copy link

mcgibbon commented Nov 4, 2021

It feels like less is more when it comes to storages, and this seems to fit the bill. It sounds exciting to be able to provide gt_data_interface on our Quantity class some day and have that be treated directly as a Storage.

@gronerl
Copy link
Contributor Author

gronerl commented Nov 11, 2021

I'm pasting some remarks by @jdahm on Slack to preserve them:


johann  8 days ago
I assume this would still be limited to arrays that implement the buffer protocol? We'd also still need a default_origin, but I suppose that could be in a thin wrapper on top of an array. (edited) 




Linus  8 days ago
Yeah, the intention would be to put that info in the __gt_data_interface__ ...i.e. your thin wrapper could expose it in that way. For your FrozenStencils it shouldn't be needed anyways though, right?

johann  8 days ago
I'm more in favor of keeping the default_origin, and using a cached stencil argument approach, but both should be possible.

johann  8 days ago
Correct, it is a hands-off approach where the origins are handled in the application instead of the storage.

Linus  8 days ago
Of course that idea isn't fully shaped yet, so the specifics of specifying origins can be discussed.

Copy link
Contributor

@egparedes egparedes left a comment

Choose a reason for hiding this comment

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

Agree with the conclusions.

@egparedes egparedes merged commit 9057f90 into GridTools:master Nov 11, 2021
tehrengruber pushed a commit to tehrengruber/gt4py that referenced this pull request Jul 28, 2022
…onstruct_inside

Remove code duplication and decrease complexity of PAST Lowering
@gronerl gronerl deleted the gdp-duck-storage branch January 20, 2023 10:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
GridTools
  
Done
Development

Successfully merging this pull request may close these issues.

None yet

7 participants