-
Notifications
You must be signed in to change notification settings - Fork 50
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
Array objects of arbitrary rank are infeasible - require a reasonable range of ranks instead #479
Comments
From the
|
That seems like a reasonable change to make. I think the absolute minimum number of dimensions that are needed to support the features used in the standard (e.g., linear algebra routines with a batch dimension) is 3. In practice, >3 are used though, so it'd be good to set the number higher. Is there any library that does not support 8 dimensions? |
8 is way too small for some APIs like |
@Zac-HD What is motivating this request? Am I correct that this stems from a concern in Hypothesis? Without further context, I am leery about imposing any explicit limits on array rank in the specification, as does not make sense to me to arbitrarily impose constraints based on present practice, when we don't have a crystal ball for the future. While not constrained in Python, |
@Zac-HD Is your proposal that the spec modify its language something to the effect of
|
Presumably many of the dimensions in these cases are size 1? A rank |
I ran into this when thinking about how to generate validly-shaped arrays for Xarray (pydata/xarray#6908 (comment)), and obviously it does have implications for our Array-API I'm certainly not proposing that the specification should cap the maximum array rank. It does specify that rank-zero arrays must be supported, and I think that's worth keeping. I'm also dubious about requiring all implementations to support some specific rank - in practice rank-
Depending on the library this might be a deliberate choice like Numpy's rank-32 limit or Kokkos rank-8, or it might be implementation-defined like "your compiler will likely crash somewhere in the hundreds of dimensions". In summary: if literally nobody complies with the spec, the spec should change. |
Precisely. In many cases we encounter tensors with many axes of extent 1, so ndim can easily go beyond 32 while the whole array can still be stored on single GPU while making sense.
As mentioned above, this is not true. PyTorch does not have this limitation, so you get at least 1 compliant library 🙂 (Update: CuPy can easily go beyond ndim=32 too) |
I would think this is a safe statement. |
In [6]: torch.zeros((1,)*2000)
Out[6]: ---------------------------------------------------------------------------
RecursionError Traceback (most recent call last)
...
RecursionError: maximum recursion depth exceeded while calling a Python object Still not arbitrarily large! (I'm impressed that it handles rank-1000 though 🤯) |
My sense is that we'd still want a minimum upper bound. Otherwise, users lack portability guarantees. E.g., one may be able to perform a batch operation on a rank 10 array in library X, but then encounter an error in library Y. Would be beneficial if spec compliant array libraries all had a minimum level of support. |
Right I think Zac was suggesting the same thing too. Would also be nice to learn about the limitation in distributed array libraries. I just checked cuNumeric, they offer prebuilt binaries up to ndim=4, and building from source would support up to ndim=9. Ping @jakirkham for Dask. |
@leofang I'd want something a bit stronger than the following, however:
|
I believe the pykokkos-base templated C++ bindings built through CMake also experience a massive increase in compile time as you increase the max supported ranks from 4 to 7 or so. IIRC you can be talking about more than an hour vs. a minute and a half or so. Not sure if other libs experience that as well. |
If kokkos uses MAX_NDIM as a template parameter that would be expected. That's what cuNumeric does, too. More template instantiations to do... For NumPy/CuPy, things are easier because MAX_NDIM is only a macro that controls the lengths of a dozen of data structures. NumPy then internally loops up to MAX_NDIM and CuPy has a JIT compiler (+ such a loop in some places), so bumping it and rebuilding the library would just work. mdspan is not affected because MAX_NDIM is not used as a template parameter IIRC. I wish I know how PyTorch pulls it off 😄 |
I don't really have an opinion on this. Two thoughts, though:
|
Given that there are two libraries that only support 4 dimensions (at least by default), that should be the max we can require. Linear algebra functionality requires at least 2 dimensions to even make sense. Lots of applications do require 3 or 4 dimensions, so stating that 4 is the minimum number of dimensions supported for compliance did sound reasonable to folks in the call today. So it looks like we can adopt this phrasing after replacing "zero" by "four":
|
IIRC we explicitly mentioned "zero" out of the potential concern that 0D arrays are excluded in certain array libraries. We should just spell it out?
|
* reduce compiled view ranks from 5 to 4 in attempt to alleviate compilation memory issue * the reason for going above 3 is that 4 is the current preferred minimum for the Python array API standard per this discussion: data-apis/array-api#479
* reduce compiled view ranks from 5 to 4 in attempt to alleviate compilation memory issue * the reason for going above 3 is that 4 is the current preferred minimum for the Python array API standard per this discussion: data-apis/array-api#479
* Sync pykokkos-base with kokkos version 3.7.00 commit d19aab9 * MAINT: PR 39 revisions * reduce compiled view ranks from 5 to 4 in attempt to alleviate compilation memory issue * the reason for going above 3 is that 4 is the current preferred minimum for the Python array API standard per this discussion: data-apis/array-api#479 * Tests: add add kokkos.finalize() to tearDownClass() * CI: disable multiple cores when building pykokkos-base in python-build action to avoid running out of memory * CI: bind kokkos.is_finalized() and guard finalize() call in tearDownClass * formatting Co-authored-by: Tyler Reddy <[email protected]>
FWIW, Python buffer protocol specifies the upper limit for exchange to be 64: |
https://github.com/data-apis/array-api/blob/main/spec/API_specification/array_object.rst#17 says:
Unfortunately this is infeasible: on any computer there's going to be a finite maximum dimensionality, and in practice it's usually much smaller - e.g.
numpy.array_api
is limited to 32-dimensional arrays. When it's impossible to comply with the standard, implementations will quite reasonably choose whatever noncompliant option makes sense for them.I'd therefore propose that this should instead require implementations to support arrays with between zero and 32 dimensions inclusive (or another reasonable constant TBD), and permit implementations to support a larger number of dimensions if they wish.
The text was updated successfully, but these errors were encountered: