Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

change code to use mfem/github-actions #221

Closed
wants to merge 4 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
176 changes: 46 additions & 130 deletions .github/workflows/build-and-test.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
# Copyright (c) 2010-2024, Lawrence Livermore National Security, LLC. Produced
# at the Lawrence Livermore National Laboratory. All Rights reserved. See files
# LICENSE and NOTICE for details. LLNL-CODE-806117.
#
# This file is part of the MFEM library. For more information and source code
# availability visit https://mfem.org.
#
# MFEM is free software; you can redistribute it and/or modify it under the
# terms of the BSD-3 license. We welcome feedback and contributions, see file
# CONTRIBUTING.md for details.

# build-and-test.yml
#
# - Builds PyMFEM in three stages:
Expand All @@ -7,54 +18,46 @@
# - Runs tests under `run_examples.py`
# - If there is a failure, uploads test outputs as an artifact

name: Build and Test
name: Build/test PyMFEM

on:
workflow_dispatch:
inputs:
test_matrix:
description: 'Test all options in the matrix. If set to false, will only trigger the CI for the default options.'
required: true
default: false
type: boolean
pull_request:
# TODO: setup a trigger to run on MFEM releases

jobs:
build-and-test:
# -------------------------------------------------------------------------------------------------
# Build and test matrix
# -------------------------------------------------------------------------------------------------
build-and-test-matrix:
if: ${{ github.event_name == 'pull_request' || inputs.test_matrix == true }}
strategy:
fail-fast: false
matrix:
# ---------- Main ----------
os: [ubuntu-latest, macos-latest]
python-version: ['3.7', '3.8', '3.9', '3.10', '3.11'] # 3.12 is not supported by scipy
# NOTE: If setup.py could accept a commit hash as an argument, that could give us more flexibility here
mfem-branch: [master, default] # 'default' uses a specific commit hash defined in setup.py:repos_sha
parallel: [false, true]

# ---------- Dependencies ----------
cuda: [true]
libceed: [false]
gslib: [true]

# ---------- Build process ----------
# When phases==true, run each individual build step explicitly: mfem -> swig -> pymfem
phases: [true]

exclude:
# CUDA does not support MacOS
- os: macos-latest
cuda: true

include:
# Include a single example where the build is executed all at once
- os: ubuntu-latest
python-version: 3.9
mfem-branch: default
parallel: false
cuda: false
libceed: false
gslib: true
phases: false

runs-on: ${{ matrix.os }}

# Reference for $${{ x && y || z }} syntax: https://7tonshark.com/posts/github-actions-ternary-operator/
name: >-
Build/test:
${{ matrix.os }},
${{ matrix.python-version }},
${{ matrix.mfem-branch }},
Expand All @@ -63,116 +66,29 @@ jobs:
env:
cuda-toolkit-version: '12.4.1'
cuda-driver-version: '550.54.15'
# These are all passed to setup.py as one concatenated string
build-flags: >-
${{ matrix.parallel && '--with-parallel' || '' }}
${{ matrix.cuda && '--with-cuda' || '' }}
${{ matrix.libceed && '--with-libceed' || '' }}
${{ matrix.gslib && '--with-gslib' || '' }}
${{ (!(matrix.mfem-branch == 'default') && format('--mfem-branch=''{0}''', matrix.mfem-branch)) || '' }}

# -------------------------------------------------------------------------------------------------
# Begin workflow
# -------------------------------------------------------------------------------------------------
steps:
- name: Checkout repo
uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
- name: Build and test pymfem
uses: mfem/github-actions/build-pymfem@pymfem-workflow
with:
os: ${{ matrix.os }}
python-version: ${{ matrix.python-version }}

# -------------------------------------------------------------------------------------------------
# Download/install dependencies
# -------------------------------------------------------------------------------------------------
- name: Install core dependencies via requirements.txt
run: pip install -r requirements.txt --verbose

