cunumpy 0.6.0__tar.gz → 0.6.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. {cunumpy-0.6.0 → cunumpy-0.6.1}/PKG-INFO +5 -3
  2. {cunumpy-0.6.0 → cunumpy-0.6.1}/README.md +4 -2
  3. {cunumpy-0.6.0 → cunumpy-0.6.1}/pyproject.toml +1 -1
  4. {cunumpy-0.6.0 → cunumpy-0.6.1}/src/cunumpy/LLM_GUIDE.md +2 -2
  5. {cunumpy-0.6.0 → cunumpy-0.6.1}/src/cunumpy/_cuda_kernel.py +9 -9
  6. {cunumpy-0.6.0 → cunumpy-0.6.1}/src/cunumpy/_emulation.py +2 -2
  7. {cunumpy-0.6.0 → cunumpy-0.6.1}/src/cunumpy/cuda/include/cunumpy/array_view.cuh +148 -4
  8. {cunumpy-0.6.0 → cunumpy-0.6.1}/src/cunumpy.egg-info/PKG-INFO +5 -3
  9. {cunumpy-0.6.0 → cunumpy-0.6.1}/setup.cfg +0 -0
  10. {cunumpy-0.6.0 → cunumpy-0.6.1}/src/cunumpy/__init__.py +0 -0
  11. {cunumpy-0.6.0 → cunumpy-0.6.1}/src/cunumpy/__init__.pyi +0 -0
  12. {cunumpy-0.6.0 → cunumpy-0.6.1}/src/cunumpy/_algorithms.py +0 -0
  13. {cunumpy-0.6.0 → cunumpy-0.6.1}/src/cunumpy/_device.py +0 -0
  14. {cunumpy-0.6.0 → cunumpy-0.6.1}/src/cunumpy/_dispatch.py +0 -0
  15. {cunumpy-0.6.0 → cunumpy-0.6.1}/src/cunumpy/_fake_cupy.py +0 -0
  16. {cunumpy-0.6.0 → cunumpy-0.6.1}/src/cunumpy/_fake_cupy_impl.py +0 -0
  17. {cunumpy-0.6.0 → cunumpy-0.6.1}/src/cunumpy/_fusion.py +0 -0
  18. {cunumpy-0.6.0 → cunumpy-0.6.1}/src/cunumpy/_kernel.py +0 -0
  19. {cunumpy-0.6.0 → cunumpy-0.6.1}/src/cunumpy/_mirror.py +0 -0
  20. {cunumpy-0.6.0 → cunumpy-0.6.1}/src/cunumpy/_morton.py +0 -0
  21. {cunumpy-0.6.0 → cunumpy-0.6.1}/src/cunumpy/_mpi.py +0 -0
  22. {cunumpy-0.6.0 → cunumpy-0.6.1}/src/cunumpy/_philox.py +0 -0
  23. {cunumpy-0.6.0 → cunumpy-0.6.1}/src/cunumpy/_profiling.py +0 -0
  24. {cunumpy-0.6.0 → cunumpy-0.6.1}/src/cunumpy/_random_streams.py +0 -0
  25. {cunumpy-0.6.0 → cunumpy-0.6.1}/src/cunumpy/_scipy_backend.py +0 -0
  26. {cunumpy-0.6.0 → cunumpy-0.6.1}/src/cunumpy/_staging.py +0 -0
  27. {cunumpy-0.6.0 → cunumpy-0.6.1}/src/cunumpy/_streams.py +0 -0
  28. {cunumpy-0.6.0 → cunumpy-0.6.1}/src/cunumpy/_transfers.py +0 -0
  29. {cunumpy-0.6.0 → cunumpy-0.6.1}/src/cunumpy/algorithms.py +0 -0
  30. {cunumpy-0.6.0 → cunumpy-0.6.1}/src/cunumpy/arguments.py +0 -0
  31. {cunumpy-0.6.0 → cunumpy-0.6.1}/src/cunumpy/cuda/__init__.py +0 -0
  32. {cunumpy-0.6.0 → cunumpy-0.6.1}/src/cunumpy/cuda/include/cunumpy/atomic.cuh +0 -0
  33. {cunumpy-0.6.0 → cunumpy-0.6.1}/src/cunumpy/cuda/include/cunumpy/index.cuh +0 -0
  34. {cunumpy-0.6.0 → cunumpy-0.6.1}/src/cunumpy/cuda/include/cunumpy/morton.cuh +0 -0
  35. {cunumpy-0.6.0 → cunumpy-0.6.1}/src/cunumpy/cuda/include/cunumpy/random.cuh +0 -0
  36. {cunumpy-0.6.0 → cunumpy-0.6.1}/src/cunumpy/cuda/include/cunumpy/reduce.cuh +0 -0
  37. {cunumpy-0.6.0 → cunumpy-0.6.1}/src/cunumpy/cuda/include/cunumpy/scan.cuh +0 -0
  38. {cunumpy-0.6.0 → cunumpy-0.6.1}/src/cunumpy/kernel_testing.py +0 -0
  39. {cunumpy-0.6.0 → cunumpy-0.6.1}/src/cunumpy/kernels.py +0 -0
  40. {cunumpy-0.6.0 → cunumpy-0.6.1}/src/cunumpy/memory.py +0 -0
  41. {cunumpy-0.6.0 → cunumpy-0.6.1}/src/cunumpy/mpi.py +0 -0
  42. {cunumpy-0.6.0 → cunumpy-0.6.1}/src/cunumpy/petsc.py +0 -0
  43. {cunumpy-0.6.0 → cunumpy-0.6.1}/src/cunumpy/profiling.py +0 -0
  44. {cunumpy-0.6.0 → cunumpy-0.6.1}/src/cunumpy/py.typed +0 -0
  45. {cunumpy-0.6.0 → cunumpy-0.6.1}/src/cunumpy/rng.py +0 -0
  46. {cunumpy-0.6.0 → cunumpy-0.6.1}/src/cunumpy/xp.py +0 -0
  47. {cunumpy-0.6.0 → cunumpy-0.6.1}/src/cunumpy.egg-info/SOURCES.txt +0 -0
  48. {cunumpy-0.6.0 → cunumpy-0.6.1}/src/cunumpy.egg-info/dependency_links.txt +0 -0
  49. {cunumpy-0.6.0 → cunumpy-0.6.1}/src/cunumpy.egg-info/requires.txt +0 -0
  50. {cunumpy-0.6.0 → cunumpy-0.6.1}/src/cunumpy.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cunumpy
