Skip to content

Update intel action in workflow and pin version. #79

Update intel action in workflow and pin version.

Update intel action in workflow and pin version. #79

# Workflow to run the FTorch test suite using jobs for GNU Fortran compiler
# and system Clang compilers (macOS arm64)
name: Test suite (macOS 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:
# This workflow
- '.github/workflows/test_suite_macos_cpu_clang.yml'
# 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 job
setup-matrix:
name: setup matrix
runs-on: macos-latest
# Terminate the job if it runs for more than 5 minutes
timeout-minutes: 5
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
env:
EVENT_NAME: ${{ github.event_name }}
steps:
- id: set-matrix
run: |
MATRIX_JSON='
{
"std": ["f2008", "f2018"],
"compiler": ["clang"]
}'
# Convert json to compact line expected by github action
MATRIX_JSON=$(echo "$MATRIX_JSON" | jq -c .)
echo "matrix=${MATRIX_JSON}" >> $GITHUB_OUTPUT
test-suite:
name: test suite (${{ matrix.compiler }}, ${{ matrix.std }})
needs: setup-matrix
# The type of runner that the job will run on
runs-on: macos-latest
strategy:
fail-fast: false
matrix: ${{ fromJSON(needs.setup-matrix.outputs.matrix) }}
# Terminate the job if it runs for more than 20 minutes
timeout-minutes: 20
# 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 FTorch repository
with:
persist-credentials: true
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Setup Python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: '3.13'
- name: Install ftorch_utils
run: |
python -m pip install --upgrade pip
python -m venv ftorch
. ftorch/bin/activate
pip install . --extra-index-url https://download.pytorch.org/whl/cpu --group test
- name: Install gfortran and OpenMPI
# Install from source to avoid compiler mismatch between gfortran versions
# between open-mpi installation and when building FTorch.
run: |
brew update
brew install gcc openmpi libomp
- name: Ensure gfortran symlink exists
run: |
GFORTRAN_PATH=$(ls $(brew --prefix)/bin/gfortran-* | sort -V | tail -n 1)
if [ ! -e "$(brew --prefix)/bin/gfortran" ]; then
ln -s "$GFORTRAN_PATH" "$(brew --prefix)/bin/gfortran"
fi
ls -l $(brew --prefix)/bin/gfortran*
- name: Set compilers as GitHub environment variables
run: |
# Add homebrew to path
echo "PATH=$(brew --prefix)/bin:$PATH" >> $GITHUB_ENV
# brew installs gfortran-<version> from the gcc package, so extract this as generic FC
echo "FC=$(brew --prefix)/bin/gfortran" >> $GITHUB_ENV
echo "MPI_FC=$(brew --prefix)/bin/mpif90" >> $GITHUB_ENV
# Use system clang for C and C++
echo "CC=clang" >> $GITHUB_ENV
echo "CXX=clang++" >> $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=$CC \
-DCMAKE_Fortran_COMPILER=$FC\
-DMPI_Fortran_COMPILER=$MPI_FC
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 DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:${Torch_DIR}/torch/lib
export FTORCH_BUILD_DIR=$(pwd)/build
mkdir -p ${FTORCH_BUILD_DIR}
# Install to /tmp/ to ensure independent from the CMake build in standalone check.
export FTORCH_INSTALL_DIR=/tmp/ftorch-install
mkdir -p ${FTORCH_INSTALL_DIR}
# NOTE: The pFUnit version (pinned during installation above) is used in the install path.
export PFUNIT_DIR=$(pwd)/pFUnit/build/installed/PFUNIT-4.12
cd ${FTORCH_BUILD_DIR}
cmake .. \
-DPython_EXECUTABLE="$(which python)" \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_COMPILER=$CC \
-DCMAKE_CXX_COMPILER=$CXX \
-DCMAKE_Fortran_COMPILER=$FC\
-DCMAKE_INSTALL_PREFIX="${FTORCH_INSTALL_DIR}" \
-DCMAKE_BUILD_TESTS=TRUE \
-DCMAKE_PREFIX_PATH="${PFUNIT_DIR};${Torch_DIR}" \
-DCMAKE_Fortran_FLAGS="-std=${FORTRAN_STANDARD}"\
-DCMAKE_C_FLAGS="-Xpreprocessor -fopenmp -I$(brew --prefix libomp)/include" \
-DCMAKE_CXX_FLAGS="-stdlib=libc++ -Xpreprocessor -fopenmp -I$(brew --prefix libomp)/include" \
-DCMAKE_EXE_LINKER_FLAGS="-L$(brew --prefix libomp)/lib -lomp"
cmake --build .
cmake --install .
- name: Check pkg-config file
run: |
# pkg-config looks in the `build` directory for libraries
export PKG_CONFIG_PATH=${PKG_CONFIG_PATH}:build
libs=$(pkg-config --libs ftorch)
cflags=$(pkg-config --cflags ftorch)
# Assert linker flags not empty
if [[ -z "${libs}" ]]
then
echo "::error ::pkg-config --libs ftorch returned empty output"
exit 1
fi
# Assert expected linker flags
lib_dir=$(grep -oE "\-L.*/lib" <<< ${libs})
lib=$(grep -oE "\-lftorch" <<< ${libs})
if [[ -z "${lib_dir}" || -z "${lib}" ]]
then
echo "::error ::pkg-config --libs ftorch do not contain expected linker flags"
exit 1
fi
# Assert compiler flags not empty
if [[ -z "${cflags}" ]]
then
echo "::error ::pkg-config --cflags ftorch returned empty output"
exit 1
fi
# Assert expected compiler flags
include_dir=$(grep -oE "/include " <<< ${cflags})
module_dir=$(grep -oE "/include/ftorch" <<< ${cflags})
if [[ -z ${include_dir} || -z ${module_dir} ]]
then
echo "::error ::pkg-config --cflags ftorch do not contain expected compiler flags"
exit 1
fi
- name: Run Fortran unit tests
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 FTORCH_BUILD_DIR=$(pwd)/build
export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:${Torch_DIR}/torch/lib:${FTORCH_BUILD_DIR}/lib
cd build
ctest --verbose --tests-regex unit
- name: Run Python unit tests
run: |
. ftorch/bin/activate
pytest --verbose test/ftorch_utils
- name: Run integration tests
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 FTORCH_BUILD_DIR=$(pwd)/build
export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:${Torch_DIR}/torch/lib:${FTORCH_BUILD_DIR}/lib
cd build
ctest --verbose --tests-regex example
# Check that we can successfully build and run an example outside the main FTorch build process
- name: Standalone SimpleNet example
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/torch"
export FTORCH_INSTALL_DIR=/tmp/ftorch-install
export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:${VIRTUAL_ENV}/lib/python${VN}/site-packages/torch/lib:${FTORCH_BUILD_DIR}/lib
export EXAMPLE_BUILD_DIR="examples/02_SimpleNet/build"
mkdir "${EXAMPLE_BUILD_DIR}"
cd "${EXAMPLE_BUILD_DIR}"
cmake .. \
-DPython_EXECUTABLE="$(which python)" \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_PREFIX_PATH="${FTORCH_INSTALL_DIR};${Torch_DIR}" \
-DCMAKE_BUILD_TESTS=TRUE \
-DCMAKE_Fortran_FLAGS="-std=${FORTRAN_STANDARD}"
cmake --build .
ctest -V