diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml deleted file mode 100644 index 3f8755573..000000000 --- a/.github/workflows/cmake.yml +++ /dev/null @@ -1,401 +0,0 @@ -name: CMake - -on: - push: - branches: - - master - - try-github-actions-for-windows - paths: - - .github/workflows/cmake.yml - - lapack_testing.py - - '**CMakeLists.txt' - - 'BLAS/**' - - 'CBLAS/**' - - 'CMAKE/**' - - 'INSTALL/**' - - 'LAPACKE/**' - - 'SRC/**' - - 'TESTING/**' - - '!**README' - - '!**Makefile' - - '!**md' - pull_request: - paths: - - .github/workflows/cmake.yml - - lapack_testing.py - - '**CMakeLists.txt' - - 'BLAS/**' - - 'CBLAS/**' - - 'CMAKE/**' - - 'INSTALL/**' - - 'LAPACKE/**' - - 'SRC/**' - - 'TESTING/**' - - '!**README' - - '!**Makefile' - - '!**md' - -permissions: - contents: read - -env: - CFLAGS: "-Wall -pedantic" - # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) - -defaults: - run: - shell: bash - -jobs: - - test-install-release: - # Use GNU compilers - - # The CMake configure and build commands are platform agnostic and should work equally - # well on Windows or Mac. You can convert this to a matrix build if you need - # cross-platform coverage. - # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix - runs-on: ${{ matrix.os }} - - env: - BUILD_TYPE: Release - FFLAGS: ${{ matrix.fflags }} - - strategy: - fail-fast: true - matrix: - os: [ macos-26, ubuntu-24.04, ubuntu-24.04-arm, windows-2025 ] - fflags: [ - "-Wall -Wno-unused-dummy-argument -Wno-unused-variable -Wno-unused-label -Werror=conversion -fimplicit-none -frecursive -fcheck=all", - "-Wall -Wno-unused-dummy-argument -Wno-unused-variable -Wno-unused-label -Werror=conversion -fimplicit-none -frecursive -fcheck=all -fopenmp" ] - - steps: - - - name: Checkout LAPACK - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - - - name: Use GCC-14 on MacOS - if: ${{ matrix.os == 'macos-26' }} - run: > - cmake -B build -G Ninja - -D CMAKE_C_COMPILER="gcc-14" - -D CMAKE_Fortran_COMPILER="gfortran-14" - -D USE_FLAT_NAMESPACE:BOOL=ON - - - name: Special flags for Windows - if: ${{ matrix.os == 'windows-2025' }} - run: > - cmake -B build -G Ninja - -D CMAKE_EXE_LINKER_FLAGS="-Wl,--stack=2097152" - - - name: Configure CMake - # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using - # a single-configuration generator such as make or Ninja. - # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type - run: > - cmake -B build -G Ninja - -D CMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} - -D CMAKE_INSTALL_PREFIX=${{github.workspace}}/lapack_install - -D CBLAS:BOOL=ON - -D LAPACKE:BOOL=ON - -D BUILD_TESTING:BOOL=ON - -D LAPACKE_WITH_TMG:BOOL=ON - -D BUILD_SHARED_LIBS:BOOL=ON - - - name: Build - # Execute tests defined by the CMake configuration. - # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail - run: cmake --build build - - - name: Test with OpenMP - working-directory: ${{github.workspace}}/build - if: ${{ contains( matrix.fflags, 'openmp' ) && (matrix.os != 'windows-2025') }} - run: ctest -C ${{env.BUILD_TYPE}} --schedule-random -j1 --output-on-failure --timeout 100 - - - name: Test - working-directory: ${{github.workspace}}/build - if: ${{ !contains( matrix.fflags, 'openmp' ) && (matrix.os != 'windows-2025') }} - run: ctest -C ${{env.BUILD_TYPE}} --schedule-random -j2 --output-on-failure --timeout 100 - - - name: Upload test results - id: upload-test-results - # Uploaded even when the tests failed; that is when the results - # are needed most. The test summary below links to the artifact. - if: ${{ !cancelled() && matrix.os != 'windows-2025' }} - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 - with: - name: test-results-${{ matrix.os }}-${{ contains( matrix.fflags, 'openmp' ) && 'openmp' || 'no-openmp' }} - path: | - build/TESTING/testing_results.txt - build/lapack_testing_junit.xml - if-no-files-found: warn - retention-days: 14 - - - name: Write test summary - if: ${{ !cancelled() && matrix.os != 'windows-2025' }} - env: - ARTIFACT_URL: ${{ steps.upload-test-results.outputs.artifact-url }} - run: | - cd build 2>/dev/null || exit 0 - python3 lapack_testing.py -d TESTING --merge-apis --markdown summary.md || true - if [ -f summary.md ]; then - cat summary.md >> "$GITHUB_STEP_SUMMARY" - if [ -n "$ARTIFACT_URL" ]; then - printf '\nThe raw output of every test run (`testing_results.txt`) and a JUnit XML report are in the [test-results artifact](%s).\n' "$ARTIFACT_URL" >> "$GITHUB_STEP_SUMMARY" - fi - fi - - - name: Install - # Since we use a single configuration generator, Ninja, there is no need to provide - # the '--config ${{env.BUILD_TYPE}}' option for the build step in the 'cmake --build' command. - run: cmake --build build --target install -j2 - - test-extended-api-only: - runs-on: ubuntu-24.04 - - env: - BUILD_TYPE: Release - FFLAGS: "-Wall -Wno-unused-dummy-argument -Wno-unused-variable -Wno-unused-label -Werror=conversion -fimplicit-none -frecursive -fcheck=all" - - strategy: - fail-fast: true - matrix: - shared_libs: [ OFF, ON ] - - steps: - - - name: Checkout LAPACK - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - - - name: Configure CMake - run: > - cmake -B build -G Ninja - -D CMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} - -D BUILD_SHARED_LIBS:BOOL=${{matrix.shared_libs}} - -D BUILD_DEFAULT_API:BOOL=OFF - -D BUILD_INDEX64_EXT_API:BOOL=ON - -D BUILD_TESTING:BOOL=ON - -D CBLAS:BOOL=ON - -D LAPACKE:BOOL=ON - -D LAPACKE_WITH_TMG:BOOL=ON - - - name: Build - run: cmake --build build --config ${{env.BUILD_TYPE}} - - - name: Test - working-directory: ${{github.workspace}}/build - run: ctest -C ${{env.BUILD_TYPE}} --schedule-random -j2 --output-on-failure --timeout 100 - - - name: Upload test results - id: upload-test-results - if: ${{ !cancelled() }} - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 - with: - name: test-results-extended-api-shared-${{ matrix.shared_libs }} - path: | - build/TESTING/testing_results.txt - build/lapack_testing_junit.xml - if-no-files-found: warn - retention-days: 14 - - - name: Write test summary - if: ${{ !cancelled() }} - env: - ARTIFACT_URL: ${{ steps.upload-test-results.outputs.artifact-url }} - run: | - cd build 2>/dev/null || exit 0 - python3 lapack_testing.py -d TESTING --merge-apis --markdown summary.md || true - if [ -f summary.md ]; then - cat summary.md >> "$GITHUB_STEP_SUMMARY" - if [ -n "$ARTIFACT_URL" ]; then - printf '\nThe raw output of every test run (`testing_results.txt`) and a JUnit XML report are in the [test-results artifact](%s).\n' "$ARTIFACT_URL" >> "$GITHUB_STEP_SUMMARY" - fi - fi - - coverage: - - runs-on: ubuntu-24.04 - - env: - BUILD_TYPE: Coverage - FFLAGS: "-fopenmp" - - steps: - - - name: Checkout LAPACK - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - with: - # Codecov cannot determine which commit a report belongs to from a - # depth-1 clone of a pull request merge commit. - fetch-depth: 2 - - - name: Configure CMake - # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using - # a single-configuration generator such as make or Ninja. - # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type - run: > - cmake -B build -G Ninja - -D CMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} - -D CMAKE_INSTALL_PREFIX=${{github.workspace}}/lapack_install - -D CBLAS:BOOL=ON - -D LAPACKE:BOOL=ON - -D BUILD_TESTING:BOOL=ON - -D LAPACKE_WITH_TMG:BOOL=ON - -D BUILD_SHARED_LIBS:BOOL=ON - - - name: Install - # Since we use a single configuration generator, Ninja, there is no need to provide - # the '--config ${{env.BUILD_TYPE}}' option for the build step in the 'cmake --build' command. - run: cmake --build build --target install -j2 - - - name: Test - working-directory: ${{github.workspace}}/build - run: ctest -C ${{env.BUILD_TYPE}} --schedule-random -j2 --output-on-failure --timeout 1800 - - - name: Coverage - # Since we use a single configuration generator, Ninja, there is no need to provide - # the '--config ${{env.BUILD_TYPE}}' option for the build step in the 'cmake --build' command. - if: ${{ !cancelled() }} - run: cmake --build build --target coverage - - - name: Summarize coverage - # The coverage target discards gcov's output, so an entirely empty report - # is indistinguishable from a good one unless we look at the numbers. - # Print them, and fail if nothing was measured at all. - if: ${{ !cancelled() }} - run: | - gcda=$(find build -name '*.gcda' | wc -l) - reports=$(find build -name '*.gcov' | wc -l) - echo "counter files (.gcda): ${gcda}" - echo "gcov reports (.gcov): ${reports}" - if [ "${gcda}" -eq 0 ] || [ "${reports}" -eq 0 ]; then - echo "::error::No coverage data was recorded; the report would be empty." - exit 1 - fi - # In a gcov report an executed line is prefixed with its execution - # count and an unexecuted one with '#####' or '====='; everything else - # ('-') is not executable. - set -- $(find build -name '*.gcov' -exec cat {} + | awk ' - /^ *[0-9]+[*]?:/ { hit++; next } - /^ *(#####|=====):/ { miss++ } - END { printf "%d %d\n", hit + 0, hit + miss + 0 }') - hit=$1 - total=$2 - if [ "${hit}" -eq 0 ]; then - echo "::error::Coverage report is empty: not a single line was executed." - exit 1 - fi - percent=$(awk -v h="${hit}" -v t="${total}" 'BEGIN { printf "%.2f", 100 * h / t }') - echo "lines executed: ${hit} of ${total} (${percent}%)" - printf '## Coverage\n\n%s%% of lines executed (%s of %s) across %s files.\n' \ - "${percent}" "${hit}" "${total}" "${reports}" >> "$GITHUB_STEP_SUMMARY" - - - name: Upload coverage report to Codecov - if: ${{ !cancelled() }} - uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0 - with: - token: ${{ secrets.CODECOV_TOKEN }} - # The .gcov files already exist, so there is no need for the uploader - # to run gcov a second time itself. - plugins: noop - verbose: true - # Pull requests from forks have no access to repository secrets, so - # they can only upload if the Codecov organization permits tokenless - # uploads. Do not turn that into a CI failure for the contributor. - fail_ci_if_error: ${{ secrets.CODECOV_TOKEN != '' }} - - test-install-cblas-lapacke-without-fortran-compiler: - - runs-on: ubuntu-24.04 - - env: - BUILD_TYPE: Release - - steps: - - - name: Checkout LAPACK - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - - - name: Install basics - run: | - sudo apt update - sudo apt install -y cmake liblapack-dev libblas-dev - sudo apt purge gfortran - - - name: Configure CMake - # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using - # a single-configuration generator such as make or Ninja. - # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type - run: > - cmake -B build -G Ninja - -D CMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} - -D CMAKE_INSTALL_PREFIX=${{github.workspace}}/lapack_install - -D CBLAS:BOOL=ON - -D LAPACKE:BOOL=ON - -D USE_OPTIMIZED_BLAS:BOOL=ON - -D USE_OPTIMIZED_LAPACK:BOOL=ON - -D BUILD_TESTING:BOOL=OFF - -D LAPACKE_WITH_TMG:BOOL=OFF - -D BUILD_SHARED_LIBS:BOOL=ON - - - name: Install - # Since we use a single configuration generator, Ninja, there is no need to provide - # the '--config ${{env.BUILD_TYPE}}' option for the build step in the 'cmake --build' command. - run: cmake --build build --target install -j2 - - memory-check: - - runs-on: ubuntu-24.04 - - env: - BUILD_TYPE: Debug - - steps: - - - name: Checkout LAPACK - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - - - name: Install APT packages - run: | - sudo apt update - sudo apt install -y cmake valgrind gfortran - - - name: Configure CMake - # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using - # a single-configuration generator such as make or Ninja. - # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type - run: > - cmake -B build -G Ninja - -D CMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} - -D CBLAS:BOOL=ON - -D LAPACKE:BOOL=ON - -D BUILD_TESTING:BOOL=ON - -D LAPACKE_WITH_TMG:BOOL=ON - -D BUILD_SHARED_LIBS:BOOL=ON - -D LAPACK_TESTING_USE_PYTHON:BOOL=OFF - - - name: Build - # Since we use a single configuration generator, Ninja, there is no need to provide - # the '--config ${{env.BUILD_TYPE}}' option for the build step in the 'cmake --build' command. - run: cmake --build build - - - name: Test - working-directory: ${{github.workspace}}/build - run: | - ctest -C ${{env.BUILD_TYPE}} --output-on-failure --schedule-random -j2 -T memcheck > memcheck.out - cat memcheck.out - if tail -n 1 memcheck.out | grep -q "Memory checking results:"; then - exit 0 - else - for f in Testing/Temporary/MemoryChecker.*.log; do - if tail -n 1 $f | grep -q "ERROR SUMMARY: 0 errors"; then - tail -n 1 $f - continue - else - echo "Memory check failed in $f" - cat $f - exit 1 - fi - done - exit 0 - fi diff --git a/.github/workflows/special.yml b/.github/workflows/special.yml new file mode 100644 index 000000000..2824f9af9 --- /dev/null +++ b/.github/workflows/special.yml @@ -0,0 +1,268 @@ +name: Special Build Configurations + +on: + push: + branches: + - master + - ci_different_compiler + paths: + - .github/workflows/special.yml + - lapack_testing.py + - '**CMakeLists.txt' + - 'BLAS/**' + - 'CBLAS/**' + - 'CMAKE/**' + - 'INSTALL/**' + - 'LAPACKE/**' + - 'SRC/**' + - 'TESTING/**' + - '!**README' + - '!**Makefile' + - '!**md' + pull_request: + paths: + - .github/workflows/special.yml + - lapack_testing.py + - '**CMakeLists.txt' + - 'BLAS/**' + - 'CBLAS/**' + - 'CMAKE/**' + - 'INSTALL/**' + - 'LAPACKE/**' + - 'SRC/**' + - 'TESTING/**' + - '!**README' + - '!**Makefile' + - '!**md' + +permissions: + contents: read + +env: + CFLAGS: "-Wall -pedantic" + FFLAGS: "-Wall -Wno-unused-dummy-argument -Wno-unused-variable -Wno-unused-label -Werror=conversion -fimplicit-none -frecursive -fcheck=all" + +defaults: + run: + shell: bash + +jobs: + openmp-build: + runs-on: ${{ matrix.os }} + + env: + FFLAGS: "-Wall -Wno-unused-dummy-argument -Wno-unused-variable -Wno-unused-label -Werror=conversion -fimplicit-none -frecursive -fcheck=all -fopenmp" + FC: ${{ matrix.toolchain.FC }} + CC: ${{ matrix.toolchain.CC }} + + strategy: + fail-fast: true + matrix: + lib_type: [ static, shared ] + toolchain: + - FC: gfortran + CC: gcc + os: [ubuntu-26.04, ubuntu-26.04-arm, windows-2025] + - FC: gfortran-14 + CC: gcc-14 + os: macos-26 + + steps: + - name: Checkout LAPACK + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 + + - name: Configure CMake + run: | + cmake -B build -G Ninja + -D CMAKE_BUILD_TYPE=Release + -D CMAKE_Fortran_COMPILER="${FC}" \ + -D CMAKE_C_COMPILER="${CC}" \ + -D CMAKE_INSTALL_PREFIX=${{github.workspace}}/lapack_install + -D CBLAS:BOOL=ON + -D LAPACKE:BOOL=ON + -D BUILD_TESTING:BOOL=ON + -D LAPACKE_WITH_TMG:BOOL=ON + -D BUILD_SHARED_LIBS:BOOL=${{ matrix.lib_type == 'shared' && 'ON' || 'OFF' }} + + - name: Build + run: cmake --build build -j2 + + - name: Test with OpenMP + working-directory: ${{github.workspace}}/build + run: ctest --schedule-random -j1 --output-on-failure --timeout 100 + + - name: Upload test results + id: upload-test-results + # Uploaded even when the tests failed; that is when the results + # are needed most. The test summary below links to the artifact. + if: ${{ !cancelled() }} + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: test-results-openmp-${{ matrix.os }} + path: | + build/TESTING/testing_results.txt + build/lapack_testing_junit.xml + if-no-files-found: warn + retention-days: 14 + + - name: Write test summary + if: ${{ !cancelled() }} + env: + ARTIFACT_URL: ${{ steps.upload-test-results.outputs.artifact-url }} + run: | + cd build 2>/dev/null || exit 0 + python3 lapack_testing.py -d TESTING --merge-apis --markdown summary.md || true + if [ -f summary.md ]; then + cat summary.md >> "$GITHUB_STEP_SUMMARY" + if [ -n "$ARTIFACT_URL" ]; then + printf '\nThe raw output of every test run (`testing_results.txt`) and a JUnit XML report are in the [test-results artifact](%s).\n' "$ARTIFACT_URL" >> "$GITHUB_STEP_SUMMARY" + fi + fi + + - name: Install + run: cmake --build build --target install -j2 + + test-extended-api-only: + runs-on: ubuntu-24.04 + + strategy: + fail-fast: true + matrix: + lib_type: [ static, shared ] + + steps: + - name: Checkout LAPACK + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 + + - name: Configure CMake + run: > + cmake -B build -G Ninja + -D CMAKE_BUILD_TYPE=Release + -D CMAKE_INSTALL_PREFIX=${{github.workspace}}/lapack_install + -D CBLAS:BOOL=ON + -D LAPACKE:BOOL=ON + -D BUILD_TESTING:BOOL=ON + -D LAPACKE_WITH_TMG:BOOL=ON + -D BUILD_SHARED_LIBS:BOOL=${{ matrix.lib_type == 'shared' && 'ON' || 'OFF' }} + -D BUILD_DEFAULT_API:BOOL=OFF + -D BUILD_INDEX64_EXT_API:BOOL=ON + + - name: Build + run: cmake --build build -j2 + + - name: Test + working-directory: ${{github.workspace}}/build + run: ctest --schedule-random -j2 --output-on-failure --timeout 100 + + - name: Upload test results + id: upload-test-results + if: ${{ !cancelled() }} + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: test-results-extended-api-${{ matrix.lib_type }} + path: | + build/TESTING/testing_results.txt + build/lapack_testing_junit.xml + if-no-files-found: warn + retention-days: 14 + + - name: Write test summary + if: ${{ !cancelled() }} + env: + ARTIFACT_URL: ${{ steps.upload-test-results.outputs.artifact-url }} + run: | + cd build 2>/dev/null || exit 0 + python3 lapack_testing.py -d TESTING --merge-apis --markdown summary.md || true + if [ -f summary.md ]; then + cat summary.md >> "$GITHUB_STEP_SUMMARY" + if [ -n "$ARTIFACT_URL" ]; then + printf '\nThe raw output of every test run (`testing_results.txt`) and a JUnit XML report are in the [test-results artifact](%s).\n' "$ARTIFACT_URL" >> "$GITHUB_STEP_SUMMARY" + fi + fi + + - name: Install + run: cmake --build build --target install -j2 + + cblas-lapacke-without-fortran-compiler: + runs-on: ubuntu-24.04 + + strategy: + fail-fast: true + matrix: + lib_type: [ static, shared ] + + steps: + - name: Checkout LAPACK + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 + + - name: Install LAPACK and BLAS, remove gfortran + run: | + sudo apt update + sudo apt install -y liblapack-dev libblas-dev + sudo apt purge gfortran + + - name: Configure CMake + run: > + cmake -B build -G Ninja + -D CMAKE_BUILD_TYPE=Release + -D CMAKE_INSTALL_PREFIX=${{github.workspace}}/lapack_install + -D CBLAS:BOOL=ON + -D LAPACKE:BOOL=ON + -D USE_OPTIMIZED_BLAS:BOOL=ON + -D USE_OPTIMIZED_LAPACK:BOOL=ON + -D BUILD_TESTING:BOOL=OFF + -D LAPACKE_WITH_TMG:BOOL=OFF + -D BUILD_SHARED_LIBS:BOOL=${{ matrix.lib_type == 'shared' && 'ON' || 'OFF' }} + + - name: Build + run: cmake --build build -j2 + + - name: Install + run: cmake --build build --target install -j2 + + memory-check: + runs-on: ubuntu-24.04 + + steps: + - name: Checkout LAPACK + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 + + - name: Install APT packages + run: | + sudo apt update + sudo apt install -y valgrind + + - name: Configure CMake + run: > + cmake -B build -G Ninja + -D CMAKE_BUILD_TYPE=Debug + -D CBLAS:BOOL=ON + -D LAPACKE:BOOL=ON + -D BUILD_TESTING:BOOL=ON + -D LAPACKE_WITH_TMG:BOOL=ON + -D BUILD_SHARED_LIBS:BOOL=ON + -D LAPACK_TESTING_USE_PYTHON:BOOL=OFF + + - name: Build + run: cmake --build build -j2 + + - name: Test + working-directory: ${{github.workspace}}/build + run: | + ctest --output-on-failure --schedule-random -j2 -T memcheck > memcheck.out + cat memcheck.out + if tail -n 1 memcheck.out | grep -q "Memory checking results:"; then + exit 0 + else + for f in Testing/Temporary/MemoryChecker.*.log; do + if tail -n 1 $f | grep -q "ERROR SUMMARY: 0 errors"; then + tail -n 1 $f + continue + else + echo "Memory check failed in $f" + cat $f + exit 1 + fi + done + exit 0 + fi