3
- Version: 0.6.0
3
+ Version: 0.6.1
4
4
  Summary: Simple wrapper for numpy and cupy. Replace `import numpy as np` with `import cunumpy as xp`.
5
5
  Author: Max
6
6
  Project-URL: Source, https://github.com/max-models/cunumpy
@@ -434,7 +434,7 @@ kernel(particles.args_markers, dt) # host or CUDA kernel
434
434
  Kernels ported from pyccel index arrays like `markers[ip, j]`, which needs
435
435
  shapes and strides rather than bare pointers. The shipped header
436
436
  `cunumpy/array_view.cuh` (found by every `CudaKernel`) provides the strided
437
- views `Array1D<T>` to `Array4D<T>`; a parameter or struct field of that type
437
+ views `Array1D<T>` to `Array16D<T>`; a parameter or struct field of that type
438
438
  takes a CuPy array, contiguous or not, and indexes `a(i, j)`. The struct can be
439
439
  generated from the annotations of the pyccel argument class, so the Python
440
440
  class is the one definition, and written to a header that a test keeps in sync:
@@ -444,7 +444,9 @@ class MarkerArguments:
444
444
  def __init__(self, markers: "float[:, :]", n_markers: int, valid: "bool[:]"): ...
445
445
 
446
446
 
447
- MarkerArgs = xp.arguments.CudaStruct.from_signature(MarkerArguments.__init__, "MarkerArgs")
447
+ MarkerArgs = xp.arguments.CudaStruct.from_signature(
448
+ MarkerArguments.__init__, "MarkerArgs"
449
+ )
448
450
  MarkerArgs.to_header(
449
451
  "marker_args.cuh"
450
452
  ) # Array2D<double> markers; long long n_markers; ...
