Skip to content

Commit 4f7566a

Browse files
committed
Support for OFI and UCX
* MPICH: Configure --with-device=ch4:ofi,ucx * Open MPI: Configure --with-ofi --with-ucx * Reproducible builds * Strip binaries to reduce size * Remove unneeded binaries * Package various licenses
1 parent 20ec177 commit 4f7566a

File tree

13 files changed

+714
-127
lines changed

13 files changed

+714
-127
lines changed

.github/workflows/cd-wheel.yml

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ jobs:
7676
shell: python
7777
name: 'setup build matrix'
7878
run: |
79+
# setup build matrix # "
7980
keys = ("os", "arch", "runner")
8081
rows = [
8182
("Linux", "aarch64", "ubuntu-22.04"),
@@ -93,6 +94,7 @@ jobs:
9394
import os, json
9495
with open(os.getenv("GITHUB_OUTPUT"), "w") as out:
9596
print(f"matrix={json.dumps(matrix)}", file=out)
97+
# "
9698
9799
build:
98100
needs: setup
@@ -113,16 +115,21 @@ jobs:
113115
if: ${{ runner.os == 'macOS' }}
114116
name: setup-macOS
115117
run: |
118+
# set macOS deployment target
119+
case $(uname -m) in
120+
arm64) echo MACOSX_DEPLOYMENT_TARGET=11.0 >> $GITHUB_ENV ;;
121+
x86_64) echo MACOSX_DEPLOYMENT_TARGET=10.15 >> $GITHUB_ENV ;;
122+
esac
116123
# create gfortran symlink
117124
cd $(brew --prefix)/bin
118125
gfortran=$(ls gfortran-* | sort | head -n 1)
119126
sudo ln -s $gfortran gfortran
127+
# unlink libevent
128+
brew unlink libevent || true
120129
# install autotools
121130
brew install autoconf
122131
brew install automake
123132
brew install libtool
124-
# unlink libevent
125-
brew unlink libevent || true
126133
# install uv
127134
brew install uv
128135
@@ -142,9 +149,14 @@ jobs:
142149

143150
- id: source-date-epoch
144151
run: |
145-
SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)
152+
read -r SOURCE_DATE_EPOCH < source-date-epoch || true
153+
SOURCE_DATE_EPOCH=${SOURCE_DATE_EPOCH:-$(git log -1 --pretty=%ct)}
146154
echo SOURCE_DATE_EPOCH=$SOURCE_DATE_EPOCH >> $GITHUB_ENV
147-
echo $(git log -1 --pretty=%ci) [timestamp=$SOURCE_DATE_EPOCH]
155+
test $(uname) = Darwin && (echo ZERO_AR_DATE=1 >> $GITHUB_ENV)
156+
echo [SOURCE_DATE_EPOCH=$SOURCE_DATE_EPOCH] $(
157+
date -u -d @$SOURCE_DATE_EPOCH 2>/dev/null ||
158+
date -u -r $SOURCE_DATE_EPOCH 2>/dev/null )
159+
working-directory: package/source
148160

