diff --git a/.github/workflows/test_t8code_macos.yml b/.github/workflows/test_t8code_macos.yml new file mode 100644 index 0000000000..9a9693f4a7 --- /dev/null +++ b/.github/workflows/test_t8code_macos.yml @@ -0,0 +1,168 @@ +name: CMake tests t8code on Mac OS + + +# This file is part of t8code. +# t8code is a C library to manage a collection (a forest) of multiple +# connected adaptive space-trees of general element types in parallel. +# +# Copyright (C) 2026 the developers +# +# t8code is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# t8code is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with t8code; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +# This workflow checks whether building and testing works on Mac OS. +# In the past, this meant that Mac-OS-specific problems in t8code became +# apparrent only in Trixi and T8Code.jl, where they are very hard and +# cumbersome to debug. This workflow is intended to avoid that by catching +# such problems as early as possible, i.e., within t8code's CI. +# not just all of t8code's remaining CI workflows rely +# To reduce runtime, (for now) only one configuration is run, that is, Debug mode +# with MPI and all external libraries (VTK, OpenCASCADE). + +env: + DEBUG_CONFIG: "-O1" + +on: + workflow_call: + # Note: To simplify adding more configurations of this workflow later, the MPI mode and the BUILD_TYPE + # are passed as input, although currently only MPI on and Debug mode are tested. + inputs: + MAKEFLAGS: + required: true + type: string + description: 'Make flags to use for compilation (like -j4)' + MPI: + required: true + type: string + description: 'Use MPI for compilation (ON/OFF)' + BUILD_TYPE: + required: true + type: string + description: 'Build type (Release/Debug)' + TEST_LEVEL: + required: true + type: string + description: 'Test level used for configuring (T8_TEST_LEVEL_FULL, T8_TEST_LEVEL_MEDIUM, or T8_TEST_LEVEL_BASIC)' + default: 'T8_TEST_LEVEL_FULL' + +jobs: + t8code_cmake_tests: + # + # Container setup: To avoid unwanted side effects of gcc or mpich, an own Clang version of the + # t8-dependencies Docker image is used. Aside from some basic packages, it contains a manually built + # Clang version of OpenMPI. + timeout-minutes: 60 + runs-on: macos-latest + steps: + # + # Part 1: Preparation + # ------------------------------------- + - uses: actions/checkout@v6 + with: + fetch-depth: 0 + - name: Update packages + run: brew update + - name: Install missing packages via Homebrew + run: brew install open-mpi ninja cmake googletest openssl + - name: Show Clang version + run: clang --version + - name: Show mpicc version + run: mpicc --version + + # - name: disable ownership checks + # run: git config --global --add safe.directory '*' + - name: init submodules + run: git submodule init + - name: update submodules + run: git submodule update + - name: Get input vars + run: export MAKEFLAGS="${{ inputs.MAKEFLAGS }}" + && export MPI="${{ inputs.MPI }}" + && export BUILD_TYPE="${{ inputs.BUILD_TYPE }}" + && echo MAKEFLAGS="$MAKEFLAGS" >> $GITHUB_ENV + && echo MPI="$MPI" >> $GITHUB_ENV + && echo BUILD_TYPE="$BUILD_TYPE" >> $GITHUB_ENV + # + # Part 2: Build t8code + # -------------------- + # Define build config + - name: Set test level + run: export TEST_LEVEL_FLAG="-DT8CODE_TEST_LEVEL=${{ inputs.TEST_LEVEL }}" + && echo TEST_LEVEL_FLAG="$TEST_LEVEL_FLAG" >> $GITHUB_ENV + - name: build config variables + run: | + export CONFIG_OPTIONS="-DCMAKE_C_COMPILER=mpicc -DCMAKE_CXX_COMPILER=mpicxx -GNinja -DCMAKE_INSTALL_PREFIX=$(pwd)/install \\ + -DT8CODE_ENABLE_MPI=$MPI -DCMAKE_BUILD_TYPE=$BUILD_TYPE ${TEST_LEVEL_FLAG} -DCMAKE_C_FLAGS_DEBUG=${DEBUG_CONFIG} -DCMAKE_CXX_FLAGS_DEBUG=${DEBUG_CONFIG} \ + -DT8CODE_BUILD_PEDANTIC=ON -DT8CODE_BUILD_WALL=ON -DT8CODE_BUILD_WERROR=OFF -DT8CODE_BUILD_WEXTRA=ON \ + -DT8CODE_BUILD_FORTRAN_INTERFACE=OFF -DT8CODE_BUILD_MESH_HANDLE=ON \ + -DT8CODE_ENABLE_OCC=OFF -DT8CODE_ENABLE_VTK=OFF" + echo CONFIG_OPTIONS="$CONFIG_OPTIONS" >> $GITHUB_ENV + # - name: build config variables + # run: | + # export CONFIG_OPTIONS="-DCMAKE_C_COMPILER=mpicc -DCMAKE_CXX_COMPILER=mpicxx -DCMAKE_Fortran_COMPILER=mpifort -GNinja \ + # -DT8CODE_ENABLE_MPI=$MPI -DCMAKE_BUILD_TYPE=$BUILD_TYPE ${TEST_LEVEL_FLAG} -DCMAKE_C_FLAGS_DEBUG=${DEBUG_CONFIG} -DCMAKE_CXX_FLAGS_DEBUG=${DEBUG_CONFIG} \ + # -DT8CODE_BUILD_PEDANTIC=ON -DT8CODE_BUILD_WALL=ON -DT8CODE_BUILD_WERROR=ON -DT8CODE_BUILD_WEXTRA=ON \ + # -DT8CODE_BUILD_FORTRAN_INTERFACE=ON -DT8CODE_BUILD_MESH_HANDLE=ON \ + # -DT8CODE_ENABLE_OCC=ON -DT8CODE_ENABLE_VTK=ON -DVTK_DIR=$VTK_INSTALL_PATH/lib/cmake/vtk-9.1" + # echo CONFIG_OPTIONS="$CONFIG_OPTIONS" >> $GITHUB_ENV + # Run cmake + - name: echo cmake line + run: echo cmake ../ $CONFIG_OPTIONS + - name: cmake + run: mkdir build && cd build && cmake ../ $CONFIG_OPTIONS + # On failure, upload logs + - name: OnFailUploadLog + if: failure() + uses: actions/upload-artifact@v7 + with: + name: cmake_w_clang_and_ompi_${{ inputs.BUILD_TYPE }}_MPI_${{ inputs.MPI }}.log + path: build/CMakeFiles/CMakeOutput.log + # Build with ninja + - name: ninja + run: cd build && ninja $MAKEFLAGS + - name: ninja install + run: cd build && ninja install $MAKEFLAGS + # + # Part 3: Run t8code tests + # ------------------------ + # - name: serial tests (if MPI is enabled) + # run: cd build && ctest $MAKEFLAGS -R _serial + if: ${{ inputs.MPI == 'ON' }} + - name: parallel tests (if MPI is enabled) + run: | + export OMPI_ALLOW_RUN_AS_ROOT=1 + export OMPI_ALLOW_RUN_AS_ROOT_CONFIRM=1 + export OMPI_MCA_btl=self,tcp + export OMPI_MCA_pml=ob1 + export OMPI_MCA_rmaps_base_oversubscribe=1 + cd build && ctest -R _parallel + env: + # Note: These openmpi options are required to ensure stable runs in github workflows and avoid stalling. + # In particular, they activate oversubscription and define the communication channels, here tcp (and self). + OMPI_ALLOW_RUN_AS_ROOT: 1 + OMPI_ALLOW_RUN_AS_ROOT_CONFIRM: 1 + OMPI_MCA_rmaps_base_oversubscribe: 1 + OMPI_MCA_btl: self,tcp + OMPI_MCA_pml: ob1 + if: ${{ inputs.MPI == 'ON' }} + - name: tests (if MPI is disabled) + run: cd build && ctest $MAKEFLAGS + if: ${{ inputs.MPI == 'OFF' }} + # On failure, upload logs + - name: OnFailUploadLog + if: failure() + uses: actions/upload-artifact@v7 + with: + name: test-suite_w_clang_and_ompi_${{ inputs.BUILD_TYPE }}_MPI_${{ inputs.MPI }}.log + path: build/Testing/Temporary/LastTest.log diff --git a/.github/workflows/testsuite.yml b/.github/workflows/testsuite.yml index 631f7f48e8..a054020008 100644 --- a/.github/workflows/testsuite.yml +++ b/.github/workflows/testsuite.yml @@ -106,129 +106,150 @@ jobs: fi # Preparation step for tests. Repo is cloned and sc + p4est are compiled with and without MPI. - preparation: - needs: [fine_grained_trigger] - secrets: inherit - if: needs.fine_grained_trigger.outputs.run_ci == 'true' - uses: ./.github/workflows/test_preparation.yml - strategy: - fail-fast: false - matrix: - MPI: [OFF, ON] - include: - - MAKEFLAGS: -j4 - with: - MAKEFLAGS: ${{ matrix.MAKEFLAGS }} - IGNORE_CACHE: false # Use this to force a new installation of sc and p4est for this specific workflow run - CACHE_COUNTER: 0 # Increase this number to force a new installation of sc and p4est and to update the cache once - MPI: ${{ matrix.MPI }} + # preparation: + # needs: [fine_grained_trigger] + # secrets: inherit + # if: needs.fine_grained_trigger.outputs.run_ci == 'true' + # uses: ./.github/workflows/test_preparation.yml + # strategy: + # fail-fast: false + # matrix: + # MPI: [OFF, ON] + # include: + # - MAKEFLAGS: -j4 + # with: + # MAKEFLAGS: ${{ matrix.MAKEFLAGS }} + # IGNORE_CACHE: false # Use this to force a new installation of sc and p4est for this specific workflow run + # CACHE_COUNTER: 0 # Increase this number to force a new installation of sc and p4est and to update the cache once + # MPI: ${{ matrix.MPI }} - # Run parallel tests for sc and p4est with and without MPI - sc_p4est_tests: - needs: preparation - uses: ./.github/workflows/test_sc_p4est.yml - strategy: - fail-fast: false - matrix: - MPI: [OFF, ON] - include: - - MAKEFLAGS: -j4 - with: - MAKEFLAGS: ${{ matrix.MAKEFLAGS }} - MPI: ${{ matrix.MPI }} + # # Run parallel tests for sc and p4est with and without MPI + # sc_p4est_tests: + # needs: preparation + # uses: ./.github/workflows/test_sc_p4est.yml + # strategy: + # fail-fast: false + # matrix: + # MPI: [OFF, ON] + # include: + # - MAKEFLAGS: -j4 + # with: + # MAKEFLAGS: ${{ matrix.MAKEFLAGS }} + # MPI: ${{ matrix.MPI }} - # Run t8code tests with and without MPI and in serial and debug mode - t8code_tests: - needs: preparation - uses: ./.github/workflows/test_t8code.yml - strategy: - fail-fast: false - matrix: - MPI: [OFF, ON] - BUILD_TYPE: [Debug, Release] - include: - - MAKEFLAGS: -j4 - with: - MAKEFLAGS: ${{ matrix.MAKEFLAGS }} - MPI: ${{ matrix.MPI }} - BUILD_TYPE: ${{ matrix.BUILD_TYPE }} - TEST_LEVEL: ${{ github.event_name == 'pull_request' && 'T8_TEST_LEVEL_MEDIUM' || 'T8_TEST_LEVEL_FULL' }} # Set TEST_LEVEL to medium if the event is a PR, otherwise full. + # # Run t8code tests with and without MPI and in serial and debug mode + # t8code_tests: + # needs: preparation + # uses: ./.github/workflows/test_t8code.yml + # strategy: + # fail-fast: false + # matrix: + # MPI: [OFF, ON] + # BUILD_TYPE: [Debug, Release] + # include: + # - MAKEFLAGS: -j4 + # with: + # MAKEFLAGS: ${{ matrix.MAKEFLAGS }} + # MPI: ${{ matrix.MPI }} + # BUILD_TYPE: ${{ matrix.BUILD_TYPE }} + # TEST_LEVEL: ${{ github.event_name == 'pull_request' && 'T8_TEST_LEVEL_MEDIUM' || 'T8_TEST_LEVEL_FULL' }} # Set TEST_LEVEL to medium if the event is a PR, otherwise full. - # Run t8code linkage tests with and without MPI and in serial and debug mode - t8code_linkage_tests: - needs: preparation - uses: ./.github/workflows/test_t8code_linkage.yml - strategy: - fail-fast: false - matrix: - MPI: [OFF, ON] - BUILD_TYPE: [Debug, Release] - include: - - MAKEFLAGS: -j4 - with: - MAKEFLAGS: ${{ matrix.MAKEFLAGS }} - MPI: ${{ matrix.MPI }} - BUILD_TYPE: ${{ matrix.BUILD_TYPE }} - TEST_LEVEL: ${{ github.event_name == 'pull_request' && 'T8_TEST_LEVEL_MEDIUM' || 'T8_TEST_LEVEL_FULL' }} # Set TEST_LEVEL to medium if the event is a PR, otherwise full. + # # Run t8code linkage tests with and without MPI and in serial and debug mode + # t8code_linkage_tests: + # needs: preparation + # uses: ./.github/workflows/test_t8code_linkage.yml + # strategy: + # fail-fast: false + # matrix: + # MPI: [OFF, ON] + # BUILD_TYPE: [Debug, Release] + # include: + # - MAKEFLAGS: -j4 + # with: + # MAKEFLAGS: ${{ matrix.MAKEFLAGS }} + # MPI: ${{ matrix.MPI }} + # BUILD_TYPE: ${{ matrix.BUILD_TYPE }} + # TEST_LEVEL: ${{ github.event_name == 'pull_request' && 'T8_TEST_LEVEL_MEDIUM' || 'T8_TEST_LEVEL_FULL' }} # Set TEST_LEVEL to medium if the event is a PR, otherwise full. - # Run t8code linkage tests with and without MPI and in serial and debug mode - t8code_api_tests: - needs: preparation - uses: ./.github/workflows/test_t8code_api.yml - strategy: - fail-fast: false - matrix: - MPI: [ON] # For now the fortran API only supports building with MPI - BUILD_TYPE: [Debug, Release] - include: - - MAKEFLAGS: -j4 - with: - MAKEFLAGS: ${{ matrix.MAKEFLAGS }} - MPI: ${{ matrix.MPI }} - BUILD_TYPE: ${{ matrix.BUILD_TYPE }} - TEST_LEVEL: ${{ github.event_name == 'pull_request' && 'T8_TEST_LEVEL_MEDIUM' || 'T8_TEST_LEVEL_FULL' }} # Set TEST_LEVEL to medium if the event is a PR, otherwise full. + # # Run t8code linkage tests with and without MPI and in serial and debug mode + # t8code_api_tests: + # needs: preparation + # uses: ./.github/workflows/test_t8code_api.yml + # strategy: + # fail-fast: false + # matrix: + # MPI: [ON] # For now the fortran API only supports building with MPI + # BUILD_TYPE: [Debug, Release] + # include: + # - MAKEFLAGS: -j4 + # with: + # MAKEFLAGS: ${{ matrix.MAKEFLAGS }} + # MPI: ${{ matrix.MPI }} + # BUILD_TYPE: ${{ matrix.BUILD_TYPE }} + # TEST_LEVEL: ${{ github.event_name == 'pull_request' && 'T8_TEST_LEVEL_MEDIUM' || 'T8_TEST_LEVEL_FULL' }} # Set TEST_LEVEL to medium if the event is a PR, otherwise full. - # Run Valgrind check for every t8code test binary. - t8code_valgrind_tests: - if: (github.event_name == 'schedule' && github.repository == 'DLR-AMR/t8code') # Only run the Valgrind check in the scheduled run. - needs: preparation - uses: ./.github/workflows/test_valgrind.yml - with: - TEST_LEVEL: T8_TEST_LEVEL_BASIC # Do Valgrind check for test level T8_TEST_LEVEL_BASIC for performance reasons. + # # Run Valgrind check for every t8code test binary. + # t8code_valgrind_tests: + # if: (github.event_name == 'schedule' && github.repository == 'DLR-AMR/t8code') # Only run the Valgrind check in the scheduled run. + # needs: preparation + # uses: ./.github/workflows/test_valgrind.yml + # with: + # TEST_LEVEL: T8_TEST_LEVEL_BASIC # Do Valgrind check for test level T8_TEST_LEVEL_BASIC for performance reasons. - # Generate code coverage and deploy to Codecov. - t8code_code_coverage: - if: (github.event_name != 'merge_group') - needs: preparation - uses: ./.github/workflows/code_coverage.yml - with: - MAKEFLAGS: -j4 - MPI: ON - BUILD_TYPE: Debug - TEST_LEVEL: T8_TEST_LEVEL_BASIC - secrets: - CODE_COV: ${{ secrets.CODE_COV }} - - # Run t8code tests with shipped submodules. This test is only for the build system, so only one config is tested. - t8code_w_shipped_submodules_tests: - needs: fine_grained_trigger - secrets: inherit - if: ${{ needs.fine_grained_trigger.outputs.run_ci == 'true' }} - uses: ./.github/workflows/test_t8code_w_shipped_submodules.yml - with: - MAKEFLAGS: -j4 - MPI: ON - BUILD_TYPE: Debug - TEST_LEVEL: ${{ github.event_name == 'pull_request' && 'T8_TEST_LEVEL_MEDIUM' || 'T8_TEST_LEVEL_FULL' }} # Set TEST_LEVEL to medium if the event is a PR, otherwise full. + # # Generate code coverage and deploy to Codecov. + # t8code_code_coverage: + # if: (github.event_name != 'merge_group') + # needs: preparation + # uses: ./.github/workflows/code_coverage.yml + # with: + # MAKEFLAGS: -j4 + # MPI: ON + # BUILD_TYPE: Debug + # TEST_LEVEL: T8_TEST_LEVEL_BASIC + # secrets: + # CODE_COV: ${{ secrets.CODE_COV }} + + # # Run t8code tests with shipped submodules. This test is only for the build system, so only one config is tested. + # t8code_w_shipped_submodules_tests: + # needs: fine_grained_trigger + # secrets: inherit + # if: ${{ needs.fine_grained_trigger.outputs.run_ci == 'true' }} + # uses: ./.github/workflows/test_t8code_w_shipped_submodules.yml + # with: + # MAKEFLAGS: -j4 + # MPI: ON + # BUILD_TYPE: Debug + # TEST_LEVEL: ${{ github.event_name == 'pull_request' && 'T8_TEST_LEVEL_MEDIUM' || 'T8_TEST_LEVEL_FULL' }} # Set TEST_LEVEL to medium if the event is a PR, otherwise full. + + # # Check t8code building and testing with the Clang compiler and openmpi. + # # Note: This workflow is meant to detect Clang- or openmpi-specific issues missed by the remaining (gcc- and mpich-based) workflows. + # # To reduce its runtime, it currently only uses one run in Debug mode with MPI activated and all external libraries like VTK or OpenCASCADE. + # t8code_w_clang_and_ompi_tests: + # needs: fine_grained_trigger + # secrets: inherit + # if: ${{ needs.fine_grained_trigger.outputs.run_ci == 'true' }} + # uses: ./.github/workflows/test_t8code_w_clang_and_ompi.yml + # strategy: + # fail-fast: false + # matrix: + # MPI: [ON] + # BUILD_TYPE: [Debug] + # include: + # - MAKEFLAGS: -j4 + # with: + # MAKEFLAGS: ${{ matrix.MAKEFLAGS }} + # MPI: ${{ matrix.MPI }} + # BUILD_TYPE: ${{ matrix.BUILD_TYPE }} + # TEST_LEVEL: ${{ github.event_name == 'pull_request' && 'T8_TEST_LEVEL_MEDIUM' || 'T8_TEST_LEVEL_FULL' }} # Set TEST_LEVEL to medium if the event is a PR, otherwise full. # Check t8code building and testing with the Clang compiler and openmpi. # Note: This workflow is meant to detect Clang- or openmpi-specific issues missed by the remaining (gcc- and mpich-based) workflows. # To reduce its runtime, it currently only uses one run in Debug mode with MPI activated and all external libraries like VTK or OpenCASCADE. - t8code_w_clang_and_ompi_tests: + t8code_macos_tests: needs: fine_grained_trigger secrets: inherit if: ${{ needs.fine_grained_trigger.outputs.run_ci == 'true' }} - uses: ./.github/workflows/test_t8code_w_clang_and_ompi.yml + uses: ./.github/workflows/test_t8code_macos.yml strategy: fail-fast: false matrix: @@ -242,12 +263,14 @@ jobs: BUILD_TYPE: ${{ matrix.BUILD_TYPE }} TEST_LEVEL: ${{ github.event_name == 'pull_request' && 'T8_TEST_LEVEL_MEDIUM' || 'T8_TEST_LEVEL_FULL' }} # Set TEST_LEVEL to medium if the event is a PR, otherwise full. - # Build doxygen documentation and check for errors / warnings. - t8code_doxygen_check: - uses: ./.github/workflows/check_doxygen.yml - t8code_tarball: - if: github.event.pull_request.draft == false - uses: ./.github/workflows/test_tarball.yml - with: - TEST_LEVEL: ${{ github.event_name == 'pull_request' && 'T8_TEST_LEVEL_MEDIUM' || 'T8_TEST_LEVEL_FULL' }} # Set TEST_LEVEL to medium if the event is a PR, otherwise full. + + # # Build doxygen documentation and check for errors / warnings. + # t8code_doxygen_check: + # uses: ./.github/workflows/check_doxygen.yml + + # t8code_tarball: + # if: github.event.pull_request.draft == false + # uses: ./.github/workflows/test_tarball.yml + # with: + # TEST_LEVEL: ${{ github.event_name == 'pull_request' && 'T8_TEST_LEVEL_MEDIUM' || 'T8_TEST_LEVEL_FULL' }} # Set TEST_LEVEL to medium if the event is a PR, otherwise full.