- name: Install MPI
if: matrix.parallel
run: |
sudo apt-get install mpich libmpich-dev
pip install mpi4py

- name: Cache CUDA
if: matrix.cuda
id: cache-cuda
uses: actions/cache@v4
with:
path: ~/cache
key: cuda-installer-${{ env.cuda-toolkit-version }}-${{ env.cuda-driver-version }}

- name: Download CUDA
if: matrix.cuda && steps.cache-cuda.outputs.cache-hit == false
run: |
CUDA_URL="https://developer.download.nvidia.com/compute/cuda/${{ env.cuda-toolkit-version }}/local_installers/cuda_${{ env.cuda-toolkit-version }}_${{ env.cuda-driver-version }}_linux.run"
curl -o ~/cache/cuda.run --create-dirs $CUDA_URL

- name: Install CUDA
if: matrix.cuda
run: |
# The --silent flag is necessary to bypass user-input, e.g. accepting the EULA
sudo sh ~/cache/cuda.run --silent --toolkit
echo "/usr/local/cuda/bin" >> $GITHUB_PATH

- name: Print dependency information
run: |
pip list
printf "\n\n---------- MPI ----------\n"
mpiexec --version || printf "MPI not installed"
printf "\n\n---------- CUDA ----------\n"
nvcc --version || printf "CUDA not installed"

# -------------------------------------------------------------------------------------------------
# Build MFEM + SWIG Bindings + PyMFEM
# -------------------------------------------------------------------------------------------------
- name: Build MFEM (step 1)
if: matrix.phases
run: python setup.py install --ext-only --vv ${{ env.build-flags }}

- name: Build SWIG wrappers (step 2)
if: matrix.phases
run: python setup.py install --swig --vv ${{ env.build-flags }}

- name: Build PyMFEM (step 3)
if: matrix.phases
run: python setup.py install --skip-ext --skip-swig --vv ${{ env.build-flags }}

- name: Build all (steps 1-3)
if: matrix.phases == false
run: python setup.py install --vv ${{ env.build-flags }}

# -------------------------------------------------------------------------------------------------
# Run tests
# -------------------------------------------------------------------------------------------------
- name: Run tests (serial)
if: matrix.parallel == false
run: |
cd test
python run_examples.py -serial -verbose

- name: Run tests (parallel)
if: matrix.parallel
run: |
cd test
python run_examples.py -parallel -verbose -np 2

# -------------------------------------------------------------------------------------------------
# Generate an artifact (output of tests) on failure
# -------------------------------------------------------------------------------------------------
- name: Generate test results artifact
id: generate-artifact
run: |
tar -cvzf sandbox.tar.gz test/sandbox
# generate a name for the artifact
txt=$(python -c "import datetime;print(datetime.datetime.now().strftime('%H_%M_%S_%f'))")
echo name="test_results_"${txt}"_"${{ github.run_id }}".tar.gz" >> $GITHUB_OUTPUT

- name: Upload Artifact
uses: actions/upload-artifact@v4
if: failure()
with:
name: ${{ steps.generate-artifact.outputs.name }}
path: sandbox.tar.gz
retention-days: 1
mfem-branch: ${{ matrix.mfem-branch }}
parallel: ${{ matrix.parallel }}
cuda: ${{ matrix.cuda }}
cuda-toolkit-version: ${{ env.cuda-toolkit-version }}
cuda-driver-version: ${{ env.cuda-driver-version }}
libceed: ${{ matrix.libceed }}
gslib: ${{ matrix.gslib }}
phases: ${{ matrix.phases }}

# -------------------------------------------------------------------------------------------------
# Build and test defaults
# -------------------------------------------------------------------------------------------------
build-and-test-defaults:
runs-on: ubuntu-latest
if: ${{ github.event_name == 'workflow_dispatch' && inputs.test_matrix == false }}
name: "Build/test: (defaults)"
steps:
- name: Build and test pymfem
uses: mfem/github-actions/build-pymfem@pymfem-workflow
Loading