cunumpy 0.6.2__tar.gz → 0.7.0__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.
- cunumpy-0.7.0/LICENSE.txt +21 -0
- {cunumpy-0.6.2 → cunumpy-0.7.0}/PKG-INFO +62 -40
- {cunumpy-0.6.2 → cunumpy-0.7.0}/README.md +33 -30
- {cunumpy-0.6.2 → cunumpy-0.7.0}/pyproject.toml +31 -13
- {cunumpy-0.6.2 → cunumpy-0.7.0}/src/cunumpy/LLM_GUIDE.md +22 -7
- {cunumpy-0.6.2 → cunumpy-0.7.0}/src/cunumpy/__init__.py +46 -18
- {cunumpy-0.6.2 → cunumpy-0.7.0}/src/cunumpy/__init__.pyi +8 -0
- cunumpy-0.7.0/src/cunumpy/_algorithms.py +512 -0
- {cunumpy-0.6.2 → cunumpy-0.7.0}/src/cunumpy/_cuda_kernel.py +794 -592
- cunumpy-0.7.0/src/cunumpy/_device.py +436 -0
- {cunumpy-0.6.2 → cunumpy-0.7.0}/src/cunumpy/_dispatch.py +312 -237
- cunumpy-0.7.0/src/cunumpy/_emulation.py +947 -0
- {cunumpy-0.6.2 → cunumpy-0.7.0}/src/cunumpy/_fake_cupy.py +6 -1
- {cunumpy-0.6.2 → cunumpy-0.7.0}/src/cunumpy/_fake_cupy_impl.py +1 -1
- cunumpy-0.7.0/src/cunumpy/_fake_cupyx.py +383 -0
- cunumpy-0.7.0/src/cunumpy/_fusion.py +105 -0
- {cunumpy-0.6.2 → cunumpy-0.7.0}/src/cunumpy/_host.py +59 -17
- {cunumpy-0.6.2 → cunumpy-0.7.0}/src/cunumpy/_kernel.py +554 -192
- cunumpy-0.7.0/src/cunumpy/_linalg.py +103 -0
- {cunumpy-0.6.2 → cunumpy-0.7.0}/src/cunumpy/_metal_kernel.py +73 -52
- {cunumpy-0.6.2 → cunumpy-0.7.0}/src/cunumpy/_mirror.py +54 -48
- {cunumpy-0.6.2 → cunumpy-0.7.0}/src/cunumpy/_morton.py +102 -35
- cunumpy-0.7.0/src/cunumpy/_mpi.py +582 -0
- cunumpy-0.7.0/src/cunumpy/_optimize.py +162 -0
- cunumpy-0.7.0/src/cunumpy/_philox.py +242 -0
- {cunumpy-0.6.2 → cunumpy-0.7.0}/src/cunumpy/_profiling.py +44 -39
- cunumpy-0.7.0/src/cunumpy/_pyccel_cache.py +305 -0
- {cunumpy-0.6.2 → cunumpy-0.7.0}/src/cunumpy/_random_streams.py +144 -48
- {cunumpy-0.6.2 → cunumpy-0.7.0}/src/cunumpy/_scipy_backend.py +68 -26
- cunumpy-0.7.0/src/cunumpy/_scipy_host.py +370 -0
- {cunumpy-0.6.2 → cunumpy-0.7.0}/src/cunumpy/_staging.py +195 -48
- cunumpy-0.7.0/src/cunumpy/_streams.py +227 -0
- cunumpy-0.7.0/src/cunumpy/_transfers.py +667 -0
- {cunumpy-0.6.2 → cunumpy-0.7.0}/src/cunumpy/algorithms.py +5 -4
- {cunumpy-0.6.2 → cunumpy-0.7.0}/src/cunumpy/arguments.py +1 -4
- {cunumpy-0.6.2 → cunumpy-0.7.0}/src/cunumpy/cuda/__init__.py +11 -16
- {cunumpy-0.6.2 → cunumpy-0.7.0}/src/cunumpy/cuda/include/cunumpy/array_view.cuh +11 -1
- {cunumpy-0.6.2 → cunumpy-0.7.0}/src/cunumpy/cuda/include/cunumpy/reduce.cuh +6 -0
- {cunumpy-0.6.2 → cunumpy-0.7.0}/src/cunumpy/cuda/include/cunumpy/scan.cuh +1 -0
- cunumpy-0.7.0/src/cunumpy/integrate.py +10 -0
- cunumpy-0.7.0/src/cunumpy/kernel_testing.py +1156 -0
- {cunumpy-0.6.2 → cunumpy-0.7.0}/src/cunumpy/kernels.py +15 -7
- {cunumpy-0.6.2 → cunumpy-0.7.0}/src/cunumpy/memory.py +3 -5
- {cunumpy-0.6.2 → cunumpy-0.7.0}/src/cunumpy/mpi.py +9 -9
- cunumpy-0.7.0/src/cunumpy/optimize.py +19 -0
- {cunumpy-0.6.2 → cunumpy-0.7.0}/src/cunumpy/petsc.py +18 -18
- {cunumpy-0.6.2 → cunumpy-0.7.0}/src/cunumpy/profiling.py +6 -3
- {cunumpy-0.6.2 → cunumpy-0.7.0}/src/cunumpy/rng.py +4 -6
- cunumpy-0.7.0/src/cunumpy/xp.py +880 -0
- {cunumpy-0.6.2 → cunumpy-0.7.0}/src/cunumpy.egg-info/PKG-INFO +62 -40
- {cunumpy-0.6.2 → cunumpy-0.7.0}/src/cunumpy.egg-info/SOURCES.txt +8 -0
- {cunumpy-0.6.2 → cunumpy-0.7.0}/src/cunumpy.egg-info/requires.txt +4 -9
- cunumpy-0.6.2/src/cunumpy/_algorithms.py +0 -299
- cunumpy-0.6.2/src/cunumpy/_device.py +0 -260
- cunumpy-0.6.2/src/cunumpy/_emulation.py +0 -614
- cunumpy-0.6.2/src/cunumpy/_fusion.py +0 -115
- cunumpy-0.6.2/src/cunumpy/_mpi.py +0 -387
- cunumpy-0.6.2/src/cunumpy/_philox.py +0 -149
- cunumpy-0.6.2/src/cunumpy/_streams.py +0 -97
- cunumpy-0.6.2/src/cunumpy/_transfers.py +0 -331
- cunumpy-0.6.2/src/cunumpy/kernel_testing.py +0 -730
- cunumpy-0.6.2/src/cunumpy/xp.py +0 -498
- {cunumpy-0.6.2 → cunumpy-0.7.0}/setup.cfg +0 -0
- {cunumpy-0.6.2 → cunumpy-0.7.0}/src/cunumpy/cuda/include/cunumpy/atomic.cuh +0 -0
- {cunumpy-0.6.2 → cunumpy-0.7.0}/src/cunumpy/cuda/include/cunumpy/index.cuh +0 -0
- {cunumpy-0.6.2 → cunumpy-0.7.0}/src/cunumpy/cuda/include/cunumpy/morton.cuh +0 -0
- {cunumpy-0.6.2 → cunumpy-0.7.0}/src/cunumpy/cuda/include/cunumpy/random.cuh +0 -0
- {cunumpy-0.6.2 → cunumpy-0.7.0}/src/cunumpy/py.typed +0 -0
- {cunumpy-0.6.2 → cunumpy-0.7.0}/src/cunumpy.egg-info/dependency_links.txt +0 -0
- {cunumpy-0.6.2 → cunumpy-0.7.0}/src/cunumpy.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Max Lindqvist
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -1,8 +1,30 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cunumpy
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.0
|
|
4
4
|
Summary: Simple wrapper for numpy and cupy. Replace `import numpy as np` with `import cunumpy as xp`.
|
|
5
5
|
Author: Max
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2025 Max Lindqvist
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
|
|
6
28
|
Project-URL: Source, https://github.com/max-models/cunumpy
|
|
7
29
|
Keywords: python
|
|
8
30
|
Classifier: Development Status :: 3 - Alpha
|
|
@@ -14,22 +36,18 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
14
36
|
Classifier: Programming Language :: Python :: 3.14
|
|
15
37
|
Requires-Python: >=3.10
|
|
16
38
|
Description-Content-Type: text/markdown
|
|
39
|
+
License-File: LICENSE.txt
|
|
17
40
|
Requires-Dist: array-api-compat
|
|
18
41
|
Requires-Dist: maybempi>=0.1.2
|
|
19
42
|
Requires-Dist: numpy
|
|
20
43
|
Provides-Extra: dev
|
|
21
|
-
Requires-Dist: ruff; extra == "dev"
|
|
22
44
|
Requires-Dist: cunumpy[docs,test-compiled]; extra == "dev"
|
|
45
|
+
Requires-Dist: pre-commit; extra == "dev"
|
|
46
|
+
Requires-Dist: pyproject-fmt; extra == "dev"
|
|
47
|
+
Requires-Dist: ruff; extra == "dev"
|
|
23
48
|
Provides-Extra: docs
|
|
49
|
+
Requires-Dist: griffe; extra == "docs"
|
|
24
50
|
Requires-Dist: ipykernel; extra == "docs"
|
|
25
|
-
Requires-Dist: myst-parser; extra == "docs"
|
|
26
|
-
Requires-Dist: nbconvert; extra == "docs"
|
|
27
|
-
Requires-Dist: nbsphinx; extra == "docs"
|
|
28
|
-
Requires-Dist: jupyterlab; extra == "docs"
|
|
29
|
-
Requires-Dist: pre-commit; extra == "docs"
|
|
30
|
-
Requires-Dist: pyproject-fmt; extra == "docs"
|
|
31
|
-
Requires-Dist: sphinx; extra == "docs"
|
|
32
|
-
Requires-Dist: sphinx-book-theme; extra == "docs"
|
|
33
51
|
Provides-Extra: metal
|
|
34
52
|
Requires-Dist: mlx; (sys_platform == "darwin" and platform_machine == "arm64") and extra == "metal"
|
|
35
53
|
Provides-Extra: test
|
|
@@ -39,6 +57,7 @@ Requires-Dist: scipy; extra == "test"
|
|
|
39
57
|
Provides-Extra: test-compiled
|
|
40
58
|
Requires-Dist: cunumpy[test]; extra == "test-compiled"
|
|
41
59
|
Requires-Dist: pyccel; extra == "test-compiled"
|
|
60
|
+
Dynamic: license-file
|
|
42
61
|
|
|
43
62
|
# CuNumpy
|
|
44
63
|
|
|
@@ -79,7 +98,7 @@ never hide a NumPy name:
|
|
|
79
98
|
|
|
80
99
|
Everything except `xp.cuda`, `xp.arguments` and `CudaKernel` works on both backends.
|
|
81
100
|
`MetalKernel` runs Metal kernels on the GPU of an Apple silicon Mac (MLX, float32, NumPy arrays;
|
|
82
|
-
`pip install 'cunumpy[metal]'`, see [the guide](
|
|
101
|
+
`pip install 'cunumpy[metal]'`, see [the guide](https://max-models.github.io/cunumpy/kernels/metal-kernel/)).
|
|
83
102
|
|
|
84
103
|
## Install
|
|
85
104
|
|
|
@@ -95,7 +114,7 @@ installation instructions for your system. CuNumpy does not install CUDA.
|
|
|
95
114
|
`array-api-compat` supplies NumPy and CuPy compatibility modules with more
|
|
96
115
|
consistent behavior for shared array operations. CuNumpy uses them internally;
|
|
97
116
|
your arrays remain ordinary NumPy or CuPy arrays. See [why CuNumpy uses
|
|
98
|
-
`array-api-compat`](
|
|
117
|
+
`array-api-compat`](https://max-models.github.io/cunumpy/guides/array-api-compat/) for a plain-language
|
|
99
118
|
explanation and examples.
|
|
100
119
|
|
|
101
120
|
## Choose a backend
|
|
@@ -121,7 +140,7 @@ Use `xp.set_backend("cupy", strict=True)` to raise when CUDA is unavailable,
|
|
|
121
140
|
preserving the previous backend. `xp.backend_info()` returns structured backend,
|
|
122
141
|
dependency, and CUDA diagnostics. Reusable streams/events, MPI staging, cell
|
|
123
142
|
ranges, and prepared reductions are described in the
|
|
124
|
-
[execution helpers guide](
|
|
143
|
+
[execution helpers guide](https://max-models.github.io/cunumpy/guides/execution-helpers/).
|
|
125
144
|
|
|
126
145
|
Use `use_backend()` for a temporary selection. It restores the previous
|
|
127
146
|
selection when the block exits, including when an exception is raised:
|
|
@@ -341,8 +360,9 @@ positional argument 0 is written, avoiding unnecessary copy-back for
|
|
|
341
360
|
read-only inputs. For a keyword call, declare the keyword name, such as
|
|
342
361
|
`outputs=("out",)`. A wrong declaration can leave GPU output values stale.
|
|
343
362
|
The wrapper can also traverse arrays nested in lists, tuples, dictionaries,
|
|
344
|
-
and selected application objects; see
|
|
345
|
-
for `object_modules`, `is_array`,
|
|
363
|
+
and selected application objects; see [Host kernels with GPU
|
|
364
|
+
data](https://max-models.github.io/cunumpy/kernels/pyccel-kernel/) for `object_modules`, `is_array`,
|
|
365
|
+
aliasing, and output declarations.
|
|
346
366
|
|
|
347
367
|
## Write CUDA kernels next to host kernels
|
|
348
368
|
|
|
@@ -477,8 +497,9 @@ Launches can be 1D to 3D (`n_threads=(nx, ny)`, `block_size=(16, 16)`) or use
|
|
|
477
497
|
an explicit `grid`, with dynamic shared memory (`shared_mem`) and a `stream`.
|
|
478
498
|
C++ function templates are instantiated with `template_args`, and
|
|
479
499
|
`CudaKernelVariants` caches kernels whose source is generated per variant
|
|
480
|
-
(e.g. per dimension and dtype). See
|
|
481
|
-
|
|
500
|
+
(e.g. per dimension and dtype). See [Writing CUDA
|
|
501
|
+
kernels](https://max-models.github.io/cunumpy/kernels/cuda-kernel/) and [CUDA
|
|
502
|
+
headers](https://max-models.github.io/cunumpy/kernels/cuda-headers/) for details.
|
|
482
503
|
|
|
483
504
|
Kernels run asynchronously, so a CUDA error (an illegal memory access, say)
|
|
484
505
|
normally surfaces at a later `.get()` or MPI call, far from the kernel that
|
|
@@ -538,35 +559,36 @@ mirror.to_host() # vector._data holds the result on both backends
|
|
|
538
559
|
|
|
539
560
|
CuNumpy supports the NumPy backend in Pyodide. It does not provide CuPy/CUDA
|
|
540
561
|
there. Ordinary Python callables can be wrapped with `PyccelKernel` without
|
|
541
|
-
compilation. See the [Pyodide guide](
|
|
562
|
+
compilation. See the [Pyodide guide](https://max-models.github.io/cunumpy/pyodide/) for a complete
|
|
542
563
|
installation example and compatibility notes.
|
|
543
564
|
|
|
544
565
|
## Documentation
|
|
545
566
|
|
|
546
|
-
The full documentation lives in [`docs
|
|
567
|
+
The full documentation lives in [`docs/`](docs/) (Astro + Starlight, `make docs-build`) and is
|
|
547
568
|
published at <https://max-models.github.io/cunumpy/>:
|
|
548
569
|
|
|
549
|
-
* Getting started: [installation](
|
|
550
|
-
[quickstart](
|
|
551
|
-
* User guide: [choosing a backend](
|
|
552
|
-
[backend-agnostic code](
|
|
553
|
-
[data movement](
|
|
554
|
-
[devices, memory and streams](
|
|
555
|
-
[MPI with one rank per GPU](
|
|
556
|
-
[timing and profiling](
|
|
557
|
-
* Porting kernels: [overview](
|
|
558
|
-
[`PyccelKernel`](
|
|
559
|
-
[`CudaKernel`](
|
|
560
|
-
[`Kernel` and `KernelCatalog`](
|
|
561
|
-
[argument objects and structs](
|
|
562
|
-
[accumulation kernels](
|
|
563
|
-
[debugging](
|
|
564
|
-
[testing](
|
|
565
|
-
* [Worked examples](
|
|
566
|
-
[best practices](
|
|
567
|
-
[troubleshooting](
|
|
568
|
-
[Pyodide](
|
|
569
|
-
[API
|
|
570
|
+
* Getting started: [installation](https://max-models.github.io/cunumpy/getting-started/installation/) and a
|
|
571
|
+
[quickstart](https://max-models.github.io/cunumpy/getting-started/quickstart/) with a map of which guide covers what.
|
|
572
|
+
* User guide: [choosing a backend](https://max-models.github.io/cunumpy/guides/backends/),
|
|
573
|
+
[backend-agnostic code](https://max-models.github.io/cunumpy/guides/portable-code/),
|
|
574
|
+
[data movement](https://max-models.github.io/cunumpy/guides/data-movement/),
|
|
575
|
+
[devices, memory and streams](https://max-models.github.io/cunumpy/guides/gpu-devices/),
|
|
576
|
+
[MPI with one rank per GPU](https://max-models.github.io/cunumpy/guides/mpi/),
|
|
577
|
+
[timing and profiling](https://max-models.github.io/cunumpy/guides/profiling/).
|
|
578
|
+
* Porting kernels: [overview](https://max-models.github.io/cunumpy/kernels/overview/),
|
|
579
|
+
[`PyccelKernel`](https://max-models.github.io/cunumpy/kernels/pyccel-kernel/),
|
|
580
|
+
[`CudaKernel`](https://max-models.github.io/cunumpy/kernels/cuda-kernel/),
|
|
581
|
+
[`Kernel` and `KernelCatalog`](https://max-models.github.io/cunumpy/kernels/dispatch/),
|
|
582
|
+
[argument objects and structs](https://max-models.github.io/cunumpy/kernels/arguments/),
|
|
583
|
+
[accumulation kernels](https://max-models.github.io/cunumpy/kernels/accumulation/),
|
|
584
|
+
[debugging](https://max-models.github.io/cunumpy/kernels/debugging/),
|
|
585
|
+
[testing](https://max-models.github.io/cunumpy/kernels/testing/).
|
|
586
|
+
* [Worked examples](https://max-models.github.io/cunumpy/examples/),
|
|
587
|
+
[best practices](https://max-models.github.io/cunumpy/best-practices/),
|
|
588
|
+
[troubleshooting](https://max-models.github.io/cunumpy/troubleshooting/),
|
|
589
|
+
[Pyodide](https://max-models.github.io/cunumpy/pyodide/), the
|
|
590
|
+
[API overview](https://max-models.github.io/cunumpy/reference/overview/) and the
|
|
591
|
+
[API reference](https://max-models.github.io/cunumpy/reference/).
|
|
570
592
|
|
|
571
593
|
### For AI coding assistants
|
|
572
594
|
|
|
@@ -37,7 +37,7 @@ never hide a NumPy name:
|
|
|
37
37
|
|
|
38
38
|
Everything except `xp.cuda`, `xp.arguments` and `CudaKernel` works on both backends.
|
|
39
39
|
`MetalKernel` runs Metal kernels on the GPU of an Apple silicon Mac (MLX, float32, NumPy arrays;
|
|
40
|
-
`pip install 'cunumpy[metal]'`, see [the guide](
|
|
40
|
+
`pip install 'cunumpy[metal]'`, see [the guide](https://max-models.github.io/cunumpy/kernels/metal-kernel/)).
|
|
41
41
|
|
|
42
42
|
## Install
|
|
43
43
|
|
|
@@ -53,7 +53,7 @@ installation instructions for your system. CuNumpy does not install CUDA.
|
|
|
53
53
|
`array-api-compat` supplies NumPy and CuPy compatibility modules with more
|
|
54
54
|
consistent behavior for shared array operations. CuNumpy uses them internally;
|
|
55
55
|
your arrays remain ordinary NumPy or CuPy arrays. See [why CuNumpy uses
|
|
56
|
-
`array-api-compat`](
|
|
56
|
+
`array-api-compat`](https://max-models.github.io/cunumpy/guides/array-api-compat/) for a plain-language
|
|
57
57
|
explanation and examples.
|
|
58
58
|
|
|
59
59
|
## Choose a backend
|
|
@@ -79,7 +79,7 @@ Use `xp.set_backend("cupy", strict=True)` to raise when CUDA is unavailable,
|
|
|
79
79
|
preserving the previous backend. `xp.backend_info()` returns structured backend,
|
|
80
80
|
dependency, and CUDA diagnostics. Reusable streams/events, MPI staging, cell
|
|
81
81
|
ranges, and prepared reductions are described in the
|
|
82
|
-
[execution helpers guide](
|
|
82
|
+
[execution helpers guide](https://max-models.github.io/cunumpy/guides/execution-helpers/).
|
|
83
83
|
|
|
84
84
|
Use `use_backend()` for a temporary selection. It restores the previous
|
|
85
85
|
selection when the block exits, including when an exception is raised:
|
|
@@ -299,8 +299,9 @@ positional argument 0 is written, avoiding unnecessary copy-back for
|
|
|
299
299
|
read-only inputs. For a keyword call, declare the keyword name, such as
|
|
300
300
|
`outputs=("out",)`. A wrong declaration can leave GPU output values stale.
|
|
301
301
|
The wrapper can also traverse arrays nested in lists, tuples, dictionaries,
|
|
302
|
-
and selected application objects; see
|
|
303
|
-
for `object_modules`, `is_array`,
|
|
302
|
+
and selected application objects; see [Host kernels with GPU
|
|
303
|
+
data](https://max-models.github.io/cunumpy/kernels/pyccel-kernel/) for `object_modules`, `is_array`,
|
|
304
|
+
aliasing, and output declarations.
|
|
304
305
|
|
|
305
306
|
## Write CUDA kernels next to host kernels
|
|
306
307
|
|
|
@@ -435,8 +436,9 @@ Launches can be 1D to 3D (`n_threads=(nx, ny)`, `block_size=(16, 16)`) or use
|
|
|
435
436
|
an explicit `grid`, with dynamic shared memory (`shared_mem`) and a `stream`.
|
|
436
437
|
C++ function templates are instantiated with `template_args`, and
|
|
437
438
|
`CudaKernelVariants` caches kernels whose source is generated per variant
|
|
438
|
-
(e.g. per dimension and dtype). See
|
|
439
|
-
|
|
439
|
+
(e.g. per dimension and dtype). See [Writing CUDA
|
|
440
|
+
kernels](https://max-models.github.io/cunumpy/kernels/cuda-kernel/) and [CUDA
|
|
441
|
+
headers](https://max-models.github.io/cunumpy/kernels/cuda-headers/) for details.
|
|
440
442
|
|
|
441
443
|
Kernels run asynchronously, so a CUDA error (an illegal memory access, say)
|
|
442
444
|
normally surfaces at a later `.get()` or MPI call, far from the kernel that
|
|
@@ -496,35 +498,36 @@ mirror.to_host() # vector._data holds the result on both backends
|
|
|
496
498
|
|
|
497
499
|
CuNumpy supports the NumPy backend in Pyodide. It does not provide CuPy/CUDA
|
|
498
500
|
there. Ordinary Python callables can be wrapped with `PyccelKernel` without
|
|
499
|
-
compilation. See the [Pyodide guide](
|
|
501
|
+
compilation. See the [Pyodide guide](https://max-models.github.io/cunumpy/pyodide/) for a complete
|
|
500
502
|
installation example and compatibility notes.
|
|
501
503
|
|
|
502
504
|
## Documentation
|
|
503
505
|
|
|
504
|
-
The full documentation lives in [`docs
|
|
506
|
+
The full documentation lives in [`docs/`](docs/) (Astro + Starlight, `make docs-build`) and is
|
|
505
507
|
published at <https://max-models.github.io/cunumpy/>:
|
|
506
508
|
|
|
507
|
-
* Getting started: [installation](
|
|
508
|
-
[quickstart](
|
|
509
|
-
* User guide: [choosing a backend](
|
|
510
|
-
[backend-agnostic code](
|
|
511
|
-
[data movement](
|
|
512
|
-
[devices, memory and streams](
|
|
513
|
-
[MPI with one rank per GPU](
|
|
514
|
-
[timing and profiling](
|
|
515
|
-
* Porting kernels: [overview](
|
|
516
|
-
[`PyccelKernel`](
|
|
517
|
-
[`CudaKernel`](
|
|
518
|
-
[`Kernel` and `KernelCatalog`](
|
|
519
|
-
[argument objects and structs](
|
|
520
|
-
[accumulation kernels](
|
|
521
|
-
[debugging](
|
|
522
|
-
[testing](
|
|
523
|
-
* [Worked examples](
|
|
524
|
-
[best practices](
|
|
525
|
-
[troubleshooting](
|
|
526
|
-
[Pyodide](
|
|
527
|
-
[API
|
|
509
|
+
* Getting started: [installation](https://max-models.github.io/cunumpy/getting-started/installation/) and a
|
|
510
|
+
[quickstart](https://max-models.github.io/cunumpy/getting-started/quickstart/) with a map of which guide covers what.
|
|
511
|
+
* User guide: [choosing a backend](https://max-models.github.io/cunumpy/guides/backends/),
|
|
512
|
+
[backend-agnostic code](https://max-models.github.io/cunumpy/guides/portable-code/),
|
|
513
|
+
[data movement](https://max-models.github.io/cunumpy/guides/data-movement/),
|
|
514
|
+
[devices, memory and streams](https://max-models.github.io/cunumpy/guides/gpu-devices/),
|
|
515
|
+
[MPI with one rank per GPU](https://max-models.github.io/cunumpy/guides/mpi/),
|
|
516
|
+
[timing and profiling](https://max-models.github.io/cunumpy/guides/profiling/).
|
|
517
|
+
* Porting kernels: [overview](https://max-models.github.io/cunumpy/kernels/overview/),
|
|
518
|
+
[`PyccelKernel`](https://max-models.github.io/cunumpy/kernels/pyccel-kernel/),
|
|
519
|
+
[`CudaKernel`](https://max-models.github.io/cunumpy/kernels/cuda-kernel/),
|
|
520
|
+
[`Kernel` and `KernelCatalog`](https://max-models.github.io/cunumpy/kernels/dispatch/),
|
|
521
|
+
[argument objects and structs](https://max-models.github.io/cunumpy/kernels/arguments/),
|
|
522
|
+
[accumulation kernels](https://max-models.github.io/cunumpy/kernels/accumulation/),
|
|
523
|
+
[debugging](https://max-models.github.io/cunumpy/kernels/debugging/),
|
|
524
|
+
[testing](https://max-models.github.io/cunumpy/kernels/testing/).
|
|
525
|
+
* [Worked examples](https://max-models.github.io/cunumpy/examples/),
|
|
526
|
+
[best practices](https://max-models.github.io/cunumpy/best-practices/),
|
|
527
|
+
[troubleshooting](https://max-models.github.io/cunumpy/troubleshooting/),
|
|
528
|
+
[Pyodide](https://max-models.github.io/cunumpy/pyodide/), the
|
|
529
|
+
[API overview](https://max-models.github.io/cunumpy/reference/overview/) and the
|
|
530
|
+
[API reference](https://max-models.github.io/cunumpy/reference/).
|
|
528
531
|
|
|
529
532
|
### For AI coding assistants
|
|
530
533
|
|
|
@@ -5,7 +5,7 @@ requires = [ "setuptools", "wheel" ]
|
|
|
5
5
|
|
|
6
6
|
[project]
|
|
7
7
|
name = "cunumpy"
|
|
8
|
-
version = "0.
|
|
8
|
+
version = "0.7.0"
|
|
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" ]
|
|
@@ -28,21 +28,14 @@ dependencies = [
|
|
|
28
28
|
]
|
|
29
29
|
|
|
30
30
|
optional-dependencies.dev = [
|
|
31
|
-
"ruff",
|
|
32
31
|
"cunumpy[test-compiled,docs]",
|
|
33
|
-
]
|
|
34
|
-
# https://medium.com/@pratikdomadiya123/build-project-documentation-quickly-with-the-sphinx-python-2a9732b66594
|
|
35
|
-
optional-dependencies.docs = [
|
|
36
|
-
"ipykernel",
|
|
37
|
-
"myst-parser",
|
|
38
|
-
"nbconvert",
|
|
39
|
-
"nbsphinx",
|
|
40
|
-
"jupyterlab",
|
|
41
32
|
"pre-commit",
|
|
42
33
|
"pyproject-fmt",
|
|
43
|
-
"
|
|
44
|
-
"sphinx-book-theme",
|
|
34
|
+
"ruff",
|
|
45
35
|
]
|
|
36
|
+
# the API reference of the docs site (docs/, Astro + Starlight) reads the docstrings with griffe;
|
|
37
|
+
# the shared docs workflow registers an ipykernel even without notebooks
|
|
38
|
+
optional-dependencies.docs = [ "griffe", "ipykernel" ]
|
|
46
39
|
optional-dependencies.metal = [ "mlx; sys_platform == 'darwin' and platform_machine == 'arm64'" ]
|
|
47
40
|
optional-dependencies.test = [ "coverage", "pytest", "scipy" ]
|
|
48
41
|
optional-dependencies.test-compiled = [ "cunumpy[test]", "pyccel" ]
|
|
@@ -58,8 +51,33 @@ cunumpy = [ "py.typed", "*.pyi", "LLM_GUIDE.md", "cuda/include/cunumpy/*.cuh" ]
|
|
|
58
51
|
# agent worktrees and scratch scripts are local copies, not part of the project
|
|
59
52
|
extend-exclude = [ ".claude" ]
|
|
60
53
|
# formatting: `ruff format`; import sorting: the isort rules of `ruff check`
|
|
61
|
-
lint.extend-select = [ "I", "TID252" ]
|
|
54
|
+
lint.extend-select = [ "D", "I", "TID252" ]
|
|
55
|
+
# D105/D107: magic methods and __init__ (constructor parameters go in the class docstring)
|
|
56
|
+
lint.extend-ignore = [ "D105", "D107" ]
|
|
62
57
|
lint.isort.known-first-party = [ "cunumpy" ]
|
|
58
|
+
lint.per-file-ignores."_fake_cupy*.py" = [ "D" ]
|
|
59
|
+
lint.per-file-ignores."conftest.py" = [ "D" ]
|
|
60
|
+
lint.per-file-ignores."docs/**" = [ "D" ]
|
|
61
|
+
lint.per-file-ignores."tests/**" = [ "D" ]
|
|
62
|
+
lint.pydocstyle.convention = "numpy"
|
|
63
63
|
|
|
64
64
|
[tool.ruff.lint.flake8-tidy-imports]
|
|
65
65
|
ban-relative-imports = "all"
|
|
66
|
+
|
|
67
|
+
# `python -m numpydoc lint src/cunumpy/*.py`: the public API (names re-exported by a public
|
|
68
|
+
# module) has full numpydoc sections; private helpers only need a one-line summary.
|
|
69
|
+
[tool.numpydoc_validation]
|
|
70
|
+
checks = [
|
|
71
|
+
"all",
|
|
72
|
+
"ES01", # extended summary is optional (docstrings are kept short)
|
|
73
|
+
"EX01", # examples are required for public functions and classes, not every method
|
|
74
|
+
"SA01", # See Also is optional
|
|
75
|
+
"GL08", # undocumented objects are caught by ruff's D rules instead
|
|
76
|
+
]
|
|
77
|
+
# one-line docstrings (properties, trivial methods) need no Returns section
|
|
78
|
+
override_RT01 = [ '\A[^\n]*\Z' ]
|
|
79
|
+
exclude = [
|
|
80
|
+
'\._[A-Za-z]\w*$', # private functions, classes and methods
|
|
81
|
+
'\.__\w+__$', # dunder methods
|
|
82
|
+
'_fake_cupy',
|
|
83
|
+
]
|
|
@@ -5,7 +5,7 @@ correct code with `cunumpy`. It ships inside the installed package
|
|
|
5
5
|
(`<site-packages>/cunumpy/LLM_GUIDE.md`; locate it with
|
|
6
6
|
`python -c "import cunumpy, pathlib; print(pathlib.Path(cunumpy.__file__).parent / 'LLM_GUIDE.md')"`).
|
|
7
7
|
It is self-contained. The full documentation is at
|
|
8
|
-
https://max-models.github.io/cunumpy/ and in `docs
|
|
8
|
+
https://max-models.github.io/cunumpy/ and in `docs/` of the repository.
|
|
9
9
|
|
|
10
10
|
## What cunumpy is
|
|
11
11
|
|
|
@@ -74,29 +74,35 @@ https://max-models.github.io/cunumpy/ and in `docs/source/` of the repository.
|
|
|
74
74
|
| launch a hand-written CUDA C kernel | `xp.kernels.CudaKernel(source, "name")` / `CudaKernel.from_file(path)` |
|
|
75
75
|
| run a Metal (MSL) kernel on an Apple silicon GPU, NumPy float32 in and out (float64 raises; `float64="cast"` computes in float32); not part of `Kernel` dispatch | `xp.kernels.MetalKernel(body, inputs=[...], outputs=[...])(*args, out=arrays, n_threads=n)`; check `xp.kernels.metal_available()` |
|
|
76
76
|
| call host-only code (SciPy, file readers) with arguments of either backend | `xp.host_call(fun, *args)`; `@xp.evaluate_on_host` on a method; `@xp.setup_on_host` on `__init__` |
|
|
77
|
-
| keep the live rows of particle arrays at the front | `n = xp.algorithms.compact_by_mask(alive, markers, weights)` |
|
|
78
|
-
| run CUDA kernel launches on the CPU in a test (fake CuPy) | `with kernel_testing.emulated_launches():
|
|
77
|
+
| keep the live rows of particle arrays at the front | `n = xp.algorithms.compact_by_mask(alive, markers, weights)`; component-major `(ncomp, N)`: `axis=-1` |
|
|
78
|
+
| run CUDA kernel launches on the CPU in a test (fake CuPy) | `with kernel_testing.emulated_launches(): ...` (also makes `kernel.compile()`/`compile_all()` build the emulation instead of CUDA); `with kernel_testing.fake_cupy_session(): ...` adds the CuPy backend; `kernel_testing.host_buffer(a)` reads a fake array; struct arguments are read through their fields |
|
|
79
|
+
| run a test on the fake CuPy from a NumPy test process | `kernel_testing.run_in_fake_cupy_subprocess(code)` (serial child, rank 0 only under MPI); `@kernel_testing.requires_device_backend` = a GPU or the fake CuPy |
|
|
79
80
|
| find the arguments a host kernel writes (copy only those back) | `PyccelKernel(fn, outputs=("out",))` (names work positionally); `xp.kernels.outputs_from_annotations(fn)`; `Kernel.from_folder(..., outputs="annotations")` |
|
|
80
81
|
| host kernel + CUDA port, chosen by backend | `xp.kernels.Kernel(host_fn, cuda_kernel_or_None)` |
|
|
81
82
|
| many kernels in a package, ported incrementally | `xp.kernels.KernelCatalog.from_package(__name__, missing_cuda="fallback")` |
|
|
82
83
|
| host kernels compiled at first call (your compile function), NumPy fallback | `from_package(..., host_suffix="_pyccel", compile_host=my_compile, host_fallback={...})` -> `xp.kernels.CompiledHostKernel` |
|
|
83
84
|
| host arrays reach kernels while CuPy is active | `Kernel(..., dispatch="arrays")` / `from_package(..., dispatch="arrays")`: CUDA only for device arguments |
|
|
84
85
|
| one kernel folder declares its kernel in its own `__init__.py` | `kernel = xp.kernels.Kernel.from_folder(__name__, host_suffix="_pyccel", compile_host=..., dispatch="arrays")`; `<name>_numba.py`, `<name>_numpy.py` in the folder are further host implementations |
|
|
85
|
-
| bring a `dispatch="arrays"` kernel's arguments to the side of the main array | `xp.kernels.as_kernel_array(a, like=grid, dtype=float)`; outputs: `with xp.kernels.kernel_output(out, like=grid, dtype=float) as buf:` |
|
|
86
|
+
| bring a `dispatch="arrays"` kernel's arguments to the side of the main array | `xp.kernels.as_kernel_array(a, like=grid, dtype=float)`; outputs: `with xp.kernels.kernel_output(out, like=grid, dtype=float) as buf:` (several: `with xp.kernels.kernel_outputs(a, b, like=grid, dtype=float) as (buf_a, buf_b):`); `strided=True` passes NumPy views in C order with gaps (`a[:, :n]`) to Pyccel hosts without a copy |
|
|
86
87
|
| choose the host implementation (pyccel/numba/numpy/python) | `xp.kernels.set_host_kernel_implementation("numpy")`, `with xp.kernels.use_host_kernel_implementation(...)`, `CUNUMPY_HOST_KERNEL_IMPLEMENTATION=numpy`; default: first available of pyccel, numba, numpy; `kernel.selected()` |
|
|
87
88
|
| require CUDA for device kernel dispatch | `xp.kernels.set_device_kernel_implementation("cuda")`, `get_device_kernel_implementation()`, `with xp.kernels.use_device_kernel_implementation(...)`, `CUNUMPY_DEVICE_KERNEL_IMPLEMENTATION=cuda`; default `None` preserves `missing_cuda` policy; explicit CUDA rejects host fallback |
|
|
88
89
|
| check host and CUDA kernels take the same parameters | `catalog.check_signatures()` (in a unit test) |
|
|
89
|
-
| test a CUDA kernel's arithmetic without a GPU | `cunumpy.kernel_testing.emulate_cuda_kernel(kernel, *numpy_args, n_threads=n)` (C++ compiler; shared memory and __syncthreads ok, no warp ops; `shared_mem=` for extern shared) |
|
|
90
|
+
| test a CUDA kernel's arithmetic without a GPU | `cunumpy.kernel_testing.emulate_cuda_kernel(kernel, *numpy_args, n_threads=n)` (C++ compiler; shared memory and __syncthreads ok, no warp ops; inline asm traps; compiled once per kernel and cached; `shared_mem=` for extern shared) |
|
|
90
91
|
| shared-memory budget of a block | `xp.cuda.max_shared_memory_per_block()` (48 KiB without a GPU) |
|
|
91
92
|
| random numbers inside a kernel, equal on the host | `#include <cunumpy/random.cuh>`: `cunumpy_uniform(seed, particle_id, step)`; host: `xp.rng.philox_uniform(seed, ids, step)` |
|
|
92
93
|
| sort points along a Z-curve / quadtree or octree nodes as contiguous ranges | `keys = xp.algorithms.morton_keys(pos, lower, upper, levels)`, `keys, order, pos = xp.algorithms.sort_by_key(keys, pos)`; in a kernel `#include <cunumpy/morton.cuh>`: `cunumpy_morton_key2(x, y, x0, y0, sx, sy, levels)` with `xp.algorithms.morton_scales(...)` |
|
|
93
94
|
| one thread per marker without passing n_threads | default: `CudaKernel(...)` uses the first array's row count for 1D launches |
|
|
94
95
|
| copy device arrays to the host for output without stalling | `xp.memory.HostStaging(shape, dtype)`: `c = staging.copy(a)` ... `c.result()` |
|
|
96
|
+
| read a device scalar without a sync (e.g. a convergence test one iteration late) | `h = xp.to_host_async(x)`; `h.ready()` never waits, `h.result()` |
|
|
95
97
|
| PIC recipes (compaction, sort by cell, MPI exchange, graphs) | docs guide "Particle codes" |
|
|
96
98
|
| reproducible random numbers per MPI rank | `xp.rng.random_streams.seed(seed, rank=rank)`, then `xp.rng.random_streams.normal(...)` / `.generator()` |
|
|
97
99
|
| group arrays/scalars into one kernel argument | `xp.arguments.CudaArguments` (flattened), `xp.arguments.CudaStruct` (C struct), `xp.arguments.CudaStructArguments` (C struct as a class); host kernels take their own argument objects, the caller picks one per backend |
|
|
98
100
|
| CUDA struct from a Pyccel argument class | `xp.arguments.CudaStruct.from_signature(Cls.__init__, "Name")`, `xp.arguments.write_cuda_header(...)` |
|
|
99
101
|
| SciPy (sparse, sparse.linalg, fft, special, ndimage, ...) on either backend | `xp.scipy.<subpackage>.<name>` (SciPy or `cupyx.scipy`); `xp.scipy.special.available(name)` |
|
|
102
|
+
| splines on the device | `xp.scipy.interpolate.UnivariateSpline`, `make_interp_spline`, `NdBSpline` (no `RectBivariateSpline`: `make_interp_spline` per axis + `NdBSpline`) |
|
|
103
|
+
| circulant solve (FFT preconditioner) on the device | `xp.scipy.linalg.solve_circulant(c, b)` (cunumpy fill-in on CuPy, SciPy's arguments) |
|
|
104
|
+
| one root/minimization/integral/ODE at setup with an `xp` callback using device data | `xp.optimize.fsolve`/`root`/`minimize`, `xp.integrate.quad`/`odeint` (SciPy on the host, callback args and results on `x0`'s backend) |
|
|
105
|
+
| many independent scalar root problems (one per ray, per marker) | `xp.optimize.newton(func, x0_array, fprime=None)` (SciPy's array Newton/secant, on the device) |
|
|
100
106
|
| chain of elementwise operations as one GPU kernel | `@xp.kernels.fuse` (`cupy.fuse` for CuPy arrays, plain call otherwise) |
|
|
101
107
|
| PETSc solve on device arrays without copies | `xp.petsc.petsc_vec(array)` (CUDA/HIP petsc4py for CuPy arrays); `xp.synchronize()` around PETSc calls |
|
|
102
108
|
| reduction inside a CUDA kernel (energy, max velocity) | `<cunumpy/reduce.cuh>`: `cunumpy_block_sum_to(out, v)`, `cunumpy_block_min/max`, `cunumpy_warp_sum` |
|
|
@@ -106,6 +112,7 @@ https://max-models.github.io/cunumpy/ and in `docs/source/` of the repository.
|
|
|
106
112
|
| timing GPU code | `with xp.profiling.timed_region("name") as t:` → `t.elapsed` |
|
|
107
113
|
| profiler markers | `xp.profiling.nvtx_range("name")` (context manager or decorator) |
|
|
108
114
|
| find transfers | `with xp.profiling.count_transfers() as c: ...; print(c.report())` |
|
|
115
|
+
| check transfers per phase of a time loop | `b = xp.profiling.TransferBudget()`; `b.count("step")(fn)` or `with b.phase("output"):`; `b.require("step", allow={"to_host": {"max_nbytes": 8}})`; `b.check()` |
|
|
109
116
|
| debug an illegal memory access | `CUNUMPY_CUDA_DEBUG=1`, then `compute-sanitizer` |
|
|
110
117
|
| test on both backends | `cunumpy.kernel_testing.BACKENDS`, `backend` fixture, `requires_cupy` |
|
|
111
118
|
| test CUDA vs host kernel | `cunumpy.kernel_testing.assert_kernels_agree(kernel, make_args, n_threads=...)` |
|
|
@@ -142,6 +149,9 @@ xp.as_device_array(value, dtype=None, ndim=None, *, name=None)
|
|
|
142
149
|
with xp.profiling.count_transfers() as c: ... # c.total, c.to_host, c.to_device,
|
|
143
150
|
# c.kernel_conversions, c.fallbacks, c.events, c.report()
|
|
144
151
|
with xp.profiling.assert_no_transfers(): ... # rejects host/device copies and host fallback
|
|
152
|
+
h = xp.to_host_async(a) # non-blocking copy of a device scalar: h.ready(), h.result()
|
|
153
|
+
budget = xp.profiling.TransferBudget() # per-phase counts: budget.phase(name),
|
|
154
|
+
# budget.count(name)(fn), budget.require(...), budget.check()
|
|
145
155
|
```
|
|
146
156
|
|
|
147
157
|
Mirror refreshes, MPI/output staging, argument conversion and kernel output
|
|
@@ -165,6 +175,9 @@ with xp.mpi.mpi_buffer(a) as buf:
|
|
|
165
175
|
with xp.mpi.mpi_buffer(a, send=False, recv=True) as buf:
|
|
166
176
|
... # array, or pinned staging copy
|
|
167
177
|
xp.mpi.set_mpi_cuda_aware(True | False | None), xp.mpi.get_mpi_cuda_aware()
|
|
178
|
+
xp.mpi.exchange(
|
|
179
|
+
comm, sends=[(send, dest, tag)], receives=[(recv, source, tag)]
|
|
180
|
+
) # waits for all transfers and GPU copy-back; MPI posting/wait errors abort comm
|
|
168
181
|
xp.algorithms.segment_sum(
|
|
169
182
|
values, keys, n_segments
|
|
170
183
|
) # out[k] = sum(values[keys == k]); keys < 0 dropped
|
|
@@ -305,8 +318,10 @@ xp.cuda.cuda_include_dir()
|
|
|
305
318
|
* Default `n_threads_from="auto"` infers from the first array, including arrays
|
|
306
319
|
in supported argument objects: 1D block -> shape[0], 2D -> shape[:2], 3D ->
|
|
307
320
|
shape[:3] (x, y, z). Per-call block overrides apply. Explicit n_threads/grid
|
|
308
|
-
wins;
|
|
309
|
-
|
|
321
|
+
wins; `"last_axis"` uses the first array's last axis (component-major
|
|
322
|
+
`(ncomp, N)` marker arrays); use a callback for flattened `.size`, reversed
|
|
323
|
+
axes or another work count, or None to require explicit sizes. Missing
|
|
324
|
+
arrays/axes raise.
|
|
310
325
|
|
|
311
326
|
Shipped CUDA headers (always on the include path):
|
|
312
327
|
|
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
"""NumPy and CuPy behind one namespace.
|
|
2
|
+
|
|
3
|
+
``import cunumpy as xp`` gives the functions of the active backend's
|
|
4
|
+
``array-api-compat`` module (``xp.zeros``, ``xp.linalg``, ...), replaced when
|
|
5
|
+
the backend changes, plus backend selection, array inspection and conversion,
|
|
6
|
+
host execution helpers (:func:`host_call`), and :data:`scipy`. Everything else
|
|
7
|
+
is in a submodule (:mod:`cunumpy.kernels`, :mod:`cunumpy.cuda`, ...). See
|
|
8
|
+
:doc:`/api` for the module layout and :doc:`/guides/backends`.
|
|
9
|
+
|
|
10
|
+
``xp.numpy_backend`` and ``xp.cupy_backend`` are booleans telling whether the
|
|
11
|
+
active backend is NumPy or CuPy (prefer :func:`get_backend` for the name).
|
|
12
|
+
"""
|
|
13
|
+
|
|
1
14
|
# cunumpy/__init__.py
|
|
2
15
|
import re as _re
|
|
3
16
|
from importlib.metadata import PackageNotFoundError, version
|
|
@@ -6,9 +19,11 @@ from cunumpy import (
|
|
|
6
19
|
algorithms,
|
|
7
20
|
arguments,
|
|
8
21
|
cuda,
|
|
22
|
+
integrate,
|
|
9
23
|
kernels,
|
|
10
24
|
memory,
|
|
11
25
|
mpi,
|
|
26
|
+
optimize,
|
|
12
27
|
petsc,
|
|
13
28
|
profiling,
|
|
14
29
|
rng,
|
|
@@ -16,11 +31,14 @@ from cunumpy import (
|
|
|
16
31
|
)
|
|
17
32
|
from cunumpy._host import evaluate_on_host, host_call, setup_on_host
|
|
18
33
|
from cunumpy._scipy_backend import scipy
|
|
34
|
+
from cunumpy._staging import to_host_async
|
|
19
35
|
from cunumpy.xp import (
|
|
36
|
+
MIN_CUPY_VERSION,
|
|
20
37
|
as_device_array,
|
|
21
38
|
assert_same_backend,
|
|
22
39
|
backend_info,
|
|
23
40
|
cupy_available,
|
|
41
|
+
cupy_version_supported,
|
|
24
42
|
default_float_dtype,
|
|
25
43
|
get_array_backend,
|
|
26
44
|
get_array_module,
|
|
@@ -38,6 +56,7 @@ from cunumpy.xp import (
|
|
|
38
56
|
|
|
39
57
|
try:
|
|
40
58
|
__version__ = version("cunumpy")
|
|
59
|
+
"""The installed version of cunumpy; ``"0.0.0+unknown"`` without package metadata."""
|
|
41
60
|
except PackageNotFoundError:
|
|
42
61
|
__version__ = "0.0.0+unknown"
|
|
43
62
|
|
|
@@ -47,18 +66,27 @@ def _version_key(text: str) -> tuple[int, ...]:
|
|
|
47
66
|
|
|
48
67
|
|
|
49
68
|
def require_version(minimum: str) -> None:
|
|
50
|
-
"""Raise ``ImportError`` if
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
69
|
+
"""Raise ``ImportError`` if the installed cunumpy is older than `minimum`.
|
|
70
|
+
|
|
71
|
+
A clearer error than a later ``AttributeError`` for code that needs a
|
|
72
|
+
feature of a given release. Only the numeric part is compared (``0.4.0``
|
|
73
|
+
and ``0.4.0.dev1`` are equal); nothing is checked when the installed
|
|
74
|
+
version is unknown (cunumpy not installed as a package, ``xp.__version__``
|
|
75
|
+
is then ``"0.0.0+unknown"``).
|
|
76
|
+
|
|
77
|
+
Parameters
|
|
78
|
+
----------
|
|
79
|
+
minimum : str
|
|
80
|
+
The oldest acceptable version, e.g. ``"0.4.0"``.
|
|
81
|
+
|
|
82
|
+
Raises
|
|
83
|
+
------
|
|
84
|
+
ImportError
|
|
85
|
+
If the installed version is older than `minimum`.
|
|
86
|
+
|
|
87
|
+
Examples
|
|
88
|
+
--------
|
|
89
|
+
>>> xp.require_version("0.4.0")
|
|
62
90
|
"""
|
|
63
91
|
if __version__.startswith("0.0.0+unknown"):
|
|
64
92
|
return
|
|
@@ -70,6 +98,7 @@ def require_version(minimum: str) -> None:
|
|
|
70
98
|
|
|
71
99
|
|
|
72
100
|
__all__ = [
|
|
101
|
+
"MIN_CUPY_VERSION",
|
|
73
102
|
"__version__",
|
|
74
103
|
"algorithms",
|
|
75
104
|
"arguments",
|
|
@@ -79,18 +108,21 @@ __all__ = [
|
|
|
79
108
|
"cuda",
|
|
80
109
|
"cupy_available",
|
|
81
110
|
"cupy_backend",
|
|
111
|
+
"cupy_version_supported",
|
|
82
112
|
"default_float_dtype",
|
|
83
113
|
"evaluate_on_host",
|
|
84
114
|
"get_array_backend",
|
|
85
115
|
"get_array_module",
|
|
86
116
|
"get_backend",
|
|
87
117
|
"host_call",
|
|
118
|
+
"integrate",
|
|
88
119
|
"is_cpu",
|
|
89
120
|
"is_gpu",
|
|
90
121
|
"kernels",
|
|
91
122
|
"memory",
|
|
92
123
|
"mpi",
|
|
93
124
|
"numpy_backend",
|
|
125
|
+
"optimize",
|
|
94
126
|
"petsc",
|
|
95
127
|
"profiling",
|
|
96
128
|
"require_version",
|
|
@@ -102,6 +134,7 @@ __all__ = [
|
|
|
102
134
|
"synchronize",
|
|
103
135
|
"to_cunumpy",
|
|
104
136
|
"to_cupy",
|
|
137
|
+
"to_host_async",
|
|
105
138
|
"to_numpy",
|
|
106
139
|
"use_backend",
|
|
107
140
|
"xp",
|
|
@@ -109,12 +142,7 @@ __all__ = [
|
|
|
109
142
|
|
|
110
143
|
|
|
111
144
|
def __getattr__(name: str):
|
|
112
|
-
"""Resolve
|
|
113
|
-
|
|
114
|
-
The public names of the active backend are copied into this namespace (see
|
|
115
|
-
`_sync_backend_namespace`), so this only runs for names missing from the
|
|
116
|
-
backend's ``__all__`` and for ``numpy_backend``/``cupy_backend``.
|
|
117
|
-
"""
|
|
145
|
+
"""Resolve ``numpy_backend``, ``cupy_backend`` and backend names not copied here."""
|
|
118
146
|
if name == "numpy_backend":
|
|
119
147
|
return xp.numpy_backend
|
|
120
148
|
if name == "cupy_backend":
|