149161
- id: build
150162
uses: pypa/[email protected]
@@ -190,7 +202,9 @@ jobs:
190202
- id: upload
191203
uses: actions/upload-artifact@v4
192204
with:
193-
name: wheel-${{ inputs.mpiname }}-${{ matrix.os }}-${{ matrix.arch }}
205+
name: "wheel-${{ inputs.mpiname }}-\
206+
${{ inputs.version || 'latest' }}-\
207+
${{ matrix.os }}-${{ matrix.arch }}"
194208
path: wheelhouse/*.whl
195209

196210
- id: check

.github/workflows/ci.yml

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,32 @@ on: # yamllint disable-line rule:truthy
1111

1212
jobs:
1313

14-
mpich:
14+
mpich-42:
1515
uses: ./.github/workflows/cd-wheel.yml
1616
with:
1717
mpiname: mpich
18+
version:
1819

19-
openmpi:
20+
mpich-41:
21+
uses: ./.github/workflows/cd-wheel.yml
22+
with:
23+
mpiname: mpich
24+
version: 4.1.3
25+
26+
mpich-34:
27+
uses: ./.github/workflows/cd-wheel.yml
28+
with:
29+
mpiname: mpich
30+
version: 3.4.3
31+
32+
openmpi-50:
33+
uses: ./.github/workflows/cd-wheel.yml
34+
with:
35+
mpiname: openmpi
36+
version:
37+
38+
openmpi-41:
2039
uses: ./.github/workflows/cd-wheel.yml
2140
with:
2241
mpiname: openmpi
42+
version: 4.1.6

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@
55
/venv/
66
*.egg-info/
77
*.tar.gz
8+
*.tar.bz2
89
*~

Makefile

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@ lint:
1010
yamllint .github/
1111

1212
clean:
13+
$(RM) -r package/METADATA
14+
$(RM) -r package/LICENSE*
1315
$(RM) -r package/build
14-
$(RM) -r package/LICENSE
15-
$(RM) -r package/install
1616
$(RM) -r package/source
1717
$(RM) -r package/workdir
18+
$(RM) -r package/install
1819
$(RM) -r package/*.egg-info
1920
$(RM) -r .*_cache

bootstrap.sh

Lines changed: 145 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,47 +8,180 @@ case "$mpiname" in
88
esac
99
version=${VERSION:-$version}
1010

11+
ucxversion=1.17.0
12+
ofiversion=1.22.0
13+
ucxversion=${UCXVERSION:-$ucxversion}
14+
ofiversion=${OFIVERSION:-$ofiversion}
15+
1116
PROJECT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
1217
PACKAGE=$PROJECT/package
1318
SOURCE=$PACKAGE/source
1419

1520
if test "$mpiname" = "mpich"; then
1621
urlbase="https://www.mpich.org/static/downloads/$version"
1722
tarball="$mpiname-$version.tar.gz"
18-
license=COPYRIGHT
1923
fi
20-
2124
if test "$mpiname" = "openmpi"; then
2225
urlbase=https://download.open-mpi.org/release/open-mpi/v${version%.*}
2326
tarball="$mpiname-$version.tar.gz"
24-
license=LICENSE
2527
fi
26-
2728
if test ! -d "$SOURCE"; then
2829
if test ! -f "$tarball"; then
2930
echo downloading "$urlbase"/"$tarball"...
30-
curl -fsO "$urlbase"/"$tarball"
31+
curl -fsSLO "$urlbase"/"$tarball"
3132
else
3233
echo reusing "$tarball"...
3334
fi
34-
echo extracting "$tarball" to "$SOURCE"...
35+
echo extracting "$tarball"...
3536
tar xf "$tarball"
3637
mv "$mpiname-$version" "$SOURCE"
3738
patch="$PROJECT/patches/$mpiname-$version"
3839
if test -f "$patch"; then
3940
patch -p1 -i "$patch" -d "$SOURCE"
4041
fi
41-
if test "$mpiname-$(uname)" = "openmpi-Darwin"; then
42-
if test -d "$SOURCE"/3rd-party; then
43-
cd "$SOURCE"/3rd-party
44-
tar xf libevent-*.tar.gz && cd libevent-*
42+
if test "$mpiname" = "mpich"; then
43+
if test "${version}" \< "4.2.0"; then
44+
disable_doc='s/^\(install-data-local:\s\+\)\$/\1#\$/'
45+
sed -i.orig "$disable_doc" "$SOURCE"/Makefile.in
46+
fi
47+
fi
48+
if test "$mpiname" = "openmpi"; then
49+
for deptarball in "$SOURCE"/3rd-party/*.tar.*; do
50+
test -f "$deptarball" || continue
51+
echo extracting "$(basename "$deptarball")"
52+
tar xf "$deptarball" -C "$(dirname "$deptarball")"
53+
done
54+
makefiles=(
55+
"$SOURCE"/3rd-party/openpmix/src/util/keyval/Makefile.in
56+
"$SOURCE"/3rd-party/prrte/src/mca/rmaps/rank_file/Makefile.in
57+
"$SOURCE"/3rd-party/prrte/src/util/hostfile/Makefile.in
58+
)
59+
for makefile in "${makefiles[@]}"; do
60+
test -f "$makefile" || continue
61+
echo "PMIX_CFLAGS_BEFORE_PICKY = @CFLAGS@" >> "$makefile"
62+
echo "PRTE_CFLAGS_BEFORE_PICKY = @CFLAGS@" >> "$makefile"
63+
done
64+
fi
65+
if test "$mpiname" = "openmpi" && test "${version}" \< "5.0.5"; then
66+
if test "$(uname)" = "Darwin" && test -d "$SOURCE"/3rd-party; then
67+
cd "$SOURCE"/3rd-party/libevent-*
4568
echo running autogen.sh on "$(basename "$(pwd)")"
4669
./autogen.sh
4770
cd "$PROJECT"
4871
fi
4972
fi
73+
echo writing package metadata ...
74+
echo "Name: $mpiname" > "$PACKAGE/METADATA"
75+
echo "Version: $version" >> "$PACKAGE/METADATA"
5076
else
5177
echo reusing directory "$SOURCE"...
78+
check() { test "$(awk "/$1/"'{print $2}' "$PACKAGE/METADATA")" = "$2"; }
79+
check Name "$mpiname" || (echo not "$mpiname-$version"!!! && exit 1)
80+
check Version "$version" || (echo not "$mpiname-$version"!!! && exit 1)
81+
fi
82+
83+
if test "$(uname)" = "Linux"; then
84+
case "$mpiname" in
85+
mpich) MODSOURCE="$SOURCE"/modules ;;
86+
openmpi) MODSOURCE="$SOURCE"/3rd-party ;;
87+
esac
88+
ofigithub="https://github.com/ofiwg/libfabric"
89+
ofiurlbase="$ofigithub/releases/download/v$ofiversion"
90+
ofitarball="libfabric-$ofiversion.tar.bz2"
91+
ofidestdir="$MODSOURCE"/"${ofitarball%%.tar.*}"
92+
if test ! -d "$ofidestdir"; then
93+
if test ! -f "$ofitarball"; then
94+
echo downloading "$ofiurlbase"/"$ofitarball"...
95+
curl -fsSLO "$ofiurlbase"/"$ofitarball"
96+
else
97+
echo reusing "$ofitarball"...
98+
fi
99+
echo extracting "$ofitarball"...
100+
tar xf "$ofitarball"
101+
mkdir -p "$(dirname "$ofidestdir")"
102+
mv "$(basename "$ofidestdir")" "$ofidestdir"
103+
else
104+
echo reusing directory "$ofidestdir"...
105+
fi
106+
ucxgithub="https://github.com/openucx/ucx"
107+
ucxurlbase="$ucxgithub/releases/download/v$ucxversion"
108+
ucxtarball="ucx-$ucxversion.tar.gz"
109+
ucxdestdir="$MODSOURCE"/"${ucxtarball%%.tar.*}"
110+
if test ! -d "$ucxdestdir"; then
111+
if test ! -f "$ucxtarball"; then
112+
echo downloading "$ucxurlbase"/"$ucxtarball"...
113+
curl -fsSLO "$ucxurlbase"/"$ucxtarball"
114+
else
115+
echo reusing "$ucxtarball"...
116+
fi
117+
echo extracting "$ucxtarball"...
118+
tar xf "$ucxtarball"
119+
mkdir -p "$(dirname "$ucxdestdir")"
120+
mv "$(basename "$ucxdestdir")" "$ucxdestdir"
121+
if test "${ucxversion}" \< "1.17.1"; then
122+
cmd='s/\(#include <limits.h>\)/\1\n#include <math.h>/'
123+
sed -i.orig "$cmd" "$ucxdestdir/src/ucs/time/time.h"
124+
fi
125+
else
126+
echo reusing directory "$ucxdestdir"...
127+
fi
128+
fi
129+
130+
if test "$mpiname" = "mpich"; then
131+
mpidate=$(sed -nE "s/MPICH_RELEASE_DATE=\"(.*)\"/\1/p" "$SOURCE/configure")
132+
fi
133+
if test "$mpiname" = "openmpi"; then
134+
mpidate=$(sed -nE "s/date=\"(.*)\"/\1/p" "$SOURCE/VERSION")
135+
fi
136+
if test -n "${mpidate+x}"; then
137+
case "$(uname)" in
138+
Linux)
139+
timestamp=$(date -d "$mpidate" "+%s")
140+
;;
141+
Darwin)
142+
datefmt="%b %d, %Y %T%z"
143+
if test "$mpiname" = "mpich"; then
144+
mpidate=$(awk '{$3=$3",";print $2,$3,$NF}' <<< "$mpidate")
145+
fi
146+
timestamp=$(date -j -f "$datefmt" "$mpidate 12:00:00+0000" "+%s")
147+
;;
148+
esac
149+
echo writing source-date-epoch ...
150+
echo "$timestamp" > "$SOURCE/source-date-epoch"
151+
fi
152+
153+
if test "$mpiname" = "mpich"; then
154+
mpilicense="$SOURCE"/COPYRIGHT
155+
otherlicenses=(
156+
"$SOURCE"/modules/hwloc/COPYING
157+
"$SOURCE"/modules/json-c/COPYING
158+
"$SOURCE"/modules/yaksa/COPYRIGHT
159+
)
160+
fi
161+
if test "$mpiname" = "openmpi"; then
162+
mpilicense="$SOURCE"/LICENSE
163+
otherlicenses=(
164+
"$SOURCE"/3rd-party/hwloc-*/COPYING
165+
"$SOURCE"/3rd-party/libevent-*/LICENSE
166+
"$SOURCE"/3rd-party/openpmix/LICENSE
167+
"$SOURCE"/3rd-party/prrte/LICENSE
168+
"$SOURCE"/3rd-party/treematch/COPYING
169+
)
170+
fi
171+
echo copying MPI license file...
172+
cp "$mpilicense" "$PACKAGE/LICENSE"
173+
if test -n "${ofidestdir+x}"; then
174+
echo copying OFI license file...
175+
cp "$ofidestdir/COPYING" "$PACKAGE/LICENSE.ofi"
176+
fi
177+
if test -n "${ucxdestdir+x}"; then
178+
echo copying UCX license file...
179+
cp "$ucxdestdir/LICENSE" "$PACKAGE/LICENSE.ucx"
52180
fi
53-
echo copying license file...
54-
cp "$SOURCE"/"$license" "$PACKAGE/LICENSE"
181+
for license in "${otherlicenses[@]}"; do
182+
test -f "$license" || continue
183+
module=$(basename "$(dirname "$license")")
184+
module="${module%%-[0-9]*}"
185+
echo copying "$module" license file...
186+
cp "$license" "$PACKAGE/LICENSE.$module"
187+
done

