numba-mpi 0.43__tar.gz → 1.0.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.
- numba_mpi-1.0.1/.github/numba_mpi_logo.png +0 -0
- {numba_mpi-0.43 → numba_mpi-1.0.1}/.github/workflows/tests+pypi.yml +4 -4
- {numba_mpi-0.43 → numba_mpi-1.0.1}/.pre-commit-config.yaml +3 -0
- {numba_mpi-0.43 → numba_mpi-1.0.1}/.zenodo.json +1 -1
- numba_mpi-1.0.1/CITATION.cff +20 -0
- {numba_mpi-0.43/numba_mpi.egg-info → numba_mpi-1.0.1}/PKG-INFO +14 -6
- numba_mpi-0.43/PKG-INFO → numba_mpi-1.0.1/README.md +11 -24
- {numba_mpi-0.43 → numba_mpi-1.0.1}/numba_mpi/__init__.py +2 -0
- {numba_mpi-0.43 → numba_mpi-1.0.1}/numba_mpi/api/initialized.py +2 -1
- {numba_mpi-0.43 → numba_mpi-1.0.1}/numba_mpi/api/rank.py +3 -2
- {numba_mpi-0.43 → numba_mpi-1.0.1}/numba_mpi/api/size.py +3 -2
- numba_mpi-0.43/README.md → numba_mpi-1.0.1/numba_mpi.egg-info/PKG-INFO +32 -4
- {numba_mpi-0.43 → numba_mpi-1.0.1}/numba_mpi.egg-info/SOURCES.txt +11 -1
- {numba_mpi-0.43 → numba_mpi-1.0.1}/numba_mpi.egg-info/requires.txt +1 -0
- {numba_mpi-0.43 → numba_mpi-1.0.1}/setup.py +5 -2
- {numba_mpi-0.43 → numba_mpi-1.0.1}/tests/api/test_allreduce.py +4 -4
- {numba_mpi-0.43 → numba_mpi-1.0.1}/tests/api/test_barrier.py +1 -2
- {numba_mpi-0.43 → numba_mpi-1.0.1}/tests/api/test_bcast.py +3 -3
- {numba_mpi-0.43 → numba_mpi-1.0.1}/tests/api/test_isend_irecv.py +45 -45
- {numba_mpi-0.43 → numba_mpi-1.0.1}/tests/api/test_scatter_gather.py +4 -4
- {numba_mpi-0.43 → numba_mpi-1.0.1}/tests/api/test_send_recv.py +13 -13
- {numba_mpi-0.43 → numba_mpi-1.0.1}/tests/common.py +0 -2
- numba_mpi-1.0.1/tests/paper_listings/exchange.py +26 -0
- numba_mpi-1.0.1/tests/paper_listings/hello.py +13 -0
- numba_mpi-1.0.1/tests/paper_listings/mpi4py_with_error.py +19 -0
- numba_mpi-1.0.1/tests/paper_listings/numba_mpi.py +10 -0
- numba_mpi-1.0.1/tests/paper_listings/py-pde.py +13 -0
- numba_mpi-1.0.1/tests/paper_listings/test.py +31 -0
- numba_mpi-1.0.1/tests/paper_listings/timing.py +19 -0
- numba_mpi-1.0.1/tests/test_paper_listings.py +37 -0
- {numba_mpi-0.43 → numba_mpi-1.0.1}/.github/numba_mpi_logo.svg +0 -0
- {numba_mpi-0.43 → numba_mpi-1.0.1}/.github/workflows/readme_snippets.yml +0 -0
- {numba_mpi-0.43 → numba_mpi-1.0.1}/.github/workflows/stale.yml +0 -0
- {numba_mpi-0.43 → numba_mpi-1.0.1}/.gitignore +0 -0
- {numba_mpi-0.43 → numba_mpi-1.0.1}/.vscode/settings.json +0 -0
- {numba_mpi-0.43 → numba_mpi-1.0.1}/CODE_OF_CONDUCT.md +0 -0
- {numba_mpi-0.43 → numba_mpi-1.0.1}/LICENSE +0 -0
- {numba_mpi-0.43 → numba_mpi-1.0.1}/numba_mpi/api/__init__.py +0 -0
- {numba_mpi-0.43 → numba_mpi-1.0.1}/numba_mpi/api/allreduce.py +0 -0
- {numba_mpi-0.43 → numba_mpi-1.0.1}/numba_mpi/api/barrier.py +0 -0
- {numba_mpi-0.43 → numba_mpi-1.0.1}/numba_mpi/api/bcast.py +0 -0
- {numba_mpi-0.43 → numba_mpi-1.0.1}/numba_mpi/api/irecv.py +0 -0
- {numba_mpi-0.43 → numba_mpi-1.0.1}/numba_mpi/api/isend.py +0 -0
- {numba_mpi-0.43 → numba_mpi-1.0.1}/numba_mpi/api/operator.py +0 -0
- {numba_mpi-0.43 → numba_mpi-1.0.1}/numba_mpi/api/recv.py +0 -0
- {numba_mpi-0.43 → numba_mpi-1.0.1}/numba_mpi/api/requests.py +0 -0
- {numba_mpi-0.43 → numba_mpi-1.0.1}/numba_mpi/api/scatter_gather.py +0 -0
- {numba_mpi-0.43 → numba_mpi-1.0.1}/numba_mpi/api/send.py +0 -0
- {numba_mpi-0.43 → numba_mpi-1.0.1}/numba_mpi/api/wtime.py +0 -0
- {numba_mpi-0.43 → numba_mpi-1.0.1}/numba_mpi/common.py +0 -0
- {numba_mpi-0.43 → numba_mpi-1.0.1}/numba_mpi/utils.py +0 -0
- {numba_mpi-0.43 → numba_mpi-1.0.1}/numba_mpi.egg-info/dependency_links.txt +0 -0
- {numba_mpi-0.43 → numba_mpi-1.0.1}/numba_mpi.egg-info/top_level.txt +0 -0
- {numba_mpi-0.43 → numba_mpi-1.0.1}/setup.cfg +0 -0
- {numba_mpi-0.43 → numba_mpi-1.0.1}/tests/__init__.py +0 -0
- {numba_mpi-0.43 → numba_mpi-1.0.1}/tests/api/test_init.py +0 -0
- {numba_mpi-0.43 → numba_mpi-1.0.1}/tests/api/test_rank.py +0 -0
- {numba_mpi-0.43 → numba_mpi-1.0.1}/tests/api/test_size.py +0 -0
- {numba_mpi-0.43 → numba_mpi-1.0.1}/tests/api/test_wtime.py +0 -0
- {numba_mpi-0.43 → numba_mpi-1.0.1}/tests/test_version.py +0 -0
- {numba_mpi-0.43 → numba_mpi-1.0.1}/tests/utils.py +0 -0
Binary file
|
@@ -33,7 +33,7 @@ jobs:
|
|
33
33
|
pip install -r numba_mpi.egg-info/requires.txt
|
34
34
|
- name: Analysing the code with pylint
|
35
35
|
run: |
|
36
|
-
pylint --unsafe-load-any-extension=y --disable=fixme $(git ls-files '*.py')
|
36
|
+
pylint --unsafe-load-any-extension=y --disable=fixme $(git ls-files '*.py' | grep -v -e ^tests/paper_listings)
|
37
37
|
|
38
38
|
precommit:
|
39
39
|
runs-on: ubuntu-latest
|
@@ -64,15 +64,15 @@ jobs:
|
|
64
64
|
- uses: mpi4py/setup-mpi@v1
|
65
65
|
- name: Build
|
66
66
|
run: |
|
67
|
-
pip install
|
67
|
+
pip install pdoc
|
68
68
|
pip install -e .
|
69
|
-
python -We -m pdoc
|
69
|
+
PDOC_ALLOW_EXEC=1 python -We -m pdoc -o html numba_mpi
|
70
70
|
- name: Deploy
|
71
71
|
if: github.ref == 'refs/heads/main'
|
72
72
|
uses: JamesIves/github-pages-deploy-action@4.1.1
|
73
73
|
with:
|
74
74
|
BRANCH: pdoc
|
75
|
-
FOLDER: html
|
75
|
+
FOLDER: html
|
76
76
|
CLEAN: true
|
77
77
|
|
78
78
|
zenodo_json:
|
@@ -7,12 +7,14 @@ repos:
|
|
7
7
|
rev: 24.1.1
|
8
8
|
hooks:
|
9
9
|
- id: black
|
10
|
+
exclude: ^tests/paper_listings/
|
10
11
|
|
11
12
|
- repo: https://github.com/timothycrosley/isort
|
12
13
|
rev: 5.13.2
|
13
14
|
hooks:
|
14
15
|
- id: isort
|
15
16
|
args: ["--profile", "black"]
|
17
|
+
exclude: ^tests/paper_listings/
|
16
18
|
|
17
19
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
18
20
|
rev: v4.5.0
|
@@ -20,3 +22,4 @@ repos:
|
|
20
22
|
- id: trailing-whitespace
|
21
23
|
- id: end-of-file-fixer
|
22
24
|
- id: debug-statements
|
25
|
+
exclude: ^tests/paper_listings/
|
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"title": "numba-mpi",
|
3
|
-
"description": "Numba @
|
3
|
+
"description": "Numba @jittable wrappers for MPI C API tested on Linux, macOS and Windows",
|
4
4
|
"creators": [
|
5
5
|
{
|
6
6
|
"affiliation": "Jagiellonian University, Kraków, Poland",
|
@@ -0,0 +1,20 @@
|
|
1
|
+
cff-version: 1.2.0
|
2
|
+
title: "numba-mpi"
|
3
|
+
url: "https://github.com/numba-mpi/numba-mpi"
|
4
|
+
preferred-citation:
|
5
|
+
type: article
|
6
|
+
authors:
|
7
|
+
- family-names: "Derlatka"
|
8
|
+
given-names: "Kacper"
|
9
|
+
- family-names: "Manna"
|
10
|
+
given-names: "Maciej"
|
11
|
+
- family-names: "Bulenok"
|
12
|
+
given-names: "Oleksii"
|
13
|
+
- family-names: "Zwicker"
|
14
|
+
given-names: "David"
|
15
|
+
- family-names: "Arabas"
|
16
|
+
given-names: "Sylwester"
|
17
|
+
doi: "10.48550/arXiv.2407.13712"
|
18
|
+
journal: "arXiv"
|
19
|
+
title: " Enabling MPI communication within Numba/LLVM JIT-compiled Python code using numba-mpi v1.0 "
|
20
|
+
year: 2024
|
@@ -1,7 +1,7 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: numba-mpi
|
3
|
-
Version: 0.
|
4
|
-
Summary: Numba @
|
3
|
+
Version: 1.0.1
|
4
|
+
Summary: Numba @jittable MPI wrappers tested on Linux, macOS and Windows
|
5
5
|
Home-page: https://github.com/numba-mpi/numba-mpi
|
6
6
|
Author: https://github.com/numba-mpi/numba-mpi/graphs/contributors
|
7
7
|
License: GPL v3
|
@@ -17,8 +17,9 @@ Requires-Dist: mpi4py
|
|
17
17
|
Requires-Dist: psutil
|
18
18
|
Provides-Extra: tests
|
19
19
|
Requires-Dist: pytest<8.0.0; extra == "tests"
|
20
|
+
Requires-Dist: py-pde; extra == "tests"
|
20
21
|
|
21
|
-
# <img src="https://raw.githubusercontent.com/numba-mpi/numba-mpi/main/.github/numba_mpi_logo.
|
22
|
+
# <img src="https://raw.githubusercontent.com/numba-mpi/numba-mpi/main/.github/numba_mpi_logo.png" width=128 height=142 alt="numba-mpi logo"> numba-mpi
|
22
23
|
|
23
24
|
[](https://www.python.org/)
|
24
25
|
[](https://numba.pydata.org)
|
@@ -34,7 +35,7 @@ Requires-Dist: pytest<8.0.0; extra == "tests"
|
|
34
35
|
[](https://zenodo.org/badge/latestdoi/316911228)
|
35
36
|
|
36
37
|
### Overview
|
37
|
-
numba-mpi provides Python wrappers to the C MPI API callable from within [Numba JIT-compiled code](https://numba.readthedocs.io/en/stable/user/jit.html) (@
|
38
|
+
numba-mpi provides Python wrappers to the C MPI API callable from within [Numba JIT-compiled code](https://numba.readthedocs.io/en/stable/user/jit.html) (@jit mode). For an outline of the project, rationale, architecture, and features, refer to: [numba-mpi arXiv e-print](https://doi.org/10.48550/arXiv.2407.13712) (please cite if numba-mpi is used in your research).
|
38
39
|
|
39
40
|
Support is provided for a subset of MPI routines covering: `size`/`rank`, `send`/`recv`, `allreduce`, `bcast`, `scatter`/`gather` & `allgather`, `barrier`, `wtime`
|
40
41
|
and basic asynchronous communication with `isend`/`irecv` (only for contiguous arrays); for request handling including `wait`/`waitall`/`waitany` and `test`/`testall`/`testany`.
|
@@ -65,7 +66,7 @@ Features that are not implemented yet include (help welcome!):
|
|
65
66
|
```python
|
66
67
|
import numba, numba_mpi, numpy
|
67
68
|
|
68
|
-
@numba.
|
69
|
+
@numba.jit()
|
69
70
|
def hello():
|
70
71
|
src = numpy.array([1., 2., 3., 4., 5.])
|
71
72
|
dst_tst = numpy.empty_like(src)
|
@@ -168,6 +169,7 @@ if numba_mpi.rank() == 0:
|
|
168
169
|
- Intel MPI: https://intel.com/content/www/us/en/developer/tools/oneapi/mpi-library-documentation.html
|
169
170
|
- MPI bindings:
|
170
171
|
- Python: https://mpi4py.readthedocs.io
|
172
|
+
- Python/JAX: https://mpi4jax.readthedocs.io
|
171
173
|
- Julia: https://juliaparallel.org/MPI.jl
|
172
174
|
- Rust: https://docs.rs/mpi
|
173
175
|
- C++: https://boost.org/doc/html/mpi.html
|
@@ -175,5 +177,11 @@ if numba_mpi.rank() == 0:
|
|
175
177
|
|
176
178
|
### Acknowledgements:
|
177
179
|
|
178
|
-
|
180
|
+
We thank [all contributors](https://github.com/numba-mpi/numba-mpi/graphs/contributors) and users who reported feedback to the project
|
181
|
+
through [GitHub issues](https://github.com/numba-mpi/numba-mpi/issues).
|
182
|
+
|
183
|
+
Development of numba-mpi has been supported by the [Polish National Science Centre](https://ncn.gov.pl/en) (grant no. 2020/39/D/ST10/01220),
|
184
|
+
the [Max Planck Society](https://www.mpg.de/en) and the [European Union](https://erc.europa.eu/) (ERC, EmulSim, 101044662).
|
185
|
+
We further acknowledge Poland’s high-performance computing infrastructure [PLGrid](https://plgrid.pl) (HPC Centers: [ACK Cyfronet AGH](https://www.cyfronet.pl/en))
|
186
|
+
for providing computer facilities and support within computational grant no. PLG/2023/016369.
|
179
187
|
|
@@ -1,24 +1,4 @@
|
|
1
|
-
|
2
|
-
Name: numba-mpi
|
3
|
-
Version: 0.43
|
4
|
-
Summary: Numba @njittable MPI wrappers tested on Linux, macOS and Windows
|
5
|
-
Home-page: https://github.com/numba-mpi/numba-mpi
|
6
|
-
Author: https://github.com/numba-mpi/numba-mpi/graphs/contributors
|
7
|
-
License: GPL v3
|
8
|
-
Project-URL: Tracker, https://github.com/numba-mpi/numba-mpi/issues
|
9
|
-
Project-URL: Documentation, https://numba-mpi.github.io/numba-mpi
|
10
|
-
Project-URL: Source, https://github.com/numba-mpi/numba-mpi
|
11
|
-
Requires-Python: >=3.8
|
12
|
-
Description-Content-Type: text/markdown
|
13
|
-
License-File: LICENSE
|
14
|
-
Requires-Dist: numba
|
15
|
-
Requires-Dist: numpy
|
16
|
-
Requires-Dist: mpi4py
|
17
|
-
Requires-Dist: psutil
|
18
|
-
Provides-Extra: tests
|
19
|
-
Requires-Dist: pytest<8.0.0; extra == "tests"
|
20
|
-
|
21
|
-
# <img src="https://raw.githubusercontent.com/numba-mpi/numba-mpi/main/.github/numba_mpi_logo.svg" style="height:50pt" alt="numba-mpi logo"> numba-mpi
|
1
|
+
# <img src="https://raw.githubusercontent.com/numba-mpi/numba-mpi/main/.github/numba_mpi_logo.svg" width=128 height=142 alt="numba-mpi logo"> numba-mpi
|
22
2
|
|
23
3
|
[](https://www.python.org/)
|
24
4
|
[](https://numba.pydata.org)
|
@@ -34,7 +14,7 @@ Requires-Dist: pytest<8.0.0; extra == "tests"
|
|
34
14
|
[](https://zenodo.org/badge/latestdoi/316911228)
|
35
15
|
|
36
16
|
### Overview
|
37
|
-
numba-mpi provides Python wrappers to the C MPI API callable from within [Numba JIT-compiled code](https://numba.readthedocs.io/en/stable/user/jit.html) (@
|
17
|
+
numba-mpi provides Python wrappers to the C MPI API callable from within [Numba JIT-compiled code](https://numba.readthedocs.io/en/stable/user/jit.html) (@jit mode). For an outline of the project, rationale, architecture, and features, refer to: [numba-mpi arXiv e-print](https://doi.org/10.48550/arXiv.2407.13712) (please cite if numba-mpi is used in your research).
|
38
18
|
|
39
19
|
Support is provided for a subset of MPI routines covering: `size`/`rank`, `send`/`recv`, `allreduce`, `bcast`, `scatter`/`gather` & `allgather`, `barrier`, `wtime`
|
40
20
|
and basic asynchronous communication with `isend`/`irecv` (only for contiguous arrays); for request handling including `wait`/`waitall`/`waitany` and `test`/`testall`/`testany`.
|
@@ -65,7 +45,7 @@ Features that are not implemented yet include (help welcome!):
|
|
65
45
|
```python
|
66
46
|
import numba, numba_mpi, numpy
|
67
47
|
|
68
|
-
@numba.
|
48
|
+
@numba.jit()
|
69
49
|
def hello():
|
70
50
|
src = numpy.array([1., 2., 3., 4., 5.])
|
71
51
|
dst_tst = numpy.empty_like(src)
|
@@ -168,6 +148,7 @@ if numba_mpi.rank() == 0:
|
|
168
148
|
- Intel MPI: https://intel.com/content/www/us/en/developer/tools/oneapi/mpi-library-documentation.html
|
169
149
|
- MPI bindings:
|
170
150
|
- Python: https://mpi4py.readthedocs.io
|
151
|
+
- Python/JAX: https://mpi4jax.readthedocs.io
|
171
152
|
- Julia: https://juliaparallel.org/MPI.jl
|
172
153
|
- Rust: https://docs.rs/mpi
|
173
154
|
- C++: https://boost.org/doc/html/mpi.html
|
@@ -175,5 +156,11 @@ if numba_mpi.rank() == 0:
|
|
175
156
|
|
176
157
|
### Acknowledgements:
|
177
158
|
|
178
|
-
|
159
|
+
We thank [all contributors](https://github.com/numba-mpi/numba-mpi/graphs/contributors) and users who reported feedback to the project
|
160
|
+
through [GitHub issues](https://github.com/numba-mpi/numba-mpi/issues).
|
161
|
+
|
162
|
+
Development of numba-mpi has been supported by the [Polish National Science Centre](https://ncn.gov.pl/en) (grant no. 2020/39/D/ST10/01220),
|
163
|
+
the [Max Planck Society](https://www.mpg.de/en) and the [European Union](https://erc.europa.eu/) (ERC, EmulSim, 101044662).
|
164
|
+
We further acknowledge Poland’s high-performance computing infrastructure [PLGrid](https://plgrid.pl) (HPC Centers: [ACK Cyfronet AGH](https://www.cyfronet.pl/en))
|
165
|
+
for providing computer facilities and support within computational grant no. PLG/2023/016369.
|
179
166
|
|
@@ -15,8 +15,9 @@ _MPI_Comm_rank.argtypes = [_MpiComm, ctypes.c_void_p]
|
|
15
15
|
|
16
16
|
@numba.njit()
|
17
17
|
def rank():
|
18
|
-
"""wrapper for MPI_Comm_rank()"""
|
18
|
+
"""wrapper for MPI_Comm_rank(), in case of failure returns 0"""
|
19
19
|
value = np.empty(1, dtype=np.intc)
|
20
20
|
status = _MPI_Comm_rank(_mpi_addr(_MPI_Comm_World_ptr), value.ctypes.data)
|
21
|
-
|
21
|
+
if status != 0:
|
22
|
+
value[0] = 0
|
22
23
|
return value[0]
|
@@ -15,8 +15,9 @@ _MPI_Comm_size.argtypes = [_MpiComm, ctypes.c_void_p]
|
|
15
15
|
|
16
16
|
@numba.njit()
|
17
17
|
def size():
|
18
|
-
"""wrapper for MPI_Comm_size()"""
|
18
|
+
"""wrapper for MPI_Comm_size(), in case of failure returns 0"""
|
19
19
|
value = np.empty(1, dtype=np.intc)
|
20
20
|
status = _MPI_Comm_size(_mpi_addr(_MPI_Comm_World_ptr), value.ctypes.data)
|
21
|
-
|
21
|
+
if status != 0:
|
22
|
+
value[0] = 0
|
22
23
|
return value[0]
|
@@ -1,4 +1,25 @@
|
|
1
|
-
|
1
|
+
Metadata-Version: 2.1
|
2
|
+
Name: numba-mpi
|
3
|
+
Version: 1.0.1
|
4
|
+
Summary: Numba @jittable MPI wrappers tested on Linux, macOS and Windows
|
5
|
+
Home-page: https://github.com/numba-mpi/numba-mpi
|
6
|
+
Author: https://github.com/numba-mpi/numba-mpi/graphs/contributors
|
7
|
+
License: GPL v3
|
8
|
+
Project-URL: Tracker, https://github.com/numba-mpi/numba-mpi/issues
|
9
|
+
Project-URL: Documentation, https://numba-mpi.github.io/numba-mpi
|
10
|
+
Project-URL: Source, https://github.com/numba-mpi/numba-mpi
|
11
|
+
Requires-Python: >=3.8
|
12
|
+
Description-Content-Type: text/markdown
|
13
|
+
License-File: LICENSE
|
14
|
+
Requires-Dist: numba
|
15
|
+
Requires-Dist: numpy
|
16
|
+
Requires-Dist: mpi4py
|
17
|
+
Requires-Dist: psutil
|
18
|
+
Provides-Extra: tests
|
19
|
+
Requires-Dist: pytest<8.0.0; extra == "tests"
|
20
|
+
Requires-Dist: py-pde; extra == "tests"
|
21
|
+
|
22
|
+
# <img src="https://raw.githubusercontent.com/numba-mpi/numba-mpi/main/.github/numba_mpi_logo.png" width=128 height=142 alt="numba-mpi logo"> numba-mpi
|
2
23
|
|
3
24
|
[](https://www.python.org/)
|
4
25
|
[](https://numba.pydata.org)
|
@@ -14,7 +35,7 @@
|
|
14
35
|
[](https://zenodo.org/badge/latestdoi/316911228)
|
15
36
|
|
16
37
|
### Overview
|
17
|
-
numba-mpi provides Python wrappers to the C MPI API callable from within [Numba JIT-compiled code](https://numba.readthedocs.io/en/stable/user/jit.html) (@
|
38
|
+
numba-mpi provides Python wrappers to the C MPI API callable from within [Numba JIT-compiled code](https://numba.readthedocs.io/en/stable/user/jit.html) (@jit mode). For an outline of the project, rationale, architecture, and features, refer to: [numba-mpi arXiv e-print](https://doi.org/10.48550/arXiv.2407.13712) (please cite if numba-mpi is used in your research).
|
18
39
|
|
19
40
|
Support is provided for a subset of MPI routines covering: `size`/`rank`, `send`/`recv`, `allreduce`, `bcast`, `scatter`/`gather` & `allgather`, `barrier`, `wtime`
|
20
41
|
and basic asynchronous communication with `isend`/`irecv` (only for contiguous arrays); for request handling including `wait`/`waitall`/`waitany` and `test`/`testall`/`testany`.
|
@@ -45,7 +66,7 @@ Features that are not implemented yet include (help welcome!):
|
|
45
66
|
```python
|
46
67
|
import numba, numba_mpi, numpy
|
47
68
|
|
48
|
-
@numba.
|
69
|
+
@numba.jit()
|
49
70
|
def hello():
|
50
71
|
src = numpy.array([1., 2., 3., 4., 5.])
|
51
72
|
dst_tst = numpy.empty_like(src)
|
@@ -148,6 +169,7 @@ if numba_mpi.rank() == 0:
|
|
148
169
|
- Intel MPI: https://intel.com/content/www/us/en/developer/tools/oneapi/mpi-library-documentation.html
|
149
170
|
- MPI bindings:
|
150
171
|
- Python: https://mpi4py.readthedocs.io
|
172
|
+
- Python/JAX: https://mpi4jax.readthedocs.io
|
151
173
|
- Julia: https://juliaparallel.org/MPI.jl
|
152
174
|
- Rust: https://docs.rs/mpi
|
153
175
|
- C++: https://boost.org/doc/html/mpi.html
|
@@ -155,5 +177,11 @@ if numba_mpi.rank() == 0:
|
|
155
177
|
|
156
178
|
### Acknowledgements:
|
157
179
|
|
158
|
-
|
180
|
+
We thank [all contributors](https://github.com/numba-mpi/numba-mpi/graphs/contributors) and users who reported feedback to the project
|
181
|
+
through [GitHub issues](https://github.com/numba-mpi/numba-mpi/issues).
|
182
|
+
|
183
|
+
Development of numba-mpi has been supported by the [Polish National Science Centre](https://ncn.gov.pl/en) (grant no. 2020/39/D/ST10/01220),
|
184
|
+
the [Max Planck Society](https://www.mpg.de/en) and the [European Union](https://erc.europa.eu/) (ERC, EmulSim, 101044662).
|
185
|
+
We further acknowledge Poland’s high-performance computing infrastructure [PLGrid](https://plgrid.pl) (HPC Centers: [ACK Cyfronet AGH](https://www.cyfronet.pl/en))
|
186
|
+
for providing computer facilities and support within computational grant no. PLG/2023/016369.
|
159
187
|
|
@@ -1,10 +1,12 @@
|
|
1
1
|
.gitignore
|
2
2
|
.pre-commit-config.yaml
|
3
3
|
.zenodo.json
|
4
|
+
CITATION.cff
|
4
5
|
CODE_OF_CONDUCT.md
|
5
6
|
LICENSE
|
6
7
|
README.md
|
7
8
|
setup.py
|
9
|
+
.github/numba_mpi_logo.png
|
8
10
|
.github/numba_mpi_logo.svg
|
9
11
|
.github/workflows/readme_snippets.yml
|
10
12
|
.github/workflows/stale.yml
|
@@ -35,6 +37,7 @@ numba_mpi/api/size.py
|
|
35
37
|
numba_mpi/api/wtime.py
|
36
38
|
tests/__init__.py
|
37
39
|
tests/common.py
|
40
|
+
tests/test_paper_listings.py
|
38
41
|
tests/test_version.py
|
39
42
|
tests/utils.py
|
40
43
|
tests/api/test_allreduce.py
|
@@ -46,4 +49,11 @@ tests/api/test_rank.py
|
|
46
49
|
tests/api/test_scatter_gather.py
|
47
50
|
tests/api/test_send_recv.py
|
48
51
|
tests/api/test_size.py
|
49
|
-
tests/api/test_wtime.py
|
52
|
+
tests/api/test_wtime.py
|
53
|
+
tests/paper_listings/exchange.py
|
54
|
+
tests/paper_listings/hello.py
|
55
|
+
tests/paper_listings/mpi4py_with_error.py
|
56
|
+
tests/paper_listings/numba_mpi.py
|
57
|
+
tests/paper_listings/py-pde.py
|
58
|
+
tests/paper_listings/test.py
|
59
|
+
tests/paper_listings/timing.py
|
@@ -7,6 +7,9 @@ def get_long_description():
|
|
7
7
|
"""returns contents of README.md file"""
|
8
8
|
with open("README.md", "r", encoding="utf8") as file:
|
9
9
|
long_description = file.read()
|
10
|
+
long_description = long_description.replace(
|
11
|
+
"numba_mpi_logo.svg", "numba_mpi_logo.png"
|
12
|
+
)
|
10
13
|
return long_description
|
11
14
|
|
12
15
|
|
@@ -21,9 +24,9 @@ setup(
|
|
21
24
|
python_requires=">=3.8",
|
22
25
|
setup_requires=["setuptools_scm"],
|
23
26
|
license="GPL v3",
|
24
|
-
description="Numba @
|
27
|
+
description="Numba @jittable MPI wrappers tested on Linux, macOS and Windows",
|
25
28
|
install_requires=("numba", "numpy", "mpi4py", "psutil"),
|
26
|
-
extras_require={"tests": ("pytest<8.0.0")}, # TODO #122
|
29
|
+
extras_require={"tests": ("pytest<8.0.0", "py-pde")}, # TODO #122
|
27
30
|
long_description=get_long_description(),
|
28
31
|
long_description_content_type="text/markdown",
|
29
32
|
packages=find_packages(include=["numba_mpi", "numba_mpi.*"]),
|
@@ -4,7 +4,7 @@ import pytest
|
|
4
4
|
from numba import njit
|
5
5
|
|
6
6
|
import numba_mpi as mpi
|
7
|
-
from tests.common import
|
7
|
+
from tests.common import data_types_real
|
8
8
|
from tests.utils import get_random_array
|
9
9
|
|
10
10
|
|
@@ -29,7 +29,7 @@ def test_allreduce(allreduce, op_mpi, op_np, data_type):
|
|
29
29
|
src = get_random_array((3,), data_type)
|
30
30
|
rcv = np.empty_like(src)
|
31
31
|
status = allreduce(src, rcv, operator=op_mpi)
|
32
|
-
assert status ==
|
32
|
+
assert status == mpi.SUCCESS
|
33
33
|
expect = op_np(np.tile(src, [mpi.size(), 1]), axis=0)
|
34
34
|
np.testing.assert_equal(rcv, expect)
|
35
35
|
|
@@ -37,7 +37,7 @@ def test_allreduce(allreduce, op_mpi, op_np, data_type):
|
|
37
37
|
src = src[0]
|
38
38
|
rcv = np.empty(1, dtype=src.dtype)
|
39
39
|
status = allreduce(src, rcv, operator=op_mpi)
|
40
|
-
assert status ==
|
40
|
+
assert status == mpi.SUCCESS
|
41
41
|
expect = op_np(np.tile(src, [mpi.size(), 1]), axis=0)
|
42
42
|
np.testing.assert_equal(rcv, expect)
|
43
43
|
|
@@ -45,6 +45,6 @@ def test_allreduce(allreduce, op_mpi, op_np, data_type):
|
|
45
45
|
src = get_random_array((), data_type)
|
46
46
|
rcv = np.empty_like(src)
|
47
47
|
status = allreduce(src, rcv, operator=op_mpi)
|
48
|
-
assert status ==
|
48
|
+
assert status == mpi.SUCCESS
|
49
49
|
expect = op_np(np.tile(src, [mpi.size(), 1]), axis=0)
|
50
50
|
np.testing.assert_equal(rcv, expect)
|
@@ -3,7 +3,6 @@ import numba
|
|
3
3
|
import pytest
|
4
4
|
|
5
5
|
import numba_mpi
|
6
|
-
from tests.common import MPI_SUCCESS
|
7
6
|
|
8
7
|
|
9
8
|
@numba.njit()
|
@@ -15,4 +14,4 @@ def jit_barrier():
|
|
15
14
|
def test_barrier(barrier):
|
16
15
|
status = barrier()
|
17
16
|
|
18
|
-
assert status ==
|
17
|
+
assert status == numba_mpi.SUCCESS
|
@@ -4,7 +4,7 @@ import numpy as np
|
|
4
4
|
import pytest
|
5
5
|
|
6
6
|
import numba_mpi as mpi
|
7
|
-
from tests.common import
|
7
|
+
from tests.common import data_types
|
8
8
|
from tests.utils import get_random_array
|
9
9
|
|
10
10
|
|
@@ -25,7 +25,7 @@ def test_bcast_np_array(data_type, bcast):
|
|
25
25
|
|
26
26
|
status = bcast(data, root)
|
27
27
|
|
28
|
-
assert status ==
|
28
|
+
assert status == mpi.SUCCESS
|
29
29
|
|
30
30
|
np.testing.assert_equal(data, datatobcast)
|
31
31
|
|
@@ -43,5 +43,5 @@ def test_bcast_string(stringtobcast):
|
|
43
43
|
data = datatobcast
|
44
44
|
|
45
45
|
status = mpi.bcast(data, root)
|
46
|
-
assert status ==
|
46
|
+
assert status == mpi.SUCCESS
|
47
47
|
assert str(data) == str(datatobcast)
|
@@ -7,7 +7,7 @@ import pytest
|
|
7
7
|
from mpi4py.MPI import ANY_SOURCE, ANY_TAG, COMM_WORLD
|
8
8
|
|
9
9
|
import numba_mpi as mpi
|
10
|
-
from tests.common import
|
10
|
+
from tests.common import data_types
|
11
11
|
from tests.utils import get_random_array
|
12
12
|
|
13
13
|
TEST_WAIT_FULL_IN_SECONDS = 0.3
|
@@ -69,23 +69,23 @@ def test_isend_irecv(isnd, ircv, wait, data_type):
|
|
69
69
|
|
70
70
|
if mpi.rank() == 0:
|
71
71
|
status, req = isnd(src, dest=1, tag=11)
|
72
|
-
assert status ==
|
72
|
+
assert status == mpi.SUCCESS
|
73
73
|
|
74
74
|
req_exp = COMM_WORLD.Isend(src, dest=1, tag=22)
|
75
75
|
|
76
76
|
status = wait(req)
|
77
|
-
assert status ==
|
77
|
+
assert status == mpi.SUCCESS
|
78
78
|
|
79
79
|
req_exp.wait()
|
80
80
|
|
81
81
|
elif mpi.rank() == 1:
|
82
82
|
status, req = ircv(dst_tst, source=0, tag=11)
|
83
|
-
assert status ==
|
83
|
+
assert status == mpi.SUCCESS
|
84
84
|
|
85
85
|
req_exp = COMM_WORLD.Irecv(dst_exp, source=0, tag=22)
|
86
86
|
|
87
87
|
status = wait(req)
|
88
|
-
assert status ==
|
88
|
+
assert status == mpi.SUCCESS
|
89
89
|
|
90
90
|
req_exp.wait()
|
91
91
|
|
@@ -106,11 +106,11 @@ def test_send_default_tag(isnd, ircv, wait):
|
|
106
106
|
|
107
107
|
if mpi.rank() == 0:
|
108
108
|
status, req = isnd(src, dest=1)
|
109
|
-
assert status ==
|
109
|
+
assert status == mpi.SUCCESS
|
110
110
|
wait(req)
|
111
111
|
elif mpi.rank() == 1:
|
112
112
|
status, req = ircv(dst_tst, source=0, tag=0)
|
113
|
-
assert status ==
|
113
|
+
assert status == mpi.SUCCESS
|
114
114
|
wait(req)
|
115
115
|
|
116
116
|
np.testing.assert_equal(dst_tst, src)
|
@@ -129,11 +129,11 @@ def test_recv_default_tag(isnd, ircv, wait):
|
|
129
129
|
|
130
130
|
if mpi.rank() == 0:
|
131
131
|
status, req = isnd(src, dest=1, tag=44)
|
132
|
-
assert status ==
|
132
|
+
assert status == mpi.SUCCESS
|
133
133
|
wait(req)
|
134
134
|
elif mpi.rank() == 1:
|
135
135
|
status, req = ircv(dst_tst, source=0)
|
136
|
-
assert status ==
|
136
|
+
assert status == mpi.SUCCESS
|
137
137
|
wait(req)
|
138
138
|
|
139
139
|
np.testing.assert_equal(dst_tst, src)
|
@@ -152,11 +152,11 @@ def test_recv_default_source(isnd, ircv, wait):
|
|
152
152
|
|
153
153
|
if mpi.rank() == 0:
|
154
154
|
status, req = isnd(src, dest=1, tag=44)
|
155
|
-
assert status ==
|
155
|
+
assert status == mpi.SUCCESS
|
156
156
|
wait(req)
|
157
157
|
elif mpi.rank() == 1:
|
158
158
|
status, req = ircv(dst_tst, tag=44)
|
159
|
-
assert status ==
|
159
|
+
assert status == mpi.SUCCESS
|
160
160
|
wait(req)
|
161
161
|
|
162
162
|
np.testing.assert_equal(dst_tst, src)
|
@@ -179,21 +179,21 @@ def test_isend_irecv_waitall(isnd, ircv, wall, data_type):
|
|
179
179
|
reqs = np.zeros((2,), dtype=mpi.RequestType)
|
180
180
|
if mpi.rank() == 0:
|
181
181
|
status, reqs[0:1] = isnd(src1, dest=1, tag=11)
|
182
|
-
assert status ==
|
182
|
+
assert status == mpi.SUCCESS
|
183
183
|
status, reqs[1:2] = isnd(src2, dest=1, tag=22)
|
184
|
-
assert status ==
|
184
|
+
assert status == mpi.SUCCESS
|
185
185
|
|
186
186
|
status = wall(reqs)
|
187
|
-
assert status ==
|
187
|
+
assert status == mpi.SUCCESS
|
188
188
|
|
189
189
|
elif mpi.rank() == 1:
|
190
190
|
status, reqs[0:1] = ircv(dst1, source=0, tag=11)
|
191
|
-
assert status ==
|
191
|
+
assert status == mpi.SUCCESS
|
192
192
|
status, reqs[1:2] = ircv(dst2, source=0, tag=22)
|
193
|
-
assert status ==
|
193
|
+
assert status == mpi.SUCCESS
|
194
194
|
|
195
195
|
status = wall(reqs)
|
196
|
-
assert status ==
|
196
|
+
assert status == mpi.SUCCESS
|
197
197
|
|
198
198
|
np.testing.assert_equal(dst1, src1)
|
199
199
|
np.testing.assert_equal(dst2, src2)
|
@@ -214,21 +214,21 @@ def test_isend_irecv_waitall_tuple(isnd, ircv, wall):
|
|
214
214
|
|
215
215
|
if mpi.rank() == 0:
|
216
216
|
status, req_1 = isnd(src1, dest=1, tag=11)
|
217
|
-
assert status ==
|
217
|
+
assert status == mpi.SUCCESS
|
218
218
|
status, req_2 = isnd(src2, dest=1, tag=22)
|
219
|
-
assert status ==
|
219
|
+
assert status == mpi.SUCCESS
|
220
220
|
|
221
221
|
status = wall((req_1, req_2))
|
222
|
-
assert status ==
|
222
|
+
assert status == mpi.SUCCESS
|
223
223
|
|
224
224
|
elif mpi.rank() == 1:
|
225
225
|
status, req_1 = ircv(dst1, source=0, tag=11)
|
226
|
-
assert status ==
|
226
|
+
assert status == mpi.SUCCESS
|
227
227
|
status, req_2 = ircv(dst2, source=0, tag=22)
|
228
|
-
assert status ==
|
228
|
+
assert status == mpi.SUCCESS
|
229
229
|
|
230
230
|
status = wall((req_1, req_2))
|
231
|
-
assert status ==
|
231
|
+
assert status == mpi.SUCCESS
|
232
232
|
|
233
233
|
np.testing.assert_equal(dst1, src1)
|
234
234
|
np.testing.assert_equal(dst2, src2)
|
@@ -248,15 +248,15 @@ def test_isend_irecv_waitall_exchange(isnd, ircv, wall):
|
|
248
248
|
reqs = np.zeros((2,), dtype=mpi.RequestType)
|
249
249
|
if mpi.rank() == 0:
|
250
250
|
status, reqs[0:1] = isnd(src, dest=1, tag=11)
|
251
|
-
assert status ==
|
251
|
+
assert status == mpi.SUCCESS
|
252
252
|
status, reqs[1:2] = ircv(dst, source=1, tag=22)
|
253
|
-
assert status ==
|
253
|
+
assert status == mpi.SUCCESS
|
254
254
|
|
255
255
|
elif mpi.rank() == 1:
|
256
256
|
status, reqs[0:1] = isnd(src, dest=0, tag=22)
|
257
|
-
assert status ==
|
257
|
+
assert status == mpi.SUCCESS
|
258
258
|
status, reqs[1:2] = ircv(dst, source=0, tag=11)
|
259
|
-
assert status ==
|
259
|
+
assert status == mpi.SUCCESS
|
260
260
|
|
261
261
|
wall(reqs)
|
262
262
|
|
@@ -303,19 +303,19 @@ def test_isend_irecv_waitany(isnd, ircv, wany, wall, data_type):
|
|
303
303
|
reqs = np.zeros((2,), dtype=mpi.RequestType)
|
304
304
|
if mpi.rank() == 0:
|
305
305
|
status, reqs[0:1] = isnd(src1, dest=1, tag=11)
|
306
|
-
assert status ==
|
306
|
+
assert status == mpi.SUCCESS
|
307
307
|
status, reqs[1:2] = isnd(src2, dest=1, tag=22)
|
308
|
-
assert status ==
|
308
|
+
assert status == mpi.SUCCESS
|
309
309
|
wall(reqs)
|
310
310
|
|
311
311
|
elif mpi.rank() == 1:
|
312
312
|
status, reqs[0:1] = ircv(dst1, source=0, tag=11)
|
313
|
-
assert status ==
|
313
|
+
assert status == mpi.SUCCESS
|
314
314
|
status, reqs[1:2] = ircv(dst2, source=0, tag=22)
|
315
|
-
assert status ==
|
315
|
+
assert status == mpi.SUCCESS
|
316
316
|
|
317
317
|
status, index = wany(reqs)
|
318
|
-
assert status ==
|
318
|
+
assert status == mpi.SUCCESS
|
319
319
|
|
320
320
|
if index == 0:
|
321
321
|
np.testing.assert_equal(dst1, src1)
|
@@ -341,14 +341,14 @@ def test_isend_irecv_test(isnd, ircv, tst, wait):
|
|
341
341
|
if mpi.rank() == 0:
|
342
342
|
time.sleep(TEST_WAIT_FULL_IN_SECONDS)
|
343
343
|
status, req = isnd(src, dest=1, tag=11)
|
344
|
-
assert status ==
|
344
|
+
assert status == mpi.SUCCESS
|
345
345
|
wait(req)
|
346
346
|
elif mpi.rank() == 1:
|
347
347
|
status, req = ircv(dst, source=0, tag=11)
|
348
|
-
assert status ==
|
348
|
+
assert status == mpi.SUCCESS
|
349
349
|
|
350
350
|
status, flag = tst(req)
|
351
|
-
while status ==
|
351
|
+
while status == mpi.SUCCESS and not flag:
|
352
352
|
time.sleep(TEST_WAIT_INCREMENT_IN_SECONDS)
|
353
353
|
status, flag = tst(req)
|
354
354
|
|
@@ -379,20 +379,20 @@ def test_isend_irecv_testall(isnd, ircv, tall, wall):
|
|
379
379
|
time.sleep(TEST_WAIT_FULL_IN_SECONDS)
|
380
380
|
|
381
381
|
status, reqs[0:1] = isnd(src1, dest=1, tag=11)
|
382
|
-
assert status ==
|
382
|
+
assert status == mpi.SUCCESS
|
383
383
|
status, reqs[1:2] = isnd(src2, dest=1, tag=22)
|
384
|
-
assert status ==
|
384
|
+
assert status == mpi.SUCCESS
|
385
385
|
|
386
386
|
wall(reqs)
|
387
387
|
|
388
388
|
elif mpi.rank() == 1:
|
389
389
|
status, reqs[0:1] = ircv(dst1, source=0, tag=11)
|
390
|
-
assert status ==
|
390
|
+
assert status == mpi.SUCCESS
|
391
391
|
status, reqs[1:2] = ircv(dst2, source=0, tag=22)
|
392
|
-
assert status ==
|
392
|
+
assert status == mpi.SUCCESS
|
393
393
|
|
394
394
|
status, flag = tall(reqs)
|
395
|
-
while status ==
|
395
|
+
while status == mpi.SUCCESS and not flag:
|
396
396
|
time.sleep(TEST_WAIT_INCREMENT_IN_SECONDS)
|
397
397
|
status, flag = tall(reqs)
|
398
398
|
|
@@ -425,20 +425,20 @@ def test_isend_irecv_testany(isnd, ircv, tany, wall):
|
|
425
425
|
time.sleep(TEST_WAIT_FULL_IN_SECONDS)
|
426
426
|
|
427
427
|
status, reqs[0:1] = isnd(src1, dest=1, tag=11)
|
428
|
-
assert status ==
|
428
|
+
assert status == mpi.SUCCESS
|
429
429
|
status, reqs[1:2] = isnd(src2, dest=1, tag=22)
|
430
|
-
assert status ==
|
430
|
+
assert status == mpi.SUCCESS
|
431
431
|
|
432
432
|
wall(reqs)
|
433
433
|
|
434
434
|
elif mpi.rank() == 1:
|
435
435
|
status, reqs[0:1] = ircv(dst1, source=0, tag=11)
|
436
|
-
assert status ==
|
436
|
+
assert status == mpi.SUCCESS
|
437
437
|
status, reqs[1:2] = ircv(dst2, source=0, tag=22)
|
438
|
-
assert status ==
|
438
|
+
assert status == mpi.SUCCESS
|
439
439
|
|
440
440
|
status, flag, index = tany(reqs)
|
441
|
-
while status ==
|
441
|
+
while status == mpi.SUCCESS and not flag:
|
442
442
|
time.sleep(TEST_WAIT_INCREMENT_IN_SECONDS)
|
443
443
|
status, flag, index = tany(reqs)
|
444
444
|
|
@@ -4,7 +4,7 @@ import numpy as np
|
|
4
4
|
import pytest
|
5
5
|
|
6
6
|
import numba_mpi as mpi
|
7
|
-
from tests.common import
|
7
|
+
from tests.common import data_types
|
8
8
|
from tests.utils import get_random_array
|
9
9
|
|
10
10
|
|
@@ -41,7 +41,7 @@ def test_scatter(data_type, scatter, send_count, data_size):
|
|
41
41
|
recv_data = np.empty(send_count, data_type).astype(dtype=data_type)
|
42
42
|
status = scatter(send_data, recv_data, send_count, root)
|
43
43
|
|
44
|
-
assert status ==
|
44
|
+
assert status == mpi.SUCCESS
|
45
45
|
np.testing.assert_equal(
|
46
46
|
recv_data, data[rank * send_count : (rank + 1) * send_count]
|
47
47
|
)
|
@@ -71,7 +71,7 @@ def test_gather(data_type, gather, recv_count, data_size):
|
|
71
71
|
|
72
72
|
status = gather(send_data, recv_data, recv_count, root)
|
73
73
|
|
74
|
-
assert status ==
|
74
|
+
assert status == mpi.SUCCESS
|
75
75
|
valid_range = slice(0, mpi.size() * recv_count)
|
76
76
|
if rank == root:
|
77
77
|
np.testing.assert_equal(data[valid_range], recv_data[valid_range])
|
@@ -98,6 +98,6 @@ def test_allgather(data_type, allgather, recv_count, data_size):
|
|
98
98
|
|
99
99
|
status = allgather(send_data, recv_data, recv_count)
|
100
100
|
|
101
|
-
assert status ==
|
101
|
+
assert status == mpi.SUCCESS
|
102
102
|
valid_range = slice(0, mpi.size() * recv_count)
|
103
103
|
np.testing.assert_equal(data[valid_range], recv_data[valid_range])
|
@@ -4,7 +4,7 @@ import pytest
|
|
4
4
|
from mpi4py.MPI import COMM_WORLD
|
5
5
|
|
6
6
|
import numba_mpi as mpi
|
7
|
-
from tests.common import
|
7
|
+
from tests.common import data_types
|
8
8
|
from tests.utils import get_random_array
|
9
9
|
|
10
10
|
|
@@ -26,11 +26,11 @@ def test_send_recv(snd, rcv, fortran_order, data_type):
|
|
26
26
|
|
27
27
|
if mpi.rank() == 0:
|
28
28
|
status = snd(src, dest=1, tag=11)
|
29
|
-
assert status ==
|
29
|
+
assert status == mpi.SUCCESS
|
30
30
|
COMM_WORLD.Send(src, dest=1, tag=22)
|
31
31
|
elif mpi.rank() == 1:
|
32
32
|
status = rcv(dst_tst, source=0, tag=11)
|
33
|
-
assert status ==
|
33
|
+
assert status == mpi.SUCCESS
|
34
34
|
COMM_WORLD.Recv(dst_exp, source=0, tag=22)
|
35
35
|
|
36
36
|
np.testing.assert_equal(dst_tst, src)
|
@@ -47,10 +47,10 @@ def test_send_recv_noncontiguous(snd, rcv, data_type):
|
|
47
47
|
|
48
48
|
if mpi.rank() == 0:
|
49
49
|
status = snd(src[::2], dest=1, tag=11)
|
50
|
-
assert status ==
|
50
|
+
assert status == mpi.SUCCESS
|
51
51
|
elif mpi.rank() == 1:
|
52
52
|
status = rcv(dst_tst[::2], source=0, tag=11)
|
53
|
-
assert status ==
|
53
|
+
assert status == mpi.SUCCESS
|
54
54
|
|
55
55
|
np.testing.assert_equal(dst_tst[1::2], 0)
|
56
56
|
np.testing.assert_equal(dst_tst[::2], src[::2])
|
@@ -66,10 +66,10 @@ def test_send_0d_arrays(snd, rcv, data_type):
|
|
66
66
|
|
67
67
|
if mpi.rank() == 0:
|
68
68
|
status = snd(src, dest=1, tag=11)
|
69
|
-
assert status ==
|
69
|
+
assert status == mpi.SUCCESS
|
70
70
|
elif mpi.rank() == 1:
|
71
71
|
status = rcv(dst_tst, source=0, tag=11)
|
72
|
-
assert status ==
|
72
|
+
assert status == mpi.SUCCESS
|
73
73
|
|
74
74
|
np.testing.assert_equal(dst_tst, src)
|
75
75
|
|
@@ -83,10 +83,10 @@ def test_send_default_tag(snd, rcv):
|
|
83
83
|
|
84
84
|
if mpi.rank() == 0:
|
85
85
|
status = snd(src, dest=1)
|
86
|
-
assert status ==
|
86
|
+
assert status == mpi.SUCCESS
|
87
87
|
elif mpi.rank() == 1:
|
88
88
|
status = rcv(dst_tst, source=0, tag=0)
|
89
|
-
assert status ==
|
89
|
+
assert status == mpi.SUCCESS
|
90
90
|
|
91
91
|
np.testing.assert_equal(dst_tst, src)
|
92
92
|
|
@@ -100,10 +100,10 @@ def test_recv_default_tag(snd, rcv):
|
|
100
100
|
|
101
101
|
if mpi.rank() == 0:
|
102
102
|
status = snd(src, dest=1, tag=44)
|
103
|
-
assert status ==
|
103
|
+
assert status == mpi.SUCCESS
|
104
104
|
elif mpi.rank() == 1:
|
105
105
|
status = rcv(dst_tst, source=0)
|
106
|
-
assert status ==
|
106
|
+
assert status == mpi.SUCCESS
|
107
107
|
|
108
108
|
np.testing.assert_equal(dst_tst, src)
|
109
109
|
|
@@ -117,9 +117,9 @@ def test_recv_default_source(snd, rcv):
|
|
117
117
|
|
118
118
|
if mpi.rank() == 0:
|
119
119
|
status = snd(src, dest=1, tag=44)
|
120
|
-
assert status ==
|
120
|
+
assert status == mpi.SUCCESS
|
121
121
|
elif mpi.rank() == 1:
|
122
122
|
status = rcv(dst_tst, tag=44)
|
123
|
-
assert status ==
|
123
|
+
assert status == mpi.SUCCESS
|
124
124
|
|
125
125
|
np.testing.assert_equal(dst_tst, src)
|
@@ -0,0 +1,26 @@
|
|
1
|
+
import numpy as np
|
2
|
+
import numba_mpi as mpi
|
3
|
+
import numba
|
4
|
+
|
5
|
+
@numba.jit(nopython=True)
|
6
|
+
def exchange_data(src_data):
|
7
|
+
dst_data = np.empty_like(src_data)
|
8
|
+
reqs = np.zeros((2,), dtype=mpi.RequestType)
|
9
|
+
|
10
|
+
if mpi.rank() == 0:
|
11
|
+
status, reqs[0:1] = mpi.isend(src_data, dest=1, tag=11)
|
12
|
+
assert status == mpi.SUCCESS
|
13
|
+
status, reqs[1:2] = mpi.irecv(dst_data, source=1, tag=22)
|
14
|
+
assert status == mpi.SUCCESS
|
15
|
+
elif mpi.rank() == 1:
|
16
|
+
status, reqs[0:1] = mpi.isend(src_data, dest=0, tag=22)
|
17
|
+
assert status == mpi.SUCCESS
|
18
|
+
status, reqs[1:2] = mpi.irecv(dst_data, source=0, tag=11)
|
19
|
+
assert status == mpi.SUCCESS
|
20
|
+
|
21
|
+
mpi.waitall(reqs)
|
22
|
+
return dst_data
|
23
|
+
|
24
|
+
if mpi.rank() < 2:
|
25
|
+
src_data = np.random.rand(10000)
|
26
|
+
dst_data = exchange_data(src_data)
|
@@ -0,0 +1,13 @@
|
|
1
|
+
import numba, timeit
|
2
|
+
|
3
|
+
@numba.jit(nopython=True)
|
4
|
+
def get_pi_part(n_intervals=1000000, rank=0, size=1):
|
5
|
+
h = 1 / n_intervals
|
6
|
+
partial_sum = 0.0
|
7
|
+
for i in range(rank + 1, n_intervals, size):
|
8
|
+
x = h * (i - 0.5)
|
9
|
+
partial_sum += 4 / (1 + x**2)
|
10
|
+
return h * partial_sum
|
11
|
+
|
12
|
+
time = lambda fun: min(timeit.repeat(fun, number=1, repeat=5))
|
13
|
+
print(f"speedup: {time(get_pi_part.py_func) / time(get_pi_part):.3g}")
|
@@ -0,0 +1,19 @@
|
|
1
|
+
import mpi4py, numba, numpy as np
|
2
|
+
|
3
|
+
N_TIMES = 10000
|
4
|
+
RTOL = 1e-3
|
5
|
+
|
6
|
+
def pi_mpi4py(n_intervals):
|
7
|
+
pi = np.array([0.])
|
8
|
+
part = np.empty_like(pi)
|
9
|
+
for _ in range(N_TIMES):
|
10
|
+
part[0] = get_pi_part(n_intervals,
|
11
|
+
mpi4py.MPI.COMM_WORLD.rank, mpi4py.MPI.COMM_WORLD.size)
|
12
|
+
mpi4py.MPI.COMM_WORLD.Allreduce(part,
|
13
|
+
(pi, mpi4py.MPI.DOUBLE), op=mpi4py.MPI.SUM)
|
14
|
+
assert abs(pi[0] - np.pi) / np.pi < RTOL
|
15
|
+
|
16
|
+
try:
|
17
|
+
numba.jit(pi_mpi4py, nopython=True)(1)
|
18
|
+
except Exception as ex:
|
19
|
+
print(ex)
|
@@ -0,0 +1,10 @@
|
|
1
|
+
import numba_mpi
|
2
|
+
|
3
|
+
@numba.jit(nopython=True)
|
4
|
+
def pi_numba_mpi(n_intervals):
|
5
|
+
pi = np.array([0.])
|
6
|
+
part = np.empty_like(pi)
|
7
|
+
for _ in range(N_TIMES):
|
8
|
+
part[0] = get_pi_part(n_intervals, numba_mpi.rank(), numba_mpi.size())
|
9
|
+
numba_mpi.allreduce(part, pi, numba_mpi.Operator.SUM)
|
10
|
+
assert abs(pi[0] - np.pi) / np.pi < RTOL
|
@@ -0,0 +1,13 @@
|
|
1
|
+
import pde
|
2
|
+
|
3
|
+
grid = pde.UnitGrid([16, 16])
|
4
|
+
state = pde.ScalarField.random_uniform(grid, 0.49, 0.51)
|
5
|
+
eq = pde.PDE({"c": "laplace(c**3-c-laplace(c))-0.01*(c-0.5)"})
|
6
|
+
|
7
|
+
final_state = eq.solve(
|
8
|
+
state,
|
9
|
+
t_range=1e4,
|
10
|
+
adaptive=True,
|
11
|
+
solver="explicit_mpi",
|
12
|
+
decomposition=[2, -1],
|
13
|
+
)
|
@@ -0,0 +1,31 @@
|
|
1
|
+
import numpy as np
|
2
|
+
import pytest
|
3
|
+
import numba_mpi as mpi
|
4
|
+
from tests.common import data_types
|
5
|
+
from tests.utils import get_random_array
|
6
|
+
|
7
|
+
@pytest.mark.parametrize("snd, rcv", (
|
8
|
+
(mpi.send, mpi.recv),
|
9
|
+
(mpi.send.py_func, mpi.recv.py_func))
|
10
|
+
)
|
11
|
+
@pytest.mark.parametrize("fortran_order", [True, False])
|
12
|
+
@pytest.mark.parametrize("data_type", data_types)
|
13
|
+
def test_send_recv(snd, rcv, fortran_order, data_type):
|
14
|
+
src = get_random_array((3, 3), data_type)
|
15
|
+
if fortran_order:
|
16
|
+
src = np.asfortranarray(src, dtype=data_type)
|
17
|
+
else:
|
18
|
+
src = src.astype(dtype=data_type)
|
19
|
+
dst_exp = np.empty_like(src)
|
20
|
+
dst_tst = np.empty_like(src)
|
21
|
+
|
22
|
+
if mpi.rank() == 0:
|
23
|
+
status = snd(src, dest=1, tag=11)
|
24
|
+
assert status == mpi.SUCCESS
|
25
|
+
COMM_WORLD.Send(src, dest=1, tag=22)
|
26
|
+
elif mpi.rank() == 1:
|
27
|
+
status = rcv(dst_tst, source=0, tag=11)
|
28
|
+
assert status == mpi.SUCCESS
|
29
|
+
COMM_WORLD.Recv(dst_exp, source=0, tag=22)
|
30
|
+
np.testing.assert_equal(dst_tst, src)
|
31
|
+
np.testing.assert_equal(dst_exp, src)
|
@@ -0,0 +1,19 @@
|
|
1
|
+
from matplotlib import pyplot
|
2
|
+
|
3
|
+
plot_x = [x for x in range(1, 11)]
|
4
|
+
plot_y = {'numba_mpi': [], 'mpi4py': []}
|
5
|
+
for x in plot_x:
|
6
|
+
for impl in plot_y:
|
7
|
+
plot_y[impl].append(min(timeit.repeat(
|
8
|
+
f"pi_{impl}(n_intervals={N_TIMES // x})",
|
9
|
+
globals=locals(),
|
10
|
+
number=1,
|
11
|
+
repeat=10
|
12
|
+
)))
|
13
|
+
|
14
|
+
if numba_mpi.rank() == 0:
|
15
|
+
pyplot.plot(
|
16
|
+
plot_x,
|
17
|
+
np.array(plot_y['mpi4py'])/np.array(plot_y['numba_mpi']),
|
18
|
+
marker='o'
|
19
|
+
)
|
@@ -0,0 +1,37 @@
|
|
1
|
+
""" checks if listings from the paper run OK """
|
2
|
+
|
3
|
+
import pathlib
|
4
|
+
|
5
|
+
import pytest
|
6
|
+
|
7
|
+
import numba_mpi
|
8
|
+
|
9
|
+
|
10
|
+
@pytest.mark.parametrize(
|
11
|
+
"files",
|
12
|
+
(
|
13
|
+
("hello.py", "mpi4py_with_error.py", "numba_mpi.py", "timing.py"),
|
14
|
+
("exchange.py",),
|
15
|
+
("test.py",),
|
16
|
+
pytest.param(
|
17
|
+
("py-pde.py",),
|
18
|
+
marks=pytest.mark.skipif(numba_mpi.size() != 2, reason="hardcoded"),
|
19
|
+
),
|
20
|
+
),
|
21
|
+
)
|
22
|
+
@pytest.mark.skipif(numba_mpi.size() == 1, reason="listings assume more than 1 worker")
|
23
|
+
def test_paper_listings(files):
|
24
|
+
"""concatenates code from all files and executes it in global scope"""
|
25
|
+
code = ""
|
26
|
+
for file in files:
|
27
|
+
with open(
|
28
|
+
pathlib.Path(__file__).parent / "paper_listings" / file, encoding="utf-8"
|
29
|
+
) as stream:
|
30
|
+
code += "".join(stream.readlines())
|
31
|
+
code += "\n"
|
32
|
+
try:
|
33
|
+
exec(code, globals()) # pylint: disable=exec-used
|
34
|
+
except Exception as ex:
|
35
|
+
for line_num, line in enumerate(code.split("\n"), start=1):
|
36
|
+
print(line_num, ":", line)
|
37
|
+
raise ex
|
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
|
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
|