Skip to content

Example 5: fix parallel .mod race by separate Fortran module dirs per target #755

Example 5: fix parallel .mod race by separate Fortran module dirs per target

Example 5: fix parallel .mod race by separate Fortran module dirs per target #755

# Workflow to run the FTorch test suite using jobs for Intel and GNU compilers
# Any changes need to be reflected in both GNU and Intel jobs
name: Test suite (Ubuntu CPU)
# Controls when the workflow will run
on:
# Triggers the workflow on pushes to the "main" branch, i.e., PR merges
push:
branches: [ "main" ]
# Triggers the workflow on pushes to open pull requests with code changes
pull_request:
paths:
- '.github/workflows/test_suite_ubuntu.yml'
- '**.c'
- '**.cpp'
- '**.fypp'
- '**.f90'
- '**.F90'
- '**.pf'
- '**.py'
- '**.sh'
- '**CMakeLists.txt'
- '**requirements.txt'
- '**data/*'
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# Cancel jobs running if new commits are pushed
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
# Write permissions are not required
permissions: {}
# Workflow run - one or more jobs that can run sequentially or in parallel
jobs:
# Dynamically build matrix for GNU job
setup-gnu-matrix:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
env:
EVENT_NAME: ${{ github.event_name }}
steps:
- id: set-matrix
run: |
if [[ "$EVENT_NAME" == 'push' ]]
then
# Include GCC 9–13 for PRs to main
MATRIX_JSON='
{
"toolchain": [
{"compiler": "gcc", "version": 13},
{"compiler": "gcc", "version": 12},
{"compiler": "gcc", "version": 11},
{"compiler": "gcc", "version": 10},
{"compiler": "gcc", "version": 9}
],
"std": ["f2008"],
"include": [
{"toolchain": {"compiler": "gcc", "version": 13}, "std": "f2018"}
]
}'
else
# Only GCC 13 for everything else
MATRIX_JSON='
{
"toolchain": [
{"compiler": "gcc", "version": 13}
],
"std": ["f2008", "f2018"]
}'
fi
# Convert json to compact line expected by github action
MATRIX_JSON=$(echo "$MATRIX_JSON" | jq -c .)
echo "matrix=${MATRIX_JSON}" >> $GITHUB_OUTPUT
GNU:
needs: setup-gnu-matrix
# The type of runner that the job will run on
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix: ${{ fromJSON(needs.setup-gnu-matrix.outputs.matrix) }}
# Terminate the job if it runs for more than 15 minutes
timeout-minutes: 15
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- name: Checkout code
with:
persist-credentials: false
uses: actions/checkout@v4
- name: setup-fortran
uses: fortran-lang/setup-fortran@d2ba6ea44297a24407def2f6e117954d844a5368 # v1
with:
compiler: ${{ matrix.toolchain.compiler }}
version: ${{ matrix.toolchain.version }}
- name: check-compilers-env
run: ${FC}
env:
FC: ${{ steps.setup-fortran.outputs.fc }}
- name: Install Python
uses: actions/setup-python@v5
with:
python-version: '3.13' # Use 3.13 as no PyTorch wheels for 3.14 yet.
- name: Install PyTorch
run: |
python -m pip install --upgrade pip
python -m venv ftorch
. ftorch/bin/activate
pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu
- name: Install OpenMPI
run: |
sudo apt update
sudo apt install -y openmpi-bin openmpi-common libopenmpi-dev
- name: Install pFUnit
run: |
# TODO: Avoid version pinning (needed because version appears in install path)
git clone -b v4.12.0 https://github.com/Goddard-Fortran-Ecosystem/pFUnit.git
mkdir pFUnit/build
cd pFUnit/build
cmake ..\
-DCMAKE_Fortran_COMPILER=gfortran\
-DMPI_Fortran_COMPILER=mpif90
make -j 4 install
- name: Build FTorch
env:
FORTRAN_STANDARD: ${{ matrix.std }}
run: |
. ftorch/bin/activate
VN=$(python -c "import sys; print('.'.join(sys.version.split('.')[:2]))")
export Torch_DIR=${VIRTUAL_ENV}/lib/python${VN}/site-packages
export BUILD_DIR=$(pwd)/build
# NOTE: The pFUnit version (pinned during installation above) is used in the install path.
export PFUNIT_DIR=$(pwd)/pFUnit/build/installed/PFUNIT-4.12
mkdir ${BUILD_DIR}
cd ${BUILD_DIR}
cmake .. \
-DPython_EXECUTABLE="$(which python)" \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_Fortran_COMPILER=gfortran \
-DCMAKE_C_COMPILER=gcc \
-DCMAKE_CXX_COMPILER=g++ \
-DCMAKE_INSTALL_PREFIX=${BUILD_DIR} \
-DCMAKE_BUILD_TESTS=TRUE \
-DCMAKE_PREFIX_PATH="${PFUNIT_DIR};${Torch_DIR}" \
-DCMAKE_Fortran_FLAGS="-std=$FORTRAN_STANDARD"
cmake --build .
cmake --install .
- name: Run unit tests
run: |
. ftorch/bin/activate
cd build
ctest --verbose --tests-regex unit
- name: Run integration tests
run: |
. ftorch/bin/activate
cd build
ctest --verbose --tests-regex example
Intel:
# Trigger intel build only if push to main, or called manually via dispatch.
if: |
(github.ref == 'refs/heads/main' && github.event_name == 'push')
|| github.event_name == 'workflow_dispatch'
|| (github.event_name == 'pull_request' && contains(github.event.pull_request.changed_files, '.github/workflows/test_suite_ubuntu.yml'))
# The type of runner that the job will run on
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
toolchain: [intel-ifx, intel-ifort]
include:
- toolchain: intel-ifx
FC: ifx
MPIFC: mpiifx
- toolchain: intel-ifort
FC: ifort
MPIFC: mpiifort
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- name: Checkout code
with:
persist-credentials: false
uses: actions/checkout@v4
- name: Install Python
uses: actions/setup-python@v5
with:
python-version: '3.13' # Use 3.13 as no PyTorch wheels for 3.14 yet.
- name: Install PyTorch
run: |
python -m pip install --upgrade pip
python -m venv ftorch
. ftorch/bin/activate
pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu
- name: Install Intel tools
uses: rscohn2/setup-oneapi@8affb2b9c36a17ffc190a96fd27ba5ad9b4b5447 # v0
with:
components: |
[email protected]
[email protected]
[email protected]
- name: Setup Intel oneAPI environment
run: |
source /opt/intel/oneapi/setvars.sh
printenv >> $GITHUB_ENV
- name: Install pFUnit
run: |
# TODO: Avoid version pinning (needed because version appears in install path)
git clone -b v4.12.0 https://github.com/Goddard-Fortran-Ecosystem/pFUnit.git
mkdir pFUnit/build
cd pFUnit/build
cmake .. \
-DCMAKE_C_COMPILER=icx \
-DCMAKE_CXX_COMPILER=icpx \
-DCMAKE_Fortran_COMPILER=${{ matrix.FC }} \
-DMPI_Fortran_COMPILER=${{ matrix.MPIFC }}
make -j 4 install
- name: Build and install FTorch
run: |
. ftorch/bin/activate
VN=$(python -c "import sys; print('.'.join(sys.version.split('.')[:2]))")
export Torch_DIR=${VIRTUAL_ENV}/lib/python${VN}/site-packages
export BUILD_DIR=$(pwd)/build
# NOTE: The pFUnit version (pinned during installation above) is used in the install path.
export PFUNIT_DIR=$(pwd)/pFUnit/build/installed/PFUNIT-4.12
mkdir ${BUILD_DIR}
cd ${BUILD_DIR}
cmake .. \
-DPython_EXECUTABLE="$(which python)" \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_COMPILER=icx \
-DCMAKE_CXX_COMPILER=icpx \
-DCMAKE_Fortran_COMPILER=${{ matrix.FC }} \
-DMPI_Fortran_COMPILER=${{ matrix.MPIFC }} \
-DCMAKE_INSTALL_PREFIX=${BUILD_DIR} \
-DCMAKE_BUILD_TESTS=TRUE \
-DCMAKE_PREFIX_PATH="${PFUNIT_DIR};${Torch_DIR}" \
-DCMAKE_Fortran_FLAGS="-stand f08"
cmake --build .
cmake --install .
- name: Run unit tests
run: |
. ftorch/bin/activate
cd build
ctest --verbose --tests-regex unit
- name: Run integration tests
run: |
. ftorch/bin/activate
cd build
ctest --verbose --tests-regex example