@@ -394,7 +394,7 @@ kernel(particles.args_markers, dt) # host or CUDA kernel
394
394
  Kernels ported from pyccel index arrays like `markers[ip, j]`, which needs
395
395
  shapes and strides rather than bare pointers. The shipped header
396
396
  `cunumpy/array_view.cuh` (found by every `CudaKernel`) provides the strided
397
- views `Array1D<T>` to `Array4D<T>`; a parameter or struct field of that type
397
+ views `Array1D<T>` to `Array16D<T>`; a parameter or struct field of that type
398
398
  takes a CuPy array, contiguous or not, and indexes `a(i, j)`. The struct can be
399
399
  generated from the annotations of the pyccel argument class, so the Python
400
400
  class is the one definition, and written to a header that a test keeps in sync:
@@ -404,7 +404,9 @@ class MarkerArguments:
404
404
  def __init__(self, markers: "float[:, :]", n_markers: int, valid: "bool[:]"): ...
405
405
 
406
406
 
407
- MarkerArgs = xp.arguments.CudaStruct.from_signature(MarkerArguments.__init__, "MarkerArgs")
407
+ MarkerArgs = xp.arguments.CudaStruct.from_signature(
408
+ MarkerArguments.__init__, "MarkerArgs"
409
+ )
408
410
  MarkerArgs.to_header(
409
411
  "marker_args.cuh"
410
412
  ) # Array2D<double> markers; long long n_markers; ...
@@ -5,7 +5,7 @@ requires = [ "setuptools", "wheel" ]
5
5
 
6
6
  [project]
7
7
  name = "cunumpy"
8
- version = "0.6.0"
8
+ version = "0.6.1"
9
9
  description = "Simple wrapper for numpy and cupy. Replace `import numpy as np` with `import cunumpy as xp`."
10
10
  readme = "README.md"
11
11
  keywords = [ "python" ]
@@ -96,7 +96,7 @@ https://max-models.github.io/cunumpy/ and in `docs/source/` of the repository.
96
96
  | PETSc solve on device arrays without copies | `xp.petsc.petsc_vec(array)` (CUDA/HIP petsc4py for CuPy arrays); `xp.synchronize()` around PETSc calls |
97
97
  | reduction inside a CUDA kernel (energy, max velocity) | `<cunumpy/reduce.cuh>`: `cunumpy_block_sum_to(out, v)`, `cunumpy_block_min/max`, `cunumpy_warp_sum` |
98
98
  | kernel writes into a host buffer owned by another library | `xp.memory.DeviceMirror(host_array)` + `<cunumpy/atomic.cuh>` |
99
- | N-D indexing in CUDA, non-contiguous arrays | `Array1D<T>`..`Array4D<T>` params from `<cunumpy/array_view.cuh>` |
99
+ | N-D indexing in CUDA, non-contiguous arrays | `Array1D<T>`..`Array16D<T>` params from `<cunumpy/array_view.cuh>` |
100
100
  | one MPI rank per GPU | `bind_local_device()` → `from mpi4py import MPI` → `require_cuda_aware_mpi()` → `synchronize_for_mpi(...)` before each call |
101
101
  | timing GPU code | `with xp.profiling.timed_region("name") as t:` → `t.elapsed` |
102
102
  | profiler markers | `xp.profiling.nvtx_range("name")` (context manager or decorator) |
@@ -307,7 +307,7 @@ Shipped CUDA headers (always on the include path):
307
307
 
308
308
  ```c
309
309
  #include <cunumpy/index.cuh> // CUNUMPY_THREAD_1D(i, n) /_2D/_3D, CUNUMPY_GRID_STRIDE_1D(i, n) {...}
310
- #include <cunumpy/array_view.cuh> // Array1D<T>..Array4D<T>: data, shape[], strides[] (elements), a(i, j), size()
310
+ #include <cunumpy/array_view.cuh> // Array1D<T>..Array16D<T>: data, shape[], strides[] (elements), a(i, j), size()
311
311
  #include <cunumpy/atomic.cuh> // cunumpy_atomic_add(double*|float*, v), _2d(data, n1, i, j, v), _3d(...)
312
312
  ```
