Skip to content

Commit 2e1e486

Browse files
authored
Metapackages (#859)
Initial support for metapackages: OpenMP, MPI, stdlib, fortran-lang/minpack
2 parents 757e003 + 24bdea2 commit 2e1e486

File tree

36 files changed

+2657
-70
lines changed

36 files changed

+2657
-70
lines changed

.github/workflows/meta.yml

Lines changed: 310 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,310 @@
1+
name: metapackage-tests
2+
3+
on:
4+
push:
5+
paths:
6+
- 'src/*meta*.f90' # On push, only launch job if something has changed in the metapackages
7+
- 'src/fpm/*meta*.f90'
8+
- 'src/fpm/manifest/*meta*.f90'
9+
- 'src/ci/meta_tests.sh'
10+
- 'src/.github/workflows/meta.yml'
11+
pull_request:
12+
release:
13+
types: [published]
14+
15+
env:
16+
CI: "ON" # We can detect this in the build system and other vendors implement it
17+
HOMEBREW_NO_ANALYTICS: "ON" # Make Homebrew installation a little quicker
18+
HOMEBREW_NO_AUTO_UPDATE: "ON"
19+
HOMEBREW_NO_BOTTLE_SOURCE_FALLBACK: "ON"
20+
HOMEBREW_NO_GITHUB_API: "ON"
21+
HOMEBREW_NO_INSTALL_CLEANUP: "ON"
22+
23+
jobs:
24+
25+
build:
26+
runs-on: ${{ matrix.os }}
27+
strategy:
28+
fail-fast: false
29+
matrix:
30+
include:
31+
- os: ubuntu-latest
32+
mpi: intel
33+
- os: ubuntu-latest
34+
mpi: openmpi
35+
- os: ubuntu-latest
36+
mpi: mpich
37+
- os: windows-latest
38+
mpi: msmpi
39+
- os: macos-latest
40+
mpi: openmpi
41+
- os: macos-latest
42+
mpi: mpich
43+
44+
45+
steps:
46+
- name: Checkout code
47+
uses: actions/checkout@v1
48+
49+
- name: (Ubuntu) setup gcc version
50+
if: contains(matrix.os,'ubuntu')
51+
run: |
52+
echo "GCC_V=10" >> $GITHUB_ENV
53+
54+
- name: (macOS) setup gcc version
55+
if: contains(matrix.os,'macos')
56+
run: |
57+
echo "GCC_V=13" >> $GITHUB_ENV
58+
59+
- name: (Windows) Install MSYS2
60+
uses: msys2/setup-msys2@v2
61+
if: contains(matrix.os,'windows') && contains(matrix.mpi,'msmpi')
62+
with:
63+
msystem: MINGW64
64+
update: true
65+
install: >-
66+
git
67+
base-devel
68+
wget
69+
unzip
70+
curl
71+
gcc-fortran
72+
73+
- name: (Windows) Setup VS Build environment
74+
if: contains(matrix.os,'windows') && contains(matrix.mpi,'intel')
75+
uses: seanmiddleditch/gha-setup-vsdevenv@master
76+
77+
- name: (Windows) Retrieve Intel toolchain
78+
if: contains(matrix.os,'windows') && contains(matrix.mpi,'intel')
79+
shell: pwsh
80+
working-directory: C:\TEMP
81+
run: |
82+
curl.exe --output webimage.exe --url https://registrationcenter-download.intel.com/akdlm/irc_nas/19085/w_HPCKit_p_2023.0.0.25931_offline.exe --retry 5 --retry-delay 5
83+
Start-Process -FilePath "webimage.exe" -ArgumentList "-s -x -f oneAPI --log extract.log" -Wait
84+
Remove-Item "webimage.exe" -Force
85+
Start-Process -FilePath "oneAPI\bootstrapper.exe" -ArgumentList "-s --action install --eula=accept --components=""intel.oneapi.win.cpp-compiler:intel.oneapi.win.ifort-compiler:intel.oneapi.win.mpi.devel"" -p=NEED_VS2017_INTEGRATION=0 -p=NEED_VS2019_INTEGRATION=0 -p=NEED_VS2022_INTEGRATION=0 --log-dir=." -Wait
86+
Remove-Item "oneAPI" -Force -Recurse
87+
88+
- name: (Ubuntu) Install gfortran
89+
if: contains(matrix.os,'ubuntu') && (!contains(matrix.mpi,'intel'))
90+
run: |
91+
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-${GCC_V} 100 \
92+
--slave /usr/bin/gfortran gfortran /usr/bin/gfortran-${GCC_V} \
93+
--slave /usr/bin/gcov gcov /usr/bin/gcov-${GCC_V}
94+
95+
- name: (Ubuntu) Install OpenMPI
96+
if: contains(matrix.os,'ubuntu') && contains(matrix.mpi,'openmpi')
97+
run: |
98+
sudo apt install -y -q openmpi-bin libopenmpi-dev
99+
100+
- name: (Ubuntu) Install MPICH
101+
if: contains(matrix.os,'ubuntu') && contains(matrix.mpi,'mpich')
102+
run: |
103+
sudo apt install -y -q mpich
104+
105+
- name: (Ubuntu) Retrieve Intel toolchain
106+
if: contains(matrix.os,'ubuntu') && contains(matrix.mpi,'intel')
107+
timeout-minutes: 1
108+
run: |
109+
wget https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS-2023.PUB
110+
sudo apt-key add GPG-PUB-KEY-INTEL-SW-PRODUCTS-2023.PUB
111+
rm GPG-PUB-KEY-INTEL-SW-PRODUCTS-2023.PUB
112+
echo "deb https://apt.repos.intel.com/oneapi all main" | sudo tee /etc/apt/sources.list.d/oneAPI.list
113+
sudo apt-get update
114+
115+
- name: (Ubuntu) Install Intel oneAPI
116+
if: contains(matrix.os,'ubuntu') && contains(matrix.mpi,'intel')
117+
timeout-minutes: 5
118+
run: sudo apt-get install intel-oneapi-compiler-fortran intel-oneapi-compiler-dpcpp-cpp-and-cpp-classic intel-oneapi-mpi intel-oneapi-mpi-devel intel-oneapi-mkl ninja-build
119+
120+
- name: (Ubuntu) Setup Intel oneAPI environment
121+
if: contains(matrix.os,'ubuntu') && contains(matrix.mpi,'intel')
122+
run: |
123+
source /opt/intel/oneapi/setvars.sh
124+
printenv >> $GITHUB_ENV
125+
126+
- name: (Windows) Put MSYS2_MinGW64 on PATH
127+
if: contains(matrix.os,'windows') && (!contains(matrix.mpi,'intel'))
128+
# there is not yet an environment variable for this path from msys2/setup-msys2
129+
run: echo "${{ runner.temp }}/msys64/mingw64/bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
130+
131+
- name: (Windows) download MS-MPI setup (SDK is from MSYS2)
132+
if: contains(matrix.os,'windows') && contains(matrix.mpi,'msmpi')
133+
# run: curl -L -O https://github.com/microsoft/Microsoft-MPI/releases/download/v10.1.2/msmpisetup.exe 10.1.1
134+
run: curl -L -O https://download.microsoft.com/download/a/5/2/a5207ca5-1203-491a-8fb8-906fd68ae623/msmpisetup.exe # 10.1.2
135+
136+
- name: (Windows) Install mpiexec.exe (-force needed to bypass GUI on headless)
137+
if: contains(matrix.os,'windows') && contains(matrix.mpi,'msmpi')
138+
run: .\msmpisetup.exe -unattend -force
139+
140+
- name: (Windows) test that mpiexec.exe exists
141+
if: contains(matrix.os,'windows') && contains(matrix.mpi,'msmpi')
142+
# can't use MSMPI_BIN as Actions doesn't update PATH from msmpisetup.exe
143+
run: Test-Path "C:\Program Files\Microsoft MPI\Bin\mpiexec.exe" -PathType leaf
144+
145+
- name: (Windows) test that OneAPI is installed
146+
if: contains(matrix.os,'windows') && contains(matrix.mpi,'intel')
147+
run: |
148+
Test-Path -Path "C:\Program Files (x86)\Intel\oneAPI\setvars.bat" -PathType leaf
149+
Test-Path -Path "C:\Program Files (x86)\Intel\oneAPI\compiler\latest\env\vars.bat" -PathType leaf
150+
151+
- name: (Windows) put MSMPI_BIN on PATH (where mpiexec is)
152+
if: contains(matrix.os,'windows') && contains(matrix.mpi,'msmpi')
153+
run: |
154+
echo "C:\Program Files\Microsoft MPI\Bin\" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
155+
echo "MSMPI_BIN=C:\Program Files\Microsoft MPI\Bin\" | Out-File -FilePath $env:GITHUB_ENV -Append
156+
157+
- name: (Windows) load OneAPI environment variables
158+
if: contains(matrix.os,'windows') && contains(matrix.mpi,'intel')
159+
shell: cmd
160+
run: |
161+
"C:\Program Files (x86)\Intel\oneAPI\setvars.bat"
162+
"C:\Program Files (x86)\Intel\oneAPI\compiler\latest\env\vars.bat"
163+
164+
- name: (Windows) Install MSYS2 msmpi package
165+
if: contains(matrix.os,'windows') && contains(matrix.mpi,'msmpi')
166+
shell: msys2 {0}
167+
run: pacman --noconfirm -S mingw-w64-x86_64-msmpi
168+
169+
- name: (macOS) Set up Homebrew
170+
if: contains(matrix.os,'macos')
171+
id: set-up-homebrew
172+
uses: Homebrew/actions/setup-homebrew@master
173+
174+
- name: (macOS) Install Homebrew gfortran
175+
if: contains(matrix.os, 'macos')
176+
run: |
177+
# Only install gcc if not already available
178+
which gfortran-${{ env.GCC_V }} || brew install gcc@${{ env.GCC_V }}
179+
which gfortran-${{ env.GCC_V }}
180+
which gfortran || ln -s /usr/local/bin/gfortran-${{ env.GCC_V }} /usr/local/bin/gfortran
181+
# Backport gfortran shared libraries to version 10 folder. This is necessary because all macOS releases of fpm
182+
# have these paths hardcoded in the executable (no PIC?). Current bootstrap version 0.8.0 has gcc-10
183+
mkdir /usr/local/opt/gcc@10
184+
mkdir /usr/local/opt/gcc@10/lib
185+
mkdir /usr/local/opt/gcc@10/lib/gcc
186+
mkdir /usr/local/opt/gcc@10/lib/gcc/10
187+
mkdir /usr/local/lib/gcc/10
188+
ln -fs /usr/local/opt/gcc@${{ env.GCC_V }}/lib/gcc/${{ env.GCC_V }}/libquadmath.0.dylib /usr/local/opt/gcc@10/lib/gcc/10/libquadmath.0.dylib
189+
ln -fs /usr/local/opt/gcc@${{ env.GCC_V }}/lib/gcc/${{ env.GCC_V }}/libgfortran.5.dylib /usr/local/opt/gcc@10/lib/gcc/10/libgfortran.5.dylib
190+
# Newer gcc versions use libgcc_s.1.1.dylib
191+
ln -fs /usr/local/lib/gcc/${{ env.GCC_V }}/libgcc_s.1.dylib /usr/local/lib/gcc/10/libgcc_s.1.dylib || ln -fs /usr/local/lib/gcc/${{ env.GCC_V }}/libgcc_s.1.1.dylib /usr/local/lib/gcc/10/libgcc_s.1.dylib
192+
193+
- name: (macOS) Install homebrew MPICH
194+
if: contains(matrix.mpi,'mpich') && contains(matrix.os,'macos')
195+
run: |
196+
brew install mpich
197+
198+
- name: (macOS) Install homebrew OpenMPI
199+
if: contains(matrix.mpi,'openmpi') && contains(matrix.os,'macos')
200+
run: |
201+
brew install --cc=gcc-${{ env.GCC_V }} openmpi
202+
203+
# Phase 1: Bootstrap fpm with existing version
204+
- name: Install fpm
205+
uses: fortran-lang/setup-fpm@v3
206+
with:
207+
fpm-version: 'v0.8.0'
208+
209+
- name: Remove fpm from path
210+
shell: bash
211+
run: |
212+
mv $(which fpm) fpm-bootstrap${{ matrix.exe }}
213+
echo "BOOTSTRAP=$PWD/fpm-bootstrap" >> $GITHUB_ENV
214+
215+
- name: Use Intel compiler for the metapackage tests
216+
if: contains(matrix.mpi,'intel')
217+
shell: bash
218+
run: |
219+
echo "FPM_FC=ifort" >> $GITHUB_ENV
220+
echo "FPM_CC=icc" >> $GITHUB_ENV
221+
echo "FPM_CXX=icpc" >> $GITHUB_ENV
222+
223+
- name: (macOS) Use gcc/g++ instead of Clang for C/C++
224+
if: contains(matrix.os,'macOS')
225+
shell: bash
226+
run: |
227+
echo "FPM_FC=gfortran-${{ env.GCC_V }}" >> $GITHUB_ENV
228+
echo "FPM_CC=gcc-${{ env.GCC_V }}" >> $GITHUB_ENV
229+
echo "FPM_CXX=g++-${{ env.GCC_V }}" >> $GITHUB_ENV
230+
231+
- name: Build Fortran fpm (bootstrap)
232+
shell: bash
233+
run: |
234+
${{ env.BOOTSTRAP }} build
235+
236+
- name: Run Fortran fpm (bootstrap)
237+
shell: bash
238+
run: |
239+
${{ env.BOOTSTRAP }} run
240+
${{ env.BOOTSTRAP }} run -- --version
241+
${{ env.BOOTSTRAP }} run -- --help
242+
243+
- name: Test Fortran fpm (bootstrap)
244+
if: (!contains(matrix.mpi,'intel'))
245+
shell: bash
246+
run: |
247+
${{ env.BOOTSTRAP }} test
248+
249+
- name: Install Fortran fpm (bootstrap)
250+
shell: bash
251+
run: |
252+
${{ env.BOOTSTRAP }} install
253+
254+
# Phase 2: Bootstrap fpm with itself
255+
- name: Replace bootstrapping version
256+
shell: bash
257+
run: |
258+
${{ env.BOOTSTRAP }} run --runner cp -- fpm-debug${{ matrix.exe }}
259+
rm -v ${{ env.BOOTSTRAP }}
260+
echo "FPM=$PWD/fpm-debug" >> $GITHUB_ENV
261+
262+
- name: Get version (normal)
263+
if: github.event_name != 'release'
264+
shell: bash
265+
run: |
266+
VERSION=$(git rev-parse --short HEAD)
267+
echo "VERSION=$VERSION" >> $GITHUB_ENV
268+
269+
- name: Get version (release)
270+
if: github.event_name == 'release'
271+
shell: bash
272+
run: |
273+
VERSION=$(echo ${{ github.ref }} | cut -dv -f2)
274+
echo "VERSION=$VERSION" >> $GITHUB_ENV
275+
FPM_VERSION=$(${{ env.FPM }} --version | grep -o '${{ env.REGEX }}')
276+
[ "$VERSION" = "$FPM_VERSION" ]
277+
env:
278+
REGEX: '[0-9]\{1,4\}\.[0-9]\{1,4\}\.[0-9]\{1,4\}'
279+
280+
- name: Build Fortran fpm
281+
shell: bash
282+
run: |
283+
${{ env.FPM }} build ${{ matrix.release-flags }}
284+
285+
- name: Run Fortran fpm
286+
shell: bash
287+
run: |
288+
${{ env.FPM }} run ${{ matrix.release-flags }}
289+
${{ env.FPM }} run ${{ matrix.release-flags }} -- --version
290+
${{ env.FPM }} run ${{ matrix.release-flags }} -- --help
291+
292+
- name: Install Fortran fpm
293+
shell: bash
294+
run: |
295+
${{ env.FPM }} install ${{ matrix.release-flags }}
296+
297+
- name: Package release version
298+
shell: bash
299+
run: |
300+
${{ env.FPM }} run ${{ matrix.release-flags }} --runner cp -- ${{ env.EXE }}
301+
rm -v ${{ env.FPM }}
302+
echo "FPM_RELEASE=${{ env.EXE }}" >> $GITHUB_ENV
303+
env:
304+
EXE: fpm-${{ env.VERSION }}-${{ matrix.os-arch }}${{ matrix.exe }}
305+
306+
- name: Run metapackage tests using the release version
307+
shell: bash
308+
run: |
309+
ci/meta_tests.sh "$PWD/${{ env.FPM_RELEASE }}"
310+

ci/meta_tests.sh

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#!/usr/bin/env bash
2+
set -ex
3+
4+
# ***********************
5+
# This script tests all example packages using any metapackage/system dependencies
6+
# ***********************
7+
8+
cd "$(dirname $0)/.."
9+
10+
if [ "$1" ]; then
11+
fpm="$1"
12+
else
13+
fpm=fpm
14+
fi
15+
16+
# Build example packages
17+
pushd example_packages/
18+
rm -rf ./*/build
19+
20+
pushd metapackage_openmp
21+
"$fpm" build --verbose
22+
"$fpm" run --verbose
23+
popd
24+
25+
pushd metapackage_stdlib
26+
"$fpm" build --verbose
27+
"$fpm" run --verbose
28+
popd
29+
30+
pushd metapackage_minpack
31+
"$fpm" build --verbose
32+
"$fpm" run --verbose
33+
popd
34+
35+
pushd metapackage_mpi
36+
"$fpm" build --verbose
37+
"$fpm" run --verbose
38+
popd
39+
40+
pushd metapackage_mpi_c
41+
"$fpm" build --verbose
42+
"$fpm" run --verbose
43+
popd
44+
45+
# Cleanup
46+
rm -rf ./*/build
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
program main
2+
use metapackage_minpack, only: simple_test
3+
implicit none
4+
logical :: success
5+
call simple_test(success)
6+
stop merge(0,1,success)
7+
end program main
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
name = "metapackage_minpack"
2+
dependencies.minpack="*"
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
module metapackage_minpack
2+
use minpack_module, only: wp
3+
use iso_fortran_env, only: real64
4+
implicit none
5+
private
6+
7+
public :: simple_test
8+
contains
9+
subroutine simple_test(success)
10+
logical, intent(out) :: success
11+
! Success! can read minpack module
12+
success = wp == real64
13+
end subroutine simple_test
14+
end module metapackage_minpack
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# test_mpi
2+
This test program prints the running thread ID using MPI.
3+
PLEASE NOTE:
4+
- Test app uses 'mpif.h' and not 'use mpi' or 'use mpi_f08' because the latter are compiler-dependent,
5+
and the MPI implementation on the local machine may not offer an implementation for them with the same
6+
compiler that fpm is using.
7+
- Using mpif.h will be the most backward compatible and platform agnostic

0 commit comments

Comments
 (0)