Skip to content

Commit 6584fdc

Browse files
authored
Documentation (#15)
More docs, more examples.
1 parent d51c764 commit 6584fdc

20 files changed

+836
-11
lines changed

.github/workflows/containers.yml

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
name: containers
2+
13
on:
24
push:
35
branches:
@@ -31,5 +33,9 @@ jobs:
3133
run: docker run -v $PWD:/repo -w/repo local /bin/bash -c "pip install . && make test-1 opt=-v"
3234
- name: run shmem4py test-2
3335
run: docker run -v $PWD:/repo -w/repo local /bin/bash -c "pip install . && make test-2 opt=-v"
36+
- name: run shmem4py demo-test-1
37+
run: docker run -v $PWD:/repo -w/repo local /bin/bash -c "pip install . && cd demo && make test-1 opt=-v"
38+
- name: run shmem4py demo-test-2
39+
run: docker run -v $PWD:/repo -w/repo local /bin/bash -c "pip install . && cd demo && make test-2 opt=-v"
3440
- name: clean docker cache
3541
run: docker image prune --all --force --filter "until=168h"

.github/workflows/native.yml

+6
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,9 @@ jobs:
6060

6161
- name: Test - 2 processes
6262
run: make test-2
63+
64+
- name: Demo - Test - 1 process
65+
run: cd demo && make test-1
66+
67+
- name: Demo - Test - 2 processes
68+
run: cd demo && make test-2

INSTALL.rst

+144
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
==============================
2+
Installation
3+
==============================
4+
5+
Overview
6+
--------
7+
8+
`shmem4py` provides Python bindings for `OpenSHMEM <http://openshmem.org/>`_, hence
9+
a working OpenSHMEM installation is a prerequisite.
10+
`Cray OpenSHMEMX <https://cray-openshmemx.readthedocs.io/>`_,
11+
`Open Source Software Solutions (OSSS) OpenSHMEM <https://github.com/openshmem-org/osss-ucx>`_,
12+
`Open MPI OpenSHMEM <https://www.open-mpi.org/doc/v3.1/man3/OpenSHMEM.3.php>`_,
13+
`OSHMPI <https://pmodels.github.io/oshmpi-www/>`_, and
14+
`Sandia OpenSHMEM <https://github.com/Sandia-OpenSHMEM/SOS>`_
15+
are supported at the moment. Generally speaking, ``shmem4py`` will be installed using
16+
the OpenSHMEM implementation's ``oshcc`` wrapper found in the ``$PATH``.
17+
18+
For detailed installation instructions, please refer to the `Installation <https://shmem4py.readthedocs.io/en/latest/installation.html>`_
19+
page in the documentation.
20+
21+
Below, we provide an example of how to install `shmem4py` with OHMPI on Ubuntu and Fedora.
22+
23+
Containers
24+
----------
25+
26+
We encourage users to use Docker/Podman containers or follow the steps executed in the
27+
`Dockerfiles <https://github.com/mpi4py/shmem4py/tree/master/docker>`_. Containers
28+
based on those files are meant to show minimal configurations for building and running
29+
`shmem4py` with different OpenSHMEM implementations. Those images are used in GitHub
30+
Actions CI/CD and we consider them tested configurations.
31+
Currently, we test with OSSS OpenSHMEM, Open MPI OpenSHMEM, OSHMPI and Sandia OpenSHMEM
32+
on the latest releases of Fedora and Ubuntu.
33+
34+
35+
shmem4py with OSHMPI (Ubuntu)
36+
-----------------------------
37+
38+
Install necessary prerequisites including MPICH using the package manager::
39+
40+
sudo apt-get update
41+
sudo apt-get install git build-essential wget automake libtool mpich python3 python3-pip python-is-python3
42+
43+
44+
Define ``$INSTALL_DIR`` to be used in the following steps, such as::
45+
46+
export INSTALL_DIR="/home/$(whoami)/shmem"
47+
48+
49+
Install OSHMPI::
50+
51+
mkdir -p $INSTALL_DIR
52+
cd $INSTALL_DIR
53+
git clone https://github.com/pmodels/oshmpi --recurse-submodules
54+
cd oshmpi
55+
./autogen.sh
56+
./configure CC=/usr/bin/mpicc CXX=/usr/bin/mpicxx --prefix=$INSTALL_DIR/oshmpi/install
57+
make -j
58+
make install
59+
cd ..
60+
61+
62+
Update ``$PATH``. It might also be beneficial to add this line in one's ``.bashrc`` file::
63+
64+
export PATH="${INSTALL_DIR}/oshmpi/install/bin/:${PATH}"
65+
66+
67+
Install ``numpy`` and ``cffi`` modules::
68+
69+
python -m pip install numpy cffi
70+
71+
72+
With all the prerequisites in place, we can install ``shmem4py``::
73+
74+
git clone https://github.com/mpi4py/shmem4py
75+
cd shmem4py
76+
python -m pip install .
77+
78+
79+
Test if everything works as expected::
80+
81+
make test-1
82+
make test-2
83+
84+
85+
shmem4py with OSHMPI (Fedora)
86+
-----------------------------
87+
88+
Install necessary prerequisites including MPICH using the package manager::
89+
90+
sudo dnf update
91+
sudo dnf install git pkg-config make automake gcc gcc-c++ kernel-devel libtool \
92+
lbzip2 hwloc hwloc-devel libevent libevent-devel \
93+
python3 python3-devel python3-pip mpich mpich-devel
94+
95+
Define ``$INSTALL_DIR`` to be used in the following steps, such as::
96+
97+
export INSTALL_DIR="/home/$(whoami)/shmem"
98+
99+
100+
Install OSHMPI::
101+
102+
mkdir -p $INSTALL_DIR
103+
cd $INSTALL_DIR
104+
git clone https://github.com/pmodels/oshmpi --recurse-submodules
105+
cd oshmpi
106+
./autogen.sh
107+
./configure CC=/usr/lib64/mpich/bin/mpicc CXX=/usr/lib64/mpich/bin/mpicxx --prefix=$INSTALL_DIR/oshmpi/install
108+
make -j
109+
make install
110+
cd ..
111+
112+
113+
Update ``$PATH``. It might also be beneficial to add the below line in one's ``.bashrc`` file.
114+
Alternatively, Fedora's ``mpi/mpich-x86_64`` module can be used instead of adding MPICH to the ``$PATH``. Run::
115+
116+
export PATH="${INSTALL_DIR}/oshmpi/install/bin/:/usr/lib64/mpich/bin/:${PATH}"
117+
118+
If ``python`` does not exist or points to a Python 2 interpreter, it might be
119+
necessary to either use ``python3`` instead of ``python`` in the following commands or create a symbolic link::
120+
121+
ln -s /usr/bin/python3 /usr/bin/python
122+
123+
Install ``numpy`` and ``cffi`` modules::
124+
125+
python -m pip install numpy cffi
126+
127+
128+
With all the prerequisites in place, we can install ``shmem4py``::
129+
130+
git clone https://github.com/mpi4py/shmem4py
131+
cd shmem4py
132+
python -m pip install .
133+
134+
135+
Test if everything works as expected::
136+
137+
make test-1
138+
make test-2
139+
140+
Next steps
141+
----------
142+
143+
With the installation complete, you can now proceed to run the `Examples <https://shmem4py.readthedocs.io/en/latest/examples.html>`_
144+
and try to base your code on them.

LICENSE.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Copyright (c) 2022, Lisandro Dalcin.
1+
Copyright (c) 2023, Lisandro Dalcin.
22
All rights reserved.
33

44
Redistribution and use in source and binary forms, with or without

README.md

-10
This file was deleted.

README.rst

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
==============================
2+
shmem4py: OpenSHMEM for Python
3+
==============================
4+
5+
.. image:: https://github.com/mpi4py/shmem4py/actions/workflows/native.yml/badge.svg
6+
:target: https://github.com/mpi4py/shmem4py/actions/workflows/native.yml
7+
.. image:: https://github.com/mpi4py/shmem4py/actions/workflows/containers.yml/badge.svg
8+
:target: https://github.com/mpi4py/shmem4py/actions/workflows/containers.yml
9+
.. image:: https://readthedocs.org/projects/shmem4py/badge/?version=latest
10+
:target: https://shmem4py.readthedocs.io/en/latest/
11+
12+
Overview
13+
--------
14+
15+
This package provides Python bindings for `OpenSHMEM <http://openshmem.org/>`_.
16+
It exposes an API which grounds on the
17+
`OpenSHMEM 1.5 specification <http://openshmem.org/site/sites/default/site_files/OpenSHMEM-1.5.pdf>`_;
18+
however, it also supports legacy 1.4 implementations.
19+
20+
Supported implementations
21+
-------------------------
22+
23+
- `Cray OpenSHMEMX <https://cray-openshmemx.readthedocs.io/>`_
24+
- `Open Source Software Solutions (OSSS) OpenSHMEM <https://github.com/openshmem-org/osss-ucx>`_
25+
- `Open MPI OpenSHMEM <https://www.open-mpi.org/doc/v3.1/man3/OpenSHMEM.3.php>`_
26+
- `OSHMPI <https://pmodels.github.io/oshmpi-www/>`_
27+
- `Sandia OpenSHMEM <https://github.com/Sandia-OpenSHMEM/SOS>`_
28+
29+
Dependencies
30+
------------
31+
32+
- `Python <https://www.python.org/>`_ 3.7 or newer
33+
- A working `OpenSHMEM <http://openshmem.org/>`_ implementation with its dependencies
34+
- Python modules: `CFFI <https://cffi.readthedocs.io/>`_, `NumPy <https://numpy.org/>`_
35+
36+
Documentation
37+
-------------
38+
39+
- Read the Docs: `https://shmem4py.readthedocs.io/ <https://shmem4py.readthedocs.io/>`_
40+
41+
42+
Acknowledgments
43+
---------------
44+
45+
This project was partially supported by the
46+
Extreme Computing Research Center (ECRC),
47+
King Abdullah University of Science and Technology (KAUST).

demo/alltoall.py

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# adapted from http://openshmem.org/site/sites/default/site_files/OpenSHMEM-1.5.pdf (Example 31)
2+
3+
from shmem4py import shmem
4+
5+
mype = shmem.my_pe()
6+
npes = shmem.n_pes()
7+
8+
count = 2
9+
10+
source = shmem.zeros(count*npes, dtype="int32")
11+
dest = shmem.full(count*npes, 9999, dtype="int32")
12+
13+
for pe in range(0, npes):
14+
for i in range(0, count):
15+
source[(pe*count) + i] = mype*npes + pe
16+
17+
print(f"{mype}: source = {source}")
18+
19+
team = shmem.Team(shmem.TEAM_WORLD)
20+
team.sync()
21+
22+
shmem.alltoall(dest, source, 2, team)
23+
24+
print(f"{mype}: dest = {dest}")
25+
26+
# verify results
27+
for pe in range(0, npes):
28+
for i in range(0, count):
29+
if dest[(pe*count) + i] != pe*npes + mype:
30+
print(f"[{mype}] ERROR: dest[{(pe*count) + i}]={dest[(pe*count) + i]}, should be {pe*npes + mype}")
31+
32+
shmem.free(dest)
33+
shmem.free(source)

demo/broadcast.py

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# adapted from http://openshmem.org/site/sites/default/site_files/OpenSHMEM-1.5.pdf (Example 33)
2+
3+
from shmem4py import shmem
4+
5+
mype = shmem.my_pe()
6+
npes = shmem.n_pes()
7+
8+
source = shmem.zeros(npes, dtype="int32")
9+
dest = shmem.full(npes, -999, dtype="int32")
10+
11+
if mype == 0:
12+
for i in range(npes):
13+
source[i] = i + 1
14+
15+
shmem.barrier_all()
16+
17+
shmem.broadcast(dest, source, 0)
18+
19+
print(f"{mype}: {dest}")
20+
21+
shmem.free(source)
22+
shmem.free(dest)

demo/collect.py

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# adapted from https://github.com/openshmem-org/openshmem-examples/blob/master/c/collect64.c
2+
3+
from shmem4py import shmem
4+
5+
npes = shmem.n_pes()
6+
me = shmem.my_pe()
7+
8+
src = shmem.array([11, 12, 13, 14])
9+
dst = shmem.full(npes*(1+npes)//2, -1)
10+
11+
shmem.barrier_all()
12+
13+
shmem.collect(dst, src, me+1)
14+
15+
print(f"AFTER: dst[{me}/{npes}] = {dst}")
16+
17+
shmem.free(src)
18+
shmem.free(dst)

demo/fcollect.py

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# adapted from https://github.com/openshmem-org/openshmem-examples/blob/master/c/fcollect.c
2+
3+
from shmem4py import shmem
4+
5+
npes = shmem.n_pes()
6+
me = shmem.my_pe()
7+
8+
dst = shmem.full(npes, 10101, dtype="int32")
9+
src = shmem.zeros(1, dtype="int32")
10+
src[0] = me + 100
11+
12+
print(f"BEFORE: dst[{me}/{npes}] = {dst}")
13+
14+
shmem.barrier_all()
15+
shmem.fcollect(dst, src)
16+
shmem.barrier_all()
17+
18+
print(f"AFTER: dst[{me}/{npes}] = {dst}")
19+
20+
shmem.free(dst)
21+
shmem.free(src)

demo/lock.py

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# adapted from http://openshmem.org/site/sites/default/site_files/OpenSHMEM-1.5.pdf (Example 45)
2+
3+
from shmem4py import shmem
4+
5+
lock = shmem.new_lock()
6+
mype = shmem.my_pe()
7+
8+
count = shmem.array([0], dtype='i')
9+
val = shmem.array([0], dtype='i')
10+
11+
shmem.set_lock(lock)
12+
shmem.get(val, count, 0)
13+
print(f"{mype}: count is {val[0]}")
14+
val[0] += 1
15+
shmem.put(count, val, 0)
16+
shmem.clear_lock(lock)
17+
18+
shmem.del_lock(lock)
19+
shmem.free(count)
20+
shmem.free(val)

demo/lock_oo.py

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# adapted from http://openshmem.org/site/sites/default/site_files/OpenSHMEM-1.5.pdf (Example 45)
2+
3+
from shmem4py import shmem
4+
5+
lock = shmem.Lock()
6+
mype = shmem.my_pe()
7+
8+
count = shmem.array([0], dtype='i')
9+
val = shmem.array([0], dtype='i')
10+
11+
lock.acquire()
12+
shmem.get(val, count, 0)
13+
print(f"{mype}: count is {val[0]}")
14+
val[0] += 1
15+
shmem.put(count, val, 0)
16+
lock.release()
17+
18+
lock.destroy()
19+
shmem.free(count)
20+
shmem.free(val)

0 commit comments

Comments
 (0)