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 diff --git a/.github/workflows/build_and_test.yaml b/.github/workflows/build_and_test.yaml new file mode 100644 index 0000000000..4a506a84df --- /dev/null +++ b/.github/workflows/build_and_test.yaml @@ -0,0 +1,242 @@ +name: Build and test + +on: + workflow_call: + inputs: + config: + type: string + required: true + image: + type: string + required: true + build_runner: + type: string + required: true + default: ubuntu-latest + test_runner: + type: string + required: true + default: ubuntu-latest + test_docker_options: + type: string + required: false + validate: + type: string + 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: + runs-on: ${{ fromJson(inputs.build_runner) }} + container: + image: ${{ inputs.image == '' && null || inputs.image }} + + 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)) -k 0 + working-directory: build + + - name: Configure plugins + run : | + 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)) -k 0 + 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: + needs: build + runs-on: ${{ fromJson(inputs.test_runner) }} + container: + image: ${{ inputs.image == '' && null || inputs.image }} + 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 + + ### 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 -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 -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 )) + + - 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 + - name: Clean HOME + run: ( shopt -s dotglob nullglob; rm -rf $HOME/* ) + shell: bash + + + ctest: + needs: build + runs-on: ${{ fromJson(inputs.test_runner) }} + container: + image: ${{ inputs.image == '' && null || inputs.image }} + 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 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/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 }} 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. 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/test.yaml b/.github/workflows/test.yaml new file mode 100644 index 0000000000..3f809d189f --- /dev/null +++ b/.github/workflows/test.yaml @@ -0,0 +1,119 @@ +name: Test + +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 + uses: glotzerlab/jetstream2-admin/.github/workflows/start.yaml@c89b62aa89f7886318edb166bc0500cfc658f24f # v1.3.0 + secrets: inherit + + typical: + name: "${{ join(matrix.config, '_') }}" + needs: start_action_runners + uses: ./.github/workflows/build_and_test.yaml + with: + config: ${{ join(matrix.config, '_') }} + 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 + 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 }} + + strategy: + fail-fast: false + matrix: + include: + - config: [clang18_py312, mpi, tbb] + validate: 'true' + + - config: [gcc13_py312] + 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' + + - 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' + + - config: [gcc14_py312, nomd] + + - config: [gcc14_py312, nohpmc] + + - config: [gcc14_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' + + - config: [gcc9_py39] + + 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, '_') }} + 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 + 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 }} + + 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: [clang14_py311, mpi, tbb, llvm] + - config: [clang13_py310, llvm] + - config: [clang12_py310, llvm] + - config: [clang11_py310, llvm] + - config: [gcc13_py312, mpi] + - 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' + + 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 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index 4d4ed74f3a..0000000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,591 +0,0 @@ -name: Test -# 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.' 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 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(); diff --git a/hoomd/VectorMath.h b/hoomd/VectorMath.h index ec32096a9a..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 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..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 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 561fcdf004..5f591fce59 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_; @@ -229,6 +237,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 */ @@ -268,8 +278,8 @@ 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, - ShortReal extra_sweep_radius = ShortReal(0.0)) + DEVICE inline SupportFuncConvexPolyhedron(const PolyhedronVertices& _verts, + ShortReal extra_sweep_radius = ShortReal(0.0)) : verts(_verts), sweep_radius(extra_sweep_radius) { } @@ -279,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 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; @@ -293,7 +304,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) { @@ -345,7 +356,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) { @@ -789,10 +800,10 @@ 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, - const ShapeConvexPolyhedron& a, - const ShapeConvexPolyhedron& b, - unsigned int& err) +DEVICE inline __attribute__((always_inline)) bool test_overlap(const vec3& r_ab, + const ShapeConvexPolyhedron& a, + const ShapeConvexPolyhedron& b, + unsigned int& err) { vec3 dr(r_ab); 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, diff --git a/hoomd/hpmc/XenoCollide3D.h b/hoomd/hpmc/XenoCollide3D.h index fca8bc6814..6d5ca06ca4 100644 --- a/hoomd/hpmc/XenoCollide3D.h +++ b/hoomd/hpmc/XenoCollide3D.h @@ -70,12 +70,12 @@ const unsigned int XENOCOLLIDE_3D_MAX_ITERATIONS = 1024; \ingroup minkowski */ template -DEVICE inline bool xenocollide_3d(const SupportFuncA& sa, - const SupportFuncB& sb, - const vec3& ab_t, - const quat& q, - const ShortReal R, - unsigned int& err_count) +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) { // 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/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; 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; 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; diff --git a/hoomd/mpcd/test/communicator_mpi_test.cc b/hoomd/mpcd/test/communicator_mpi_test.cc index 118f1862e9..77c3767f02 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()) {