Skip to content

Test LLVM Flang

Test LLVM Flang #237

Workflow file for this run

name: Test LLVM Flang
on:
# Trigger the workflow on push or pull request
#push:
pull_request: # DANGEROUS! MUST be disabled for self-hosted runners!
# Trigger the workflow by cron. The default time zone of GitHub Actions is UTC.
schedule:
- cron: '0 4 2-31/4 * *'
# Trigger the workflow manually
workflow_dispatch:
inputs:
git-ref:
description: Git Ref (Optional)
required: false
maxtr:
description: Maximum number of trust-region iterations
required: false
# Show the git ref in the workflow name if it is invoked manually.
run-name: ${{ github.event_name == 'workflow_dispatch' && format('Manual run {0}, maxtr {1}', inputs.git-ref, inputs.maxtr) || '' }}
jobs:
test:
name: Run LLVM Flang tests
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix: # At most 256 combinations are allowed.
os: [ubuntu-latest, ubuntu-24.04-arm, macos-latest, macos-15-intel, windows-latest, windows-11-arm]
solver: [newuoa, cobyla, lincoa, bobyqa, uobyqa]
fflags: [-O1, -O2, -g, -fast] # We omit -O3, or there would be too many combinations!
testdim: [small, big]
steps:
- name: Run `sudo apt update`
if: startsWith(matrix.os, 'ubuntu')
run: sudo apt update || true # Otherwise, free-disk-space or other actions relying on `apt` may fail
- name: Free disk space
if: startsWith(matrix.os, 'ubuntu')
uses: jlumbroso/free-disk-space@main
with:
# all of these default to true, but feel free to set to "false" if necessary for your workflow
android: true
dotnet: true
haskell: true
large-packages: true
docker-images: true
swap-storage: false # Important, or the runner may be shut down due to memory starvation.
- name: Clone Repository (Latest)
uses: actions/checkout@v6.0.2
if: github.event.inputs.git-ref == ''
with:
submodules: recursive
# ssh-key: ${{ secrets.SSH_PRIVATE_KEY_ACT }} # This forces checkout to use SSH, not HTTPS
# As of 260213, checkout with ssh fails on Windows arm runners due to "UNPROTECTED PRIVATE KEY FILE"
- name: Clone Repository (Custom Ref)
uses: actions/checkout@v6.0.2
if: github.event.inputs.git-ref != ''
with:
ref: ${{ github.event.inputs.git-ref }}
# ssh-key: ${{ secrets.SSH_PRIVATE_KEY_ACT }} # This forces checkout to use SSH, not HTTPS
# As of 260213, checkout with ssh fails on Windows arm runners due to "UNPROTECTED PRIVATE KEY FILE"
submodules: recursive
- name: Miscellaneous setup
shell: bash
run: bash .github/scripts/misc_setup
- name: Install LLVM Flang on non-Windows; treat timeout as SUCCESS (exit 0), which may happen on macos-intel.
if: runner.os != 'Windows'
uses: equipez/run-bash-command@v2
with:
timelimit: 180m
command: |
bash .github/scripts/install_llvm \
|| { echo "Warning: LLVM Flang installation failed!!" >&2; exit 0; }
- name: Install LLVM Flang on Windows
if: runner.os == 'Windows'
shell: bash
run: |
bash .github/scripts/install_llvm \
|| { echo "Warning: LLVM Flang installation failed!!" >&2; exit 0; }
# Check where is clang_rt.builtins
ls -alR "/c/Program Files/LLVM/lib" || echo "LLVM/lib not found!!"
ARCH=$(flang -dumpmachine | cut -d- -f1)
echo "Flang target architecture: ${ARCH}"
echo "Looking for clang_rt.builtins*${ARCH} in /c/Program Files/LLVM/lib"
find "/c/Program Files/LLVM/lib" -name "clang_rt.builtins*$(ARCH)*" 2>/dev/null | sort -V | tail -n 1 || echo "clang_rt.builtins*${ARCH} not found!!"
echo "Looking for clang_rt.builtins* in /c/Program Files/LLVM/lib (the last one found will be printed)"
find "/c/Program Files/LLVM/lib" -name "clang_rt.builtins*" 2>/dev/null | sort -V | tail -n 1 || echo "clang_rt.builtins not found!!"
echo "Looking for clang_rt.builtins* in /c/Program Files/LLVM/lib (all found will be printed)"
find "/c/Program Files/LLVM/lib" -name "clang_rt.builtins*" 2>/dev/null || echo "clang_rt.builtins not found!!"
- name: Revise maxtr
# This is to see whether "GitHub Actions xx lost communication with the server" was caused
# by maxtr = huge(maxtr) - 1_IK. We suspect this because the error occurs with IK = i8
# and IK = i4 for all solvers when testdim = small, but not with IK = i2 at all.
# Update 20240422: The error does not occur any more after the update. WHY? Does this imply
# INFINITE CYCLING in the code?
# update 20250816: First, server shutdown is observed on LINCOA/BOBYQA small tests with IK = i4.
# Is this the same issue as before? Second, in the current workflow (and many others), the
# definition of IK changes daily. If this issue is related to IK, it will not be observed every day.
shell: bash
if: ${{ github.event.inputs.maxtr != '' }}
run: |
cd fortran/${{ matrix.solver }}
$SEDI 's|maxtr = huge(maxtr) - 1_IK|maxtr = ${{ github.event.inputs.maxtr }}|' *.f90
grep 'maxtr = ' *.f90
- name: Revise linalg.f90 to see why "Y >= 0 unless X contains NaN" fails
shell: bash
run: |
if [[ $(uname) = 'Darwin' ]]; then # macOS uses BSD sed, which does not understand \s or \n
brew install gnu-sed
SEDI="gsed -i"
fi
cd fortran/common/
$SEDI "s|\(^\s*\)\(call assert(\)\(y >= 0 .or. any(is_nan(x))\)\(.*$\)|\1if (.not. (\3)) then\n\1\1write(*,*) '====> x = ', x, 'y = ', y, 'p = ', p_loc, 'scaling = ', scaling, 'x/scaling = ', x/scaling, 'sumxs2', sum((x / scaling)**2), 'sumx2 = ', sum(x**2), 'sqrt(sumx2) = ', sqrt(sum(x**2))\n\1\1error stop\n\1end if\n\1\2\3\4|" linalg.f90
cat linalg.f90
- name: Revise string.f90
shell: bash
run: |
if [[ $(uname) = 'Darwin' ]]; then # macOS uses BSD sed, which does not understand \s or \n
brew install gnu-sed
SEDI="gsed -i"
fi
cd fortran/common/
$SEDI "s|\(^.*\)\(x <= -REALMAX \* (1.0 - 10.0\*\*(-ndgt_loc)) .eqv. str2real(s) <= -REALMAX \* (1.0 - 10.0\*\*(-ndgt_loc))\)|if (.not. \2) then\n write(*,*) '====> x = ', x, 's = ', s, 'str2real(s) = ', str2real(s)\nerror stop\nelse\n\1\2|" string.f90
$SEDI "s|\(^\s*\& 'IS_NEGINF(X) \.EQV\. IS_NEGINF(STR2REAL(S)).*$\)|\1\nend if|" string.f90
$SEDI "s|\(^.*\)\(x >= REALMAX \* (1.0 - 10.0\*\*(-ndgt_loc)) .eqv. str2real(s) >= REALMAX \* (1.0 - 10.0\*\*(-ndgt_loc))\)|if (.not. \2) then\n write(*,*) '====> x = ', x, 's = ', s, 'str2real(s) = ', str2real(s)\nerror stop\nelse\n\1\2|" string.f90
$SEDI "s|\(^\s*\& 'IS_POSINF(X) \.EQV\. IS_POSINF(STR2REAL(S)).*$\)|\1\nend if|" string.f90
cat string.f90
- name: Conduct the test
shell: bash
run: |
##########################################################################################
# Skip the test on windows-latest if flang is not found and LLVM version is less than 22,
# as LLVM 21 installed by choco on windows-latest does not include flang. See
# https://github.com/llvm/llvm-project/issues/181348
if [[ "${{ matrix.os }}" == windows-latest ]] ; then
echo "We are on ${{ matrix.os }}. LLVM installed by choco may not provide flang."
# Infer the version of LLVM from llvm-ar. We should have used `llvm-config --version`,
# but it is not available on windows-latest after LLVM 21.1.8 is installed with choco.
LLVM_VERSION=$(llvm-ar --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | cut -d. -f1)
echo "LLVM version inferred from llvm-ar: $LLVM_VERSION"
FLANG_PATH=$(command -v flang 2>/dev/null || echo "NOT_FOUND")
echo "Flang path: $FLANG_PATH"
if [[ "$LLVM_VERSION" -lt 22 && "$FLANG_PATH" == "NOT_FOUND" ]] ; then
echo "Warning: flang not found!! Skipping the test." >&2
exit 0
fi
fi
##########################################################################################
# On macos-intel, the installation of LLVM Flang with Homebrew may fail. If so and if the
# current day is not divisible by 3, then we skip the test.
if ! type flang >/dev/null 2>&1 ; then
if [[ ${{ runner.os }} == macOS && ${{ runner.arch }} == X64 && $(( $(date +%-d) % 3 )) -ne 0 ]] ; then
echo "Warning: flang not found!! Skipping the test." >&2
exit 0
else
echo "Error: flang not found!! Skipping the test." >&2
exit 1
fi
fi
export FFLAGS=${{ matrix.fflags }}
export TESTDIM=${{ matrix.testdim }}
IK=i$(( 2**(1 + $(date +%-d) % 3) ))
echo "IK=${IK}"
echo "IK=${IK}" >> "$GITHUB_ENV"
# 20260213: We skip the extensive test on Windows due to the following reasons. The
# examples will still be tested on Windows.
# 0. It is quite difficult to debug on Windows. We choose to develop and debug the code on
# Linux and macOS, and only run a quick test on Windows to see whether it works at all.
# 1. Windows does not support the symlink of Linux. Makefile will fail when copying source files.
# 2. Makefile.common does not work on Windows for the moment due to quotation marks.
# Nevertheless, we should still define IK etc., as they will be used when defining the artifact names.
if [[ "$RUNNER_OS" != "Windows" ]] ; then
cd "$ROOT_DIR"/fortran/tests && make ftest_${IK}.${{ matrix.solver }}
fi
cd "$ROOT_DIR"/fortran/examples/${{ matrix.solver }}
export EXAMPLE_NUM=1 && make clean && make ftest
export EXAMPLE_NUM=2 && make clean && make ftest
- name: Store artifacts
uses: actions/upload-artifact@v7
if: always() # Always run even if the workflow is canceled manually or due to overtime.
with:
name: ${{ matrix.os }}-${{ matrix.solver }}-${{ env.IK }}-${{ matrix.fflags }}-${{ matrix.testdim }}
path: ${{ env.TEST_DIR }}/prima/fortran/tests/test.${{ matrix.solver }}/log/*.log
- name: Remove the test data
if: always() # Always run even if the workflow is canceled manually or due to overtime.
shell: bash # Important; otherwise, `rm -rf` will not work on Windows.
run: rm -rf ${{ env.TEST_DIR }}