Test gfortran #420
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Test gfortran | |
| 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 16 * * *' | |
| # Trigger the workflow manually | |
| workflow_dispatch: | |
| inputs: | |
| git-ref: | |
| description: Git Ref (Optional) | |
| 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}', inputs.git-ref) || '' }} | |
| jobs: | |
| test: | |
| name: Run gfortran tests | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, ubuntu-24.04-arm, windows-latest, windows-11-arm, macos-15-intel, macos-latest] | |
| compiler: [gcc] | |
| version: [13, latest] # Too expensive to test all versions | |
| solver: [newuoa, cobyla, lincoa, bobyqa, uobyqa] | |
| testdim: [small, big] | |
| # With FFLAGS=-O3, the following combinations encounter failures of assertion on X == X_UNC/ALT | |
| # when testing | |
| # bobyqa: gtest_i4_r8_d1_tst, chebquad | |
| # lincoa: gtest_i4_r8_d1_tst, chebquad | |
| # cobyla: gtest_i4_r8_d1_tst, trigssqs | |
| # See | |
| # https://github.com/libprima/prima/issues/268 | |
| # https://github.com/s-prima/prima/actions/runs/22023414613 | |
| # This should be investigated and fixed when we have a macOS with M* chip at hand. | |
| # It is reproducible on zMS. | |
| exclude: | |
| - os: macos-latest | |
| testdim: small | |
| version: latest | |
| solver: bobyqa | |
| - os: macos-latest | |
| testdim: small | |
| version: latest | |
| solver: lincoa | |
| - os: macos-latest | |
| testdim: small | |
| version: latest | |
| solver: cobyla | |
| steps: | |
| - name: Set http.postBuffer and core.compression | |
| # This is a workaround for random "early EOF" of checkout. | |
| # See https://github.com/actions/checkout/issues/748, https://github.com/actions/checkout/issues/1379 | |
| if: startsWith(matrix.os, 'windows') | |
| run: git config --global http.postBuffer 1048576000 && git config --global core.compression 0 | |
| - 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 231227, checkout with ssh fails frequently on Windows runners. | |
| - name: Clone Repository (Custom Ref) | |
| uses: actions/checkout@v6.0.2 | |
| if: github.event.inputs.git-ref != '' | |
| with: | |
| ref: ${{ github.event.inputs.git-ref }} | |
| submodules: recursive | |
| # ssh-key: ${{ secrets.SSH_PRIVATE_KEY_ACT }} # This forces checkout to use SSH, not HTTPS | |
| # As of 231227, checkout with ssh fails frequently on Windows runners. | |
| - name: Miscellaneous setup | |
| shell: bash # Important; otherwise, the following statements do not work on Windows. | |
| run: bash .github/scripts/misc_setup | |
| - name: Set up Fortran | |
| uses: fortran-lang/setup-fortran@main | |
| with: | |
| compiler: ${{ matrix.compiler }} | |
| version: ${{ matrix.version }} | |
| - name: Check gfortran version | |
| shell: bash | |
| run: | | |
| which gcc && gcc --version && which gfortran && gfortran --version | |
| - name: Revise Makefile.common to exclude r16 tests when the dimension is big | |
| if: ${{ matrix.testdim == 'big' }} | |
| shell: bash | |
| run: | | |
| cd fortran/tests/makefiles || exit 42 | |
| $SEDI "s|\$(TST)_.*r16_d[0,1]_tst||g" Makefile.common && cat Makefile.common | |
| - name: Revise test_bobyqa.f90, test_lincoa.f90, and test_cobyla.f90 so that we know what is happening if assertion 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/tests || exit 42 | |
| $SEDI "s|\(\s*\)\(call.*X == X_UNC.*\)|\1if (.not. (all(abs(x - x_unc) <= 0) .and. (abs(f - f_unc) <= 0 .or. (is_neginf(f) .and. is_neginf(f_unc))))) then\n\1write(*,*) 'probname = ', strip(prob%probname), 'n = ', n, 'x0 = ', x0\n\1write(*,*) 'npt = ', npt, 'rhobeg = ', rhobeg, 'rhoend = ', rhoend\n\1write(*,*) 'maxfun = ', maxfun, 'maxhist = ', maxhist, 'ftarget = ', ftarget, 'iprint = ', iprint\n\1write(*,*) 'f, x = ', f, x\n\1write(*,*) 'f_unc, x_unc = ', f_unc, x_unc\n\1write(*,*) 'fhist = ', fhist\n\1write(*,*) 'xhist = ', xhist\n\1write(*,*) 'fhist_unc = ', fhist_unc\n\1write(*,*) 'xhist_unc = ', xhist_unc\n\1error stop\n\1else\n\1write(*,*) '>>> X == X_UNC and F == F_UNC <<< probname = ', strip(prob%probname), ', irand = ', irand\n\1end if\n\1\2|" test_bobyqa.f90 | |
| cat test_bobyqa.f90 | |
| $SEDI "s|\(\s*\)\(call.*X == X_ALT.*\)|\1if (.not. (all(abs(x - x_alt) <= 0) .and. (abs(f - f_alt) <= 0 .or. (is_neginf(f) .and. is_neginf(f_alt))))) then\n\1write(*,*) 'probname = ', strip(prob%probname), 'n = ', n, 'x0 = ', x0\n\1write(*,*) 'npt = ', npt, 'rhobeg = ', rhobeg, 'rhoend = ', rhoend\n\1write(*,*) 'maxfun = ', maxfun, 'maxhist = ', maxhist, 'ftarget = ', ftarget, 'iprint = ', iprint\n\1write(*,*) 'f, x = ', f, x\n\1write(*,*) 'f_alt, x_alt = ', f_alt, x_alt\n\1write(*,*) 'fhist = ', fhist\n\1write(*,*) 'xhist = ', xhist\n\1write(*,*) 'fhist_alt = ', fhist_alt\n\1write(*,*) 'xhist_alt = ', xhist_alt\n\1error stop\n\1else\n\1write(*,*) '>>> X == X_ALT and F == F_ALT <<< probname = ', strip(prob%probname), ', irand = ', irand\n\1end if\n\1\2|" test_lincoa.f90 | |
| cat test_lincoa.f90 | |
| $SEDI "s|\(\s*\)\(call.*X == X_ALT.*\)|\1if (.not. (all(abs(x - x_alt) <= 0) .and. (abs(f - f_alt) <= 0 .or. (is_neginf(f) .and. is_neginf(f_alt))))) then\n\1write(*,*) 'probname = ', strip(prob%probname), 'n = ', n, 'x0 = ', x0\n\1write(*,*) 'rhobeg = ', rhobeg, 'rhoend = ', rhoend\n\1write(*,*) 'maxfun = ', maxfun, 'maxhist = ', maxhist, 'ftarget = ', ftarget, 'iprint = ', iprint\n\1write(*,*) 'f, x = ', f, x\n\1write(*,*) 'f_alt, x_alt = ', f_alt, x_alt\n\1write(*,*) 'fhist = ', fhist\n\1write(*,*) 'xhist = ', xhist\n\1write(*,*) 'fhist_alt = ', fhist_alt\n\1write(*,*) 'xhist_alt = ', xhist_alt\n\1error stop\n\1else\n\1write(*,*) '>>> X == X_ALT and F == F_ALT <<< probname = ', strip(prob%probname), ', irand = ', irand\n\1end if\n\1\2|" test_cobyla.f90 | |
| cat test_cobyla.f90 | |
| - name: Revise string.f90, so that we know what is happening if assertion 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 || exit 42 | |
| $SEDI "s|\(call assert(abs(x - str2real(s)) <= abs(x) \* 10.0\*\*(-ndgt_loc), 'STR2REAL(S) == X', srname)\)|if (.not. abs(x - str2real(s)) <= abs(x) * 10.0**(-ndgt_loc)) then\nwrite(*,*) '====> x = ', x, 's = ', s, 'sx = ', str2real(s)\nerror stop\nelse\n\1\nend if|" string.f90 | |
| cat string.f90 | |
| - name: Revise linalg.f90 regarding a postcondition of p_norm, so that we know what is happening if it 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 || exit 42 | |
| $SEDI "s|'Y >= 0 unless X contains NaN'|'Y >= 0 unless X contains NaN'\&\n\&\/\/num2str(y)\/\/num2str(sum(abs(x)))\/\/num2str(int(is_nan(sum(abs(x)))))\/\/num2str(x)|" linalg.f90 | |
| $SEDI "s|function p_norm(x, p) result(y)|function p_norm(x, p) result(y)\nuse, non_intrinsic :: string_mod, only : num2str|" linalg.f90 | |
| cat linalg.f90 | |
| - name: Conduct the test; treat timeout as SUCCESS (exit 0). Only for non-Windows. | |
| if: runner.os != 'Windows' | |
| uses: equipez/run-bash-command@v2 | |
| with: | |
| timelimit: 320m | |
| command: | | |
| IK=i$(( 2**(1 + $(date +%-d) % 3) )) | |
| echo "IK=${IK}" | |
| echo "IK=${IK}" >> "$GITHUB_ENV" | |
| # Use $(( )) rather than $(expr ). See https://unix.stackexchange.com/questions/63166/bash-e-exits-when-let-or-expr-evaluates-to-0 | |
| export TESTDIM=${{ matrix.testdim }} | |
| echo "TESTDIM=$TESTDIM" >> "$GITHUB_ENV" | |
| FFLAGS=-O$(($(date +%-d) % 5)) | |
| FFLAGS=${FFLAGS/O0/g} | |
| FFLAGS=${FFLAGS/O4/fast} | |
| export FFLAGS | |
| echo "FFLAGS=$FFLAGS" | |
| echo "FFLAGS=$FFLAGS" >> "$GITHUB_ENV" | |
| cd "$ROOT_DIR"/fortran/tests && make gtest_${IK}_c.${{ matrix.solver }} && make gtest_${IK}.${{ matrix.solver }} | |
| cd "$ROOT_DIR"/fortran/examples/${{ matrix.solver }} | |
| export EXAMPLE_NUM=1 && make clean && make gtest | |
| export EXAMPLE_NUM=2 && make clean && make gtest | |
| - name: Conduct the test on Windows | |
| if: runner.os == 'Windows' | |
| shell: bash # Important; otherwise, `<` will not work on Windows. | |
| run: | | |
| # 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. | |
| IK=i$(( 2**(1 + $(date +%-d) % 3) )) | |
| echo "IK=${IK}" | |
| echo "IK=${IK}" >> "$GITHUB_ENV" | |
| # Use $(( )) rather than $(expr ). See https://unix.stackexchange.com/questions/63166/bash-e-exits-when-let-or-expr-evaluates-to-0 | |
| export TESTDIM=${{ matrix.testdim }} | |
| echo "TESTDIM=$TESTDIM" >> "$GITHUB_ENV" | |
| FFLAGS=-O$(($(date +%-d) % 5)) | |
| FFLAGS=${FFLAGS/O0/g} | |
| FFLAGS=${FFLAGS/O4/fast} | |
| export FFLAGS | |
| echo "FFLAGS=$FFLAGS" | |
| echo "FFLAGS=$FFLAGS" >> "$GITHUB_ENV" | |
| cd "$ROOT_DIR"/fortran/examples/${{ matrix.solver }} | |
| export EXAMPLE_NUM=1 && make clean && make gtest | |
| export EXAMPLE_NUM=2 && make clean && make gtest | |
| - name: Store artifacts | |
| uses: actions/upload-artifact@v7 | |
| if: always() # Always run even if the workflow is canceled manually or due to overtime. | |
| # Note that `$TEST_DIR` does not work on Windows, where its equivalent is `$env:TEST_DIR`. | |
| # In the following, we enquire `$TEST_DIR` by using the `env` context, which is platform independent. | |
| with: | |
| name: ${{ matrix.os }}-${{ matrix.solver }}-${{ env.IK }}-${{ matrix.version }}-${{ env.TESTDIM }}-${{ env.FFLAGS }} | |
| 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 }} |