313
313
 
@@ -123,7 +123,7 @@ def cuda_include_dir() -> str:
123
123
 
124
124
  :class:`CudaKernel` adds it to the include path automatically, so kernels
125
125
  can ``#include "cunumpy/array_view.cuh"`` (strided ``Array1D<T>``
126
- to ``Array4D<T>`` views passed by value) and
126
+ to ``Array16D<T>`` views passed by value) and
127
127
  ``#include "cunumpy/index.cuh"`` (thread-index and grid-stride macros such
128
128
  as ``CUNUMPY_THREAD_1D(i, n)``), ``#include "cunumpy/atomic.cuh"`` (atomic
129
129
  adds) and ``#include "cunumpy/reduce.cuh"`` (warp and block reductions).
@@ -188,7 +188,7 @@ class CudaParameter(NamedTuple):
188
188
  The struct type, for a struct passed by value.
189
189
  view_ndim : int | None
190
190
  The number of dimensions, for an array view (``Array1D<T>`` to
191
- ``Array4D<T>`` or ``CArray1D<T>`` to ``CArray4D<T>``, see
191
+ ``Array16D<T>`` or ``CArray1D<T>`` to ``CArray16D<T>``, see
192
192
  :func:`cuda_include_dir`) passed by value.
193
193
  contiguous : bool
194
194
  Whether the array view is C-contiguous (``CArray2D<T>``): packed