build-wheel.sh

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ WORKDIR=package/workdir
66
DESTDIR=package/install
77
ARCHLIST=${ARCHLIST:-$(uname -m)}
88

9-
export CIBW_BUILD_FRONTEND='build'
9+
read -r SOURCE_DATE_EPOCH < "$SOURCE"/source-date-epoch
10+
export SOURCE_DATE_EPOCH=$SOURCE_DATE_EPOCH
11+
12+
export CIBW_BUILD_FRONTEND='build[uv]'
1013
export CIBW_BUILD='cp313-*'
1114
export CIBW_SKIP='*musllinux*'
1215
export CIBW_ARCHS=$ARCHLIST
@@ -19,19 +22,20 @@ if test "$(uname)" = Linux; then
1922
containerengine=$(basename "$(command -v podman || command -v docker)")
2023
export CIBW_CONTAINER_ENGINE=$containerengine
2124
export SOURCE="/project/$SOURCE"
22-
export WORKDIR="/host/$PWD/$WORKDIR"
23-
export DESTDIR="/host/$PWD/$DESTDIR"
25+
export WORKDIR="/host$PWD/$WORKDIR"
26+
export DESTDIR="/host$PWD/$DESTDIR"
2427
platform=linux
2528
fi
2629
if test "$(uname)" = Darwin; then
30+
export CIBW_BUILD_FRONTEND='build'
31+
export CIBW_BUILD='pp310-*'
2732
export SOURCE="$PWD/$SOURCE"
2833
export WORKDIR="$PWD/$WORKDIR"
2934
export DESTDIR="$PWD/$DESTDIR"
30-
export CIBW_BUILD='pp310-*'
3135
platform=macos
3236
fi
3337

34-
python -m pipx run \
38+
pipx run \
3539
cibuildwheel \
3640
--platform "$platform" \
3741
--output-dir "${1:-dist}" \

0 commit comments

Comments
 (0)