From d3aa85bf4096d01850e213168fad4316e006e746 Mon Sep 17 00:00:00 2001 From: "Joshua A. Anderson" Date: Wed, 5 Jun 2024 12:55:12 -0400 Subject: [PATCH 01/32] Disable existing test workflow. --- .github/workflows/test.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4d4ed74f3a..4c7088d037 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,14 +7,14 @@ concurrency: cancel-in-progress: true on: - pull_request: - types: [opened, labeled, reopened, synchronize] - - # Trigger on pushes to the trunk branches. This prevents building commits twice when the pull - # request source branch is in the same repository. - push: - branches: - - "trunk-*" + # pull_request: + # types: [opened, labeled, reopened, synchronize] + + # # Trigger on pushes to the trunk branches. This prevents building commits twice when the pull + # # request source branch is in the same repository. + # push: + # branches: + # - "trunk-*" # Trigger on request. workflow_dispatch: From ee0864f27e6f594f7fb13adb88def3bed1329e3d Mon Sep 17 00:00:00 2001 From: "Joshua A. Anderson" Date: Wed, 5 Jun 2024 12:55:48 -0400 Subject: [PATCH 02/32] 1:1 mapping of jinja workflow to reusable workflows Release test configurations have not yet been added. --- .github/workflows/build_and_test.yaml | 268 ++++++++++++++++++++++++++ .github/workflows/tests_new.yaml | 89 +++++++++ 2 files changed, 357 insertions(+) create mode 100644 .github/workflows/build_and_test.yaml create mode 100644 .github/workflows/tests_new.yaml diff --git a/.github/workflows/build_and_test.yaml b/.github/workflows/build_and_test.yaml new file mode 100644 index 0000000000..2793c63d58 --- /dev/null +++ b/.github/workflows/build_and_test.yaml @@ -0,0 +1,268 @@ +name: Build and test + +on: + workflow_call: + inputs: + config: + type: string + required: true + container_prefix: + type: string + required: true + build_runner: + type: string + required: true + default: "[self-hosted,jetstream2,CPU]" + test_runner: + type: string + required: true + default: ubuntu-latest + test_docker_options: + type: string + required: false + validate: + type: boolean + required: false + +env: + # prevent deadlocked MPI tests from causing the job to cancel + MPIEXEC_TIMEOUT: 3000 + # allow mpirun to execute as root in the tests + OMPI_ALLOW_RUN_AS_ROOT: 1 + OMPI_ALLOW_RUN_AS_ROOT_CONFIRM: 1 + # allow openmpi to oversubscribe cores + OMPI_MCA_rmaps_base_oversubscribe: 1 + # prevent errors from mis-configured openib systems + OMPI_MCA_btl: "vader,self" + # skip running the CPU tests in GPU builds + _HOOMD_SKIP_CPU_TESTS_WHEN_GPUS_PRESENT_: 1 + # Require GPU tests in GPU builds. + _HOOMD_REQUIRE_GPU_TESTS_IN_GPU_BUILDS_: 1 + # import HOOMD out of the build directory + PYTHONPATH: ${{ github.workspace }}/install + +jobs: + build: + name: Build [${{ inputs.config }}] + runs-on: ${{fromJson(inputs.build_runner) }} + container: + image: glotzerlab/ci:2024.06.04-${{ inputs.container_prefix }} + + steps: + - name: Set Werror on recent compilers + run: | + echo "CXXFLAGS=-Werror" >> $GITHUB_ENV + - name: Clean workspace + run: ( shopt -s dotglob nullglob; rm -rf ./* ) + shell: bash + - name: Checkout + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + with: + path: code + submodules: true + + - name: Configure + run: | + if [[ ${BUILD_DEBUG} == "true" ]]; then BUILD_TYPE="Debug"; else BUILD_TYPE="Release"; fi + echo "BUILD_TYPE=${BUILD_TYPE}" + cmake -S code -B build -GNinja \ + -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \ + -DENABLE_GPU=${ENABLE_GPU:-"OFF"} \ + -DENABLE_MPI=${ENABLE_MPI:-"OFF"} \ + -DENABLE_TBB=${ENABLE_TBB:-"OFF"} \ + -DENABLE_LLVM=${ENABLE_LLVM:-"OFF"} \ + -DBUILD_MD=${BUILD_MD:-"ON"} \ + -DBUILD_MPCD=${BUILD_MD:-"ON"} \ + -DBUILD_METAL=${BUILD_MD:-"ON"} \ + -DBUILD_HPMC=${BUILD_HPMC:-"ON"} \ + -DCUDA_ARCH_LIST="60;70" \ + -DENABLE_DEBUG_JIT=ON \ + -DCMAKE_INSTALL_PREFIX=${GITHUB_WORKSPACE}/install \ + -DPLUGINS="" + env: + ENABLE_GPU: ${{ contains(inputs.config, 'cuda') }} + ENABLE_MPI: ${{ contains(inputs.config, 'mpi') }} + ENABLE_TBB: ${{ contains(inputs.config, 'tbb') }} + ENABLE_LLVM: ${{ contains(inputs.config, 'llvm') }} + BUILD_MD: ${{ !contains(inputs.config, 'nomd') }} + BUILD_HPMC: ${{ !contains(inputs.config, 'nohpmc') }} + BUILD_DEBUG: ${{ contains(inputs.config, 'debug') }} + shell: bash + - name: Build + run: ninja install -j $(($(getconf _NPROCESSORS_ONLN) + 2)) + working-directory: build + - name: Configure plugins + run : | + mkdir -p build-example-plugins + cd build-example-plugins + if [[ ${BUILD_DEBUG} == "true" ]]; then BUILD_TYPE="Debug"; else BUILD_TYPE="Release"; fi + echo "BUILD_TYPE=${BUILD_TYPE}" + CMAKE_PREFIX_PATH=${GITHUB_WORKSPACE}/install cmake -S code/example_plugins -B build-example-plugins -GNinja -DCMAKE_BUILD_TYPE=${BUILD_TYPE} + env: + BUILD_DEBUG: ${{ contains(inputs.config, 'debug') }} + shell: bash + - name: Build plugins + run: ninja install -j $(($(getconf _NPROCESSORS_ONLN) + 2)) + working-directory: build-example-plugins + + - name: Remove object files + run: find build -type f -name '*.o' -delete + - name: 'Tar build' + run: tar --use-compress-program='zstd -10 -T0' -cvf build.tar build + - name: 'Tar install' + run: tar --use-compress-program='zstd -10 -T0' -cvf install.tar install + - name: 'Upload build' + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + with: + name: build-${{ inputs.config }}-${{ github.sha }} + path: build.tar + retention-days: 7 + - name: 'Upload install' + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + with: + name: install-${{ inputs.config }}-${{ github.sha }} + path: install.tar + retention-days: 7 + + - name: Clean workspace + run: ( shopt -s dotglob nullglob; rm -rf ./* ) + shell: bash + - name: Clean HOME + run: ( shopt -s dotglob nullglob; rm -rf $HOME/* ) + shell: bash + + + pytest: + name: Run pytest [${{ inputs.config }}] + needs: build + runs-on: ${{ fromJson(inputs.test_runner) }} + container: + image: glotzerlab/ci:2024.06.04-${{ inputs.container_prefix }} + options: ${{ inputs.test_docker_options }} -e CUDA_VISIBLE_DEVICES + + steps: + - name: Clean workspace + run: ( shopt -s dotglob nullglob; rm -rf ./* ) + shell: bash + - name: Checkout + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + with: + path: code + submodules: true + + - name: Download install + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 + with: + name: install-${{ inputs.config }}-${{ github.sha }} + - name: Untar install + run: tar --use-compress-program='zstd -10 -T0' -xvf install.tar + + - name: Run pytest (serial) + run: python3 -m pytest --pyargs hoomd -x -v -ra --durations=0 --durations-min=0.1 + - name: Run pytest (mpi) + if: ${{ contains(inputs.config, 'mpi') }} + run: mpirun -n 2 ${GITHUB_WORKSPACE}/install/hoomd/pytest/pytest-openmpi.sh --pyargs hoomd -x -v -ra --durations=0 --durations-min=0.1 || (( cat pytest.out.1 && exit 1 )) + - name: Run pytest (serial without cupy) + if: ${{ contains(inputs.config, 'cuda') }} + run: python3 -m pytest --pyargs hoomd -x -v -ra --durations=0 --durations-min=0.1 -m cupy_optional + env: + _HOOMD_DISALLOW_CUPY_: 1 + - name: Run pytest (mpi without cupy) + if: ${{ contains(inputs.config, 'cuda') && contains(inputs.config, 'mpi') }} + run: mpirun -n 2 ${GITHUB_WORKSPACE}/install/hoomd/pytest/pytest-openmpi.sh --pyargs hoomd -x -v -ra --durations=0 --durations-min=0.1 -m cupy_optional || (( cat pytest.out.1 && exit 1 )) + env: + _HOOMD_DISALLOW_CUPY_: 1 + + - name: Clean workspace + run: ( shopt -s dotglob nullglob; rm -rf ./* ) + shell: bash + - name: Clean HOME + run: ( shopt -s dotglob nullglob; rm -rf $HOME/* ) + shell: bash + + + ctest: + name: Run ctest [${{ inputs.config }}] + needs: build + runs-on: ${{ fromJson(inputs.test_runner) }} + container: + image: glotzerlab/ci:2024.06.04-${{ inputs.container_prefix }} + options: ${{ inputs.test_docker_options }} -e CUDA_VISIBLE_DEVICES + + steps: + - name: Clean workspace + run: ( shopt -s dotglob nullglob; rm -rf ./* ) + shell: bash + - name: Checkout + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + with: + path: code + submodules: true + + - name: Download build + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 + with: + name: build-${{ inputs.config }}-${{ github.sha }} + - name: Untar build + run: tar --use-compress-program='zstd -10 -T0' -xvf build.tar + + - name: Run tests + run: >- + ctest + -T test + --output-on-failure + --test-output-size-failed 1048576 + --test-output-size-passed 1048576 + working-directory: build + + - name: Clean workspace + run: ( shopt -s dotglob nullglob; rm -rf ./* ) + shell: bash + - name: Clean HOME + run: ( shopt -s dotglob nullglob; rm -rf $HOME/* ) + shell: bash + + + validate: + name: Validate [${{ inputs.config }}] + needs: build + runs-on: ${{ fromJson(inputs.test_runner) }} + container: + image: glotzerlab/ci:2024.06.04-${{ inputs.container_prefix }} + options: ${{ inputs.test_docker_options }} -e CUDA_VISIBLE_DEVICES + + if: ${{ contains(github.event.pull_request.labels.*.name, 'validate') && inputs.validate }} + steps: + - name: Clean workspace + run: ( shopt -s dotglob nullglob; rm -rf ./* ) + shell: bash + - name: Checkout + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + with: + path: code + submodules: true + + - name: Download install + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 + with: + name: install-${{ inputs.config }}-${{ github.sha }} + - name: Untar install + run: tar --use-compress-program='zstd -10 -T0' -xvf install.tar + + - name: Run pytest (serial) + if: ${{ !contains(inputs.config, 'mpi') }} + run: python3 -m pytest --pyargs hoomd -x -v -ra --durations=0 --durations-min=0.1 -p hoomd.pytest_plugin_validate -m validate --validate + - name: Run pytest (mpi) + if: ${{ contains(inputs.config, 'mpi') }} + run: mpirun -n 2 ${GITHUB_WORKSPACE}/install/hoomd/pytest/pytest-openmpi.sh --pyargs hoomd -x -v -ra --durations=0 --durations-min=0.1 -p hoomd.pytest_plugin_validate -m validate --validate || (( cat pytest.out.1 && exit 1 )) + - name: Run howto guides (serial) + if: ${{ contains(inputs.config, 'llvm') }} # some examples require LLVM + run: 'for i in *.py; do echo "Running howto: $i" && python3 $i || exit 1; done' + working-directory: code/sphinx-doc/howto + + - name: Clean workspace + run: ( shopt -s dotglob nullglob; rm -rf ./* ) + shell: bash + - name: Clean HOME + run: ( shopt -s dotglob nullglob; rm -rf $HOME/* ) + shell: bash diff --git a/.github/workflows/tests_new.yaml b/.github/workflows/tests_new.yaml new file mode 100644 index 0000000000..06e57f34ca --- /dev/null +++ b/.github/workflows/tests_new.yaml @@ -0,0 +1,89 @@ +name: Tests (new) + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +on: + pull_request: + types: [opened, labeled, reopened, synchronize] + + push: + branches: + - "trunk-*" + + workflow_dispatch: + +jobs: + start_action_runners: + name: Start action runners + runs-on: ubuntu-latest + steps: + - name: Use jetstream2-admin/start + uses: glotzerlab/jetstream2-admin/start@v1.2.5 + with: + OS_APPLICATION_CREDENTIAL_ID: ${{ secrets.OS_APPLICATION_CREDENTIAL_ID }} + OS_APPLICATION_CREDENTIAL_SECRET: ${{ secrets.OS_APPLICATION_CREDENTIAL_SECRET }} + + typical: + name: Build and test typical configurations + uses: ./.github/workflows/build_and_test.yaml + with: + config: ${{ join(matrix.config, '_') }} + container_prefix: ${{ matrix.config[0] }} + build_runner: ${{ toJson(matrix.build_runner) }} + test_runner: ${{ toJson(matrix.test_runner) }} + test_docker_options: ${{ matrix.test_docker_options }} + validate: ${{ matrix.validate }} + + strategy: + fail-fast: false + matrix: + include: + - config: [clang14_py311, mpi, tbb, llvm] + build_runner: [self-hosted,jetstream2,CPU] + test_runner: ubuntu-latest + validate: true + + - config: [gcc13_py312] + build_runner: [self-hosted,jetstream2,CPU] + test_runner: ubuntu-latest + validate: true + + - config: [cuda120_gcc11_py310, mpi, llvm] + build_runner: [self-hosted,jetstream2,CPU] + test_runner: [self-hosted,GPU] + test_docker_options: '--gpus=all --device /dev/nvidia0 --device /dev/nvidia1 --device /dev/nvidia-uvm --device /dev/nvidia-uvm-tools --device /dev/nvidiactl' + validate: true + + - config: [cuda120_gcc11_py310] + build_runner: [self-hosted,jetstream2,CPU] + test_runner: [self-hosted,GPU] + test_docker_options: '--gpus=all --device /dev/nvidia0 --device /dev/nvidia1 --device /dev/nvidia-uvm --device /dev/nvidia-uvm-tools --device /dev/nvidiactl' + validate: true + + - config: [gcc13_py312, nomd] + build_runner: [self-hosted,jetstream2,CPU] + test_runner: ubuntu-latest + validate: false + + - config: [gcc13_py312, nohpmc] + build_runner: [self-hosted,jetstream2,CPU] + test_runner: ubuntu-latest + validate: false + + - config: [gcc13_py312, nomd, nohpmc] + build_runner: [self-hosted,jetstream2,CPU] + test_runner: ubuntu-latest + validate: false + + - config: [cuda120_gcc11_py310 mpi, llvm, debug] + build_runner: [self-hosted,jetstream2,CPU] + test_runner: [self-hosted,GPU] + test_docker_options: '--gpus=all --device /dev/nvidia0 --device /dev/nvidia1 --device /dev/nvidia-uvm --device /dev/nvidia-uvm-tools --device /dev/nvidiactl' + validate: false + + - config: [gcc9_py39] + build_runner: [self-hosted,jetstream2,CPU] + test_runner: ubuntu-latest + validate: false From e867cd033e6d9266bbcc0935a77862b6f065a4dd Mon Sep 17 00:00:00 2001 From: "Joshua A. Anderson" Date: Wed, 5 Jun 2024 14:07:39 -0400 Subject: [PATCH 03/32] Test on GitHub provided runners for now. --- .github/workflows/build_and_test.yaml | 10 +++++++--- .github/workflows/tests_new.yaml | 12 ++++++------ 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build_and_test.yaml b/.github/workflows/build_and_test.yaml index 2793c63d58..758175f7cc 100644 --- a/.github/workflows/build_and_test.yaml +++ b/.github/workflows/build_and_test.yaml @@ -23,7 +23,7 @@ on: validate: type: boolean required: false - + env: # prevent deadlocked MPI tests from causing the job to cancel MPIEXEC_TIMEOUT: 3000 @@ -88,29 +88,33 @@ jobs: BUILD_HPMC: ${{ !contains(inputs.config, 'nohpmc') }} BUILD_DEBUG: ${{ contains(inputs.config, 'debug') }} shell: bash + - name: Build run: ninja install -j $(($(getconf _NPROCESSORS_ONLN) + 2)) working-directory: build + - name: Configure plugins run : | - mkdir -p build-example-plugins - cd build-example-plugins if [[ ${BUILD_DEBUG} == "true" ]]; then BUILD_TYPE="Debug"; else BUILD_TYPE="Release"; fi echo "BUILD_TYPE=${BUILD_TYPE}" CMAKE_PREFIX_PATH=${GITHUB_WORKSPACE}/install cmake -S code/example_plugins -B build-example-plugins -GNinja -DCMAKE_BUILD_TYPE=${BUILD_TYPE} env: BUILD_DEBUG: ${{ contains(inputs.config, 'debug') }} shell: bash + - name: Build plugins run: ninja install -j $(($(getconf _NPROCESSORS_ONLN) + 2)) working-directory: build-example-plugins - name: Remove object files run: find build -type f -name '*.o' -delete + - name: 'Tar build' run: tar --use-compress-program='zstd -10 -T0' -cvf build.tar build + - name: 'Tar install' run: tar --use-compress-program='zstd -10 -T0' -cvf install.tar install + - name: 'Upload build' uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 with: diff --git a/.github/workflows/tests_new.yaml b/.github/workflows/tests_new.yaml index 06e57f34ca..453db46b54 100644 --- a/.github/workflows/tests_new.yaml +++ b/.github/workflows/tests_new.yaml @@ -55,18 +55,18 @@ jobs: test_runner: [self-hosted,GPU] test_docker_options: '--gpus=all --device /dev/nvidia0 --device /dev/nvidia1 --device /dev/nvidia-uvm --device /dev/nvidia-uvm-tools --device /dev/nvidiactl' validate: true - + - config: [cuda120_gcc11_py310] build_runner: [self-hosted,jetstream2,CPU] test_runner: [self-hosted,GPU] test_docker_options: '--gpus=all --device /dev/nvidia0 --device /dev/nvidia1 --device /dev/nvidia-uvm --device /dev/nvidia-uvm-tools --device /dev/nvidiactl' validate: true - + - config: [gcc13_py312, nomd] build_runner: [self-hosted,jetstream2,CPU] test_runner: ubuntu-latest validate: false - + - config: [gcc13_py312, nohpmc] build_runner: [self-hosted,jetstream2,CPU] test_runner: ubuntu-latest @@ -76,13 +76,13 @@ jobs: build_runner: [self-hosted,jetstream2,CPU] test_runner: ubuntu-latest validate: false - - - config: [cuda120_gcc11_py310 mpi, llvm, debug] + + - config: [cuda120_gcc11_py310, mpi, llvm, debug] build_runner: [self-hosted,jetstream2,CPU] test_runner: [self-hosted,GPU] test_docker_options: '--gpus=all --device /dev/nvidia0 --device /dev/nvidia1 --device /dev/nvidia-uvm --device /dev/nvidia-uvm-tools --device /dev/nvidiactl' validate: false - + - config: [gcc9_py39] build_runner: [self-hosted,jetstream2,CPU] test_runner: ubuntu-latest From ce06d81ac72299f56b6daba12c917768c448a6b5 Mon Sep 17 00:00:00 2001 From: "Joshua A. Anderson" Date: Wed, 5 Jun 2024 15:09:51 -0400 Subject: [PATCH 04/32] Attempt to improve job names. --- .github/workflows/build_and_test.yaml | 18 +++++++----------- .github/workflows/tests_new.yaml | 2 +- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/.github/workflows/build_and_test.yaml b/.github/workflows/build_and_test.yaml index 758175f7cc..9cae65f24f 100644 --- a/.github/workflows/build_and_test.yaml +++ b/.github/workflows/build_and_test.yaml @@ -23,7 +23,7 @@ on: validate: type: boolean required: false - + env: # prevent deadlocked MPI tests from causing the job to cancel MPIEXEC_TIMEOUT: 3000 @@ -43,7 +43,6 @@ env: jobs: build: - name: Build [${{ inputs.config }}] runs-on: ${{fromJson(inputs.build_runner) }} container: image: glotzerlab/ci:2024.06.04-${{ inputs.container_prefix }} @@ -88,11 +87,11 @@ jobs: BUILD_HPMC: ${{ !contains(inputs.config, 'nohpmc') }} BUILD_DEBUG: ${{ contains(inputs.config, 'debug') }} shell: bash - + - name: Build run: ninja install -j $(($(getconf _NPROCESSORS_ONLN) + 2)) working-directory: build - + - name: Configure plugins run : | if [[ ${BUILD_DEBUG} == "true" ]]; then BUILD_TYPE="Debug"; else BUILD_TYPE="Release"; fi @@ -101,20 +100,20 @@ jobs: env: BUILD_DEBUG: ${{ contains(inputs.config, 'debug') }} shell: bash - + - name: Build plugins run: ninja install -j $(($(getconf _NPROCESSORS_ONLN) + 2)) working-directory: build-example-plugins - name: Remove object files run: find build -type f -name '*.o' -delete - + - name: 'Tar build' run: tar --use-compress-program='zstd -10 -T0' -cvf build.tar build - + - name: 'Tar install' run: tar --use-compress-program='zstd -10 -T0' -cvf install.tar install - + - name: 'Upload build' uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 with: @@ -137,7 +136,6 @@ jobs: pytest: - name: Run pytest [${{ inputs.config }}] needs: build runs-on: ${{ fromJson(inputs.test_runner) }} container: @@ -186,7 +184,6 @@ jobs: ctest: - name: Run ctest [${{ inputs.config }}] needs: build runs-on: ${{ fromJson(inputs.test_runner) }} container: @@ -228,7 +225,6 @@ jobs: validate: - name: Validate [${{ inputs.config }}] needs: build runs-on: ${{ fromJson(inputs.test_runner) }} container: diff --git a/.github/workflows/tests_new.yaml b/.github/workflows/tests_new.yaml index 453db46b54..546c150baf 100644 --- a/.github/workflows/tests_new.yaml +++ b/.github/workflows/tests_new.yaml @@ -26,7 +26,7 @@ jobs: OS_APPLICATION_CREDENTIAL_SECRET: ${{ secrets.OS_APPLICATION_CREDENTIAL_SECRET }} typical: - name: Build and test typical configurations + name: "${{ join(matrix.config, '_') }}" uses: ./.github/workflows/build_and_test.yaml with: config: ${{ join(matrix.config, '_') }} From 8cf8cb6606b84f5378972286fc382c29e9d41ab2 Mon Sep 17 00:00:00 2001 From: "Joshua A. Anderson" Date: Wed, 5 Jun 2024 15:26:04 -0400 Subject: [PATCH 05/32] Remove duplicate and add release tests. --- .github/workflows/build_and_test.yaml | 6 +-- .github/workflows/test.yml | 2 +- .github/workflows/tests_new.yaml | 70 +++++++++++++++++---------- 3 files changed, 46 insertions(+), 32 deletions(-) diff --git a/.github/workflows/build_and_test.yaml b/.github/workflows/build_and_test.yaml index 9cae65f24f..da2b8cfa4b 100644 --- a/.github/workflows/build_and_test.yaml +++ b/.github/workflows/build_and_test.yaml @@ -9,10 +9,6 @@ on: container_prefix: type: string required: true - build_runner: - type: string - required: true - default: "[self-hosted,jetstream2,CPU]" test_runner: type: string required: true @@ -43,7 +39,7 @@ env: jobs: build: - runs-on: ${{fromJson(inputs.build_runner) }} + runs-on: [self-hosted,jetstream2,CPU] container: image: glotzerlab/ci:2024.06.04-${{ inputs.container_prefix }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4c7088d037..0defdbd3ab 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,4 +1,4 @@ -name: Test +name: Test (old) # Edit the `test.yml` in `.github/workflows/templates` and run `make_workflows.py` to update the # workflow. diff --git a/.github/workflows/tests_new.yaml b/.github/workflows/tests_new.yaml index 546c150baf..a006523261 100644 --- a/.github/workflows/tests_new.yaml +++ b/.github/workflows/tests_new.yaml @@ -1,4 +1,4 @@ -name: Tests (new) +name: Test concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -31,59 +31,77 @@ jobs: with: config: ${{ join(matrix.config, '_') }} container_prefix: ${{ matrix.config[0] }} - build_runner: ${{ toJson(matrix.build_runner) }} - test_runner: ${{ toJson(matrix.test_runner) }} + # Default to ubuntu-latest when unset + test_runner: ${{ matrix.test_runner == '' && 'ubuntu-latest' || toJson(matrix.test_runner) }} test_docker_options: ${{ matrix.test_docker_options }} - validate: ${{ matrix.validate }} + # Default to false when unset + validate: ${{ matrix.validate == '' && false || matrix.validate }} strategy: fail-fast: false matrix: include: - config: [clang14_py311, mpi, tbb, llvm] - build_runner: [self-hosted,jetstream2,CPU] - test_runner: ubuntu-latest validate: true - config: [gcc13_py312] - build_runner: [self-hosted,jetstream2,CPU] - test_runner: ubuntu-latest validate: true - config: [cuda120_gcc11_py310, mpi, llvm] - build_runner: [self-hosted,jetstream2,CPU] test_runner: [self-hosted,GPU] test_docker_options: '--gpus=all --device /dev/nvidia0 --device /dev/nvidia1 --device /dev/nvidia-uvm --device /dev/nvidia-uvm-tools --device /dev/nvidiactl' validate: true - config: [cuda120_gcc11_py310] - build_runner: [self-hosted,jetstream2,CPU] test_runner: [self-hosted,GPU] test_docker_options: '--gpus=all --device /dev/nvidia0 --device /dev/nvidia1 --device /dev/nvidia-uvm --device /dev/nvidia-uvm-tools --device /dev/nvidiactl' validate: true - config: [gcc13_py312, nomd] - build_runner: [self-hosted,jetstream2,CPU] - test_runner: ubuntu-latest - validate: false - + - config: [gcc13_py312, nohpmc] - build_runner: [self-hosted,jetstream2,CPU] - test_runner: ubuntu-latest - validate: false - + - config: [gcc13_py312, nomd, nohpmc] - build_runner: [self-hosted,jetstream2,CPU] - test_runner: ubuntu-latest - validate: false - + - config: [cuda120_gcc11_py310, mpi, llvm, debug] - build_runner: [self-hosted,jetstream2,CPU] test_runner: [self-hosted,GPU] test_docker_options: '--gpus=all --device /dev/nvidia0 --device /dev/nvidia1 --device /dev/nvidia-uvm --device /dev/nvidia-uvm-tools --device /dev/nvidiactl' validate: false - config: [gcc9_py39] - build_runner: [self-hosted,jetstream2,CPU] - test_runner: ubuntu-latest - validate: false + + release: + if: ${{ contains(github.event.pull_request.labels.*.name, 'release') }} + name: "${{ join(matrix.config, '_') }}" + uses: ./.github/workflows/build_and_test.yaml + with: + config: ${{ join(matrix.config, '_') }} + container_prefix: ${{ matrix.config[0] }} + # Default to ubuntu-latest when unset + test_runner: ${{ matrix.test_runner == '' && 'ubuntu-latest' || toJson(matrix.test_runner) }} + test_docker_options: ${{ matrix.test_docker_options }} + # Default to false when unset + validate: ${{ matrix.validate == '' && false || matrix.validate }} + + strategy: + fail-fast: false + matrix: + include: + - config: [clang18_py312, mpi] + - config: [clang17_py312, mpi] + - config: [clang16_py312, mpi, llvm] + - config: [clang15_py312, mpi, llvm] + - config: [clang13_py310, llvm] + - config: [clang12_py310, llvm] + - config: [clang11_py310, llvm] + - config: [gcc14_py312] + - config: [gcc12_py311] + - config: [gcc11_py310] + - config: [gcc10_py310] + - config: [cuda118_gcc11_py310, mpi, llvm] + test_runner: [self-hosted,GPU] + test_docker_options: '--gpus=all --device /dev/nvidia0 --device /dev/nvidia1 --device /dev/nvidia-uvm --device /dev/nvidia-uvm-tools --device /dev/nvidiactl' + + - config: [cuda117_gcc11_py310, mpi, llvm] + test_runner: [self-hosted,GPU] + test_docker_options: '--gpus=all --device /dev/nvidia0 --device /dev/nvidia1 --device /dev/nvidia-uvm --device /dev/nvidia-uvm-tools --device /dev/nvidiactl' From 8f9d932b1d3a318f6d8d44d2d57bc5938ce6512e Mon Sep 17 00:00:00 2001 From: "Joshua A. Anderson" Date: Wed, 5 Jun 2024 15:28:16 -0400 Subject: [PATCH 06/32] Add final test gate. --- .github/workflows/tests_new.yaml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/workflows/tests_new.yaml b/.github/workflows/tests_new.yaml index a006523261..91ab07edcc 100644 --- a/.github/workflows/tests_new.yaml +++ b/.github/workflows/tests_new.yaml @@ -105,3 +105,14 @@ jobs: - config: [cuda117_gcc11_py310, mpi, llvm] test_runner: [self-hosted,GPU] test_docker_options: '--gpus=all --device /dev/nvidia0 --device /dev/nvidia1 --device /dev/nvidia-uvm --device /dev/nvidia-uvm-tools --device /dev/nvidiactl' + + tests_complete: + name: Unit test + if: always() + needs: [typical] + runs-on: ubuntu-latest + + steps: + - run: jq --exit-status 'all(.result == "success")' <<< '${{ toJson(needs) }}' + - name: Done + run: exit 0 From 1d99df1b6b8b43d52a3d9466a983e68537266bd3 Mon Sep 17 00:00:00 2001 From: "Joshua A. Anderson" Date: Wed, 5 Jun 2024 15:32:56 -0400 Subject: [PATCH 07/32] Attempt to restore missing jobs. --- .github/workflows/build_and_test.yaml | 4 ++-- .github/workflows/tests_new.yaml | 13 ++++++------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build_and_test.yaml b/.github/workflows/build_and_test.yaml index da2b8cfa4b..90bab289f1 100644 --- a/.github/workflows/build_and_test.yaml +++ b/.github/workflows/build_and_test.yaml @@ -17,7 +17,7 @@ on: type: string required: false validate: - type: boolean + type: string required: false env: @@ -227,7 +227,7 @@ jobs: image: glotzerlab/ci:2024.06.04-${{ inputs.container_prefix }} options: ${{ inputs.test_docker_options }} -e CUDA_VISIBLE_DEVICES - if: ${{ contains(github.event.pull_request.labels.*.name, 'validate') && inputs.validate }} + if: ${{ contains(github.event.pull_request.labels.*.name, 'validate') && inputs.validate == 'true' }} steps: - name: Clean workspace run: ( shopt -s dotglob nullglob; rm -rf ./* ) diff --git a/.github/workflows/tests_new.yaml b/.github/workflows/tests_new.yaml index 91ab07edcc..4b300c2580 100644 --- a/.github/workflows/tests_new.yaml +++ b/.github/workflows/tests_new.yaml @@ -35,27 +35,27 @@ jobs: test_runner: ${{ matrix.test_runner == '' && 'ubuntu-latest' || toJson(matrix.test_runner) }} test_docker_options: ${{ matrix.test_docker_options }} # Default to false when unset - validate: ${{ matrix.validate == '' && false || matrix.validate }} + validate: ${{ matrix.validate == '' && 'false' || matrix.validate }} strategy: fail-fast: false matrix: include: - config: [clang14_py311, mpi, tbb, llvm] - validate: true + validate: 'true' - config: [gcc13_py312] - validate: true + validate: 'true' - config: [cuda120_gcc11_py310, mpi, llvm] test_runner: [self-hosted,GPU] test_docker_options: '--gpus=all --device /dev/nvidia0 --device /dev/nvidia1 --device /dev/nvidia-uvm --device /dev/nvidia-uvm-tools --device /dev/nvidiactl' - validate: true + validate: 'true' - config: [cuda120_gcc11_py310] test_runner: [self-hosted,GPU] test_docker_options: '--gpus=all --device /dev/nvidia0 --device /dev/nvidia1 --device /dev/nvidia-uvm --device /dev/nvidia-uvm-tools --device /dev/nvidiactl' - validate: true + validate: 'true' - config: [gcc13_py312, nomd] @@ -66,7 +66,6 @@ jobs: - config: [cuda120_gcc11_py310, mpi, llvm, debug] test_runner: [self-hosted,GPU] test_docker_options: '--gpus=all --device /dev/nvidia0 --device /dev/nvidia1 --device /dev/nvidia-uvm --device /dev/nvidia-uvm-tools --device /dev/nvidiactl' - validate: false - config: [gcc9_py39] @@ -81,7 +80,7 @@ jobs: test_runner: ${{ matrix.test_runner == '' && 'ubuntu-latest' || toJson(matrix.test_runner) }} test_docker_options: ${{ matrix.test_docker_options }} # Default to false when unset - validate: ${{ matrix.validate == '' && false || matrix.validate }} + validate: ${{ matrix.validate == '' && 'false' || matrix.validate }} strategy: fail-fast: false From 357a5e915d68e430f7c5f5a6939560dd2e89af5c Mon Sep 17 00:00:00 2001 From: "Joshua A. Anderson" Date: Wed, 5 Jun 2024 20:00:49 -0400 Subject: [PATCH 08/32] Combine validate and pytest. --- .github/workflows/build_and_test.yaml | 62 ++++++++------------------- .github/workflows/tests_new.yaml | 15 ++++--- 2 files changed, 26 insertions(+), 51 deletions(-) diff --git a/.github/workflows/build_and_test.yaml b/.github/workflows/build_and_test.yaml index 90bab289f1..a3eda9d27d 100644 --- a/.github/workflows/build_and_test.yaml +++ b/.github/workflows/build_and_test.yaml @@ -155,22 +155,40 @@ jobs: - name: Untar install run: tar --use-compress-program='zstd -10 -T0' -xvf install.tar + ### Unit tests - name: Run pytest (serial) run: python3 -m pytest --pyargs hoomd -x -v -ra --durations=0 --durations-min=0.1 + - name: Run pytest (mpi) if: ${{ contains(inputs.config, 'mpi') }} run: mpirun -n 2 ${GITHUB_WORKSPACE}/install/hoomd/pytest/pytest-openmpi.sh --pyargs hoomd -x -v -ra --durations=0 --durations-min=0.1 || (( cat pytest.out.1 && exit 1 )) + - name: Run pytest (serial without cupy) if: ${{ contains(inputs.config, 'cuda') }} run: python3 -m pytest --pyargs hoomd -x -v -ra --durations=0 --durations-min=0.1 -m cupy_optional env: _HOOMD_DISALLOW_CUPY_: 1 + - name: Run pytest (mpi without cupy) if: ${{ contains(inputs.config, 'cuda') && contains(inputs.config, 'mpi') }} run: mpirun -n 2 ${GITHUB_WORKSPACE}/install/hoomd/pytest/pytest-openmpi.sh --pyargs hoomd -x -v -ra --durations=0 --durations-min=0.1 -m cupy_optional || (( cat pytest.out.1 && exit 1 )) env: _HOOMD_DISALLOW_CUPY_: 1 + ### Validation tests + - name: Run pytest (serial) + if: ${{ !contains(inputs.config, 'mpi') && contains(github.event.pull_request.labels.*.name, 'validate') && inputs.validate == 'true' }} + run: python3 -m pytest --pyargs hoomd -x -v -ra --durations=0 --durations-min=0.1 -p hoomd.pytest_plugin_validate -m validate --validate + + - name: Run pytest (mpi) + if: ${{ contains(inputs.config, 'mpi') && contains(github.event.pull_request.labels.*.name, 'validate') && inputs.validate == 'true' }} + run: mpirun -n 2 ${GITHUB_WORKSPACE}/install/hoomd/pytest/pytest-openmpi.sh --pyargs hoomd -x -v -ra --durations=0 --durations-min=0.1 -p hoomd.pytest_plugin_validate -m validate --validate || (( cat pytest.out.1 && exit 1 )) + + - name: Run howto guides (serial) + if: ${{ contains(inputs.config, 'llvm') && contains(github.event.pull_request.labels.*.name, 'validate') && inputs.validate == 'true' }} # some examples require LLVM + run: 'for i in *.py; do echo "Running howto: $i" && python3 $i || exit 1; done' + working-directory: code/sphinx-doc/howto + - name: Clean workspace run: ( shopt -s dotglob nullglob; rm -rf ./* ) shell: bash @@ -218,47 +236,3 @@ jobs: - name: Clean HOME run: ( shopt -s dotglob nullglob; rm -rf $HOME/* ) shell: bash - - - validate: - needs: build - runs-on: ${{ fromJson(inputs.test_runner) }} - container: - image: glotzerlab/ci:2024.06.04-${{ inputs.container_prefix }} - options: ${{ inputs.test_docker_options }} -e CUDA_VISIBLE_DEVICES - - if: ${{ contains(github.event.pull_request.labels.*.name, 'validate') && inputs.validate == 'true' }} - steps: - - name: Clean workspace - run: ( shopt -s dotglob nullglob; rm -rf ./* ) - shell: bash - - name: Checkout - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - with: - path: code - submodules: true - - - name: Download install - uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 - with: - name: install-${{ inputs.config }}-${{ github.sha }} - - name: Untar install - run: tar --use-compress-program='zstd -10 -T0' -xvf install.tar - - - name: Run pytest (serial) - if: ${{ !contains(inputs.config, 'mpi') }} - run: python3 -m pytest --pyargs hoomd -x -v -ra --durations=0 --durations-min=0.1 -p hoomd.pytest_plugin_validate -m validate --validate - - name: Run pytest (mpi) - if: ${{ contains(inputs.config, 'mpi') }} - run: mpirun -n 2 ${GITHUB_WORKSPACE}/install/hoomd/pytest/pytest-openmpi.sh --pyargs hoomd -x -v -ra --durations=0 --durations-min=0.1 -p hoomd.pytest_plugin_validate -m validate --validate || (( cat pytest.out.1 && exit 1 )) - - name: Run howto guides (serial) - if: ${{ contains(inputs.config, 'llvm') }} # some examples require LLVM - run: 'for i in *.py; do echo "Running howto: $i" && python3 $i || exit 1; done' - working-directory: code/sphinx-doc/howto - - - name: Clean workspace - run: ( shopt -s dotglob nullglob; rm -rf ./* ) - shell: bash - - name: Clean HOME - run: ( shopt -s dotglob nullglob; rm -rf $HOME/* ) - shell: bash diff --git a/.github/workflows/tests_new.yaml b/.github/workflows/tests_new.yaml index 4b300c2580..78c4be65e4 100644 --- a/.github/workflows/tests_new.yaml +++ b/.github/workflows/tests_new.yaml @@ -17,16 +17,12 @@ on: jobs: start_action_runners: name: Start action runners - runs-on: ubuntu-latest - steps: - - name: Use jetstream2-admin/start - uses: glotzerlab/jetstream2-admin/start@v1.2.5 - with: - OS_APPLICATION_CREDENTIAL_ID: ${{ secrets.OS_APPLICATION_CREDENTIAL_ID }} - OS_APPLICATION_CREDENTIAL_SECRET: ${{ secrets.OS_APPLICATION_CREDENTIAL_SECRET }} + uses: glotzerlab/jetstream2-admin/.github/workflows/start.yaml@c5d1d59b0b3e069b611f4002bbba4d5ff8e01c60 + secrets: inherit typical: name: "${{ join(matrix.config, '_') }}" + needs: start_action_runners uses: ./.github/workflows/build_and_test.yaml with: config: ${{ join(matrix.config, '_') }} @@ -72,6 +68,7 @@ jobs: release: if: ${{ contains(github.event.pull_request.labels.*.name, 'release') }} name: "${{ join(matrix.config, '_') }}" + needs: start_action_runners uses: ./.github/workflows/build_and_test.yaml with: config: ${{ join(matrix.config, '_') }} @@ -82,6 +79,10 @@ jobs: # Default to false when unset validate: ${{ matrix.validate == '' && 'false' || matrix.validate }} + # TODO: possible to implelemtn fallback to `ubuntu-latest` when actions runners are offline? + + # runs-on: ${{ needs.start_workflow.outputs.exit_code == 3 && 'ubuntu-20.04' || 'ubuntu-24.04' }} + strategy: fail-fast: false matrix: From 3893e85d00c3843f7ef3e85c62bd5d9ea06b94d5 Mon Sep 17 00:00:00 2001 From: "Joshua A. Anderson" Date: Thu, 6 Jun 2024 08:07:31 -0400 Subject: [PATCH 09/32] GitHub provided runner fallback. Use GitHub provided runners when jetstream2 is not available. --- .github/workflows/build_and_test.yaml | 6 +++++- .github/workflows/tests_new.yaml | 12 ++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build_and_test.yaml b/.github/workflows/build_and_test.yaml index a3eda9d27d..9a3e071c6a 100644 --- a/.github/workflows/build_and_test.yaml +++ b/.github/workflows/build_and_test.yaml @@ -9,6 +9,10 @@ on: container_prefix: type: string required: true + build_runner: + type: string + required: true + default: ubuntu-latest test_runner: type: string required: true @@ -39,7 +43,7 @@ env: jobs: build: - runs-on: [self-hosted,jetstream2,CPU] + runs-on: ${{ fromJson(inputs.build_runner) }} container: image: glotzerlab/ci:2024.06.04-${{ inputs.container_prefix }} diff --git a/.github/workflows/tests_new.yaml b/.github/workflows/tests_new.yaml index 78c4be65e4..8e145fe300 100644 --- a/.github/workflows/tests_new.yaml +++ b/.github/workflows/tests_new.yaml @@ -16,8 +16,8 @@ on: jobs: start_action_runners: - name: Start action runners - uses: glotzerlab/jetstream2-admin/.github/workflows/start.yaml@c5d1d59b0b3e069b611f4002bbba4d5ff8e01c60 + name: Start + uses: glotzerlab/jetstream2-admin/.github/workflows/start.yaml@a862161adac42e4173f3d142ebd4ddfcde54779b secrets: inherit typical: @@ -27,6 +27,8 @@ jobs: with: config: ${{ join(matrix.config, '_') }} container_prefix: ${{ matrix.config[0] }} + # Use self-hosted runners or fall back to GitHub hosted runners when self-hosted are offline + build_runner: ${{ needs.start_action_runners.outputs.active == '0' && 'ubuntu-latest' || '["self-hosted","jetstream2","CPU"]' }} # Default to ubuntu-latest when unset test_runner: ${{ matrix.test_runner == '' && 'ubuntu-latest' || toJson(matrix.test_runner) }} test_docker_options: ${{ matrix.test_docker_options }} @@ -73,16 +75,14 @@ jobs: with: config: ${{ join(matrix.config, '_') }} container_prefix: ${{ matrix.config[0] }} + # Use self-hosted runners or fall back to GitHub hosted runners when self-hosted are offline + build_runner: ${{ needs.start_action_runners.outputs.active == '0' && 'ubuntu-latest' || '["self-hosted","jetstream2","CPU"]' }} # Default to ubuntu-latest when unset test_runner: ${{ matrix.test_runner == '' && 'ubuntu-latest' || toJson(matrix.test_runner) }} test_docker_options: ${{ matrix.test_docker_options }} # Default to false when unset validate: ${{ matrix.validate == '' && 'false' || matrix.validate }} - # TODO: possible to implelemtn fallback to `ubuntu-latest` when actions runners are offline? - - # runs-on: ${{ needs.start_workflow.outputs.exit_code == 3 && 'ubuntu-20.04' || 'ubuntu-24.04' }} - strategy: fail-fast: false matrix: From 49addb054b3b19f5ab293e2481e5dcb1ce80dc90 Mon Sep 17 00:00:00 2001 From: "Joshua A. Anderson" Date: Thu, 6 Jun 2024 13:21:18 -0400 Subject: [PATCH 10/32] Trigger CI. From 672755901b096512118bb95420d3d0c0832baee7 Mon Sep 17 00:00:00 2001 From: "Joshua A. Anderson" Date: Thu, 6 Jun 2024 13:26:44 -0400 Subject: [PATCH 11/32] Debug testing build_runner. --- .github/workflows/build_and_test.yaml | 12 ++++++++++++ .github/workflows/tests_new.yaml | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_and_test.yaml b/.github/workflows/build_and_test.yaml index 9a3e071c6a..34ab0a20f3 100644 --- a/.github/workflows/build_and_test.yaml +++ b/.github/workflows/build_and_test.yaml @@ -42,6 +42,18 @@ env: PYTHONPATH: ${{ github.workspace }}/install jobs: + debug: + runs-on: ubuntu-latest + steps: + - name: build_runner + run: echo ${{ inputs.build_runner }} + - name: build_runner_from_json + run: echo ${{ fromJson(inputs.build_runner) }} + - name: test_runner + run: echo ${{ inputs.test_runner }} + - name: test_runner_from_json + run: echo ${{ fromJson(inputs.test_runner) }} + build: runs-on: ${{ fromJson(inputs.build_runner) }} container: diff --git a/.github/workflows/tests_new.yaml b/.github/workflows/tests_new.yaml index 8e145fe300..58dbf7db2b 100644 --- a/.github/workflows/tests_new.yaml +++ b/.github/workflows/tests_new.yaml @@ -28,7 +28,7 @@ jobs: config: ${{ join(matrix.config, '_') }} container_prefix: ${{ matrix.config[0] }} # Use self-hosted runners or fall back to GitHub hosted runners when self-hosted are offline - build_runner: ${{ needs.start_action_runners.outputs.active == '0' && 'ubuntu-latest' || '["self-hosted","jetstream2","CPU"]' }} + build_runner: ${{ needs.start_action_runners.outputs.active == '0' && toJson('ubuntu-latest') || '["self-hosted","jetstream2","CPU"]' }} # Default to ubuntu-latest when unset test_runner: ${{ matrix.test_runner == '' && 'ubuntu-latest' || toJson(matrix.test_runner) }} test_docker_options: ${{ matrix.test_docker_options }} From 87bd7223a4b5be818cbe5cd080fd6be69c7db5df Mon Sep 17 00:00:00 2001 From: "Joshua A. Anderson" Date: Thu, 6 Jun 2024 13:37:58 -0400 Subject: [PATCH 12/32] Attempt to fix dynamic runner selection. --- .github/workflows/build_and_test.yaml | 8 ++++---- .github/workflows/tests_new.yaml | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build_and_test.yaml b/.github/workflows/build_and_test.yaml index 34ab0a20f3..b5c2429247 100644 --- a/.github/workflows/build_and_test.yaml +++ b/.github/workflows/build_and_test.yaml @@ -46,13 +46,13 @@ jobs: runs-on: ubuntu-latest steps: - name: build_runner - run: echo ${{ inputs.build_runner }} + run: echo '${{ inputs.build_runner }}' - name: build_runner_from_json - run: echo ${{ fromJson(inputs.build_runner) }} + run: echo '${{ fromJson(inputs.build_runner) }}' - name: test_runner - run: echo ${{ inputs.test_runner }} + run: echo '${{ inputs.test_runner }}' - name: test_runner_from_json - run: echo ${{ fromJson(inputs.test_runner) }} + run: echo '${{ fromJson(inputs.test_runner) }}' build: runs-on: ${{ fromJson(inputs.build_runner) }} diff --git a/.github/workflows/tests_new.yaml b/.github/workflows/tests_new.yaml index 58dbf7db2b..a9975a8ea8 100644 --- a/.github/workflows/tests_new.yaml +++ b/.github/workflows/tests_new.yaml @@ -17,7 +17,7 @@ on: jobs: start_action_runners: name: Start - uses: glotzerlab/jetstream2-admin/.github/workflows/start.yaml@a862161adac42e4173f3d142ebd4ddfcde54779b + uses: glotzerlab/jetstream2-admin/.github/workflows/start.yaml@cc78b529b8f408239597619e30c9d47880c3b409 secrets: inherit typical: @@ -30,7 +30,7 @@ jobs: # Use self-hosted runners or fall back to GitHub hosted runners when self-hosted are offline build_runner: ${{ needs.start_action_runners.outputs.active == '0' && toJson('ubuntu-latest') || '["self-hosted","jetstream2","CPU"]' }} # Default to ubuntu-latest when unset - test_runner: ${{ matrix.test_runner == '' && 'ubuntu-latest' || toJson(matrix.test_runner) }} + test_runner: ${{ matrix.test_runner == '' && toJson('ubuntu-latest') || toJson(matrix.test_runner) }} test_docker_options: ${{ matrix.test_docker_options }} # Default to false when unset validate: ${{ matrix.validate == '' && 'false' || matrix.validate }} @@ -76,9 +76,9 @@ jobs: config: ${{ join(matrix.config, '_') }} container_prefix: ${{ matrix.config[0] }} # Use self-hosted runners or fall back to GitHub hosted runners when self-hosted are offline - build_runner: ${{ needs.start_action_runners.outputs.active == '0' && 'ubuntu-latest' || '["self-hosted","jetstream2","CPU"]' }} + build_runner: ${{ needs.start_action_runners.outputs.active == '0' && toJson('ubuntu-latest') || '["self-hosted","jetstream2","CPU"]' }} # Default to ubuntu-latest when unset - test_runner: ${{ matrix.test_runner == '' && 'ubuntu-latest' || toJson(matrix.test_runner) }} + test_runner: ${{ matrix.test_runner == '' && toJson('ubuntu-latest') || toJson(matrix.test_runner) }} test_docker_options: ${{ matrix.test_docker_options }} # Default to false when unset validate: ${{ matrix.validate == '' && 'false' || matrix.validate }} From 2c47d882e0b9bda44e02f73472de348ee0be1468 Mon Sep 17 00:00:00 2001 From: "Joshua A. Anderson" Date: Thu, 6 Jun 2024 14:13:42 -0400 Subject: [PATCH 13/32] Label validation tests more clearly. --- .github/workflows/build_and_test.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_and_test.yaml b/.github/workflows/build_and_test.yaml index b5c2429247..06ad4c3a88 100644 --- a/.github/workflows/build_and_test.yaml +++ b/.github/workflows/build_and_test.yaml @@ -192,11 +192,11 @@ jobs: _HOOMD_DISALLOW_CUPY_: 1 ### Validation tests - - name: Run pytest (serial) + - name: Run pytest -m validate (serial) if: ${{ !contains(inputs.config, 'mpi') && contains(github.event.pull_request.labels.*.name, 'validate') && inputs.validate == 'true' }} run: python3 -m pytest --pyargs hoomd -x -v -ra --durations=0 --durations-min=0.1 -p hoomd.pytest_plugin_validate -m validate --validate - - name: Run pytest (mpi) + - name: Run pytest -m validate (mpi) if: ${{ contains(inputs.config, 'mpi') && contains(github.event.pull_request.labels.*.name, 'validate') && inputs.validate == 'true' }} run: mpirun -n 2 ${GITHUB_WORKSPACE}/install/hoomd/pytest/pytest-openmpi.sh --pyargs hoomd -x -v -ra --durations=0 --durations-min=0.1 -p hoomd.pytest_plugin_validate -m validate --validate || (( cat pytest.out.1 && exit 1 )) From 0ca269cf9971203e487cb804257555bf397494d3 Mon Sep 17 00:00:00 2001 From: "Joshua A. Anderson" Date: Thu, 6 Jun 2024 14:13:49 -0400 Subject: [PATCH 14/32] Use tagged jetstream2-admin --- .github/workflows/tests_new.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests_new.yaml b/.github/workflows/tests_new.yaml index a9975a8ea8..c25139e03a 100644 --- a/.github/workflows/tests_new.yaml +++ b/.github/workflows/tests_new.yaml @@ -17,7 +17,7 @@ on: jobs: start_action_runners: name: Start - uses: glotzerlab/jetstream2-admin/.github/workflows/start.yaml@cc78b529b8f408239597619e30c9d47880c3b409 + uses: glotzerlab/jetstream2-admin/.github/workflows/start.yaml@c89b62aa89f7886318edb166bc0500cfc658f24f # v1.3.0 secrets: inherit typical: From bf2074e26a949cb3a41b23523249e85975c5701f Mon Sep 17 00:00:00 2001 From: "Joshua A. Anderson" Date: Thu, 6 Jun 2024 14:16:22 -0400 Subject: [PATCH 15/32] Remove the now unused make_workflows and templates. --- .github/workflows/make_workflows.py | 56 -- .../workflows/templates/configurations.yml | 39 -- .github/workflows/templates/release.yml | 86 --- .github/workflows/templates/test.yml | 306 --------- .github/workflows/templates/workflow.yml | 49 -- .../workflows/{tests_new.yaml => test.yaml} | 0 .github/workflows/test.yml | 591 ------------------ .pre-commit-config.yaml | 7 - 8 files changed, 1134 deletions(-) delete mode 100644 .github/workflows/make_workflows.py delete mode 100644 .github/workflows/templates/configurations.yml delete mode 100644 .github/workflows/templates/release.yml delete mode 100644 .github/workflows/templates/test.yml delete mode 100644 .github/workflows/templates/workflow.yml rename .github/workflows/{tests_new.yaml => test.yaml} (100%) delete mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/make_workflows.py b/.github/workflows/make_workflows.py deleted file mode 100644 index a23340417a..0000000000 --- a/.github/workflows/make_workflows.py +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) 2009-2024 The Regents of the University of Michigan. -# Part of HOOMD-blue, released under the BSD 3-Clause License. - -"""Evaluate the workflow jinja templates.""" - -import jinja2 -import yaml -import os - -if __name__ == '__main__': - # change to the directory of the script - os.chdir(os.path.dirname(os.path.realpath(__file__))) - - env = jinja2.Environment(loader=jinja2.FileSystemLoader('templates'), - block_start_string='<%', - block_end_string='%>', - variable_start_string='<<', - variable_end_string='>>', - comment_start_string='<#', - comment_end_string='#>', - trim_blocks=True, - lstrip_blocks=True) - template = env.get_template('test.yml') - with open('templates/configurations.yml', 'r') as f: - configurations = yaml.safe_load(f) - - # preprocess configurations and fill out additional fields needed by - # `test.yml` to configure the matrix jobs - for name, configuration in configurations.items(): - for entry in configuration: - if entry['config'].startswith('[cuda'): - entry['build_runner'] = "[self-hosted,jetstream2,CPU]" - - entry['test_runner'] = "[self-hosted,GPU]" - # device options needed to access the GPU devices on the runners - # because the nvidia container toolkit is built without cgroups - # support: - # https://aur.archlinux.org/packages/nvidia-container-toolkit - entry['test_docker_options'] = \ - "--gpus=all --device /dev/nvidia0 " \ - "--device /dev/nvidia1 " \ - "--device /dev/nvidia-uvm " \ - "--device /dev/nvidia-uvm-tools " \ - "--device /dev/nvidiactl" - else: - entry['test_runner'] = "ubuntu-latest" - entry['build_runner'] = "[self-hosted,jetstream2,CPU]" - entry['test_docker_options'] = "" - - with open('test.yml', 'w') as f: - f.write(template.render(configurations)) - - template = env.get_template('release.yml') - with open('release.yml', 'w') as f: - f.write(template.render()) diff --git a/.github/workflows/templates/configurations.yml b/.github/workflows/templates/configurations.yml deleted file mode 100644 index 8cf0c58a02..0000000000 --- a/.github/workflows/templates/configurations.yml +++ /dev/null @@ -1,39 +0,0 @@ -# configurations to build and test on every pull request -# each entry is a mapping with: -# - config: a string encoded list containing the docker image name and any number of build options. -# - The build options are `mpi`, `tbb`, `llvm`, `nomd`, and `nohpmc`. -unit_test_configurations: -- config: "[clang14_py311, mpi, tbb, llvm]" -- config: "[gcc13_py312]" -- config: "[gcc13_py312, nomd]" -- config: "[gcc13_py312, nohpmc]" -- config: "[gcc13_py312, nomd, nohpmc]" -- config: "[cuda120_gcc11_py310, mpi, llvm, debug]" -- config: "[cuda120_gcc11_py310, mpi, llvm]" -- config: "[cuda120_gcc11_py310]" -- config: "[gcc9_py39]" - -# Configurations on which to run longer validation tests. Must be a subset of -# `unit_test_configurations` -validate_configurations: -- config: "[clang14_py311, mpi, tbb, llvm]" -- config: "[gcc13_py312]" -- config: "[cuda120_gcc11_py310, mpi, llvm]" -- config: "[cuda120_gcc11_py310]" - -# Configurations to build and test only rarely, such as just before a release. -# There should be no overlap between this list and `unit_test_configurations` -release_test_configurations: -- config: "[clang18_py312, mpi]" -- config: "[clang17_py312, mpi]" -- config: "[clang16_py312, mpi, llvm]" -- config: "[clang15_py312, mpi, llvm]" -- config: "[clang13_py310, llvm]" -- config: "[clang12_py310, llvm]" -- config: "[clang11_py310, llvm]" -- config: "[gcc14_py312]" -- config: "[gcc12_py311]" -- config: "[gcc11_py310]" -- config: "[gcc10_py310]" -- config: "[cuda118_gcc11_py310, mpi, llvm]" -- config: "[cuda117_gcc11_py310, mpi, llvm]" diff --git a/.github/workflows/templates/release.yml b/.github/workflows/templates/release.yml deleted file mode 100644 index 21223260fa..0000000000 --- a/.github/workflows/templates/release.yml +++ /dev/null @@ -1,86 +0,0 @@ -<% extends "workflow.yml" %> -<% block name %> -# Edit `release.yml` in `.github/workflows/templates` and run `make_workflows.py` to update the -# workflow. -name: GitHub Release -<% endblock %> -<% block on_push_tags %> - # Trigger on tags. Tag builds create GitHub releases with the change log and source tarball. - tags: - - "v*" -<% endblock %> -<% block env %> -env: - name: hoomd - -defaults: - run: - shell: bash -<% endblock %> -<% block jobs %> -jobs: - release: - name: Build release tarball - runs-on: ubuntu-latest - container: - image: << container_prefix >>-ubuntu20.04 - - steps: - - name: Checkout - uses: actions/checkout@v4.1.4 - with: - fetch-depth: 0 - submodules: true - path: code - - - name: Determine last tag via git describe - if: ${{ ! startsWith(github.ref, 'refs/tags/v') }} - run: echo "tag=$(git describe --abbrev=0)" >> $GITHUB_ENV - working-directory: code - - # git describe does not return the current tag in tag pushes on GitHub Actions, use GITHUB_REF instead - - name: Determine tag from GITHUB_REF - if: startsWith(github.ref, 'refs/tags/v') - run: echo "tag=$(echo ${GITHUB_REF} | sed -e 's/refs\/tags\///g')" >> $GITHUB_ENV - - - name: Write version change log - run: .github/workflows/make-changelog-md.sh ${tag:1} | tee ${GITHUB_WORKSPACE}/changelog.md - working-directory: code - - - name: Copy source - run: cp -R code ${name}-${tag:1} - - - name: Remove .git - run: rm -rf ${name}-${tag:1}/.git && ls -laR ${name}-${tag:1} - - - name: Tar source - run: tar -cvzf ${name}-${tag:1}.tar.gz ${name}-${tag:1} - - - name: Upload release files - uses: actions/upload-artifact@v4.3.3 - with: - name: release - path: | - *.tar.gz - changelog.md - - publish: - name: Publish [GitHub] - needs: [release] - runs-on: ubuntu-latest - - steps: - - name: Download artifacts - uses: actions/download-artifact@v4.1.7 - with: - name: release - - - name: Create release - uses: softprops/action-gh-release@v2.0.2 - if: startsWith(github.ref, 'refs/tags/v') - with: - files: "*.tar.gz" - body_path: changelog.md - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} -<% endblock %> diff --git a/.github/workflows/templates/test.yml b/.github/workflows/templates/test.yml deleted file mode 100644 index bf7f5e6370..0000000000 --- a/.github/workflows/templates/test.yml +++ /dev/null @@ -1,306 +0,0 @@ -<% extends "workflow.yml" %> -<% block name %> -name: Test -# Edit the `test.yml` in `.github/workflows/templates` and run `make_workflows.py` to update the -# workflow. -<% endblock %> -<% block on_pull_request %> - pull_request: - types: [opened, labeled, reopened, synchronize] -<% endblock %> -<% block env %> -env: - # prevent deadlocked MPI tests from causing the job to cancel - MPIEXEC_TIMEOUT: 3000 - # allow mpirun to execute as root in the tests - OMPI_ALLOW_RUN_AS_ROOT: 1 - OMPI_ALLOW_RUN_AS_ROOT_CONFIRM: 1 - # allow openmpi to oversubscribe cores - OMPI_MCA_rmaps_base_oversubscribe: 1 - # prevent errors from mis-configured openib systems - OMPI_MCA_btl: "vader,self" - # skip running the CPU tests in GPU builds - _HOOMD_SKIP_CPU_TESTS_WHEN_GPUS_PRESENT_: 1 - # Require GPU tests in GPU builds. - _HOOMD_REQUIRE_GPU_TESTS_IN_GPU_BUILDS_: 1 - # import HOOMD out of the build directory - PYTHONPATH: ${{ github.workspace }}/install -<% endblock %> -<% set tar_command="tar --use-compress-program='zstd -10 -T0'" %> -<% macro job(name, run_tests, configurations, needs='') %> - name: << name >> [${{ join(matrix.config, '_') }}] - <% if needs != '' %> - needs: << needs >> - <% endif %> - <% if run_tests %> - runs-on: ${{ matrix.test_runner }} - container: - image: << container_prefix >>-${{ matrix.config[0] }} - options: ${{ matrix.test_docker_options }} -e CUDA_VISIBLE_DEVICES - <% else %> - runs-on: ${{ matrix.build_runner }} - container: - image: << container_prefix >>-${{ matrix.config[0] }} - <% endif %> - strategy: - matrix: - include: - <% for configuration in configurations %> - - {config: << configuration.config >>, build_runner: << configuration.build_runner >>, test_runner: << configuration.test_runner >>, test_docker_options: '<< configuration.test_docker_options >>' } - <% endfor %> -<% endmacro %> -<% set build_steps %> - - name: Configure - run: | - mkdir -p build - cd build - if [[ ${BUILD_DEBUG} == "true" ]]; then BUILD_TYPE="Debug"; else BUILD_TYPE="Release"; fi - echo "BUILD_TYPE=${BUILD_TYPE}" - cmake ../code -GNinja \ - -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \ - -DENABLE_GPU=${ENABLE_GPU:-"OFF"} \ - -DENABLE_MPI=${ENABLE_MPI:-"OFF"} \ - -DENABLE_TBB=${ENABLE_TBB:-"OFF"} \ - -DENABLE_LLVM=${ENABLE_LLVM:-"OFF"} \ - -DBUILD_MD=${BUILD_MD:-"ON"} \ - -DBUILD_MPCD=${BUILD_MD:-"ON"} \ - -DBUILD_METAL=${BUILD_MD:-"ON"} \ - -DBUILD_HPMC=${BUILD_HPMC:-"ON"} \ - -DCUDA_ARCH_LIST="60;70" \ - -DENABLE_DEBUG_JIT=ON \ - -DCMAKE_INSTALL_PREFIX=${GITHUB_WORKSPACE}/install \ - -DPLUGINS="" - env: - ENABLE_GPU: ${{ contains(matrix.config[0], 'cuda') }} - ENABLE_MPI: ${{ contains(matrix.config, 'mpi') }} - ENABLE_TBB: ${{ contains(matrix.config, 'tbb') }} - ENABLE_LLVM: ${{ contains(matrix.config, 'llvm') }} - BUILD_MD: ${{ !contains(matrix.config, 'nomd') }} - BUILD_HPMC: ${{ !contains(matrix.config, 'nohpmc') }} - BUILD_DEBUG: ${{ contains(matrix.config, 'debug') }} - shell: bash - - name: Build - run: ninja install -j $(($(getconf _NPROCESSORS_ONLN) + 2)) - working-directory: build - - name: Configure plugins - run : | - mkdir -p build-example-plugins - cd build-example-plugins - if [[ ${BUILD_DEBUG} == "true" ]]; then BUILD_TYPE="Debug"; else BUILD_TYPE="Release"; fi - echo "BUILD_TYPE=${BUILD_TYPE}" - CMAKE_PREFIX_PATH=${GITHUB_WORKSPACE}/install cmake ../code/example_plugins -GNinja -DCMAKE_BUILD_TYPE=${BUILD_TYPE} - env: - BUILD_DEBUG: ${{ contains(matrix.config, 'debug') }} - shell: bash - - name: Build plugins - run: ninja install -j $(($(getconf _NPROCESSORS_ONLN) + 2)) - working-directory: build-example-plugins -<% endset %> -<% set upload_steps %> - - name: Remove object files - run: find build -type f -name '*.o' -delete - # Tar the build directory to preserve permissions and reduce HTTP requests on upload. - - name: 'Tar build' - run: << tar_command >> -cvf build.tar build - - name: 'Tar install' - run: << tar_command >> -cvf install.tar install - # Upload the tarballs. Retain the file for a limited time in case developers need to download - # and run tests locally for further debugging. - - name: 'Upload build' - uses: actions/upload-artifact@v4.3.3 - with: - name: build-${{ join(matrix.config, '_') }}-${{ github.sha }} - path: build.tar - retention-days: 7 - - name: 'Upload install' - uses: actions/upload-artifact@v4.3.3 - with: - name: install-${{ join(matrix.config, '_') }}-${{ github.sha }} - path: install.tar - retention-days: 7 -<% endset %> -<% set download_build_steps %> - - name: Download build - uses: actions/download-artifact@v4.1.7 - with: - name: build-${{ join(matrix.config, '_') }}-${{ github.sha }} - - name: Untar build - run: << tar_command >> -xvf build.tar -<% endset %> -<% set download_install_steps %> - - name: Download install - uses: actions/download-artifact@v4.1.7 - with: - name: install-${{ join(matrix.config, '_') }}-${{ github.sha }} - - name: Untar install - run: << tar_command >> -xvf install.tar -<% endset %> -<% set pytest_options="--pyargs hoomd -x -v -ra --durations=0 --durations-min=0.1" %> -<% set pytest_validate_options="-p hoomd.pytest_plugin_validate -m validate --validate" %> -<% set invoke_pytest_serial="python3 -m pytest" %> -<% set invoke_pytest_mpi="mpirun -n 2 ${GITHUB_WORKSPACE}/install/hoomd/pytest/pytest-openmpi.sh" %> -<% set pytest_steps %> - - name: Run pytest (serial) - run: << invoke_pytest_serial >> << pytest_options >> - - name: Run pytest (mpi) - if: ${{ contains(matrix.config, 'mpi') }} - run: << invoke_pytest_mpi >> << pytest_options >> || (( cat pytest.out.1 && exit 1 )) - - name: Run pytest (serial without cupy) - if: ${{ contains(matrix.config[0], 'cuda') }} - run: << invoke_pytest_serial >> << pytest_options >> -m cupy_optional - env: - _HOOMD_DISALLOW_CUPY_: 1 - - name: Run pytest (mpi without cupy) - if: ${{ contains(matrix.config[0], 'cuda') && contains(matrix.config, 'mpi') }} - run: << invoke_pytest_mpi >> << pytest_options >> -m cupy_optional || (( cat pytest.out.1 && exit 1 )) - env: - _HOOMD_DISALLOW_CUPY_: 1 -<% endset %> -<% set ctest_steps %> - - name: Run tests - run: >- - ctest - -T test - --output-on-failure - --test-output-size-failed 1048576 - --test-output-size-passed 1048576 - working-directory: build -<% endset %> -<% set validate_steps %> - - name: Run pytest (serial) - if: ${{ !contains(matrix.config, 'mpi') }} - run: << invoke_pytest_serial >> << pytest_options >> << pytest_validate_options >> - - name: Run pytest (mpi) - if: ${{ contains(matrix.config, 'mpi') }} - run: << invoke_pytest_mpi >> << pytest_options >> << pytest_validate_options >> || (( cat pytest.out.1 && exit 1 )) - - name: Run howto guides (serial) - if: ${{ contains(matrix.config, 'llvm') }} # some examples require LLVM - run: 'for i in *.py; do echo "Running howto: $i" && python3 $i || exit 1; done' - working-directory: code/sphinx-doc/howto -<% endset %> -<% set prepare_steps %> - - name: Clean workspace - run: ( shopt -s dotglob nullglob; rm -rf ./* ) - shell: bash - - name: Checkout - uses: actions/checkout@v4.1.4 - with: - path: code - submodules: true -<% endset %> -<% set post_cleanup_steps %> - - name: Clean workspace - run: ( shopt -s dotglob nullglob; rm -rf ./* ) - shell: bash - - name: Clean HOME - run: ( shopt -s dotglob nullglob; rm -rf $HOME/* ) - shell: bash -<% endset %> -<% block jobs %> -# Use multiple jobs to reduce the amount of time spent on GPU runners. Use CPU runners for -# compiling all tests configurations (GPU and CPU), then upload the build directory (sans object -# files) as an artifact. Test jobs depend on the build job, download the install directory, and run -# the tests. Upload each build configuration to a separate artifact. - -# Github Actions does not support any form of templating at this time, not even YAML anchors. -# To minimize the number of duplicated lines, encode the job configuration as an array in config: -# [image, (mpi), (tbb)] -jobs: - start_action_runners: - name: Start action runners - runs-on: ubuntu-latest - steps: - - name: Use jetstream2-admin/start - uses: glotzerlab/jetstream2-admin/start@v1.2.5 - with: - OS_APPLICATION_CREDENTIAL_ID: ${{ secrets.OS_APPLICATION_CREDENTIAL_ID }} - OS_APPLICATION_CREDENTIAL_SECRET: ${{ secrets.OS_APPLICATION_CREDENTIAL_SECRET }} - - build: -<< job(name='Build', run_tests=False, configurations=unit_test_configurations) >> - steps: - - name: Set Werror on recent compilers - run: | - echo "CXXFLAGS=-Werror" >> $GITHUB_ENV - if: ${{ !startsWith(matrix.config[0], 'gcc7') }} -<< prepare_steps >> -<< build_steps >> -<< upload_steps >> -<< post_cleanup_steps >> - - pytest: -<< job(name='Run pytest', run_tests=True, configurations=unit_test_configurations, needs='build') >> - steps: -<< prepare_steps >> -<< download_install_steps >> -<< pytest_steps >> -<< post_cleanup_steps >> - - ctest: -<< job(name='Run ctest', run_tests=True, configurations=unit_test_configurations, needs='build') >> - steps: -<< prepare_steps >> -<< download_build_steps >> -<< ctest_steps >> -<< post_cleanup_steps >> - - validate: -<< job(name='Validate', run_tests=True, configurations=validate_configurations, needs='build') >> - if: ${{ contains(github.event.pull_request.labels.*.name, 'validate') }} - steps: -<< prepare_steps >> -<< download_install_steps >> -<< validate_steps >> -<< post_cleanup_steps >> - - build_release: -<< job(name='Build', run_tests=False, configurations=release_test_configurations) >> - if: ${{ contains(github.event.pull_request.labels.*.name, 'release') }} - steps: -<< prepare_steps >> -<< build_steps >> -<< upload_steps >> -<< post_cleanup_steps >> - - pytest_release: -<< job(name='Run pytest', run_tests=True, configurations=release_test_configurations, needs='build_release') >> - if: ${{ contains(github.event.pull_request.labels.*.name, 'release') }} - steps: -<< prepare_steps >> -<< download_install_steps >> -<< pytest_steps >> -<< post_cleanup_steps >> - - ctest_release: -<< job(name='Run ctest', run_tests=True, configurations=release_test_configurations, needs='build_release') >> - if: ${{ contains(github.event.pull_request.labels.*.name, 'release') }} - steps: -<< prepare_steps >> -<< download_build_steps >> -<< ctest_steps >> -<< post_cleanup_steps >> - - # This job is used to provide a single requirement for branch merge conditions. GitHub considers - # the check passing even if it is skipped, so this job raises errors when required jobs were not - # run. - unit_tests_complete: - name: Unit test - needs: [pytest, ctest, validate] - if: ${{ always() && github.event_name == 'pull_request' }} - runs-on: ubuntu-latest - - steps: - - name: Error if pytest did not succeed - if: needs.pytest.result != 'success' - run: echo "::error ::pytest tests failed." && exit 1 - - name: Error if ctest did not succeed - if: needs.ctest.result != 'success' - run: echo "::error ::ctest tests failed." && exit 1 - - name: Warn if validate did not run - if: needs.validate.result == 'skipped' - run: echo "::warning ::Skipped validation tests." && exit 1 - - name: Error if validate did not succeed - if: needs.validate.result != 'success' - run: echo "::error ::Validation tests failed." && exit 1 - - run: echo "Done!" -<% endblock %> diff --git a/.github/workflows/templates/workflow.yml b/.github/workflows/templates/workflow.yml deleted file mode 100644 index f0268bca93..0000000000 --- a/.github/workflows/templates/workflow.yml +++ /dev/null @@ -1,49 +0,0 @@ -<% block name %><% endblock %> -<% set container_prefix="glotzerlab/ci:2024.06.04" %> - -<% block concurrency %> -concurrency: - <% block concurrency_group %> - group: ${{ github.workflow }}-${{ github.ref }} - <% endblock %> - <% block concurrency_cancel_in_progress %> - cancel-in-progress: true - <% endblock %> -<% endblock %> - -<% block on %> -on: - <% block on_pull_request %> - # Trigger on pull requests. - pull_request: - <% endblock %> - - <% block on_push %> - # Trigger on pushes to the trunk branches. This prevents building commits twice when the pull - # request source branch is in the same repository. - push: - <% block on_push_branches %> - branches: - - "trunk-*" - <% endblock %> - <% block on_push_tags %> - <% endblock %> - <% endblock %> - - <% block on_workflow_dispatch %> - # Trigger on request. - workflow_dispatch: - <% endblock %> -<% endblock %> - -<% block permissions %> -<% endblock %> - -<% block env %> -<% endblock %> - -<% block defaults %> -<% endblock %> - -<% block jobs %> -<% endblock %> diff --git a/.github/workflows/tests_new.yaml b/.github/workflows/test.yaml similarity index 100% rename from .github/workflows/tests_new.yaml rename to .github/workflows/test.yaml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index 0defdbd3ab..0000000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,591 +0,0 @@ -name: Test (old) -# Edit the `test.yml` in `.github/workflows/templates` and run `make_workflows.py` to update the -# workflow. - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -on: - # pull_request: - # types: [opened, labeled, reopened, synchronize] - - # # Trigger on pushes to the trunk branches. This prevents building commits twice when the pull - # # request source branch is in the same repository. - # push: - # branches: - # - "trunk-*" - - # Trigger on request. - workflow_dispatch: - - -env: - # prevent deadlocked MPI tests from causing the job to cancel - MPIEXEC_TIMEOUT: 3000 - # allow mpirun to execute as root in the tests - OMPI_ALLOW_RUN_AS_ROOT: 1 - OMPI_ALLOW_RUN_AS_ROOT_CONFIRM: 1 - # allow openmpi to oversubscribe cores - OMPI_MCA_rmaps_base_oversubscribe: 1 - # prevent errors from mis-configured openib systems - OMPI_MCA_btl: "vader,self" - # skip running the CPU tests in GPU builds - _HOOMD_SKIP_CPU_TESTS_WHEN_GPUS_PRESENT_: 1 - # Require GPU tests in GPU builds. - _HOOMD_REQUIRE_GPU_TESTS_IN_GPU_BUILDS_: 1 - # import HOOMD out of the build directory - PYTHONPATH: ${{ github.workspace }}/install - - -# Use multiple jobs to reduce the amount of time spent on GPU runners. Use CPU runners for -# compiling all tests configurations (GPU and CPU), then upload the build directory (sans object -# files) as an artifact. Test jobs depend on the build job, download the install directory, and run -# the tests. Upload each build configuration to a separate artifact. - -# Github Actions does not support any form of templating at this time, not even YAML anchors. -# To minimize the number of duplicated lines, encode the job configuration as an array in config: -# [image, (mpi), (tbb)] -jobs: - start_action_runners: - name: Start action runners - runs-on: ubuntu-latest - steps: - - name: Use jetstream2-admin/start - uses: glotzerlab/jetstream2-admin/start@v1.2.5 - with: - OS_APPLICATION_CREDENTIAL_ID: ${{ secrets.OS_APPLICATION_CREDENTIAL_ID }} - OS_APPLICATION_CREDENTIAL_SECRET: ${{ secrets.OS_APPLICATION_CREDENTIAL_SECRET }} - - build: - name: Build [${{ join(matrix.config, '_') }}] - runs-on: ${{ matrix.build_runner }} - container: - image: glotzerlab/ci:2024.06.04-${{ matrix.config[0] }} - strategy: - matrix: - include: - - {config: [clang14_py311, mpi, tbb, llvm], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [gcc13_py312], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [gcc13_py312, nomd], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [gcc13_py312, nohpmc], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [gcc13_py312, nomd, nohpmc], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [cuda120_gcc11_py310, mpi, llvm, debug], build_runner: [self-hosted,jetstream2,CPU], test_runner: [self-hosted,GPU], test_docker_options: '--gpus=all --device /dev/nvidia0 --device /dev/nvidia1 --device /dev/nvidia-uvm --device /dev/nvidia-uvm-tools --device /dev/nvidiactl' } - - {config: [cuda120_gcc11_py310, mpi, llvm], build_runner: [self-hosted,jetstream2,CPU], test_runner: [self-hosted,GPU], test_docker_options: '--gpus=all --device /dev/nvidia0 --device /dev/nvidia1 --device /dev/nvidia-uvm --device /dev/nvidia-uvm-tools --device /dev/nvidiactl' } - - {config: [cuda120_gcc11_py310], build_runner: [self-hosted,jetstream2,CPU], test_runner: [self-hosted,GPU], test_docker_options: '--gpus=all --device /dev/nvidia0 --device /dev/nvidia1 --device /dev/nvidia-uvm --device /dev/nvidia-uvm-tools --device /dev/nvidiactl' } - - {config: [gcc9_py39], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - steps: - - name: Set Werror on recent compilers - run: | - echo "CXXFLAGS=-Werror" >> $GITHUB_ENV - if: ${{ !startsWith(matrix.config[0], 'gcc7') }} - - name: Clean workspace - run: ( shopt -s dotglob nullglob; rm -rf ./* ) - shell: bash - - name: Checkout - uses: actions/checkout@v4.1.4 - with: - path: code - submodules: true - - - name: Configure - run: | - mkdir -p build - cd build - if [[ ${BUILD_DEBUG} == "true" ]]; then BUILD_TYPE="Debug"; else BUILD_TYPE="Release"; fi - echo "BUILD_TYPE=${BUILD_TYPE}" - cmake ../code -GNinja \ - -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \ - -DENABLE_GPU=${ENABLE_GPU:-"OFF"} \ - -DENABLE_MPI=${ENABLE_MPI:-"OFF"} \ - -DENABLE_TBB=${ENABLE_TBB:-"OFF"} \ - -DENABLE_LLVM=${ENABLE_LLVM:-"OFF"} \ - -DBUILD_MD=${BUILD_MD:-"ON"} \ - -DBUILD_MPCD=${BUILD_MD:-"ON"} \ - -DBUILD_METAL=${BUILD_MD:-"ON"} \ - -DBUILD_HPMC=${BUILD_HPMC:-"ON"} \ - -DCUDA_ARCH_LIST="60;70" \ - -DENABLE_DEBUG_JIT=ON \ - -DCMAKE_INSTALL_PREFIX=${GITHUB_WORKSPACE}/install \ - -DPLUGINS="" - env: - ENABLE_GPU: ${{ contains(matrix.config[0], 'cuda') }} - ENABLE_MPI: ${{ contains(matrix.config, 'mpi') }} - ENABLE_TBB: ${{ contains(matrix.config, 'tbb') }} - ENABLE_LLVM: ${{ contains(matrix.config, 'llvm') }} - BUILD_MD: ${{ !contains(matrix.config, 'nomd') }} - BUILD_HPMC: ${{ !contains(matrix.config, 'nohpmc') }} - BUILD_DEBUG: ${{ contains(matrix.config, 'debug') }} - shell: bash - - name: Build - run: ninja install -j $(($(getconf _NPROCESSORS_ONLN) + 2)) - working-directory: build - - name: Configure plugins - run : | - mkdir -p build-example-plugins - cd build-example-plugins - if [[ ${BUILD_DEBUG} == "true" ]]; then BUILD_TYPE="Debug"; else BUILD_TYPE="Release"; fi - echo "BUILD_TYPE=${BUILD_TYPE}" - CMAKE_PREFIX_PATH=${GITHUB_WORKSPACE}/install cmake ../code/example_plugins -GNinja -DCMAKE_BUILD_TYPE=${BUILD_TYPE} - env: - BUILD_DEBUG: ${{ contains(matrix.config, 'debug') }} - shell: bash - - name: Build plugins - run: ninja install -j $(($(getconf _NPROCESSORS_ONLN) + 2)) - working-directory: build-example-plugins - - - name: Remove object files - run: find build -type f -name '*.o' -delete - # Tar the build directory to preserve permissions and reduce HTTP requests on upload. - - name: 'Tar build' - run: tar --use-compress-program='zstd -10 -T0' -cvf build.tar build - - name: 'Tar install' - run: tar --use-compress-program='zstd -10 -T0' -cvf install.tar install - # Upload the tarballs. Retain the file for a limited time in case developers need to download - # and run tests locally for further debugging. - - name: 'Upload build' - uses: actions/upload-artifact@v4.3.3 - with: - name: build-${{ join(matrix.config, '_') }}-${{ github.sha }} - path: build.tar - retention-days: 7 - - name: 'Upload install' - uses: actions/upload-artifact@v4.3.3 - with: - name: install-${{ join(matrix.config, '_') }}-${{ github.sha }} - path: install.tar - retention-days: 7 - - - name: Clean workspace - run: ( shopt -s dotglob nullglob; rm -rf ./* ) - shell: bash - - name: Clean HOME - run: ( shopt -s dotglob nullglob; rm -rf $HOME/* ) - shell: bash - - - pytest: - name: Run pytest [${{ join(matrix.config, '_') }}] - needs: build - runs-on: ${{ matrix.test_runner }} - container: - image: glotzerlab/ci:2024.06.04-${{ matrix.config[0] }} - options: ${{ matrix.test_docker_options }} -e CUDA_VISIBLE_DEVICES - strategy: - matrix: - include: - - {config: [clang14_py311, mpi, tbb, llvm], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [gcc13_py312], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [gcc13_py312, nomd], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [gcc13_py312, nohpmc], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [gcc13_py312, nomd, nohpmc], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [cuda120_gcc11_py310, mpi, llvm, debug], build_runner: [self-hosted,jetstream2,CPU], test_runner: [self-hosted,GPU], test_docker_options: '--gpus=all --device /dev/nvidia0 --device /dev/nvidia1 --device /dev/nvidia-uvm --device /dev/nvidia-uvm-tools --device /dev/nvidiactl' } - - {config: [cuda120_gcc11_py310, mpi, llvm], build_runner: [self-hosted,jetstream2,CPU], test_runner: [self-hosted,GPU], test_docker_options: '--gpus=all --device /dev/nvidia0 --device /dev/nvidia1 --device /dev/nvidia-uvm --device /dev/nvidia-uvm-tools --device /dev/nvidiactl' } - - {config: [cuda120_gcc11_py310], build_runner: [self-hosted,jetstream2,CPU], test_runner: [self-hosted,GPU], test_docker_options: '--gpus=all --device /dev/nvidia0 --device /dev/nvidia1 --device /dev/nvidia-uvm --device /dev/nvidia-uvm-tools --device /dev/nvidiactl' } - - {config: [gcc9_py39], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - steps: - - name: Clean workspace - run: ( shopt -s dotglob nullglob; rm -rf ./* ) - shell: bash - - name: Checkout - uses: actions/checkout@v4.1.4 - with: - path: code - submodules: true - - - name: Download install - uses: actions/download-artifact@v4.1.7 - with: - name: install-${{ join(matrix.config, '_') }}-${{ github.sha }} - - name: Untar install - run: tar --use-compress-program='zstd -10 -T0' -xvf install.tar - - - name: Run pytest (serial) - run: python3 -m pytest --pyargs hoomd -x -v -ra --durations=0 --durations-min=0.1 - - name: Run pytest (mpi) - if: ${{ contains(matrix.config, 'mpi') }} - run: mpirun -n 2 ${GITHUB_WORKSPACE}/install/hoomd/pytest/pytest-openmpi.sh --pyargs hoomd -x -v -ra --durations=0 --durations-min=0.1 || (( cat pytest.out.1 && exit 1 )) - - name: Run pytest (serial without cupy) - if: ${{ contains(matrix.config[0], 'cuda') }} - run: python3 -m pytest --pyargs hoomd -x -v -ra --durations=0 --durations-min=0.1 -m cupy_optional - env: - _HOOMD_DISALLOW_CUPY_: 1 - - name: Run pytest (mpi without cupy) - if: ${{ contains(matrix.config[0], 'cuda') && contains(matrix.config, 'mpi') }} - run: mpirun -n 2 ${GITHUB_WORKSPACE}/install/hoomd/pytest/pytest-openmpi.sh --pyargs hoomd -x -v -ra --durations=0 --durations-min=0.1 -m cupy_optional || (( cat pytest.out.1 && exit 1 )) - env: - _HOOMD_DISALLOW_CUPY_: 1 - - - name: Clean workspace - run: ( shopt -s dotglob nullglob; rm -rf ./* ) - shell: bash - - name: Clean HOME - run: ( shopt -s dotglob nullglob; rm -rf $HOME/* ) - shell: bash - - - ctest: - name: Run ctest [${{ join(matrix.config, '_') }}] - needs: build - runs-on: ${{ matrix.test_runner }} - container: - image: glotzerlab/ci:2024.06.04-${{ matrix.config[0] }} - options: ${{ matrix.test_docker_options }} -e CUDA_VISIBLE_DEVICES - strategy: - matrix: - include: - - {config: [clang14_py311, mpi, tbb, llvm], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [gcc13_py312], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [gcc13_py312, nomd], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [gcc13_py312, nohpmc], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [gcc13_py312, nomd, nohpmc], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [cuda120_gcc11_py310, mpi, llvm, debug], build_runner: [self-hosted,jetstream2,CPU], test_runner: [self-hosted,GPU], test_docker_options: '--gpus=all --device /dev/nvidia0 --device /dev/nvidia1 --device /dev/nvidia-uvm --device /dev/nvidia-uvm-tools --device /dev/nvidiactl' } - - {config: [cuda120_gcc11_py310, mpi, llvm], build_runner: [self-hosted,jetstream2,CPU], test_runner: [self-hosted,GPU], test_docker_options: '--gpus=all --device /dev/nvidia0 --device /dev/nvidia1 --device /dev/nvidia-uvm --device /dev/nvidia-uvm-tools --device /dev/nvidiactl' } - - {config: [cuda120_gcc11_py310], build_runner: [self-hosted,jetstream2,CPU], test_runner: [self-hosted,GPU], test_docker_options: '--gpus=all --device /dev/nvidia0 --device /dev/nvidia1 --device /dev/nvidia-uvm --device /dev/nvidia-uvm-tools --device /dev/nvidiactl' } - - {config: [gcc9_py39], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - steps: - - name: Clean workspace - run: ( shopt -s dotglob nullglob; rm -rf ./* ) - shell: bash - - name: Checkout - uses: actions/checkout@v4.1.4 - with: - path: code - submodules: true - - - name: Download build - uses: actions/download-artifact@v4.1.7 - with: - name: build-${{ join(matrix.config, '_') }}-${{ github.sha }} - - name: Untar build - run: tar --use-compress-program='zstd -10 -T0' -xvf build.tar - - - name: Run tests - run: >- - ctest - -T test - --output-on-failure - --test-output-size-failed 1048576 - --test-output-size-passed 1048576 - working-directory: build - - - name: Clean workspace - run: ( shopt -s dotglob nullglob; rm -rf ./* ) - shell: bash - - name: Clean HOME - run: ( shopt -s dotglob nullglob; rm -rf $HOME/* ) - shell: bash - - - validate: - name: Validate [${{ join(matrix.config, '_') }}] - needs: build - runs-on: ${{ matrix.test_runner }} - container: - image: glotzerlab/ci:2024.06.04-${{ matrix.config[0] }} - options: ${{ matrix.test_docker_options }} -e CUDA_VISIBLE_DEVICES - strategy: - matrix: - include: - - {config: [clang14_py311, mpi, tbb, llvm], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [gcc13_py312], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [cuda120_gcc11_py310, mpi, llvm], build_runner: [self-hosted,jetstream2,CPU], test_runner: [self-hosted,GPU], test_docker_options: '--gpus=all --device /dev/nvidia0 --device /dev/nvidia1 --device /dev/nvidia-uvm --device /dev/nvidia-uvm-tools --device /dev/nvidiactl' } - - {config: [cuda120_gcc11_py310], build_runner: [self-hosted,jetstream2,CPU], test_runner: [self-hosted,GPU], test_docker_options: '--gpus=all --device /dev/nvidia0 --device /dev/nvidia1 --device /dev/nvidia-uvm --device /dev/nvidia-uvm-tools --device /dev/nvidiactl' } - - if: ${{ contains(github.event.pull_request.labels.*.name, 'validate') }} - steps: - - name: Clean workspace - run: ( shopt -s dotglob nullglob; rm -rf ./* ) - shell: bash - - name: Checkout - uses: actions/checkout@v4.1.4 - with: - path: code - submodules: true - - - name: Download install - uses: actions/download-artifact@v4.1.7 - with: - name: install-${{ join(matrix.config, '_') }}-${{ github.sha }} - - name: Untar install - run: tar --use-compress-program='zstd -10 -T0' -xvf install.tar - - - name: Run pytest (serial) - if: ${{ !contains(matrix.config, 'mpi') }} - run: python3 -m pytest --pyargs hoomd -x -v -ra --durations=0 --durations-min=0.1 -p hoomd.pytest_plugin_validate -m validate --validate - - name: Run pytest (mpi) - if: ${{ contains(matrix.config, 'mpi') }} - run: mpirun -n 2 ${GITHUB_WORKSPACE}/install/hoomd/pytest/pytest-openmpi.sh --pyargs hoomd -x -v -ra --durations=0 --durations-min=0.1 -p hoomd.pytest_plugin_validate -m validate --validate || (( cat pytest.out.1 && exit 1 )) - - name: Run howto guides (serial) - if: ${{ contains(matrix.config, 'llvm') }} # some examples require LLVM - run: 'for i in *.py; do echo "Running howto: $i" && python3 $i || exit 1; done' - working-directory: code/sphinx-doc/howto - - - name: Clean workspace - run: ( shopt -s dotglob nullglob; rm -rf ./* ) - shell: bash - - name: Clean HOME - run: ( shopt -s dotglob nullglob; rm -rf $HOME/* ) - shell: bash - - - build_release: - name: Build [${{ join(matrix.config, '_') }}] - runs-on: ${{ matrix.build_runner }} - container: - image: glotzerlab/ci:2024.06.04-${{ matrix.config[0] }} - strategy: - matrix: - include: - - {config: [clang18_py312, mpi], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [clang17_py312, mpi], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [clang16_py312, mpi, llvm], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [clang15_py312, mpi, llvm], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [clang13_py310, llvm], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [clang12_py310, llvm], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [clang11_py310, llvm], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [gcc14_py312], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [gcc12_py311], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [gcc11_py310], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [gcc10_py310], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [cuda118_gcc11_py310, mpi, llvm], build_runner: [self-hosted,jetstream2,CPU], test_runner: [self-hosted,GPU], test_docker_options: '--gpus=all --device /dev/nvidia0 --device /dev/nvidia1 --device /dev/nvidia-uvm --device /dev/nvidia-uvm-tools --device /dev/nvidiactl' } - - {config: [cuda117_gcc11_py310, mpi, llvm], build_runner: [self-hosted,jetstream2,CPU], test_runner: [self-hosted,GPU], test_docker_options: '--gpus=all --device /dev/nvidia0 --device /dev/nvidia1 --device /dev/nvidia-uvm --device /dev/nvidia-uvm-tools --device /dev/nvidiactl' } - - if: ${{ contains(github.event.pull_request.labels.*.name, 'release') }} - steps: - - name: Clean workspace - run: ( shopt -s dotglob nullglob; rm -rf ./* ) - shell: bash - - name: Checkout - uses: actions/checkout@v4.1.4 - with: - path: code - submodules: true - - - name: Configure - run: | - mkdir -p build - cd build - if [[ ${BUILD_DEBUG} == "true" ]]; then BUILD_TYPE="Debug"; else BUILD_TYPE="Release"; fi - echo "BUILD_TYPE=${BUILD_TYPE}" - cmake ../code -GNinja \ - -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \ - -DENABLE_GPU=${ENABLE_GPU:-"OFF"} \ - -DENABLE_MPI=${ENABLE_MPI:-"OFF"} \ - -DENABLE_TBB=${ENABLE_TBB:-"OFF"} \ - -DENABLE_LLVM=${ENABLE_LLVM:-"OFF"} \ - -DBUILD_MD=${BUILD_MD:-"ON"} \ - -DBUILD_MPCD=${BUILD_MD:-"ON"} \ - -DBUILD_METAL=${BUILD_MD:-"ON"} \ - -DBUILD_HPMC=${BUILD_HPMC:-"ON"} \ - -DCUDA_ARCH_LIST="60;70" \ - -DENABLE_DEBUG_JIT=ON \ - -DCMAKE_INSTALL_PREFIX=${GITHUB_WORKSPACE}/install \ - -DPLUGINS="" - env: - ENABLE_GPU: ${{ contains(matrix.config[0], 'cuda') }} - ENABLE_MPI: ${{ contains(matrix.config, 'mpi') }} - ENABLE_TBB: ${{ contains(matrix.config, 'tbb') }} - ENABLE_LLVM: ${{ contains(matrix.config, 'llvm') }} - BUILD_MD: ${{ !contains(matrix.config, 'nomd') }} - BUILD_HPMC: ${{ !contains(matrix.config, 'nohpmc') }} - BUILD_DEBUG: ${{ contains(matrix.config, 'debug') }} - shell: bash - - name: Build - run: ninja install -j $(($(getconf _NPROCESSORS_ONLN) + 2)) - working-directory: build - - name: Configure plugins - run : | - mkdir -p build-example-plugins - cd build-example-plugins - if [[ ${BUILD_DEBUG} == "true" ]]; then BUILD_TYPE="Debug"; else BUILD_TYPE="Release"; fi - echo "BUILD_TYPE=${BUILD_TYPE}" - CMAKE_PREFIX_PATH=${GITHUB_WORKSPACE}/install cmake ../code/example_plugins -GNinja -DCMAKE_BUILD_TYPE=${BUILD_TYPE} - env: - BUILD_DEBUG: ${{ contains(matrix.config, 'debug') }} - shell: bash - - name: Build plugins - run: ninja install -j $(($(getconf _NPROCESSORS_ONLN) + 2)) - working-directory: build-example-plugins - - - name: Remove object files - run: find build -type f -name '*.o' -delete - # Tar the build directory to preserve permissions and reduce HTTP requests on upload. - - name: 'Tar build' - run: tar --use-compress-program='zstd -10 -T0' -cvf build.tar build - - name: 'Tar install' - run: tar --use-compress-program='zstd -10 -T0' -cvf install.tar install - # Upload the tarballs. Retain the file for a limited time in case developers need to download - # and run tests locally for further debugging. - - name: 'Upload build' - uses: actions/upload-artifact@v4.3.3 - with: - name: build-${{ join(matrix.config, '_') }}-${{ github.sha }} - path: build.tar - retention-days: 7 - - name: 'Upload install' - uses: actions/upload-artifact@v4.3.3 - with: - name: install-${{ join(matrix.config, '_') }}-${{ github.sha }} - path: install.tar - retention-days: 7 - - - name: Clean workspace - run: ( shopt -s dotglob nullglob; rm -rf ./* ) - shell: bash - - name: Clean HOME - run: ( shopt -s dotglob nullglob; rm -rf $HOME/* ) - shell: bash - - - pytest_release: - name: Run pytest [${{ join(matrix.config, '_') }}] - needs: build_release - runs-on: ${{ matrix.test_runner }} - container: - image: glotzerlab/ci:2024.06.04-${{ matrix.config[0] }} - options: ${{ matrix.test_docker_options }} -e CUDA_VISIBLE_DEVICES - strategy: - matrix: - include: - - {config: [clang18_py312, mpi], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [clang17_py312, mpi], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [clang16_py312, mpi, llvm], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [clang15_py312, mpi, llvm], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [clang13_py310, llvm], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [clang12_py310, llvm], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [clang11_py310, llvm], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [gcc14_py312], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [gcc12_py311], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [gcc11_py310], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [gcc10_py310], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [cuda118_gcc11_py310, mpi, llvm], build_runner: [self-hosted,jetstream2,CPU], test_runner: [self-hosted,GPU], test_docker_options: '--gpus=all --device /dev/nvidia0 --device /dev/nvidia1 --device /dev/nvidia-uvm --device /dev/nvidia-uvm-tools --device /dev/nvidiactl' } - - {config: [cuda117_gcc11_py310, mpi, llvm], build_runner: [self-hosted,jetstream2,CPU], test_runner: [self-hosted,GPU], test_docker_options: '--gpus=all --device /dev/nvidia0 --device /dev/nvidia1 --device /dev/nvidia-uvm --device /dev/nvidia-uvm-tools --device /dev/nvidiactl' } - - if: ${{ contains(github.event.pull_request.labels.*.name, 'release') }} - steps: - - name: Clean workspace - run: ( shopt -s dotglob nullglob; rm -rf ./* ) - shell: bash - - name: Checkout - uses: actions/checkout@v4.1.4 - with: - path: code - submodules: true - - - name: Download install - uses: actions/download-artifact@v4.1.7 - with: - name: install-${{ join(matrix.config, '_') }}-${{ github.sha }} - - name: Untar install - run: tar --use-compress-program='zstd -10 -T0' -xvf install.tar - - - name: Run pytest (serial) - run: python3 -m pytest --pyargs hoomd -x -v -ra --durations=0 --durations-min=0.1 - - name: Run pytest (mpi) - if: ${{ contains(matrix.config, 'mpi') }} - run: mpirun -n 2 ${GITHUB_WORKSPACE}/install/hoomd/pytest/pytest-openmpi.sh --pyargs hoomd -x -v -ra --durations=0 --durations-min=0.1 || (( cat pytest.out.1 && exit 1 )) - - name: Run pytest (serial without cupy) - if: ${{ contains(matrix.config[0], 'cuda') }} - run: python3 -m pytest --pyargs hoomd -x -v -ra --durations=0 --durations-min=0.1 -m cupy_optional - env: - _HOOMD_DISALLOW_CUPY_: 1 - - name: Run pytest (mpi without cupy) - if: ${{ contains(matrix.config[0], 'cuda') && contains(matrix.config, 'mpi') }} - run: mpirun -n 2 ${GITHUB_WORKSPACE}/install/hoomd/pytest/pytest-openmpi.sh --pyargs hoomd -x -v -ra --durations=0 --durations-min=0.1 -m cupy_optional || (( cat pytest.out.1 && exit 1 )) - env: - _HOOMD_DISALLOW_CUPY_: 1 - - - name: Clean workspace - run: ( shopt -s dotglob nullglob; rm -rf ./* ) - shell: bash - - name: Clean HOME - run: ( shopt -s dotglob nullglob; rm -rf $HOME/* ) - shell: bash - - - ctest_release: - name: Run ctest [${{ join(matrix.config, '_') }}] - needs: build_release - runs-on: ${{ matrix.test_runner }} - container: - image: glotzerlab/ci:2024.06.04-${{ matrix.config[0] }} - options: ${{ matrix.test_docker_options }} -e CUDA_VISIBLE_DEVICES - strategy: - matrix: - include: - - {config: [clang18_py312, mpi], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [clang17_py312, mpi], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [clang16_py312, mpi, llvm], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [clang15_py312, mpi, llvm], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [clang13_py310, llvm], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [clang12_py310, llvm], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [clang11_py310, llvm], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [gcc14_py312], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [gcc12_py311], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [gcc11_py310], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [gcc10_py310], build_runner: [self-hosted,jetstream2,CPU], test_runner: ubuntu-latest, test_docker_options: '' } - - {config: [cuda118_gcc11_py310, mpi, llvm], build_runner: [self-hosted,jetstream2,CPU], test_runner: [self-hosted,GPU], test_docker_options: '--gpus=all --device /dev/nvidia0 --device /dev/nvidia1 --device /dev/nvidia-uvm --device /dev/nvidia-uvm-tools --device /dev/nvidiactl' } - - {config: [cuda117_gcc11_py310, mpi, llvm], build_runner: [self-hosted,jetstream2,CPU], test_runner: [self-hosted,GPU], test_docker_options: '--gpus=all --device /dev/nvidia0 --device /dev/nvidia1 --device /dev/nvidia-uvm --device /dev/nvidia-uvm-tools --device /dev/nvidiactl' } - - if: ${{ contains(github.event.pull_request.labels.*.name, 'release') }} - steps: - - name: Clean workspace - run: ( shopt -s dotglob nullglob; rm -rf ./* ) - shell: bash - - name: Checkout - uses: actions/checkout@v4.1.4 - with: - path: code - submodules: true - - - name: Download build - uses: actions/download-artifact@v4.1.7 - with: - name: build-${{ join(matrix.config, '_') }}-${{ github.sha }} - - name: Untar build - run: tar --use-compress-program='zstd -10 -T0' -xvf build.tar - - - name: Run tests - run: >- - ctest - -T test - --output-on-failure - --test-output-size-failed 1048576 - --test-output-size-passed 1048576 - working-directory: build - - - name: Clean workspace - run: ( shopt -s dotglob nullglob; rm -rf ./* ) - shell: bash - - name: Clean HOME - run: ( shopt -s dotglob nullglob; rm -rf $HOME/* ) - shell: bash - - - # This job is used to provide a single requirement for branch merge conditions. GitHub considers - # the check passing even if it is skipped, so this job raises errors when required jobs were not - # run. - unit_tests_complete: - name: Unit test - needs: [pytest, ctest, validate] - if: ${{ always() && github.event_name == 'pull_request' }} - runs-on: ubuntu-latest - - steps: - - name: Error if pytest did not succeed - if: needs.pytest.result != 'success' - run: echo "::error ::pytest tests failed." && exit 1 - - name: Error if ctest did not succeed - if: needs.ctest.result != 'success' - run: echo "::error ::ctest tests failed." && exit 1 - - name: Warn if validate did not run - if: needs.validate.result == 'skipped' - run: echo "::warning ::Skipped validation tests." && exit 1 - - name: Error if validate did not succeed - if: needs.validate.result != 'success' - run: echo "::error ::Validation tests failed." && exit 1 - - run: echo "Done!" diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d09aceccb4..dac91ebd24 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -11,13 +11,6 @@ exclude: (?x)( repos: - repo: local hooks: - - id: make_workflows - name: make_workflows - language: python - entry: python3 .github/workflows/make_workflows.py - pass_filenames: false - always_run: true - additional_dependencies: [jinja2==3.1.2, pyyaml==6.0.1] - id: check-maintainer name: Check for maintainer comments description: 'Enforce that `maintainer` comments are removed.' From 9e970fb1f326e7e38a1ea931c6827b327f5c245c Mon Sep 17 00:00:00 2001 From: "Joshua A. Anderson" Date: Thu, 6 Jun 2024 14:17:26 -0400 Subject: [PATCH 16/32] Switch to shared stale bot configuration. --- .github/workflows/stale.yaml | 11 ++++++++++ .github/workflows/stale.yml | 39 ------------------------------------ 2 files changed, 11 insertions(+), 39 deletions(-) create mode 100644 .github/workflows/stale.yaml delete mode 100644 .github/workflows/stale.yml diff --git a/.github/workflows/stale.yaml b/.github/workflows/stale.yaml new file mode 100644 index 0000000000..2a8cdf75af --- /dev/null +++ b/.github/workflows/stale.yaml @@ -0,0 +1,11 @@ +name: Close stale issues and PRs + +on: + schedule: + - cron: '0 19 * * *' + + workflow_dispatch: + +jobs: + stale: + uses: glotzerlab/workflows/.github/workflows/stale.yaml@5cfac9da9cb78e16ae97a9119b6fd13c1c2d6f5e # 0.1.0 diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml deleted file mode 100644 index e3c8161c7b..0000000000 --- a/.github/workflows/stale.yml +++ /dev/null @@ -1,39 +0,0 @@ -name: Close stale issues and PRs - -on: - schedule: - - cron: '0 19 * * *' - - # Trigger on request. - workflow_dispatch: - -jobs: - stale: - runs-on: ubuntu-latest - steps: - - name: Run stale action - uses: actions/stale@v9.0.0 - with: - operations-per-run: 120 - delete-branch: true - days-before-close: 10 - stale-issue-label: stale - stale-pr-label: stale - exempt-issue-labels: essential - exempt-pr-labels: essential - - days-before-issue-stale: 260 - stale-issue-message: > - This issue has been automatically marked as stale because it has not had - recent activity. It will be closed if no further activity occurs. - close-issue-message: > - This issue has been automatically closed because it has not had - recent activity. - - days-before-pr-stale: 20 - stale-pr-message: > - This pull request has been automatically marked as stale because it has not had - recent activity. It will be closed if no further activity occurs. - close-pr-message: > - This pull request has been automatically closed because it has not had - recent activity. From 8566a854fc15e0127c20ae11ba44051dce269c73 Mon Sep 17 00:00:00 2001 From: "Joshua A. Anderson" Date: Thu, 6 Jun 2024 14:22:24 -0400 Subject: [PATCH 17/32] Refactor release workflow. --- .github/workflows/release.yaml | 95 ++++++++++++++++++++++++++++++++ .github/workflows/release.yml | 98 ---------------------------------- 2 files changed, 95 insertions(+), 98 deletions(-) create mode 100644 .github/workflows/release.yaml delete mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 0000000000..0802c287e3 --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,95 @@ +name: GitHub Release + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +on: + pull_request: + + push: + branches: + - "trunk-*" + tags: + - "v*" + + workflow_dispatch: + + +env: + name: hoomd + +defaults: + run: + shell: bash + + +jobs: + release: + name: Build release tarball + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + with: + fetch-depth: 0 + submodules: true + path: code + + - name: Install tools + run: sudo apt-get install pcregrep pandoc + + - name: Determine last tag via git describe + if: ${{ ! startsWith(github.ref, 'refs/tags/v') }} + run: echo "tag=$(git describe --abbrev=0)" >> $GITHUB_ENV + working-directory: code + + # git describe does not return the current tag in tag pushes on GitHub Actions, use GITHUB_REF instead + - name: Determine tag from GITHUB_REF + if: startsWith(github.ref, 'refs/tags/v') + run: echo "tag=$(echo ${GITHUB_REF} | sed -e 's/refs\/tags\///g')" >> $GITHUB_ENV + + - name: Write version change log + run: .github/workflows/make-changelog-md.sh ${tag:1} | tee ${GITHUB_WORKSPACE}/changelog.md + working-directory: code + + - name: Copy source + run: cp -R code ${name}-${tag:1} + + - name: Remove .git + run: rm -rf ${name}-${tag:1}/.git && ls -laR ${name}-${tag:1} + + - name: Tar source + run: tar -cvzf ${name}-${tag:1}.tar.gz ${name}-${tag:1} + + - name: Tar source + run: tar -cvJf ${name}-${tag:1}.tar.xz ${name}-${tag:1} + + - name: Upload release files + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + with: + name: release + path: | + *.tar.gz + changelog.md + + publish: + name: Publish [GitHub] + needs: [release] + runs-on: ubuntu-latest + + steps: + - name: Download artifacts + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 + with: + name: release + + - name: Create release + uses: softprops/action-gh-release@69320dbe05506a9a39fc8ae11030b214ec2d1f87 # v2.0.5 + if: startsWith(github.ref, 'refs/tags/v') + with: + files: "*.tar.*" + body_path: changelog.md + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index 2a31363a83..0000000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,98 +0,0 @@ -# Edit `release.yml` in `.github/workflows/templates` and run `make_workflows.py` to update the -# workflow. -name: GitHub Release - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -on: - # Trigger on pull requests. - pull_request: - - # Trigger on pushes to the trunk branches. This prevents building commits twice when the pull - # request source branch is in the same repository. - push: - branches: - - "trunk-*" - # Trigger on tags. Tag builds create GitHub releases with the change log and source tarball. - tags: - - "v*" - - # Trigger on request. - workflow_dispatch: - - -env: - name: hoomd - -defaults: - run: - shell: bash - - -jobs: - release: - name: Build release tarball - runs-on: ubuntu-latest - container: - image: glotzerlab/ci:2024.06.04-ubuntu20.04 - - steps: - - name: Checkout - uses: actions/checkout@v4.1.4 - with: - fetch-depth: 0 - submodules: true - path: code - - - name: Determine last tag via git describe - if: ${{ ! startsWith(github.ref, 'refs/tags/v') }} - run: echo "tag=$(git describe --abbrev=0)" >> $GITHUB_ENV - working-directory: code - - # git describe does not return the current tag in tag pushes on GitHub Actions, use GITHUB_REF instead - - name: Determine tag from GITHUB_REF - if: startsWith(github.ref, 'refs/tags/v') - run: echo "tag=$(echo ${GITHUB_REF} | sed -e 's/refs\/tags\///g')" >> $GITHUB_ENV - - - name: Write version change log - run: .github/workflows/make-changelog-md.sh ${tag:1} | tee ${GITHUB_WORKSPACE}/changelog.md - working-directory: code - - - name: Copy source - run: cp -R code ${name}-${tag:1} - - - name: Remove .git - run: rm -rf ${name}-${tag:1}/.git && ls -laR ${name}-${tag:1} - - - name: Tar source - run: tar -cvzf ${name}-${tag:1}.tar.gz ${name}-${tag:1} - - - name: Upload release files - uses: actions/upload-artifact@v4.3.3 - with: - name: release - path: | - *.tar.gz - changelog.md - - publish: - name: Publish [GitHub] - needs: [release] - runs-on: ubuntu-latest - - steps: - - name: Download artifacts - uses: actions/download-artifact@v4.1.7 - with: - name: release - - - name: Create release - uses: softprops/action-gh-release@v2.0.2 - if: startsWith(github.ref, 'refs/tags/v') - with: - files: "*.tar.gz" - body_path: changelog.md - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From ea3e878ab29b3ad4173040bbf670a83605a379a4 Mon Sep 17 00:00:00 2001 From: "Joshua A. Anderson" Date: Thu, 6 Jun 2024 14:24:30 -0400 Subject: [PATCH 18/32] Remove debug code. --- .github/workflows/build_and_test.yaml | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/.github/workflows/build_and_test.yaml b/.github/workflows/build_and_test.yaml index 06ad4c3a88..3cda6bae51 100644 --- a/.github/workflows/build_and_test.yaml +++ b/.github/workflows/build_and_test.yaml @@ -42,18 +42,6 @@ env: PYTHONPATH: ${{ github.workspace }}/install jobs: - debug: - runs-on: ubuntu-latest - steps: - - name: build_runner - run: echo '${{ inputs.build_runner }}' - - name: build_runner_from_json - run: echo '${{ fromJson(inputs.build_runner) }}' - - name: test_runner - run: echo '${{ inputs.test_runner }}' - - name: test_runner_from_json - run: echo '${{ fromJson(inputs.test_runner) }}' - build: runs-on: ${{ fromJson(inputs.build_runner) }} container: From 084019349c7d7a851a3623c2404c84e39f15f281 Mon Sep 17 00:00:00 2001 From: "Joshua A. Anderson" Date: Thu, 6 Jun 2024 14:25:39 -0400 Subject: [PATCH 19/32] Update GitHub actions with dependabot. --- .github/dependabot.yaml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml index e55f6a0839..87985bd108 100644 --- a/.github/dependabot.yaml +++ b/.github/dependabot.yaml @@ -1,5 +1,26 @@ version: 2 updates: +- package-ecosystem: "github-actions" + directory: "/" + target-branch: trunk-patch + schedule: + interval: "monthly" + time: "07:00" + timezone: "EST5EDT" + pull-request-branch-name: + separator: "-" + open-pull-requests-limit: 2 + reviewers: + - joaander + groups: + actions-version: + applies-to: version-updates + patterns: + - '*' + actions-security: + applies-to: security-updates + patterns: + - '*' - package-ecosystem: "pip" directory: "/" target-branch: trunk-patch From 882f17e3608559b2ffaee212f27c2499a289ff03 Mon Sep 17 00:00:00 2001 From: "Joshua A. Anderson" Date: Thu, 6 Jun 2024 14:26:55 -0400 Subject: [PATCH 20/32] Run pre-commit. --- .github/workflows/build_and_test.yaml | 14 +++++++------- .github/workflows/test.yaml | 6 +++--- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/build_and_test.yaml b/.github/workflows/build_and_test.yaml index 3cda6bae51..8150e64ad6 100644 --- a/.github/workflows/build_and_test.yaml +++ b/.github/workflows/build_and_test.yaml @@ -23,7 +23,7 @@ on: validate: type: string required: false - + env: # prevent deadlocked MPI tests from causing the job to cancel MPIEXEC_TIMEOUT: 3000 @@ -87,11 +87,11 @@ jobs: BUILD_HPMC: ${{ !contains(inputs.config, 'nohpmc') }} BUILD_DEBUG: ${{ contains(inputs.config, 'debug') }} shell: bash - + - name: Build run: ninja install -j $(($(getconf _NPROCESSORS_ONLN) + 2)) working-directory: build - + - name: Configure plugins run : | if [[ ${BUILD_DEBUG} == "true" ]]; then BUILD_TYPE="Debug"; else BUILD_TYPE="Release"; fi @@ -100,20 +100,20 @@ jobs: env: BUILD_DEBUG: ${{ contains(inputs.config, 'debug') }} shell: bash - + - name: Build plugins run: ninja install -j $(($(getconf _NPROCESSORS_ONLN) + 2)) working-directory: build-example-plugins - name: Remove object files run: find build -type f -name '*.o' -delete - + - name: 'Tar build' run: tar --use-compress-program='zstd -10 -T0' -cvf build.tar build - + - name: 'Tar install' run: tar --use-compress-program='zstd -10 -T0' -cvf install.tar install - + - name: 'Upload build' uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 with: diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index c25139e03a..7ed0558870 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -56,11 +56,11 @@ jobs: validate: 'true' - config: [gcc13_py312, nomd] - + - config: [gcc13_py312, nohpmc] - + - config: [gcc13_py312, nomd, nohpmc] - + - config: [cuda120_gcc11_py310, mpi, llvm, debug] test_runner: [self-hosted,GPU] test_docker_options: '--gpus=all --device /dev/nvidia0 --device /dev/nvidia1 --device /dev/nvidia-uvm --device /dev/nvidia-uvm-tools --device /dev/nvidiactl' From feeedea5bc4b97e6b884a5c5b2cc0df2336081a6 Mon Sep 17 00:00:00 2001 From: "Joshua A. Anderson" Date: Thu, 6 Jun 2024 14:42:34 -0400 Subject: [PATCH 21/32] Pass full image name to reusable workflow. --- .github/workflows/build_and_test.yaml | 8 ++++---- .github/workflows/test.yaml | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build_and_test.yaml b/.github/workflows/build_and_test.yaml index 8150e64ad6..b0822af312 100644 --- a/.github/workflows/build_and_test.yaml +++ b/.github/workflows/build_and_test.yaml @@ -6,7 +6,7 @@ on: config: type: string required: true - container_prefix: + image: type: string required: true build_runner: @@ -45,7 +45,7 @@ jobs: build: runs-on: ${{ fromJson(inputs.build_runner) }} container: - image: glotzerlab/ci:2024.06.04-${{ inputs.container_prefix }} + image: ${{ inputs.image == '' && null || inputs.image }} steps: - name: Set Werror on recent compilers @@ -139,7 +139,7 @@ jobs: needs: build runs-on: ${{ fromJson(inputs.test_runner) }} container: - image: glotzerlab/ci:2024.06.04-${{ inputs.container_prefix }} + image: ${{ inputs.image == '' && null || inputs.image }} options: ${{ inputs.test_docker_options }} -e CUDA_VISIBLE_DEVICES steps: @@ -205,7 +205,7 @@ jobs: needs: build runs-on: ${{ fromJson(inputs.test_runner) }} container: - image: glotzerlab/ci:2024.06.04-${{ inputs.container_prefix }} + image: ${{ inputs.image == '' && null || inputs.image }} options: ${{ inputs.test_docker_options }} -e CUDA_VISIBLE_DEVICES steps: diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 7ed0558870..d3fedbd0eb 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -26,7 +26,7 @@ jobs: uses: ./.github/workflows/build_and_test.yaml with: config: ${{ join(matrix.config, '_') }} - container_prefix: ${{ matrix.config[0] }} + image: glotzerlab/ci:2024.06.04-${{ matrix.config[0] }} # Use self-hosted runners or fall back to GitHub hosted runners when self-hosted are offline build_runner: ${{ needs.start_action_runners.outputs.active == '0' && toJson('ubuntu-latest') || '["self-hosted","jetstream2","CPU"]' }} # Default to ubuntu-latest when unset @@ -74,7 +74,7 @@ jobs: uses: ./.github/workflows/build_and_test.yaml with: config: ${{ join(matrix.config, '_') }} - container_prefix: ${{ matrix.config[0] }} + image: glotzerlab/ci:2024.06.04-${{ matrix.config[0] }} # Use self-hosted runners or fall back to GitHub hosted runners when self-hosted are offline build_runner: ${{ needs.start_action_runners.outputs.active == '0' && toJson('ubuntu-latest') || '["self-hosted","jetstream2","CPU"]' }} # Default to ubuntu-latest when unset From e39b0135ebce6e18897d28bdcd7e50b8a7351f83 Mon Sep 17 00:00:00 2001 From: "Joshua A. Anderson" Date: Thu, 6 Jun 2024 14:49:34 -0400 Subject: [PATCH 22/32] Document currently tested compilers. --- BUILDING.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BUILDING.rst b/BUILDING.rst index 364554c03b..ee53f21856 100644 --- a/BUILDING.rst +++ b/BUILDING.rst @@ -77,7 +77,7 @@ Install prerequisites **General requirements:** -- C++17 capable compiler (tested with ``gcc`` 9 - 13 and ``clang`` 10 - 16) +- C++17 capable compiler (tested with ``gcc`` 9 - 14 and ``clang`` 10 - 18) - Python >= 3.9 - NumPy >= 1.19 - pybind11 >= 2.12 From bd5d505e245f3a293c0534db03ebf017f5fb1592 Mon Sep 17 00:00:00 2001 From: "Joshua A. Anderson" Date: Thu, 6 Jun 2024 15:22:40 -0400 Subject: [PATCH 23/32] Remove template specifier on constructors and destructors. --- hoomd/md/PotentialExternal.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hoomd/md/PotentialExternal.h b/hoomd/md/PotentialExternal.h index d637aca31c..700ae00c14 100644 --- a/hoomd/md/PotentialExternal.h +++ b/hoomd/md/PotentialExternal.h @@ -37,8 +37,8 @@ template class PotentialExternal : public ForceCompute { public: //! Constructs the compute - PotentialExternal(std::shared_ptr sysdef); - virtual ~PotentialExternal(); + PotentialExternal(std::shared_ptr sysdef); + virtual ~PotentialExternal(); //! type of external potential parameters typedef typename evaluator::param_type param_type; From ebd5581e860ebb90a648fd7726eae4adde3b4d57 Mon Sep 17 00:00:00 2001 From: "Joshua A. Anderson" Date: Thu, 6 Jun 2024 15:52:15 -0400 Subject: [PATCH 24/32] Use std::vector for variable MPI request arrays. --- .github/workflows/test.yaml | 2 +- hoomd/Communicator.cc | 18 +++++++++--------- hoomd/CommunicatorGPU.cc | 30 +++++++++++++++--------------- hoomd/HOOMDMPI.h | 1 + hoomd/LoadBalancer.cc | 10 +++++----- 5 files changed, 31 insertions(+), 30 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index d3fedbd0eb..65e1afecc1 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -94,7 +94,7 @@ jobs: - config: [clang13_py310, llvm] - config: [clang12_py310, llvm] - config: [clang11_py310, llvm] - - config: [gcc14_py312] + - config: [gcc14_py312, mpi] - config: [gcc12_py311] - config: [gcc11_py310] - config: [gcc10_py310] diff --git a/hoomd/Communicator.cc b/hoomd/Communicator.cc index 3b1165d2b3..67a8b0b30d 100644 --- a/hoomd/Communicator.cc +++ b/hoomd/Communicator.cc @@ -254,9 +254,9 @@ void Communicator::GroupCommunicator::migrateGroups(bool incomplete, /* * communicate rank information (phase 1) */ - unsigned int n_send_groups[m_comm.m_n_unique_neigh]; - unsigned int n_recv_groups[m_comm.m_n_unique_neigh]; - unsigned int offs[m_comm.m_n_unique_neigh]; + std::vector n_send_groups(m_comm.m_n_unique_neigh); + std::vector n_recv_groups(m_comm.m_n_unique_neigh); + std::vector offs(m_comm.m_n_unique_neigh); unsigned int n_recv_tot = 0; { @@ -272,8 +272,8 @@ void Communicator::GroupCommunicator::migrateGroups(bool incomplete, for (unsigned int ineigh = 0; ineigh < m_comm.m_n_unique_neigh; ineigh++) n_send_groups[ineigh] = h_end.data[ineigh] - h_begin.data[ineigh]; - MPI_Request req[2 * m_comm.m_n_unique_neigh]; - MPI_Status stat[2 * m_comm.m_n_unique_neigh]; + std::vector req(2 * m_comm.m_n_unique_neigh); + std::vector stat(2 * m_comm.m_n_unique_neigh); unsigned int nreq = 0; @@ -299,7 +299,7 @@ void Communicator::GroupCommunicator::migrateGroups(bool incomplete, &req[nreq++]); } // end neighbor loop - MPI_Waitall(nreq, req, stat); + MPI_Waitall(nreq, req.data(), stat.data()); // sum up receive counts for (unsigned int ineigh = 0; ineigh < m_comm.m_n_unique_neigh; ineigh++) @@ -601,8 +601,8 @@ void Communicator::GroupCommunicator::migrateGroups(bool incomplete, for (unsigned int ineigh = 0; ineigh < m_comm.m_n_unique_neigh; ineigh++) n_send_groups[ineigh] = h_end.data[ineigh] - h_begin.data[ineigh]; - MPI_Request req[2 * m_comm.m_n_unique_neigh]; - MPI_Status stat[2 * m_comm.m_n_unique_neigh]; + std::vector req(2 * m_comm.m_n_unique_neigh); + std::vector stat(2 * m_comm.m_n_unique_neigh); unsigned int nreq = 0; @@ -628,7 +628,7 @@ void Communicator::GroupCommunicator::migrateGroups(bool incomplete, &req[nreq++]); } // end neighbor loop - MPI_Waitall(nreq, req, stat); + MPI_Waitall(nreq, req.data(), stat.data()); // sum up receive counts for (unsigned int ineigh = 0; ineigh < m_comm.m_n_unique_neigh; ineigh++) diff --git a/hoomd/CommunicatorGPU.cc b/hoomd/CommunicatorGPU.cc index 6e14af15b2..b8f67b2a93 100644 --- a/hoomd/CommunicatorGPU.cc +++ b/hoomd/CommunicatorGPU.cc @@ -704,8 +704,8 @@ void CommunicatorGPU::GroupCommunicatorGPU::migrateGroups(bool incom for (unsigned int ineigh = 0; ineigh < m_gpu_comm.m_n_unique_neigh; ineigh++) n_send_groups[ineigh] = h_end.data[ineigh] - h_begin.data[ineigh]; - MPI_Request req[2 * m_gpu_comm.m_n_unique_neigh]; - MPI_Status stat[2 * m_gpu_comm.m_n_unique_neigh]; + std::vector req(2 * m_gpu_comm.m_n_unique_neigh); + std::vector stat(2 * m_gpu_comm.m_n_unique_neigh); unsigned int nreq = 0; @@ -733,7 +733,7 @@ void CommunicatorGPU::GroupCommunicatorGPU::migrateGroups(bool incom recv_bytes += (unsigned int)sizeof(unsigned int); } // end neighbor loop - MPI_Waitall(nreq, req, stat); + MPI_Waitall(nreq, req.data(), stat.data()); // sum up receive counts for (unsigned int ineigh = 0; ineigh < m_gpu_comm.m_n_unique_neigh; ineigh++) @@ -1059,8 +1059,8 @@ void CommunicatorGPU::GroupCommunicatorGPU::migrateGroups(bool incom for (unsigned int ineigh = 0; ineigh < m_gpu_comm.m_n_unique_neigh; ineigh++) n_send_groups[ineigh] = h_end.data[ineigh] - h_begin.data[ineigh]; - MPI_Request req[2 * m_gpu_comm.m_n_unique_neigh]; - MPI_Status stat[2 * m_gpu_comm.m_n_unique_neigh]; + std::vector req(2 * m_gpu_comm.m_n_unique_neigh); + std::vector stat(2 * m_gpu_comm.m_n_unique_neigh); unsigned int nreq = 0; @@ -1088,7 +1088,7 @@ void CommunicatorGPU::GroupCommunicatorGPU::migrateGroups(bool incom recv_bytes += (unsigned int)sizeof(unsigned int); } // end neighbor loop - MPI_Waitall(nreq, req, stat); + MPI_Waitall(nreq, req.data(), stat.data()); // sum up receive counts for (unsigned int ineigh = 0; ineigh < m_gpu_comm.m_n_unique_neigh; ineigh++) @@ -1488,8 +1488,8 @@ void CommunicatorGPU::GroupCommunicatorGPU::exchangeGhostGroups( = h_ghost_group_end.data[ineigh + stage * m_gpu_comm.m_n_unique_neigh] - h_ghost_group_begin.data[ineigh + stage * m_gpu_comm.m_n_unique_neigh]; - MPI_Request req[2 * m_gpu_comm.m_n_unique_neigh]; - MPI_Status stat[2 * m_gpu_comm.m_n_unique_neigh]; + std::vector req(2 * m_gpu_comm.m_n_unique_neigh); + std::vector stat(2 * m_gpu_comm.m_n_unique_neigh); unsigned int nreq = 0; @@ -1526,7 +1526,7 @@ void CommunicatorGPU::GroupCommunicatorGPU::exchangeGhostGroups( recv_bytes += (unsigned int)sizeof(unsigned int); } - MPI_Waitall(nreq, req, stat); + MPI_Waitall(nreq, req.data(), stat.data()); // total up receive counts for (unsigned int ineigh = 0; ineigh < m_gpu_comm.m_n_unique_neigh; ineigh++) @@ -1902,8 +1902,8 @@ void CommunicatorGPU::migrateParticles() for (unsigned int ineigh = 0; ineigh < m_n_unique_neigh; ineigh++) n_send_ptls[ineigh] = h_end.data[ineigh] - h_begin.data[ineigh]; - MPI_Request req[2 * m_n_unique_neigh]; - MPI_Status stat[2 * m_n_unique_neigh]; + std::vector req(2 * m_n_unique_neigh); + std::vector stat(2 * m_n_unique_neigh); unsigned int nreq = 0; @@ -1939,7 +1939,7 @@ void CommunicatorGPU::migrateParticles() recv_bytes += (unsigned int)sizeof(unsigned int); } // end neighbor loop - MPI_Waitall(nreq, req, stat); + MPI_Waitall(nreq, req.data(), stat.data()); // sum up receive counts for (unsigned int ineigh = 0; ineigh < m_n_unique_neigh; ineigh++) @@ -2405,8 +2405,8 @@ void CommunicatorGPU::exchangeGhosts() = h_ghost_end.data[ineigh + stage * m_n_unique_neigh] - h_ghost_begin.data[ineigh + stage * m_n_unique_neigh]; - MPI_Request req[2 * m_n_unique_neigh]; - MPI_Status stat[2 * m_n_unique_neigh]; + std::vector req(2 * m_n_unique_neigh); + std::vector stat(2 * m_n_unique_neigh); unsigned int nreq = 0; @@ -2443,7 +2443,7 @@ void CommunicatorGPU::exchangeGhosts() recv_bytes += (unsigned int)sizeof(unsigned int); } - MPI_Waitall(nreq, req, stat); + MPI_Waitall(nreq, req.data(), stat.data()); // total up receive counts for (unsigned int ineigh = 0; ineigh < m_n_unique_neigh; ineigh++) diff --git a/hoomd/HOOMDMPI.h b/hoomd/HOOMDMPI.h index 58115e52b3..3cedc49212 100644 --- a/hoomd/HOOMDMPI.h +++ b/hoomd/HOOMDMPI.h @@ -20,6 +20,7 @@ #include +#include #include #include #include diff --git a/hoomd/LoadBalancer.cc b/hoomd/LoadBalancer.cc index 38f9fce00a..1b4bde01e6 100644 --- a/hoomd/LoadBalancer.cc +++ b/hoomd/LoadBalancer.cc @@ -564,12 +564,12 @@ void LoadBalancer::computeOwnedParticles() } countParticlesOffRank(cnts); - MPI_Request req[2 * m_comm->getNUniqueNeighbors()]; - MPI_Status stat[2 * m_comm->getNUniqueNeighbors()]; + std::vector req(2 * m_comm->getNUniqueNeighbors()); + std::vector stat(2 * m_comm->getNUniqueNeighbors()); unsigned int nreq = 0; - unsigned int n_send_ptls[m_comm->getNUniqueNeighbors()]; - unsigned int n_recv_ptls[m_comm->getNUniqueNeighbors()]; + std::vector n_send_ptls(m_comm->getNUniqueNeighbors()); + std::vector n_recv_ptls(m_comm->getNUniqueNeighbors()); for (unsigned int cur_neigh = 0; cur_neigh < m_comm->getNUniqueNeighbors(); ++cur_neigh) { unsigned int neigh_rank = h_unique_neigh.data[cur_neigh]; @@ -590,7 +590,7 @@ void LoadBalancer::computeOwnedParticles() m_mpi_comm, &req[nreq++]); } - MPI_Waitall(nreq, req, stat); + MPI_Waitall(nreq, req.data(), stat.data()); // reduce the particles sent to me int N_own = m_pdata->getN(); From 2d6e6cef62aa02978bba10989d1fbf95661a55a7 Mon Sep 17 00:00:00 2001 From: "Joshua A. Anderson" Date: Thu, 6 Jun 2024 16:21:49 -0400 Subject: [PATCH 25/32] Fix more variable arrays. --- .github/workflows/build_and_test.yaml | 4 ++-- hoomd/md/NeighborList.cc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build_and_test.yaml b/.github/workflows/build_and_test.yaml index b0822af312..4a506a84df 100644 --- a/.github/workflows/build_and_test.yaml +++ b/.github/workflows/build_and_test.yaml @@ -89,7 +89,7 @@ jobs: shell: bash - name: Build - run: ninja install -j $(($(getconf _NPROCESSORS_ONLN) + 2)) + run: ninja install -j $(($(getconf _NPROCESSORS_ONLN) + 2)) -k 0 working-directory: build - name: Configure plugins @@ -102,7 +102,7 @@ jobs: shell: bash - name: Build plugins - run: ninja install -j $(($(getconf _NPROCESSORS_ONLN) + 2)) + run: ninja install -j $(($(getconf _NPROCESSORS_ONLN) + 2)) -k 0 working-directory: build-example-plugins - name: Remove object files diff --git a/hoomd/md/NeighborList.cc b/hoomd/md/NeighborList.cc index f6d0ccd5bc..0a67d5db3c 100644 --- a/hoomd/md/NeighborList.cc +++ b/hoomd/md/NeighborList.cc @@ -750,7 +750,7 @@ pybind11::list NeighborList::getExclusions() */ void NeighborList::countExclusions() { - unsigned int MAX_COUNT_EXCLUDED = 16; + constexpr unsigned int MAX_COUNT_EXCLUDED = 16; unsigned int excluded_count[MAX_COUNT_EXCLUDED + 2]; unsigned int num_excluded, max_num_excluded; From 43e20cd7df41c98df7110986410cb9bcb9c1e71b Mon Sep 17 00:00:00 2001 From: "Joshua A. Anderson" Date: Thu, 6 Jun 2024 16:32:04 -0400 Subject: [PATCH 26/32] Fix an uninitialized variable warning. --- hoomd/mpcd/test/communicator_mpi_test.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hoomd/mpcd/test/communicator_mpi_test.cc b/hoomd/mpcd/test/communicator_mpi_test.cc index 118f1862e9..3a8af9bc02 100644 --- a/hoomd/mpcd/test/communicator_mpi_test.cc +++ b/hoomd/mpcd/test/communicator_mpi_test.cc @@ -480,7 +480,8 @@ void test_communicator_migrate(communicator_creator comm_creator, comm->migrateParticles(2); { unsigned int tag(0xffffffff), type(0xffffffff); - Scalar3 pos, vel; + Scalar3 pos = make_scalar3(0,0,0); + Scalar3 vel = make_scalar3(0,0,0); if (pdata->getN()) { From 0d7b90933086694e40ea23ac8e7cbb99d996020d Mon Sep 17 00:00:00 2001 From: "Joshua A. Anderson" Date: Thu, 6 Jun 2024 17:53:42 -0400 Subject: [PATCH 27/32] Fix more uses of VLAs. --- hoomd/hpmc/ShapeConvexPolyhedron.h | 2 ++ hoomd/hpmc/ShapeUnion.h | 6 +++--- hoomd/hpmc/UpdaterMuVT.h | 12 ++++++------ 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/hoomd/hpmc/ShapeConvexPolyhedron.h b/hoomd/hpmc/ShapeConvexPolyhedron.h index 561fcdf004..ee6e87f046 100644 --- a/hoomd/hpmc/ShapeConvexPolyhedron.h +++ b/hoomd/hpmc/ShapeConvexPolyhedron.h @@ -229,6 +229,8 @@ struct PolyhedronVertices : ShapeParams /// Z coordinate of vertices ManagedArray z; + /// TODO: store aligned copy of d here for use in the support function. + /** List of triangles hull_verts[3*i], hull_verts[3*i+1], hull_verts[3*i+2] making up the convex hull */ diff --git a/hoomd/hpmc/ShapeUnion.h b/hoomd/hpmc/ShapeUnion.h index bfff2da48d..3967e4faf8 100644 --- a/hoomd/hpmc/ShapeUnion.h +++ b/hoomd/hpmc/ShapeUnion.h @@ -1124,13 +1124,13 @@ DEVICE inline bool sample_narrow_phase(RNG& rng, r, dim, detail::SamplingMethod::accurate); - typename Shape::depletion_storage_type temp[ntemp]; + std::vector temp(ntemp); unsigned int nelem = initializeDepletionTemporaryStorage(shape_i, shape_j, r_ij, r, dim, - temp, + temp.data(), V, detail::SamplingMethod::accurate); @@ -1143,7 +1143,7 @@ DEVICE inline bool sample_narrow_phase(RNG& rng, p, dim, nelem, - temp, + temp.data(), detail::SamplingMethod::accurate)) return false; diff --git a/hoomd/hpmc/UpdaterMuVT.h b/hoomd/hpmc/UpdaterMuVT.h index ccf4be40e0..f9b342e87e 100644 --- a/hoomd/hpmc/UpdaterMuVT.h +++ b/hoomd/hpmc/UpdaterMuVT.h @@ -1010,15 +1010,15 @@ template void UpdaterMuVT::update(uint64_t timestep) 0, m_exec_conf->getHOOMDWorldMPICommunicator(), &stat); - char s[n]; - MPI_Recv(s, + std::vector s(n); + MPI_Recv(s.data(), n, MPI_CHAR, m_gibbs_other, 0, m_exec_conf->getHOOMDWorldMPICommunicator(), &stat); - type_name = std::string(s); + type_name = std::string(s.data()); // resolve type name type = m_pdata->getTypeByName(type_name); @@ -1245,9 +1245,9 @@ template void UpdaterMuVT::update(uint64_t timestep) m_gibbs_other, 0, m_exec_conf->getHOOMDWorldMPICommunicator()); - char s[n]; - memcpy(s, type_name.c_str(), n); - MPI_Send(s, + std::vector s(n); + memcpy(s.data(), type_name.c_str(), n); + MPI_Send(s.data(), n, MPI_CHAR, m_gibbs_other, From c03d8cb63769c3760ff4e5e657001bc173c0bca5 Mon Sep 17 00:00:00 2001 From: "Joshua A. Anderson" Date: Mon, 10 Jun 2024 11:08:28 -0400 Subject: [PATCH 28/32] Inline much of the convex polyhedron overlap code. --- hoomd/VectorMath.h | 2 +- hoomd/hpmc/MinkowskiMath.h | 2 +- hoomd/hpmc/ShapeConvexPolyhedron.h | 6 +++--- hoomd/hpmc/XenoCollide3D.h | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/hoomd/VectorMath.h b/hoomd/VectorMath.h index ec32096a9a..d570f299b9 100644 --- a/hoomd/VectorMath.h +++ b/hoomd/VectorMath.h @@ -1187,7 +1187,7 @@ template struct rotmat3 Multiplication is matrix multiplication, where the vector is represented as a column vector. */ -template DEVICE inline vec3 operator*(const rotmat3& A, const vec3& b) +template DEVICE inline __attribute__((always_inline)) vec3 operator*(const rotmat3& A, const vec3& b) { return vec3(dot(A.row0, b), dot(A.row1, b), dot(A.row2, b)); } diff --git a/hoomd/hpmc/MinkowskiMath.h b/hoomd/hpmc/MinkowskiMath.h index b4a14cddd4..72100a98c5 100644 --- a/hoomd/hpmc/MinkowskiMath.h +++ b/hoomd/hpmc/MinkowskiMath.h @@ -65,7 +65,7 @@ template class CompositeSupportFunc3D \returns S_B(n) - S_A(n) in world space coords (transformations put n into local coords for S_A and S_b) */ - DEVICE vec3 operator()(const vec3& n) const + DEVICE inline __attribute__((always_inline)) vec3 operator()(const vec3& n) const { // translation/rotation formula comes from pg 168 of "Games Programming Gems 7" #ifdef __HIPCC__ diff --git a/hoomd/hpmc/ShapeConvexPolyhedron.h b/hoomd/hpmc/ShapeConvexPolyhedron.h index ee6e87f046..0e4ffe8527 100644 --- a/hoomd/hpmc/ShapeConvexPolyhedron.h +++ b/hoomd/hpmc/ShapeConvexPolyhedron.h @@ -270,7 +270,7 @@ class SupportFuncConvexPolyhedron Note that for performance it is assumed that unused vertices (beyond N) have already been set to zero. */ - DEVICE SupportFuncConvexPolyhedron(const PolyhedronVertices& _verts, + DEVICE inline SupportFuncConvexPolyhedron(const PolyhedronVertices& _verts, ShortReal extra_sweep_radius = ShortReal(0.0)) : verts(_verts), sweep_radius(extra_sweep_radius) { @@ -281,7 +281,7 @@ class SupportFuncConvexPolyhedron @param n Normal vector input (in the local frame) @returns Local coords of the point furthest in the direction of n */ - DEVICE vec3 operator()(const vec3& n) const + DEVICE inline __attribute__((always_inline)) vec3 operator()(const vec3& n) const { ShortReal max_dot = -(verts.diameter * verts.diameter); unsigned int max_idx = 0; @@ -791,7 +791,7 @@ struct ShapeConvexPolyhedron @returns true when *a* and *b* overlap, and false when they are disjoint */ template<> -DEVICE inline bool test_overlap(const vec3& r_ab, +DEVICE inline __attribute__((always_inline)) bool test_overlap(const vec3& r_ab, const ShapeConvexPolyhedron& a, const ShapeConvexPolyhedron& b, unsigned int& err) diff --git a/hoomd/hpmc/XenoCollide3D.h b/hoomd/hpmc/XenoCollide3D.h index fca8bc6814..80f0923c72 100644 --- a/hoomd/hpmc/XenoCollide3D.h +++ b/hoomd/hpmc/XenoCollide3D.h @@ -70,7 +70,7 @@ const unsigned int XENOCOLLIDE_3D_MAX_ITERATIONS = 1024; \ingroup minkowski */ template -DEVICE inline bool xenocollide_3d(const SupportFuncA& sa, +DEVICE inline __attribute__((always_inline)) bool xenocollide_3d(const SupportFuncA& sa, const SupportFuncB& sb, const vec3& ab_t, const quat& q, From d1dbc61fc5df4de64d26b5c9f27fd3933149d35f Mon Sep 17 00:00:00 2001 From: "Joshua A. Anderson" Date: Mon, 10 Jun 2024 11:37:22 -0400 Subject: [PATCH 29/32] Replace scratchpad array with statically sized one. The maximum size is 4096 vertices. I doubt any user is attempting such a large vertex count polyhedron. --- hoomd/hpmc/ShapeConvexPolyhedron.h | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/hoomd/hpmc/ShapeConvexPolyhedron.h b/hoomd/hpmc/ShapeConvexPolyhedron.h index 0e4ffe8527..99ceaa3eef 100644 --- a/hoomd/hpmc/ShapeConvexPolyhedron.h +++ b/hoomd/hpmc/ShapeConvexPolyhedron.h @@ -43,6 +43,8 @@ namespace detail */ struct PolyhedronVertices : ShapeParams { + static constexpr unsigned int MAX_VERTS = 4096; + /// Default constructor initializes zero values. DEVICE PolyhedronVertices() : n_hull_verts(0), N(0), diameter(ShortReal(0)), sweep_radius(ShortReal(0)), ignore(0) @@ -81,6 +83,12 @@ struct PolyhedronVertices : ShapeParams bool managed = false) { N = (unsigned int)verts.size(); + + if (N > MAX_VERTS) + { + throw std::domain_error("Too many vertices in polyhedron."); + } + diameter = 0; sweep_radius = sweep_radius_; @@ -295,7 +303,7 @@ class SupportFuncConvexPolyhedron __m256 ny_v = _mm256_broadcast_ss(&n.y); __m256 nz_v = _mm256_broadcast_ss(&n.z); __m256 max_dot_v = _mm256_broadcast_ss(&max_dot); - float d_s[verts.x.size()] __attribute__((aligned(32))); + float d_s[PolyhedronVertices::MAX_VERTS] __attribute__((aligned(32))); for (unsigned int i = 0; i < verts.N; i += 8) { @@ -347,7 +355,7 @@ class SupportFuncConvexPolyhedron __m128 ny_v = _mm_load_ps1(&n.y); __m128 nz_v = _mm_load_ps1(&n.z); __m128 max_dot_v = _mm_load_ps1(&max_dot); - float d_s[verts.x.size()] __attribute__((aligned(16))); + float d_s[PolyhedronVertices::MAX_VERTS] __attribute__((aligned(16))); for (unsigned int i = 0; i < verts.N; i += 4) { From b16a9e9d560b60a1852552f39255d5590cc90d80 Mon Sep 17 00:00:00 2001 From: "Joshua A. Anderson" Date: Mon, 10 Jun 2024 11:38:30 -0400 Subject: [PATCH 30/32] Run pre-commit. --- hoomd/VectorMath.h | 4 +++- hoomd/hpmc/MinkowskiMath.h | 3 ++- hoomd/hpmc/ShapeConvexPolyhedron.h | 15 ++++++++------- hoomd/hpmc/XenoCollide3D.h | 10 +++++----- hoomd/mpcd/test/communicator_mpi_test.cc | 4 ++-- 5 files changed, 20 insertions(+), 16 deletions(-) diff --git a/hoomd/VectorMath.h b/hoomd/VectorMath.h index d570f299b9..b1714c8a56 100644 --- a/hoomd/VectorMath.h +++ b/hoomd/VectorMath.h @@ -1187,7 +1187,9 @@ template struct rotmat3 Multiplication is matrix multiplication, where the vector is represented as a column vector. */ -template DEVICE inline __attribute__((always_inline)) vec3 operator*(const rotmat3& A, const vec3& b) +template +DEVICE inline __attribute__((always_inline)) vec3 operator*(const rotmat3& A, + const vec3& b) { return vec3(dot(A.row0, b), dot(A.row1, b), dot(A.row2, b)); } diff --git a/hoomd/hpmc/MinkowskiMath.h b/hoomd/hpmc/MinkowskiMath.h index 72100a98c5..f0a1ea549c 100644 --- a/hoomd/hpmc/MinkowskiMath.h +++ b/hoomd/hpmc/MinkowskiMath.h @@ -65,7 +65,8 @@ template class CompositeSupportFunc3D \returns S_B(n) - S_A(n) in world space coords (transformations put n into local coords for S_A and S_b) */ - DEVICE inline __attribute__((always_inline)) vec3 operator()(const vec3& n) const + DEVICE inline __attribute__((always_inline)) vec3 + operator()(const vec3& n) const { // translation/rotation formula comes from pg 168 of "Games Programming Gems 7" #ifdef __HIPCC__ diff --git a/hoomd/hpmc/ShapeConvexPolyhedron.h b/hoomd/hpmc/ShapeConvexPolyhedron.h index 99ceaa3eef..5f591fce59 100644 --- a/hoomd/hpmc/ShapeConvexPolyhedron.h +++ b/hoomd/hpmc/ShapeConvexPolyhedron.h @@ -44,7 +44,7 @@ namespace detail struct PolyhedronVertices : ShapeParams { static constexpr unsigned int MAX_VERTS = 4096; - + /// Default constructor initializes zero values. DEVICE PolyhedronVertices() : n_hull_verts(0), N(0), diameter(ShortReal(0)), sweep_radius(ShortReal(0)), ignore(0) @@ -88,7 +88,7 @@ struct PolyhedronVertices : ShapeParams { throw std::domain_error("Too many vertices in polyhedron."); } - + diameter = 0; sweep_radius = sweep_radius_; @@ -279,7 +279,7 @@ class SupportFuncConvexPolyhedron been set to zero. */ DEVICE inline SupportFuncConvexPolyhedron(const PolyhedronVertices& _verts, - ShortReal extra_sweep_radius = ShortReal(0.0)) + ShortReal extra_sweep_radius = ShortReal(0.0)) : verts(_verts), sweep_radius(extra_sweep_radius) { } @@ -289,7 +289,8 @@ class SupportFuncConvexPolyhedron @param n Normal vector input (in the local frame) @returns Local coords of the point furthest in the direction of n */ - DEVICE inline __attribute__((always_inline)) vec3 operator()(const vec3& n) const + DEVICE inline __attribute__((always_inline)) vec3 + operator()(const vec3& n) const { ShortReal max_dot = -(verts.diameter * verts.diameter); unsigned int max_idx = 0; @@ -800,9 +801,9 @@ struct ShapeConvexPolyhedron */ template<> DEVICE inline __attribute__((always_inline)) bool test_overlap(const vec3& r_ab, - const ShapeConvexPolyhedron& a, - const ShapeConvexPolyhedron& b, - unsigned int& err) + const ShapeConvexPolyhedron& a, + const ShapeConvexPolyhedron& b, + unsigned int& err) { vec3 dr(r_ab); diff --git a/hoomd/hpmc/XenoCollide3D.h b/hoomd/hpmc/XenoCollide3D.h index 80f0923c72..6d5ca06ca4 100644 --- a/hoomd/hpmc/XenoCollide3D.h +++ b/hoomd/hpmc/XenoCollide3D.h @@ -71,11 +71,11 @@ const unsigned int XENOCOLLIDE_3D_MAX_ITERATIONS = 1024; */ template DEVICE inline __attribute__((always_inline)) bool xenocollide_3d(const SupportFuncA& sa, - const SupportFuncB& sb, - const vec3& ab_t, - const quat& q, - const ShortReal R, - unsigned int& err_count) + const SupportFuncB& sb, + const vec3& ab_t, + const quat& q, + const ShortReal R, + unsigned int& err_count) { // This implementation of XenoCollide is hand-written from the description of the algorithm on // page 171 of _Games Programming Gems 7_ diff --git a/hoomd/mpcd/test/communicator_mpi_test.cc b/hoomd/mpcd/test/communicator_mpi_test.cc index 3a8af9bc02..77c3767f02 100644 --- a/hoomd/mpcd/test/communicator_mpi_test.cc +++ b/hoomd/mpcd/test/communicator_mpi_test.cc @@ -480,8 +480,8 @@ void test_communicator_migrate(communicator_creator comm_creator, comm->migrateParticles(2); { unsigned int tag(0xffffffff), type(0xffffffff); - Scalar3 pos = make_scalar3(0,0,0); - Scalar3 vel = make_scalar3(0,0,0); + Scalar3 pos = make_scalar3(0, 0, 0); + Scalar3 vel = make_scalar3(0, 0, 0); if (pdata->getN()) { From e6eaf30bc22cb2bd858c661e3b469504e921b653 Mon Sep 17 00:00:00 2001 From: "Joshua A. Anderson" Date: Mon, 10 Jun 2024 12:01:35 -0400 Subject: [PATCH 31/32] Fix VLA usage in PotentialTersoff.h. --- hoomd/md/PotentialTersoff.h | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/hoomd/md/PotentialTersoff.h b/hoomd/md/PotentialTersoff.h index 225f403555..398465746b 100644 --- a/hoomd/md/PotentialTersoff.h +++ b/hoomd/md/PotentialTersoff.h @@ -135,6 +135,9 @@ template class PotentialTersoff : public ForceCompute // r_cut (not squared) given to the neighborlist std::shared_ptr> m_r_cut_nlist; + // scratch pad memory per type + std::vector m_phi_ab; + //! Actually compute the forces virtual void computeForces(uint64_t timestep); }; @@ -145,7 +148,8 @@ template class PotentialTersoff : public ForceCompute template PotentialTersoff::PotentialTersoff(std::shared_ptr sysdef, std::shared_ptr nlist) - : ForceCompute(sysdef), m_nlist(nlist), m_typpair_idx(m_pdata->getNTypes()) + : ForceCompute(sysdef), m_nlist(nlist), m_typpair_idx(m_pdata->getNTypes()), + m_phi_ab(m_pdata->getNTypes()) { this->m_exec_conf->msg->notice(5) << "Constructing PotentialTersoff" << std::endl; @@ -605,12 +609,10 @@ template void PotentialTersoff::computeForces(uint64 Scalar viriali_yz(0.0); Scalar viriali_zz(0.0); - Scalar phi_ab[ntypes]; - // reset phi for (unsigned int typ_b = 0; typ_b < ntypes; ++typ_b) { - phi_ab[typ_b] = Scalar(0.0); + m_phi_ab[typ_b] = Scalar(0.0); } // all neighbors of this particle @@ -645,7 +647,7 @@ template void PotentialTersoff::computeForces(uint64 // evaluate the scalar per-neighbor contribution evaluator eval(rij_sq, rcutsq, param); - eval.evalPhi(phi_ab[typej]); + eval.evalPhi(m_phi_ab[typej]); } // self-energy @@ -656,7 +658,7 @@ template void PotentialTersoff::computeForces(uint64 Scalar rcutsq = h_rcutsq.data[typpair_idx]; evaluator eval(Scalar(0.0), rcutsq, param); Scalar energy(0.0); - eval.evalSelfEnergy(energy, phi_ab[typ_b]); + eval.evalSelfEnergy(energy, m_phi_ab[typ_b]); pei += energy; } } @@ -760,7 +762,7 @@ template void PotentialTersoff::computeForces(uint64 Scalar force_divr = Scalar(0.0); Scalar potential_eng = Scalar(0.0); Scalar bij = Scalar(0.0); - eval.evalForceij(fR, fA, chi, phi_ab[typej], bij, force_divr, potential_eng); + eval.evalForceij(fR, fA, chi, m_phi_ab[typej], bij, force_divr, potential_eng); // add this force to particle i fi += force_divr * dxij; From 5adc61c2aa08c310965bde45b7b5a8c1b10a2a40 Mon Sep 17 00:00:00 2001 From: "Joshua A. Anderson" Date: Mon, 10 Jun 2024 13:12:56 -0400 Subject: [PATCH 32/32] Test the latest compilers in the typical build configurations. --- .github/workflows/test.yaml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 65e1afecc1..3f809d189f 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -39,7 +39,7 @@ jobs: fail-fast: false matrix: include: - - config: [clang14_py311, mpi, tbb, llvm] + - config: [clang18_py312, mpi, tbb] validate: 'true' - config: [gcc13_py312] @@ -55,11 +55,11 @@ jobs: test_docker_options: '--gpus=all --device /dev/nvidia0 --device /dev/nvidia1 --device /dev/nvidia-uvm --device /dev/nvidia-uvm-tools --device /dev/nvidiactl' validate: 'true' - - config: [gcc13_py312, nomd] + - config: [gcc14_py312, nomd] - - config: [gcc13_py312, nohpmc] + - config: [gcc14_py312, nohpmc] - - config: [gcc13_py312, nomd, nohpmc] + - config: [gcc14_py312, nomd, nohpmc] - config: [cuda120_gcc11_py310, mpi, llvm, debug] test_runner: [self-hosted,GPU] @@ -91,10 +91,11 @@ jobs: - config: [clang17_py312, mpi] - config: [clang16_py312, mpi, llvm] - config: [clang15_py312, mpi, llvm] + - config: [clang14_py311, mpi, tbb, llvm] - config: [clang13_py310, llvm] - config: [clang12_py310, llvm] - config: [clang11_py310, llvm] - - config: [gcc14_py312, mpi] + - config: [gcc13_py312, mpi] - config: [gcc12_py311] - config: [gcc11_py310] - config: [gcc10_py310]