@@ -265,11 +265,11 @@ _CTYPE_OF = {
265
265
  _QUALIFIERS = {"const", "volatile", "__restrict__", "__restrict", "restrict"}
266
266
 
267
267
  _COMPLEX = re.compile(r"(?:(?:thrust|cuda::std)::)?complex\s*<\s*(float|double)\s*>")
268
- # Array1D<T> to Array4D<T> and CArray1D<T> to CArray4D<T> (cunumpy/array_view.cuh),
268
+ # Array1D<T> to Array16D<T> and CArray1D<T> to CArray16D<T> (cunumpy/array_view.cuh),
269
269
  # T a scalar type of _CTYPES
270
- _VIEW = re.compile(r"\b(C?)Array([1234])D\s*<((?:[^<>]|complex<[^<>]*>)+?)>")
270
+ _VIEW = re.compile(r"\b(C?)Array([1-9]|1[0-6])D\s*<((?:[^<>]|complex<[^<>]*>)+?)>")
271
271
  _TOKEN = re.compile(
272
- r"C?Array[1234]D<[^<>]*(?:<[^<>]*>[^<>]*)?>|complex<(?:float|double)>"
272
+ r"C?Array(?:[1-9]|1[0-6])D<[^<>]*(?:<[^<>]*>[^<>]*)?>|complex<(?:float|double)>"
273
273
  r"|[A-Za-z_]\w*|\*|\[\s*\]",
274
274
  )
275
275
 
@@ -905,8 +905,8 @@ def _pyccel_ctype(annotation: Any, scalars: Mapping[str, str], what: str) -> str
905
905
  ctype = scalars[scalar]
906
906
  if ndim == 0:
907
907
  return ctype
908
- if ndim > 4:
909
- raise ValueError(f"{what}: arrays have at most 4 dimensions, got {ndim}")
908
+ if ndim > 16:
909
+ raise ValueError(f"{what}: arrays have at most 16 dimensions, got {ndim}")
910
910
  return f"Array{ndim}D<{ctype}>"
911
911
 
912
912
 
@@ -1075,7 +1075,7 @@ class CudaStruct:
1075
1075
  ``(field name, C type)`` pairs, in order, e.g. ``("x", "double*")`` or
1076
1076
  ``("n", "int")``. Scalar fields, pointers to the scalar types of
1077
1077
  :func:`ctype_of` (or ``void*``), and array views ``Array1D<T>`` to
1078
- ``Array4D<T>`` of those scalar types (from ``cunumpy/array_view.cuh``,
1078
+ ``Array16D<T>`` of those scalar types (from ``cunumpy/array_view.cuh``,
1079
1079
  packed as pointer, shape and strides in elements) are supported.
1080
1080
 
1081
1081
  Examples
@@ -1848,7 +1848,7 @@ class CudaKernel:
1848
1848
  The headers shipped with cunumpy (:func:`cuda_include_dir`) are always
1849
1849
  found at compile time (see :meth:`compile_options`):
1850
1850
  ``#include "cunumpy/array_view.cuh"`` gives the ``Array1D<T>`` to
1851
- ``Array4D<T>`` views, ``#include "cunumpy/index.cuh"`` the thread-index
1851
+ ``Array16D<T>`` views, ``#include "cunumpy/index.cuh"`` the thread-index
1852
1852
  macros, ``#include "cunumpy/atomic.cuh"`` atomic adds,
1853
1853
  ``#include "cunumpy/reduce.cuh"`` warp and block reductions.
1854
1854
  source_dir : str | Path | None
@@ -16,7 +16,7 @@ so the call looks like a launch::
16
16
  np.testing.assert_allclose(y, 2.0 * x)
17
17
 
18
18
  Arguments follow the kernel signature: NumPy arrays for pointer and array view
19
- parameters (``Array1D<T>`` to ``Array4D<T>``; any strides, they are passed as
19
+ parameters (``Array1D<T>`` to ``Array16D<T>``; any strides, they are passed as
20
20
  contiguous copies), Python or NumPy scalars for scalar parameters (cast and
21
21
  checked like in a launch). Arrays are written back into the given arrays.
22
22
 
@@ -354,7 +354,7 @@ def emulate_cuda_kernel(
354
354
  buffer.tofile(path)
355
355
  ctype = param.ctype if param.dtype is not None else "unsigned char"
356
356
  element = (
357
- re.match(r"C?Array\dD<(.*)>", ctype).group(1)
357
+ re.match(r"C?Array\d+D<(.*)>", ctype).group(1)
358
358
  if param.view_ndim is not None
359
359
  else ctype
360
360
  )
@@ -1,6 +1,6 @@
1
1
  // Array views for CUDA kernels, passed by value from Python.
2
2
  //
3
- // Array1D<T> to Array4D<T> describe a (possibly non-contiguous)
3
+ // Array1D<T> to Array16D<T> describe a (possibly non-contiguous)
4
4
  // device array the way NumPy/CuPy do: a data pointer, a shape and strides.
5
5
  // Strides are in ELEMENTS, not bytes, so that `a(i, j)` is
6
6
  // `data[i * strides[0] + j * strides[1]]`. Elements are accessed with
@@ -9,7 +9,7 @@
9
9
  //
10
10
  // The views are created on the Python side by cunumpy (a kernel parameter or a
11
11
  // CudaStruct field of type `Array2D<double>` takes a CuPy array). They are
12
- // passed by value, so the memory layout must be exactly, for ndim = 1 to 4:
12
+ // passed by value, so the memory layout must be exactly, for ndim = 1 to 16:
13
13
  //
14
14
  // T* data; // 8 bytes
15
15
  // long long shape[ndim]; // ndim * 8 bytes
@@ -20,12 +20,12 @@
20
20
  // the end of this file check the size. Member functions do not change the
21
21
  // layout.
22
22
  //
23
- // CArray1D<T> to CArray4D<T> are C-contiguous (row-major) views: a data
23
+ // CArray1D<T> to CArray16D<T> are C-contiguous (row-major) views: a data
24
24
  // pointer and a shape, no strides. `a(i, j)` is `data[i * shape[1] + j]`, so
25
25
  // the last index is always the fast one and the compiler knows it has unit
26
26
  // stride. A parameter or field of these types only takes C-contiguous arrays;
27
27
  // cunumpy raises for a non-contiguous view instead of copying it (a copy would
28
- // silently drop what the kernel writes). Their layout, for ndim = 1 to 4:
28
+ // silently drop what the kernel writes). Their layout, for ndim = 1 to 16:
29
29
  //
30
30
  // T* data; // 8 bytes
31
31
  // long long shape[ndim]; // ndim * 8 bytes
@@ -223,6 +223,101 @@ struct CArray4D {
223
223
  }
224
224
  };
225
225
 
226
+ // Higher-dimensional views share an implementation; aliases keep the named
227
+ // types used by kernel signatures and Python's argument packer.
228
+ namespace cunumpy_detail {
229
+ template <typename T, int N>
230
+ struct ArrayView {
231
+ T* data;
232
+ long long shape[N];
233
+ long long strides[N];
234
+
235
+ template <typename... Indices>
236
+ __device__ __forceinline__ T& operator()(Indices... indices) const {
237
+ static_assert(sizeof...(Indices) == N, "wrong number of array indices");
238
+ const long long index[N] = {static_cast<long long>(indices)...};
239
+ long long offset = 0;
240
+ #pragma unroll
241
+ for (int axis = 0; axis < N; ++axis) {
242
+ CUNUMPY_CHECK_INDEX(index[axis], axis, shape[axis]);
243
+ offset += index[axis] * strides[axis];
244
+ }
245
+ return data[offset];
246
+ }
247
+
248
+ __device__ __forceinline__ long long size() const {
249
+ long long result = 1;
250
+ #pragma unroll
251
+ for (int axis = 0; axis < N; ++axis) result *= shape[axis];
252
+ return result;
253
+ }
254
+ };
255
+
256
+ template <typename T, int N>
257
+ struct CArrayView {
258
+ T* data;
259
+ long long shape[N];
260
+
261
+ template <typename... Indices>
262
+ __device__ __forceinline__ T& operator()(Indices... indices) const {
263
+ static_assert(sizeof...(Indices) == N, "wrong number of array indices");
264
+ const long long index[N] = {static_cast<long long>(indices)...};
265
+ long long offset = 0;
266
+ #pragma unroll
267
+ for (int axis = 0; axis < N; ++axis) {
268
+ CUNUMPY_CHECK_INDEX(index[axis], axis, shape[axis]);
269
+ offset = offset * shape[axis] + index[axis];
270
+ }
271
+ return data[offset];
272
+ }
273
+
274
+ __device__ __forceinline__ long long size() const {
275
+ long long result = 1;
276
+ #pragma unroll
277
+ for (int axis = 0; axis < N; ++axis) result *= shape[axis];
278
+ return result;
279
+ }
280
+
281
+ __host__ __device__ operator ArrayView<T, N>() const {
282
+ ArrayView<T, N> result{};
283
+ result.data = data;
284
+ long long stride = 1;
285
+ #pragma unroll
286
+ for (int axis = N - 1; axis >= 0; --axis) {
287
+ result.shape[axis] = shape[axis];
288
+ result.strides[axis] = stride;
289
+ stride *= shape[axis];
290
+ }
291
+ return result;
292
+ }
293
+ };
294
+ } // namespace cunumpy_detail
295
+
296
+ template <typename T> using Array5D = cunumpy_detail::ArrayView<T, 5>;
297
+ template <typename T> using CArray5D = cunumpy_detail::CArrayView<T, 5>;
298
+ template <typename T> using Array6D = cunumpy_detail::ArrayView<T, 6>;
299
+ template <typename T> using CArray6D = cunumpy_detail::CArrayView<T, 6>;
300
+ template <typename T> using Array7D = cunumpy_detail::ArrayView<T, 7>;
301
+ template <typename T> using CArray7D = cunumpy_detail::CArrayView<T, 7>;
302
+ template <typename T> using Array8D = cunumpy_detail::ArrayView<T, 8>;
303
+ template <typename T> using CArray8D = cunumpy_detail::CArrayView<T, 8>;
304
+ template <typename T> using Array9D = cunumpy_detail::ArrayView<T, 9>;
305
+ template <typename T> using CArray9D = cunumpy_detail::CArrayView<T, 9>;
306
+ template <typename T> using Array10D = cunumpy_detail::ArrayView<T, 10>;
307
+ template <typename T> using CArray10D = cunumpy_detail::CArrayView<T, 10>;
308
+ template <typename T> using Array11D = cunumpy_detail::ArrayView<T, 11>;
309
+ template <typename T> using CArray11D = cunumpy_detail::CArrayView<T, 11>;
310
+ template <typename T> using Array12D = cunumpy_detail::ArrayView<T, 12>;
311
+ template <typename T> using CArray12D = cunumpy_detail::CArrayView<T, 12>;
312
+ template <typename T> using Array13D = cunumpy_detail::ArrayView<T, 13>;
313
+ template <typename T> using CArray13D = cunumpy_detail::CArrayView<T, 13>;
314
+ template <typename T> using Array14D = cunumpy_detail::ArrayView<T, 14>;
315
+ template <typename T> using CArray14D = cunumpy_detail::CArrayView<T, 14>;
316
+ template <typename T> using Array15D = cunumpy_detail::ArrayView<T, 15>;
317
+ template <typename T> using CArray15D = cunumpy_detail::CArrayView<T, 15>;
318
+ template <typename T> using Array16D = cunumpy_detail::ArrayView<T, 16>;
319
+ template <typename T> using CArray16D = cunumpy_detail::CArrayView<T, 16>;
320
+
226
321
  // The layouts the Python side packs: pointer, shape (and strides), 8-byte
227
322
  // aligned.
228
323
  static_assert(sizeof(Array1D<double>) == 24, "unexpected Array1D layout");
@@ -237,4 +332,53 @@ static_assert(sizeof(CArray3D<double>) == 32, "unexpected CArray3D layout");
237
332
  static_assert(sizeof(CArray4D<double>) == 40, "unexpected CArray4D layout");
238
333
  static_assert(alignof(CArray2D<float>) == 8, "unexpected CArray2D alignment");
239
334
 
335
+ static_assert(sizeof(Array5D<double>) == 88, "unexpected Array5D layout");
336
+ static_assert(alignof(Array5D<float>) == 8, "unexpected Array5D alignment");
337
+ static_assert(sizeof(CArray5D<double>) == 48, "unexpected CArray5D layout");
338
+ static_assert(alignof(CArray5D<float>) == 8, "unexpected CArray5D alignment");
339
+ static_assert(sizeof(Array6D<double>) == 104, "unexpected Array6D layout");
340
+ static_assert(alignof(Array6D<float>) == 8, "unexpected Array6D alignment");
341
+ static_assert(sizeof(CArray6D<double>) == 56, "unexpected CArray6D layout");
342
+ static_assert(alignof(CArray6D<float>) == 8, "unexpected CArray6D alignment");
343
+ static_assert(sizeof(Array7D<double>) == 120, "unexpected Array7D layout");
344
+ static_assert(alignof(Array7D<float>) == 8, "unexpected Array7D alignment");
345
+ static_assert(sizeof(CArray7D<double>) == 64, "unexpected CArray7D layout");
346
+ static_assert(alignof(CArray7D<float>) == 8, "unexpected CArray7D alignment");
347
+ static_assert(sizeof(Array8D<double>) == 136, "unexpected Array8D layout");
348
+ static_assert(alignof(Array8D<float>) == 8, "unexpected Array8D alignment");
349
+ static_assert(sizeof(CArray8D<double>) == 72, "unexpected CArray8D layout");
350
+ static_assert(alignof(CArray8D<float>) == 8, "unexpected CArray8D alignment");
351
+ static_assert(sizeof(Array9D<double>) == 152, "unexpected Array9D layout");
352
+ static_assert(alignof(Array9D<float>) == 8, "unexpected Array9D alignment");
353
+ static_assert(sizeof(CArray9D<double>) == 80, "unexpected CArray9D layout");
354
+ static_assert(alignof(CArray9D<float>) == 8, "unexpected CArray9D alignment");
355
+ static_assert(sizeof(Array10D<double>) == 168, "unexpected Array10D layout");
356
+ static_assert(alignof(Array10D<float>) == 8, "unexpected Array10D alignment");
357
+ static_assert(sizeof(CArray10D<double>) == 88, "unexpected CArray10D layout");
358
+ static_assert(alignof(CArray10D<float>) == 8, "unexpected CArray10D alignment");
359
+ static_assert(sizeof(Array11D<double>) == 184, "unexpected Array11D layout");
360
+ static_assert(alignof(Array11D<float>) == 8, "unexpected Array11D alignment");
361
+ static_assert(sizeof(CArray11D<double>) == 96, "unexpected CArray11D layout");
362
+ static_assert(alignof(CArray11D<float>) == 8, "unexpected CArray11D alignment");
363
+ static_assert(sizeof(Array12D<double>) == 200, "unexpected Array12D layout");
364
+ static_assert(alignof(Array12D<float>) == 8, "unexpected Array12D alignment");
365
+ static_assert(sizeof(CArray12D<double>) == 104, "unexpected CArray12D layout");
366
+ static_assert(alignof(CArray12D<float>) == 8, "unexpected CArray12D alignment");
367
+ static_assert(sizeof(Array13D<double>) == 216, "unexpected Array13D layout");
368
+ static_assert(alignof(Array13D<float>) == 8, "unexpected Array13D alignment");
369
+ static_assert(sizeof(CArray13D<double>) == 112, "unexpected CArray13D layout");
370
+ static_assert(alignof(CArray13D<float>) == 8, "unexpected CArray13D alignment");
371
+ static_assert(sizeof(Array14D<double>) == 232, "unexpected Array14D layout");
372
+ static_assert(alignof(Array14D<float>) == 8, "unexpected Array14D alignment");
373
+ static_assert(sizeof(CArray14D<double>) == 120, "unexpected CArray14D layout");
374
+ static_assert(alignof(CArray14D<float>) == 8, "unexpected CArray14D alignment");
375
+ static_assert(sizeof(Array15D<double>) == 248, "unexpected Array15D layout");
376
+ static_assert(alignof(Array15D<float>) == 8, "unexpected Array15D alignment");
377
+ static_assert(sizeof(CArray15D<double>) == 128, "unexpected CArray15D layout");
378
+ static_assert(alignof(CArray15D<float>) == 8, "unexpected CArray15D alignment");
379
+ static_assert(sizeof(Array16D<double>) == 264, "unexpected Array16D layout");
380
+ static_assert(alignof(Array16D<float>) == 8, "unexpected Array16D alignment");
381
+ static_assert(sizeof(CArray16D<double>) == 136, "unexpected CArray16D layout");
382
+ static_assert(alignof(CArray16D<float>) == 8, "unexpected CArray16D alignment");
383
+
240
384
  #endif // CUNUMPY_ARRAY_VIEW_CUH
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cunumpy
3
- Version: 0.6.0
3
+ Version: 0.6.1
4
4
  Summary: Simple wrapper for numpy and cupy. Replace `import numpy as np` with `import cunumpy as xp`.
5
5
  Author: Max
6
6
  Project-URL: Source, https://github.com/max-models/cunumpy
@@ -434,7 +434,7 @@ kernel(particles.args_markers, dt) # host or CUDA kernel
434
434
  Kernels ported from pyccel index arrays like `markers[ip, j]`, which needs
435
435
  shapes and strides rather than bare pointers. The shipped header
436
436
  `cunumpy/array_view.cuh` (found by every `CudaKernel`) provides the strided
437
- views `Array1D<T>` to `Array4D<T>`; a parameter or struct field of that type
437
+ views `Array1D<T>` to `Array16D<T>`; a parameter or struct field of that type
438
438
  takes a CuPy array, contiguous or not, and indexes `a(i, j)`. The struct can be
439
439
  generated from the annotations of the pyccel argument class, so the Python
440
440
  class is the one definition, and written to a header that a test keeps in sync:
@@ -444,7 +444,9 @@ class MarkerArguments:
444
444
  def __init__(self, markers: "float[:, :]", n_markers: int, valid: "bool[:]"): ...
445
445
 
446
446
 
447
- MarkerArgs = xp.arguments.CudaStruct.from_signature(MarkerArguments.__init__, "MarkerArgs")
447
+ MarkerArgs = xp.arguments.CudaStruct.from_signature(
448
+ MarkerArguments.__init__, "MarkerArgs"
449
+ )
448
450
  MarkerArgs.to_header(
449
451
  "marker_args.cuh"
450
452
  ) # Array2D<double> markers; long long n_markers; ...
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes