diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml index b748649fe9..dbb595636f 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -1,8 +1,6 @@ name: Build Documentation on: - # Trigger the workflow on push or pull request, - # but only for the master branch push: branches: - develop @@ -31,6 +29,6 @@ jobs: TOKEN: ${{ secrets.GH_PAT }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Build the Docker image run: docker-compose run ubuntu-docs diff --git a/.github/workflows/build-statistics.yml b/.github/workflows/build-statistics.yml index 7ab263c04e..5e46197c7c 100644 --- a/.github/workflows/build-statistics.yml +++ b/.github/workflows/build-statistics.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Generate build stats uses: DARMA-tasking/build-stats@master diff --git a/.github/workflows/check-commit-format.yml b/.github/workflows/check-commit-format.yml index 4b0259d86a..2fe7393712 100644 --- a/.github/workflows/check-commit-format.yml +++ b/.github/workflows/check-commit-format.yml @@ -7,7 +7,7 @@ jobs: name: Check commit runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 ref: ${{ github.event.pull_request.head.sha }} diff --git a/.github/workflows/check-include-guards.yml b/.github/workflows/check-include-guards.yml index 12d0d62a90..5f15011f30 100644 --- a/.github/workflows/check-include-guards.yml +++ b/.github/workflows/check-include-guards.yml @@ -8,7 +8,7 @@ jobs: steps: - name: Checkout source code - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Setup Dependencies uses: actions/setup-python@v2 diff --git a/.github/workflows/check-trailing-whitespace.yml b/.github/workflows/check-trailing-whitespace.yml index 98a9351f34..d7c287528d 100644 --- a/.github/workflows/check-trailing-whitespace.yml +++ b/.github/workflows/check-trailing-whitespace.yml @@ -7,7 +7,7 @@ jobs: name: Find Trailing Whitespace runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: DARMA-tasking/find-trailing-whitespace@master with: exclude: "sketches;lib" diff --git a/.github/workflows/macosx-clang-mpich.yml b/.github/workflows/macosx-clang-mpich.yml index c142b287e5..04ddf42da9 100644 --- a/.github/workflows/macosx-clang-mpich.yml +++ b/.github/workflows/macosx-clang-mpich.yml @@ -26,22 +26,20 @@ jobs: CMAKE_BUILD_TYPE: release VT_LB_ENABLED: 1 VT_TRACE_ENABLED: 1 - VT_USE_OPENMP: 0 - VT_USE_STD_THREAD: 0 VT_WERROR: 1 CMAKE_CXX_STANDARD: 17 CMAKE_GENERATOR: "Unix Makefiles" CMAKE_BUILD_PARALLEL_LEVEL: 4 steps: - - uses: actions/checkout@v2 - - uses: actions/cache@v2 + - uses: actions/checkout@v3 + - uses: actions/cache@v3 with: path: ~/.ccache key: ${{ runner.os }}-macosx-clang-8-ccache-${{ secrets.GH_ACTIONS_CACHE_VERSION }}-${{ hashFiles('**/*') }} restore-keys: | ${{ runner.os }}-macosx-clang-8-ccache-${{ secrets.GH_ACTIONS_CACHE_VERSION }} - - uses: actions/cache@v2 + - uses: actions/cache@v3 id: mpich-cache with: path: ~/.mpich diff --git a/.github/workflows/pushdockerimage.yml b/.github/workflows/pushdockerimage.yml index c007177c38..0fd24234c6 100644 --- a/.github/workflows/pushdockerimage.yml +++ b/.github/workflows/pushdockerimage.yml @@ -1,12 +1,9 @@ name: Docker Image CI on: - # Trigger the workflow on push or pull request, - # but only for the master branch push: branches: - develop - - 1.* jobs: @@ -15,7 +12,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Docker Build & Push uses: jerray/publish-docker-action@master with: diff --git a/.github/workflows/run-git-check.yml b/.github/workflows/run-git-check.yml index 51e4c71c53..714cbb82b9 100644 --- a/.github/workflows/run-git-check.yml +++ b/.github/workflows/run-git-check.yml @@ -7,7 +7,7 @@ jobs: name: Run git check runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 ref: ${{ github.event.pull_request.head.sha }} diff --git a/.gitignore b/.gitignore index a8e6e47a87..ee9ae770e9 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,6 @@ build transport lib/*-build lib/checkpoint -lib/detector lib/googletest lib/kokkos .emacs.desktop diff --git a/CMakeLists.txt b/CMakeLists.txt index 760070f899..2d33275dd0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.17 FATAL_ERROR) +cmake_minimum_required(VERSION 3.23 FATAL_ERROR) file(READ "VERSION" _vt_version_str) string(STRIP "${_vt_version_str}" _vt_version_str) @@ -39,7 +39,7 @@ set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_CXX_STANDARD_REQUIRED ON) if(NOT CMAKE_CXX_STANDARD) - set(CMAKE_CXX_STANDARD 14 CACHE STRING "The C++ standard to use") + set(CMAKE_CXX_STANDARD 17 CACHE STRING "The C++ standard to use") endif() message(STATUS "CMAKE_CXX_STANDARD: ${CMAKE_CXX_STANDARD}") diff --git a/README.md b/README.md index e39ef4d542..e3975b37ac 100644 --- a/README.md +++ b/README.md @@ -8,11 +8,17 @@ [![gcc-8, ubuntu, mpich, address sanitizer](https://dev.azure.com/DARMA-tasking/DARMA/_apis/build/status/PR%20tests%20(gcc-8%2C%20ubuntu%2C%20mpich%2C%20address%20sanitizer)?branchName=develop&Label=(gcc-8%2C%20ubuntu%2C%20mpich%2C%20address%20sanitizer))](https://dev.azure.com/DARMA-tasking/DARMA/_build/latest?definitionId=9&branchName=develop) [![gcc-9, ubuntu, mpich, zoltan](https://dev.azure.com/DARMA-tasking/DARMA/_apis/build/status/PR%20tests%20(gcc-9%2C%20ubuntu%2C%20mpich%2C%20zoltan)?branchName=develop&Label=(gcc-9%2C%20ubuntu%2C%20mpich%2C%20zoltan))](https://dev.azure.com/DARMA-tasking/DARMA/_build/latest?definitionId=10&branchName=develop) [![gcc-10, ubuntu, openmpi, no LB](https://dev.azure.com/DARMA-tasking/DARMA/_apis/build/status/PR%20tests%20(gcc-10%2C%20ubuntu%2C%20openmpi%2C%20no%20LB)?branchName=develop&Label=(gcc-10%2C%20ubuntu%2C%20openmpi%2C%20no%20LB))](https://dev.azure.com/DARMA-tasking/DARMA/_build/latest?definitionId=4&branchName=develop) -[![clang-5, ubuntu, mpich, trace](https://dev.azure.com/DARMA-tasking/DARMA/_apis/build/status/PR%20tests%20(clang-5.0%2C%20ubuntu%2C%20mpich)?branchName=develop&Label=(clang-5.0%2C%20ubuntu%2C%20mpich))](https://dev.azure.com/DARMA-tasking/DARMA/_build/latest?definitionId=5&branchName=develop) +[![gcc-11, ubuntu, mpich](https://dev.azure.com/DARMA-tasking/DARMA/_apis/build/status/PR%20tests%20(gcc-11%2C%20ubuntu%2C%20mpich)?branchName=develop&Label=(gcc-11%2C%20ubuntu%2C%20mpich))](https://dev.azure.com/DARMA-tasking/DARMA/_build/latest?definitionId=29&branchName=develop) +[![gcc-12, ubuntu, mpich](https://dev.azure.com/DARMA-tasking/DARMA/_apis/build/status/PR%20tests%20(gcc-12%2C%20ubuntu%2C%20mpich)?branchName=develop&Label=(gcc-12%2C%20ubuntu%2C%20mpich))](https://dev.azure.com/DARMA-tasking/DARMA/_build/latest?definitionId=30&branchName=develop) [![clang-9, ubuntu, mpich](https://dev.azure.com/DARMA-tasking/DARMA/_apis/build/status/PR%20tests%20(clang-9%2C%20ubuntu%2C%20mpich)?branchName=develop&Label=(clang-9.0%2C%20ubuntu%2C%20mpich))](https://dev.azure.com/DARMA-tasking/DARMA/_build?definitionId=22&branchName=develop) [![clang-10, ubuntu, mpich](https://dev.azure.com/DARMA-tasking/DARMA/_apis/build/status/PR%20tests%20(clang-10%2C%20ubuntu%2C%20mpich)?branchName=develop&Label=(clang-10.0%2C%20ubuntu%2C%20mpich))](https://dev.azure.com/DARMA-tasking/DARMA/_build?definitionId=21&branchName=develop) -[![nvidia cuda 10.1, ubuntu, mpich](https://dev.azure.com/DARMA-tasking/DARMA/_apis/build/status/PR%20tests%20(nvidia%20cuda%2010.1%2C%20ubuntu%2C%20mpich)?branchName=develop&Label=(nvidia%20cuda%2010.1%2C%20ubuntu%2C%20mpich))](https://dev.azure.com/DARMA-tasking/DARMA/_build/latest?definitionId=11&branchName=develop) +[![clang-11, ubuntu, mpich](https://dev.azure.com/DARMA-tasking/DARMA/_apis/build/status/PR%20tests%20(clang-11%2C%20ubuntu%2C%20mpich)?branchName=develop&Label=(clang-11.0%2C%20ubuntu%2C%20mpich))](https://dev.azure.com/DARMA-tasking/DARMA/_build?definitionId=25&branchName=develop) +[![clang-12, ubuntu, mpich](https://dev.azure.com/DARMA-tasking/DARMA/_apis/build/status/PR%20tests%20(clang-12%2C%20ubuntu%2C%20mpich)?branchName=develop&Label=(clang-12.0%2C%20ubuntu%2C%20mpich))](https://dev.azure.com/DARMA-tasking/DARMA/_build?definitionId=26&branchName=develop) +[![clang-13, ubuntu, mpich](https://dev.azure.com/DARMA-tasking/DARMA/_apis/build/status/PR%20tests%20(clang-13%2C%20ubuntu%2C%20mpich)?branchName=develop&Label=(clang-13.0%2C%20ubuntu%2C%20mpich))](https://dev.azure.com/DARMA-tasking/DARMA/_build?definitionId=27&branchName=develop) +[![clang-13, alpine, mpich](https://dev.azure.com/DARMA-tasking/DARMA/_apis/build/status/PR%20tests%20(clang-13%2C%20alpine%2C%20mpich)?branchName=develop&Label=(clang-13.0%2C%20alpine%2C%20mpich))](https://dev.azure.com/DARMA-tasking/DARMA/_build?definitionId=23&branchName=develop) +[![clang-14, ubuntu, mpich](https://dev.azure.com/DARMA-tasking/DARMA/_apis/build/status/PR%20tests%20(clang-14%2C%20ubuntu%2C%20mpich)?branchName=develop&Label=(clang-14.0%2C%20ubuntu%2C%20mpich))](https://dev.azure.com/DARMA-tasking/DARMA/_build?definitionId=28&branchName=develop) [![nvidia cuda 11.0, ubuntu, mpich](https://dev.azure.com/DARMA-tasking/DARMA/_apis/build/status/PR%20tests%20(nvidia%20cuda%2011.0%2C%20ubuntu%2C%20mpich)?branchName=develop&Label=(nvidia%20cuda%2011.0%2C%20ubuntu%2C%20mpich))](https://dev.azure.com/DARMA-tasking/DARMA/_build/latest?definitionId=12&branchName=develop) +[![nvidia cuda 11.2, ubuntu, mpich](https://dev.azure.com/DARMA-tasking/DARMA/_apis/build/status/PR%20tests%20(nvidia%20cuda%2011.2%2C%20ubuntu%2C%20mpich)?branchName=develop&Label=(nvidia%20cuda%2011.2%2C%20ubuntu%2C%20mpich))](https://dev.azure.com/DARMA-tasking/DARMA/_build/latest?definitionId=32&branchName=develop) [![gcc-10, ubuntu, openmpi, no LB, spack-package](https://dev.azure.com/DARMA-tasking/DARMA/_apis/build/status/PR%20tests%20spack-package%20(gcc-10%2C%20ubuntu%2C%20openmpi%2C%20no%20LB%2C%20spack-package)?branchName=develop&Label=(gcc-10%2C%20ubuntu%2C%20openmpi%2C%20no%20LB%2C%20spack-package))](https://dev.azure.com/DARMA-tasking/DARMA/_build/latest?definitionId=20&branchName=develop) [![icpx, ubuntu, mpich](https://dev.azure.com/DARMA-tasking/DARMA/_apis/build/status/PR%20tests%20(intel%20icpx%2C%20ubuntu%2C%20mpich)?branchName=develop&Label=(icpx%2C%20ubuntu%2C%20mpich))](https://dev.azure.com/DARMA-tasking/DARMA/_build?definitionId=24&branchName=develop) ![apple clang, macosx, mpich](https://github.com/DARMA-tasking/vt/workflows/PR%20tests%20(clang-8,%20macosx,%20mpich)/badge.svg?branch=develop) diff --git a/VERSION b/VERSION index 23aa839063..f0bb29e763 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.2.2 +1.3.0 diff --git a/ci/azure/azure-clang-10-ubuntu-mpich.yml b/ci/azure/azure-clang-10-ubuntu-mpich.yml index 0ac50073f3..f43987d6a0 100644 --- a/ci/azure/azure-clang-10-ubuntu-mpich.yml +++ b/ci/azure/azure-clang-10-ubuntu-mpich.yml @@ -46,15 +46,13 @@ variables: VT_UNITY_BUILD: 1 VT_PRODUCTION_BUILD: 0 VT_FCONTEXT: 0 - VT_USE_OPENMP: 0 - VT_USE_STD_THREAD: 0 VT_ZOLTAN: 0 VT_CI_BUILD: 1 VT_DIAGNOSTICS: 1 VT_NO_COLOR: 1 VT_BUILD_SHARED_LIBS: 0 VT_INCLUSION: TPL - CMAKE_CXX_STANDARD: 14 + CMAKE_CXX_STANDARD: 17 TEST_LB_SCHEMA: 0 CACHE: "$(Agent.TempDirectory)/cache/" cache_name: ubuntu-clang-10-cache @@ -76,12 +74,8 @@ stages: vmImage: 'ubuntu-22.04' timeoutInMinutes: 180 steps: - - task: Bash@3 - displayName: Job setup - inputs: - targetType: 'inline' - script: | - echo setup + - checkout: self + fetchDepth: 0 - task: Bash@3 displayName: Build timestamp for caching continueOnError: true diff --git a/ci/azure/azure-clang-11-ubuntu-mpich.yml b/ci/azure/azure-clang-11-ubuntu-mpich.yml index d5fdade5ec..396c74c6f6 100644 --- a/ci/azure/azure-clang-11-ubuntu-mpich.yml +++ b/ci/azure/azure-clang-11-ubuntu-mpich.yml @@ -45,16 +45,14 @@ variables: VT_TESTS_NUM_NODES: 2 VT_UNITY_BUILD: 1 VT_PRODUCTION_BUILD: 0 - VT_FCONTEXT: 0 - VT_USE_OPENMP: 0 - VT_USE_STD_THREAD: 0 + VT_FCONTEXT: 1 VT_ZOLTAN: 0 VT_CI_BUILD: 1 VT_DIAGNOSTICS: 1 VT_NO_COLOR: 1 VT_BUILD_SHARED_LIBS: 0 VT_INCLUSION: TPL - CMAKE_CXX_STANDARD: 14 + CMAKE_CXX_STANDARD: 17 TEST_LB_SCHEMA: 0 CACHE: "$(Agent.TempDirectory)/cache/" cache_name: ubuntu-clang-11-cache @@ -76,12 +74,8 @@ stages: vmImage: 'ubuntu-22.04' timeoutInMinutes: 180 steps: - - task: Bash@3 - displayName: Job setup - inputs: - targetType: 'inline' - script: | - echo setup + - checkout: self + fetchDepth: 0 - task: Bash@3 displayName: Build timestamp for caching continueOnError: true diff --git a/ci/azure/azure-clang-12-ubuntu-mpich.yml b/ci/azure/azure-clang-12-ubuntu-mpich.yml index 3a53fd419c..78cc859b96 100644 --- a/ci/azure/azure-clang-12-ubuntu-mpich.yml +++ b/ci/azure/azure-clang-12-ubuntu-mpich.yml @@ -46,15 +46,13 @@ variables: VT_UNITY_BUILD: 1 VT_PRODUCTION_BUILD: 0 VT_FCONTEXT: 0 - VT_USE_OPENMP: 0 - VT_USE_STD_THREAD: 0 VT_ZOLTAN: 0 VT_CI_BUILD: 1 VT_DIAGNOSTICS: 1 VT_NO_COLOR: 1 VT_BUILD_SHARED_LIBS: 0 VT_INCLUSION: TPL - CMAKE_CXX_STANDARD: 14 + CMAKE_CXX_STANDARD: 17 TEST_LB_SCHEMA: 0 CACHE: "$(Agent.TempDirectory)/cache/" cache_name: ubuntu-clang-12-cache @@ -76,12 +74,8 @@ stages: vmImage: 'ubuntu-22.04' timeoutInMinutes: 180 steps: - - task: Bash@3 - displayName: Job setup - inputs: - targetType: 'inline' - script: | - echo setup + - checkout: self + fetchDepth: 0 - task: Bash@3 displayName: Build timestamp for caching continueOnError: true diff --git a/ci/azure/azure-clang-13-ubuntu-mpich.yml b/ci/azure/azure-clang-13-ubuntu-mpich.yml index 9cdfb186fd..f393cc8694 100644 --- a/ci/azure/azure-clang-13-ubuntu-mpich.yml +++ b/ci/azure/azure-clang-13-ubuntu-mpich.yml @@ -46,8 +46,6 @@ variables: VT_UNITY_BUILD: 1 VT_PRODUCTION_BUILD: 0 VT_FCONTEXT: 0 - VT_USE_OPENMP: 0 - VT_USE_STD_THREAD: 0 VT_ZOLTAN: 0 VT_CI_BUILD: 1 VT_DIAGNOSTICS: 1 @@ -76,12 +74,8 @@ stages: vmImage: 'ubuntu-22.04' timeoutInMinutes: 180 steps: - - task: Bash@3 - displayName: Job setup - inputs: - targetType: 'inline' - script: | - echo setup + - checkout: self + fetchDepth: 0 - task: Bash@3 displayName: Build timestamp for caching continueOnError: true diff --git a/ci/azure/azure-clang-14-ubuntu-mpich.yml b/ci/azure/azure-clang-14-ubuntu-mpich.yml index 15039a055e..d348c2e827 100644 --- a/ci/azure/azure-clang-14-ubuntu-mpich.yml +++ b/ci/azure/azure-clang-14-ubuntu-mpich.yml @@ -32,7 +32,7 @@ variables: ULIMIT_CORE: 0 CODE_COVERAGE: 0 VT_LB: 1 - VT_TRACE: 0 + VT_TRACE: 1 VT_TRACE_RT: 0 VT_TRACE_ONLY: 1 VT_MIMALLOC: 0 @@ -46,15 +46,13 @@ variables: VT_UNITY_BUILD: 1 VT_PRODUCTION_BUILD: 0 VT_FCONTEXT: 0 - VT_USE_OPENMP: 0 - VT_USE_STD_THREAD: 0 VT_ZOLTAN: 0 VT_CI_BUILD: 1 VT_DIAGNOSTICS: 1 VT_NO_COLOR: 1 VT_BUILD_SHARED_LIBS: 0 VT_INCLUSION: TPL - CMAKE_CXX_STANDARD: 14 + CMAKE_CXX_STANDARD: 17 TEST_LB_SCHEMA: 0 CACHE: "$(Agent.TempDirectory)/cache/" cache_name: ubuntu-clang-14-cache @@ -76,12 +74,8 @@ stages: vmImage: 'ubuntu-22.04' timeoutInMinutes: 180 steps: - - task: Bash@3 - displayName: Job setup - inputs: - targetType: 'inline' - script: | - echo setup + - checkout: self + fetchDepth: 0 - task: Bash@3 displayName: Build timestamp for caching continueOnError: true diff --git a/ci/azure/azure-clang-5.0-ubuntu-mpich.yml b/ci/azure/azure-clang-5.0-ubuntu-mpich.yml deleted file mode 100644 index 8d2fe025e3..0000000000 --- a/ci/azure/azure-clang-5.0-ubuntu-mpich.yml +++ /dev/null @@ -1,211 +0,0 @@ -############################################################################### -############## Warning this is a generated file---do not modify ############### -############################################################################### - -name: PR tests (clang-5.0, ubuntu, mpich) - -trigger: - branches: - include: - - develop - - 1.0.0* - -pr: - drafts: false - autoCancel: true - branches: - include: - - '*' - - -resources: -- repo: self - -variables: - tag: '$(Build.BuildId)' - REPO: lifflander1/vt - ARCH: amd64 - UBUNTU: 18.04 - COMPILER_TYPE: clang - COMPILER: clang-5.0 - BUILD_TYPE: release - ULIMIT_CORE: 0 - CODE_COVERAGE: 0 - VT_LB: 1 - VT_TRACE: 1 - VT_TRACE_RT: 0 - VT_TRACE_ONLY: 1 - VT_MIMALLOC: 0 - VT_DOCS: 0 - VT_ASAN: 0 - VT_UBSAN: 0 - VT_WERROR: 1 - VT_POOL: 1 - VT_EXTENDED_TESTS: 1 - VT_TESTS_NUM_NODES: 2 - VT_UNITY_BUILD: 1 - VT_PRODUCTION_BUILD: 0 - VT_FCONTEXT: 0 - VT_USE_OPENMP: 1 - VT_USE_STD_THREAD: 0 - VT_ZOLTAN: 0 - VT_CI_BUILD: 1 - VT_DIAGNOSTICS: 1 - VT_NO_COLOR: 1 - VT_BUILD_SHARED_LIBS: 0 - VT_INCLUSION: TPL - CMAKE_CXX_STANDARD: 14 - TEST_LB_SCHEMA: 0 - CACHE: "$(Agent.TempDirectory)/cache/" - cache_name: ubuntu-clang-5.0-cache - build_root: "$(CACHE)/$(ARCH)-ubuntu-$(UBUNTU)-$(COMPILER)-cache/" - TS: 0 - TS_YEAR: 0 - TS_MONTH: 0 - TS_DAY: 0 - - - -stages: -- stage: Build - displayName: Build image - jobs: - - job: Build - displayName: Build - pool: - vmImage: 'ubuntu-22.04' - timeoutInMinutes: 180 - steps: - - task: Bash@3 - displayName: Job setup - inputs: - targetType: 'inline' - script: | - echo setup - - task: Bash@3 - displayName: Build timestamp for caching - continueOnError: true - inputs: - targetType: 'inline' - script: | - echo 'string(TIMESTAMP current_date "%H;%M;%S" UTC)' > script - echo 'execute_process(COMMAND ${CMAKE_COMMAND} -E echo "${current_date}")' >> script - val=$(cmake -P script) - echo "##vso[task.setvariable variable=TS]$val" - echo 'string(TIMESTAMP current_date "%Y" UTC)' > script - echo 'execute_process(COMMAND ${CMAKE_COMMAND} -E echo "${current_date}")' >> script - val=$(cmake -P script) - echo "##vso[task.setvariable variable=TS_YEAR]$val" - echo 'string(TIMESTAMP current_date "%m" UTC)' > script - echo 'execute_process(COMMAND ${CMAKE_COMMAND} -E echo "${current_date}")' >> script - val=$(cmake -P script) - echo "##vso[task.setvariable variable=TS_MONTH]$val" - echo 'string(TIMESTAMP current_date "%d" UTC)' > script - echo 'execute_process(COMMAND ${CMAKE_COMMAND} -E echo "${current_date}")' >> script - val=$(cmake -P script) - echo "##vso[task.setvariable variable=TS_DAY]$val" - - task: Bash@3 - displayName: Output timestamp for caching - continueOnError: true - condition: in(variables['Agent.JobStatus'], 'Succeeded', 'SucceededWithIssues') - inputs: - targetType: 'inline' - script: 'echo "my pipeline variable is $(TS) $(TS_YEAR) $(TS_MONTH) $(TS_DAY)"' - - task: Cache@2 - displayName: Update cache - continueOnError: true - condition: in(variables['Agent.JobStatus'], 'Succeeded', 'SucceededWithIssues') - inputs: - securityNamespace: cache - key: $(Agent.OS) | "$(cache_name)" | $(TS_YEAR) | $(TS_MONTH) | $(TS_DAY) | $(TS) - path: '$(build_root)/ccache' - restoreKeys: | - $(Agent.OS) | "$(cache_name)" | $(TS_YEAR) | $(TS_MONTH) | $(TS_DAY) - $(Agent.OS) | "$(cache_name)" | $(TS_YEAR) | $(TS_MONTH) - $(Agent.OS) | "$(cache_name)" | $(TS_YEAR) - $(Agent.OS) | "$(cache_name)" - - task: Bash@3 - displayName: Check for changes in containers - condition: in(variables['Agent.JobStatus'], 'Succeeded', 'SucceededWithIssues') - inputs: - targetType: 'inline' - script: | - val=$(./scripts/check_containers.sh) - echo "##vso[task.setvariable variable=compose_command]$val" - - task: DockerCompose@0 - displayName: Pull container - inputs: - containerregistrytype: 'Container Registry' - dockerComposeFile: '**/docker-compose.yml' - action: 'Run a Docker Compose command' - dockerComposeCommand: '$(compose_command) ubuntu-cpp-clean' - - task: DockerCompose@0 - displayName: Build container - inputs: - containerregistrytype: 'Container Registry' - dockerComposeFile: '**/docker-compose.yml' - action: 'Run a Docker Compose command' - dockerComposeCommand: 'run ubuntu-cpp-clean' - env: - CODECOV_TOKEN: $(codecov_token) - - task: Bash@3 - displayName: Put compilation's and tests' logs in PR comment - continueOnError: true - condition: and(succeededOrFailed(), eq(variables['Build.Reason'], 'PullRequest')) - inputs: - targetType: 'inline' - script: | - ./scripts/report_logs_in_comment.sh \ - "$(build_root)/vt/compilation_errors_warnings.out" \ - "$(build_root)/vt/cmake-output.log" \ - "$(Build.BuildNumber)" \ - "$(System.PullRequest.PullRequestNumber)" \ - "$(Build.Repository.Name)" \ - "$GITHUB_PAT" \ - "$(Build.BuildId)" \ - "$(System.JobId)" \ - "$(Agent.JobStatus)" - env: - GITHUB_PAT: $(github_pat) - - task: DockerCompose@0 - displayName: Push container to registry - continueOnError: true - condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/develop')) - inputs: - containerregistrytype: 'Container Registry' - dockerRegistryEndpoint: 'dockerRegistryConnection1' - dockerComposeFile: '**/docker-compose.yml' - action: 'Run a Docker Compose command' - dockerComposeCommand: 'push ubuntu-cpp-clean' - - task: Bash@3 - displayName: Create artifacts - continueOnError: true - condition: in(variables['Agent.JobStatus'], 'Succeeded', 'SucceededWithIssues') - inputs: - targetType: 'inline' - script: | - zip -j $(Agent.TempDirectory)/LastTest.log.gz $(build_root)/vt/Testing/Temporary/LastTest.log - zip -j $(Agent.TempDirectory)/cmake-output.log.gz $(build_root)/vt/cmake-output.log - - task: PublishPipelineArtifact@1 - displayName: Upload CMake test output artifact - continueOnError: true - condition: in(variables['Agent.JobStatus'], 'Succeeded', 'SucceededWithIssues') - inputs: - targetPath: '$(Agent.TempDirectory)/LastTest.log.gz' - artifact: 'CMakeLastTestLog' - publishLocation: 'pipeline' - - task: PublishPipelineArtifact@1 - displayName: Upload CMake full output artifact - continueOnError: true - condition: in(variables['Agent.JobStatus'], 'Succeeded', 'SucceededWithIssues') - inputs: - targetPath: '$(Agent.TempDirectory)/cmake-output.log.gz' - artifact: 'CMakeOutputLog' - publishLocation: 'pipeline' - - task: Bash@3 - displayName: Finish pipeline - condition: in(variables['Agent.JobStatus'], 'Succeeded', 'SucceededWithIssues') - inputs: - targetType: 'inline' - script: | - echo Done diff --git a/ci/azure/azure-clang-9-ubuntu-mpich.yml b/ci/azure/azure-clang-9-ubuntu-mpich.yml index 2a82daef40..6ffc1053b2 100644 --- a/ci/azure/azure-clang-9-ubuntu-mpich.yml +++ b/ci/azure/azure-clang-9-ubuntu-mpich.yml @@ -46,15 +46,13 @@ variables: VT_UNITY_BUILD: 1 VT_PRODUCTION_BUILD: 0 VT_FCONTEXT: 0 - VT_USE_OPENMP: 0 - VT_USE_STD_THREAD: 0 VT_ZOLTAN: 0 VT_CI_BUILD: 1 VT_DIAGNOSTICS: 1 VT_NO_COLOR: 1 VT_BUILD_SHARED_LIBS: 1 VT_INCLUSION: EXT_LIB - CMAKE_CXX_STANDARD: 14 + CMAKE_CXX_STANDARD: 17 TEST_LB_SCHEMA: 0 CACHE: "$(Agent.TempDirectory)/cache/" cache_name: ubuntu-clang-9-cache @@ -76,12 +74,8 @@ stages: vmImage: 'ubuntu-22.04' timeoutInMinutes: 180 steps: - - task: Bash@3 - displayName: Job setup - inputs: - targetType: 'inline' - script: | - echo setup + - checkout: self + fetchDepth: 0 - task: Bash@3 displayName: Build timestamp for caching continueOnError: true diff --git a/ci/azure/azure-clang-alpine-mpich.yml b/ci/azure/azure-clang-alpine-mpich.yml index 5714f8d0ef..6511ef65c5 100644 --- a/ci/azure/azure-clang-alpine-mpich.yml +++ b/ci/azure/azure-clang-alpine-mpich.yml @@ -46,15 +46,13 @@ variables: VT_UNITY_BUILD: 1 VT_PRODUCTION_BUILD: 1 VT_FCONTEXT: 0 - VT_USE_OPENMP: 0 - VT_USE_STD_THREAD: 0 VT_ZOLTAN: 0 VT_CI_BUILD: 1 VT_DIAGNOSTICS: 1 VT_NO_COLOR: 1 VT_BUILD_SHARED_LIBS: 0 VT_INCLUSION: TPL - CMAKE_CXX_STANDARD: 14 + CMAKE_CXX_STANDARD: 17 TEST_LB_SCHEMA: 0 CACHE: "$(Agent.TempDirectory)/cache/" cache_name: alpine-clang-13-cache @@ -76,12 +74,8 @@ stages: vmImage: 'ubuntu-22.04' timeoutInMinutes: 180 steps: - - task: Bash@3 - displayName: Job setup - inputs: - targetType: 'inline' - script: | - echo setup + - checkout: self + fetchDepth: 0 - task: Bash@3 displayName: Build timestamp for caching continueOnError: true diff --git a/ci/azure/azure-gcc-10-ubuntu-openmpi-spack.yml b/ci/azure/azure-gcc-10-ubuntu-openmpi-spack.yml index 314ddb024f..2403745511 100644 --- a/ci/azure/azure-gcc-10-ubuntu-openmpi-spack.yml +++ b/ci/azure/azure-gcc-10-ubuntu-openmpi-spack.yml @@ -34,8 +34,6 @@ variables: VT_EXTENDED_TESTS: 0 VT_UNITY_BUILD: 1 VT_FCONTEXT: 0 - VT_USE_OPENMP: 0 - VT_USE_STD_THREAD: 0 VT_ZOLTAN: 0 VT_CI_BUILD: 1 VT_DIAGNOSTICS: 1 diff --git a/ci/azure/azure-gcc-10-ubuntu-openmpi.yml b/ci/azure/azure-gcc-10-ubuntu-openmpi.yml index fe0eae6b13..051dfa3769 100644 --- a/ci/azure/azure-gcc-10-ubuntu-openmpi.yml +++ b/ci/azure/azure-gcc-10-ubuntu-openmpi.yml @@ -46,15 +46,13 @@ variables: VT_UNITY_BUILD: 1 VT_PRODUCTION_BUILD: 0 VT_FCONTEXT: 0 - VT_USE_OPENMP: 0 - VT_USE_STD_THREAD: 0 VT_ZOLTAN: 0 VT_CI_BUILD: 1 VT_DIAGNOSTICS: 1 VT_NO_COLOR: 1 VT_BUILD_SHARED_LIBS: 0 VT_INCLUSION: TPL - CMAKE_CXX_STANDARD: 14 + CMAKE_CXX_STANDARD: 17 TEST_LB_SCHEMA: 0 CACHE: "$(Agent.TempDirectory)/cache/" cache_name: ubuntu-gcc-10-cache @@ -76,12 +74,8 @@ stages: vmImage: 'ubuntu-22.04' timeoutInMinutes: 180 steps: - - task: Bash@3 - displayName: Job setup - inputs: - targetType: 'inline' - script: | - echo setup + - checkout: self + fetchDepth: 0 - task: Bash@3 displayName: Build timestamp for caching continueOnError: true diff --git a/ci/azure/azure-gcc-11-ubuntu-mpich.yml b/ci/azure/azure-gcc-11-ubuntu-mpich.yml index 7c12573f48..bce0aa68bd 100644 --- a/ci/azure/azure-gcc-11-ubuntu-mpich.yml +++ b/ci/azure/azure-gcc-11-ubuntu-mpich.yml @@ -46,15 +46,13 @@ variables: VT_UNITY_BUILD: 1 VT_PRODUCTION_BUILD: 0 VT_FCONTEXT: 0 - VT_USE_OPENMP: 0 - VT_USE_STD_THREAD: 0 VT_ZOLTAN: 0 VT_CI_BUILD: 1 VT_DIAGNOSTICS: 1 VT_NO_COLOR: 1 VT_BUILD_SHARED_LIBS: 0 VT_INCLUSION: TPL - CMAKE_CXX_STANDARD: 14 + CMAKE_CXX_STANDARD: 17 TEST_LB_SCHEMA: 1 CACHE: "$(Agent.TempDirectory)/cache/" cache_name: ubuntu-gcc-11-cache @@ -76,12 +74,8 @@ stages: vmImage: 'ubuntu-22.04' timeoutInMinutes: 180 steps: - - task: Bash@3 - displayName: Job setup - inputs: - targetType: 'inline' - script: | - echo setup + - checkout: self + fetchDepth: 0 - task: Bash@3 displayName: Build timestamp for caching continueOnError: true diff --git a/ci/azure/azure-gcc-12-ubuntu-mpich.yml b/ci/azure/azure-gcc-12-ubuntu-mpich.yml index ef4ecf34b1..dac939334e 100644 --- a/ci/azure/azure-gcc-12-ubuntu-mpich.yml +++ b/ci/azure/azure-gcc-12-ubuntu-mpich.yml @@ -46,8 +46,6 @@ variables: VT_UNITY_BUILD: 1 VT_PRODUCTION_BUILD: 0 VT_FCONTEXT: 0 - VT_USE_OPENMP: 0 - VT_USE_STD_THREAD: 0 VT_ZOLTAN: 0 VT_CI_BUILD: 1 VT_DIAGNOSTICS: 1 @@ -76,12 +74,8 @@ stages: vmImage: 'ubuntu-22.04' timeoutInMinutes: 180 steps: - - task: Bash@3 - displayName: Job setup - inputs: - targetType: 'inline' - script: | - echo setup + - checkout: self + fetchDepth: 0 - task: Bash@3 displayName: Build timestamp for caching continueOnError: true diff --git a/ci/azure/azure-gcc-7-ubuntu-mpich.yml b/ci/azure/azure-gcc-7-ubuntu-mpich.yml index 704b0b9176..a8ba7da182 100644 --- a/ci/azure/azure-gcc-7-ubuntu-mpich.yml +++ b/ci/azure/azure-gcc-7-ubuntu-mpich.yml @@ -43,18 +43,16 @@ variables: VT_POOL: 1 VT_EXTENDED_TESTS: 1 VT_TESTS_NUM_NODES: 2 - VT_UNITY_BUILD: 1 + VT_UNITY_BUILD: 0 VT_PRODUCTION_BUILD: 0 VT_FCONTEXT: 0 - VT_USE_OPENMP: 0 - VT_USE_STD_THREAD: 0 VT_ZOLTAN: 0 VT_CI_BUILD: 1 VT_DIAGNOSTICS: 1 VT_NO_COLOR: 1 VT_BUILD_SHARED_LIBS: 0 VT_INCLUSION: TPL - CMAKE_CXX_STANDARD: 14 + CMAKE_CXX_STANDARD: 17 TEST_LB_SCHEMA: 0 CACHE: "$(Agent.TempDirectory)/cache/" cache_name: ubuntu-gcc-7-cache @@ -76,12 +74,8 @@ stages: vmImage: 'ubuntu-22.04' timeoutInMinutes: 180 steps: - - task: Bash@3 - displayName: Job setup - inputs: - targetType: 'inline' - script: | - echo setup + - checkout: self + fetchDepth: 0 - task: Bash@3 displayName: Build timestamp for caching continueOnError: true diff --git a/ci/azure/azure-gcc-8-ubuntu-mpich.yml b/ci/azure/azure-gcc-8-ubuntu-mpich.yml index 7bdc753f51..af37277c9e 100644 --- a/ci/azure/azure-gcc-8-ubuntu-mpich.yml +++ b/ci/azure/azure-gcc-8-ubuntu-mpich.yml @@ -43,18 +43,16 @@ variables: VT_POOL: 0 VT_EXTENDED_TESTS: 1 VT_TESTS_NUM_NODES: 2 - VT_UNITY_BUILD: 1 + VT_UNITY_BUILD: 0 VT_PRODUCTION_BUILD: 0 VT_FCONTEXT: 0 - VT_USE_OPENMP: 0 - VT_USE_STD_THREAD: 1 VT_ZOLTAN: 0 VT_CI_BUILD: 1 VT_DIAGNOSTICS: 1 VT_NO_COLOR: 1 VT_BUILD_SHARED_LIBS: 0 VT_INCLUSION: TPL - CMAKE_CXX_STANDARD: 14 + CMAKE_CXX_STANDARD: 17 TEST_LB_SCHEMA: 0 CACHE: "$(Agent.TempDirectory)/cache/" cache_name: ubuntu-gcc-8-cache @@ -76,12 +74,8 @@ stages: vmImage: 'ubuntu-22.04' timeoutInMinutes: 180 steps: - - task: Bash@3 - displayName: Job setup - inputs: - targetType: 'inline' - script: | - echo setup + - checkout: self + fetchDepth: 0 - task: Bash@3 displayName: Build timestamp for caching continueOnError: true diff --git a/ci/azure/azure-gcc-9-ubuntu-mpich.yml b/ci/azure/azure-gcc-9-ubuntu-mpich.yml index e4470087d4..412fdfdfe1 100644 --- a/ci/azure/azure-gcc-9-ubuntu-mpich.yml +++ b/ci/azure/azure-gcc-9-ubuntu-mpich.yml @@ -46,15 +46,13 @@ variables: VT_UNITY_BUILD: 1 VT_PRODUCTION_BUILD: 0 VT_FCONTEXT: 0 - VT_USE_OPENMP: 0 - VT_USE_STD_THREAD: 0 VT_ZOLTAN: 1 VT_CI_BUILD: 1 VT_DIAGNOSTICS: 1 VT_NO_COLOR: 1 VT_BUILD_SHARED_LIBS: 0 VT_INCLUSION: TPL - CMAKE_CXX_STANDARD: 14 + CMAKE_CXX_STANDARD: 17 TEST_LB_SCHEMA: 0 CACHE: "$(Agent.TempDirectory)/cache/" cache_name: ubuntu-gcc-9-cache @@ -76,12 +74,8 @@ stages: vmImage: 'ubuntu-22.04' timeoutInMinutes: 180 steps: - - task: Bash@3 - displayName: Job setup - inputs: - targetType: 'inline' - script: | - echo setup + - checkout: self + fetchDepth: 0 - task: Bash@3 displayName: Build timestamp for caching continueOnError: true diff --git a/ci/azure/azure-intel-oneapi-icpc-ubuntu-mpich.yml b/ci/azure/azure-intel-oneapi-icpc-ubuntu-mpich.yml index c4e30dcd3c..3b20cedf91 100644 --- a/ci/azure/azure-intel-oneapi-icpc-ubuntu-mpich.yml +++ b/ci/azure/azure-intel-oneapi-icpc-ubuntu-mpich.yml @@ -46,15 +46,13 @@ variables: VT_UNITY_BUILD: 1 VT_PRODUCTION_BUILD: 0 VT_FCONTEXT: 0 - VT_USE_OPENMP: 0 - VT_USE_STD_THREAD: 0 VT_ZOLTAN: 0 VT_CI_BUILD: 1 VT_DIAGNOSTICS: 1 VT_NO_COLOR: 1 VT_BUILD_SHARED_LIBS: 0 VT_INCLUSION: TPL - CMAKE_CXX_STANDARD: 14 + CMAKE_CXX_STANDARD: 17 TEST_LB_SCHEMA: 0 CACHE: "$(Agent.TempDirectory)/cache/" cache_name: ubuntu-intel-oneapi-icpc-cache @@ -76,12 +74,8 @@ stages: vmImage: 'ubuntu-22.04' timeoutInMinutes: 180 steps: - - task: Bash@3 - displayName: Job setup - inputs: - targetType: 'inline' - script: | - echo setup + - checkout: self + fetchDepth: 0 - task: Bash@3 displayName: Build timestamp for caching continueOnError: true diff --git a/ci/azure/azure-intel-oneapi-icpx-ubuntu-mpich.yml b/ci/azure/azure-intel-oneapi-icpx-ubuntu-mpich.yml index 763f524106..8221fad655 100644 --- a/ci/azure/azure-intel-oneapi-icpx-ubuntu-mpich.yml +++ b/ci/azure/azure-intel-oneapi-icpx-ubuntu-mpich.yml @@ -46,15 +46,13 @@ variables: VT_UNITY_BUILD: 1 VT_PRODUCTION_BUILD: 0 VT_FCONTEXT: 0 - VT_USE_OPENMP: 0 - VT_USE_STD_THREAD: 0 VT_ZOLTAN: 0 VT_CI_BUILD: 1 VT_DIAGNOSTICS: 1 VT_NO_COLOR: 1 VT_BUILD_SHARED_LIBS: 0 VT_INCLUSION: TPL - CMAKE_CXX_STANDARD: 14 + CMAKE_CXX_STANDARD: 17 TEST_LB_SCHEMA: 0 CACHE: "$(Agent.TempDirectory)/cache/" cache_name: ubuntu-intel-oneapi-icpx-cache @@ -76,12 +74,8 @@ stages: vmImage: 'ubuntu-22.04' timeoutInMinutes: 180 steps: - - task: Bash@3 - displayName: Job setup - inputs: - targetType: 'inline' - script: | - echo setup + - checkout: self + fetchDepth: 0 - task: Bash@3 displayName: Build timestamp for caching continueOnError: true diff --git a/ci/azure/azure-nvidia-10-ubuntu-mpich.yml b/ci/azure/azure-nvidia-11-2-ubuntu-mpich.yml similarity index 95% rename from ci/azure/azure-nvidia-10-ubuntu-mpich.yml rename to ci/azure/azure-nvidia-11-2-ubuntu-mpich.yml index 59f46c75b3..bcfc857ab5 100644 --- a/ci/azure/azure-nvidia-10-ubuntu-mpich.yml +++ b/ci/azure/azure-nvidia-11-2-ubuntu-mpich.yml @@ -2,7 +2,7 @@ ############## Warning this is a generated file---do not modify ############### ############################################################################### -name: PR tests (nvidia cuda 10.1, ubuntu, mpich) +name: PR tests (nvidia cuda 11.2, ubuntu, mpich) trigger: branches: @@ -25,9 +25,9 @@ variables: tag: '$(Build.BuildId)' REPO: lifflander1/vt ARCH: amd64 - UBUNTU: 18.04 + UBUNTU: 20.04 COMPILER_TYPE: nvidia - COMPILER: nvcc-10 + COMPILER: 11.2.0 BUILD_TYPE: release ULIMIT_CORE: 0 CODE_COVERAGE: 0 @@ -42,22 +42,20 @@ variables: VT_WERROR: 1 VT_POOL: 0 VT_EXTENDED_TESTS: 0 - VT_TESTS_NUM_NODES: 2 + VT_TESTS_NUM_NODES: 4 VT_UNITY_BUILD: 1 - VT_PRODUCTION_BUILD: 1 + VT_PRODUCTION_BUILD: 0 VT_FCONTEXT: 0 - VT_USE_OPENMP: 0 - VT_USE_STD_THREAD: 0 VT_ZOLTAN: 0 VT_CI_BUILD: 1 VT_DIAGNOSTICS: 0 VT_NO_COLOR: 1 VT_BUILD_SHARED_LIBS: 0 VT_INCLUSION: TPL - CMAKE_CXX_STANDARD: 14 + CMAKE_CXX_STANDARD: 17 TEST_LB_SCHEMA: 0 CACHE: "$(Agent.TempDirectory)/cache/" - cache_name: ubuntu-nvidia-10-cache + cache_name: ubuntu-nvidia-11.2-cache build_root: "$(CACHE)/$(ARCH)-ubuntu-$(UBUNTU)-$(COMPILER)-cache/" TS: 0 TS_YEAR: 0 @@ -76,12 +74,8 @@ stages: vmImage: 'ubuntu-22.04' timeoutInMinutes: 180 steps: - - task: Bash@3 - displayName: Job setup - inputs: - targetType: 'inline' - script: | - echo setup + - checkout: self + fetchDepth: 0 - task: Bash@3 displayName: Build timestamp for caching continueOnError: true diff --git a/ci/azure/azure-nvidia-11-ubuntu-mpich.yml b/ci/azure/azure-nvidia-11-ubuntu-mpich.yml index 84c4368f2d..b9e412655d 100644 --- a/ci/azure/azure-nvidia-11-ubuntu-mpich.yml +++ b/ci/azure/azure-nvidia-11-ubuntu-mpich.yml @@ -25,9 +25,9 @@ variables: tag: '$(Build.BuildId)' REPO: lifflander1/vt ARCH: amd64 - UBUNTU: 18.04 + UBUNTU: 20.04 COMPILER_TYPE: nvidia - COMPILER: nvcc-11 + COMPILER: 11.0.3 BUILD_TYPE: release ULIMIT_CORE: 0 CODE_COVERAGE: 0 @@ -46,15 +46,13 @@ variables: VT_UNITY_BUILD: 1 VT_PRODUCTION_BUILD: 0 VT_FCONTEXT: 0 - VT_USE_OPENMP: 0 - VT_USE_STD_THREAD: 0 VT_ZOLTAN: 0 VT_CI_BUILD: 1 VT_DIAGNOSTICS: 0 VT_NO_COLOR: 1 VT_BUILD_SHARED_LIBS: 0 VT_INCLUSION: TPL - CMAKE_CXX_STANDARD: 14 + CMAKE_CXX_STANDARD: 17 TEST_LB_SCHEMA: 0 CACHE: "$(Agent.TempDirectory)/cache/" cache_name: ubuntu-nvidia-11-cache @@ -76,12 +74,8 @@ stages: vmImage: 'ubuntu-22.04' timeoutInMinutes: 180 steps: - - task: Bash@3 - displayName: Job setup - inputs: - targetType: 'inline' - script: | - echo setup + - checkout: self + fetchDepth: 0 - task: Bash@3 displayName: Build timestamp for caching continueOnError: true diff --git a/ci/build_cpp.sh b/ci/build_cpp.sh index 38baeb16bf..ddb76f1d5b 100755 --- a/ci/build_cpp.sh +++ b/ci/build_cpp.sh @@ -6,7 +6,6 @@ source_dir=${1} build_dir=${2} # Dependency versions, when fetched via git. -detector_rev=master checkpoint_rev=develop if test "${VT_DOXYGEN_ENABLED:-0}" -eq 1 @@ -38,40 +37,11 @@ fi mkdir -p "${build_dir}" pushd "${build_dir}" -if test -d "detector" -then - rm -Rf detector -fi - if test -d "checkpoint" then rm -Rf checkpoint fi -if test -d "${source_dir}/lib/detector" -then - { echo "Detector already in lib... not downloading, building, and installing"; } 2>/dev/null -else - if test "${VT_DOXYGEN_ENABLED:-0}" -eq 1 - then - cd "${source_dir}/lib" - git clone -b "${detector_rev}" --depth 1 https://github.com/DARMA-tasking/detector.git - cd - - else - git clone -b "${detector_rev}" --depth 1 https://github.com/DARMA-tasking/detector.git - export DETECTOR=$PWD/detector - export DETECTOR_BUILD=${build_dir}/detector - mkdir -p "$DETECTOR_BUILD" - cd "$DETECTOR_BUILD" - mkdir build - cd build - cmake -G "${CMAKE_GENERATOR:-Ninja}" \ - -DCMAKE_INSTALL_PREFIX="$DETECTOR_BUILD/install" \ - "$DETECTOR" - cmake --build . ${dashj} --target install - fi -fi - if test -d "${source_dir}/lib/checkpoint" then { echo "Checkpoint already in lib... not downloading, building, and installing"; } 2>/dev/null @@ -91,7 +61,6 @@ else cd build cmake -G "${CMAKE_GENERATOR:-Ninja}" \ -DCMAKE_INSTALL_PREFIX="$CHECKPOINT_BUILD/install" \ - -Ddetector_DIR="$DETECTOR_BUILD/install" \ "$CHECKPOINT" cmake --build . ${dashj} --target install fi @@ -133,8 +102,6 @@ cmake -G "${CMAKE_GENERATOR:-Ninja}" \ -Dvt_fcontext_enabled="${VT_FCONTEXT_ENABLED:-0}" \ -Dvt_fcontext_build_tests_examples="${VT_FCONTEXT_BUILD_TESTS_EXAMPLES:-0}" \ -Dvt_rdma_tests_enabled="${VT_RDMA_TESTS_ENABLED:-1}" \ - -DUSE_OPENMP="${VT_USE_OPENMP:-0}" \ - -DUSE_STD_THREAD="${VT_USE_STD_THREAD:-0}" \ -DCODE_COVERAGE="${CODE_COVERAGE:-0}" \ -DMI_INTERPOSE:BOOL=ON \ -DMI_OVERRIDE:BOOL=ON \ @@ -146,7 +113,6 @@ cmake -G "${CMAKE_GENERATOR:-Ninja}" \ -DCMAKE_CXX_COMPILER="${CXX:-c++}" \ -DCMAKE_C_COMPILER="${CC:-cc}" \ -DCMAKE_EXE_LINKER_FLAGS="${CMAKE_EXE_LINKER_FLAGS:-}" \ - -Ddetector_DIR="$DETECTOR_BUILD/install" \ -Dcheckpoint_DIR="$CHECKPOINT_BUILD/install" \ -DCMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH:-}" \ -DCMAKE_INSTALL_PREFIX="$VT_BUILD/install" \ @@ -154,7 +120,7 @@ cmake -G "${CMAKE_GENERATOR:-Ninja}" \ -Dvt_debug_verbose="${VT_DEBUG_VERBOSE:-}" \ -Dvt_tests_num_nodes="${VT_TESTS_NUM_NODES:-}" \ -Dvt_no_color_enabled="${VT_NO_COLOR_ENABLED:-0}" \ - -DCMAKE_CXX_STANDARD="${CMAKE_CXX_STANDARD:-14}" \ + -DCMAKE_CXX_STANDARD="${CMAKE_CXX_STANDARD:-17}" \ -DBUILD_SHARED_LIBS="${BUILD_SHARED_LIBS:-0}" \ "$VT" cmake_conf_ret=$? diff --git a/ci/build_vt_sample.sh b/ci/build_vt_sample.sh index 2537151af8..68d6fcd574 100755 --- a/ci/build_vt_sample.sh +++ b/ci/build_vt_sample.sh @@ -20,9 +20,8 @@ if test "$is_alpine" -eq 0 && test "${VT_CI_BUILD:-0}" -eq 1 then export VT=${source_dir} export VT_BUILD=${build_dir}/vt - export VT_INSTALL=${VT_BUILD}/install - export DETECTOR=${build_dir}/detector - export CHECKPOINT=${DETECTOR}/build/checkpoint + export VT_INSTALL=${VT_BUILD}/install/cmake + export CHECKPOINT=${build_dir}/checkpoint cd "$VT_BUILD" @@ -35,7 +34,8 @@ then if test "$VT_INCLUSION_TYPE" = "EXT_LIB" then - export vt_DIR="$VT_INSTALL" + VT="$VT_INSTALL" + CHECKPOINT="" fi git clone https://github.com/DARMA-tasking/vt-sample-project @@ -45,13 +45,12 @@ then cmake -G "${CMAKE_GENERATOR:-Ninja}" \ -Dvt_DIR="${VT}" \ -Dcheckpoint_DIR="${CHECKPOINT}" \ - -Ddetector_DIR="${DETECTOR}" \ -Dkokkos_DISABLE:BOOL=1 \ -Dkokkos_kernels_DISABLE:BOOL=1 \ -Dvt_trace_only="1" \ -DVT_BUILD_EXAMPLES="0" \ -DVT_BUILD_TESTS="0" \ - -DCMAKE_CXX_STANDARD="${CMAKE_CXX_STANDARD:-14}" \ + -DCMAKE_CXX_STANDARD="${CMAKE_CXX_STANDARD:-17}" \ -DCMAKE_EXPORT_COMPILE_COMMANDS=1 \ -DCMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE:-Release}" \ -DCMAKE_CXX_COMPILER="${CXX:-c++}" \ diff --git a/ci/ctest_build_all.sh b/ci/ctest_build_all.sh index a0d83754e5..59fcc5fffd 100755 --- a/ci/ctest_build_all.sh +++ b/ci/ctest_build_all.sh @@ -6,7 +6,6 @@ source_dir=${1} build_dir=${2} # Dependency versions, when fetched via git. -detector_rev=master checkpoint_rev=develop if test "${VT_DOXYGEN_ENABLED:-0}" -eq 1 @@ -40,40 +39,11 @@ fi mkdir -p "${build_dir}" pushd "${build_dir}" -if test -d "detector" -then - rm -Rf detector -fi - if test -d "checkpoint" then rm -Rf checkpoint fi -if test -d "${source_dir}/lib/detector" -then - { echo "Detector already in lib... not downloading, building, and installing"; } 2>/dev/null -else - if test "${VT_DOXYGEN_ENABLED:-0}" -eq 1 - then - cd "${source_dir}/lib" - git clone -b "${detector_rev}" --depth 1 https://github.com/DARMA-tasking/detector.git - cd - - else - git clone -b "${detector_rev}" --depth 1 https://github.com/DARMA-tasking/detector.git - export DETECTOR=$PWD/detector - export DETECTOR_BUILD=${build_dir}/detector - mkdir -p "$DETECTOR_BUILD" - cd "$DETECTOR_BUILD" - mkdir build - cd build - cmake -G "${CMAKE_GENERATOR:-Ninja}" \ - -DCMAKE_INSTALL_PREFIX="$DETECTOR_BUILD/install" \ - "$DETECTOR" - cmake --build . ${dashj} --target install - fi -fi - if test -d "${source_dir}/lib/checkpoint" then { echo "Checkpoint already in lib... not downloading, building, and installing"; } 2>/dev/null @@ -93,7 +63,6 @@ else cd build cmake -G "${CMAKE_GENERATOR:-Ninja}" \ -DCMAKE_INSTALL_PREFIX="$CHECKPOINT_BUILD/install" \ - -Ddetector_DIR="$DETECTOR_BUILD/install" \ "$CHECKPOINT" cmake --build . ${dashj} --target install fi diff --git a/ci/ctest_job_script.cmake b/ci/ctest_job_script.cmake index d8333086a8..b6d354dc2f 100644 --- a/ci/ctest_job_script.cmake +++ b/ci/ctest_job_script.cmake @@ -83,12 +83,6 @@ endif() if ( NOT DEFINED ENV{VT_RDMA_TESTS_ENABLED} ) set(ENV{VT_RDMA_TESTS_ENABLED} "1") endif() -if ( NOT DEFINED ENV{VT_USE_OPENMP} ) - set(ENV{VT_USE_OPENMP} "0") -endif() -if ( NOT DEFINED ENV{VT_USE_STD_THREAD} ) - set(ENV{VT_USE_STD_THREAD} "0") -endif() if ( NOT DEFINED ENV{CODE_COVERAGE} ) set(ENV{CODE_COVERAGE} "0") endif() @@ -143,8 +137,6 @@ set(configureOpts "-Dvt_fcontext_enabled=$ENV{VT_FCONTEXT_ENABLED}" "-Dvt_fcontext_build_tests_examples=$ENV{VT_FCONTEXT_BUILD_TESTS_EXAMPLES}" "-Dvt_rdma_tests_enabled=$ENV{VT_RDMA_TESTS_ENABLED}" - "-DUSE_OPENMP=$ENV{VT_USE_OPENMP}" - "-DUSE_STD_THREAD=$ENV{VT_USE_STD_THREAD}" "-DCODE_COVERAGE=$ENV{CODE_COVERAGE}" "-DMI_INTERPOSE:BOOL=ON" "-DMI_OVERRIDE:BOOL=ON" @@ -156,7 +148,6 @@ set(configureOpts "-DCMAKE_CXX_COMPILER=$ENV{CXX}" "-DCMAKE_C_COMPILER=$ENV{CC}" "-DCMAKE_EXE_LINKER_FLAGS=$ENV{CMAKE_EXE_LINKER_FLAGS}" - "-Ddetector_DIR=$ENV{DETECTOR_BUILD}/install" "-Dcheckpoint_DIR=$ENV{CHECKPOINT_BUILD}/install" "-DCMAKE_PREFIX_PATH=$ENV{CMAKE_PREFIX_PATH}" "-DCMAKE_INSTALL_PREFIX=$ENV{VT_BUILD}/install" diff --git a/ci/docker/alpine-cpp.dockerfile b/ci/docker/alpine-cpp.dockerfile index 844ec6d788..a2cf6b73c5 100644 --- a/ci/docker/alpine-cpp.dockerfile +++ b/ci/docker/alpine-cpp.dockerfile @@ -64,8 +64,6 @@ ARG VT_WERROR_ENABLED ARG VT_POOL_ENABLED ARG VT_PRODUCTION_BUILD_ENABLED ARG VT_FCONTEXT_ENABLED -ARG VT_USE_OPENMP -ARG VT_USE_STD_THREAD ARG CMAKE_BUILD_TYPE ARG VT_NO_COLOR_ENABLED ARG BUILD_SHARED_LIBS @@ -82,8 +80,6 @@ ENV VT_LB_ENABLED=${VT_LB_ENABLED} \ VT_POOL_ENABLED=${VT_POOL_ENABLED} \ VT_PRODUCTION_BUILD_ENABLED=${VT_PRODUCTION_BUILD_ENABLED} \ VT_FCONTEXT_ENABLED=${VT_FCONTEXT_ENABLED} \ - VT_USE_OPENMP=${VT_USE_OPENMP} \ - VT_USE_STD_THREAD=${VT_USE_STD_THREAD} \ VT_NO_COLOR_ENABLED=${VT_NO_COLOR_ENABLED} \ CMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD} \ BUILD_SHARED_LIBS=${BUILD_SHARED_LIBS} \ diff --git a/ci/docker/develop.dockerfile b/ci/docker/develop.dockerfile index dd1a58af51..ba5cc734cc 100644 --- a/ci/docker/develop.dockerfile +++ b/ci/docker/develop.dockerfile @@ -44,8 +44,6 @@ ARG VT_ZOLTAN_ENABLED ARG CMAKE_BUILD_TYPE ARG VT_EXTENDED_TESTS_ENABLED ARG VT_FCONTEXT_ENABLED -ARG VT_USE_OPENMP -ARG VT_USE_STD_THREAD ARG VT_NO_COLOR_ENABLED ARG BUILD_SHARED_LIBS ARG CMAKE_CXX_STANDARD @@ -64,8 +62,6 @@ ENV VT_LB_ENABLED=${VT_LB_ENABLED} \ VT_EXTENDED_TESTS_ENABLED=${VT_EXTENDED_TESTS_ENABLED} \ VT_UNITY_BUILD_ENABLED=${VT_UNITY_BUILD_ENABLED} \ VT_FCONTEXT_ENABLED=${VT_FCONTEXT_ENABLED} \ - VT_USE_OPENMP=${VT_USE_OPENMP} \ - VT_USE_STD_THREAD=${VT_USE_STD_THREAD} \ VT_DIAGNOSTICS_ENABLED=${VT_DIAGNOSTICS_ENABLED} \ VT_DIAGNOSTICS_RUNTIME_ENABLED=${VT_DIAGNOSTICS_RUNTIME_ENABLED} \ VT_NO_COLOR_ENABLED=${VT_NO_COLOR_ENABLED} \ diff --git a/ci/docker/ubuntu-18.04-gnu-docs.dockerfile b/ci/docker/ubuntu-18.04-gnu-docs.dockerfile index ff83f47016..b88af792e3 100644 --- a/ci/docker/ubuntu-18.04-gnu-docs.dockerfile +++ b/ci/docker/ubuntu-18.04-gnu-docs.dockerfile @@ -39,7 +39,7 @@ ENV MPI_EXTRA_FLAGS="" \ PATH=/usr/lib/ccache/:$PATH COPY ./ci/deps/cmake.sh cmake.sh -RUN ./cmake.sh 3.18.4 +RUN ./cmake.sh 3.23.4 ENV PATH=/cmake/bin/:$PATH @@ -60,8 +60,6 @@ ARG VT_PRODUCTION_BUILD_ENABLED ARG CMAKE_BUILD_TYPE ARG VT_EXTENDED_TESTS_ENABLED ARG VT_FCONTEXT_ENABLED -ARG VT_USE_OPENMP -ARG VT_USE_STD_THREAD ARG VT_NO_COLOR_ENABLED ARG BUILD_SHARED_LIBS ARG CMAKE_CXX_STANDARD @@ -79,8 +77,6 @@ ENV VT_LB_ENABLED=${VT_LB_ENABLED} \ VT_MPI_GUARD_ENABLED=${VT_MPI_GUARD_ENABLED} \ VT_EXTENDED_TESTS_ENABLED=${VT_EXTENDED_TESTS_ENABLED} \ VT_FCONTEXT_ENABLED=${VT_FCONTEXT_ENABLED} \ - VT_USE_OPENMP=${VT_USE_OPENMP} \ - VT_USE_STD_THREAD=${VT_USE_STD_THREAD} \ VT_DIAGNOSTICS_ENABLED=${VT_DIAGNOSTICS_ENABLED} \ VT_DIAGNOSTICS_RUNTIME_ENABLED=${VT_DIAGNOSTICS_RUNTIME_ENABLED} \ VT_NO_COLOR_ENABLED=${VT_NO_COLOR_ENABLED} \ diff --git a/ci/docker/ubuntu-20.04-gnu-openmpi-cpp.dockerfile b/ci/docker/ubuntu-20.04-gnu-openmpi-cpp.dockerfile index 7630963b4d..20ae266e7d 100644 --- a/ci/docker/ubuntu-20.04-gnu-openmpi-cpp.dockerfile +++ b/ci/docker/ubuntu-20.04-gnu-openmpi-cpp.dockerfile @@ -52,7 +52,7 @@ ENV CC=gcc \ CXX=g++ COPY ./ci/deps/cmake.sh cmake.sh -RUN ./cmake.sh 3.18.4 +RUN ./cmake.sh 3.23.4 ENV PATH=/cmake/bin/:$PATH ENV LESSCHARSET=utf-8 @@ -89,8 +89,6 @@ ARG VT_POOL_ENABLED ARG VT_PRODUCTION_BUILD_ENABLED ARG VT_ZOLTAN_ENABLED ARG VT_FCONTEXT_ENABLED -ARG VT_USE_OPENMP -ARG VT_USE_STD_THREAD ARG CMAKE_BUILD_TYPE ARG VT_EXTENDED_TESTS_ENABLED ARG VT_NO_COLOR_ENABLED @@ -112,8 +110,6 @@ ENV VT_LB_ENABLED=${VT_LB_ENABLED} \ VT_UNITY_BUILD_ENABLED=${VT_UNITY_BUILD_ENABLED} \ VT_PRODUCTION_BUILD_ENABLED=${VT_PRODUCTION_BUILD_ENABLED} \ VT_FCONTEXT_ENABLED=${VT_FCONTEXT_ENABLED} \ - VT_USE_OPENMP=${VT_USE_OPENMP} \ - VT_USE_STD_THREAD=${VT_USE_STD_THREAD} \ VT_DIAGNOSTICS_ENABLED=${VT_DIAGNOSTICS_ENABLED} \ VT_DIAGNOSTICS_RUNTIME_ENABLED=${VT_DIAGNOSTICS_RUNTIME_ENABLED} \ VT_NO_COLOR_ENABLED=${VT_NO_COLOR_ENABLED} \ diff --git a/ci/docker/ubuntu-clang-cpp.dockerfile b/ci/docker/ubuntu-clang-cpp.dockerfile index df7d0de7be..0436a57db9 100644 --- a/ci/docker/ubuntu-clang-cpp.dockerfile +++ b/ci/docker/ubuntu-clang-cpp.dockerfile @@ -44,7 +44,7 @@ COPY ./ci/deps/libunwind.sh libunwind.sh RUN ./libunwind.sh 1.6.2 COPY ./ci/deps/cmake.sh cmake.sh -RUN ./cmake.sh 3.18.4 +RUN ./cmake.sh 3.23.4 ENV PATH=/cmake/bin/:$PATH ENV LESSCHARSET=utf-8 @@ -77,8 +77,6 @@ ARG VT_PRODUCTION_BUILD_ENABLED ARG VT_TRACE_ENABLED ARG VT_TRACE_RUNTIME_ENABLED ARG VT_UBSAN_ENABLED -ARG VT_USE_OPENMP -ARG VT_USE_STD_THREAD ARG VT_WERROR_ENABLED ARG CMAKE_CXX_STANDARD @@ -100,8 +98,6 @@ ENV BUILD_SHARED_LIBS=${BUILD_SHARED_LIBS} \ VT_TRACE_RUNTIME_ENABLED=${VT_TRACE_RUNTIME} \ VT_UBSAN_ENABLED=${VT_UBSAN_ENABLED} \ VT_UNITY_BUILD_ENABLED=${VT_UNITY_BUILD_ENABLED} \ - VT_USE_OPENMP=${VT_USE_OPENMP} \ - VT_USE_STD_THREAD=${VT_USE_STD_THREAD} \ VT_WERROR_ENABLED=${VT_WERROR_ENABLED} \ CMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD} diff --git a/ci/docker/ubuntu-gnu-cpp.dockerfile b/ci/docker/ubuntu-gnu-cpp.dockerfile index 0c234aa9c0..d32a4e7df6 100644 --- a/ci/docker/ubuntu-gnu-cpp.dockerfile +++ b/ci/docker/ubuntu-gnu-cpp.dockerfile @@ -57,7 +57,7 @@ ENV CC=gcc \ CXX=g++ COPY ./ci/deps/cmake.sh cmake.sh -RUN ./cmake.sh 3.18.4 +RUN ./cmake.sh 3.23.4 ENV PATH=/cmake/bin/:$PATH ENV LESSCHARSET=utf-8 @@ -104,8 +104,6 @@ ARG VT_PRODUCTION_BUILD_ENABLED ARG VT_TRACE_ENABLED ARG VT_TRACE_RUNTIME_ENABLED ARG VT_UBSAN_ENABLED -ARG VT_USE_OPENMP -ARG VT_USE_STD_THREAD ARG VT_WERROR_ENABLED ARG VT_ZOLTAN_ENABLED ARG CMAKE_CXX_STANDARD @@ -128,8 +126,6 @@ ENV BUILD_SHARED_LIBS=${BUILD_SHARED_LIBS} \ VT_TRACE_RUNTIME_ENABLED=${VT_TRACE_RUNTIME} \ VT_UBSAN_ENABLED=${VT_UBSAN_ENABLED} \ VT_UNITY_BUILD_ENABLED=${VT_UNITY_BUILD_ENABLED} \ - VT_USE_OPENMP=${VT_USE_OPENMP} \ - VT_USE_STD_THREAD=${VT_USE_STD_THREAD} \ VT_WERROR_ENABLED=${VT_WERROR_ENABLED} \ VT_ZOLTAN_ENABLED=${VT_ZOLTAN_ENABLED} \ CMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD} diff --git a/ci/docker/ubuntu-intel-oneapi-cpp.dockerfile b/ci/docker/ubuntu-intel-oneapi-cpp.dockerfile index 1cc6a200d3..c3ce8235c7 100644 --- a/ci/docker/ubuntu-intel-oneapi-cpp.dockerfile +++ b/ci/docker/ubuntu-intel-oneapi-cpp.dockerfile @@ -11,7 +11,7 @@ ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update -y -q && \ apt-get install -y -q --no-install-recommends \ - intel-oneapi-compiler-dpcpp-cpp-and-cpp-classic \ + intel-oneapi-compiler-dpcpp-cpp-and-cpp-classic-2022.2.1 \ ca-certificates \ less \ curl \ @@ -70,8 +70,6 @@ ARG VT_WERROR_ENABLED ARG VT_POOL_ENABLED ARG VT_PRODUCTION_BUILD_ENABLED ARG VT_FCONTEXT_ENABLED -ARG VT_USE_OPENMP -ARG VT_USE_STD_THREAD ARG CMAKE_BUILD_TYPE ARG VT_EXTENDED_TESTS_ENABLED ARG CMAKE_CXX_STANDARD @@ -89,8 +87,6 @@ ENV VT_LB_ENABLED=${VT_LB_ENABLED} \ VT_UNITY_BUILD_ENABLED=${VT_UNITY_BUILD_ENABLED} \ VT_PRODUCTION_BUILD_ENABLED=${VT_PRODUCTION_BUILD_ENABLED} \ VT_FCONTEXT_ENABLED=${VT_FCONTEXT_ENABLED} \ - VT_USE_OPENMP=${VT_USE_OPENMP} \ - VT_USE_STD_THREAD=${VT_USE_STD_THREAD} \ VT_DIAGNOSTICS_ENABLED=${VT_DIAGNOSTICS_ENABLED} \ VT_DIAGNOSTICS_RUNTIME_ENABLED=${VT_DIAGNOSTICS_RUNTIME_ENABLED} \ CMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD} \ diff --git a/ci/docker/ubuntu-nvidia-cpp.dockerfile b/ci/docker/ubuntu-nvidia-cpp.dockerfile index 316fc385d2..8c803045ca 100644 --- a/ci/docker/ubuntu-nvidia-cpp.dockerfile +++ b/ci/docker/ubuntu-nvidia-cpp.dockerfile @@ -1,10 +1,11 @@ -ARG cuda=10.1 +ARG compiler=11.0.3 ARG arch=amd64 -FROM ${arch}/ubuntu:18.04 as base +# Works with 20.04 and 22.04 +ARG ubuntu=20.04 +FROM --platform=${arch} nvidia/cuda:${compiler}-devel-ubuntu${ubuntu} as base ARG proxy="" -ARG compiler=nvcc-10 ENV https_proxy=${proxy} \ http_proxy=${proxy} @@ -12,9 +13,8 @@ ENV https_proxy=${proxy} \ ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update -y -q && \ - apt-get install -y -q --no-install-recommends \ + apt-get install -y --no-install-recommends \ ca-certificates \ - g++-7 \ curl \ less \ git \ @@ -31,49 +31,11 @@ RUN apt-get update -y -q && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* -RUN if test ${compiler} = "nvcc-10"; then \ - wget http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-ubuntu1804.pin && \ - mv cuda-ubuntu1804.pin /etc/apt/preferences.d/cuda-repository-pin-600 && \ - wget http://developer.download.nvidia.com/compute/cuda/10.1/Prod/local_installers/cuda-repo-ubuntu1804-10-1-local-10.1.243-418.87.00_1.0-1_amd64.deb && \ - dpkg -i cuda-repo-ubuntu1804-10-1-local-10.1.243-418.87.00_1.0-1_amd64.deb && \ - apt-key add /var/cuda-repo-10-1-local-10.1.243-418.87.00/7fa2af80.pub && \ - apt-get update && \ - apt-get -y install cuda-nvcc-10-1 cuda-cudart-dev-10-1 && \ - apt-get clean && \ - rm -rf /var/lib/apt/lists/* && \ - rm -rf cuda-repo-ubuntu1804-10-1-local-10.1.243-418.87.00_1.0-1_amd64.deb && \ - ln -s /usr/local/cuda-10.1 /usr/local/cuda-versioned; \ - elif test ${compiler} = "nvcc-10.2"; then \ - wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-ubuntu1804.pin && \ - mv cuda-ubuntu1804.pin /etc/apt/preferences.d/cuda-repository-pin-600 && \ - wget https://developer.download.nvidia.com/compute/cuda/10.2/Prod/local_installers/cuda-repo-ubuntu1804-10-2-local-10.2.89-440.33.01_1.0-1_amd64.deb && \ - dpkg -i cuda-repo-ubuntu1804-10-2-local-10.2.89-440.33.01_1.0-1_amd64.deb && \ - apt-key add /var/cuda-repo-10-2-local-10.2.89-440.33.01/7fa2af80.pub && \ - apt-get update && \ - apt-get -y install cuda && \ - apt-get clean && \ - rm -rf /var/lib/apt/lists/* && \ - rm -rf cuda-repo-ubuntu1804-10-2-local-10.2.89-440.33.01_1.0-1_amd64.deb && \ - ln -s /usr/local/cuda-10.2 /usr/local/cuda-versioned; \ - else \ - wget http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-ubuntu1804.pin && \ - mv cuda-ubuntu1804.pin /etc/apt/preferences.d/cuda-repository-pin-600 && \ - wget http://developer.download.nvidia.com/compute/cuda/11.0.1/local_installers/cuda-repo-ubuntu1804-11-0-local_11.0.1-450.36.06-1_amd64.deb && \ - dpkg -i cuda-repo-ubuntu1804-11-0-local_11.0.1-450.36.06-1_amd64.deb && \ - apt-key add /var/cuda-repo-ubuntu1804-11-0-local/7fa2af80.pub && \ - apt-get update && \ - apt-get -y install cuda-nvcc-11-0 && \ - apt-get clean && \ - rm -rf /var/lib/apt/lists/* && \ - rm -rf cuda-repo-ubuntu1804-11-0-local_11.0.1-450.36.06-1_amd64.deb && \ - ln -s /usr/local/cuda-11.0 /usr/local/cuda-versioned; \ - fi - ENV CC=gcc \ CXX=g++ COPY ./ci/deps/cmake.sh cmake.sh -RUN ./cmake.sh 3.18.4 +RUN ./cmake.sh 3.23.4 ENV PATH=/cmake/bin/:$PATH ENV LESSCHARSET=utf-8 @@ -81,16 +43,13 @@ ENV LESSCHARSET=utf-8 COPY ./ci/deps/mpich.sh mpich.sh RUN ./mpich.sh 3.3.2 -j4 -ENV CUDACXX=/usr/local/cuda-versioned/bin/nvcc -ENV PATH=/usr/local/cuda-versioned/bin/:$PATH - RUN mkdir -p /nvcc_wrapper/build && \ - wget https://raw.githubusercontent.com/kokkos/kokkos/3.4.00/bin/nvcc_wrapper -P /nvcc_wrapper/build && \ + wget https://raw.githubusercontent.com/kokkos/kokkos/master/bin/nvcc_wrapper -P /nvcc_wrapper/build && \ chmod +x /nvcc_wrapper/build/nvcc_wrapper ENV MPI_EXTRA_FLAGS="" \ - CXX=/nvcc_wrapper/build/nvcc_wrapper \ - PATH=/usr/lib/ccache/:$PATH + PATH=/usr/lib/ccache/:/nvcc_wrapper/build:$PATH \ + CXX=nvcc_wrapper FROM base as build COPY . /vt @@ -108,8 +67,6 @@ ARG VT_PRODUCTION_BUILD_ENABLED ARG CMAKE_BUILD_TYPE ARG VT_EXTENDED_TESTS_ENABLED ARG VT_FCONTEXT_ENABLED -ARG VT_USE_OPENMP -ARG VT_USE_STD_THREAD ARG VT_NO_COLOR_ENABLED ARG BUILD_SHARED_LIBS ARG CMAKE_CXX_STANDARD @@ -127,8 +84,6 @@ ENV VT_LB_ENABLED=${VT_LB_ENABLED} \ VT_UNITY_BUILD_ENABLED=${VT_UNITY_BUILD_ENABLED} \ VT_PRODUCTION_BUILD_ENABLED=${VT_PRODUCTION_BUILD_ENABLED} \ VT_FCONTEXT_ENABLED=${VT_FCONTEXT_ENABLED} \ - VT_USE_OPENMP=${VT_USE_OPENMP} \ - VT_USE_STD_THREAD=${VT_USE_STD_THREAD} \ VT_DIAGNOSTICS_ENABLED=${VT_DIAGNOSTICS_ENABLED} \ VT_DIAGNOSTICS_RUNTIME_ENABLED=${VT_DIAGNOSTICS_RUNTIME_ENABLED} \ VT_NO_COLOR_ENABLED=${VT_NO_COLOR_ENABLED} \ diff --git a/ci/test_spack_package.sh b/ci/test_spack_package.sh index ccb1d00de0..abdc18eed2 100755 --- a/ci/test_spack_package.sh +++ b/ci/test_spack_package.sh @@ -26,8 +26,6 @@ variables_map["diagnostics_enabled"]="${VT_DIAGNOSTICS_ENABLED:-0}" variables_map["diagnostics_runtime_enabled"]="${VT_DIAGNOSTICS_RUNTIME_ENABLED:-0}" variables_map["unity_build_enabled"]="${VT_UNITY_BUILD_ENABLED:-0}" variables_map["fcontext_enabled"]="${VT_FCONTEXT_ENABLED:-0}" -variables_map["use_openmp"]="${VT_USE_OPENMP:-0}" -variables_map["use_std_thread"]="${VT_USE_STD_THREAD:-0}" cmd_vars=() for flag in "${!variables_map[@]}" diff --git a/cmake/check_compiler.cmake b/cmake/check_compiler.cmake index cc513d3df9..3212345d8f 100644 --- a/cmake/check_compiler.cmake +++ b/cmake/check_compiler.cmake @@ -12,7 +12,7 @@ function(check_cc_quirk VAR CC_FILE) ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/cc_tests/${CC_FILE} OUTPUT_VARIABLE check_cc_quirk_output - CXX_STANDARD 14 + CXX_STANDARD 17 CXX_STANDARD_REQUIRED ON CXX_EXTENSIONS OFF ) diff --git a/cmake/link_vt.cmake b/cmake/link_vt.cmake index e1fa69d8c4..b85f79dff0 100644 --- a/cmake/link_vt.cmake +++ b/cmake/link_vt.cmake @@ -17,8 +17,6 @@ function(link_target_with_vt) singleValArg TARGET BUILD_TYPE - LINK_OPENMP - LINK_STDTHREAD LINK_GTEST # the following linking options are enabled by default LINK_ATOMIC @@ -29,7 +27,6 @@ function(link_target_with_vt) LINK_ZLIB LINK_FCONTEXT LINK_CHECKPOINT - LINK_DETECTOR LINK_CLI11 LINK_DL LINK_ZOLTAN @@ -196,15 +193,6 @@ function(link_target_with_vt) ) endif() - if (NOT DEFINED ARG_LINK_DETECTOR AND ${ARG_DEFAULT_LINK_SET} OR ARG_LINK_DETECTOR) - if (${ARG_DEBUG_LINK}) - message(STATUS "link_target_with_vt: detector=${ARG_LINK_DETECTOR}") - endif() - target_link_libraries( - ${ARG_TARGET} PUBLIC ${ARG_BUILD_TYPE} vt::lib::detector - ) - endif() - if (NOT DEFINED ARG_LINK_CLI11 AND ${ARG_DEFAULT_LINK_SET} OR ARG_LINK_CLI11) if (${ARG_DEBUG_LINK}) message(STATUS "link_target_with_vt: cli11=${ARG_LINK_CLI11}") @@ -215,25 +203,6 @@ function(link_target_with_vt) ) endif() - if (NOT DEFINED ARG_LINK_OPENMP AND DEFAULT_THREADING STREQUAL openmp OR ARG_LINK_OPENMP) - if (${ARG_DEBUG_LINK}) - message( - STATUS - "link_target_with_vt: dt=${DEFAULT_THREADING}, omp=${ARG_LINK_OPENMP}" - ) - endif() - target_link_libraries( - ${ARG_TARGET} PUBLIC ${ARG_BUILD_TYPE} OpenMP::OpenMP_CXX - ) - elseif (NOT DEFINED ARG_LINK_STDTHREAD AND DEFAULT_THREADING STREQUAL stdthread OR ARG_LINK_STDTHREAD) - if (${ARG_DEBUG_LINK}) - message(STATUS "link_target_with_vt(..): stdthread=${ARG_LINK_STDTHREAD}") - endif() - target_link_libraries( - ${ARG_TARGET} PUBLIC ${ARG_BUILD_TYPE} Threads::Threads - ) - endif() - if (${vt_mimalloc_enabled}) if (${ARG_DEBUG_LINK}) message(STATUS "link_target_with_vt: mimalloc=${vt_mimalloc_enabled}") diff --git a/cmake/load_bundled_libraries.cmake b/cmake/load_bundled_libraries.cmake index 6331d8f93c..96146ad6d3 100644 --- a/cmake/load_bundled_libraries.cmake +++ b/cmake/load_bundled_libraries.cmake @@ -2,9 +2,6 @@ include(SetCXXCompilerFlags) -# Export a minimum version flag for any bundled libraries that don't set their own -set(CMAKE_CXX_STANDARD 14) - # Optionally include libfort which is used by diagnostics if (vt_libfort_enabled) set(FORT_ENABLE_TESTING OFF CACHE INTERNAL "") diff --git a/cmake/load_local_packages.cmake b/cmake/load_local_packages.cmake index ac98393db5..029d8bd96e 100644 --- a/cmake/load_local_packages.cmake +++ b/cmake/load_local_packages.cmake @@ -5,15 +5,6 @@ include(cmake/local_package.cmake) -if (EXISTS "${PROJECT_LIB_DIR}/detector") - add_subdirectory(${PROJECT_LIB_DIR}/detector) -else() - # require directories for these packages - require_pkg_directory(detector "VT detector library") - # find these required packages locally - find_package_local(detector "${detector_DIR}" detector) -endif() - if (EXISTS "${PROJECT_LIB_DIR}/checkpoint") add_subdirectory(${PROJECT_LIB_DIR}/checkpoint) else() diff --git a/cmake/load_packages.cmake b/cmake/load_packages.cmake index b3c8eb05c7..01c60990e4 100644 --- a/cmake/load_packages.cmake +++ b/cmake/load_packages.cmake @@ -1,6 +1,6 @@ get_directory_property(projHasParent PARENT_DIRECTORY) -# Local packages that VT depends on (detector/checkpoint) +# Local packages that VT depends on: checkpoint include(cmake/load_local_packages.cmake) # MPI package diff --git a/cmake/load_threading_package.cmake b/cmake/load_threading_package.cmake index 29350db140..8b5e5e1c36 100644 --- a/cmake/load_threading_package.cmake +++ b/cmake/load_threading_package.cmake @@ -2,46 +2,17 @@ # Load and discover threading settings # -include(cmake/threading_config.cmake) - # Threading build configuration -option(USE_STD_THREAD "whether to force use of std::thread for threading" OFF) -option(USE_OPENMP "whether to force use of OpenMP for threading" OFF) option(vt_fcontext_enabled "Build VT with fcontext (ULT) enabled" OFF) -if (USE_STD_THREAD) - message( - STATUS - "Using std::thread for worker threading" - ) - find_package(Threads) - config_for_std_thread() -elseif(USE_OPENMP) - message( - STATUS - "Using OpenMP for worker threading" - ) - find_package(OpenMP) - config_for_openmp() - if (NOT OpenMP_FOUND) - message( - FATAL_ERROR - "requested OpenMP with -DUSE_OPENMP=On, but cannot find " - "valid OpenMP in compiler" - ) - endif() -elseif(vt_fcontext_enabled) +if(vt_fcontext_enabled) message( STATUS "Using fcontext for worker threading" ) - config_for_fcontext() else() message( STATUS "Threading disabled" ) - config_no_threading() endif() - -set(THREADS_DEPENDENCY ${LOCAL_THREADS_DEPENDENCY} CACHE STRING "Rule for threading dependency used in vtConfig" FORCE) diff --git a/cmake/threading_config.cmake b/cmake/threading_config.cmake deleted file mode 100644 index 39a878d483..0000000000 --- a/cmake/threading_config.cmake +++ /dev/null @@ -1,39 +0,0 @@ -function(config_for_openmp) - message( - STATUS - "OpenMP has been found: " - "Linker=\"${OpenMP_EXE_LINKER_FLAGS}\", " - "CC FLAGS=\"${OpenMP_C_FLAGS}\", " - "CXX FLAGS=\"${OpenMP_CXX_FLAGS}\"" - ) - - set(DEFAULT_THREADING openmp PARENT_SCOPE) - - set(vt_feature_cmake_openmp "1" PARENT_SCOPE) - set(vt_feature_cmake_stdthread "0" PARENT_SCOPE) - set(vt_fcontext_enabled "0" PARENT_SCOPE) - - set(LOCAL_THREADS_DEPENDENCY "find_dependency(OpenMP REQUIRED)" PARENT_SCOPE) -endfunction(config_for_openmp) - -function(config_for_std_thread) - set(DEFAULT_THREADING stdthread PARENT_SCOPE) - - set(vt_feature_cmake_openmp "0" PARENT_SCOPE) - set(vt_feature_cmake_stdthread "1" PARENT_SCOPE) - set(vt_fcontext_enabled "0" PARENT_SCOPE) - - set(LOCAL_THREADS_DEPENDENCY "find_dependency(Threads REQUIRED)" PARENT_SCOPE) -endfunction(config_for_std_thread) - -function(config_for_fcontext) - set(vt_feature_cmake_openmp "0" PARENT_SCOPE) - set(vt_feature_cmake_stdthread "0" PARENT_SCOPE) - set(vt_fcontext_enabled "1" PARENT_SCOPE) -endfunction(config_for_fcontext) - -function(config_no_threading) - set(vt_feature_cmake_openmp "0" PARENT_SCOPE) - set(vt_feature_cmake_stdthread "0" PARENT_SCOPE) - set(vt_fcontext_enabled "0" PARENT_SCOPE) -endfunction(config_no_threading) diff --git a/cmake/trace_only_functions.cmake b/cmake/trace_only_functions.cmake index 591f56075c..edeaf57ff4 100644 --- a/cmake/trace_only_functions.cmake +++ b/cmake/trace_only_functions.cmake @@ -50,8 +50,7 @@ function(create_trace_only_target) vt/utils/demangle/demangle.h vt/utils/bits/bits_counter.h vt/utils/bits/bits_common.h vt/utils/bits/bits_packer.h vt/utils/bits/bits_packer.impl.h vt/utils/adt/union.h - vt/utils/tls/tls.h vt/utils/tls/std_tls.h vt/utils/tls/null_tls.h - vt/utils/tls/tls.impl.h vt/utils/adt/histogram_approx.h + vt/utils/adt/histogram_approx.h # vt/collective vt/collective/basic.h @@ -157,7 +156,7 @@ function(set_trace_only_config) # since the scope is local to this function set(vt_feature_cmake_trace_enabled "1") set(vt_feature_cmake_trace_only "1") - config_no_threading() + set(vt_fcontext_enabled "0" PARENT_SCOPE) configure_file( ${PROJECT_BASE_DIR}/cmake_config.h.in diff --git a/cmake/vtConfig.cmake.in b/cmake/vtConfig.cmake.in index c13ed413d6..97a179750d 100644 --- a/cmake/vtConfig.cmake.in +++ b/cmake/vtConfig.cmake.in @@ -14,16 +14,10 @@ endif() include(CMakeFindDependencyMacro) -@THREADS_DEPENDENCY@ @ZOLTAN_DEPENDENCY@ find_dependency(MPI REQUIRED) -if (@detector_PACKAGE_LOADED@) - set (detector_DIR @detector_DIR@) - find_dependency(detector REQUIRED HINTS @detector_DIR@) -endif() - if (@checkpoint_PACKAGE_LOADED@) set (checkpoint_DIR @checkpoint_DIR@) find_dependency(checkpoint REQUIRED HINTS @checkpoint_DIR@) diff --git a/cmake_config.h.in b/cmake_config.h.in index 686c98e95e..fe189b7565 100644 --- a/cmake_config.h.in +++ b/cmake_config.h.in @@ -46,9 +46,7 @@ #define vt_feature_cmake_trace_enabled @vt_feature_cmake_trace_enabled@ #define vt_feature_cmake_trace_only @vt_feature_cmake_trace_only@ #define vt_feature_cmake_lblite @vt_feature_cmake_lblite@ -#define vt_feature_cmake_openmp @vt_feature_cmake_openmp@ #define vt_feature_cmake_production @vt_feature_cmake_production@ -#define vt_feature_cmake_stdthread @vt_feature_cmake_stdthread@ #define vt_feature_cmake_mpi_rdma @vt_feature_cmake_mpi_rdma@ #define vt_feature_cmake_print_term_msgs @vt_feature_cmake_print_term_msgs@ #define vt_feature_cmake_no_pool_alloc_env @vt_feature_cmake_no_pool_alloc_env@ diff --git a/docker-compose.yml b/docker-compose.yml index 08a5d240dc..f9048ba96d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -14,7 +14,7 @@ # clang-4.0, clang-5.0, clang-6.0, clang-7, clang-8, # clang-9, clang-10, # icpx, -# nvcc-10, nvcc-10.2, nvcc-11} +# nvcc-11, nvcc-11.2} # REPO=lifflander1/vt # UBUNTU={18.04, 20.04} # ULIMIT_CORE=0 @@ -33,8 +33,6 @@ # VT_UNITY_BUILD=0 # Build with Unity/Jumbo mode enabled # VT_PRODUCTION_BUILD=0 # Disable assertions and debug prints # VT_FCONTEXT=0 # Force use of fcontext for threading -# VT_USE_OPENMP=0 # Force use of OpenMP for threading -# VT_USE_STD_THREAD=0 # Force use of std::thread for threading # VT_DIAGNOSTICS=1 # Build with diagnostics enabled # VT_DIAGNOSTICS_RUNTIME=0 # Enable diagnostics collection at runtime by default # BUILD_TYPE=release # CMake build type @@ -86,9 +84,8 @@ volumes: amd64-ubuntu-20.04-gcc-10-cache: amd64-ubuntu-18.04-icpx-cache: amd64-ubuntu-18.04-icpc-cache: - amd64-ubuntu-18.04-nvcc-10-cache: - amd64-ubuntu-18.04-nvcc-10.2-cache: amd64-ubuntu-18.04-nvcc-11-cache: + amd64-ubuntu-18.04-nvcc-11.2-cache: amd64-alpine-clang-4.0-cache: amd64-alpine-clang-5.0-cache: amd64-alpine-clang-6.0-cache: @@ -106,9 +103,8 @@ volumes: amd64-alpine-icc-20-cache: amd64-alpine-icpx-cache: amd64-alpine-icpc-cache: - amd64-alpine-nvcc-10-cache: - amd64-alpine-nvcc-10.2-cache: amd64-alpine-nvcc-11-cache: + amd64-alpine-nvcc-11.2-cache: arm64v8-ubuntu-18.04-gcc-7-cache: arm64v8-alpine-gcc-7-cache: @@ -139,8 +135,6 @@ x-vtopts: &vtopts VT_UNITY_BUILD_ENABLED: ${VT_UNITY_BUILD:-0} VT_PRODUCTION_BUILD_ENABLED: ${VT_PRODUCTION_BUILD:-0} VT_FCONTEXT_ENABLED: ${VT_FCONTEXT:-0} - VT_USE_OPENMP: ${VT_USE_OPENMP:-0} - VT_USE_STD_THREAD: ${VT_USE_STD_THREAD:-0} VT_DIAGNOSTICS_ENABLED: ${VT_DIAGNOSTICS:-1} VT_DIAGNOSTICS_RUNTIME_ENABLED: ${VT_DIAGNOSTICS_RUNTIME:-0} CMAKE_BUILD_TYPE: ${BUILD_TYPE:-release} @@ -159,7 +153,7 @@ x-vtopts: &vtopts VT_INCLUSION_TYPE: ${VT_INCLUSION:-TPL} CODECOV_TOKEN: ${CODECOV_TOKEN:-} TEST_LB_SCHEMA: ${TEST_LB_SCHEMA:-0} - CMAKE_CXX_STANDARD: ${CMAKE_CXX_STANDARD:-14} + CMAKE_CXX_STANDARD: ${CMAKE_CXX_STANDARD:-17} services: ############################################################################## diff --git a/docs/Doxyfile.in-mcss b/docs/Doxyfile.in-mcss index aa8bc4751f..8d1fd5803e 100644 --- a/docs/Doxyfile.in-mcss +++ b/docs/Doxyfile.in-mcss @@ -14,7 +14,7 @@ M_LINKS_NAVBAR1 = \ M_LINKS_NAVBAR2 = \ "annotated" \ "files" \ - "GitHub Checkpoint Detector LBAF Checkpoint Analyzer Documentation" + "GitHub Checkpoint LBAF Checkpoint Analyzer Documentation" ALIASES += \ diff --git a/docs/md/building.md b/docs/md/building.md index 60728d090f..d47c2b7048 100644 --- a/docs/md/building.md +++ b/docs/md/building.md @@ -9,26 +9,19 @@ external dependencies come bundled with \vt for ease of compiling. To build \vt, one must obtain the following dependencies: \subsection required-deps Required - - detector, (*vt* ecosystem) - checkpoint, (*vt* ecosystem) - MPI (mpich/openmpi/mvapich/IBM Spectrum MPI/Cray MPICH/etc.) -\subsection optional-deps Optional (if threading enabled) - - - OpenMP _or_ - - Default to `std::thread` - \subsection automatic-build-deps Automatically build dependencies -Assuming MPI is installed and accessible via CC/CXX, the only other dependencies -that are required are checkpoint and detector. The easiest way to get these -built are to clone them inside `vt/lib`: +Assuming MPI is installed and accessible via CC/CXX, the only other dependency +that is required is checkpoint. The easiest way to get these +built are to clone it inside `vt/lib`: ```bash $ git clone git@github.com:DARMA-tasking/vt $ cd vt/lib $ git clone git@github.com:DARMA-tasking/checkpoint -$ git clone git@github.com:DARMA-tasking/detector ``` With these in `vt/lib`, cmake will automatically build them and stitch them into @@ -36,7 +29,7 @@ With these in `vt/lib`, cmake will automatically build them and stitch them into \subsection use-cmake-directly-vars Using cmake directly -One may use `cmake` as normal on *vt*, with checkpoint and detector cloned in +One may use `cmake` as normal on *vt*, with checkpoint cloned in `vt/lib` to compile them all together as explained above. The following are some custom configuration build options that can be provided to `cmake` to change the build configuration: @@ -65,8 +58,6 @@ build configuration: | `vt_fcontext_enabled` | 0 | Force use of fcontext for threading | | `vt_tests_num_nodes` | - | Maximum number of nodes used for tests. If empty, then the default value detected by CMake is used | | `CODE_COVERAGE` | 0 | Enable code coverage for VT examples/tests | -| `USE_OPENMP` | 0 | Force use of OpenMP for threading | -| `USE_STD_THREAD` | 0 | Force use of std::thread for threading | | `VT_BUILD_TESTS` | 1 | Build all VT tests | | `VT_BUILD_EXAMPLES` | 1 | Build all VT examples | | `vt_debug_verbose` | 1 (not Release) | Enable VT verbose debug prints at compile-time | @@ -95,8 +86,6 @@ parameters. | `VT_WERROR_ENABLED ` | 0 | Treat all warnings as errors | | `VT_POOL_ENABLED ` | 1 | Use memory pool in *vt* for message allocation | | `VT_FCONTEXT_ENABLED` | 0 | Force use of fcontext for threading | -| `VT_USE_OPENMP` | 0 | Force use of OpenMP for threading | -| `VT_USE_STD_THREAD` | 0 | Force use of std::thread for threading | | `VT_ZOLTAN_ENABLED ` | 0 | Build with Zoltan enabled for `ZoltanLB` support | | `ZOLTAN_DIR ` | | Directory pointing to Zoltan installation | | `VT_MPI_GUARD_ENABLED ` | 0 | Guards against mis-use of MPI calls in code using *vt* | @@ -154,7 +143,7 @@ which `docker-compose` will read. # clang-4.0, clang-5.0, clang-6.0, clang-7, clang-8, # clang-9, clang-10, # icc-18, icc-19, -# nvcc-10, nvcc-11} +# nvcc-10, nvcc-11, nvcc-11.2} # REPO=lifflander1/vt # UBUNTU={18.04, 20.04} # ULIMIT_CORE=0 @@ -172,8 +161,6 @@ which `docker-compose` will read. # VT_ZOLTAN=0 # Build with Zoltan enabled # VT_UNITY_BUILD=0 # Build with Unity/Jumbo mode enabled # VT_FCONTEXT=0 # Force use of fcontext for threading -# VT_USE_OPENMP=0 # Force use of OpenMP for threading -# VT_USE_STD_THREAD=0 # Force use of std::thread for threading # VT_DIAGNOSTICS=1 # Build with diagnostics enabled # VT_DIAGNOSTICS_RUNTIME=0 # Enable diagnostics at runtime by default # BUILD_TYPE=release # CMake build type diff --git a/docs/md/mainpage.md b/docs/md/mainpage.md index 270b84eb70..7583c0aa63 100644 --- a/docs/md/mainpage.md +++ b/docs/md/mainpage.md @@ -27,7 +27,6 @@ supercomputer architectures. The main public repositories are: | ---------------------------------- | -------------------------------------------------------------- | -------------------------- | | HPC Runtime | @m_span{m-text m-success} DARMA/vt @m_endspan (Virtual Transport) | [Github](https://github.com/DARMA-tasking/vt) | | HPC Serialization | @m_span{m-text m-success} DARMA/checkpoint @m_endspan (Checkpointing and Serialization Library) | [Github](https://github.com/DARMA-tasking/checkpoint) | -| C++ trait detection and checking | @m_span{m-text m-success} DARMA/detector @m_endspan (C++ trait detector) | [Github](https://github.com/DARMA-tasking/detector) | | HPC LB Simulator | @m_span{m-text m-success} DARMA/LBAF @m_endspan (Load Balancing Analysis Framework) | [Github](https://github.com/DARMA-tasking/LB-analysis-framework) | | HPC Serializer compiler analyzer | @m_span{m-text m-success} DARMA/checkpoint-analyzer @m_endspan (Static verification of serializers) | [Github](https://github.com/DARMA-tasking/checkpoint-member-analyzer) | | Toolkit documentation | @m_span{m-text m-success} DARMA/docs @m_endspan | [Docs](https://github.com/DARMA-tasking/DARMA-tasking.github.io) | diff --git a/docs/md/param.md b/docs/md/param.md deleted file mode 100644 index e51af1a698..0000000000 --- a/docs/md/param.md +++ /dev/null @@ -1,8 +0,0 @@ -\page param Parameterization -\brief Handler parameterization - -@m_class{m-label m-danger} **Experimental** - -The parameterization component `vt::param::Param`, accessed via `vt::theParam()` -is an experimental component for parameterizing arguments into active function -handlers as an alternative to messages. diff --git a/docs/md/vt.md b/docs/md/vt.md index 10d1c888b6..a9c4064320 100644 --- a/docs/md/vt.md +++ b/docs/md/vt.md @@ -29,7 +29,7 @@ management. - RDMA using MPI one-sided for data transfer - Asynchronous Collectives across nodes/groups (scatter, async barrier, reduce, ...) - General scheduler with prioritization - - Built-in interoperability with MPI and threading libraries (Kokkos, OpenMP, ...) + - Built-in interoperability with MPI and threading libraries (e.g. Kokkos, fcontext) - Object groups for node-level encapsulation - Virtual contexts for migratable virtualization and dispatch - Abstractions for multi-dimensional indices, mapping, and linearization @@ -50,7 +50,6 @@ management. | \subpage location | `vt::theLocMan()` | \copybrief location | @m_class{m-label m-success} **Core** | | \subpage mem-usage | `vt::theMemUsage()` | \copybrief mem-usage | @m_class{m-label m-warning} **Optional** | | \subpage objgroup | `vt::theObjGroup()` | \copybrief objgroup | @m_class{m-label m-success} **Core** | -| \subpage param | `vt::theParam()` | \copybrief param | @m_class{m-label m-danger} **Experimental** | | \subpage pipe | `vt::theCB()` | \copybrief pipe | @m_class{m-label m-success} **Core** | | \subpage node-lb-data | `vt::theNodeLBData()` | \copybrief node-lb-data | @m_class{m-label m-warning} **Optional** | | \subpage phase | `vt::thePhase()` | \copybrief phase | @m_class{m-label m-success} **Core** | diff --git a/examples/callback/callback.cc b/examples/callback/callback.cc index df734afcaf..316ddb0090 100644 --- a/examples/callback/callback.cc +++ b/examples/callback/callback.cc @@ -110,13 +110,13 @@ struct MyObj { struct MyCol : vt::Collection { }; // Collection handler callback endpoint -void colHan(TestMsg* msg, MyCol* col) { +void colHan(MyCol* col, TestMsg* msg) { printOutput(msg, "MyCol colHan (non-intrusive)"); } void bounceCallback(vt::Callback cb) { auto msg = vt::makeMessage(cb); - vt::theMsg()->sendMsg(1, msg); + vt::theMsg()->sendMsg(1, msg); } int main(int argc, char** argv) { diff --git a/examples/collection/jacobi1d_vt.cc b/examples/collection/jacobi1d_vt.cc index 90311bdde1..959693ad09 100644 --- a/examples/collection/jacobi1d_vt.cc +++ b/examples/collection/jacobi1d_vt.cc @@ -322,7 +322,7 @@ struct LinearPb1DJacobi : vt::Collection { bool isWorkDone( vt::objgroup::proxy::Proxy const& proxy){ auto const this_node = vt::theContext()->getNode(); - return proxy[this_node].invoke(); + return proxy[this_node].invoke<&NodeObj::isWorkFinished>(); } int main(int argc, char** argv) { diff --git a/examples/collection/jacobi2d_vt.cc b/examples/collection/jacobi2d_vt.cc index 747da6a3dc..46e9c2b8d7 100644 --- a/examples/collection/jacobi2d_vt.cc +++ b/examples/collection/jacobi2d_vt.cc @@ -427,7 +427,7 @@ struct LinearPb2DJacobi : vt::Collection { bool isWorkDone( vt::objgroup::proxy::Proxy const& proxy){ auto const this_node = vt::theContext()->getNode(); - return proxy[this_node].invoke(); + return proxy[this_node].invoke<&NodeObj::isWorkFinished>(); } int main(int argc, char** argv) { diff --git a/examples/collection/lb_iter.cc b/examples/collection/lb_iter.cc index 5b4a3ac2ca..6d467b0347 100644 --- a/examples/collection/lb_iter.cc +++ b/examples/collection/lb_iter.cc @@ -47,22 +47,7 @@ static constexpr int32_t const default_num_elms = 64; static int32_t num_iter = 8; struct IterCol : vt::Collection { - IterCol() = default; - - struct IterMsg : vt::CollectionMessage { - IterMsg() = default; - IterMsg( - int64_t const in_work_amt, int64_t const in_iter, int64_t const subphase - ) - : iter_(in_iter), work_amt_(in_work_amt), subphase_(subphase) - { } - - int64_t iter_ = 0; - int64_t work_amt_ = 0; - int64_t subphase_ = 0; - }; - - void iterWork(IterMsg* msg); + void iterWork(int64_t work_amt, int64_t iter, int subphase); template void serialize(SerializerT& s) { @@ -76,10 +61,10 @@ struct IterCol : vt::Collection { static double weight = 1.0f; -void IterCol::iterWork(IterMsg* msg) { - this->lb_data_.setSubPhase(msg->subphase_); +void IterCol::iterWork(int64_t work_amt, int64_t iter, int subphase) { + this->lb_data_.setSubPhase(subphase); double val = 0.1f; - double val2 = 0.4f * msg->work_amt_; + double val2 = 0.4f * work_amt; auto const idx = getIndex().x(); int64_t const max_work = 1000 * weight; int64_t const mid_work = 100 * weight; @@ -131,13 +116,13 @@ int main(int argc, char** argv) { auto cur_time = vt::timing::getCurrentTime(); vt::runInEpochCollective([=]{ - proxy.broadcastCollective(10, i, 0); + proxy.broadcastCollective<&IterCol::iterWork>(10, i, 0); }); vt::runInEpochCollective([=]{ - proxy.broadcastCollective(5, i, 1); + proxy.broadcastCollective<&IterCol::iterWork>(5, i, 1); }); vt::runInEpochCollective([=]{ - proxy.broadcastCollective(15, i, 2); + proxy.broadcastCollective<&IterCol::iterWork>(15, i, 2); }); auto total_time = vt::timing::getCurrentTime() - cur_time; diff --git a/examples/collection/migrate_collection.cc b/examples/collection/migrate_collection.cc index bc77c205f3..ee86a8bd2d 100644 --- a/examples/collection/migrate_collection.cc +++ b/examples/collection/migrate_collection.cc @@ -65,20 +65,12 @@ struct Hello : vt::Collection { double test_val = 0.0; }; -struct ColMsg : vt::CollectionMessage { - explicit ColMsg(vt::NodeType const& in_from_node) - : from_node(in_from_node) - { } - - vt::NodeType from_node = vt::uninitialized_destination; -}; - -static void doWork(ColMsg* msg, Hello* col) { +static void doWork(Hello* col) { vt::NodeType this_node = vt::theContext()->getNode(); fmt::print("{}: idx={}: val={}\n", this_node, col->getIndex(), col->test_val); } -static void migrateToNext(ColMsg* msg, Hello* col) { +static void migrateToNext(Hello* col) { vt::NodeType this_node = vt::theContext()->getNode(); vt::NodeType num_nodes = vt::theContext()->getNumNodes(); vt::NodeType next_node = (this_node + 1) % num_nodes; @@ -109,13 +101,9 @@ int main(int argc, char** argv) { .wait(); if (this_node == 0) { - vt::runInEpochRooted([=] { proxy.broadcast(this_node); }); - - vt::runInEpochRooted( - [=] { proxy.broadcast(this_node); } - ); - - vt::runInEpochRooted([=] { proxy.broadcast(this_node); }); + vt::runInEpochRooted([=] { proxy.broadcast(); }); + vt::runInEpochRooted([=] { proxy.broadcast(); }); + vt::runInEpochRooted([=] { proxy.broadcast(); }); } vt::finalize(); diff --git a/examples/collection/polymorphic_collection.cc b/examples/collection/polymorphic_collection.cc index e470b65576..88bab1448f 100644 --- a/examples/collection/polymorphic_collection.cc +++ b/examples/collection/polymorphic_collection.cc @@ -46,7 +46,6 @@ /// [Polymorphic collection example] static constexpr int32_t const default_num_elms = 16; struct InitialConsTag{}; -struct ColMsg; struct Hello : vt::Collection { checkpoint_virtual_serialize_root() @@ -62,19 +61,11 @@ struct Hello : vt::Collection { s | test_val; } - virtual void doWork(ColMsg* msg); + virtual void doWork(); double test_val = 0.0; }; -struct ColMsg : vt::CollectionMessage { - explicit ColMsg(vt::NodeType const& in_from_node) - : from_node(in_from_node) - { } - - vt::NodeType from_node = vt::uninitialized_destination; -}; - template struct HelloTyped : Hello { checkpoint_virtual_serialize_derived_from(Hello) @@ -84,7 +75,7 @@ struct HelloTyped : Hello { : Hello(checkpoint::SERIALIZE_CONSTRUCT_TAG{}) {} - virtual void doWork(ColMsg* msg) override; + virtual void doWork() override; template void serialize(Serializer& s) { @@ -95,14 +86,14 @@ struct HelloTyped : Hello { }; template <> -void HelloTyped::doWork(ColMsg* msg) { +void HelloTyped::doWork() { fmt::print("correctly doing this -- int!\n"); - Hello::doWork(msg); + Hello::doWork(); } template <> -void HelloTyped::doWork(ColMsg* msg) { - Hello::doWork(msg); +void HelloTyped::doWork() { + Hello::doWork(); fmt::print("correctly doing this -- double!\n"); } @@ -124,7 +115,7 @@ HelloTyped::HelloTyped(InitialConsTag) } } -void Hello::doWork(ColMsg* msg) { +void Hello::doWork() { vt_print( gen, "idx={}: val={}, type={}\n", getIndex(), test_val, typeid(*this).name() @@ -147,7 +138,7 @@ void Hello::doWork(ColMsg* msg) { } -static void migrateToNext(ColMsg* msg, Hello* col) { +static void migrateToNext(Hello* col) { vt::NodeType this_node = vt::theContext()->getNode(); vt::NodeType num_nodes = vt::theContext()->getNumNodes(); vt::NodeType next_node = (this_node + 1) % num_nodes; @@ -191,21 +182,13 @@ int main(int argc, char** argv) { .wait(); for (int p = 0; p < 10; p++) { - vt::runInEpochCollective([&]{ - proxy.broadcastCollective(this_node); - }); - vt::runInEpochCollective([&]{ - proxy.broadcastCollective(this_node); - }); - vt::runInEpochCollective([&]{ - proxy.broadcastCollective(this_node); - }); + vt::runInEpochCollective([&]{ proxy.broadcastCollective<&Hello::doWork>(); }); + vt::runInEpochCollective([&]{ proxy.broadcastCollective(); }); + vt::runInEpochCollective([&]{ proxy.broadcastCollective<&Hello::doWork>(); }); } for (int p = 0; p < 10; p++) { - vt::runInEpochCollective([&]{ - proxy.broadcastCollective(this_node); - }); + vt::runInEpochCollective([&]{ proxy.broadcastCollective<&Hello::doWork>(); }); vt::thePhase()->nextPhaseCollective(); } diff --git a/examples/collection/transpose.cc b/examples/collection/transpose.cc index 32b1074880..0a4c1ad965 100644 --- a/examples/collection/transpose.cc +++ b/examples/collection/transpose.cc @@ -165,7 +165,7 @@ struct Block : vt::Collection { ); auto const from_idx = getIndex().x(); auto data_msg = vt::makeMessage(data_,from_idx); - vt::theMsg()->sendMsg( + vt::theMsg()->sendMsg( requesting_node, data_msg ); } @@ -313,7 +313,7 @@ static void solveGroupSetup(vt::NodeType this_node, vt::VirtualProxyType coll_pr if (this_node == 1) { auto msg = vt::makeMessage(coll_proxy); vt::envelopeSetGroup(msg->env, group_id); - vt::theMsg()->broadcastMsg(msg); + vt::theMsg()->broadcastMsg(msg); } }, true ); diff --git a/examples/group/group_collective.cc b/examples/group/group_collective.cc index f75ea2664a..e43a4b0e5e 100644 --- a/examples/group/group_collective.cc +++ b/examples/group/group_collective.cc @@ -91,7 +91,7 @@ int main(int argc, char** argv) { if (this_node == 1) { auto msg = vt::makeMessage(); vt::envelopeSetGroup(msg->env, group); - vt::theMsg()->broadcastMsg(msg); + vt::theMsg()->broadcastMsg(msg); } } ); diff --git a/examples/group/group_rooted.cc b/examples/group/group_rooted.cc index bd3f3777ef..094da60fe9 100644 --- a/examples/group/group_rooted.cc +++ b/examples/group/group_rooted.cc @@ -71,7 +71,7 @@ int main(int argc, char** argv) { if (this_node == 0) { auto msg = vt::makeMessage(this_node); - vt::theMsg()->broadcastMsg(msg); + vt::theMsg()->broadcastMsg(msg); using RangeType = vt::group::region::Range; auto list = std::make_unique(num_nodes / 2, num_nodes); @@ -79,7 +79,7 @@ int main(int argc, char** argv) { vt::theGroup()->newGroup(std::move(list), [=](vt::GroupType group){ auto gmsg = vt::makeMessage(this_node); vt::envelopeSetGroup(gmsg->env, group); - vt::theMsg()->broadcastMsg(gmsg); + vt::theMsg()->broadcastMsg(gmsg); }); } diff --git a/examples/hello_world/CMakeLists.txt b/examples/hello_world/CMakeLists.txt index 2fa6194395..1b7d464fc1 100644 --- a/examples/hello_world/CMakeLists.txt +++ b/examples/hello_world/CMakeLists.txt @@ -10,7 +10,6 @@ set( hello_world_virtual_context hello_world_virtual_context_remote ring - param objgroup ) diff --git a/examples/hello_world/hello_world.cc b/examples/hello_world/hello_world.cc index 659dc86bda..5200de3783 100644 --- a/examples/hello_world/hello_world.cc +++ b/examples/hello_world/hello_world.cc @@ -49,9 +49,9 @@ struct HelloMsg : vt::Message { vt::NodeType from = 0; }; -static void hello_world(HelloMsg* msg) { +void hello_world(int a, int b, float c) { vt::NodeType this_node = vt::theContext()->getNode(); - fmt::print("{}: Hello from node {}\n", this_node, msg->from); + fmt::print("{}: Hello from node vals = {} {} {}\n", this_node, a, b, c); } int main(int argc, char** argv) { @@ -65,8 +65,7 @@ int main(int argc, char** argv) { } if (this_node == 0) { - auto msg = vt::makeMessage(this_node); - vt::theMsg()->broadcastMsg(msg); + vt::theMsg()->send(vt::Node{1}, 10, 20, 11.3f); } vt::finalize(); diff --git a/examples/hello_world/hello_world_collection.cc b/examples/hello_world/hello_world_collection.cc index 0bfbd3d826..bd9305dc2e 100644 --- a/examples/hello_world/hello_world_collection.cc +++ b/examples/hello_world/hello_world_collection.cc @@ -51,10 +51,8 @@ struct Hello : vt::Collection { vtAssert(counter_ == 1, "Must be equal"); } - using TestMsg = vt::CollectionMessage; - - void doWork(TestMsg* msg) { - fmt::print("Hello from {}\n", this->getIndex()); + void doWork(int val) { + fmt::print("Hello from {}: val={}\n", this->getIndex(), val); counter_++; } @@ -79,7 +77,7 @@ int main(int argc, char** argv) { .bounds(range) .bulkInsert() .wait(); - proxy.broadcast(); + proxy.broadcast<&Hello::doWork>(10); } vt::finalize(); diff --git a/examples/hello_world/hello_world_collection_collective.cc b/examples/hello_world/hello_world_collection_collective.cc index 091f67101a..d0e06fcd59 100644 --- a/examples/hello_world/hello_world_collection_collective.cc +++ b/examples/hello_world/hello_world_collection_collective.cc @@ -52,11 +52,11 @@ struct Hello : vt::Collection { vtAssert(counter_ == num_nodes, "Should receive # nodes broadcasts"); } - using TestMsg = vt::CollectionMessage; - - void doWork(TestMsg* msg) { + void doWork(int val) { counter_++; - fmt::print("Hello from {}, counter_={}\n", this->getIndex().x(), counter_); + fmt::print( + "Hello from {}, val={}, counter_={}\n", getIndex(), val, counter_ + ); } private: @@ -78,7 +78,7 @@ int main(int argc, char** argv) { .wait(); // All nodes send a broadcast to all elements - proxy.broadcast(); + proxy.broadcast<&Hello::doWork>(29); vt::finalize(); diff --git a/examples/hello_world/hello_world_collection_reduce.cc b/examples/hello_world/hello_world_collection_reduce.cc index dcbb5f2930..38db1bde36 100644 --- a/examples/hello_world/hello_world_collection_reduce.cc +++ b/examples/hello_world/hello_world_collection_reduce.cc @@ -51,9 +51,7 @@ struct Hello : vt::Collection { fmt::print("Reduce complete at {} value {}\n", this->getIndex(), msg->getVal()); } - using TestMsg = vt::CollectionMessage; - - void doWork(TestMsg* msg) { + void doWork() { fmt::print("Hello from {}\n", this->getIndex()); // Get the proxy for the collection @@ -85,7 +83,7 @@ int main(int argc, char** argv) { .wait(); if (this_node == 0) { - proxy.broadcast(); + proxy.broadcast<&Hello::doWork>(); } vt::finalize(); diff --git a/examples/hello_world/hello_world_collection_staged_insert.cc b/examples/hello_world/hello_world_collection_staged_insert.cc index e3c026d5ec..ef097c61cd 100644 --- a/examples/hello_world/hello_world_collection_staged_insert.cc +++ b/examples/hello_world/hello_world_collection_staged_insert.cc @@ -58,9 +58,7 @@ struct Hello : vt::Collection { vtAssert(counter_ == 1, "Must be equal"); } - using TestMsg = vt::CollectionMessage; - - void doWork(TestMsg* msg) { + void doWork() { counter_++; vt::NodeType this_node = vt::theContext()->getNode(); @@ -107,7 +105,7 @@ int main(int argc, char** argv) { .wait(); if (this_node == 1) { - proxy.broadcast(); + proxy.broadcast<&Hello::doWork>(); } vt::finalize(); diff --git a/examples/hello_world/hello_world_virtual_context.cc b/examples/hello_world/hello_world_virtual_context.cc index 0153a5097e..8b7e6c7591 100644 --- a/examples/hello_world/hello_world_virtual_context.cc +++ b/examples/hello_world/hello_world_virtual_context.cc @@ -67,7 +67,7 @@ struct MyVC : vt::vrt::VirtualContext { { } }; -static void my_han(TestMsg* msg, MyVC* vc) { +static void my_han(MyVC* vc, TestMsg* msg) { auto this_node = vt::theContext()->getNode(); fmt::print( "{}: vc={}: msg->from={}, vc->my_data={}\n", @@ -105,7 +105,7 @@ int main(int argc, char** argv) { // send out the proxy to all the nodes auto msg = vt::makeMessage(proxy); - vt::theMsg()->broadcastMsg(msg); + vt::theMsg()->broadcastMsg(msg); } vt::finalize(); diff --git a/examples/hello_world/hello_world_virtual_context_remote.cc b/examples/hello_world/hello_world_virtual_context_remote.cc index 98a579aa64..69a1ce73b5 100644 --- a/examples/hello_world/hello_world_virtual_context_remote.cc +++ b/examples/hello_world/hello_world_virtual_context_remote.cc @@ -61,7 +61,7 @@ struct MyVC : vt::vrt::VirtualContext { } }; -static void testHan(TestMsg* msg, MyVC* vc) { +static void testHan(MyVC* vc, TestMsg* msg) { fmt::print("testHan: msg->from={}, my_data={}\n", msg->from, vc->my_data); } diff --git a/examples/hello_world/objgroup.cc b/examples/hello_world/objgroup.cc index a9d5620657..73b377000c 100644 --- a/examples/hello_world/objgroup.cc +++ b/examples/hello_world/objgroup.cc @@ -44,15 +44,10 @@ #include /// [Object group creation] -struct MyMsg : vt::Message { - MyMsg(int in_a, int in_b) : a(in_a), b(in_b) { } - int a = 0, b = 0; -}; - struct MyObjGroup { - void handler(MyMsg* msg) { + void handler(int a, int b) { auto node = vt::theContext()->getNode(); - fmt::print("{}: MyObjGroup::handler on a={}, b={}\n", node, msg->a, msg->b); + fmt::print("{}: MyObjGroup::handler on a={}, b={}\n", node, a, b); } }; @@ -67,11 +62,11 @@ int main(int argc, char** argv) { ); if (this_node == 0) { - proxy[0].send(5,10); + proxy[0].send<&MyObjGroup::handler>(5,10); if (num_nodes > 1) { - proxy[1].send(10,20); + proxy[1].send<&MyObjGroup::handler>(10,20); } - proxy.broadcast(400,500); + proxy.broadcast<&MyObjGroup::handler>(400,500); } vt::finalize(); diff --git a/examples/hello_world/param.cc b/examples/hello_world/param.cc deleted file mode 100644 index d9af0a2b10..0000000000 --- a/examples/hello_world/param.cc +++ /dev/null @@ -1,100 +0,0 @@ -/* -//@HEADER -// ***************************************************************************** -// -// param.cc -// DARMA/vt => Virtual Transport -// -// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC -// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. -// Government retains certain rights in this software. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Questions? Contact darma@sandia.gov -// -// ***************************************************************************** -//@HEADER -*/ - -#include - -#define VT_COMPILE_PARAM_EXAMPLE 0 - -#if VT_COMPILE_PARAM_EXAMPLE - -static void fnTest(int a, int b, bool x) { - fmt::print("fn: a={}, b={}, x={}\n", a, b, x ? "true" : "false"); -} - -static void fnTest2(int x, int y) { - fmt::print("fn2: x={},y={}\n",x,y); -} - -static void fnTest3(int x, double y) { - fmt::print("fn3: x={},y={}\n",x,y); -} - -struct FunctorTest1 { - void operator()(int x, double y) const { - fmt::print("FunctorTest1: x={},y={}\n",x,y); - } -}; - -#endif - -int main(int argc, char** argv) { - vt::initialize(argc, argv); - - vt::NodeType num_nodes = vt::theContext()->getNumNodes(); - - if (num_nodes == 1) { - return vt::rerror("requires at least 2 nodes"); - } - -#if VT_COMPILE_PARAM_EXAMPLE - vt::NodeType this_node = vt::theContext()->getNode(); - - if (this_node == 0) { - vt::theParam()->sendData(1, vt::buildData(10, 20, false), PARAM_FUNCTION_RHS(fnTest)); - vt::theParam()->sendData(1, PARAM_FUNCTION_RHS(fnTest), 50, 29, false); - vt::theParam()->sendData(1, vt::buildData(10, 20, false)); - vt::theParam()->sendData(1, 45, 23, true); - - vt::theParam()->sendData(1, 20, 10); - vt::theParam()->sendData(1, 20, 50.0); - - vt::theParam()->sendData(1, vt::buildData(20, 50.0)); - vt::theParam()->sendData(1, 20, 100.0); - vt::theParam()->sendData(1, vt::buildData(10, 70.0)); - } -#endif - - vt::finalize(); - - return 0; -} diff --git a/examples/hello_world/ring.cc b/examples/hello_world/ring.cc index b955c930f6..2488dbf24f 100644 --- a/examples/hello_world/ring.cc +++ b/examples/hello_world/ring.cc @@ -75,7 +75,7 @@ static void sendToNext() { vt::NodeType next_node = this_node + 1 >= num_nodes ? 0 : this_node + 1; auto msg = vt::makeMessage(this_node); - vt::theMsg()->sendMsg(next_node, msg); + vt::theMsg()->sendMsg(next_node, msg); } int main(int argc, char** argv) { diff --git a/examples/rdma/rdma_simple_get.cc b/examples/rdma/rdma_simple_get.cc index 6ae5587d49..79d92ceb07 100644 --- a/examples/rdma/rdma_simple_get.cc +++ b/examples/rdma/rdma_simple_get.cc @@ -112,7 +112,7 @@ int main(int argc, char** argv) { auto msg = vt::makeMessage(this_node); msg->han = my_handle; - vt::theMsg()->broadcastMsg(msg); + vt::theMsg()->broadcastMsg(msg); } vt::finalize(); diff --git a/examples/rdma/rdma_simple_get_direct.cc b/examples/rdma/rdma_simple_get_direct.cc index ae4a9e00e7..5a720caab6 100644 --- a/examples/rdma/rdma_simple_get_direct.cc +++ b/examples/rdma/rdma_simple_get_direct.cc @@ -87,7 +87,7 @@ int main(int argc, char** argv) { auto msg = vt::makeMessage(this_node); msg->han = my_handle; - vt::theMsg()->broadcastMsg(msg); + vt::theMsg()->broadcastMsg(msg); } vt::finalize(); diff --git a/examples/rdma/rdma_simple_put.cc b/examples/rdma/rdma_simple_put.cc index 854e3d11e5..b9f24bb036 100644 --- a/examples/rdma/rdma_simple_put.cc +++ b/examples/rdma/rdma_simple_put.cc @@ -88,7 +88,7 @@ static void put_data_fn(HandleMsg* msg) { fmt::print("{}: after put: sending msg back to 0\n", this_node); auto msg2 = vt::makeMessage(this_node); msg2->han = handle; - vt::theMsg()->sendMsg(0, msg2); + vt::theMsg()->sendMsg(0, msg2); } ); } @@ -144,7 +144,7 @@ int main(int argc, char** argv) { auto msg = vt::makeMessage(this_node); msg->han = my_handle; - vt::theMsg()->broadcastMsg(msg, false); + vt::theMsg()->broadcastMsg(msg, false); } vt::finalize(); diff --git a/examples/rdma/rdma_simple_put_direct.cc b/examples/rdma/rdma_simple_put_direct.cc index 7463b0a959..eba91a7c25 100644 --- a/examples/rdma/rdma_simple_put_direct.cc +++ b/examples/rdma/rdma_simple_put_direct.cc @@ -84,7 +84,7 @@ static void putDataFn(HandleMsg* msg) { ); auto back = vt::makeMessage(han); - vt::theMsg()->sendMsg(0, back); + vt::theMsg()->sendMsg(0, back); }); } } @@ -117,8 +117,8 @@ int main(int argc, char** argv) { auto msg1 = vt::makeMessage(my_handle); auto msg2 = vt::makeMessage(my_handle); - vt::theMsg()->sendMsg(1, msg1); - vt::theMsg()->sendMsg(2, msg2); + vt::theMsg()->sendMsg(1, msg1); + vt::theMsg()->sendMsg(2, msg2); } vt::finalize(); diff --git a/examples/termination/termination_collective.cc b/examples/termination/termination_collective.cc index 09ecfa6a4a..90f4ef68f1 100644 --- a/examples/termination/termination_collective.cc +++ b/examples/termination/termination_collective.cc @@ -63,7 +63,7 @@ static void test_handler(TestMsg* msg) { num--; if (num > 0) { auto msg_send = vt::makeMessage(); - vt::theMsg()->sendMsg(nextNode(), msg_send); + vt::theMsg()->sendMsg(nextNode(), msg_send); } } @@ -89,7 +89,7 @@ int main(int argc, char** argv) { { auto msg = vt::makeMessage(); vt::envelopeSetEpoch(msg->env, epoch); - vt::theMsg()->sendMsg(nextNode(), msg); + vt::theMsg()->sendMsg(nextNode(), msg); } vt::theTerm()->finishedEpoch(epoch); diff --git a/examples/termination/termination_rooted.cc b/examples/termination/termination_rooted.cc index 08c3977b2f..3eb2c752d0 100644 --- a/examples/termination/termination_rooted.cc +++ b/examples/termination/termination_rooted.cc @@ -63,7 +63,7 @@ static void test_handler(TestMsg* msg) { num--; if (num > 0) { auto msg_send = vt::makeMessage(); - vt::theMsg()->sendMsg(nextNode(), msg_send); + vt::theMsg()->sendMsg(nextNode(), msg_send); } } @@ -88,7 +88,7 @@ int main(int argc, char** argv) { auto msg = vt::makeMessage(); vt::envelopeSetEpoch(msg->env, epoch); - vt::theMsg()->sendMsg(nextNode(), msg); + vt::theMsg()->sendMsg(nextNode(), msg); vt::theTerm()->finishedEpoch(epoch); } diff --git a/scripts/JSON_data_files_validator.py b/scripts/JSON_data_files_validator.py index 8f81933559..436f17d14b 100644 --- a/scripts/JSON_data_files_validator.py +++ b/scripts/JSON_data_files_validator.py @@ -38,11 +38,22 @@ def get_error_message(iterable_collection: Iterable) -> str: def _get_valid_schema(self) -> Schema: """ Returns representation of a valid schema """ - allowed_types = ("LBDatafile", "LBStatsfile") + allowed_types_data = ("LBDatafile") valid_schema_data = Schema( { - 'type': And(str, lambda a: a in allowed_types, - error=f"{self.get_error_message(allowed_types)} must be chosen"), + Optional('type'): And(str, lambda a: a in allowed_types_data, + error=f"{self.get_error_message(allowed_types_data)} must be chosen"), + Optional('metadata'): { + Optional('type'): And(str, lambda a: a in allowed_types_data, + error=f"{self.get_error_message(allowed_types_data)} must be chosen"), + Optional('rank'): int, + Optional('shared_node'): { + 'id': int, + 'size': int, + 'rank': int, + 'num_nodes': int, + }, + }, 'phases': [ { 'id': int, @@ -98,10 +109,15 @@ def _get_valid_schema(self) -> Schema: ] } ) + allowed_types_stats = ("LBStatsfile") valid_schema_stats = Schema( { - 'type': And(str, lambda a: a in allowed_types, - error=f"{self.get_error_message(allowed_types)} must be chosen"), + Optional('type'): And(str, lambda a: a in allowed_types_stats, + error=f"{self.get_error_message(allowed_types_stats)} must be chosen"), + Optional('metadata'): { + Optional('type'): And(str, lambda a: a in allowed_types_stats, + error=f"{self.get_error_message(allowed_types_stats)} must be chosen"), + }, 'phases': [ { "id": int, @@ -417,7 +433,13 @@ def __validate_file(file_path): decompressed_dict = json.loads(compr_bytes.decode("utf-8")) # Extracting type from JSON data - schema_type = decompressed_dict.get("type") + schema_type = None + if decompressed_dict.get("metadata") is not None: + schema_type = decompressed_dict.get("metadata").get("type") + else: + if decompressed_dict.get("type") is not None: + schema_type = decompressed_dict.get("type") + if schema_type is not None: # Validate schema if SchemaValidator(schema_type=schema_type).is_valid(schema_to_validate=decompressed_dict): diff --git a/scripts/check_containers.sh b/scripts/check_containers.sh index dd56b273f0..87e89121b6 100755 --- a/scripts/check_containers.sh +++ b/scripts/check_containers.sh @@ -1,11 +1,14 @@ #!/usr/bin/env bash -# Check if there were any dockerfiles modified in the latest pull request. -# Note: this is specific to the way Azure checks out git repo. +# Check if there were any dockerfiles modified in the PR. +# Note: this is specific to Azure - in the pipeline's local branch git history +# contains one merge commit for all of the changes in the PR. diff_latest() { - git diff --name-only "$(git log --skip=1 -1 --merges --pretty=format:%H)".. + printf "Files modified in the pull request:\n" >&2 + git diff --name-only HEAD^1 HEAD | tee >(cat >&2) } +# Decide which docker-compose command to use: if diff_latest | grep -i dockerfile > /dev/null then echo "build --pull" diff --git a/scripts/workflow-azure-template.yml b/scripts/workflow-azure-template.yml index 66acb678d1..f7b7f3edc0 100644 --- a/scripts/workflow-azure-template.yml +++ b/scripts/workflow-azure-template.yml @@ -34,8 +34,6 @@ variables: VT_UNITY_BUILD: [% vt_unity_build %] VT_PRODUCTION_BUILD: [% vt_production_build %] VT_FCONTEXT: [% vt_fcontext %] - VT_USE_OPENMP: [% vt_use_openmp %] - VT_USE_STD_THREAD: [% vt_use_std_thread %] VT_ZOLTAN: [% vt_zoltan %] VT_CI_BUILD: [% vt_ci_build %] VT_DIAGNOSTICS: [% vt_diagnostics %] @@ -64,12 +62,8 @@ stages: [% workflow_runs_on %] timeoutInMinutes: 180 steps: - - task: Bash@3 - displayName: Job setup - inputs: - targetType: 'inline' - script: | - [% job_setup %] + - checkout: self + fetchDepth: 0 - task: Bash@3 displayName: Build timestamp for caching continueOnError: true diff --git a/scripts/workflows-azure.ini b/scripts/workflows-azure.ini index cf556adae8..661c4bbff8 100644 --- a/scripts/workflows-azure.ini +++ b/scripts/workflows-azure.ini @@ -14,8 +14,6 @@ vt_extended_tests = 1 vt_unity_build = 1 vt_production_build = 0 vt_fcontext = 0 -vt_use_openmp = 0 -vt_use_std_thread = 0 vt_zoltan = 0 vt_ci_build = 1 vt_tests_num_nodes = 2 @@ -39,11 +37,10 @@ build_root = $(ARCH)-[% linux %]-$(UBUNTU)-$(COMPILER)-cache linux_env = " UBUNTU: [% distro %]" vt_diagnostics = 1 pr_pattern = "pr:\\n drafts: false\\n autoCancel: true\\n branches:\\n include:\\n - '*'\\n" -job_setup = "echo setup" vt_no_color = 1 vt_build_shared_libs = 0 vt_inclusion = TPL -cmake_cxx_standard = 14 +cmake_cxx_standard = 17 [PR-tests-intel-oneAPI] test_configuration = "intel icpx, ubuntu, mpich" @@ -63,27 +60,27 @@ cache_name = ubuntu-intel-oneapi-icpc-cache output_name = ci/azure/azure-intel-oneapi-icpc-ubuntu-mpich.yml vt_extended_tests = 0 -[PR-tests-nvcc-10-1] -test_configuration = "nvidia cuda 10.1, ubuntu, mpich" +[PR-tests-nvcc-11-0] +test_configuration = "nvidia cuda 11.0, ubuntu, mpich" compiler_type = nvidia -compiler = nvcc-10 -distro = 18.04 -cache_name = ubuntu-nvidia-10-cache -output_name = ci/azure/azure-nvidia-10-ubuntu-mpich.yml +compiler = 11.0.3 +distro = 20.04 +cache_name = ubuntu-nvidia-11-cache +output_name = ci/azure/azure-nvidia-11-ubuntu-mpich.yml vt_extended_tests = 0 job_name = build_optional +vt_diagnostics = 0 vt_trace = 1 vt_pool = 0 -vt_diagnostics = 0 -vt_production_build = 1 +vt_tests_num_nodes = 4 -[PR-tests-nvcc-11-0] -test_configuration = "nvidia cuda 11.0, ubuntu, mpich" +[PR-tests-nvcc-11-2] +test_configuration = "nvidia cuda 11.2, ubuntu, mpich" compiler_type = nvidia -compiler = nvcc-11 -distro = 18.04 -cache_name = ubuntu-nvidia-11-cache -output_name = ci/azure/azure-nvidia-11-ubuntu-mpich.yml +compiler = 11.2.0 +distro = 20.04 +cache_name = ubuntu-nvidia-11.2-cache +output_name = ci/azure/azure-nvidia-11-2-ubuntu-mpich.yml vt_extended_tests = 0 job_name = build_optional vt_diagnostics = 0 @@ -98,6 +95,7 @@ compiler = gcc-7 distro = 18.04 vt_trace = 1 vt_trace_rt = 1 +vt_unity_build = 0 code_coverage = 1 docker_target = "[% linux %]-cpp-clean-noinstall" output_name = ci/azure/azure-gcc-7-ubuntu-mpich.yml @@ -110,8 +108,8 @@ distro = 18.04 vt_trace = 1 vt_pool = 0 vt_asan = 1 +vt_unity_build = 0 output_name = ci/azure/azure-gcc-8-ubuntu-mpich.yml -vt_use_std_thread = 1 lsan_options = suppressions=/vt/tests/lsan.supp [PR-tests-gcc-9] @@ -145,16 +143,6 @@ compiler = gcc-12 distro = 22.04 output_name = ci/azure/azure-gcc-12-ubuntu-mpich.yml pr_pattern = "pr:\\n drafts: true\\n autoCancel: true\\n branches:\\n include:\\n - '*'\\n" -cmake_cxx_standard = 17 - -[PR-tests-clang-5] -test_configuration = "clang-5.0, ubuntu, mpich" -compiler_type = clang -compiler = clang-5.0 -distro = 18.04 -output_name = ci/azure/azure-clang-5.0-ubuntu-mpich.yml -vt_trace = 1 -vt_use_openmp = 1 [PR-tests-clang-13-alpine] test_configuration = "clang-13, alpine, mpich" @@ -191,6 +179,7 @@ compiler_type = clang compiler = clang-11 distro = 22.04 output_name = ci/azure/azure-clang-11-ubuntu-mpich.yml +vt_fcontext = 1 [PR-tests-clang-12] test_configuration = "clang-12, ubuntu, mpich" @@ -205,7 +194,6 @@ compiler_type = clang compiler = clang-13 distro = 22.04 output_name = ci/azure/azure-clang-13-ubuntu-mpich.yml -cmake_cxx_standard = 17 [PR-tests-clang-14] test_configuration = "clang-14, ubuntu, mpich" @@ -213,3 +201,4 @@ compiler_type = clang compiler = clang-14 distro = 22.04 output_name = ci/azure/azure-clang-14-ubuntu-mpich.yml +vt_trace = 1 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 97351d778d..d9326cd274 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -19,8 +19,8 @@ set(TOP_LEVEL_SUBDIRS runnable activefn # Add single-directory components - context event handler parameterization sequence termination - scheduler worker standalone runtime trace timing demangle rdmahandle + context event handler sequence termination + scheduler standalone runtime trace timing demangle rdmahandle ) set( PROJECT_SUBDIRS_LIST @@ -98,7 +98,7 @@ set( serialization/messaging serialization/traits serialization/auto_dispatch serialization/sizing utils/demangle utils/container utils/bits utils/mutex utils/file_spec - utils/hash utils/atomic utils/tls utils/static_checks utils/string + utils/hash utils/atomic utils/static_checks utils/string utils/memory utils/mpi_limits utils/compress utils/json utils/strong registry/auto registry/auto/functor registry/auto/map registry/auto/collection @@ -340,3 +340,10 @@ export( FILE "vtTargets.cmake" NAMESPACE vt::runtime:: ) + +if (EXISTS "${PROJECT_LIB_DIR}/checkpoint") + install( + TARGETS checkpoint + EXPORT ${VIRTUAL_TRANSPORT_LIBRARY} + ) +endif() diff --git a/src/vt/collective/collective_ops.cc b/src/vt/collective/collective_ops.cc index d376da4337..b69d7d1122 100644 --- a/src/vt/collective/collective_ops.cc +++ b/src/vt/collective/collective_ops.cc @@ -46,7 +46,6 @@ #include "vt/runtime/runtime.h" #include "vt/scheduler/scheduler.h" #include "vt/runtime/runtime_inst.h" -#include "vt/utils/tls/tls.h" #include #include @@ -215,8 +214,8 @@ void printOverwrittens( template RuntimePtrType CollectiveAnyOps::initialize( - int& argc, char**& argv, WorkerCountType const num_workers, - bool is_interop, MPI_Comm* comm, arguments::AppConfig const* appConfig + int& argc, char**& argv, bool is_interop, MPI_Comm* comm, + arguments::AppConfig const* appConfig ) { using vt::runtime::RuntimeInst; using vt::runtime::Runtime; @@ -225,7 +224,7 @@ RuntimePtrType CollectiveAnyOps::initialize( MPI_Comm resolved_comm = comm not_eq nullptr ? *comm : MPI_COMM_WORLD; RuntimeInst::rt = std::make_unique( - argc, argv, num_workers, is_interop, resolved_comm, + argc, argv, is_interop, resolved_comm, eRuntimeInstance::DefaultInstance, appConfig ); @@ -254,9 +253,7 @@ void CollectiveAnyOps::setCurrentRuntimeTLS(RuntimeUnsafePtrType in) { } template -void CollectiveAnyOps::scheduleThenFinalize( - RuntimePtrType in_rt, WorkerCountType const workers -) { +void CollectiveAnyOps::scheduleThenFinalize(RuntimePtrType in_rt) { bool const has_rt = in_rt != nullptr; auto rt_use = has_rt ? in_rt.unsafe() : curRT; @@ -264,15 +261,7 @@ void CollectiveAnyOps::scheduleThenFinalize( theSched()->runSchedulerWhile([rt_use]{ return not rt_use->isTerminated(); }); }; - if (workers == no_workers) { - sched_fn(); - } else { - #if vt_threading_enabled - theWorkerGrp()->spawnWorkersBlock(sched_fn); - #else - sched_fn(); - #endif - } + sched_fn(); CollectiveAnyOps::finalize(has_rt ? std::move(in_rt) : nullptr); } diff --git a/src/vt/collective/collective_ops.h b/src/vt/collective/collective_ops.h index 2a9d17dc5f..3b36e8a29f 100644 --- a/src/vt/collective/collective_ops.h +++ b/src/vt/collective/collective_ops.h @@ -61,14 +61,19 @@ template struct CollectiveAnyOps { // The general methods that interact with the managed runtime holder static RuntimePtrType initialize( - int& argc, char**& argv, WorkerCountType const num_workers = no_workers, - bool is_interop = false, MPI_Comm* comm = nullptr, + int& argc, char**& argv, bool is_interop = false, MPI_Comm* comm = nullptr, arguments::AppConfig const* appConfig = nullptr ); + [[deprecated]] static RuntimePtrType initialize( + int& argc, char**& argv, PhysicalResourceType const /* num_workers */, + bool is_interop = false, MPI_Comm* comm = nullptr, + arguments::AppConfig const* appConfig = nullptr + ) + { + return initialize(argc, argv, is_interop, comm, appConfig); + } static void finalize(RuntimePtrType in_rt = nullptr); - static void scheduleThenFinalize( - RuntimePtrType in_rt = nullptr, WorkerCountType const workers = no_workers - ); + static void scheduleThenFinalize(RuntimePtrType in_rt = nullptr); static void setCurrentRuntimeTLS(RuntimeUnsafePtrType in_rt = nullptr); static void abort(std::string const str = "", ErrorCodeType const code = 0); static void output( diff --git a/src/vt/collective/reduce/reduce.h b/src/vt/collective/reduce/reduce.h index 55b5d30083..71a3809827 100644 --- a/src/vt/collective/reduce/reduce.h +++ b/src/vt/collective/reduce/reduce.h @@ -58,6 +58,7 @@ #include "vt/collective/tree/tree.h" #include "vt/utils/hash/hash_tuple.h" #include "vt/messaging/pending_send.h" +#include "vt/utils/fntraits/fntraits.h" #include #include @@ -146,6 +147,27 @@ struct Reduce : virtual collective::tree::Tree { ReduceNumType num_contrib = 1 ); + /** + * \brief Reduce a message up the tree, possibly delayed through a pending send + * + * \param[in] root the root node where the final handler provides the result + * \param[in] msg the message to reduce on this node + * \param[in] id the reduction stamp (optional), provided if out-of-order + * \param[in] num_contrib number of expected contributions from this node + * + * \return the pending send corresponding to the reduce + */ + template + PendingSendType reduce( + NodeType root, + typename FuncTraits::MsgT* const msg, + detail::ReduceStamp id = detail::ReduceStamp{}, + ReduceNumType num_contrib = 1 + ) { + using MsgT = typename FuncTraits::MsgT; + return reduce(root, msg, id, num_contrib); + } + /** * \brief Reduce a message up the tree * @@ -163,6 +185,27 @@ struct Reduce : virtual collective::tree::Tree { ReduceNumType num_contrib = 1 ); + /** + * \brief Reduce a message up the tree + * + * \param[in] root the root node where the final handler provides the result + * \param[in] msg the message to reduce on this node + * \param[in] id the reduction stamp (optional), provided if out-of-order + * \param[in] num_contrib number of expected contributions from this node + * + * \return the next reduction stamp + */ + template + detail::ReduceStamp reduceImmediate( + NodeType root, + typename FuncTraits::MsgT* const msg, + detail::ReduceStamp id = detail::ReduceStamp{}, + ReduceNumType num_contrib = 1 + ) { + using MsgT = typename FuncTraits::MsgT; + return reduceImmediate(root, msg, id, num_contrib); + } + /** * \brief Reduce a message up the tree * @@ -205,6 +248,29 @@ struct Reduce : virtual collective::tree::Tree { >(root, msg, cb, id, num_contrib); } + /** + * \brief Reduce a message up the tree + * + * \param[in] root the root node where the final handler provides the result + * \param[in] msg the message to reduce on this node + * \param[in] cb the callback to trigger on the root node + * \param[in] id the reduction stamp (optional), provided if out-of-order + * \param[in] num_contrib number of expected contributions from this node + * + * \return the next reduction stamp + */ + template + PendingSendType reduce( + NodeType const& root, + typename FuncTraits::MsgT* msg, + Callback::MsgT> cb, + detail::ReduceStamp id = detail::ReduceStamp{}, + ReduceNumType const& num_contrib = 1 + ) { + using MsgT = typename FuncTraits::MsgT; + return reduce(root, msg, cb, id, num_contrib); + } + /** * \brief Reduce a message up the tree * @@ -247,6 +313,29 @@ struct Reduce : virtual collective::tree::Tree { >(root, msg, cb, id, num_contrib); } + /** + * \brief Reduce a message up the tree + * + * \param[in] root the root node where the final handler provides the result + * \param[in] msg the message to reduce on this node + * \param[in] cb the callback to trigger on the root node + * \param[in] id the reduction stamp (optional), provided if out-of-order + * \param[in] num_contrib number of expected contributions from this node + * + * \return the next reduction stamp + */ + template + detail::ReduceStamp reduceImmediate( + NodeType const& root, + typename FuncTraits::MsgT* msg, + Callback::MsgT> cb, + detail::ReduceStamp id = detail::ReduceStamp{}, + ReduceNumType const& num_contrib = 1 + ) { + using MsgT = typename FuncTraits::MsgT; + return reduceImmediate(root, msg, cb, id, num_contrib); + } + /** * \brief Reduce a message up the tree with a target function on the root node * @@ -287,6 +376,31 @@ struct Reduce : virtual collective::tree::Tree { >(root, msg, id, num_contrib); } + /** + * \brief Reduce a message up the tree with a target function on the root node + * + * \param[in] root the root node where the final handler provides the result + * \param[in] msg the message to reduce on this node + * \param[in] id the reduction stamp (optional), provided if out-of-order + * \param[in] num_contrib number of expected contributions from this node + * + * \return the next reduction stamp + */ + template < + typename OpT, + typename FunctorT, + auto f + > + PendingSendType reduce( + NodeType const& root, + typename FuncTraits::MsgT* msg, + detail::ReduceStamp id = detail::ReduceStamp{}, + ReduceNumType const& num_contrib = 1 + ) { + using MsgT = typename FuncTraits::MsgT; + return reduce(root, msg, id, num_contrib); + } + /** * \brief Reduce a message up the tree with a target function on the root node * @@ -327,6 +441,31 @@ struct Reduce : virtual collective::tree::Tree { >(root, msg, id, num_contrib); } + /** + * \brief Reduce a message up the tree with a target function on the root node + * + * \param[in] root the root node where the final handler provides the result + * \param[in] msg the message to reduce on this node + * \param[in] id the reduction stamp (optional), provided if out-of-order + * \param[in] num_contrib number of expected contributions from this node + * + * \return the next reduction stamp + */ + template < + typename OpT, + typename FunctorT, + auto f + > + detail::ReduceStamp reduceImmediate( + NodeType const& root, + typename FuncTraits::MsgT* msg, + detail::ReduceStamp id = detail::ReduceStamp{}, + ReduceNumType const& num_contrib = 1 + ) { + using MsgT = typename FuncTraits::MsgT; + return reduceImmediate(root, msg, id, num_contrib); + } + /** * \internal \brief Combine in a new message for a given reduction * diff --git a/src/vt/collective/reduce/reduce.impl.h b/src/vt/collective/reduce/reduce.impl.h index 0a2724d38d..ccd37b57c4 100644 --- a/src/vt/collective/reduce/reduce.impl.h +++ b/src/vt/collective/reduce/reduce.impl.h @@ -128,7 +128,7 @@ Reduce::PendingSendType Reduce::reduce( ) { auto msg_ptr = promoteMsg(msg); return PendingSendType{theMsg()->getEpochContextMsg(msg_ptr), [=](){ - reduceImmediate(root, msg_ptr.get(), id, num_contrib); + reduceImmediate(root, msg_ptr.get(), id, num_contrib); } }; } @@ -282,7 +282,7 @@ void Reduce::startReduce(detail::ReduceStamp id, bool use_num_contrib) { scope_.str(), detail::stringizeStamp(id), root, this_node ); - theMsg()->sendMsg>(root, typed_msg); + theMsg()->sendMsg>(root, typed_msg); } else { vt_debug_print( normal, reduce, @@ -300,7 +300,7 @@ void Reduce::startReduce(detail::ReduceStamp id, bool use_num_contrib) { scope_.str(), detail::stringizeStamp(id), parent ); - theMsg()->sendMsg>(parent, typed_msg); + theMsg()->sendMsg>(parent, typed_msg); } } } diff --git a/src/vt/collective/scatter/scatter.cc b/src/vt/collective/scatter/scatter.cc index 370672f88a..1d9ee9dde0 100644 --- a/src/vt/collective/scatter/scatter.cc +++ b/src/vt/collective/scatter/scatter.cc @@ -112,7 +112,7 @@ void Scatter::scatterIn(ScatterMsg* msg) { ); std::memcpy(ptr, in_ptr, child_bytes_size); in_ptr += child_bytes_size; - theMsg()->sendMsg( + theMsg()->sendMsg( child, child_msg ); }); diff --git a/src/vt/collective/scatter/scatter.h b/src/vt/collective/scatter/scatter.h index a15d59c3ca..291527211b 100644 --- a/src/vt/collective/scatter/scatter.h +++ b/src/vt/collective/scatter/scatter.h @@ -49,6 +49,7 @@ #include "vt/activefn/activefn.h" #include "vt/messaging/message.h" #include "vt/collective/tree/tree.h" +#include "vt/utils/fntraits/fntraits.h" #include #include @@ -89,6 +90,26 @@ struct Scatter : virtual collective::tree::Tree { FuncSizeType size_fn, FuncDataType data_fn ); + /** + * \brief Scatter data to all nodes + * + * The functions passed to scatter through the arguments \c size_fn and + * \c data_fn will not be retained after this call returns. + * + * \param[in] total_size total size of data to scatter + * \param[in] max_proc_size max data to be scattered to any node + * \param[in] size_fn callback to get size for each node + * \param[in] data_fn callback to get data for each node + */ + template + void scatter( + std::size_t const& total_size, std::size_t const& max_proc_size, + FuncSizeType size_fn, FuncDataType data_fn + ) { + using MsgT = std::remove_pointer_t::Arg1>; + return scatter(total_size, max_proc_size, size_fn, data_fn); + } + protected: /** * \internal \brief Receive scattered data down the spanning tree diff --git a/src/vt/collective/scatter/scatter.impl.h b/src/vt/collective/scatter/scatter.impl.h index 0e757b67fb..8423d08177 100644 --- a/src/vt/collective/scatter/scatter.impl.h +++ b/src/vt/collective/scatter/scatter.impl.h @@ -93,7 +93,7 @@ void Scatter::scatter( auto const& this_node = theContext()->getNode(); scatter_msg->user_han = handler; if (this_node != root_node) { - theMsg()->sendMsg( + theMsg()->sendMsg( root_node, scatter_msg ); } else { diff --git a/src/vt/collective/startup.cc b/src/vt/collective/startup.cc index 1c01d3d56d..6ad271c485 100644 --- a/src/vt/collective/startup.cc +++ b/src/vt/collective/startup.cc @@ -50,21 +50,12 @@ namespace vt { // vt::{initialize,finalize} for main ::vt namespace -RuntimePtrType initialize( - int& argc, char**& argv, WorkerCountType const num_workers, - bool is_interop, MPI_Comm* comm, arguments::AppConfig const* appConfig -) { - return CollectiveOps::initialize( - argc, argv, num_workers, is_interop, comm, appConfig - ); -} - RuntimePtrType initialize( int& argc, char**& argv, MPI_Comm* comm, arguments::AppConfig const* appConfig ) { bool const is_interop = comm != nullptr; return CollectiveOps::initialize( - argc, argv, no_workers, is_interop, comm, appConfig + argc, argv, is_interop, comm, appConfig ); } @@ -72,7 +63,7 @@ RuntimePtrType initialize(MPI_Comm* comm) { int argc = 0; char** argv = nullptr; bool const is_interop = comm != nullptr; - return CollectiveOps::initialize(argc,argv,no_workers,is_interop,comm); + return CollectiveOps::initialize(argc,argv,is_interop,comm); } RuntimePtrType initialize( diff --git a/src/vt/collective/startup.h b/src/vt/collective/startup.h index 2f50850c0c..bd70071384 100644 --- a/src/vt/collective/startup.h +++ b/src/vt/collective/startup.h @@ -49,11 +49,6 @@ namespace vt { -RuntimePtrType initialize( - int& argc, char**& argv, WorkerCountType const num_workers, - bool is_interop = false, MPI_Comm* comm = nullptr, - arguments::AppConfig const* appConfig = nullptr -); RuntimePtrType initialize( int& argc, char**& argv, MPI_Comm* comm = nullptr, arguments::AppConfig const* appConfig = nullptr diff --git a/src/vt/configs/arguments/app_config.h b/src/vt/configs/arguments/app_config.h index 00224cbfe8..6a7f961b88 100644 --- a/src/vt/configs/arguments/app_config.h +++ b/src/vt/configs/arguments/app_config.h @@ -145,6 +145,7 @@ struct AppConfig { bool vt_lb_keep_last_elm = false; bool vt_lb_data = false; bool vt_lb_data_compress = true; + bool vt_lb_data_in = false; std::string vt_lb_data_dir = "vt_lb_data"; std::string vt_lb_data_file = "data.%p.json"; std::string vt_lb_data_dir_in = "vt_lb_data_in"; @@ -319,6 +320,7 @@ struct AppConfig { | vt_lb_data_compress | vt_lb_data_dir | vt_lb_data_file + | vt_lb_data_in | vt_lb_data_dir_in | vt_lb_data_file_in | vt_lb_statistics diff --git a/src/vt/configs/arguments/args.cc b/src/vt/configs/arguments/args.cc index bc5d1e5825..0e8d8f0186 100644 --- a/src/vt/configs/arguments/args.cc +++ b/src/vt/configs/arguments/args.cc @@ -356,7 +356,6 @@ void addDebugPrintArgs(CLI::App& app, AppConfig& appConfig) { auto lap = "Enable debug_rdma = \"" debug_pp(rdma) "\""; auto map = "Enable debug_rdma_channel = \"" debug_pp(rdma_channel) "\""; auto nap = "Enable debug_rdma_state = \"" debug_pp(rdma_state) "\""; - auto oap = "Enable debug_param = \"" debug_pp(param) "\""; auto pap = "Enable debug_handler = \"" debug_pp(handler) "\""; auto qap = "Enable debug_hierlb = \"" debug_pp(hierlb) "\""; auto qbp = "Enable debug_temperedlb = \"" debug_pp(temperedlb) "\""; @@ -393,7 +392,6 @@ void addDebugPrintArgs(CLI::App& app, AppConfig& appConfig) { auto la = app.add_flag("--vt_debug_rdma", appConfig.vt_debug_rdma, lap); auto ma = app.add_flag("--vt_debug_rdma_channel", appConfig.vt_debug_rdma_channel, map); auto na = app.add_flag("--vt_debug_rdma_state", appConfig.vt_debug_rdma_state, nap); - auto oa = app.add_flag("--vt_debug_param", appConfig.vt_debug_param, oap); auto pa = app.add_flag("--vt_debug_handler", appConfig.vt_debug_handler, pap); auto qa = app.add_flag("--vt_debug_hierlb", appConfig.vt_debug_hierlb, qap); auto qb = app.add_flag("--vt_debug_temperedlb", appConfig.vt_debug_temperedlb, qbp); @@ -430,7 +428,6 @@ void addDebugPrintArgs(CLI::App& app, AppConfig& appConfig) { la->group(debugGroup); ma->group(debugGroup); na->group(debugGroup); - oa->group(debugGroup); pa->group(debugGroup); qa->group(debugGroup); qb->group(debugGroup); @@ -468,6 +465,7 @@ void addLbArgs(CLI::App& app, AppConfig& appConfig) { auto lb_interval = "Load balancing interval"; auto lb_keep_last_elm = "Do not migrate last element in collection"; auto lb_data = "Enable load balancing data"; + auto lb_data_in = "Enable load balancing data input"; auto lb_data_comp = "Compress load balancing data output with brotli"; auto lb_data_dir = "Load balancing data output directory"; auto lb_data_file = "Load balancing data output file name"; @@ -489,6 +487,7 @@ void addLbArgs(CLI::App& app, AppConfig& appConfig) { auto w = app.add_option("--vt_lb_interval", appConfig.vt_lb_interval, lb_interval)->capture_default_str(); auto wl = app.add_flag("--vt_lb_keep_last_elm", appConfig.vt_lb_keep_last_elm, lb_keep_last_elm); auto ww = app.add_flag("--vt_lb_data", appConfig.vt_lb_data, lb_data); + auto za = app.add_flag("--vt_lb_data_in", appConfig.vt_lb_data_in, lb_data_in); auto xz = app.add_flag("--vt_lb_data_compress", appConfig.vt_lb_data_compress, lb_data_comp); auto wx = app.add_option("--vt_lb_data_dir", appConfig.vt_lb_data_dir, lb_data_dir)->capture_default_str(); auto wy = app.add_option("--vt_lb_data_file", appConfig.vt_lb_data_file, lb_data_file)->capture_default_str(); @@ -502,6 +501,10 @@ void addLbArgs(CLI::App& app, AppConfig& appConfig) { auto lbspec = app.add_flag("--vt_lb_spec", appConfig.vt_lb_spec, lb_spec); auto lbspecfile = app.add_option("--vt_lb_spec_file", appConfig.vt_lb_spec_file, lb_spec_file)->capture_default_str()->check(CLI::ExistingFile); + // --vt_lb_name excludes --vt_lb_file_name, and vice versa + v->excludes(u); + u->excludes(v); + auto debugLB = "Load Balancing"; s->group(debugLB); t1->group(debugLB); @@ -513,6 +516,7 @@ void addLbArgs(CLI::App& app, AppConfig& appConfig) { wl->group(debugLB); ww->group(debugLB); wx->group(debugLB); + za->group(debugLB); wy->group(debugLB); xx->group(debugLB); xy->group(debugLB); diff --git a/src/vt/configs/debug/debug_config.h b/src/vt/configs/debug/debug_config.h index e9edddcd06..999586b1fc 100644 --- a/src/vt/configs/debug/debug_config.h +++ b/src/vt/configs/debug/debug_config.h @@ -63,25 +63,24 @@ enum CatEnum : uint64_t { rdma = 1ull<<11, rdma_channel = 1ull<<12, rdma_state = 1ull<<13, - param = 1ull<<14, - handler = 1ull<<15, - hierlb = 1ull<<16, - scatter = 1ull<<17, - serial_msg = 1ull<<18, - trace = 1ull<<19, - location = 1ull<<20, - lb = 1ull<<21, - vrt = 1ull<<22, - vrt_coll = 1ull<<23, - worker = 1ull<<24, - group = 1ull<<25, - broadcast = 1ull<<26, - objgroup = 1ull<<27, - temperedlb = 1ull<<28, - phase = 1ull<<29, - context = 1ull<<30, - epoch = 1ull<<31, - temperedwmin = 1ull<<32 + handler = 1ull<<14, + hierlb = 1ull<<15, + scatter = 1ull<<16, + serial_msg = 1ull<<17, + trace = 1ull<<18, + location = 1ull<<19, + lb = 1ull<<20, + vrt = 1ull<<21, + vrt_coll = 1ull<<22, + worker = 1ull<<23, + group = 1ull<<24, + broadcast = 1ull<<25, + objgroup = 1ull<<26, + temperedlb = 1ull<<27, + phase = 1ull<<28, + context = 1ull<<29, + epoch = 1ull<<30, + temperedwmin = 1ull<<31 }; enum CtxEnum : uint64_t { @@ -132,7 +131,6 @@ vt_option_category_pretty_print(temperedwmin, "TemperedWMin") vt_option_category_pretty_print(lb, "lb") vt_option_category_pretty_print(location, "location") vt_option_category_pretty_print(objgroup, "objgroup") -vt_option_category_pretty_print(param, "parameterization") vt_option_category_pretty_print(phase, "phase") vt_option_category_pretty_print(pipe, "pipe") vt_option_category_pretty_print(pool, "pool") diff --git a/src/vt/configs/debug/debug_masterconfig.h b/src/vt/configs/debug/debug_masterconfig.h index 716c0264a4..fe6cd1d75e 100644 --- a/src/vt/configs/debug/debug_masterconfig.h +++ b/src/vt/configs/debug/debug_masterconfig.h @@ -78,12 +78,4 @@ using VTPrintConfig = Configuration< }} /* end namespace vt::config */ -#define backend_no_threading \ - !vt_check_enabled(openmp) && !vt_check_enabled(stdthread) - -#define vt_threading_enabled \ - (vt_check_enabled(openmp) \ - or vt_check_enabled(stdthread) \ - or vt_check_enabled(fcontext)) - #endif /*INCLUDED_VT_CONFIGS_DEBUG_DEBUG_MASTERCONFIG_H*/ diff --git a/src/vt/configs/features/features_defines.h b/src/vt/configs/features/features_defines.h index ab782a6b49..86e40db65d 100644 --- a/src/vt/configs/features/features_defines.h +++ b/src/vt/configs/features/features_defines.h @@ -56,9 +56,7 @@ #define vt_feature_trace_enabled 0 || vt_feature_cmake_trace_enabled #define vt_feature_trace_only 0 || vt_feature_cmake_trace_only #define vt_feature_lblite 0 || vt_feature_cmake_lblite -#define vt_feature_openmp 0 || vt_feature_cmake_openmp #define vt_feature_production 0 || vt_feature_cmake_production -#define vt_feature_stdthread 0 || vt_feature_cmake_stdthread #define vt_feature_mpi_rdma 0 || vt_feature_cmake_mpi_rdma #define vt_feature_print_term_msgs 0 || vt_feature_cmake_print_term_msgs #define vt_feature_no_pool_alloc_env 0 || vt_feature_cmake_no_pool_alloc_env diff --git a/src/vt/configs/features/features_featureswitch.h b/src/vt/configs/features/features_featureswitch.h index 7cd43ff34b..53841cdb4c 100644 --- a/src/vt/configs/features/features_featureswitch.h +++ b/src/vt/configs/features/features_featureswitch.h @@ -58,12 +58,10 @@ #define vt_feature_str_mpi_rdma "Native RDMA with MPI" #define vt_feature_str_no_feature "No feature" #define vt_feature_str_no_pool_alloc_env "No memory pool envelope" -#define vt_feature_str_openmp "OpenMP Threading" #define vt_feature_str_print_term_msgs "Print Termination Control Messages" #define vt_feature_str_priorities "Message priorities" #define vt_feature_str_production_build "Production Build (assertions and " \ "debug prints disabled)" -#define vt_feature_str_stdthread "std::thread Threading" #define vt_feature_str_trace_enabled "Tracing Projections" #define vt_feature_str_zoltan "Zoltan for load balancing" diff --git a/src/vt/configs/types/types_sentinels.h b/src/vt/configs/types/types_sentinels.h index 62d942f8dd..cc2235a17a 100644 --- a/src/vt/configs/types/types_sentinels.h +++ b/src/vt/configs/types/types_sentinels.h @@ -49,12 +49,10 @@ namespace vt { -// Physical identifier sentinel values (nodes, cores, workers, etc.) +// Physical identifier sentinel values (nodes etc.) static constexpr NodeType const uninitialized_destination = static_cast(0xFFFF); -static constexpr WorkerCountType const no_workers = static_cast(0xFFFF); -static constexpr WorkerIDType const no_worker_id = static_cast(0xFFFE); -static constexpr WorkerIDType const worker_id_comm_thread = static_cast(0xFEED); -static constexpr WorkerIDType const comm_debug_print = static_cast(-1); + +static constexpr PhysicalResourceType const no_workers [[deprecated]] = static_cast(0xFFFF); // Runtime default `empty' sentinel value static constexpr uint64_t const u64empty = 0xFFFFFFFFFFFFFFFF; diff --git a/src/vt/configs/types/types_type.h b/src/vt/configs/types/types_type.h index 0397318e5a..6b7809311e 100644 --- a/src/vt/configs/types/types_type.h +++ b/src/vt/configs/types/types_type.h @@ -57,10 +57,6 @@ using PhysicalResourceType = int16_t; using NodeType = PhysicalResourceType; /// Used to hold a core ID using CoreType = PhysicalResourceType; -/// Used to hold the number of workers on a node -using WorkerCountType = PhysicalResourceType; -/// Used to hold the ID of a worker on a node -using WorkerIDType = PhysicalResourceType; // Runtime system entity types /// Used to hold a handler ID which identifier a function pointer/context diff --git a/src/vt/context/context.cc b/src/vt/context/context.cc index 5215863db1..7c559883b8 100644 --- a/src/vt/context/context.cc +++ b/src/vt/context/context.cc @@ -90,20 +90,12 @@ Context::Context(bool const is_interop, MPI_Comm comm) { communicator_ = comm; numNodes_ = static_cast(numNodesLocal); thisNode_ = static_cast(thisNodeLocal); - - setDefaultWorker(); } Context::~Context() { MPI_Comm_free(&communicator_); } -void Context::setDefaultWorker() { - setWorker(worker_id_comm_thread); -} - -DeclareClassOutsideInitTLS(Context, WorkerIDType, thisWorker_, no_worker_id) - void Context::setTask(runnable::RunnableNew* in_task) { cur_task_ = in_task; } diff --git a/src/vt/context/context.h b/src/vt/context/context.h index 4955997e04..c391ee0305 100644 --- a/src/vt/context/context.h +++ b/src/vt/context/context.h @@ -50,7 +50,6 @@ #include "vt/config.h" #include "vt/runtime/component/component_pack.h" #include "vt/context/context_attorney_fwd.h" -#include "vt/utils/tls/tls.h" #if vt_check_enabled(trace_only) namespace vt { namespace runnable { @@ -120,35 +119,6 @@ struct Context : runtime::component::Component { */ inline MPI_Comm getComm() const { return communicator_; } - /** - * \brief Relevant only in threaded mode (e.g., \c std::thread, or OpenMP - * threads), gets the number of worker threads being used on a given node - * - * \see \c vt::WorkerCountType - * - * \return the number of worker threads - */ - inline WorkerCountType getNumWorkers() const { return numWorkers_; } - - /** - * \brief Informs whether VT is running threaded mode - * - * \return whether the VT runtime has workers enabled on a given node - */ - inline bool hasWorkers() const { return numWorkers_ != no_workers; } - - /** - * \brief Relevant only in threaded mode (e.g., \c std::thread, or OpenMP - * threads), gets the current worker thread being used to execute a handler - * - * \see \c vt::WorkerIDType - * - * \return whether the worker thread ID being used, sequentially numbered - */ - inline WorkerIDType getWorker() const { - return AccessClassTLS(Context, thisWorker_); - } - /// Used to manage protected access for other VT runtime components friend struct ContextAttorney; @@ -158,7 +128,6 @@ struct Context : runtime::component::Component { void serialize(SerializerT& s) { s | thisNode_ | numNodes_ - | numWorkers_ | communicator_; } @@ -204,25 +173,10 @@ struct Context : runtime::component::Component { */ void setTask(runnable::RunnableNew* in_task); - /// Set the number of workers through the attorney (internal) - void setNumWorkers(WorkerCountType const worker_count) { - numWorkers_ = worker_count; - } - /// Set the worker through the attorney (internal) - void setWorker(WorkerIDType const worker) { - AccessClassTLS(Context, thisWorker_) = worker; - } - -private: - /// Set the default worker that runs in threaded mode - void setDefaultWorker(); - private: NodeType thisNode_ = uninitialized_destination; NodeType numNodes_ = uninitialized_destination; - WorkerCountType numWorkers_ = no_workers; MPI_Comm communicator_ = MPI_COMM_NULL; - DeclareClassInsideInitTLS(Context, WorkerIDType, thisWorker_, no_worker_id) runnable::RunnableNew* cur_task_ = nullptr; }; diff --git a/src/vt/context/context_attorney.cc b/src/vt/context/context_attorney.cc index 78024ee136..0098c01587 100644 --- a/src/vt/context/context_attorney.cc +++ b/src/vt/context/context_attorney.cc @@ -44,18 +44,9 @@ #include "vt/config.h" #include "vt/context/context.h" #include "vt/context/context_attorney.h" -#include "vt/worker/worker_common.h" namespace vt { namespace ctx { -/*static*/ void ContextAttorney::setWorker(WorkerIDType const worker) { - theContext()->setWorker(worker); -} - -/*static*/ void ContextAttorney::setNumWorkers(WorkerCountType const nworkers) { - theContext()->setNumWorkers(nworkers); -} - /*static*/ void ContextAttorney::setTask(runnable::RunnableNew* in_task) { theContext()->setTask(in_task); } diff --git a/src/vt/context/context_attorney.h b/src/vt/context/context_attorney.h index dbd01acc71..8a41b7a179 100644 --- a/src/vt/context/context_attorney.h +++ b/src/vt/context/context_attorney.h @@ -46,7 +46,6 @@ #include "vt/config.h" #include "vt/context/context_attorney_fwd.h" -#include "vt/worker/worker_headers.h" #include "vt/runtime/runtime_headers.h" #include "vt/runnable/runnable.fwd.h" #include "vt/context/runnable_context/set_context.fwd.h" @@ -60,27 +59,14 @@ namespace vt { namespace ctx { * * \brief Used by VT internals for write access to the Context * - * Attorney pattern to Context for setting number of workers and current worker + * Attorney pattern to Context for setting the running task * by the runtime and other components */ struct ContextAttorney { - #if vt_threading_enabled - /// Allow the worker to modify the contextual worker - friend worker::WorkerGroupType; - /// Allow the worker group to modify the contextual worker - friend worker::WorkerType; - #endif - /// Allow the runtime to set the number of workers - friend runtime::Runtime; - /// Allow \c ctx::SetContext to modify the running task friend ctx::SetContext; private: - /// Allow internal runtime to set the worker - static void setWorker(WorkerIDType const worker); - /// Allow internal runtime to set the number of workers - static void setNumWorkers(WorkerCountType const worker_count); /// Allow setting the current running task static void setTask(runnable::RunnableNew* in_task); }; diff --git a/src/vt/context/runnable_context/collection.cc b/src/vt/context/runnable_context/collection.cc index 41ebb250ff..666ef0cb7e 100644 --- a/src/vt/context/runnable_context/collection.cc +++ b/src/vt/context/runnable_context/collection.cc @@ -46,7 +46,7 @@ namespace vt { namespace ctx { void Collection::start() { - set_(); + set_(elm_); } void Collection::finish() { diff --git a/src/vt/context/runnable_context/collection.h b/src/vt/context/runnable_context/collection.h index a31246d95d..8b1abd67ae 100644 --- a/src/vt/context/runnable_context/collection.h +++ b/src/vt/context/runnable_context/collection.h @@ -87,8 +87,9 @@ struct Collection { void resume(); private: - std::function set_; /**< Set context function */ - std::function clear_; /**< Clear context function */ + std::function set_; /**< Set context function */ + std::function clear_; /**< Clear context function */ + void* elm_ = nullptr; /**< The element (untyped) */ }; }} /* end namespace vt::ctx */ diff --git a/src/vt/context/runnable_context/collection.impl.h b/src/vt/context/runnable_context/collection.impl.h index 9a22c23bc4..403cc960f8 100644 --- a/src/vt/context/runnable_context/collection.impl.h +++ b/src/vt/context/runnable_context/collection.impl.h @@ -54,9 +54,11 @@ template /*explicit*/ Collection::Collection( vrt::collection::Indexable* elm ) { - auto idx_ = elm->getIndex(); - auto proxy_ = elm->getProxy(); - set_ = [=]{ + elm_ = elm; + set_ = [](void* in_elm){ + auto e = static_cast*>(in_elm); + auto& idx_ = e->getIndex(); + auto proxy_ = e->getProxy(); vrt::collection::CollectionContextHolder::set(&idx_, proxy_); }; clear_ = []{ diff --git a/src/vt/context/runnable_context/lb_data.cc b/src/vt/context/runnable_context/lb_data.cc index 917f239291..bb0d57105e 100644 --- a/src/vt/context/runnable_context/lb_data.cc +++ b/src/vt/context/runnable_context/lb_data.cc @@ -46,30 +46,32 @@ namespace vt { namespace ctx { -void LBData::start() { +void LBData::start(TimeType time) { // record start time if (should_instrument_) { - lb_data_->startTime(); + lb_data_->start(time); } } -void LBData::finish() { +void LBData::finish(TimeType time) { // record end time if (should_instrument_) { - lb_data_->stopTime(); + lb_data_->stop(time); } } void LBData::send(elm::ElementIDStruct dest, MsgSizeType bytes) { - lb_data_->sendToEntity(dest, cur_elm_id_, bytes); + if (should_instrument_) { + lb_data_->sendToEntity(dest, cur_elm_id_, bytes); + } } -void LBData::suspend() { - finish(); +void LBData::suspend(TimeType time) { + finish(time); } -void LBData::resume() { - start(); +void LBData::resume(TimeType time) { + start(time); } typename LBData::ElementIDStruct const& LBData::getCurrentElementID() const { diff --git a/src/vt/context/runnable_context/lb_data.h b/src/vt/context/runnable_context/lb_data.h index 89dc703025..f211a90839 100644 --- a/src/vt/context/runnable_context/lb_data.h +++ b/src/vt/context/runnable_context/lb_data.h @@ -81,15 +81,20 @@ struct LBData { should_instrument_(true) { } + /** + * \brief Return whether time is required + */ + bool needsTime() const { return should_instrument_; } + /** * \brief Set the context and timing for a collection task */ - void start(); + void start(TimeType time); /** * \brief Remove the context and store timing for a collection task */ - void finish(); + void finish(TimeType time); /** * \brief Record LB data whenever a message is sent and a collection @@ -100,8 +105,8 @@ struct LBData { */ void send(elm::ElementIDStruct dest, MsgSizeType bytes); - void suspend(); - void resume(); + void suspend(TimeType time); + void resume(TimeType time); /** * \brief Get the current element ID struct for the running context diff --git a/src/vt/context/runnable_context/trace.cc b/src/vt/context/runnable_context/trace.cc index 921d6cb43a..bb955a8212 100644 --- a/src/vt/context/runnable_context/trace.cc +++ b/src/vt/context/runnable_context/trace.cc @@ -54,7 +54,7 @@ namespace vt { namespace ctx { -void Trace::start() { +void Trace::start(TimeType time) { if (not is_traced_) { return; } @@ -67,30 +67,30 @@ void Trace::start() { from_node_ != uninitialized_destination ? from_node_ : cur_node; processing_tag_ = theTrace()->beginProcessing( - trace_id, msg_size_, event_, from_node, idx1_, idx2_, idx3_, idx4_ + trace_id, msg_size_, event_, from_node, idx1_, idx2_, idx3_, idx4_, time ); } else { processing_tag_ = theTrace()->beginProcessing( - trace_id, msg_size_, event_, from_node_ + trace_id, msg_size_, event_, from_node_, time ); } } -void Trace::finish() { +void Trace::finish(TimeType time) { if (not is_traced_) { return; } - theTrace()->endProcessing(processing_tag_); + theTrace()->endProcessing(processing_tag_, time); } -void Trace::suspend() { - finish(); +void Trace::suspend(TimeType time) { + finish(time); } -void Trace::resume() { +void Trace::resume(TimeType time) { // @todo: connect up the last event to this new one after suspension - start(); + start(time); } }} /* end namespace vt::ctx */ diff --git a/src/vt/context/runnable_context/trace.h b/src/vt/context/runnable_context/trace.h index d09f35a9cd..aa4577bf28 100644 --- a/src/vt/context/runnable_context/trace.h +++ b/src/vt/context/runnable_context/trace.h @@ -101,10 +101,10 @@ struct Trace { */ trace::TraceEventIDType getEvent() const { return event_; } - void start(); - void finish(); - void suspend(); - void resume(); + void start(TimeType time); + void finish(TimeType time); + void suspend(TimeType time); + void resume(TimeType time); private: /// Whether it's a collection or not diff --git a/src/vt/elm/elm_lb_data.cc b/src/vt/elm/elm_lb_data.cc index d5dc5d5584..ff8f09ebad 100644 --- a/src/vt/elm/elm_lb_data.cc +++ b/src/vt/elm/elm_lb_data.cc @@ -50,8 +50,8 @@ namespace vt { namespace elm { -void ElementLBData::startTime() { - TimeTypeWrapper const start_time = timing::getCurrentTime(); +void ElementLBData::start(TimeType time) { + TimeTypeWrapper const start_time = time; cur_time_ = start_time.seconds(); cur_time_started_ = true; @@ -62,8 +62,8 @@ void ElementLBData::startTime() { ); } -void ElementLBData::stopTime() { - TimeTypeWrapper const stop_time = timing::getCurrentTime(); +void ElementLBData::stop(TimeType time) { + TimeTypeWrapper const stop_time = time; TimeTypeWrapper const total_time = stop_time.seconds() - cur_time_; //vtAssert(cur_time_started_, "Must have started time"); auto const started = cur_time_started_; diff --git a/src/vt/elm/elm_lb_data.h b/src/vt/elm/elm_lb_data.h index 554856f8d1..1ebc07c6c3 100644 --- a/src/vt/elm/elm_lb_data.h +++ b/src/vt/elm/elm_lb_data.h @@ -61,8 +61,8 @@ struct ElementLBData { ElementLBData(ElementLBData const&) = default; ElementLBData(ElementLBData&&) = default; - void startTime(); - void stopTime(); + void start(TimeType time); + void stop(TimeType time); void addTime(TimeTypeWrapper const& time); void sendToEntity(ElementIDStruct to, ElementIDStruct from, double bytes); diff --git a/src/vt/event/event.cc b/src/vt/event/event.cc index f9b8dd7653..59737386cc 100644 --- a/src/vt/event/event.cc +++ b/src/vt/event/event.cc @@ -123,7 +123,7 @@ EventType AsyncEvent::attachAction(EventType const& event, ActionType callable) event, event_id, static_cast(event_state), this_node ); - theMsg()->sendMsg( + theMsg()->sendMsg( owning_node, msg ); @@ -162,7 +162,7 @@ EventType AsyncEvent::attachAction(EventType const& event, ActionType callable) vtAssertExpr(send_back == msg->sent_from_node_); auto msg_send = makeMessage(event, msg->event_back_); - theMsg()->sendMsg( + theMsg()->sendMsg( send_back, msg_send ); }; diff --git a/src/vt/group/collective/group_collective_finished.cc b/src/vt/group/collective/group_collective_finished.cc index 2b7b1864e6..a327676f17 100644 --- a/src/vt/group/collective/group_collective_finished.cc +++ b/src/vt/group/collective/group_collective_finished.cc @@ -68,7 +68,7 @@ void InfoColl::CollSetupFinished::operator()(FinishedReduceMsg* msg) { auto nmsg = makeMessage( msg->getGroup(),info->new_tree_cont_ ); - theMsg()->sendMsg( + theMsg()->sendMsg( info->known_root_node_, nmsg ); } else { diff --git a/src/vt/group/collective/group_info_collective.cc b/src/vt/group/collective/group_info_collective.cc index 248c02deda..7c7075eb67 100644 --- a/src/vt/group/collective/group_info_collective.cc +++ b/src/vt/group/collective/group_info_collective.cc @@ -227,7 +227,7 @@ void InfoColl::setupCollective() { auto msg = makeMessage( group_, up_tree_cont_, in_group, size, child ); - theMsg()->sendMsg(parent, msg); + theMsg()->sendMsg(parent, msg); } } @@ -336,7 +336,7 @@ void InfoColl::upTree() { auto msg = makeMessage( group,new_root_cont_,true,subtree_zero,root_node,0,extra ); - theMsg()->sendMsg(root_node, msg); + theMsg()->sendMsg(root_node, msg); for (std::size_t i = 1; i < msg_list.size(); i++) { vt_debug_print( @@ -347,7 +347,7 @@ void InfoColl::upTree() { msg_list[i]->setOpID(down_tree_cont_); auto pmsg = promoteMsg(msg_list[i]); - theMsg()->sendMsg(root_node, pmsg); + theMsg()->sendMsg(root_node, pmsg); ++send_down_; } in_phase_two_ = true; @@ -377,7 +377,7 @@ void InfoColl::upTree() { auto cmsg = makeMessage( group,op,is_in_group,total_subtree,child,level ); - theMsg()->sendMsg(p, cmsg); + theMsg()->sendMsg(p, cmsg); for (auto&& msg : msg_in_group) { span_children_.push_back(msg->getChild()); @@ -406,14 +406,14 @@ void InfoColl::upTree() { auto msg = makeMessage( group,op,is_in_group,static_cast(subtree_),child,0,extra ); - theMsg()->sendMsg(p, msg); + theMsg()->sendMsg(p, msg); /* * Forward all the children messages up the tree (up to 2 of them) */ for (std::size_t i = 0; i < msg_in_group.size(); i++) { // new MsgPtr to avoid thief of original in collection auto msg_out = promoteMsg(msg_in_group[i].get()); - theMsg()->sendMsg(p, msg_out); + theMsg()->sendMsg(p, msg_out); } } else if (is_in_group && msg_in_group.size() == 1) { /* @@ -438,10 +438,10 @@ void InfoColl::upTree() { auto msg = makeMessage( group,op,is_in_group,total_subtree,child,0,extra ); - theMsg()->sendMsg(p, msg); + theMsg()->sendMsg(p, msg); // new MsgPtr to avoid thief of original in collection auto msg_out = promoteMsg(msg_in_group[0].get()); - theMsg()->sendMsg(p, msg_out); + theMsg()->sendMsg(p, msg_out); } else { vtAssertExpr(msg_in_group.size() > 2); @@ -478,7 +478,7 @@ void InfoColl::upTree() { auto msg = makeMessage( group,op,is_in_group,total_subtree,child,0,extra ); - theMsg()->sendMsg(p, msg); + theMsg()->sendMsg(p, msg); vt_debug_print( verbose, group, @@ -494,7 +494,7 @@ void InfoColl::upTree() { GroupCollectiveMsg* tmsg = *iter; c[i] = tmsg->getChild(); auto pmsg = promoteMsg(tmsg); - theMsg()->sendMsg(p, pmsg); + theMsg()->sendMsg(p, pmsg); iter++; } @@ -503,7 +503,7 @@ void InfoColl::upTree() { GroupCollectiveMsg* tmsg = *iter; tmsg->setOpID(down_tree_cont_); auto pmsg = promoteMsg(tmsg); - theMsg()->sendMsg(c[i % extra], pmsg); + theMsg()->sendMsg(c[i % extra], pmsg); ++send_down_; ++iter; } @@ -639,13 +639,13 @@ void InfoColl::downTree(GroupCollectiveMsg* msg) { auto const& num = collective_->span_children_.size(); auto const& child = collective_->span_children_[msg->getChild() % num]; auto nmsg = makeMessage(*msg); - theMsg()->sendMsg(child, nmsg); + theMsg()->sendMsg(child, nmsg); ++send_down_; } auto const& group_ = getGroupID(); auto nmsg = makeMessage(group_,down_tree_fin_cont_); - theMsg()->sendMsg(from, nmsg); + theMsg()->sendMsg(from, nmsg); } void InfoColl::newTree(NodeType const& parent) { @@ -686,7 +686,7 @@ void InfoColl::sendDownNewTree() { group_, c ); auto msg = makeMessage(group_,new_tree_cont_); - theMsg()->sendMsg(c, msg); + theMsg()->sendMsg(c, msg); } } @@ -727,7 +727,7 @@ void InfoColl::finalize() { auto msg = makeMessage( group_,finalize_cont_,known_root_node_,is_default_group_ ); - theMsg()->sendMsg(c, msg); + theMsg()->sendMsg(c, msg); } if (!is_in_group) { diff --git a/src/vt/group/global/group_default.impl.h b/src/vt/group/global/group_default.impl.h index 57ec37eca8..8d50239776 100644 --- a/src/vt/group/global/group_default.impl.h +++ b/src/vt/group/global/group_default.impl.h @@ -65,7 +65,7 @@ template * handler> } else { auto msg = makeMessage(); envelopeSetTag(msg->env, phase); - theMsg()->sendMsg(node, msg); + theMsg()->sendMsg(node, msg); } } diff --git a/src/vt/group/group_info.impl.h b/src/vt/group/group_info.impl.h index ba8ca3113b..10fdfd5794 100644 --- a/src/vt/group/group_info.impl.h +++ b/src/vt/group/group_info.impl.h @@ -115,7 +115,7 @@ template if (op_id != no_op_id) { // Send back message auto retmsg = makeMessage(group, op_id); - theMsg()->sendMsg( + theMsg()->sendMsg( parent, retmsg ); } @@ -151,7 +151,7 @@ template auto contmsg = makeMessage(group, op_id); if (parent != this_node) { - theMsg()->sendMsg( + theMsg()->sendMsg( parent, contmsg ); } else { diff --git a/src/vt/group/group_manager.h b/src/vt/group/group_manager.h index 24f9a6c101..63c9f61e8b 100644 --- a/src/vt/group/group_manager.h +++ b/src/vt/group/group_manager.h @@ -62,6 +62,7 @@ #include "vt/collective/reduce/reduce.h" #include "vt/collective/collective_scope.h" #include "vt/runtime/component/component_pack.h" +#include "vt/utils/fntraits/fntraits.h" #include #include @@ -193,6 +194,15 @@ struct GroupManager : runtime::component::Component { template *f> void sendMsg(GroupType const group, MsgT* msg); + template + void sendMsg( + GroupType const group, + typename FuncTraits::MsgT* msg + ) { + using MsgT = typename FuncTraits::MsgT; + return sendMsg(group, msg); + } + friend struct Info; friend struct InfoColl; friend struct FinishedWork; diff --git a/src/vt/messaging/active.cc b/src/vt/messaging/active.cc index 63ef24da3e..9ab3235191 100644 --- a/src/vt/messaging/active.cc +++ b/src/vt/messaging/active.cc @@ -495,10 +495,16 @@ EventType ActiveMessenger::doMessageSend( } else { recordLBDataCommForSend(dest, base, base.size()); - runnable::makeRunnable(base, true, envelopeGetHandler(msg->env), dest) - .withTDEpochFromMsg(is_term) - .withLBData(&bare_handler_lb_data_, bare_handler_dummy_elm_id_for_lb_data_) - .enqueue(); + auto han = envelopeGetHandler(msg->env); + bool const is_obj = HandlerManagerType::isHandlerObjGroup(han); + if (is_obj) { + objgroup::dispatchObjGroup(base, han, dest, nullptr); + } else { + runnable::makeRunnable(base, true, envelopeGetHandler(msg->env), dest) + .withTDEpochFromMsg(is_term) + .withLBData(&bare_handler_lb_data_, bare_handler_dummy_elm_id_for_lb_data_) + .enqueue(); + } } return no_event; } @@ -953,11 +959,16 @@ void ActiveMessenger::prepareActiveMsgToRun( ); } - runnable::makeRunnable(base, not is_term, handler, from_node) - .withContinuation(cont) - .withTDEpochFromMsg(is_term) - .withLBData(&bare_handler_lb_data_, bare_handler_dummy_elm_id_for_lb_data_) - .enqueue(); + bool const is_obj = HandlerManagerType::isHandlerObjGroup(handler); + if (is_obj) { + objgroup::dispatchObjGroup(base, handler, from_node, cont); + } else { + runnable::makeRunnable(base, not is_term, handler, from_node) + .withContinuation(cont) + .withTDEpochFromMsg(is_term) + .withLBData(&bare_handler_lb_data_, bare_handler_dummy_elm_id_for_lb_data_) + .enqueue(); + } if (is_term) { tdRecvCount.increment(1); diff --git a/src/vt/messaging/active.h b/src/vt/messaging/active.h index 49aa04b43f..b1d8e198a7 100644 --- a/src/vt/messaging/active.h +++ b/src/vt/messaging/active.h @@ -56,6 +56,7 @@ #include "vt/messaging/request_holder.h" #include "vt/messaging/send_info.h" #include "vt/messaging/async_op_wrapper.h" +#include "vt/messaging/param_msg.h" #include "vt/event/event.h" #include "vt/registry/auto/auto_registry_interface.h" #include "vt/trace/trace_common.h" @@ -63,6 +64,8 @@ #include "vt/runtime/component/component_pack.h" #include "vt/elm/elm_id.h" #include "vt/elm/elm_lb_data.h" +#include "vt/utils/strong/strong_type.h" +#include "vt/utils/fntraits/fntraits.h" #if vt_check_enabled(trace_enabled) #include "vt/trace/trace_headers.h" @@ -86,7 +89,12 @@ using ContinuationDeleterType = } /* end namespace vt */ -namespace vt { namespace messaging { +namespace vt { + +struct StrongNodeType { }; +using Node = Strong; + +namespace messaging { /** \file */ @@ -686,6 +694,27 @@ struct ActiveMessenger : runtime::component::PollableComponent TagType tag = no_tag ); + /** + * \brief Broadcast a message (message type not required). + * + * \note Takes ownership of the supplied message. + * + * \param[in] msg the message to broadcast + * \param[in] deliver_to_sender whether msg should be delivered to sender + * \param[in] tag the tag to put on the message + * + * \return the \c PendingSend for the sent message + */ + template + PendingSendType broadcastMsg( + MsgPtrThief::MsgT> msg, + bool deliver_to_sender = true, + TagType tag = no_tag + ) { + using MsgT = typename FuncTraits::MsgT; + return broadcastMsg(msg, deliver_to_sender, tag); + } + /** * \brief Send a message. * @@ -704,6 +733,61 @@ struct ActiveMessenger : runtime::component::PollableComponent TagType tag = no_tag ); + /** + * \brief Send a message (message type not required). + * + * \note Takes ownership of the supplied message. + * + * \param[in] dest the destination node to send the message to + * \param[in] msg the message to send + * \param[in] tag the tag to put on the message + * + * \return the \c PendingSend for the sent message + */ + template + PendingSendType sendMsg( + NodeType dest, + MsgPtrThief::MsgT> msg, + TagType tag = no_tag + ) { + using MsgT = typename FuncTraits::MsgT; + return sendMsg(dest, msg, tag); + } + + /** + * \brief Send parameters to a handler in a message + * + * \param[in] dest the destination node to send the message to + * \param[in] params the parameters + * + * \return the \c PendingSend for the sent message + */ + template + PendingSendType send(Node dest, Params&&... params) { + using Tuple = typename FuncTraits::TupleType; + using MsgT = ParamMsg; + auto msg = vt::makeMessage(std::forward(params)...); + auto han = auto_registry::makeAutoHandlerParam(); + return sendMsg(dest.get(), han, msg, no_tag); + } + + /** + * \brief Broadcast parameters to a handler in a message + * + * \param[in] params the parameters + * + * \return the \c PendingSend for the sent message + */ + template + PendingSendType broadcast(Params&&... params) { + using Tuple = typename FuncTraits::TupleType; + using MsgT = ParamMsg; + auto msg = vt::makeMessage(std::forward(params)...); + auto han = auto_registry::makeAutoHandlerParam(); + constexpr bool deliver_to_sender = true; + return broadcastMsg(han, msg, deliver_to_sender, no_tag); + } + /** * \brief Send a message with explicit size. * diff --git a/src/vt/worker/worker_group_counter.h b/src/vt/messaging/async_op_hip.h similarity index 51% rename from src/vt/worker/worker_group_counter.h rename to src/vt/messaging/async_op_hip.h index 3961484018..bdd27ce1aa 100644 --- a/src/vt/worker/worker_group_counter.h +++ b/src/vt/messaging/async_op_hip.h @@ -2,7 +2,7 @@ //@HEADER // ***************************************************************************** // -// worker_group_counter.h +// async_op_hip.h // DARMA/vt => Virtual Transport // // Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC @@ -41,56 +41,80 @@ //@HEADER */ -#if !defined INCLUDED_VT_WORKER_WORKER_GROUP_COUNTER_H -#define INCLUDED_VT_WORKER_WORKER_GROUP_COUNTER_H +#if !defined INCLUDED_VT_MESSAGING_ASYNC_OP_HIP_H +#define INCLUDED_VT_MESSAGING_ASYNC_OP_HIP_H -#include "vt/config.h" -#include "vt/worker/worker_common.h" -#include "vt/utils/atomic/atomic.h" -#include "vt/utils/container/process_ready_buffer.h" +#include "vt/messaging/async_op.h" -#include +#if __HIPCC__ +#include +#endif -namespace vt { namespace worker { +namespace vt { namespace messaging { -using ::vt::util::atomic::AtomicType; -using ::vt::util::container::ProcessBuffer; +#if __HIPCC__ -struct WorkerGroupCounter { - using IdleListenerType = std::function; - using IdleListenerContainerType = std::list; - using EnqueueCountContainerType = ProcessBuffer; +/** + * \struct AsyncOpHIP + * + * \brief An asynchronous HIP event on which VT can poll completion. + */ +struct AsyncOpHIP : AsyncOp { - WorkerGroupCounter() { - attachEnqueueProgressFn(); + /** + * \brief Construct with stream + * + * \param[in] in_stream the HIP stream to generate an event from + * \param[in] in_cont the action to execute when event completes + */ + AsyncOpHIP(hipStream_t in_stream, ActionType in_cont = nullptr) + : cont_(in_cont) + { + vtAbortIf(hipSuccess != hipEventCreate(&event_), "Failed to create event"); + vtAbortIf(hipSuccess != hipEventRecord(event_, in_stream), "Failed to record event"); } - // This method may be called from multiple threads - void enqueued(WorkUnitCountType num = 1); - void finished(WorkerIDType id, WorkUnitCountType num = 1); + /** + * \brief Construct with an event + * + * \param[in] in_event the HIP event to poll + * \param[in] in_cont the action to execute when event completes + */ + AsyncOpHIP(hipEvent_t in_event, ActionType in_cont = nullptr) + : event_(in_event), + cont_(in_cont) + { } - // These methods should only be called by a single thread (i.e., comm thread) - void enqueuedComm(WorkUnitCountType num = 1); - void registerIdleListener(IdleListenerType listener); - void progress(); + /** + * \brief Poll completion of the HIP event + * + * \return whether the HIP event is complete + */ + bool poll() override { + auto ret = hipEventQuery(event_); + if (hipSuccess != ret && hipErrorNotReady != ret) { + vtAbort(fmt::format("Failure on stream event: {}: {}", hipGetErrorName(ret), hipGetErrorString(ret))); + } + return ret == hipSuccess; + } -protected: - void assertCommThread(); - void attachEnqueueProgressFn(); - void triggerListeners(eWorkerGroupEvent event); - void updateConsumedTerm(); + /** + * \brief Trigger continuation after completion + */ + void done() override { + vtAbortIf(hipSuccess != hipEventDestroy(event_), "Failed to destroy event"); + if (cont_) { + cont_(); + } + } private: - AtomicType num_enqueued_ = {0}; - AtomicType num_finished_ = {0}; - AtomicType maybe_idle_= {false}; - WorkUnitCountType num_consumed_ = 0; - IdleListenerContainerType listeners_; - eWorkerGroupEvent last_event_ = eWorkerGroupEvent::InvalidEvent; - EnqueueCountContainerType enqueued_count_; + hipEvent_t event_ = {}; /**< The HIP event being tested */ + ActionType cont_ = nullptr; /**< The continuation after event completes */ }; +#endif /* __HIPCC__ */ -}} /* end namespace vt::worker */ +}} /* end namespace vt::messaging */ -#endif /*INCLUDED_VT_WORKER_WORKER_GROUP_COUNTER_H*/ +#endif /*INCLUDED_VT_MESSAGING_ASYNC_OP_HIP_H*/ diff --git a/src/vt/objgroup/dispatch/dispatch_base.h b/src/vt/messaging/param_msg.h similarity index 60% rename from src/vt/objgroup/dispatch/dispatch_base.h rename to src/vt/messaging/param_msg.h index 42bc9b63ab..d3e7c25087 100644 --- a/src/vt/objgroup/dispatch/dispatch_base.h +++ b/src/vt/messaging/param_msg.h @@ -2,7 +2,7 @@ //@HEADER // ***************************************************************************** // -// dispatch_base.h +// param_msg.h // DARMA/vt => Virtual Transport // // Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC @@ -41,46 +41,58 @@ //@HEADER */ -#if !defined INCLUDED_VT_OBJGROUP_DISPATCH_DISPATCH_BASE_H -#define INCLUDED_VT_OBJGROUP_DISPATCH_DISPATCH_BASE_H +#if !defined INCLUDED_VT_MESSAGING_PARAM_MSG_H +#define INCLUDED_VT_MESSAGING_PARAM_MSG_H -#include "vt/config.h" -#include "vt/objgroup/common.h" -#include "vt/messaging/message/smart_ptr.h" +#include "vt/messaging/message/message_serialize.h" -namespace vt { namespace objgroup { namespace dispatch { +namespace vt { namespace messaging { -/* - * DispatchBase implements type erasure to dispatch to a obj group without - * encoding the message directly in the message (as an alternative to using a - * std::function) - */ +template +struct ParamMsg; + +template +struct ParamMsg< + Tuple, std::enable_if_t::value> +> : vt::Message +{ + ParamMsg() = default; -struct DispatchBase { - explicit DispatchBase(ObjGroupProxyType in_proxy) - : proxy_(in_proxy) + template + explicit ParamMsg(Params&&... in_params) + : params(std::forward(in_params)...) { } - virtual ~DispatchBase() = default; + Tuple params; + Tuple& getTuple() { return params; } +}; - /* - * Dispatch to the handler; the base is closed around the proper object - * pointer that is type-erased here - */ - virtual void run(HandlerType han, BaseMessage* msg) = 0; - virtual void* objPtr() const = 0; +template +struct ParamMsg< + Tuple, std::enable_if_t::value> +> : vt::Message +{ + using MessageParentType = vt::Message; + vt_msg_serialize_if_needed_by_parent_or_type1(Tuple); // by tup - ObjGroupProxyType proxy() const { return proxy_; } + ParamMsg() = default; - template - void serialize(Serializer& s) { - s | proxy_; - } + template + explicit ParamMsg(Params&&... in_params) + : params(std::make_unique(std::forward(in_params)...)) + { } + + std::unique_ptr params; -private: - ObjGroupProxyType proxy_ = no_obj_group; + Tuple& getTuple() { return *params.get(); } + + template + void serialize(SerializerT& s) { + MessageParentType::serialize(s); + s | params; + } }; -}}} /* end namespace vt::objgroup::dispatch */ +}} /* end namespace vt::messaging */ -#endif /*INCLUDED_VT_OBJGROUP_DISPATCH_DISPATCH_BASE_H*/ +#endif /*INCLUDED_VT_MESSAGING_PARAM_MSG_H*/ diff --git a/src/vt/objgroup/dispatch/dispatch.h b/src/vt/objgroup/dispatch/dispatch.h deleted file mode 100644 index 417640fe50..0000000000 --- a/src/vt/objgroup/dispatch/dispatch.h +++ /dev/null @@ -1,77 +0,0 @@ -/* -//@HEADER -// ***************************************************************************** -// -// dispatch.h -// DARMA/vt => Virtual Transport -// -// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC -// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. -// Government retains certain rights in this software. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Questions? Contact darma@sandia.gov -// -// ***************************************************************************** -//@HEADER -*/ - -#if !defined INCLUDED_VT_OBJGROUP_DISPATCH_DISPATCH_H -#define INCLUDED_VT_OBJGROUP_DISPATCH_DISPATCH_H - -#include "vt/config.h" -#include "vt/objgroup/common.h" -#include "vt/objgroup/dispatch/dispatch_base.h" -#include "vt/messaging/message/smart_ptr.h" - -namespace vt { namespace objgroup { namespace dispatch { - -template -struct Dispatch final : DispatchBase { - Dispatch() = delete; - Dispatch(Dispatch const&) = delete; - Dispatch(Dispatch&&) = default; - - Dispatch(ObjGroupProxyType in_proxy, ObjT* in_obj) - : DispatchBase(in_proxy), obj_(in_obj) - { } - - virtual ~Dispatch() = default; - - void run(HandlerType han, BaseMessage* msg) override; - void* objPtr() const override { return obj_; } - -private: - ObjT* obj_ = nullptr; -}; - -}}} /* end namespace vt::objgroup::dispatch */ - -#include "vt/objgroup/dispatch/dispatch.impl.h" - -#endif /*INCLUDED_VT_OBJGROUP_DISPATCH_DISPATCH_H*/ diff --git a/src/vt/objgroup/dispatch/dispatch.impl.h b/src/vt/objgroup/dispatch/dispatch.impl.h deleted file mode 100644 index 57cb32dfe5..0000000000 --- a/src/vt/objgroup/dispatch/dispatch.impl.h +++ /dev/null @@ -1,73 +0,0 @@ -/* -//@HEADER -// ***************************************************************************** -// -// dispatch.impl.h -// DARMA/vt => Virtual Transport -// -// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC -// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. -// Government retains certain rights in this software. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Questions? Contact darma@sandia.gov -// -// ***************************************************************************** -//@HEADER -*/ - -#if !defined INCLUDED_VT_OBJGROUP_DISPATCH_DISPATCH_IMPL_H -#define INCLUDED_VT_OBJGROUP_DISPATCH_DISPATCH_IMPL_H - -#include "vt/config.h" -#include "vt/objgroup/common.h" -#include "vt/registry/auto/auto_registry.h" - -namespace vt { namespace objgroup { namespace dispatch { - -template -void Dispatch::run(HandlerType han, BaseMessage* msg) { - using ActiveFnType = void(ObjT::*)(vt::BaseMessage*); - vtAssert(obj_ != nullptr, "Must have a valid object"); - // Consume if there is an epoch for this message - auto tmsg = static_cast(msg); - auto cur_epoch = envelopeGetEpoch(tmsg->env); - if (cur_epoch != no_epoch) { - theMsg()->pushEpoch(cur_epoch); - } - auto base_func = auto_registry::getAutoHandlerObjGroup(han); - auto type_func = reinterpret_cast(base_func); - (obj_->*type_func)(msg); - if (cur_epoch != no_epoch) { - theMsg()->popEpoch(cur_epoch); - } -} - -}}} /* end namespace vt::objgroup::dispatch */ - -#endif /*INCLUDED_VT_OBJGROUP_DISPATCH_DISPATCH_IMPL_H*/ diff --git a/src/vt/objgroup/manager.cc b/src/vt/objgroup/manager.cc index a3932db0bb..18888093dc 100644 --- a/src/vt/objgroup/manager.cc +++ b/src/vt/objgroup/manager.cc @@ -83,32 +83,6 @@ ObjGroupProxyType ObjGroupManager::getProxy(ObjGroupProxyType proxy) { return proxy; } -void ObjGroupManager::dispatch(MsgSharedPtr msg, HandlerType han) { - // Extract the control-bit sequence from the handler - auto const ctrl = HandlerManager::getHandlerControl(han); - vt_debug_print( - verbose, objgroup, - "dispatch: ctrl={:x}, han={:x}\n", ctrl, han - ); - auto const node = 0; - auto const proxy = proxy::ObjGroupProxy::create(ctrl, node, true); - auto dispatch_iter = dispatch_.find(proxy); - vt_debug_print( - normal, objgroup, - "dispatch: try ctrl={:x}, han={:x}, has dispatch={}\n", - ctrl, han, dispatch_iter != dispatch_.end() - ); - if (dispatch_iter == dispatch_.end()) { - auto const epoch = envelopeGetEpoch(msg->env); - if (epoch != no_epoch and epoch != term::any_epoch_sentinel) { - theTerm()->produce(epoch); - } - pending_[proxy].push_back(msg); - } else { - dispatch_iter->second->run(han,msg.get()); - } -} - ObjGroupProxyType ObjGroupManager::makeCollectiveImpl( std::string const& label, HolderBasePtrType base, void* obj_ptr ) { @@ -163,12 +137,12 @@ elm::ElementIDStruct ObjGroupManager::getNextElm(ObjGroupProxyType proxy) { } } -void dispatchObjGroup(MsgSharedPtr msg, HandlerType han) { - vt_debug_print( - verbose, objgroup, - "dispatchObjGroup: han={:x}\n", han - ); - return theObjGroup()->dispatch(msg,han); +std::unordered_map>& getObjs() { + return theObjGroup()->objs_; +} + +std::unordered_map>& getPending() { + return theObjGroup()->pending_; } }} /* end namespace vt::objgroup */ diff --git a/src/vt/objgroup/manager.fwd.h b/src/vt/objgroup/manager.fwd.h index 9b67f7e5d2..14ad2bb4af 100644 --- a/src/vt/objgroup/manager.fwd.h +++ b/src/vt/objgroup/manager.fwd.h @@ -60,12 +60,18 @@ namespace detail { holder::HolderBase* getHolderBase(HandlerType handler); } /* end namespace detail */ -void dispatchObjGroup(MsgSharedPtr msg, HandlerType han); +template +void dispatchObjGroup( + MsgSharedPtr msg, HandlerType han, NodeType from_node, ActionType cont +); + +std::unordered_map>& getObjs(); +std::unordered_map>& getPending(); template messaging::PendingSend send(MsgSharedPtr msg, HandlerType han, NodeType node); -template -void invoke(messaging::MsgPtrThief msg, HandlerType han, NodeType node); +template +decltype(auto) invoke(messaging::MsgSharedPtr msg, HandlerType han, NodeType node); template messaging::PendingSend broadcast(MsgSharedPtr msg, HandlerType han); diff --git a/src/vt/objgroup/manager.h b/src/vt/objgroup/manager.h index a43c107501..0080182e5e 100644 --- a/src/vt/objgroup/manager.h +++ b/src/vt/objgroup/manager.h @@ -46,17 +46,18 @@ #include "vt/config.h" #include "vt/runtime/component/component_pack.h" +#include "vt/utils/static_checks/function_ret_check.h" #include "vt/objgroup/common.h" #include "vt/objgroup/manager.fwd.h" #include "vt/objgroup/proxy/proxy_objgroup.h" #include "vt/objgroup/holder/holder.h" #include "vt/objgroup/holder/holder_user.h" #include "vt/objgroup/holder/holder_basic.h" -#include "vt/objgroup/dispatch/dispatch.h" #include "vt/messaging/message/message.h" #include "vt/messaging/message/smart_ptr.h" #include "vt/messaging/pending_send.h" #include "vt/elm/elm_id.h" +#include "vt/utils/fntraits/fntraits.h" #include #include @@ -89,11 +90,9 @@ struct ObjGroupManager : runtime::component::Component { using MakeFnType = std::function()>; using HolderBaseType = holder::HolderBase; using HolderBasePtrType = std::unique_ptr; - using DispatchBaseType = dispatch::DispatchBase; - using DispatchBasePtrType = std::unique_ptr; - using MsgContainerType = std::vector>; using PendingSendType = messaging::PendingSend; +public: /** * \internal \brief Construct the ObjGroupManager */ @@ -219,6 +218,22 @@ struct ObjGroupManager : runtime::component::Component { template fn> PendingSendType send(ProxyElmType proxy, MsgSharedPtr msg); + /** + * \internal \brief Send a message to an element of the object group + * + * \param[in] proxy proxy to the object group + * \param[in] msg message to send + */ + template + PendingSendType send( + ProxyElmType::ObjT> proxy, + MsgSharedPtr::MsgT> msg + ) { + using ObjType = typename ObjFuncTraits::ObjT; + using MsgType = typename ObjFuncTraits::MsgT; + return send(proxy, msg); + } + /** * \internal \brief Invoke message handler on an element of the object group * The message handler will be invoked inline without going through scheduler @@ -227,7 +242,7 @@ struct ObjGroupManager : runtime::component::Component { * \param[in] msg message */ template fn> - void invoke(ProxyElmType proxy, messaging::MsgPtrThief msg); + decltype(auto) invoke(ProxyElmType proxy, messaging::MsgPtrThief msg); /** * \internal \brief Invoke function 'f' on an element of the object group @@ -236,7 +251,7 @@ struct ObjGroupManager : runtime::component::Component { * \param[in] proxy proxy to the object group * \param[in] args function arguments */ - template + template decltype(auto) invoke(ProxyElmType proxy, Args&&... args); /** @@ -248,6 +263,22 @@ struct ObjGroupManager : runtime::component::Component { template fn> PendingSendType broadcast(ProxyType proxy, MsgSharedPtr msg); + /** + * \internal \brief Broadcast a message to all nodes in object group + * + * \param[in] proxy proxy to the object group + * \param[in] msg message to broadcast + */ + template + PendingSendType broadcast( + ProxyType::ObjT> proxy, + MsgSharedPtr::MsgT> msg + ) { + using ObjType = typename ObjFuncTraits::ObjT; + using MsgType = typename ObjFuncTraits::MsgT; + return broadcast(proxy, msg); + } + /** * \brief Change the traced name of the object group * @@ -275,6 +306,25 @@ struct ObjGroupManager : runtime::component::Component { collective::reduce::ReduceStamp const& stamp ); + /** + * \brief Perform a reduction over an objgroup + * + * \param[in] proxy proxy to the object group + * \param[in] msg reduction message + * \param[in] stamp stamp to identify reduction across nodes + * + * \return the PendingSend corresponding to the reduce + */ + template + PendingSendType reduce( + ProxyType proxy, + messaging::MsgPtrThief::MsgT> msg, + collective::reduce::ReduceStamp const& stamp + ) { + using MsgT = typename FuncTraits::MsgT; + return reduce(proxy, msg, stamp); + } + /** * \brief Get a pointer to the local objgroup instance. Returns null if the * object doesn't exist. @@ -330,17 +380,6 @@ struct ObjGroupManager : runtime::component::Component { template std::string getLabel(ProxyType proxy) const; - /* - * Dispatch to a live obj group pointer with a handler - */ - /** - * \internal \brief Dispatch message to objgroup - * - * \param[in] msg the message - * \param[in] han the handler to invoke - */ - void dispatch(MsgSharedPtr msg, HandlerType han); - /** * \internal \brief Send a message to an objgroup * @@ -359,8 +398,10 @@ struct ObjGroupManager : runtime::component::Component { * \param[in] han handler to invoke * \param[in] node node to invoke the handler on */ - template - void invoke(messaging::MsgPtrThief msg, HandlerType han, NodeType node); + template + decltype(auto) invoke( + messaging::MsgSharedPtr msg, HandlerType han, NodeType node + ); /** * \internal \brief Broadcast message to an objgroup @@ -383,7 +424,6 @@ struct ObjGroupManager : runtime::component::Component { template void serialize(SerializerT& s) { s | cur_obj_id_ - | dispatch_ | objs_ | obj_to_proxy_ | pending_ @@ -392,6 +432,8 @@ struct ObjGroupManager : runtime::component::Component { // Friend function to access the holder without including this header file friend holder::HolderBase* detail::getHolderBase(HandlerType handler); + friend std::unordered_map& getObjs(); + friend std::unordered_map>& getPending(); private: /** @@ -451,14 +493,12 @@ struct ObjGroupManager : runtime::component::Component { private: /// The current obj ID, sequential on each node for collective construction ObjGroupIDType cur_obj_id_ = fst_obj_group_id; - /// Function to dispatch to the base class for type-erasure to run handler - std::unordered_map dispatch_; /// Type-erased pointers to the objects held on this node std::unordered_map objs_; /// Reverse lookup map from an object pointer to the proxy std::unordered_map obj_to_proxy_; /// Messages that are pending creation for delivery - std::unordered_map pending_; + std::unordered_map> pending_; /// Map of object groups' labels std::unordered_map labels_; }; diff --git a/src/vt/objgroup/manager.impl.h b/src/vt/objgroup/manager.impl.h index dffb5f7917..936d2bc40b 100644 --- a/src/vt/objgroup/manager.impl.h +++ b/src/vt/objgroup/manager.impl.h @@ -52,7 +52,6 @@ #include "vt/objgroup/holder/holder.h" #include "vt/objgroup/holder/holder_user.h" #include "vt/objgroup/holder/holder_basic.h" -#include "vt/objgroup/dispatch/dispatch.h" #include "vt/objgroup/type_registry/registry.h" #include "vt/registry/auto/auto_registry.h" #include "vt/collective/collective_alg.h" @@ -130,15 +129,6 @@ ObjGroupManager::makeCollective(MakeFnType fn, std::string const& label) { template void ObjGroupManager::destroyCollective(ProxyType proxy) { auto const proxy_bits = proxy.getProxy(); - auto iter = dispatch_.find(proxy_bits); - if (iter != dispatch_.end()) { - auto ptr = iter->second->objPtr(); - auto obj_iter = obj_to_proxy_.find(ptr); - if (obj_iter != obj_to_proxy_.end()) { - obj_to_proxy_.erase(obj_iter); - } - dispatch_.erase(iter); - } auto obj_iter = objs_.find(proxy_bits); if (obj_iter != objs_.end()) { objs_.erase(obj_iter); @@ -152,30 +142,15 @@ void ObjGroupManager::destroyCollective(ProxyType proxy) { template void ObjGroupManager::regObjProxy(ObjT* obj, ObjGroupProxyType proxy) { - auto iter = dispatch_.find(proxy); - vtAssertExpr(iter == dispatch_.end()); vt_debug_print( normal, objgroup, "regObjProxy: obj={}, proxy={:x}\n", print_ptr(obj), proxy ); - DispatchBasePtrType b = std::make_unique>(proxy,obj); - dispatch_.emplace( - std::piecewise_construct, - std::forward_as_tuple(proxy), - std::forward_as_tuple(std::move(b)) - ); auto pending_iter = pending_.find(proxy); if (pending_iter != pending_.end()) { - for (auto&& msg : pending_iter->second) { - theSched()->enqueue([msg]{ - auto const handler = envelopeGetHandler(msg->env); - auto const epoch = envelopeGetEpoch(msg->env); - theObjGroup()->dispatch(msg,handler); - if (epoch != no_epoch) { - theTerm()->consume(epoch); - } - }); + for (auto&& pending : pending_iter->second) { + pending(); } pending_.erase(pending_iter); } @@ -218,7 +193,7 @@ ObjGroupManager::PendingSendType ObjGroupManager::send(ProxyElmType proxy, } template fn> -void ObjGroupManager::invoke( +decltype(auto) ObjGroupManager::invoke( ProxyElmType proxy, messaging::MsgPtrThief msg ) { auto const proxy_bits = proxy.getProxy(); @@ -232,10 +207,11 @@ void ObjGroupManager::invoke( proxy_bits, dest_node, ctrl, han ); - invoke(msg, han, dest_node); + auto& msg_ptr = msg.msg_; + return invoke(msg_ptr, han, dest_node); } -template +template decltype(auto) ObjGroupManager::invoke(ProxyElmType proxy, Args&&... args) { auto const dest_node = proxy.getNode(); @@ -244,12 +220,12 @@ ObjGroupManager::invoke(ProxyElmType proxy, Args&&... args) { vtAssert( dest_node == this_node, fmt::format( - "Attempting to invoke handler on node:{} instead of node:{}!\n", this_node, - dest_node - ) - ); + "Attempting to invoke handler on node:{} instead of node:{}!\n", + this_node, dest_node)); - return runnable::invoke(get(proxy), std::forward(args)...); + return runnable::makeRunnableVoid(false, uninitialized_handler, this_node) + .withObjGroup(get(proxy)) + .runLambda(f, get(proxy), std::forward(args)...); } @@ -275,11 +251,11 @@ ObjGroupManager::PendingSendType ObjGroupManager::send( return objgroup::send(msg,han,dest_node); } -template -void ObjGroupManager::invoke( - messaging::MsgPtrThief msg, HandlerType han, NodeType dest_node +template +decltype(auto) ObjGroupManager::invoke( + messaging::MsgSharedPtr msg, HandlerType han, NodeType dest_node ) { - objgroup::invoke(msg, han, dest_node); + return objgroup::invoke(msg, han, dest_node); } template @@ -296,7 +272,7 @@ ObjGroupManager::PendingSendType ObjGroupManager::reduce( auto const objgroup = proxy.getProxy(); auto r = theCollective()->getReducerObjGroup(objgroup); - return r->template reduce(root, msg.get(), stamp); + return r->template reduce(root, msg.get(), stamp); } template diff --git a/src/vt/objgroup/manager.static.h b/src/vt/objgroup/manager.static.h index faf6aaa5b3..ac24a78aec 100644 --- a/src/vt/objgroup/manager.static.h +++ b/src/vt/objgroup/manager.static.h @@ -46,6 +46,7 @@ #include "vt/config.h" #include "vt/objgroup/common.h" +#include "vt/objgroup/proxy/proxy_bits.h" #include "vt/objgroup/holder/holder_base.h" #include "vt/messaging/active.h" #include "vt/runnable/make_runnable.h" @@ -60,24 +61,23 @@ messaging::PendingSend send(MsgSharedPtr msg, HandlerType han, NodeType de if (dest_node != this_node) { return theMsg()->sendMsg(dest_node, han,msg, no_tag); } else { - // Get the current epoch for the message - auto const cur_epoch = theMsg()->setupEpochMsg(msg); - - return messaging::PendingSend{cur_epoch, [msg, han, cur_epoch, this_node](){ - auto holder = detail::getHolderBase(han); - auto const& elm_id = holder->getElmID(); - auto lb_data = &holder->getLBData(); - - runnable::makeRunnable(msg, true, han, this_node) - .withTDEpoch(cur_epoch) - .withLBData(lb_data, elm_id) - .enqueue(); + theMsg()->setupEpochMsg(msg); + envelopeSetHandler(msg->env, han); + return messaging::PendingSend{msg, [](MsgSharedPtr& inner_msg){ + dispatchObjGroup( + inner_msg.template to(), + envelopeGetHandler(inner_msg->env), + theContext()->getNode(), + nullptr + ); }}; } } -template -void invoke(messaging::MsgPtrThief msg, HandlerType han, NodeType dest_node) { +template +decltype(auto) invoke( + messaging::MsgSharedPtr msg, HandlerType han, NodeType dest_node +) { auto const this_node = theContext()->getNode(); vtAssert( @@ -89,9 +89,14 @@ void invoke(messaging::MsgPtrThief msg, HandlerType han, NodeType dest_nod ); // this is a local invocation.. no thread required - runnable::makeRunnable(msg.msg_, false, han, this_node) - .withTDEpochFromMsg() - .run(); + auto holder = detail::getHolderBase(han); + auto const& elm_id = holder->getElmID(); + auto elm = holder->getPtr(); + auto lb_data = &holder->getLBData(); + return runnable::makeRunnableVoid(false, han, this_node) + .withObjGroup(elm) + .withLBData(lb_data, elm_id) + .runLambda(f, static_cast(elm), msg.get()); } template @@ -99,6 +104,78 @@ messaging::PendingSend broadcast(MsgSharedPtr msg, HandlerType han) { return theMsg()->broadcastMsg(han, msg); } +namespace detail { + +template +void dispatchImpl( + MsgSharedPtr const& msg, HandlerType han, NodeType from_node, + ActionType cont, ObjT* obj +) { + auto holder = detail::getHolderBase(han); + auto const& elm_id = holder->getElmID(); + auto lb_data = &holder->getLBData(); + runnable::makeRunnable(msg, true, han, from_node) + .withContinuation(cont) + .withObjGroup(obj) + .withLBData(lb_data, elm_id) + .withTDEpochFromMsg() + .enqueue(); +} + +template +void dispatch( + MsgSharedPtr msg, HandlerType han, NodeType from_node, + ActionType cont +) { + // Extract the control-bit sequence from the handler + auto const ctrl = HandlerManager::getHandlerControl(han); + vt_debug_print( + verbose, objgroup, + "dispatch: ctrl={:x}, han={:x}\n", ctrl, han + ); + auto const node = 0; + auto const proxy = proxy::ObjGroupProxy::create(ctrl, node, true); + auto& objs = getObjs(); + auto obj_iter = objs.find(proxy); + vt_debug_print( + normal, objgroup, + "dispatch: try ctrl={:x}, han={:x}, has dispatch={}\n", + ctrl, han, obj_iter != objs.end() + ); + if (obj_iter == objs.end()) { + auto const epoch = envelopeGetEpoch(msg->env); + if (epoch != no_epoch) { + theTerm()->produce(epoch); + } + auto& pending = getPending(); + pending[proxy].emplace_back([=]{ + auto& objs2 = getObjs(); + auto obj_iter2 = objs2.find(proxy); + vtAssert(obj_iter2 != objs2.end(), "Obj must exist"); + detail::dispatchImpl(msg, han, from_node, cont, obj_iter2->second->getPtr()); + if (epoch != no_epoch) { + theTerm()->consume(epoch); + } + }); + } else { + detail::dispatchImpl(msg, han, from_node, cont, obj_iter->second->getPtr()); + } +} + +} /* end namespace detail */ + +template +void dispatchObjGroup( + MsgSharedPtr msg, HandlerType han, NodeType from_node, + ActionType cont +) { + vt_debug_print( + verbose, objgroup, + "dispatchObjGroup: han={:x}\n", han + ); + return detail::dispatch(msg, han, from_node, cont); +} + }} /* end namespace vt::objgroup */ #endif /*INCLUDED_VT_OBJGROUP_MANAGER_STATIC_H*/ diff --git a/src/vt/objgroup/proxy/proxy_objgroup.h b/src/vt/objgroup/proxy/proxy_objgroup.h index 704993db8b..b235bdcf95 100644 --- a/src/vt/objgroup/proxy/proxy_objgroup.h +++ b/src/vt/objgroup/proxy/proxy_objgroup.h @@ -58,6 +58,7 @@ #include "vt/rdmahandle/handle.fwd.h" #include "vt/rdmahandle/handle_set.fwd.h" #include "vt/messaging/pending_send.h" +#include "vt/utils/fntraits/fntraits.h" namespace vt { namespace objgroup { namespace proxy { @@ -126,6 +127,21 @@ struct Proxy { template fn> PendingSendType broadcastMsg(messaging::MsgPtrThief msg) const; + /** + * \brief Broadcast a message to all nodes to be delivered to the local object + * instance + * \note Takes ownership of the supplied message + * + * \param[in] msg the message + */ + template + PendingSendType broadcastMsg( + messaging::MsgPtrThief::MsgT> msg + ) const { + using MsgType = typename ObjFuncTraits::MsgT; + return broadcastMsg(msg); + } + /** * \brief Broadcast a message to all nodes to be delivered to the local object * instance @@ -135,6 +151,15 @@ struct Proxy { template fn, typename... Args> PendingSendType broadcast(Args&&... args) const; + /** + * \brief Broadcast a message to all nodes to be delivered to the local object + * instance + * + * \param[in] args args to pass to the message constructor + */ + template + PendingSendType broadcast(Args&&... args) const; + /** * \brief Reduce over the objgroup instances on each node with a callback * target. @@ -154,6 +179,7 @@ struct Proxy { PendingSendType reduce( MsgPtrT msg, Callback cb, ReduceStamp stamp = ReduceStamp{} ) const; + template < typename OpT = collective::None, typename MsgPtrT, @@ -161,16 +187,15 @@ struct Proxy { > PendingSendType reduce( MsgPtrT msg, Callback cb, ReduceStamp stamp = ReduceStamp{} - ) const - { + ) const { return reduce< OpT, MsgPtrT, MsgT, &MsgT::template msgHandler< MsgT, OpT, collective::reduce::operators::ReduceCallback - > - >(msg, cb, stamp); + > + >(msg, cb, stamp); } /** @@ -370,6 +395,21 @@ struct Proxy { template * f, typename... Args> messaging::PendingSend broadcast(Args&&... args) const; + /** + * \brief Broadcast a message. + * + * \note Creates message from given args + * + * \param[in] args the arguments used to make a message + * + * \return the \c PendingSend for the sent message + */ + template + messaging::PendingSend broadcast(Args&&... args) const { + using MsgType = typename FuncTraits::MsgT; + return broadcast(std::forward(args)...); + } + /** * \brief Broadcast a message. * @@ -384,6 +424,25 @@ struct Proxy { messaging::PendingSend broadcastMsg(messaging::MsgPtrThief msg, TagType tag = no_tag) const; + /** + * \brief Broadcast a message. + * + * \note Takes ownership of the supplied message. + * + * \param[in] msg the message to broadcast + * \param[in] tag the tag to put on the message + * + * \return the \c PendingSend for the sent message + */ + template + messaging::PendingSend broadcastMsg( + messaging::MsgPtrThief::MsgT> msg, + TagType tag = no_tag + ) const { + using MsgType = typename FuncTraits::MsgT; + return broadcastMsg(msg, tag); + } + /** * \brief Reduce a message up the tree, possibly delayed through a pending * send diff --git a/src/vt/objgroup/proxy/proxy_objgroup.impl.h b/src/vt/objgroup/proxy/proxy_objgroup.impl.h index 78a9b30ece..46cf20ad69 100644 --- a/src/vt/objgroup/proxy/proxy_objgroup.impl.h +++ b/src/vt/objgroup/proxy/proxy_objgroup.impl.h @@ -52,6 +52,8 @@ #include "vt/collective/reduce/operators/default_op.h" #include "vt/pipe/callback/cb_union/cb_raw_base.h" #include "vt/rdmahandle/manager.h" +#include "vt/messaging/param_msg.h" +#include "vt/objgroup/proxy/proxy_bits.h" namespace vt { namespace objgroup { namespace proxy { @@ -82,6 +84,29 @@ typename Proxy::PendingSendType Proxy::broadcast(Args&&... args) con return broadcastMsg(makeMessage(std::forward(args)...)); } +template +template +typename Proxy::PendingSendType +Proxy::broadcast(Params&&... params) const { + using MsgT = typename ObjFuncTraits::MsgT; + if constexpr (std::is_same_v) { + using Tuple = typename ObjFuncTraits::TupleType; + using SendMsgT = messaging::ParamMsg; + auto msg = vt::makeMessage(std::forward(params)...); + auto const ctrl = proxy::ObjGroupProxy::getID(proxy_); + auto const han = auto_registry::makeAutoHandlerObjGroupParam< + ObjT, decltype(f), f, SendMsgT + >(ctrl); + return theObjGroup()->broadcast(msg, han); + } else { + auto msg = makeMessage(std::forward(params)...); + return broadcastMsg(msg); + } + + // Silence nvcc warning (no longer needed for CUDA 11.7 and up) + return typename Proxy::PendingSendType{std::nullptr_t{}}; +} + template template < typename OpT, typename MsgPtrT, typename MsgT, ActiveTypedFnType *f @@ -217,7 +242,7 @@ messaging::PendingSend Proxy::broadcast(Args&&... args) const { template * f> messaging::PendingSend Proxy::broadcastMsg(messaging::MsgPtrThief msg, TagType tag) const { - return theMsg()->broadcastMsg(msg, true, tag); + return theMsg()->broadcastMsg(msg, true, tag); } template diff --git a/src/vt/objgroup/proxy/proxy_objgroup_elm.h b/src/vt/objgroup/proxy/proxy_objgroup_elm.h index 967a3c3790..812de35633 100644 --- a/src/vt/objgroup/proxy/proxy_objgroup_elm.h +++ b/src/vt/objgroup/proxy/proxy_objgroup_elm.h @@ -51,6 +51,7 @@ #include "vt/messaging/message/smart_ptr.h" #include "vt/activefn/activefn.h" #include "vt/messaging/pending_send.fwd.h" +#include "vt/utils/fntraits/fntraits.h" namespace vt { namespace objgroup { namespace proxy { @@ -120,6 +121,21 @@ struct ProxyElm { template fn> PendingSendType sendMsg(messaging::MsgPtrThief msg) const; + /** + * \brief Send a message to the node/element indexed by this proxy to be + * delivered to the local object instance + * \note Takes ownership of the supplied message + * + * \param[in] msg the message + */ + template + decltype(auto) sendMsg( + messaging::MsgPtrThief::MsgT> msg + ) const { + using MsgT = typename ObjFuncTraits::MsgT; + return sendMsg(msg); + } + /** * \brief Send a message to the node/element indexed by this proxy to be * delivered to the local object instance @@ -129,6 +145,15 @@ struct ProxyElm { template fn, typename... Args> PendingSendType send(Args&&... args) const; + /** + * \brief Send a message to the node/element indexed by this proxy to be + * delivered to the local object instance + * + * \param[in] args args to pass to the message constructor + */ + template + PendingSendType send(Args&&... args) const; + /** * \brief Invoke locally a message handler on the node/element indexed by this proxy. * The message handler will be invoked inline without going through scheduler @@ -136,7 +161,7 @@ struct ProxyElm { * \param[in] args args to pass to the message constructor */ template fn, typename... Args> - void invoke(Args&&... args) const; + decltype(auto) invoke(Args&&... args) const; /** * \brief Invoke locally a function 'f' on the node/element indexed by this proxy. @@ -144,7 +169,7 @@ struct ProxyElm { * * \param[in] args function arguments */ - template + template decltype(auto) invoke(Args&&... args) const; /** @@ -213,6 +238,18 @@ struct ProxyElm { template * f, typename... Args> void send(Args&&... args) const; + /** + * \brief Send a message to the node indexed by this proxy to be + * delivered to the local object instance + * + * \param[in] args args to pass to the message constructor + */ + template + void send(Args&&... args) const { + using MsgT = typename FuncTraits::MsgT; + send(std::forward(args)...); + } + private: NodeType node_ = uninitialized_destination; /**< The indexed node */ }; diff --git a/src/vt/objgroup/proxy/proxy_objgroup_elm.impl.h b/src/vt/objgroup/proxy/proxy_objgroup_elm.impl.h index 2a97f6d4d5..dccd7b4f09 100644 --- a/src/vt/objgroup/proxy/proxy_objgroup_elm.impl.h +++ b/src/vt/objgroup/proxy/proxy_objgroup_elm.impl.h @@ -78,23 +78,47 @@ typename ProxyElm::PendingSendType ProxyElm::send(Args&&... args) co } template -template fn, typename... Args> -void ProxyElm::invoke(Args&&... args) const { +template +typename ProxyElm::PendingSendType +ProxyElm::send(Params&&... params) const { + using MsgT = typename ObjFuncTraits::MsgT; + if constexpr (std::is_same_v) { + using Tuple = typename ObjFuncTraits::TupleType; + using SendMsgT = messaging::ParamMsg; + auto msg = vt::makeMessage(std::forward(params)...); + auto const ctrl = proxy::ObjGroupProxy::getID(proxy_); + auto const han = auto_registry::makeAutoHandlerObjGroupParam< + ObjT, decltype(f), f, SendMsgT + >(ctrl); + return theObjGroup()->send(msg, han, node_); + } else { + auto msg = makeMessage(std::forward(params)...); + return sendMsg(msg); + } + + // Silence nvcc warning (no longer needed for CUDA 11.7 and up) + return ProxyElm::PendingSendType{std::nullptr_t{}}; +} + +template +template f, typename... Args> +decltype(auto) ProxyElm::invoke(Args&&... args) const { auto proxy = ProxyElm(*this); - theObjGroup()->invoke( - proxy, makeMessage(std::forward(args)...) - ); + auto msg = makeMessage(std::forward(args)...); + return theObjGroup()->invoke(proxy, msg); } template -template -decltype(auto) ProxyElm::invoke( - Args&&... args -) const -{ +template +decltype(auto) ProxyElm::invoke(Args&&... args) const { auto proxy = ProxyElm(*this); - return theObjGroup()->invoke( - proxy, std::forward(args)...); + using MsgT = typename ObjFuncTraits::MsgT; + if constexpr (std::is_same_v) { + return theObjGroup()->invoke(proxy, std::forward(args)...); + } else { + auto msg = makeMessage(std::forward(args)...); + return theObjGroup()->invoke(proxy, msg); + } } template @@ -120,7 +144,7 @@ inline ProxyElm::ProxyElm(NodeType in_node) : node_{in_node} {} template * f, typename... Args> void ProxyElm::send(Args&&... args) const { - vt::theMsg()->sendMsg( + vt::theMsg()->sendMsg( node_, vt::makeMessage(std::forward(args)...)); } diff --git a/src/vt/parameterization/param_meta.h b/src/vt/parameterization/param_meta.h deleted file mode 100644 index ef556e5dff..0000000000 --- a/src/vt/parameterization/param_meta.h +++ /dev/null @@ -1,95 +0,0 @@ -/* -//@HEADER -// ***************************************************************************** -// -// param_meta.h -// DARMA/vt => Virtual Transport -// -// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC -// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. -// Government retains certain rights in this software. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Questions? Contact darma@sandia.gov -// -// ***************************************************************************** -//@HEADER -*/ - -#if !defined INCLUDED_VT_PARAMETERIZATION_PARAM_META_H -#define INCLUDED_VT_PARAMETERIZATION_PARAM_META_H - -#include "vt/config.h" - -#include -#include -#include -#include - -namespace vt { namespace param { - -template -using MultiParamType = void(*)(Args...); - -template -struct NonType {}; - -#define PARAM_FUNCTION_RHS(value) vt::param::NonType() -#define PARAM_FUNCTION(value) decltype(&value),(&value) - -template -auto callFnTuple(Function f, Tuple t, std::index_sequence) { - return f( - std::forward::type>( - std::get(t) - )... - ); -} - -template -void invokeFnTuple(TypedFnT f, std::tuple t) { - using TupleType = std::tuple; - callFnTuple(f, std::forward(t), std::make_index_sequence{}); -} - -template -void invokeCallableTuple(std::tuple& tup, FnT fn, bool const& is_functor) { - using TupleType = typename std::decay::type; - static constexpr auto size = std::tuple_size::value; - if (is_functor) { - auto typed_fn = reinterpret_cast>(fn); - return invokeFnTuple(typed_fn, tup); - } else { - auto typed_fn = reinterpret_cast>(fn); - return invokeFnTuple(typed_fn, tup); - } -} - -}} /* end namespace vt::param */ - -#endif /*INCLUDED_VT_PARAMETERIZATION_PARAM_META_H*/ diff --git a/src/vt/parameterization/parameterization.cc b/src/vt/parameterization/parameterization.cc deleted file mode 100644 index 379db2ac0c..0000000000 --- a/src/vt/parameterization/parameterization.cc +++ /dev/null @@ -1,48 +0,0 @@ -/* -//@HEADER -// ***************************************************************************** -// -// parameterization.cc -// DARMA/vt => Virtual Transport -// -// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC -// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. -// Government retains certain rights in this software. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Questions? Contact darma@sandia.gov -// -// ***************************************************************************** -//@HEADER -*/ - -#include "vt/parameterization/parameterization.h" - -namespace vt { namespace param { - -}} //end namespace vt::param diff --git a/src/vt/parameterization/parameterization.h b/src/vt/parameterization/parameterization.h deleted file mode 100644 index eb0fa73191..0000000000 --- a/src/vt/parameterization/parameterization.h +++ /dev/null @@ -1,280 +0,0 @@ -/* -//@HEADER -// ***************************************************************************** -// -// parameterization.h -// DARMA/vt => Virtual Transport -// -// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC -// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. -// Government retains certain rights in this software. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Questions? Contact darma@sandia.gov -// -// ***************************************************************************** -//@HEADER -*/ - -#if !defined INCLUDED_VT_PARAMETERIZATION_PARAMETERIZATION_H -#define INCLUDED_VT_PARAMETERIZATION_PARAMETERIZATION_H - -#include "vt/config.h" -#include "vt/messaging/message.h" -#include "vt/messaging/active.h" -#include "vt/registry/auto/auto_registry_interface.h" -#include "vt/utils/static_checks/all_true.h" -#include "vt/parameterization/param_meta.h" -#include "vt/runtime/component/component_pack.h" - -#include -#include -#include -#include - -namespace vt { namespace param { - -using namespace ::vt::util; - -using HandlerManagerType = vt::HandlerManager; - -template -struct DataMsg : vt::Message { - using MessageParentType = vt::Message; - vt_msg_serialize_if_needed_by_parent_or_type1(Tuple); // by tup - - Tuple tup; - HandlerType sub_han = uninitialized_handler; - - DataMsg() = default; - DataMsg(HandlerType const in_sub_han, Tuple&& a) - : Message(), tup(std::forward(a)), sub_han(in_sub_han) - { } - - template - DataMsg(HandlerType const in_sub_han, Args&&... a) - : Message(), tup(std::forward(a)...), sub_han(in_sub_han) - { } - - template - void serialize(SerializerT& s) { - MessageParentType::serialize(s); - s | tup; - s | sub_han; - } -}; - - -template -static void dataMessageHandler(DataMsg* msg) { - vt_debug_print( - normal, param, - "dataMessageHandler: id={}\n", msg->sub_han - ); - -#if vt_check_enabled(trace_enabled) - trace::TraceProcessingTag processing_tag; - { - trace::TraceEntryIDType ep = auto_registry::handlerTraceID(msg->sub_han); - trace::TraceEventIDType event = envelopeGetTraceEvent(msg->env); - - size_t msg_size = sizeof(*msg); - NodeType const& from_node = theContext()->getFromNodeCurrentTask(); - - processing_tag = - theTrace()->beginProcessing(ep, msg_size, event, from_node); - } -#endif - - if (HandlerManagerType::isHandlerFunctor(msg->sub_han)) { - auto const& fn = auto_registry::getAutoHandlerFunctor(msg->sub_han); - invokeCallableTuple(msg->tup, fn, true); - } else { - // regular active function - auto const& fn = auto_registry::getAutoHandler(msg->sub_han); - invokeCallableTuple(msg->tup, fn, false); - } - -#if vt_check_enabled(trace_enabled) - theTrace()->endProcessing(processing_tag); -#endif -} - -/** - * \struct Param - * - * \brief An experimental component for parameterizing handlers. - * - * Clean support for parameterization does not exist until C++17. This component - * is an attempt at parameterizing for C++14 with non-type templates. - * - * \warning This is an experimental component. - */ -struct Param : runtime::component::Component { - - std::string name() override { return "Param"; } - - template - void sendDataTuple( - NodeType const& dest, HandlerType const han, std::tuple&& tup - ) { - staticCheckCopyable(); - - using TupleType = typename std::decay::type; - - auto m = makeMessage>( - han, std::forward>(tup) - ); - theMsg()->sendMsg, dataMessageHandler>(dest, m); - } - - template - void staticCheckCopyable() { - using cond = all_true::value...>; - - static_assert( - std::is_same::value == true, - "All types passed for parameterization must be trivially copyable" - ); - } - - template - void sendDataMsg( - NodeType const& dest, HandlerType const __attribute__((unused)) han, - MsgSharedPtr m - ) { - auto pmsg = promoteMsg(m.get()); - theMsg()->sendMsg(dest, pmsg); - } - - template - void sendData( - NodeType const& dest, Tuple tup, - NonType __attribute__((unused)) non = NonType() - ) { - auto const& han = auto_registry::makeAutoHandlerParam(); - sendDataTuple(dest, han, std::forward(tup)); - } - - template - void sendData( - NodeType const& dest, MsgSharedPtr>> msg, - NonType __attribute__((unused)) non = NonType() - ) { - auto const& han = auto_registry::makeAutoHandlerParam(); - msg->sub_han = han; - sendDataMsg(dest, han, msg); - } - - template - void sendData( - NodeType const& dest, NonType __attribute__((unused)) non, - Args&&... a - ) { - auto const& han = auto_registry::makeAutoHandlerParam(); - - staticCheckCopyable(); - - using TupleType = std::tuple; - - auto m = makeMessage>(han, std::forward(a)...); - sendDataMsg(dest, han, m); - } - - template - void sendData(NodeType const& dest, Args&&... a) { - sendData(dest, NonType(), std::forward(a)...); - } - - /* - * Functor variants - */ - - template - void sendDataHelperFunctor( - NodeType const& dest, std::tuple&& tup - ) { - auto const& han = auto_registry::makeAutoHandlerFunctor< - FunctorT, false, Args... - >(); - sendDataTuple(dest, han, std::forward>(tup)); - } - - template - void sendData(NodeType const& dest, Tuple tup) { - sendDataHelperFunctor(dest, std::forward(tup)); - } - - template - void sendData( - NodeType const& dest, MsgSharedPtr>> msg - ) { - staticCheckCopyable(); - - auto const& han = auto_registry::makeAutoHandlerFunctor< - FunctorT, false, Args... - >(); - msg->sub_han = han; - - sendDataMsg(dest, han, msg); - } - - template - void sendData(NodeType const& dest, Args&&... a) { - staticCheckCopyable(); - - auto const& han = auto_registry::makeAutoHandlerFunctor< - FunctorT, false, Args... - >(); - - using TupleType = std::tuple; - - auto m = makeMessage>(han, std::forward(a)...); - sendDataMsg(dest, han, m); - } - - template - void serialize(Serializer&) {} -}; - -}} //end namespace vt::param - -namespace vt { - -extern param::Param* theParam(); - -template -MsgSharedPtr>> buildData(Args&&... a) { - return makeMessage>>( - uninitialized_handler, std::forward(a)... - ); -} - -} //end namespace vt - -#endif /*INCLUDED_VT_PARAMETERIZATION_PARAMETERIZATION_H*/ diff --git a/src/vt/pipe/callback/anon/callback_anon.impl.h b/src/vt/pipe/callback/anon/callback_anon.impl.h index 83a84f7dd1..04378a0a29 100644 --- a/src/vt/pipe/callback/anon/callback_anon.impl.h +++ b/src/vt/pipe/callback/anon/callback_anon.impl.h @@ -80,7 +80,7 @@ CallbackAnon::triggerDispatch(SignalDataType* data, PipeType const& pid) { triggerPipe(pid); } else { auto msg = makeMessage(pid); - theMsg()->sendMsg(pipe_node, msg); + theMsg()->sendMsg(pipe_node, msg); } } @@ -105,7 +105,7 @@ CallbackAnon::triggerDispatch(SignalDataType* data, PipeType const& pid) { */ setPipeType(data->env); envelopeSetGroup(data->env,pid); - theMsg()->sendMsg(pipe_node, data); + theMsg()->sendMsg(pipe_node, data); } } diff --git a/src/vt/pipe/callback/anon/callback_anon_tl.cc b/src/vt/pipe/callback/anon/callback_anon_tl.cc index dc2b2aab8a..02f76bb1c0 100644 --- a/src/vt/pipe/callback/anon/callback_anon_tl.cc +++ b/src/vt/pipe/callback/anon/callback_anon_tl.cc @@ -65,7 +65,7 @@ void CallbackAnonTypeless::triggerVoid(PipeType const& pipe) { theCB()->triggerPipe(pipe); } else { auto msg = makeMessage(pipe,true); - theMsg()->sendMsg(pipe_node, msg); + theMsg()->sendMsg(pipe_node, msg); } } diff --git a/src/vt/pipe/callback/callback_handler_bcast.h b/src/vt/pipe/callback/callback_handler_bcast.h index 411042b205..b53e5cdf03 100644 --- a/src/vt/pipe/callback/callback_handler_bcast.h +++ b/src/vt/pipe/callback/callback_handler_bcast.h @@ -62,7 +62,7 @@ struct CallbackBcast : CallbackBase> { private: void trigger_(SignalDataType* data) override { - theMsg()->broadcastMsg(data); + theMsg()->broadcastMsg(data); } }; diff --git a/src/vt/pool/header/pool_header.cc b/src/vt/pool/header/pool_header.cc index a85329a92b..fd0ff7cdf6 100644 --- a/src/vt/pool/header/pool_header.cc +++ b/src/vt/pool/header/pool_header.cc @@ -54,7 +54,6 @@ namespace vt { namespace pool { view.buffer = buffer; view.layout->prealloc.alloc_size = num_bytes; view.layout->prealloc.oversize = oversize; - view.layout->prealloc.alloc_worker = theContext()->getWorker(); auto buf_start = buffer + sizeof(Header); return buf_start; } @@ -71,12 +70,6 @@ namespace vt { namespace pool { return view.layout->prealloc.oversize; } -/*static*/ WorkerIDType HeaderManager::getHeaderWorker(char* buffer) { - AllocView view; - view.buffer = buffer - sizeof(Header); - return view.layout->prealloc.alloc_worker; -} - /*static*/ char* HeaderManager::getHeaderPtr(char* buffer) { return buffer - sizeof(Header); } diff --git a/src/vt/pool/header/pool_header.h b/src/vt/pool/header/pool_header.h index e0d5ea65f6..fbba10a23f 100644 --- a/src/vt/pool/header/pool_header.h +++ b/src/vt/pool/header/pool_header.h @@ -49,7 +49,6 @@ namespace vt { namespace pool { struct Header { - WorkerIDType alloc_worker; size_t alloc_size; size_t oversize; }; @@ -69,7 +68,6 @@ struct HeaderManager { ); static size_t getHeaderBytes(char* buffer); static size_t getHeaderOversizeBytes(char* buffer); - static WorkerIDType getHeaderWorker(char* buffer); static char* getHeaderPtr(char* buffer); }; diff --git a/src/vt/pool/pool.cc b/src/vt/pool/pool.cc index 31195a7cb7..98a6c7aaa7 100644 --- a/src/vt/pool/pool.cc +++ b/src/vt/pool/pool.cc @@ -43,7 +43,6 @@ #include "vt/config.h" #include "vt/pool/pool.h" -#include "vt/worker/worker_headers.h" #include "vt/pool/static_sized/memory_pool_equal.h" #include @@ -107,29 +106,19 @@ bool Pool::tryPooledDealloc(void* const buf) { void* Pool::pooledAlloc( size_t const& num_bytes, size_t const& oversize, ePoolSize const pool_type ) { - auto const worker = theContext()->getWorker(); - bool const comm_thread = worker == worker_id_comm_thread; void* ret = nullptr; vt_debug_print( normal, pool, - "Pool::pooled_alloc of size={}, type={}, ret={}, worker={}\n", - num_bytes, print_pool_type(pool_type), ret, worker + "Pool::pooled_alloc of size={}, type={}, ret={}\n", + num_bytes, print_pool_type(pool_type), ret ); if (pool_type == ePoolSize::Small) { - auto pool = comm_thread ? small_msg.get() : s_msg_worker_[worker].get(); - vtAssert( - (comm_thread || s_msg_worker_.size() > static_cast(worker)), - "Must have worker pool" - ); + auto pool = small_msg.get(); ret = pool->alloc(num_bytes, oversize); } else if (pool_type == ePoolSize::Medium) { - auto pool = comm_thread ? medium_msg.get() : m_msg_worker_[worker].get(); - vtAssert( - (comm_thread || m_msg_worker_.size() > static_cast(worker)), - "Must have worker pool" - ); + auto pool = medium_msg.get(); ret = pool->alloc(num_bytes, oversize); } else { vtAssert(0, "Pool must be valid"); @@ -191,31 +180,14 @@ void* Pool::alloc(size_t const& num_bytes, size_t oversize) { void Pool::dealloc(void* const buf) { auto buf_char = static_cast(buf); auto const& actual_alloc_size = HeaderManagerType::getHeaderBytes(buf_char); - auto const& alloc_worker = HeaderManagerType::getHeaderWorker(buf_char); auto const& ptr_actual = HeaderManagerType::getHeaderPtr(buf_char); - auto const& oversize = HeaderManagerType::getHeaderOversizeBytes(buf_char); - auto const worker = theContext()->getWorker(); - - ePoolSize const pool_type = getPoolType(actual_alloc_size, oversize); vt_debug_print( normal, pool, - "Pool::dealloc of buf={}, type={}, alloc_size={}, worker={}, ptr={}\n", - buf, print_pool_type(pool_type), actual_alloc_size, alloc_worker, - print_ptr(ptr_actual) + "Pool::dealloc of buf={}, alloc_size={}, ptr={}\n", + buf, actual_alloc_size, print_ptr(ptr_actual) ); - if (pool_type != ePoolSize::Malloc && alloc_worker != worker) { - #if vt_threading_enabled - theWorkerGrp()->enqueueForWorker(worker, [buf]{ - thePool()->dealloc(buf); - }); - #else - thePool()->dealloc(buf); - #endif - return; - } - bool success = false; #if vt_check_enabled(memory_pool) @@ -264,22 +236,6 @@ Pool::tryGrowAllocation(void* buf, size_t grow_amount) { return true; } -void Pool::initWorkerPools(WorkerCountType const& num_workers) { - #if vt_check_enabled(memory_pool) - for (auto i = 0; i < num_workers; i++) { - s_msg_worker_.emplace_back(initSPool()); - m_msg_worker_.emplace_back(initMPool()); - } - #endif -} - -void Pool::finalize() { - #if vt_check_enabled(memory_pool) - s_msg_worker_.clear(); - m_msg_worker_.clear(); - #endif -} - bool Pool::active() const { return vt_check_enabled(memory_pool); } diff --git a/src/vt/pool/pool.h b/src/vt/pool/pool.h index 885b9af498..3983bedf43 100644 --- a/src/vt/pool/pool.h +++ b/src/vt/pool/pool.h @@ -174,26 +174,10 @@ struct Pool : runtime::component::Component { */ bool active_env() const; - /** - * \brief Initialize worker-specific pools due to the lack of thread-safety of - * the memory allocator. This will create distinct memory pool instances for - * each worker thread to access - * - * \param[in] num_workers number of workers on this node - */ - void initWorkerPools(WorkerCountType const& num_workers); - - /** - * \brief Cleanup/free the memory pools - */ - void finalize() override; - template void serialize(SerializerT& s) { s | small_msg - | medium_msg - | s_msg_worker_ - | m_msg_worker_; + | medium_msg; } private: @@ -265,9 +249,6 @@ struct Pool : runtime::component::Component { private: MemPoolSType small_msg = nullptr; MemPoolMType medium_msg = nullptr; - - std::vector s_msg_worker_; - std::vector m_msg_worker_; }; }} //end namespace vt::pool diff --git a/src/vt/pool/static_sized/memory_pool_equal.cc b/src/vt/pool/static_sized/memory_pool_equal.impl.h similarity index 95% rename from src/vt/pool/static_sized/memory_pool_equal.cc rename to src/vt/pool/static_sized/memory_pool_equal.impl.h index 1b997777bb..47979cf821 100644 --- a/src/vt/pool/static_sized/memory_pool_equal.cc +++ b/src/vt/pool/static_sized/memory_pool_equal.impl.h @@ -2,7 +2,7 @@ //@HEADER // ***************************************************************************** // -// memory_pool_equal.cc +// memory_pool_equal.impl.h // DARMA/vt => Virtual Transport // // Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC @@ -41,6 +41,9 @@ //@HEADER */ +#if !defined INCLUDED_VT_POOL_STATIC_SIZED_MEMORY_POOL_EQUAL_IMPL_H +#define INCLUDED_VT_POOL_STATIC_SIZED_MEMORY_POOL_EQUAL_IMPL_H + #include "vt/config.h" #include "vt/pool/static_sized/memory_pool_equal.h" #include "vt/pool/header/pool_header.h" @@ -152,3 +155,5 @@ template struct MemoryPoolEqual; template struct MemoryPoolEqual; }} //end namespace vt::pool + +#endif /*INCLUDED_VT_POOL_STATIC_SIZED_MEMORY_POOL_EQUAL_IMPL_H*/ diff --git a/src/vt/rdma/collection/rdma_collection.cc b/src/vt/rdma/collection/rdma_collection.cc index 04085d3c83..c8565a1b9a 100644 --- a/src/vt/rdma/collection/rdma_collection.cc +++ b/src/vt/rdma/collection/rdma_collection.cc @@ -125,7 +125,7 @@ namespace vt { namespace rdma { if (tag != no_tag) { envelopeSetTag(msg->env, tag); } - theMsg()->sendMsg( + theMsg()->sendMsg( default_node, msg ); diff --git a/src/vt/rdma/rdma.cc b/src/vt/rdma/rdma.cc index d451bc8eda..522bec52f3 100644 --- a/src/vt/rdma/rdma.cc +++ b/src/vt/rdma/rdma.cc @@ -187,7 +187,7 @@ RDMAManager::RDMAManager() ); if (send_back != uninitialized_destination) { auto new_msg = makeMessage(op_id); - theMsg()->sendMsg(send_back, new_msg); + theMsg()->sendMsg(send_back, new_msg); } }, false, recv_node ); @@ -228,7 +228,7 @@ RDMAManager::RDMAManager() ); if (send_back != uninitialized_destination) { auto new_msg = makeMessage(op_id); - theMsg()->sendMsg( + theMsg()->sendMsg( send_back, new_msg ); } @@ -250,7 +250,7 @@ RDMAManager::RDMAManager() ); if (send_back) { auto new_msg = makeMessage(op_id); - theMsg()->sendMsg( + theMsg()->sendMsg( send_back, new_msg ); } @@ -669,7 +669,7 @@ void RDMAManager::putData( envelopeSetTag(msg->env, tag); } - theMsg()->sendMsg( + theMsg()->sendMsg( put_node, msg, no_tag ); @@ -965,7 +965,7 @@ void RDMAManager::getDataIntoBuf( if (tag != no_tag) { envelopeSetTag(msg->env, tag); } - theMsg()->sendMsg(getNode, msg); + theMsg()->sendMsg(getNode, msg); pending_ops_.emplace( std::piecewise_construct, @@ -1002,7 +1002,7 @@ void RDMAManager::getData( if (tag != no_tag) { envelopeSetTag(msg->env, tag); } - theMsg()->sendMsg(getNode, msg); + theMsg()->sendMsg(getNode, msg); pending_ops_.emplace( std::piecewise_construct, @@ -1095,7 +1095,7 @@ void RDMAManager::setupChannelWithRemote( auto msg = makeMessage( type, han, num_bytes, tag, cb, dest, override_target ); - theMsg()->sendMsg(other_node, msg); + theMsg()->sendMsg(other_node, msg); return createDirectChannelInternal( type, han, dest, nullptr, target, tag, num_bytes @@ -1295,7 +1295,7 @@ void RDMAManager::createDirectChannelInternal( auto msg = makeMessage( type, han, unique_channel_tag, target, this_node, cb ); - theMsg()->sendMsg(target, msg); + theMsg()->sendMsg(target, msg); } else { return createDirectChannelFinish( type, han, non_target, action, channel_tag, is_target, num_bytes, @@ -1337,7 +1337,7 @@ void RDMAManager::removeDirectChannel( auto msg = makeMessage( RDMA_TypeType::Get, han, no_byte, no_tag, cb ); - theMsg()->sendMsg(target, msg); + theMsg()->sendMsg(target, msg); } else { auto iter = channels_.find( makeChannelLookup(han,RDMA_TypeType::Get,target,this_node) diff --git a/src/vt/rdma/state/rdma_state.cc b/src/vt/rdma/state/rdma_state.cc index 72f39b226b..bd8190d48b 100644 --- a/src/vt/rdma/state/rdma_state.cc +++ b/src/vt/rdma/state/rdma_state.cc @@ -261,7 +261,7 @@ void State::getData( size_t msg_size = info.num_bytes; processing_tag = - theTrace()->beginProcessing(trace_id, msg_size, event, from_node); + theTrace()->beginProcessing(trace_id, msg_size, event, from_node, timing::getCurrentTime()); } #endif @@ -280,7 +280,7 @@ void State::getData( } #if vt_check_enabled(trace_enabled) - theTrace()->endProcessing(processing_tag); + theTrace()->endProcessing(processing_tag, timing::getCurrentTime()); #endif } else { pending_tag_gets[tag].push_back(info); @@ -328,7 +328,7 @@ void State::putData( size_t msg_size = info.num_bytes; processing_tag = - theTrace()->beginProcessing(trace_id, msg_size, event, from_node); + theTrace()->beginProcessing(trace_id, msg_size, event, from_node, timing::getCurrentTime()); } #endif @@ -346,7 +346,7 @@ void State::putData( } #if vt_check_enabled(trace_enabled) - theTrace()->endProcessing(processing_tag); + theTrace()->endProcessing(processing_tag, timing::getCurrentTime()); #endif } else { pending_tag_puts[tag].push_back(info); diff --git a/src/vt/registry/auto/auto_registry.h b/src/vt/registry/auto/auto_registry.h index 36362d1bb3..c10320d77a 100644 --- a/src/vt/registry/auto/auto_registry.h +++ b/src/vt/registry/auto/auto_registry.h @@ -62,7 +62,7 @@ namespace vt { namespace auto_registry { AutoActiveType const& getAutoHandler(HandlerType const handler); -AutoActiveObjGroupType getAutoHandlerObjGroup(HandlerType han); +AutoActiveObjGroupType const& getAutoHandlerObjGroup(HandlerType han); AutoHandlerType getAutoHandlerObjTypeIdx(HandlerType han); template f> diff --git a/src/vt/registry/auto/auto_registry_common.h b/src/vt/registry/auto/auto_registry_common.h index d8eb56b66b..a428bbc7a0 100644 --- a/src/vt/registry/auto/auto_registry_common.h +++ b/src/vt/registry/auto/auto_registry_common.h @@ -58,6 +58,13 @@ #include #include +namespace vt::vrt::collection { + +template +struct ColMsgWrap; + +} /* end namespace vt::vrt::collection */ + namespace vt { namespace auto_registry { struct SentinelObject {}; @@ -69,77 +76,61 @@ struct BaseHandlersDispatcher { template struct HandlersDispatcher final : BaseHandlersDispatcher { - explicit HandlersDispatcher(HandlerT in_fn_ptr) : fn_ptr_(in_fn_ptr) { } + using ColTypedFnType = vrt::collection::ActiveColTypedFnType; + using ColMemberTypedFnType = vrt::collection::ActiveColMemberTypedFnType; -private: - template - struct DispatchImpl; - - template - using isActiveVoidFnType = std::enable_if_t< - std::is_same< - T, - ActiveVoidFnType* - >::value - >; - - template - struct DispatchImpl> { - static void run(MsgT*, void*, HandlerT han) { han(); } - }; - - template - using isActiveTypedFnType = std::enable_if_t< - std::is_same< - T, - ActiveTypedFnType* - >::value - >; - - template - struct DispatchImpl> { - static void run(MsgT* msg, void*, HandlerT han) { han(msg); } - }; - - template - using isActiveColTypedFnType = std::enable_if_t< - std::is_same< - T, - vrt::collection::ActiveColTypedFnType* - >::value - >; - - template - struct DispatchImpl> { - static void run(MsgT* msg, void* object, HandlerT han) { - auto elm = static_cast(object); - han(msg, elm); - } - }; - - template - using isActiveColMemberTypedFnType = std::enable_if_t< - std::is_same< - T, - vrt::collection::ActiveColMemberTypedFnType - >::value - >; - - template - struct DispatchImpl> { - static void run(MsgT* msg, void* object, HandlerT han) { - auto elm = static_cast(object); - (elm->*han)(msg); - } - }; + explicit HandlersDispatcher(HandlerT in_fn_ptr) : fp(in_fn_ptr) { } + + template + using ColMsgTrait = typename U::IsCollectionMessage; + template + using IsColMsgTrait = + detection::is_detected_convertible; + + template + using ColTrait = typename U::IsCollectionType; + template + using IsColTrait = + detection::is_detected_convertible; public: - void dispatch(messaging::BaseMsg* msg, void* object) const override { - DispatchImpl::run(static_cast(msg), object, fn_ptr_); + void dispatch(messaging::BaseMsg* base_msg, void* object) const override { + using T = HandlerT; + + [[maybe_unused]] auto msg = static_cast(base_msg); + [[maybe_unused]] auto elm = static_cast(object); + + if constexpr (std::is_same_v) { + fp(); + } else if constexpr (std::is_same_v*>) { + fp(msg); + } else if constexpr (std::is_same_v) { + if constexpr (IsColTrait::value and not IsColMsgTrait::value) { + auto wrap_msg = static_cast< + vrt::collection::ColMsgWrap* + >(base_msg); + fp(elm, &wrap_msg->getMsg()); + } else { + fp(elm, msg); + } + } else if constexpr (std::is_same_v) { + if constexpr (IsColTrait::value and not IsColMsgTrait::value) { + auto wrap_msg = static_cast< + vrt::collection::ColMsgWrap* + >(base_msg); + (elm->*fp)(&wrap_msg->getMsg()); + } else { + (elm->*fp)(msg); + } + } else if constexpr (std::is_same_v) { + std::apply(fp, msg->getTuple()); + } else { + std::apply(fp, std::tuple_cat(std::make_tuple(elm), msg->getTuple())); + } } private: - HandlerT fn_ptr_ = nullptr; + HandlerT fp = nullptr; }; struct BaseMapsDispatcher { @@ -153,31 +144,7 @@ struct BaseMapsDispatcher { template struct MapsDispatcher final : BaseMapsDispatcher { - explicit MapsDispatcher(HandlerT in_fn_ptr) : fn_ptr_(in_fn_ptr) { } - -private: - template - struct DispatchImpl; - - template - using isActiveMapFnPtrType = std::enable_if_t< - std::is_same< - T, - vt::mapping::ActiveMapTypedFnType* - >::value - >; - - template - struct DispatchImpl> { - static NodeType run( - IndexT* cur_idx_ptr, - IndexT* range_ptr, - NodeType num_nodes, - HandlerT han - ) { - return han(cur_idx_ptr, range_ptr, num_nodes); - } - }; + explicit MapsDispatcher(HandlerT in_fn_ptr) : fp(in_fn_ptr) { } public: NodeType dispatch( @@ -185,16 +152,22 @@ struct MapsDispatcher final : BaseMapsDispatcher { index::BaseIndex* range_ptr, NodeType num_nodes ) const override { - return DispatchImpl::run( - static_cast(cur_idx_ptr), - static_cast(range_ptr), - num_nodes, - fn_ptr_ - ); + using T = HandlerT; + + if constexpr (std::is_same_v*>) { + return fp( + static_cast(cur_idx_ptr), + static_cast(range_ptr), + num_nodes + ); + } else { + vtAbort("Invalid function type for map handler"); + return uninitialized_destination; + } } private: - HandlerT fn_ptr_ = nullptr; + HandlerT fp = nullptr; }; struct BaseScatterDispatcher { @@ -204,32 +177,21 @@ struct BaseScatterDispatcher { template struct ScatterDispatcher final : BaseScatterDispatcher { - explicit ScatterDispatcher(HandlerT in_fn_ptr) : fn_ptr_(in_fn_ptr) {} - -private: - template - struct DispatchImpl; - - template - using isActiveTypedFnType = std::enable_if_t< - std::is_same< - T, - ActiveTypedFnType* - >::value - >; - - template - struct DispatchImpl> { - static void run(MsgT* msg, void*, HandlerT han) { han(msg); } - }; + explicit ScatterDispatcher(HandlerT in_fn_ptr) : fp(in_fn_ptr) {} public: - void dispatch(void* msg, void* object) const override { - DispatchImpl::run(static_cast(msg), object, fn_ptr_); + void dispatch(void* msg, void*) const override { + using T = HandlerT; + + if constexpr (std::is_same_v*>) { + fp(static_cast(msg)); + } else { + vtAbort("Invalid function type for scatter handler"); + } } private: - HandlerT fn_ptr_ = nullptr; + HandlerT fp = nullptr; }; using BaseHandlersDispatcherPtr = std::unique_ptr; @@ -241,6 +203,7 @@ using AutoActiveFunctorType = BaseHandlersDispatcherPtr; using AutoActiveVCType = BaseHandlersDispatcherPtr; using AutoActiveCollectionType = BaseHandlersDispatcherPtr; using AutoActiveCollectionMemType = BaseHandlersDispatcherPtr; +using AutoActiveObjGroupType = BaseHandlersDispatcherPtr; using AutoActiveMapType = BaseMapsDispatcherPtr; using AutoActiveMapFunctorType = BaseMapsDispatcherPtr; @@ -248,7 +211,6 @@ using AutoActiveSeedMapType = mapping::ActiveSeedMapFnPtrType; using AutoActiveRDMAGetType = ActiveRDMAGetFnPtrType; using AutoActiveRDMAPutType = ActiveRDMAPutFnPtrType; using AutoActiveIndexType = std::size_t; -using AutoActiveObjGroupType = objgroup::ActiveObjAnyType; using HandlerManagerType = vt::HandlerManager; using AutoHandlerType = HandlerType; diff --git a/src/vt/registry/auto/auto_registry_general.h b/src/vt/registry/auto/auto_registry_general.h index 01d045f266..aec46e5f4a 100644 --- a/src/vt/registry/auto/auto_registry_general.h +++ b/src/vt/registry/auto/auto_registry_general.h @@ -45,6 +45,7 @@ #include "vt/config.h" #include "vt/registry/auto/auto_registry_common.h" +#include "vt/messaging/param_msg.h" #include "vt/utils/demangle/demangle.h" @@ -154,10 +155,11 @@ struct FunctorAdapterArgs { // Need to provide a non-pointer overload for parameterization auto-registered // functions for GCC -template +template struct FunctorAdapterParam { using FunctionPtrType = F; - using ObjType = void; + using ObjType = SentinelObject; + using MsgType = MsgT; static constexpr FunctionPtrType getFunction() { return f; } diff --git a/src/vt/registry/auto/auto_registry_impl.h b/src/vt/registry/auto/auto_registry_impl.h index e4589be686..a36a133697 100644 --- a/src/vt/registry/auto/auto_registry_impl.h +++ b/src/vt/registry/auto/auto_registry_impl.h @@ -54,7 +54,7 @@ namespace vt { namespace auto_registry { -inline AutoActiveObjGroupType getAutoHandlerObjGroup(HandlerType han) { +inline AutoActiveObjGroupType const& getAutoHandlerObjGroup(HandlerType han) { using ContainerType = AutoActiveObjGroupContainerType; auto const id = HandlerManagerType::getHandlerIdentifier(han); @@ -68,10 +68,30 @@ inline AutoHandlerType getAutoHandlerObjTypeIdx(HandlerType han) { return getAutoRegistryGen().at(id).getObjIdx(); } +template +inline HandlerType makeAutoHandlerObjGroupParam(HandlerControlType ctrl) { + using AdapterT = FunctorAdapterMember; + using ContainerType = AutoActiveObjGroupContainerType; + using RegInfoType = AutoRegInfoType; + using FuncType = T; + using RunType = RunnableGen; + + constexpr bool is_auto = true; + constexpr bool is_functor = false; + auto const idx = RunType::idx; + constexpr auto reg_type = RegistryTypeEnum::RegObjGroup; + auto const han = HandlerManagerType::makeHandler( + is_auto, is_functor, idx, reg_type, ctrl + ); + auto obj_idx = objgroup::registry::makeObjIdx(); + getAutoRegistryGen().at(idx).setObjIdx(obj_idx); + return han; +} + template f> inline HandlerType makeAutoHandlerObjGroup(HandlerControlType ctrl) { using AdapterT = - FunctorAdapterMember, f, ObjT>; + FunctorAdapterMember, f, ObjT, MsgT>; using ContainerType = AutoActiveObjGroupContainerType; using RegInfoType = AutoRegInfoType; using FuncType = objgroup::ActiveObjAnyType; @@ -144,9 +164,9 @@ inline BaseScatterDispatcherPtr const& getScatterAutoHandler(HandlerType const h return getAutoRegistryGen().at(han_id).getFun(); } -template +template inline HandlerType makeAutoHandlerParam() { - using AdapterT = FunctorAdapterParam; + using AdapterT = FunctorAdapterParam; using ContainerType = AutoActiveContainerType; using RegInfoType = AutoRegInfoType; using FuncType = ActiveFnPtrType; diff --git a/src/vt/registry/auto/collection/auto_registry_collection.h b/src/vt/registry/auto/collection/auto_registry_collection.h index d025a07646..8436c88ec0 100644 --- a/src/vt/registry/auto/collection/auto_registry_collection.h +++ b/src/vt/registry/auto/collection/auto_registry_collection.h @@ -68,6 +68,9 @@ template < > HandlerType makeAutoHandlerCollectionMem(); +template +HandlerType makeAutoHandlerCollectionMemParam(); + template * f> void setHandlerTraceNameColl(std::string const& name, std::string const& parent = ""); diff --git a/src/vt/registry/auto/collection/auto_registry_collection.impl.h b/src/vt/registry/auto/collection/auto_registry_collection.impl.h index 3c10e40ee8..062241c4ee 100644 --- a/src/vt/registry/auto/collection/auto_registry_collection.impl.h +++ b/src/vt/registry/auto/collection/auto_registry_collection.impl.h @@ -97,6 +97,20 @@ inline HandlerType makeAutoHandlerCollectionMem() { return handler; } +template +inline HandlerType makeAutoHandlerCollectionMemParam() { + using FunctorT = FunctorAdapterMember; + using ContainerType = AutoActiveCollectionMemContainerType; + using RegInfoType = AutoRegInfoType; + using FuncType = T; + + auto const id = + RunnableGen::idx; + constexpr auto reg_type = RegistryTypeEnum::RegVrtCollectionMember; + auto handler = HandlerManager::makeHandler(false, false, id, reg_type); + return handler; +} + template * f> void setHandlerTraceNameColl(std::string const& name, std::string const& parent) { #if vt_check_enabled(trace_enabled) diff --git a/src/vt/runnable/invoke.h b/src/vt/runnable/invoke.h index 7e494ab1d5..9c0596699d 100644 --- a/src/vt/runnable/invoke.h +++ b/src/vt/runnable/invoke.h @@ -140,12 +140,12 @@ static trace::TraceProcessingTag BeginProcessingInvokeEvent() { const auto trace_event = theTrace()->messageCreation(trace_id, 0); const auto from_node = theContext()->getNode(); - return theTrace()->beginProcessing(trace_id, 0, trace_event, from_node); + return theTrace()->beginProcessing(trace_id, 0, trace_event, from_node, timing::getCurrentTime()); } template static void EndProcessingInvokeEvent(trace::TraceProcessingTag processing_tag) { - theTrace()->endProcessing(processing_tag); + theTrace()->endProcessing(processing_tag, timing::getCurrentTime()); const auto trace_id = CallableWrapper::GetTraceID(); theTrace()->messageCreation(trace_id, 0); diff --git a/src/vt/runnable/make_runnable.h b/src/vt/runnable/make_runnable.h index 283b4eca0d..e3b713b83e 100644 --- a/src/vt/runnable/make_runnable.h +++ b/src/vt/runnable/make_runnable.h @@ -78,7 +78,6 @@ struct RunnableMaker { ) : impl_(in_impl), msg_(in_msg), handler_(in_handler), - is_void_(in_msg == nullptr), from_node_(in_from_node), has_msg_(in_msg != nullptr) { } @@ -92,7 +91,9 @@ struct RunnableMaker { * \param[in] cont the continuation */ RunnableMaker&& withContinuation(ActionType cont) { - impl_->addContextCont(cont); + if (cont != nullptr) { + impl_->addContextCont(cont); + } return std::move(*this); } @@ -157,6 +158,20 @@ struct RunnableMaker { return std::move(*this); } + /** + * \brief Add an objgroup; sets up the handler + * + * \param[in] elm the collection element pointer + */ + template + RunnableMaker&& withObjGroup(ElmT* elm) { + set_handler_ = true; + if (handler_ != uninitialized_handler) { + impl_->setupHandlerObjGroup(elm, handler_); + } + return std::move(*this); + } + /** * \brief Add LB data for instrumentation * @@ -255,21 +270,31 @@ struct RunnableMaker { is_done_ = true; } + /** + * \brief Run the runnable immediately with a lambda + */ + template + auto runLambda(Callable&& c, Args&&... args) { + setup(); + auto local_impl = std::unique_ptr(impl_); + impl_ = nullptr; + is_done_ = true; + return local_impl->runLambda(std::forward(c), std::forward(args)...); + } + /** * \brief Enqueue the runnable in the scheduler for execution later */ void enqueue(); /** - * \brief Set an explicit task for this runnable (not going through normal - * handler) + * \brief Return the underlying \c RunnableNew + * + * \warning This is for testing only * - * \param[in] task_ the task to execute + * \return the underlying runnable */ - RunnableMaker&& withExplicitTask(ActionType task_) { - impl_->setExplicitTask(task_); - return std::move(*this); - } + RunnableNew* getRunnableImpl() { return impl_; } private: /** @@ -277,7 +302,7 @@ struct RunnableMaker { */ void setup() { if (not set_handler_) { - impl_->setupHandler(handler_, is_void_); + impl_->setupHandler(handler_); set_handler_ = true; } } @@ -287,7 +312,6 @@ struct RunnableMaker { MsgSharedPtr const& msg_; HandlerType handler_ = uninitialized_handler; bool set_handler_ = false; - bool is_void_ = false; NodeType from_node_ = uninitialized_destination; bool is_done_ = false; bool is_term_ = false; diff --git a/src/vt/runnable/runnable.cc b/src/vt/runnable/runnable.cc index c15e56b0c4..4beb1dba91 100644 --- a/src/vt/runnable/runnable.cc +++ b/src/vt/runnable/runnable.cc @@ -53,83 +53,52 @@ namespace vt { namespace runnable { -void RunnableNew::setupHandler(HandlerType handler, bool is_void) { +void RunnableNew::setupHandler(HandlerType handler) { using HandlerManagerType = HandlerManager; + bool const is_obj = HandlerManagerType::isHandlerObjGroup(handler); + vtAssert(not is_obj, "Must not be object"); - if (not is_void) { - if (is_obj) { - task_ = [=] { objgroup::dispatchObjGroup(msg_, handler); }; - return; - } else { - bool const is_auto = HandlerManagerType::isHandlerAuto(handler); - bool const is_functor = HandlerManagerType::isHandlerFunctor(handler); - - if (is_auto && is_functor) { - auto const& func = auto_registry::getAutoHandlerFunctor(handler); - auto const num_args = auto_registry::getAutoHandlerFunctorArgs(handler); - if (num_args == 0) { - task_ = [=, &func] { func->dispatch(nullptr, nullptr); }; - } else { - task_ = [=, &func] { func->dispatch(msg_.get(), nullptr); }; - } - - return; - } else { - bool const is_base_msg_derived = - HandlerManagerType::isHandlerBaseMsgDerived(handler); - if (is_base_msg_derived) { - auto const& func = auto_registry::getAutoHandler(handler); - task_ = [=, &func] { func->dispatch(msg_.get(), nullptr); }; - return; - } - - auto const& func = auto_registry::getScatterAutoHandler(handler); - task_ = [=, &func] { func->dispatch(msg_.get(), nullptr); }; - return; - } - } - } else { - bool const is_auto = HandlerManagerType::isHandlerAuto(handler); - bool const is_functor = HandlerManagerType::isHandlerFunctor(handler); + bool const is_auto = HandlerManagerType::isHandlerAuto(handler); + bool const is_functor = HandlerManagerType::isHandlerFunctor(handler); - if (is_auto && is_functor) { - auto const& func = auto_registry::getAutoHandlerFunctor(handler); - task_ = [=, &func] { func->dispatch(nullptr, nullptr); }; - return; - } else if (is_auto) { - bool const is_base_msg_derived = - HandlerManagerType::isHandlerBaseMsgDerived(handler); - if (is_base_msg_derived) { - auto const& func = auto_registry::getAutoHandler(handler); - task_ = [=, &func] { func->dispatch(msg_.get(), nullptr); }; - return; - } - - auto const& func = auto_registry::getScatterAutoHandler(handler); - task_ = [=, &func] { func->dispatch(msg_.get(), nullptr); }; + if (is_auto && is_functor) { + f_.func_ = auto_registry::getAutoHandlerFunctor(handler).get(); + return; + } else { + bool const is_base_msg_derived = + HandlerManagerType::isHandlerBaseMsgDerived(handler); + if (is_base_msg_derived) { + f_.func_ = auto_registry::getAutoHandler(handler).get(); return; - } else { - vtAbort("Must be auto/functor for a void handler"); } + + is_scatter_ = true; + f_.func_scat_ = auto_registry::getScatterAutoHandler(handler).get(); + return; } } +void RunnableNew::setupHandlerObjGroup(void* obj, HandlerType handler) { + f_.func_ = auto_registry::getAutoHandlerObjGroup(handler).get(); + obj_ = obj; +} + void RunnableNew::setupHandlerElement( vrt::collection::UntypedCollection* elm, HandlerType handler ) { auto const member = HandlerManager::isHandlerMember(handler); - auto const& func = member ? - auto_registry::getAutoHandlerCollectionMem(handler) : - auto_registry::getAutoHandlerCollection(handler); - task_ = [=, &func] { func->dispatch(msg_.get(), elm); }; + f_.func_ = member ? + auto_registry::getAutoHandlerCollectionMem(handler).get() : + auto_registry::getAutoHandlerCollection(handler).get(); + obj_ = elm; } void RunnableNew::setupHandlerElement( vrt::VirtualContext* elm, HandlerType handler ) { - auto const& func = auto_registry::getAutoHandlerVC(handler); - task_ = [=, &func] { func->dispatch(msg_.get(), elm); }; + f_.func_ = auto_registry::getAutoHandlerVC(handler).get(); + obj_ = elm; } void RunnableNew::run() { @@ -146,17 +115,25 @@ void RunnableNew::run() { ); #endif + bool needs_time = false; +#if vt_check_enabled(trace_enabled) + if (contexts_.has_trace) needs_time = true; + else +#endif + if (contexts_.has_lb) + { + needs_time = contexts_.lb.needsTime(); + } + TimeType start_time = needs_time ? theSched()->getRecentTime() : NAN; + #if vt_check_enabled(fcontext) if (suspended_) { - resume(); - } else { - start(); - } -#else - start(); + resume(start_time); + } else #endif - - vtAssert(task_ != nullptr, "Must have a valid task to run"); + { + start(start_time); + } #if vt_check_enabled(fcontext) if (is_threaded_ and not theConfig()->vt_ult_disable) { @@ -167,7 +144,9 @@ void RunnableNew::run() { tm->getThread(tid_)->resume(); } else { // allocate a new thread to run the task - tid_ = tm->allocateThreadRun(task_); + tid_ = tm->allocateThreadRun([&]{ + f_.func_->dispatch(msg_ == nullptr ? nullptr : msg_.get(), obj_); + }); } // check if it is done running, and save that state @@ -185,22 +164,30 @@ void RunnableNew::run() { vt_force_use(is_threaded_, tid_) #endif - task_(); + if (is_scatter_) { + f_.func_scat_->dispatch(msg_ == nullptr ? nullptr : msg_.get(), obj_); + } else { + f_.func_->dispatch(msg_ == nullptr ? nullptr : msg_.get(), obj_); + } #if vt_check_enabled(fcontext) done_ = true; #endif } + theSched()->setRecentTimeToStale(); + TimeType end_time = needs_time ? theSched()->getRecentTime() : NAN; + + #if vt_check_enabled(fcontext) if (done_) { - finish(); + finish(end_time); } else { suspended_ = true; - suspend(); + suspend(end_time); } #else - finish(); + finish(end_time); #endif #if vt_check_enabled(fcontext) @@ -212,49 +199,49 @@ void RunnableNew::run() { #endif } -void RunnableNew::start() { +void RunnableNew::start(TimeType time) { contexts_.setcontext.start(); if (contexts_.has_td) contexts_.td.start(); if (contexts_.has_col) contexts_.col.start(); - if (contexts_.has_lb) contexts_.lb.start(); + if (contexts_.has_lb) contexts_.lb.start(time); #if vt_check_enabled(trace_enabled) - if (contexts_.has_trace) contexts_.trace.start(); + if (contexts_.has_trace) contexts_.trace.start(time); #endif } -void RunnableNew::finish() { +void RunnableNew::finish(TimeType time) { contexts_.setcontext.finish(); if (contexts_.has_td) contexts_.td.finish(); if (contexts_.has_col) contexts_.col.finish(); if (contexts_.has_cont) contexts_.cont.finish(); - if (contexts_.has_lb) contexts_.lb.finish(); + if (contexts_.has_lb) contexts_.lb.finish(time); #if vt_check_enabled(trace_enabled) - if (contexts_.has_trace) contexts_.trace.finish(); + if (contexts_.has_trace) contexts_.trace.finish(time); #endif } -void RunnableNew::suspend() { +void RunnableNew::suspend(TimeType time) { #if vt_check_enabled(fcontext) contexts_.setcontext.suspend(); if (contexts_.has_td) contexts_.td.suspend(); if (contexts_.has_col) contexts_.col.suspend(); - if (contexts_.has_lb) contexts_.lb.suspend(); + if (contexts_.has_lb) contexts_.lb.suspend(time); # if vt_check_enabled(trace_enabled) - if (contexts_.has_trace) contexts_.trace.suspend(); + if (contexts_.has_trace) contexts_.trace.suspend(time); # endif #endif } -void RunnableNew::resume() { +void RunnableNew::resume(TimeType time) { #if vt_check_enabled(fcontext) contexts_.setcontext.resume(); if (contexts_.has_td) contexts_.td.resume(); if (contexts_.has_col) contexts_.col.resume(); - if (contexts_.has_lb) contexts_.lb.resume(); + if (contexts_.has_lb) contexts_.lb.resume(time); # if vt_check_enabled(trace_enabled) - if (contexts_.has_trace) contexts_.trace.resume(); + if (contexts_.has_trace) contexts_.trace.resume(time); # endif #endif } @@ -279,4 +266,4 @@ RunnableNewAlloc::runnable = std::make_unique< }} /* end namespace vt::runnable */ -#include "vt/pool/static_sized/memory_pool_equal.cc" +#include "vt/pool/static_sized/memory_pool_equal.impl.h" diff --git a/src/vt/runnable/runnable.h b/src/vt/runnable/runnable.h index ecd235b16a..3151a4fe43 100644 --- a/src/vt/runnable/runnable.h +++ b/src/vt/runnable/runnable.h @@ -96,6 +96,8 @@ struct Contexts { struct RunnableNew { template using FnParamType = void(*)(Args...); + using DispatcherType = auto_registry::BaseHandlersDispatcherPtr::pointer; + using DispatcherScatterType = auto_registry::BaseScatterDispatcherPtr::pointer; /** * \brief Construct a new \c RunnableNew with a message @@ -194,6 +196,14 @@ struct RunnableNew { vrt::collection::UntypedCollection* elm, HandlerType handler ); + /** + * \brief Set up a handler to run on an object group + * + * \param[in] elm the object pointer + * \param[in] handler the handler ID bits + */ + void setupHandlerObjGroup(void* obj, HandlerType handler); + /** * \brief Set up a handler to run on an non-collection object * @@ -206,9 +216,8 @@ struct RunnableNew { * \brief Set up a basic handler to run * * \param[in] handler the handler ID bits - * \param[in] is_void whether it's a void handler w/o an associated message */ - void setupHandler(HandlerType handler, bool is_void = false); + void setupHandler(HandlerType handler); /** * \brief Run the task! @@ -219,6 +228,28 @@ struct RunnableNew { */ void run(); + /** + * \brief Run the task as a lambda! + */ + template + decltype(auto) runLambda(Callable&& c, Args&&... args) { + auto start_time = timing::getCurrentTime(); + start(start_time); + + // Arrange a scope guard to call finish() without any sort of dynamic allocation + struct finisher { + RunnableNew* r; + finisher(RunnableNew* in_r) : r(in_r){}; + ~finisher() { + auto finish_time = timing::getCurrentTime(); + r->finish(finish_time); + } + }; + finisher f(this); + + return std::invoke(std::forward(c), std::forward(args)...); + } + #if vt_check_enabled(fcontext) /** * \brief Get the thread ID associated with the runnable. @@ -236,25 +267,25 @@ struct RunnableNew { * \internal \brief Loop through all the contexts associated with this * runnable and invoke \c start() on them. */ - void start(); + void start(TimeType time); /** * \internal \brief Loop through all the contexts associated with this * runnable and invoke \c finish() on them. */ - void finish(); + void finish(TimeType time); /** * \internal \brief Loop through all the contexts associated with this * runnable and invoke \c suspend() on them. */ - void suspend(); + void suspend(TimeType time); /** * \internal \brief Loop through all the contexts associated with this * runnable and invoke \c resume() on them. */ - void resume(); + void resume(TimeType time); public: /** @@ -306,15 +337,6 @@ struct RunnableNew { bool isSuspended() const { return suspended_; } #endif - /** - * \brief Set an explicit task for the runnable bypassing the handler - * - * \param[in] task_in the task - */ - void setExplicitTask(ActionType task_in) { - task_ = task_in; - } - /** * \internal \brief Operator new for runnables targeting pool * @@ -334,7 +356,12 @@ struct RunnableNew { private: detail::Contexts contexts_; /**< The contexts */ MsgSharedPtr msg_ = nullptr; /**< The associated message */ - ActionType task_ = nullptr; /**< The runnable's task */ + void* obj_ = nullptr; /**< Object pointer */ + union { + DispatcherType func_; + DispatcherScatterType func_scat_; + } f_; + bool is_scatter_ = false; #if vt_check_enabled(fcontext) bool is_threaded_ = false; /**< Whether ULTs are supported */ bool done_ = false; /**< Whether task is complete */ diff --git a/src/vt/runtime/runtime.cc b/src/vt/runtime/runtime.cc index 8d1ac247ff..3958fed6b5 100644 --- a/src/vt/runtime/runtime.cc +++ b/src/vt/runtime/runtime.cc @@ -50,7 +50,6 @@ #include "vt/termination/termination.h" #include "vt/pool/pool.h" #include "vt/rdma/rdma_headers.h" -#include "vt/parameterization/parameterization.h" #include "vt/pipe/pipe_manager.h" #include "vt/objgroup/manager.h" #include "vt/scheduler/scheduler.h" @@ -59,7 +58,6 @@ #include "vt/vrt/context/context_vrtmanager.h" #include "vt/vrt/collection/collection_headers.h" #include "vt/vrt/collection/balance/lb_type.h" -#include "vt/worker/worker_headers.h" #include "vt/configs/debug/debug_colorize.h" #include "vt/configs/error/stack_out.h" #include "vt/utils/memory/memory_usage.h" @@ -96,11 +94,9 @@ namespace vt { namespace runtime { /*static*/ bool volatile Runtime::sig_user_1_ = false; Runtime::Runtime( - int& argc, char**& argv, WorkerCountType in_num_workers, - bool const interop_mode, MPI_Comm in_comm, RuntimeInstType const in_instance, - arguments::AppConfig const* appConfig + int& argc, char**& argv, bool const interop_mode, MPI_Comm in_comm, + RuntimeInstType const in_instance, arguments::AppConfig const* appConfig ) : instance_(in_instance), runtime_active_(false), is_interop_(interop_mode), - num_workers_(in_num_workers), initial_communicator_(in_comm), arg_config_(std::make_unique()), app_config_(&arg_config_->config_) @@ -205,6 +201,46 @@ Runtime::Runtime( setupSignalHandler(); setupSignalHandlerINT(); setupTerminateHandler(); + + if (arg_config_->config_.vt_lb_data) { + determinePhysicalNodeIDs(); + } +} + +void Runtime::determinePhysicalNodeIDs() { + MPI_Comm i_comm = initial_communicator_; + + MPI_Comm shm_comm; + MPI_Comm_split_type(i_comm, MPI_COMM_TYPE_SHARED, 0, MPI_INFO_NULL, &shm_comm); + int shm_rank = -1; + int node_size = -1; + MPI_Comm_rank(shm_comm, &shm_rank); + MPI_Comm_size(shm_comm, &node_size); + + int num_nodes = -1; + int is_rank_0 = (shm_rank == 0) ? 1 : 0; + MPI_Allreduce(&is_rank_0, &num_nodes, 1, MPI_INT, MPI_SUM, i_comm); + + int starting_rank = -1; + MPI_Comm_rank(i_comm, &starting_rank); + + MPI_Comm node_number_comm; + MPI_Comm_split(i_comm, shm_rank, starting_rank, &node_number_comm); + + int node_id = -1; + if (shm_rank == 0) { + MPI_Comm_rank(node_number_comm, &node_id); + } + MPI_Bcast(&node_id, 1, MPI_INT, 0, shm_comm); + + MPI_Comm_free(&shm_comm); + MPI_Comm_free(&node_number_comm); + + has_physical_node_info = true; + physical_node_id = node_id; + physical_num_nodes = num_nodes; + physical_node_size = node_size; + physical_node_rank = shm_rank; } bool Runtime::hasSchedRun() const { @@ -388,15 +424,11 @@ bool Runtime::tryFinalize(bool const disable_sig) { bool Runtime::needLBDataRestartReader() { #if vt_check_enabled(lblite) - if (arg_config_->config_.vt_lb_data) { - auto lbNames = vrt::collection::balance::get_lb_names(); - auto mapLB = vrt::collection::balance::LBType::OfflineLB; - if (arg_config_->config_.vt_lb_name == lbNames[mapLB]) { - return true; - } - } + if (true) { + return arg_config_->config_.vt_lb_data_in; + } else #endif - return false; + return false; } bool Runtime::initialize(bool const force_now) { @@ -755,17 +787,6 @@ void Runtime::initializeComponents() { >{} ); - #if vt_threading_enabled - p_->registerComponent( - &theWorkerGrp, Deps< - ctx::Context, // Everything depends on theContext - messaging::ActiveMessenger, // Depends on active messenger to send msgs - sched::Scheduler, // Depends on scheduler - term::TerminationDetector // Depends on TD for idle callbacks - >{} - ); - #endif - p_->registerComponent( &theCollective, Deps< ctx::Context, // Everything depends on theContext @@ -799,13 +820,6 @@ void Runtime::initializeComponents() { >{} ); - p_->registerComponent( - &theParam, Deps< - ctx::Context, // Everything depends on theContext - messaging::ActiveMessenger // Depends on active messenger sending - >{} - ); - p_->registerComponent( &theLocMan, Deps< ctx::Context, // Everything depends on theContext @@ -898,7 +912,6 @@ void Runtime::initializeComponents() { p_->add(); p_->add(); p_->add(); - p_->add(); p_->add(); p_->add(); p_->add(); @@ -914,13 +927,6 @@ void Runtime::initializeComponents() { p_->add(); } - #if vt_threading_enabled - bool const has_workers = num_workers_ != no_workers; - if (has_workers) { - p_->add(); - } - #endif - p_->construct(); vt_debug_print( @@ -962,7 +968,7 @@ void Runtime::initializeOptionalComponents() { "begin: initializeOptionalComponents\n" ); - initializeWorkers(num_workers_); + initializeTDCallbacks(); vt_debug_print( verbose, runtime, @@ -970,62 +976,40 @@ void Runtime::initializeOptionalComponents() { ); } -void Runtime::initializeWorkers(WorkerCountType const num_workers) { +void Runtime::initializeTDCallbacks() { using ::vt::ctx::ContextAttorney; vt_debug_print( normal, runtime, - "begin: initializeWorkers: workers={}\n", - num_workers + "begin: initializeTDCallbacks\n" ); - bool const has_workers = num_workers != no_workers; - - if (has_workers) { - #if vt_threading_enabled - ContextAttorney::setNumWorkers(num_workers); - - // Initialize individual memory pool for each worker - thePool->initWorkerPools(num_workers); - - auto localTermFn = [](worker::eWorkerGroupEvent event){ - bool const no_local_workers = false; - bool const is_idle = event == worker::eWorkerGroupEvent::WorkersIdle; - bool const is_busy = event == worker::eWorkerGroupEvent::WorkersBusy; - if (is_idle || is_busy) { - ::vt::theTerm()->setLocalTerminated(is_idle, no_local_workers); - } - }; - theWorkerGrp->registerIdleListener(localTermFn); - #endif - } else { - // Without workers running on the node, the termination detector should - // enable/disable the global collective epoch based on the state of the - // scheduler; register listeners to activate/deactivate that epoch - auto td = vt::theTerm(); - theSched->registerTrigger( - sched::SchedulerEvent::BeginIdleMinusTerm, [td]{ - vt_debug_print( - normal, runtime, - "setLocalTerminated: BeginIdle: true\n" - ); - td->setLocalTerminated(true, false); - } - ); - theSched->registerTrigger( - sched::SchedulerEvent::EndIdleMinusTerm, [td]{ - vt_debug_print( - normal, runtime, - "setLocalTerminated: EndIdle: false\n" - ); - td->setLocalTerminated(false, false); - } - ); - } + // Without workers running on the node, the termination detector should + // enable/disable the global collective epoch based on the state of the + // scheduler; register listeners to activate/deactivate that epoch + auto td = vt::theTerm(); + theSched->registerTrigger( + sched::SchedulerEvent::BeginIdleMinusTerm, [td]{ + vt_debug_print( + normal, runtime, + "setLocalTerminated: BeginIdle: true\n" + ); + td->setLocalTerminated(true, false); + } + ); + theSched->registerTrigger( + sched::SchedulerEvent::EndIdleMinusTerm, [td]{ + vt_debug_print( + normal, runtime, + "setLocalTerminated: EndIdle: false\n" + ); + td->setLocalTerminated(false, false); + } + ); vt_debug_print( normal, runtime, - "end: initializeWorkers\n" + "end: initializeTDCallbacks\n" ); } @@ -1079,12 +1063,6 @@ void Runtime::printMemoryFootprint() const { printComponentFootprint( static_cast(base) ); - } else if (name == "WorkerGroupOMP" || name == "WorkerGroup") { - #if vt_threading_enabled - printComponentFootprint( - static_cast(base) - ); - #endif } else if (name == "Collective") { printComponentFootprint( static_cast(base) @@ -1097,10 +1075,6 @@ void Runtime::printMemoryFootprint() const { printComponentFootprint( static_cast(base) ); - } else if (name == "Param") { - printComponentFootprint( - static_cast(base) - ); } else if (name == "RDMAManager") { printComponentFootprint( static_cast(base) diff --git a/src/vt/runtime/runtime.h b/src/vt/runtime/runtime.h index 26b0a38f9c..00c6fed4e8 100644 --- a/src/vt/runtime/runtime.h +++ b/src/vt/runtime/runtime.h @@ -48,7 +48,6 @@ #include "vt/runtime/runtime_common.h" #include "vt/runtime/runtime_component_fwd.h" #include "vt/runtime/component/component_pack.h" -#include "vt/worker/worker_headers.h" #include "vt/timing/timing_type.h" // Optional components @@ -93,14 +92,12 @@ struct Runtime { * * \param[in] argc argument count (modified after VT extracts) * \param[in] argv arguments (modified after VT extracts) - * \param[in] in_num_workers number of worker threads to initialize * \param[in] interop_mode whether running in interoperability mode * \param[in] in_comm the MPI communicator (if in interoperability mode) * \param[in] in_instance the runtime instance to set */ Runtime( int& argc, char**& argv, - WorkerCountType in_num_workers = no_workers, bool const interop_mode = false, MPI_Comm in_comm = MPI_COMM_WORLD, RuntimeInstType const in_instance = RuntimeInstType::DefaultInstance, @@ -272,6 +269,11 @@ struct Runtime { */ static void writeToFile(std::string const& str); + /** + * \internal \brief Determine the physical node IDs for LB data files + */ + void determinePhysicalNodeIDs(); + protected: /** * \internal \brief Try to initialize @@ -304,11 +306,9 @@ struct Runtime { void initializeOptionalComponents(); /** - * \internal \brief Initialize workers - * - * \param[in] num_workers number of workers to create + * \internal \brief Initialize TD callbacks */ - void initializeWorkers(WorkerCountType const num_workers); + void initializeTDCallbacks(); /** * \internal \brief Check if we should create a LB data restart reader component @@ -409,7 +409,6 @@ struct Runtime { ComponentPtrType theCollective = nullptr; ComponentPtrType thePool = nullptr; ComponentPtrType theRDMA = nullptr; - ComponentPtrType theParam = nullptr; ComponentPtrType theSched = nullptr; ComponentPtrType theLocMan = nullptr; ComponentPtrType theVirtualManager = nullptr; @@ -426,11 +425,6 @@ struct Runtime { ComponentPtrType thePhase = nullptr; ComponentPtrType theEpoch = nullptr; - // Node-level worker-based components for vt (these are optional) - #if vt_threading_enabled - ComponentPtrType theWorkerGrp = nullptr; - #endif - // Optional components #if vt_check_enabled(trace_enabled) ComponentPtrType theTrace = nullptr; @@ -441,13 +435,18 @@ struct Runtime { static bool volatile sig_user_1_; + bool has_physical_node_info = false; + int physical_node_id = -1; + int physical_num_nodes = -1; + int physical_node_size = -1; + int physical_node_rank = -1; + protected: bool finalize_on_term_ = false; bool initialized_ = false, finalized_ = false, aborted_ = false; bool runtime_active_ = false; bool is_interop_ = false; bool sig_handlers_disabled_ = false; - WorkerCountType num_workers_ = no_workers; //< Communicator to be given to theContext creation; don't use otherwise. MPI_Comm initial_communicator_ = MPI_COMM_NULL; std::unique_ptr p_; diff --git a/src/vt/runtime/runtime_banner.cc b/src/vt/runtime/runtime_banner.cc index c694f1c298..ee02c32387 100644 --- a/src/vt/runtime/runtime_banner.cc +++ b/src/vt/runtime/runtime_banner.cc @@ -72,8 +72,6 @@ void Runtime::printStartupBanner() { } NodeType const nodes = theContext->getNumNodes(); - WorkerCountType const workers = theContext->getNumWorkers(); - bool const has_workers = theContext->hasWorkers(); std::string is_interop_str = is_interop_ ? @@ -81,24 +79,9 @@ void Runtime::printStartupBanner() { std::string(""); std::string init = "Runtime Initializing:" + is_interop_str; std::string mode = std::string("mode: "); - std::string mode_type = - std::string(num_workers_ == no_workers ? "single" : "multi") + - std::string("-thread per rank"); - std::string thd = !has_workers ? std::string("") : - std::string(", worker threading: ") + - std::string( - #if vt_check_enabled(openmp) - "OpenMP" - #elif vt_check_enabled(stdthread) - "std::thread" - #else - "" - #endif - ); - std::string cnt = !has_workers ? std::string("") : - (std::string(", ") + std::to_string(workers) + std::string(" workers/node")); + std::string mode_type = std::string("single-thread per rank"); std::string node_str = nodes == 1 ? "node" : "nodes"; - std::string all_node = std::to_string(nodes) + " " + node_str + cnt; + std::string all_node = std::to_string(nodes) + " " + node_str; char hostname[1024]; gethostname(hostname, 1024); @@ -123,9 +106,6 @@ void Runtime::printStartupBanner() { #if vt_check_enabled(lblite) features.push_back(vt_feature_str_lblite); #endif -#if vt_check_enabled(openmp) - features.push_back(vt_feature_str_openmp); -#endif #if vt_check_enabled(production_build) features.push_back(vt_feature_str_production_build); #endif @@ -135,9 +115,6 @@ void Runtime::printStartupBanner() { #if vt_check_enabled(fcontext) features.push_back(vt_feature_str_fcontext); #endif -#if vt_check_enabled(stdthread) - features.push_back(vt_feature_str_stdthread); -#endif #if vt_check_enabled(mpi_rdma) features.push_back(vt_feature_str_mpi_rdma); #endif @@ -178,7 +155,7 @@ void Runtime::printStartupBanner() { std::array< std::string, 11 > info_lines = { fmt::format("{}Version: {}\n", green, emph(vt_version_string)), - fmt::format("{} {}{}\n", reg(init), reg(mode), emph(mode_type + thd)), + fmt::format("{} {}{}\n", reg(init), reg(mode), emph(mode_type)), fmt::format("{}Program: {} ({})\n", green, emph(getAppConfig()->prog_name), emph(getAppConfig()->argv_prog_name)), fmt::format("{}Running on: {}\n", green, emph(all_node)), @@ -362,6 +339,11 @@ void Runtime::printStartupBanner() { auto f12 = opt_on("--vt_lb_data_dir", f11); fmt::print("{}\t{}{}", vt_pre, f12, reset); } + } + + if (getAppConfig()->vt_lb_data_in) { + auto f9 = opt_on("--vt_lb_data_in", "Load balancing data input"); + fmt::print("{}\t{}{}", vt_pre, f9, reset); auto const fnamein = getAppConfig()->vt_lb_data_file_in; if (fnamein != "") { diff --git a/src/vt/runtime/runtime_get.cc b/src/vt/runtime/runtime_get.cc index 8aa6dab0c2..40610b387f 100644 --- a/src/vt/runtime/runtime_get.cc +++ b/src/vt/runtime/runtime_get.cc @@ -46,7 +46,6 @@ #include "vt/context/context.h" #include "vt/runtime/runtime.h" #include "vt/runtime/runtime_inst.h" -#include "vt/utils/tls/tls.h" #include "vt/vrt/context/context_vrtmanager.h" #include "vt/context/context.h" #include "vt/messaging/active.h" @@ -55,12 +54,10 @@ #include "vt/collective/collective_alg.h" #include "vt/pool/pool.h" #include "vt/rdma/rdma.h" -#include "vt/parameterization/parameterization.h" #include "vt/trace/trace.h" #include "vt/scheduler/scheduler.h" #include "vt/topos/location/location_headers.h" #include "vt/vrt/collection/collection_headers.h" -#include "vt/worker/worker_headers.h" #include "vt/group/group_headers.h" #include "vt/pipe/pipe_headers.h" #include "vt/objgroup/headers.h" @@ -87,65 +84,46 @@ namespace vt { * */ -static runtime::Runtime* no_rt = nullptr; - -#define IS_COMM_THREAD curRT->theContext->getWorker() == worker_id_comm_thread -#define CUR_RT_SAFE (IS_COMM_THREAD ? curRT : no_rt) -#define CUR_RT_TS curRT -#define CUR_RT CUR_RT_SAFE - -#define CHECK_THD \ - do { \ - bool const check = IS_COMM_THREAD; \ - std::string str("Only comm thread can access this component"); \ - vtAssertExpr(check && str.c_str()); \ - if (!check) { CUR_RT->abort(str, 29); } \ - } while (0); - using CollectionManagerType = vrt::collection::CollectionManager; +using NodeLBDataType = vrt::collection::balance::NodeLBData; +using LBDataRestartReaderType = vrt::collection::balance::LBDataRestartReader; +using LBManagerType = vrt::collection::balance::LBManager; +using TimeTriggerManagerType = timetrigger::TimeTriggerManager; // Thread-safe runtime components -ctx::Context* theContext() { return CUR_RT_TS->theContext; } -pool::Pool* thePool() { return CUR_RT_TS->thePool; } -vrt::VirtualContextManager* theVirtualManager() { return CUR_RT_TS->theVirtualManager; } -#if vt_threading_enabled -worker::WorkerGroupType* theWorkerGrp() { return CUR_RT_TS->theWorkerGrp; } -#endif +ctx::Context* theContext() { return curRT->theContext; } +pool::Pool* thePool() { return curRT->thePool; } +vrt::VirtualContextManager* theVirtualManager() { return curRT->theVirtualManager; } // Non thread-safe runtime components -collective::CollectiveAlg* theCollective() { return CUR_RT->theCollective; } -event::AsyncEvent* theEvent() { return CUR_RT->theEvent; } -messaging::ActiveMessenger* theMsg() { return CUR_RT->theMsg; } -param::Param* theParam() { return CUR_RT->theParam; } -rdma::RDMAManager* theRDMA() { return CUR_RT->theRDMA; } -sched::Scheduler* theSched() { return CUR_RT->theSched; } -term::TerminationDetector* theTerm() { return CUR_RT->theTerm; } -location::LocationManager* theLocMan() { return CUR_RT->theLocMan; } -CollectionManagerType* theCollection() { return CUR_RT->theCollection; } -group::GroupManager* theGroup() { return CUR_RT->theGroup; } -pipe::PipeManager* theCB() { return CUR_RT->theCB; } -objgroup::ObjGroupManager* theObjGroup() { return CUR_RT->theObjGroup; } -rdma::Manager* theHandleRDMA() { return CUR_RT->theHandleRDMA; } -util::memory::MemoryUsage* theMemUsage() { return CUR_RT->theMemUsage; } -vrt::collection::balance::NodeLBData* theNodeLBData() { return CUR_RT->theNodeLBData; } -vrt::collection::balance::LBDataRestartReader* theLBDataReader() { return CUR_RT->theLBDataReader; } -vrt::collection::balance::LBManager* theLBManager() { return CUR_RT->theLBManager; } -timetrigger::TimeTriggerManager* theTimeTrigger() { return CUR_RT->theTimeTrigger; } -vt::arguments::AppConfig* theConfig() { return &CUR_RT->theArgConfig->config_; } -vt::phase::PhaseManager* thePhase() { return CUR_RT->thePhase; } -epoch::EpochManip* theEpoch() { return CUR_RT->theEpoch; } +collective::CollectiveAlg* theCollective() { return curRT->theCollective; } +event::AsyncEvent* theEvent() { return curRT->theEvent; } +messaging::ActiveMessenger* theMsg() { return curRT->theMsg; } +rdma::RDMAManager* theRDMA() { return curRT->theRDMA; } +sched::Scheduler* theSched() { return curRT->theSched; } +term::TerminationDetector* theTerm() { return curRT->theTerm; } +location::LocationManager* theLocMan() { return curRT->theLocMan; } +CollectionManagerType* theCollection() { return curRT->theCollection; } +group::GroupManager* theGroup() { return curRT->theGroup; } +pipe::PipeManager* theCB() { return curRT->theCB; } +objgroup::ObjGroupManager* theObjGroup() { return curRT->theObjGroup; } +rdma::Manager* theHandleRDMA() { return curRT->theHandleRDMA; } +util::memory::MemoryUsage* theMemUsage() { return curRT->theMemUsage; } +NodeLBDataType* theNodeLBData() { return curRT->theNodeLBData; } +LBDataRestartReaderType* theLBDataReader() { return curRT->theLBDataReader; } +LBManagerType* theLBManager() { return curRT->theLBManager; } +TimeTriggerManagerType* theTimeTrigger() { return curRT->theTimeTrigger; } +vt::arguments::AppConfig* theConfig() { return &curRT->theArgConfig->config_; } +vt::phase::PhaseManager* thePhase() { return curRT->thePhase; } +epoch::EpochManip* theEpoch() { return curRT->theEpoch; } #if vt_check_enabled(trace_enabled) -trace::Trace* theTrace() { return CUR_RT->theTrace; } +trace::Trace* theTrace() { return curRT->theTrace; } #endif #if vt_check_enabled(mpi_access_guards) -pmpi::PMPIComponent* thePMPI() { return CUR_RT->thePMPI; } +pmpi::PMPIComponent* thePMPI() { return curRT->thePMPI; } #endif -#undef CUR_RT -#undef CUR_RT_SAFE -#undef IS_COMM_THREAD - } /* end namespace vt */ namespace vt { namespace debug { diff --git a/src/vt/runtime/runtime_inst.cc b/src/vt/runtime/runtime_inst.cc index 70c377ce99..4baf371f71 100644 --- a/src/vt/runtime/runtime_inst.cc +++ b/src/vt/runtime/runtime_inst.cc @@ -49,7 +49,6 @@ namespace vt { -//DeclareInitTLS(runtime::Runtime*, curRT, nullptr); runtime::Runtime* curRT = nullptr; ::vt::runtime::Runtime* rt = nullptr; diff --git a/src/vt/runtime/runtime_inst.h b/src/vt/runtime/runtime_inst.h index 367cf02b7c..1269c3b311 100644 --- a/src/vt/runtime/runtime_inst.h +++ b/src/vt/runtime/runtime_inst.h @@ -46,7 +46,6 @@ #include "vt/config.h" #include "vt/runtime/runtime_common.h" -#include "vt/utils/tls/tls.h" #include diff --git a/src/vt/scheduler/base_unit.cc b/src/vt/scheduler/base_unit.cc index 3a4292d289..85dfdbbea0 100644 --- a/src/vt/scheduler/base_unit.cc +++ b/src/vt/scheduler/base_unit.cc @@ -62,6 +62,7 @@ void BaseUnit::execute() { #endif } else if (work_) { work_(); + theSched()->setRecentTimeToStale(); } } diff --git a/src/vt/scheduler/scheduler.cc b/src/vt/scheduler/scheduler.cc index 58890baeda..d67a23da11 100644 --- a/src/vt/scheduler/scheduler.cc +++ b/src/vt/scheduler/scheduler.cc @@ -46,7 +46,6 @@ #include "vt/messaging/active.h" #include "vt/event/event.h" #include "vt/termination/termination.h" -#include "vt/worker/worker_headers.h" #include "vt/vrt/collection/manager.h" #include "vt/objgroup/manager.fwd.h" #include "vt/configs/arguments/app_config.h" @@ -240,24 +239,24 @@ void Scheduler::runProgress(bool msg_only, TimeType current_time) { if (theConfig()->vt_print_memory_at_threshold) { printMemoryUsage(); } - + is_recent_time_stale_ = true; if (special_progress_) { // Reset count of processed handlers since the last time progress was invoked processed_after_last_progress_ = 0; - last_progress_time_ = timing::getCurrentTime(); + last_progress_time_ = getRecentTime(); } } void Scheduler::runSchedulerOnceImpl(bool msg_only) { if (special_progress_) { - auto current_time = timing::getCurrentTime(); + auto current_time = getRecentTime(); auto time_since_last_progress = current_time - last_progress_time_; if (shouldCallProgress(processed_after_last_progress_, time_since_last_progress)) { runProgress(msg_only, current_time); } } else if (work_queue_.empty()) { if (curRT->needsCurrentTime()) { - runProgress(msg_only, timing::getCurrentTime()); + runProgress(msg_only, getRecentTime()); } else { runProgress(msg_only, TimeType{0}); } diff --git a/src/vt/scheduler/scheduler.h b/src/vt/scheduler/scheduler.h index 4cc2e96d95..1f01738c0b 100644 --- a/src/vt/scheduler/scheduler.h +++ b/src/vt/scheduler/scheduler.h @@ -324,6 +324,25 @@ struct Scheduler : runtime::component::Component { */ void resume(ThreadIDType tid); + /** + * \brief Return a valid recent time, after checking whether an update is needed + * + * \return a valid recent time + */ + TimeType getRecentTime() { + if(is_recent_time_stale_) { + recent_time_ = timing::getCurrentTime(); + is_recent_time_stale_ = false; + } + return recent_time_; + } + + /** + * \brief Set the flag so that recent_time_ will be updated at next get request + * + */ + void setRecentTimeToStale() { is_recent_time_stale_ = true; } + #if vt_check_enabled(fcontext) /** * \brief Get the thread manager @@ -353,6 +372,9 @@ struct Scheduler : runtime::component::Component { | last_threshold_memory_usage_ | threshold_memory_usage_ | last_memory_usage_poll_ + | special_progress_ + | recent_time_ + | is_recent_time_stale_ | progressCount | workUnitCount | queueSizeGauge @@ -425,6 +447,8 @@ struct Scheduler : runtime::component::Component { std::size_t last_memory_usage_poll_ = 0; bool special_progress_ = false; /**< time-based/k-handler progress enabled */ + TimeType recent_time_; + bool is_recent_time_stale_ = true; // Access to triggerEvent. template diff --git a/src/vt/serialization/messaging/serialized_messenger.impl.h b/src/vt/serialization/messaging/serialized_messenger.impl.h index fa65da93d4..5b9c296ae0 100644 --- a/src/vt/serialization/messaging/serialized_messenger.impl.h +++ b/src/vt/serialization/messaging/serialized_messenger.impl.h @@ -53,6 +53,7 @@ #include "vt/serialization/messaging/serialized_messenger.h" #include "vt/messaging/envelope/envelope_set.h" // envelopeSetRef #include "vt/runnable/make_runnable.h" +#include "vt/objgroup/manager.fwd.h" #include #include @@ -88,9 +89,16 @@ template auto msg_data = ptr_offset; auto user_msg = deserializeFullMessage(msg_data); - runnable::makeRunnable(user_msg, true, handler, sys_msg->from_node) - .withTDEpochFromMsg() - .enqueue(); + bool const is_obj = HandlerManager::isHandlerObjGroup(handler); + if (is_obj) { + objgroup::dispatchObjGroup( + user_msg.template to(), handler, sys_msg->from_node, nullptr + ); + } else { + runnable::makeRunnable(user_msg, true, handler, sys_msg->from_node) + .withTDEpochFromMsg() + .enqueue(); + } } template @@ -132,10 +140,17 @@ template handler, recv_tag, envelopeGetEpoch(msg->env) ); - runnable::makeRunnable(msg, true, handler, node) - .withTDEpoch(epoch, not is_valid_epoch) - .withContinuation(action) - .enqueue(); + bool const is_obj = HandlerManager::isHandlerObjGroup(handler); + if (is_obj) { + objgroup::dispatchObjGroup( + msg.template to(), handler, node, action + ); + } else { + runnable::makeRunnable(msg, true, handler, node) + .withTDEpoch(epoch, not is_valid_epoch) + .withContinuation(action) + .enqueue(); + } if (is_valid_epoch) { theTerm()->consume(epoch); @@ -174,9 +189,16 @@ template print_ptr(user_msg.get()), envelopeGetEpoch(sys_msg->env) ); - runnable::makeRunnable(user_msg, true, handler, sys_msg->from_node) - .withTDEpochFromMsg() - .enqueue(); + bool const is_obj = HandlerManager::isHandlerObjGroup(handler); + if (is_obj) { + objgroup::dispatchObjGroup( + user_msg.template to(), handler, sys_msg->from_node, nullptr + ); + } else { + runnable::makeRunnable(user_msg, true, handler, sys_msg->from_node) + .withTDEpochFromMsg() + .enqueue(); + } } template @@ -407,9 +429,16 @@ template auto base_msg = user_msg.template to(); return messaging::PendingSend(base_msg, [=](MsgPtr in) { - runnable::makeRunnable(user_msg, true, typed_handler, node) - .withTDEpochFromMsg() - .enqueue(); + bool const is_obj = HandlerManager::isHandlerObjGroup(typed_handler); + if (is_obj) { + objgroup::dispatchObjGroup( + user_msg.template to(), typed_handler, node, nullptr + ); + } else { + runnable::makeRunnable(user_msg, true, typed_handler, node) + .withTDEpochFromMsg() + .enqueue(); + } }); } }; diff --git a/src/vt/standalone/vt_main.h b/src/vt/standalone/vt_main.h index 862e54d32d..3c3aaea113 100644 --- a/src/vt/standalone/vt_main.h +++ b/src/vt/standalone/vt_main.h @@ -48,7 +48,6 @@ #include "vt/context/context.h" #include "vt/collective/collective_ops.h" #include "vt/runtime/runtime_headers.h" -#include "vt/worker/worker_headers.h" #include #include @@ -56,7 +55,6 @@ namespace vt { namespace standalone { static constexpr NodeType const main_node = 0; -static constexpr WorkerCountType const default_vt_num_workers = 4; template inline void vrLaunchMainContext() { @@ -79,25 +77,14 @@ inline void vrCommThreadWork() { } template -int vt_main( - int argc, char** argv, WorkerCountType workers = no_workers - //default_vt_num_workers -) { - auto rt = CollectiveOps::initialize(argc, argv, workers); - vt_debug_print(verbose, gen, "vt_main: initialized workers={}\n", workers); +int vt_main(int argc, char** argv) { + auto rt = CollectiveOps::initialize(argc, argv); + vt_debug_print(verbose, gen, "vt_main: initialized\n"); auto comm_fn = vrCommThreadWork; + comm_fn(); - if (workers == no_workers or !vt_threading_enabled) { - comm_fn(); - } else { - #if vt_threading_enabled - vtAssert(theWorkerGrp() != nullptr, "Must have valid worker group"); - theWorkerGrp()->spawnWorkersBlock(comm_fn); - #endif - } - - vt_debug_print(verbose, gen, "vt_main: auto finalize workers={}\n", workers); + vt_debug_print(verbose, gen, "vt_main: auto finalize\n"); return 0; } diff --git a/src/vt/termination/dijkstra-scholten/comm.cc b/src/vt/termination/dijkstra-scholten/comm.cc index 998429afdb..3788348429 100644 --- a/src/vt/termination/dijkstra-scholten/comm.cc +++ b/src/vt/termination/dijkstra-scholten/comm.cc @@ -66,7 +66,7 @@ namespace vt { namespace term { namespace ds { vtAssertExpr(successor != node); auto msg = makeMessage(epoch,node,successor,count); theMsg()->markAsTermMessage(msg); - theMsg()->sendMsg(successor, msg); + theMsg()->sendMsg(successor, msg); } /*static*/ void StateDS::acknowledge( @@ -81,7 +81,7 @@ namespace vt { namespace term { namespace ds { vtAssertExpr(predecessor != node); auto msg = makeMessage(epoch,node,predecessor,count); theMsg()->markAsTermMessage(msg); - theMsg()->sendMsg(predecessor, msg); + theMsg()->sendMsg(predecessor, msg); } /*static*/ void StateDS::rootTerminated(EpochType epoch) { diff --git a/src/vt/termination/termination.cc b/src/vt/termination/termination.cc index d0af8168c4..a8a5db7dd7 100644 --- a/src/vt/termination/termination.cc +++ b/src/vt/termination/termination.cc @@ -365,7 +365,7 @@ bool TerminationDetector::propagateEpoch(TermStateType& state) { parent, print_ptr(msg.get()), state.getEpoch(), state.getCurWave() ); - theMsg()->sendMsg(parent, msg); + theMsg()->sendMsg(parent, msg); } else /*if (is_root) */ { is_term = state.g_prod1 == state.g_cons1 and @@ -404,7 +404,7 @@ bool TerminationDetector::propagateEpoch(TermStateType& state) { if (is_term) { auto msg = makeMessage(state.getEpoch()); theMsg()->markAsTermMessage(msg); - theMsg()->broadcastMsg(msg, false); + theMsg()->broadcastMsg(msg, false); vt_debug_print( terse, term, @@ -441,7 +441,7 @@ bool TerminationDetector::propagateEpoch(TermStateType& state) { auto msg = makeMessage(state.getEpoch(), state.getCurWave()); theMsg()->markAsTermMessage(msg); - theMsg()->broadcastMsg(msg, false); + theMsg()->broadcastMsg(msg, false); } } @@ -520,7 +520,7 @@ void TerminationDetector::countsConstant(TermStateType& state) { if (not theConfig()->vt_no_detect_hang) { auto msg = makeMessage(); theMsg()->markAsTermMessage(msg.get()); - theMsg()->broadcastMsg(msg, false); + theMsg()->broadcastMsg(msg, false); hangCheckHandler(nullptr); } } @@ -537,7 +537,7 @@ void TerminationDetector::startEpochGraphBuild() { if (theConfig()->vt_epoch_graph_on_hang) { auto msg = makeMessage(); theMsg()->markAsTermMessage(msg.get()); - theMsg()->broadcastMsg(msg, false); + theMsg()->broadcastMsg(msg, false); buildLocalGraphHandler(nullptr); } } @@ -705,7 +705,7 @@ void TerminationDetector::inquireTerminated( bool const is_ready = true; auto msg = makeMessage(epoch,is_ready); - theMsg()->sendMsg(from, msg); + theMsg()->sendMsg(from, msg); }); } @@ -773,7 +773,7 @@ TermStatusEnum TerminationDetector::testEpochTerminated(EpochType epoch) { * terminated or not */ auto msg = makeMessage(epoch,this_node_); - theMsg()->sendMsg(root, msg); + theMsg()->sendMsg(root, msg); epoch_wait_status_.insert(epoch); } status = TermStatusEnum::Remote; @@ -957,7 +957,7 @@ void TerminationDetector::initializeRootedWaveEpoch( */ auto msg = makeMessage(epoch); theMsg()->markAsTermMessage(msg); - theMsg()->broadcastMsg(msg, false); + theMsg()->broadcastMsg(msg, false); /* * Setup the new rooted epoch locally on the root node (this node) diff --git a/src/vt/topos/index/traits/traits.h b/src/vt/topos/index/traits/traits.h index bd17a1248b..f6a7260f0c 100644 --- a/src/vt/topos/index/traits/traits.h +++ b/src/vt/topos/index/traits/traits.h @@ -50,7 +50,7 @@ #include #include -#include "detector_headers.h" +#include "checkpoint/detector.h" namespace vt { namespace index { diff --git a/src/vt/topos/location/location.h b/src/vt/topos/location/location.h index fec0849067..1e465e0e34 100644 --- a/src/vt/topos/location/location.h +++ b/src/vt/topos/location/location.h @@ -224,6 +224,12 @@ struct EntityLocationCoord : LocationCoord { EntityID const& id, NodeType const& home_node, NodeActionType const& action ); + template *f> + void setupMessageForRouting( + EntityID const& id, NodeType const& home_node, + MsgSharedPtr const& msg + ); + /** * \brief Route a message with a custom handler * @@ -237,6 +243,22 @@ struct EntityLocationCoord : LocationCoord { MsgSharedPtr const& msg ); + /** + * \brief Route a message with a custom handler + * + * \param[in] m message shared pointer + */ + template + void routePreparedMsgHandler(MsgSharedPtr const& msg); + + /** + * \brief Route a message with a custom handler + * + * \param[in] m message shared pointer + */ + template + void routePreparedMsg(MsgSharedPtr const& msg); + /** * \brief Route a message with a custom handler where the element is local * diff --git a/src/vt/topos/location/location.impl.h b/src/vt/topos/location/location.impl.h index 277ce6b83e..b0f065f3ad 100644 --- a/src/vt/topos/location/location.impl.h +++ b/src/vt/topos/location/location.impl.h @@ -174,7 +174,7 @@ void EntityLocationCoord::registerEntity( ); msg->setResolvedNode(this_node); theMsg()->markAsLocationMessage(msg); - theMsg()->sendMsg::updateLocation>(home, msg); + theMsg()->sendMsg<&EntityLocationCoord::updateLocation>(home, msg); } } } @@ -424,7 +424,7 @@ void EntityLocationCoord::getLocation( this_inst, id, event_id, this_node, home_node ); theMsg()->markAsLocationMessage(msg); - theMsg()->sendMsg::getLocationHandler>(home_node, msg); + theMsg()->sendMsg<&EntityLocationCoord::getLocationHandler>(home_node, msg); // save a pending action when information about location arrives pending_actions_.emplace( std::piecewise_construct, @@ -497,7 +497,7 @@ void EntityLocationCoord::sendEagerUpdate( auto msg = makeMessage( this_inst, id, ask_node, home_node, deliver_node ); - theMsg()->sendMsg::recvEagerUpdate>(ask_node, msg); + theMsg()->sendMsg<&EntityLocationCoord::recvEagerUpdate>(ask_node, msg); } } @@ -535,7 +535,7 @@ void EntityLocationCoord::routeMsgNode( // set the instance on the message to deliver to the correct manager msg->setLocInst(this_inst); - auto m = msg; + auto m = msg; //copy for msg thief // send to the node discovered by the location manager theMsg()->sendMsg::routedHandler>(to_node, m); } else { @@ -656,6 +656,29 @@ template *f> void EntityLocationCoord::routeMsgHandler( EntityID const& id, NodeType const& home_node, MsgSharedPtr const& msg +) { + setupMessageForRouting(id, home_node, msg); + + routePreparedMsgHandler(msg); +} + +template +template +void EntityLocationCoord::routePreparedMsgHandler( + MsgSharedPtr const& msg +) { + if (local_registered_.find(msg->getEntity()) == local_registered_.end()) { + return routePreparedMsg(msg); + } else { + return routeMsgHandlerLocal(msg); + } +} + +template +template *f> +void EntityLocationCoord::setupMessageForRouting( + EntityID const& id, NodeType const& home_node, + MsgSharedPtr const& msg ) { using auto_registry::HandlerManagerType; @@ -668,12 +691,10 @@ void EntityLocationCoord::routeMsgHandler( # endif msg->setHandler(handler); - - if (local_registered_.find(id) == local_registered_.end()) { - return routeMsg(id,home_node,msg); - } else { - return routeMsgHandlerLocal(msg); - } + msg->setEntity(id); + msg->setHomeNode(home_node); + msg->setLocFromNode(theContext()->getNode()); + msg->setLocInst(this_inst); } template @@ -688,19 +709,9 @@ void EntityLocationCoord::routeMsgHandlerLocal( template template -void EntityLocationCoord::routeMsg( - EntityID const& id, NodeType const& home_node, - MsgSharedPtr const& msg, NodeType from_node +void EntityLocationCoord::routePreparedMsg( + MsgSharedPtr const& msg ) { - auto const from = - from_node == uninitialized_destination ? theContext()->getNode() : - from_node; - - // set field for location routed message - msg->setEntity(id); - msg->setHomeNode(home_node); - msg->setLocFromNode(from); - auto const msg_size = sizeof(*msg); bool const use_eager = useEagerProtocol(msg); auto const epoch = theMsg()->getEpochContextMsg(msg); @@ -708,30 +719,48 @@ void EntityLocationCoord::routeMsg( vt_debug_print( verbose, location, "routeMsg: inst={}, home={}, msg_size={}, is_large_msg={}, eager={}, " - "in_from={}, from={}, msg{}, msg from={}, epoch={:x}\n", - this_inst, home_node, msg_size, msg_size > small_msg_max_size, use_eager, - from_node, from, print_ptr(msg.get()), msg->getLocFromNode(), + "msg={}, from={}, epoch={:x}\n", + this_inst, msg->getHomeNode(), msg_size, msg_size > small_msg_max_size, use_eager, + print_ptr(msg.get()), msg->getLocFromNode(), epoch ); - msg->setLocInst(this_inst); - if (use_eager) { theMsg()->pushEpoch(epoch); - routeMsgEager(id, home_node, msg); + routeMsgEager(msg->getEntity(), msg->getHomeNode(), msg); theMsg()->popEpoch(epoch); } else { theTerm()->produce(epoch); // non-eager protocol: get location first then send message after resolution - getLocation(id, home_node, [=](NodeType node) { + getLocation(msg->getEntity(), msg->getHomeNode(), [=](NodeType node) { theMsg()->pushEpoch(epoch); - routeMsgNode(id, home_node, node, msg); + routeMsgNode( + msg->getEntity(), msg->getHomeNode(), node, msg + ); theMsg()->popEpoch(epoch); theTerm()->consume(epoch); }); } } +template +template +void EntityLocationCoord::routeMsg( + EntityID const& id, NodeType const& home_node, + MsgSharedPtr const& msg, NodeType from_node +) { + auto const from = + from_node == uninitialized_destination ? theContext()->getNode() : + from_node; + + // set field for location routed message + msg->setEntity(id); + msg->setHomeNode(home_node); + msg->setLocFromNode(from); + + routePreparedMsg(msg); +} + template void EntityLocationCoord::updatePendingRequest( LocEventID const& event_id, EntityID const& id, @@ -863,7 +892,7 @@ template ); msg2->setResolvedNode(node); theMsg()->markAsLocationMessage(msg2); - theMsg()->sendMsg::updateLocation>(ask_node, msg2); + theMsg()->sendMsg<&EntityLocationCoord::updateLocation>(ask_node, msg2); }); theMsg()->popEpoch(epoch); theTerm()->consume(epoch); diff --git a/src/vt/trace/trace.cc b/src/vt/trace/trace.cc index dd1f3a7dff..885fc450ca 100644 --- a/src/vt/trace/trace.cc +++ b/src/vt/trace/trace.cc @@ -117,7 +117,7 @@ void Trace::startup() /*override*/ { void Trace::finalize() /*override*/ { // Always end any between-loop event left open. - endProcessing(between_sched_event_); + endProcessing(between_sched_event_, timing::getCurrentTime()); between_sched_event_ = TraceProcessingTag{}; } @@ -335,9 +335,9 @@ void Trace::addMemoryEvent(std::size_t memory, double time) { TraceProcessingTag Trace::beginProcessing( TraceEntryIDType const ep, TraceMsgLenType const len, TraceEventIDType const event, NodeType const from_node, + TimeType const time, uint64_t const idx1, uint64_t const idx2, - uint64_t const idx3, uint64_t const idx4, - double const time + uint64_t const idx3, uint64_t const idx4 ) { if (not checkDynamicRuntimeEnabled()) { return TraceProcessingTag{}; @@ -367,7 +367,7 @@ TraceProcessingTag Trace::beginProcessing( void Trace::endProcessing( TraceProcessingTag const& processing_tag, - double const time + TimeType const time ) { // End event honored even if tracing is disabled in this phase. // This ensures proper stack unwinding in all contexts. @@ -420,13 +420,13 @@ void Trace::endProcessing( void Trace::pendingSchedulerLoop() { // Always end between-loop event. - endProcessing(between_sched_event_); + endProcessing(between_sched_event_, timing::getCurrentTime()); between_sched_event_ = TraceProcessingTag{}; } void Trace::beginSchedulerLoop() { // Always end between-loop event. The pending case is not always triggered. - endProcessing(between_sched_event_); + endProcessing(between_sched_event_, timing::getCurrentTime()); between_sched_event_ = TraceProcessingTag{}; // Capture the current open event depth. @@ -449,7 +449,7 @@ void Trace::endSchedulerLoop() { // Start an event representing time outside of top-level scheduler. if (event_holds_.size() == 1) { between_sched_event_ = beginProcessing( - between_sched_event_type_, 0, trace::no_trace_event, 0 + between_sched_event_type_, 0, trace::no_trace_event, 0, timing::getCurrentTime() ); } } diff --git a/src/vt/trace/trace.h b/src/vt/trace/trace.h index e41fe2050f..31fe8b6c8b 100644 --- a/src/vt/trace/trace.h +++ b/src/vt/trace/trace.h @@ -136,20 +136,20 @@ struct Trace : runtime::component::Component, TraceLite { * \param[in] len size of message in bytes * \param[in] event the associated trace event * \param[in] from_node which node instigated this processing + * \param[in] time the time this occurred * \param[in] idx1 (optional) if collection, dimension 1 * \param[in] idx2 (optional) if collection, dimension 2 * \param[in] idx3 (optional) if collection, dimension 3 * \param[in] idx4 (optional) if collection, dimension 4 - * \param[in] time the time this occurred * * \return a tag to close this processing event */ TraceProcessingTag beginProcessing( TraceEntryIDType const ep, TraceMsgLenType const len, TraceEventIDType const event, NodeType const from_node, + TimeType const time, uint64_t const idx1 = 0, uint64_t const idx2 = 0, - uint64_t const idx3 = 0, uint64_t const idx4 = 0, - double const time = getCurrentTime() + uint64_t const idx3 = 0, uint64_t const idx4 = 0 ); /** @@ -162,7 +162,7 @@ struct Trace : runtime::component::Component, TraceLite { */ void endProcessing( TraceProcessingTag const& processing_tag, - double const time = getCurrentTime() + TimeType const time ); /** diff --git a/src/vt/trace/trace_user_event.cc b/src/vt/trace/trace_user_event.cc index 3d7e74a9bd..483f0dec80 100644 --- a/src/vt/trace/trace_user_event.cc +++ b/src/vt/trace/trace_user_event.cc @@ -87,7 +87,7 @@ UserEventIDType UserEventRegistry::hash(std::string const& in_event_name) { auto const node = theContext()->getNode(); if (node != 0) { auto msg = makeMessage(false, id, in_event_name); - theMsg()->sendMsg(0, msg); + theMsg()->sendMsg(0, msg); } } return id; @@ -99,7 +99,7 @@ UserEventIDType UserEventRegistry::rooted(std::string const& in_event_name) { auto const node = theContext()->getNode(); if (node != 0) { auto msg = makeMessage(false, id, in_event_name); - theMsg()->sendMsg(0, msg); + theMsg()->sendMsg(0, msg); } return id; } @@ -112,7 +112,7 @@ UserEventIDType UserEventRegistry::user( auto const node = theContext()->getNode(); if (node != 0) { auto msg = makeMessage(true, id, in_event_name); - theMsg()->sendMsg(0, msg); + theMsg()->sendMsg(0, msg); } return id; } diff --git a/src/vt/transport.h b/src/vt/transport.h index d035867f7a..3db2d37da5 100644 --- a/src/vt/transport.h +++ b/src/vt/transport.h @@ -56,7 +56,6 @@ #include "vt/collective/collective.h" #include "vt/event/event.h" #include "vt/messaging/active.h" -#include "vt/parameterization/parameterization.h" #include "vt/event/event_msgs.h" #include "vt/termination/termination.h" #include "vt/rdma/rdma_headers.h" @@ -69,8 +68,6 @@ #include "vt/vrt/context/context_vrtheaders.h" #include "vt/vrt/collection/collection_headers.h" #include "vt/standalone/vt_main.h" -#include "vt/utils/tls/tls.h" -#include "vt/utils/atomic/atomic.h" #include "vt/group/group_headers.h" #include "vt/epoch/epoch_headers.h" #include "vt/pipe/pipe_headers.h" diff --git a/src/vt/utils/adt/union.h b/src/vt/utils/adt/union.h index 5ed5d436cd..ba047537d6 100644 --- a/src/vt/utils/adt/union.h +++ b/src/vt/utils/adt/union.h @@ -724,7 +724,7 @@ struct AlignedCharUnion : UnionCopy { template void staticAssertCorrectness() const { - detail::AllUnique{}; + vt_force_use(detail::AllUnique{}); static_assert( detail::MustBe::is_same, "Must be the valid type in union" ); diff --git a/src/vt/utils/atomic/atomic.h b/src/vt/utils/atomic/atomic.h deleted file mode 100644 index 702a89b593..0000000000 --- a/src/vt/utils/atomic/atomic.h +++ /dev/null @@ -1,72 +0,0 @@ -/* -//@HEADER -// ***************************************************************************** -// -// atomic.h -// DARMA/vt => Virtual Transport -// -// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC -// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. -// Government retains certain rights in this software. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Questions? Contact darma@sandia.gov -// -// ***************************************************************************** -//@HEADER -*/ - -#if !defined INCLUDED_VT_UTILS_ATOMIC_ATOMIC_H -#define INCLUDED_VT_UTILS_ATOMIC_ATOMIC_H - -#include "vt/config.h" - -#if vt_check_enabled(openmp) - #include "vt/utils/atomic/omp_atomic.h" -#elif vt_check_enabled(stdthread) - #include "vt/utils/atomic/std_atomic.h" -#else - #include "vt/utils/atomic/null_atomic.h" -#endif - -namespace vt { namespace util { namespace atomic { - -#if vt_check_enabled(openmp) - template - using AtomicType = AtomicOMP; -#elif vt_check_enabled(stdthread) - template - using AtomicType = AtomicSTD; -#else - template - using AtomicType = AtomicNull; -#endif - -}}} /* end namespace vt::util::atomic */ - -#endif /*INCLUDED_VT_UTILS_ATOMIC_ATOMIC_H*/ diff --git a/src/vt/utils/atomic/null_atomic.h b/src/vt/utils/atomic/null_atomic.h deleted file mode 100644 index 80d2d31b87..0000000000 --- a/src/vt/utils/atomic/null_atomic.h +++ /dev/null @@ -1,104 +0,0 @@ -/* -//@HEADER -// ***************************************************************************** -// -// null_atomic.h -// DARMA/vt => Virtual Transport -// -// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC -// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. -// Government retains certain rights in this software. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Questions? Contact darma@sandia.gov -// -// ***************************************************************************** -//@HEADER -*/ - -#if !defined INCLUDED_VT_UTILS_ATOMIC_NULL_ATOMIC_H -#define INCLUDED_VT_UTILS_ATOMIC_NULL_ATOMIC_H - -#include "vt/config.h" - -#if backend_no_threading - -// Needed for memory order -#include - -namespace vt { namespace util { namespace atomic { - -static constexpr std::memory_order order_default = std::memory_order_seq_cst; - -template -struct AtomicNull { - using OrderType = std::memory_order; - - AtomicNull(T&& in_value) : value_(std::forward(in_value)) { } - AtomicNull(T const& in_value) : value_(in_value) { } - AtomicNull(AtomicNull const&) = delete; - AtomicNull& operator=(AtomicNull const&) = delete; - - inline void add(T const in) { value_ += in; } - inline void sub(T const in) { value_ -= in; } - inline T fetch_add(T const in) { T tmp = value_; value_ += in; return tmp; } - inline T add_fetch(T const in) { value_ += in; return value_; } - inline T fetch_sub(T const in) { T tmp = value_; value_ -= in; return tmp; } - inline T sub_fetch(T const in) { value_ -= in; return value_; } - - // pre-increment - T operator++() { return fetch_add(1) + 1; } - T operator--() { return fetch_sub(1) - 1; } - // post-increment - T operator++(int) { return fetch_add(1); } - T operator--(int) { return fetch_sub(1); } - // operators +=, -= (pre-increment type operation) - T operator+=(T const& val) { return fetch_add(val) + val; } - T operator-=(T const& val) { return fetch_sub(val) + val; } - - operator T() const { return load(); } - inline T load(OrderType t = order_default) const { return value_; } - inline void store(T in, OrderType t = order_default) { value_ = in; } - T operator=(T in) { store(in); return in; } - - bool compare_exchange_strong( - T& expected, T desired, - OrderType st = order_default, OrderType sf = order_default - ) { - return value_ == expected ? value_ = desired, true : false; - } - -private: - T value_; -}; - -}}} /* end namespace vt::util::atomic */ - -#endif /*backend_no_threading*/ - -#endif /*INCLUDED_VT_UTILS_ATOMIC_NULL_ATOMIC_H*/ diff --git a/src/vt/utils/atomic/omp_atomic.h b/src/vt/utils/atomic/omp_atomic.h deleted file mode 100644 index f92c0c6121..0000000000 --- a/src/vt/utils/atomic/omp_atomic.h +++ /dev/null @@ -1,179 +0,0 @@ -/* -//@HEADER -// ***************************************************************************** -// -// omp_atomic.h -// DARMA/vt => Virtual Transport -// -// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC -// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. -// Government retains certain rights in this software. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Questions? Contact darma@sandia.gov -// -// ***************************************************************************** -//@HEADER -*/ - -#if !defined INCLUDED_VT_UTILS_ATOMIC_OMP_ATOMIC_H -#define INCLUDED_VT_UTILS_ATOMIC_OMP_ATOMIC_H - -#include "vt/config.h" - -#if vt_check_enabled(openmp) - -#include -#include - -namespace vt { namespace util { namespace atomic { - -template -struct AtomicOMP { - AtomicOMP(T&& in_value) : value_(std::forward(in_value)) { } - AtomicOMP(T const& in_value) : value_(in_value) { } - AtomicOMP(AtomicOMP const&) = delete; - AtomicOMP& operator=(AtomicOMP const&) = delete; - - void add(T const in) { - #pragma omp atomic update - value_ += in; - } - - void sub(T const in) { - #pragma omp atomic update - value_ -= in; - } - - T fetch_add(T const in) { - T tmp; - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wunused-value" - #pragma omp atomic capture - { - tmp = value_; - value_ += in; - } - #pragma GCC diagnostic pop - return tmp; - } - - T add_fetch(T const in) { - T tmp; - #pragma omp atomic capture - { - value_ += in; - tmp = value_; - } - return tmp; - } - - T fetch_sub(T const in) { - T tmp; - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wunused-value" - #pragma omp atomic capture - { - tmp = value_; - value_ -= in; - } - #pragma GCC diagnostic pop - return tmp; - } - - T sub_fetch(T const in) { - T tmp; - #pragma omp atomic capture - { - value_ -= in; - tmp = value_; - } - return tmp; - } - - // pre-increment - T operator++() { return fetch_add(1) + 1; } - T operator--() { return fetch_sub(1) - 1; } - // post-increment - T operator++(int) { return fetch_add(1); } - T operator--(int) { return fetch_sub(1); } - // operators +=, -= (pre-increment type operation) - T operator+=(T const& val) { return fetch_add(val) + val; } - T operator-=(T const& val) { return fetch_sub(val) + val; } - - operator T() const { - return load(); - } - - T load(std::memory_order order = std::memory_order_seq_cst) const { - T tmp; - #pragma omp atomic read - tmp = value_; - return tmp; - } - - void store(T in, std::memory_order order = std::memory_order_seq_cst) { - #pragma omp atomic write - value_ = in; - } - - T operator=(T in) { - store(in); - return in; - } - - bool compare_exchange_strong( - T& expected, T desired, - std::memory_order success = std::memory_order_seq_cst, - std::memory_order failure = std::memory_order_seq_cst - ) { - bool cas_succeed = false; - #pragma omp critical - { - if (value_ == expected) { - value_ = desired; - cas_succeed = true; - } - } - return cas_succeed; - } - - template - void serialize(Serializer& s) { - s | value_; - } - -private: - T value_; -}; - -}}} /* end namespace vt::util::atomic */ - -#endif /*vt_check_enabled(openmp)*/ - -#endif /*INCLUDED_VT_UTILS_ATOMIC_OMP_ATOMIC_H*/ diff --git a/src/vt/utils/atomic/std_atomic.h b/src/vt/utils/atomic/std_atomic.h deleted file mode 100644 index 433e9a1807..0000000000 --- a/src/vt/utils/atomic/std_atomic.h +++ /dev/null @@ -1,61 +0,0 @@ -/* -//@HEADER -// ***************************************************************************** -// -// std_atomic.h -// DARMA/vt => Virtual Transport -// -// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC -// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. -// Government retains certain rights in this software. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Questions? Contact darma@sandia.gov -// -// ***************************************************************************** -//@HEADER -*/ - -#if !defined INCLUDED_VT_UTILS_ATOMIC_STD_ATOMIC_H -#define INCLUDED_VT_UTILS_ATOMIC_STD_ATOMIC_H - -#include "vt/config.h" - -#if vt_check_enabled(stdthread) -#include - -namespace vt { namespace util { namespace atomic { - -template -using AtomicSTD = std::atomic; - -}}} /* end namespace vt::util::atomic */ - -#endif /*vt_check_enabled(stdthread)*/ - -#endif /*INCLUDED_VT_UTILS_ATOMIC_STD_ATOMIC_H*/ diff --git a/src/vt/utils/container/concurrent_deque_locked.h b/src/vt/utils/container/concurrent_deque_locked.h index e0f514ecb2..18be51d3bd 100644 --- a/src/vt/utils/container/concurrent_deque_locked.h +++ b/src/vt/utils/container/concurrent_deque_locked.h @@ -55,8 +55,6 @@ namespace vt { namespace util { namespace container { -using ::vt::util::mutex::MutexType; - /* * Implement a very simple concurrent deque that just uses std::mutex for access * control... obviously this should be greatly improved and made lock free but @@ -110,11 +108,11 @@ struct ConcurrentDequeLocked { } private: - MutexType* getMutex(); + std::mutex* getMutex(); private: bool needs_lock_ = true; - MutexType container_mutex_{}; + std::mutex container_mutex_{}; ContainerType container_; }; diff --git a/src/vt/utils/container/concurrent_deque_locked.impl.h b/src/vt/utils/container/concurrent_deque_locked.impl.h index 0b8c76958f..fb3659b50f 100644 --- a/src/vt/utils/container/concurrent_deque_locked.impl.h +++ b/src/vt/utils/container/concurrent_deque_locked.impl.h @@ -45,7 +45,6 @@ #define INCLUDED_VT_UTILS_CONTAINER_CONCURRENT_DEQUE_LOCKED_IMPL_H #include "vt/config.h" -#include "vt/utils/mutex/mutex.h" #include "vt/utils/container/concurrent_deque_locked.h" #include @@ -53,42 +52,41 @@ namespace vt { namespace util { namespace container { -using ::vt::util::mutex::LockGuardPtrType; -using ::vt::util::mutex::MutexType; +using LockGuardType = std::lock_guard; template -MutexType* ConcurrentDequeLocked::getMutex() { +std::mutex* ConcurrentDequeLocked::getMutex() { return needs_lock_ ? &container_mutex_: nullptr; } template void ConcurrentDequeLocked::emplaceBack(T&& elm) { - LockGuardPtrType lock(getMutex()); + LockGuardType lock(getMutex()); container_.emplace_back(std::forward(elm)); } template void ConcurrentDequeLocked::emplaceFront(T&& elm) { - LockGuardPtrType lock(getMutex()); + LockGuardType lock(getMutex()); container_.emplace_front(std::forward(elm)); } template void ConcurrentDequeLocked::pushBack(T const& elm) { - LockGuardPtrType lock(getMutex()); + LockGuardType lock(getMutex()); container_.push_back(elm); } template void ConcurrentDequeLocked::pushFront(T const& elm) { - LockGuardPtrType lock(getMutex()); + LockGuardType lock(getMutex()); container_.push_front(elm); } template typename ConcurrentDequeLocked::TConstRef ConcurrentDequeLocked::front() const { - LockGuardPtrType lock(getMutex()); + LockGuardType lock(getMutex()); auto const& val = container_.front(); return val; } @@ -96,14 +94,14 @@ ConcurrentDequeLocked::front() const { template typename ConcurrentDequeLocked::TConstRef ConcurrentDequeLocked::back() const { - LockGuardPtrType lock(getMutex()); + LockGuardType lock(getMutex()); auto const& val = container_.back(); return val; } template T ConcurrentDequeLocked::popGetFront() { - LockGuardPtrType lock(getMutex()); + LockGuardType lock(getMutex()); auto elm = container_.front(); container_.pop_front(); return elm; @@ -111,7 +109,7 @@ T ConcurrentDequeLocked::popGetFront() { template T ConcurrentDequeLocked::popGetBack() { - LockGuardPtrType lock(getMutex()); + LockGuardType lock(getMutex()); auto elm = container_.back(); container_.pop_back(); return elm; @@ -120,7 +118,7 @@ T ConcurrentDequeLocked::popGetBack() { template typename ConcurrentDequeLocked::TRef ConcurrentDequeLocked::at(SizeType const& pos) { - LockGuardPtrType lock(getMutex()); + LockGuardType lock(getMutex()); auto& val = container_.at(pos); return val; } @@ -129,40 +127,40 @@ template typename ConcurrentDequeLocked::TConstRef ConcurrentDequeLocked::at( SizeType const& pos ) const { - LockGuardPtrType lock(getMutex()); + LockGuardType lock(getMutex()); auto const& val = container_.at(pos); return val; } template typename ConcurrentDequeLocked::TRef ConcurrentDequeLocked::front() { - LockGuardPtrType lock(getMutex()); + LockGuardType lock(getMutex()); auto& val = container_.front(); return val; } template typename ConcurrentDequeLocked::TRef ConcurrentDequeLocked::back() { - LockGuardPtrType lock(getMutex()); + LockGuardType lock(getMutex()); auto& val = container_.back(); return val; } template void ConcurrentDequeLocked::popFront() { - LockGuardPtrType lock(getMutex()); + LockGuardType lock(getMutex()); container_.pop_front(); } template void ConcurrentDequeLocked::popBack() { - LockGuardPtrType lock(getMutex()); + LockGuardType lock(getMutex()); container_.pop_back(); } template typename ConcurrentDequeLocked::SizeType ConcurrentDequeLocked::size() { - LockGuardPtrType lock(getMutex()); + LockGuardType lock(getMutex()); auto const& val = container_.size(); return val; } diff --git a/src/vt/utils/container/process_ready_buffer.h b/src/vt/utils/container/process_ready_buffer.h deleted file mode 100644 index 7602126695..0000000000 --- a/src/vt/utils/container/process_ready_buffer.h +++ /dev/null @@ -1,134 +0,0 @@ -/* -//@HEADER -// ***************************************************************************** -// -// process_ready_buffer.h -// DARMA/vt => Virtual Transport -// -// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC -// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. -// Government retains certain rights in this software. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Questions? Contact darma@sandia.gov -// -// ***************************************************************************** -//@HEADER -*/ - -#if !defined INCLUDED_VT_UTILS_CONTAINER_PROCESS_READY_BUFFER_H -#define INCLUDED_VT_UTILS_CONTAINER_PROCESS_READY_BUFFER_H - -#include "vt/config.h" -#include "vt/context/context.h" -#include "vt/utils/mutex/mutex.h" - -#include -#include - -namespace vt { namespace util { namespace container { - -using ::vt::util::mutex::MutexType; -using ::vt::util::mutex::LockGuardPtrType; - -template -struct ProcessBuffer { - using ProcessFnType = std::function; - - void push(T const& elm) { - LockGuardPtrType lock(getMutex()); - buffer_.push_back(elm); - progressEngine(true); - } - - void emplace(T&& elm) { - LockGuardPtrType lock(getMutex()); - buffer_.emplace_back(std::forward(elm)); - progressEngine(true); - } - - void attach(ProcessFnType fn, WorkerIDType worker = no_worker_id) { - LockGuardPtrType lock(getMutex()); - process_fn_ = fn; - worker_ = worker; - progressEngine(true); - } - - inline void progress() { progressEngine(false); } - - template - void serialize(Serializer& s) { - s | buffer_ - | needs_lock_ - | worker_ - | process_fn_ - | mutex_; - } - -private: - void apply(ProcessFnType fn, bool locked) { - bool found = true; - T elm_out; - do { - { - LockGuardPtrType lock(locked ? nullptr : getMutex()); - if (buffer_.size() > 0) { - found = true; - T elm(std::move(buffer_.front())); - elm_out = std::move(elm); - buffer_.pop_front(); - } else { - found = false; - } - } - if (found) { - fn(elm_out); - } - } while (found); - } - -private: - inline void progressEngine(bool has_lock) { - if (process_fn_ && isProcessWorker()) { apply(process_fn_, has_lock); } - } - inline bool isProcessWorker() const { - return worker_ == no_worker_id || worker_ == ::vt::theContext()->getWorker(); - } - inline MutexType* getMutex() { return needs_lock_ ? &mutex_: nullptr; } - -private: - std::list buffer_; - bool needs_lock_ = true; - MutexType mutex_{}; - WorkerIDType worker_ = no_worker_id; - ProcessFnType process_fn_ = nullptr; -}; - -}}} /* end namespace vt::util::container */ - -#endif /*INCLUDED_VT_UTILS_CONTAINER_PROCESS_READY_BUFFER_H*/ diff --git a/src/vt/utils/fntraits/fntraits.h b/src/vt/utils/fntraits/fntraits.h new file mode 100644 index 0000000000..92dbde7af1 --- /dev/null +++ b/src/vt/utils/fntraits/fntraits.h @@ -0,0 +1,214 @@ +/* +//@HEADER +// ***************************************************************************** +// +// fntraits.h +// DARMA/vt => Virtual Transport +// +// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC +// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. +// Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from this +// software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact darma@sandia.gov +// +// ***************************************************************************** +//@HEADER +*/ + +#if !defined INCLUDED_VT_UTILS_FNTRAITS_FNTRAITS_H +#define INCLUDED_VT_UTILS_FNTRAITS_FNTRAITS_H + +namespace vt::util::fntraits::detail { + +struct NoMsg {}; + +template +struct ObjFuncTraitsImpl; + +template +struct ObjFuncTraitsImpl< + std::enable_if_t< + std::is_convertible::value or + std::is_convertible::value or + std::is_convertible::value or + std::is_convertible::value + >, + Return(*)(Obj*, Msg*) +> { + static constexpr bool is_member = false; + using ObjT = Obj; + using MsgT = Msg; + using ReturnT = Return; +}; + +template +struct ObjFuncTraitsImpl< + std::enable_if_t>, + Return(*)(Obj*) +> { + static constexpr bool is_member = false; + using ObjT = Obj; + using MsgT = NoMsg; + using ReturnT = Return; + using TupleType = std::tuple<>; +}; + +template +struct ObjFuncTraitsImpl< + std::enable_if_t< + not ( + std::is_convertible::value or + std::is_convertible::value or + std::is_convertible::value or + std::is_convertible::value + ) + >, + Return(*)(Obj*, Arg, Args...) +> { + static constexpr bool is_member = false; + using ObjT = Obj; + using MsgT = NoMsg; + using TupleType = std::tuple, std::decay_t...>; + using ReturnT = Return; +}; + +template +struct ObjFuncTraitsImpl< + std::enable_if_t< + std::is_convertible::value or + std::is_convertible::value or + std::is_convertible::value or + std::is_convertible::value + >, + Return(Obj::*)(Msg*) +> { + static constexpr bool is_member = true; + using ObjT = Obj; + using MsgT = Msg; + using ReturnT = Return; +}; + +template +struct ObjFuncTraitsImpl< + std::enable_if_t>, + Return(Obj::*)() +> { + static constexpr bool is_member = true; + using ObjT = Obj; + using MsgT = NoMsg; + using TupleType = std::tuple<>; + using ReturnT = Return; +}; + +template +struct ObjFuncTraitsImpl< + std::enable_if_t< + not ( + std::is_convertible::value or + std::is_convertible::value or + std::is_convertible::value or + std::is_convertible::value + ) + >, + Return(Obj::*)(Arg, Args...) +> { + static constexpr bool is_member = true; + using ObjT = Obj; + using MsgT = NoMsg; + using TupleType = std::tuple, std::decay_t...>; + using ReturnT = Return; +}; + +/////////////////////////////////////////////////////////////////////////////// + +template +struct FuncTraitsImpl; + +template +struct FuncTraitsImpl< + std::enable_if_t< + std::is_convertible::value or + std::is_convertible::value or + std::is_convertible::value or + std::is_convertible::value + >, + Return(*)(Msg*) +> { + static constexpr bool is_member = false; + using MsgT = Msg; + using ReturnT = Return; +}; + +template +struct FuncTraitsImpl< + std::enable_if_t>, + Return(*)() +> { + static constexpr bool is_member = false; + using MsgT = NoMsg; + using ReturnT = Return; + using TupleType = std::tuple<>; +}; + +template +struct FuncTraitsImpl< + std::enable_if_t< + not ( + std::is_convertible::value or + std::is_convertible::value or + std::is_convertible::value or + std::is_convertible::value + ) + >, + Return(*)(Arg, Args...) +> { + static constexpr bool is_member = false; + using MsgT = NoMsg; + using Arg1 = Arg; + using TupleType = std::tuple, std::decay_t...>; + using ReturnT = Return; +}; + +} /* end namespace vt::util::fntraits::detail */ + +/////////////////////////////////////////////////////////////////////////////// + +namespace vt { + +template +struct ObjFuncTraits : util::fntraits::detail::ObjFuncTraitsImpl {}; + +template +struct FuncTraits : util::fntraits::detail::FuncTraitsImpl {}; + +using NoMsg = util::fntraits::detail::NoMsg; + +} /* end namespace vt */ + +#endif /*INCLUDED_VT_UTILS_FNTRAITS_FNTRAITS_H*/ diff --git a/src/vt/utils/json/json_appender.h b/src/vt/utils/json/json_appender.h index 3caf69f221..0f742b5581 100644 --- a/src/vt/utils/json/json_appender.h +++ b/src/vt/utils/json/json_appender.h @@ -69,36 +69,36 @@ struct Appender : BaseAppender { * \brief Construct a JSON appender for a specific array with a filename * * \param[in] array the JSON array name - * \param[in] schema_name the JSON schema name + * \param[in] metadata the JSON metadata * \param[in] filename the JSON filename * \param[in] compress whether to compress the output */ Appender( - std::string const& array, std::string const& schema_name, + std::string const& array, jsonlib const& metadata, std::string const& filename, bool compress ) - : Appender(array, schema_name, StreamLike{filename}, compress) + : Appender(array, metadata, StreamLike{filename}, compress) { } /** * \brief Construct a JSON appender for a specific array with a stream * * \param[in] array the JSON array name - * \param[in] schema_name the JSON schema name + * \param[in] metadata the JSON metadata * \param[in] in_os the output stream * \param[in] compress whether to compress the output */ Appender( - std::string const& array, std::string const& schema_name, StreamLike in_os, + std::string const& array, jsonlib const& metadata, StreamLike in_os, bool compress ) : os_(std::move(in_os)), oa_(std::make_shared(os_, compress)) { - oa_->write_character('{'); - auto schema_str = fmt::format("\"type\":\"{}\",", schema_name); - oa_->write_characters(schema_str.c_str(), schema_str.length()); - auto str = fmt::format("\"{}\":[", array); + oa_->write_characters("{\"metadata\":", 12); + SerializerType s(oa_, ' ', jsonlib::error_handler_t::strict); + s.dump(metadata, false, true, 0); + auto str = fmt::format(",\"{}\":[", array); oa_->write_characters(str.c_str(), str.length()); } diff --git a/src/vt/utils/mutex/lock_guard.h b/src/vt/utils/mutex/lock_guard.h deleted file mode 100644 index 4452cc2f90..0000000000 --- a/src/vt/utils/mutex/lock_guard.h +++ /dev/null @@ -1,77 +0,0 @@ -/* -//@HEADER -// ***************************************************************************** -// -// lock_guard.h -// DARMA/vt => Virtual Transport -// -// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC -// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. -// Government retains certain rights in this software. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Questions? Contact darma@sandia.gov -// -// ***************************************************************************** -//@HEADER -*/ - -#if !defined INCLUDED_VT_UTILS_MUTEX_LOCK_GUARD_H -#define INCLUDED_VT_UTILS_MUTEX_LOCK_GUARD_H - -#include "vt/config.h" - -#include - -namespace vt { namespace util { namespace mutex { - -template -using LockGuardAnyType = std::lock_guard; - -template -struct LockGuardPtr { - explicit LockGuardPtr(MutexT* mutex) : mutex_(mutex) { - if (mutex_) { mutex_->lock(); } - } - LockGuardPtr(LockGuardPtr const&) = delete; - LockGuardPtr& operator=(LockGuardPtr const&) = delete; - - ~LockGuardPtr() { - if (mutex_) { mutex_->unlock(); } - } - -private: - MutexT* mutex_ = nullptr; -}; - -template -using LockGuardAnyPtrType = LockGuardPtr; - -}}} // end namespace vt::util::mutex - -#endif /*INCLUDED_VT_UTILS_MUTEX_LOCK_GUARD_H*/ diff --git a/src/vt/utils/mutex/mutex.h b/src/vt/utils/mutex/mutex.h deleted file mode 100644 index 1c25fbc8ff..0000000000 --- a/src/vt/utils/mutex/mutex.h +++ /dev/null @@ -1,78 +0,0 @@ -/* -//@HEADER -// ***************************************************************************** -// -// mutex.h -// DARMA/vt => Virtual Transport -// -// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC -// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. -// Government retains certain rights in this software. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Questions? Contact darma@sandia.gov -// -// ***************************************************************************** -//@HEADER -*/ - -#if !defined INCLUDED_VT_UTILS_MUTEX_MUTEX_H -#define INCLUDED_VT_UTILS_MUTEX_MUTEX_H - -#include "vt/config.h" -#include "vt/utils/mutex/lock_guard.h" -#include "vt/utils/mutex/null_mutex.h" - -#include - -#if vt_check_enabled(openmp) - #include "vt/utils/mutex/omp_mutex.h" -#elif vt_check_enabled(stdthread) - #include "vt/utils/mutex/std_mutex.h" -#else - #include "vt/utils/mutex/null_mutex.h" -#endif - -namespace vt { namespace util { namespace mutex { - -#if vt_check_enabled(openmp) - using MutexType = OMPMutex; -#elif vt_check_enabled(stdthread) - using MutexType = STDMutex; -#else - using MutexType = NullMutex; -#endif - -using NullMutexType = NullMutex; - -using LockGuardType = LockGuardAnyType; -using LockGuardPtrType = LockGuardAnyPtrType; - -}}} /* end namespace vt::util::mutex */ - -#endif /*INCLUDED_VT_UTILS_MUTEX_MUTEX_H*/ diff --git a/src/vt/utils/mutex/mutex_traits.h b/src/vt/utils/mutex/mutex_traits.h deleted file mode 100644 index 4c158b754e..0000000000 --- a/src/vt/utils/mutex/mutex_traits.h +++ /dev/null @@ -1,86 +0,0 @@ -/* -//@HEADER -// ***************************************************************************** -// -// mutex_traits.h -// DARMA/vt => Virtual Transport -// -// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC -// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. -// Government retains certain rights in this software. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Questions? Contact darma@sandia.gov -// -// ***************************************************************************** -//@HEADER -*/ - -#if !defined INCLUDED_VT_UTILS_MUTEX_MUTEX_TRAITS_H -#define INCLUDED_VT_UTILS_MUTEX_MUTEX_TRAITS_H - -#include "vt/config.h" - -#include "detector_headers.h" - -namespace vt { namespace util { namespace mutex { - -template -struct MutexTraits { - template - using constructor_t = decltype(U(std::declval()...)); - using has_constructor = detection::is_detected; - - template - using copy_constructor_t = decltype(U(std::declval())); - using has_copy_constructor = detection::is_detected; - - template - using lock_t = decltype(std::declval().lock()); - using has_lock = detection::is_detected; - - template - using unlock_t = decltype(std::declval().unlock()); - using has_unlock = detection::is_detected; - - template - using try_lock_t = decltype(std::declval().try_lock()); - using has_try_lock = detection::is_detected_exact; - - // This defines what it means to be an `mutex' - static constexpr auto const is_mutex = - // default constructor and copy constructor - has_constructor::value and not has_copy_constructor::value and - // methods: lock(), unlock(), try_lock() - has_lock::value and has_unlock::value and - has_try_lock::value; -}; - -}}} /* end namespace vt::util::mutex */ - -#endif /*INCLUDED_VT_UTILS_MUTEX_MUTEX_TRAITS_H*/ diff --git a/src/vt/utils/mutex/null_mutex.h b/src/vt/utils/mutex/null_mutex.h deleted file mode 100644 index 61a463ab50..0000000000 --- a/src/vt/utils/mutex/null_mutex.h +++ /dev/null @@ -1,64 +0,0 @@ -/* -//@HEADER -// ***************************************************************************** -// -// null_mutex.h -// DARMA/vt => Virtual Transport -// -// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC -// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. -// Government retains certain rights in this software. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Questions? Contact darma@sandia.gov -// -// ***************************************************************************** -//@HEADER -*/ - -#if !defined INCLUDED_VT_UTILS_MUTEX_NULL_MUTEX_H -#define INCLUDED_VT_UTILS_MUTEX_NULL_MUTEX_H - -#include "vt/config.h" - -namespace vt { namespace util { namespace mutex { - -struct NullMutex { - NullMutex() = default; - NullMutex(NullMutex const&) = delete; - - virtual ~NullMutex() = default; - - void lock() { } - void unlock() { } - bool try_lock() { return true; } -}; - -}}} /* end namespace vt::util::mutex */ - -#endif /*INCLUDED_VT_UTILS_MUTEX_NULL_MUTEX_H*/ diff --git a/src/vt/utils/mutex/omp_mutex.cc b/src/vt/utils/mutex/omp_mutex.cc deleted file mode 100644 index fabadfd134..0000000000 --- a/src/vt/utils/mutex/omp_mutex.cc +++ /dev/null @@ -1,80 +0,0 @@ -/* -//@HEADER -// ***************************************************************************** -// -// omp_mutex.cc -// DARMA/vt => Virtual Transport -// -// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC -// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. -// Government retains certain rights in this software. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Questions? Contact darma@sandia.gov -// -// ***************************************************************************** -//@HEADER -*/ - -#include "vt/config.h" -#include "vt/utils/mutex/omp_mutex.h" - -#if vt_check_enabled(openmp) - -#include - -namespace vt { namespace util { namespace mutex { - -OMPMutex::OMPMutex() { - //fmt::print("constructing lock: ptr={}\n", &omp_lock); - omp_init_lock(&omp_lock); -} - -OMPMutex::~OMPMutex() { - // There is a bug in OpenMP that causes this to segfault when it's called - // after the OpenMP runtime is already finalized. - - //omp_destroy_lock(&omp_lock); -} - -void OMPMutex::lock() { - omp_set_lock(&omp_lock); -} - -void OMPMutex::unlock() { - omp_unset_lock(&omp_lock); -} - -bool OMPMutex::try_lock() { - int const ret = omp_test_lock(&omp_lock); - return ret == 1; -} - -}}} /* end namespace vt::util::mutex */ - -#endif diff --git a/src/vt/utils/mutex/std_mutex.h b/src/vt/utils/mutex/std_mutex.h deleted file mode 100644 index dfb43b8e8f..0000000000 --- a/src/vt/utils/mutex/std_mutex.h +++ /dev/null @@ -1,71 +0,0 @@ -/* -//@HEADER -// ***************************************************************************** -// -// std_mutex.h -// DARMA/vt => Virtual Transport -// -// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC -// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. -// Government retains certain rights in this software. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Questions? Contact darma@sandia.gov -// -// ***************************************************************************** -//@HEADER -*/ - -#if !defined INCLUDED_VT_UTILS_MUTEX_STD_MUTEX_H -#define INCLUDED_VT_UTILS_MUTEX_STD_MUTEX_H - -#include "vt/config.h" - -#if vt_check_enabled(stdthread) -#include - -namespace vt { namespace util { namespace mutex { - -using STDMutex = std::mutex; - -}}} // end namespace vt::util::mutex - -#include "vt/utils/mutex/mutex_traits.h" - -namespace vt { namespace util { namespace mutex { - -static_assert( - MutexTraits::is_mutex, - "STDMutex should follow the mutex concept" -); - -}}} // end namespace vt::util::mutex - -#endif /*vt_check_enabled(stdthread)*/ - -#endif /*INCLUDED_VT_UTILS_MUTEX_STD_MUTEX_H*/ diff --git a/src/vt/utils/tls/null_tls.h b/src/vt/utils/tls/null_tls.h deleted file mode 100644 index 4290444924..0000000000 --- a/src/vt/utils/tls/null_tls.h +++ /dev/null @@ -1,81 +0,0 @@ -/* -//@HEADER -// ***************************************************************************** -// -// null_tls.h -// DARMA/vt => Virtual Transport -// -// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC -// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. -// Government retains certain rights in this software. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Questions? Contact darma@sandia.gov -// -// ***************************************************************************** -//@HEADER -*/ - -#if !defined INCLUDED_VT_UTILS_TLS_NULL_TLS_H -#define INCLUDED_VT_UTILS_TLS_NULL_TLS_H - -#include "vt/config.h" - -#if backend_no_threading || backend_null_tls - -namespace vt { namespace util { namespace tls { - -template -struct ThreadLocalNull { - T& get() { access_++; return value_; } - int64_t numAccess() const { return access_; } -private: - static T value_; - int64_t access_ = 0; -}; - -template -struct ThreadLocalInitNull { - T& get() { access_++; return value_; } - int64_t numAccess() const { return access_; } -private: - static T value_; - int64_t access_ = 0; -}; - -template -T ThreadLocalNull::value_; - -template -T ThreadLocalInitNull::value_ = {val}; - -}}} /* end namespace vt::util::tls */ - -#endif /*backend_no_threading*/ - -#endif /*INCLUDED_VT_UTILS_TLS_NULL_TLS_H*/ diff --git a/src/vt/utils/tls/omp_tls.h b/src/vt/utils/tls/omp_tls.h deleted file mode 100644 index cf3ada77fe..0000000000 --- a/src/vt/utils/tls/omp_tls.h +++ /dev/null @@ -1,99 +0,0 @@ -/* -//@HEADER -// ***************************************************************************** -// -// omp_tls.h -// DARMA/vt => Virtual Transport -// -// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC -// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. -// Government retains certain rights in this software. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Questions? Contact darma@sandia.gov -// -// ***************************************************************************** -//@HEADER -*/ - -#if !defined INCLUDED_VT_UTILS_TLS_OMP_TLS_H -#define INCLUDED_VT_UTILS_TLS_OMP_TLS_H - -#include "vt/config.h" - -#if vt_check_enabled(openmp) -#include - -namespace vt { namespace util { namespace tls { - -template -struct ThreadLocalInitOMP { - T& get() { access_++; return value_; } - int64_t numAccess() const { return access_; } -private: - #if defined(__GNUC__) - static thread_local T value_; - #else - static T value_; - #pragma omp threadprivate (value_) - #endif - int64_t access_ = 0; -}; - -template -struct ThreadLocalOMP { - T& get() { access_++; return value_; } - int64_t numAccess() const { return access_; } -private: - #if defined(__GNUC__) - static thread_local T value_; - #else - static T value_; - #pragma omp threadprivate (value_) - #endif - int64_t access_ = 0; -}; - -#if defined(__GNUC__) - template - T thread_local ThreadLocalInitOMP::value_ = val; - - template - T thread_local ThreadLocalOMP::value_; -#else - template - T ThreadLocalInitOMP::value_ = val; - - template - T ThreadLocalOMP::value_; -#endif - -}}} /* end namespace vt::util::tls */ - -#endif /*vt_check_enabled(openmp)*/ -#endif /*INCLUDED_VT_UTILS_TLS_OMP_TLS_H*/ diff --git a/src/vt/utils/tls/std_tls.h b/src/vt/utils/tls/std_tls.h deleted file mode 100644 index d1c35fb212..0000000000 --- a/src/vt/utils/tls/std_tls.h +++ /dev/null @@ -1,81 +0,0 @@ -/* -//@HEADER -// ***************************************************************************** -// -// std_tls.h -// DARMA/vt => Virtual Transport -// -// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC -// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. -// Government retains certain rights in this software. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Questions? Contact darma@sandia.gov -// -// ***************************************************************************** -//@HEADER -*/ - -#if !defined INCLUDED_VT_UTILS_TLS_STD_TLS_H -#define INCLUDED_VT_UTILS_TLS_STD_TLS_H - -#include "vt/config.h" - -#if vt_check_enabled(stdthread) - -namespace vt { namespace util { namespace tls { - -template -struct ThreadLocalInitSTD { - T& get() { access_++; return value_; } - int64_t numAccess() const { return access_; } -private: - static thread_local T value_; - int64_t access_ = 0; -}; - -template -struct ThreadLocalSTD { - T& get() { access_++; return value_; } - int64_t numAccess() const { return access_; } -private: - static thread_local T value_; - int64_t access_ = 0; -}; - -template -thread_local T ThreadLocalInitSTD::value_ = {val}; - -template -thread_local T ThreadLocalSTD::value_; - -}}} /* end namespace vt::util::tls */ - -#endif /*vt_check_enabled(stdthread)*/ - -#endif /*INCLUDED_VT_UTILS_TLS_STD_TLS_H*/ diff --git a/src/vt/utils/tls/tls.h b/src/vt/utils/tls/tls.h deleted file mode 100644 index b402f15a37..0000000000 --- a/src/vt/utils/tls/tls.h +++ /dev/null @@ -1,146 +0,0 @@ -/* -//@HEADER -// ***************************************************************************** -// -// tls.h -// DARMA/vt => Virtual Transport -// -// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC -// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. -// Government retains certain rights in this software. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Questions? Contact darma@sandia.gov -// -// ***************************************************************************** -//@HEADER -*/ - -#if !defined INCLUDED_VT_UTILS_TLS_TLS_H -#define INCLUDED_VT_UTILS_TLS_TLS_H - -#include "vt/config.h" - -#define backend_null_tls 1 - -#if vt_check_enabled(openmp) - #include "vt/utils/tls/omp_tls.h" -#elif vt_check_enabled(stdthread) - #include "vt/utils/tls/std_tls.h" -#else - #include "vt/utils/tls/null_tls.h" -#endif - -#if backend_null_tls - #include "vt/utils/tls/null_tls.h" -#endif - -namespace vt { namespace util { namespace tls { - -#if vt_check_enabled(openmp) - template - using ThreadLocalType = ThreadLocalOMP; - - template - using ThreadLocalInitType = ThreadLocalInitOMP; -#elif vt_check_enabled(stdthread) - template - using ThreadLocalType = ThreadLocalSTD; - - template - using ThreadLocalInitType = ThreadLocalInitSTD; -#else - template - using ThreadLocalType = ThreadLocalNull; - - template - using ThreadLocalInitType = ThreadLocalInitNull; -#endif - -#if backend_null_tls - template - using ThreadLocalNullType = ThreadLocalNull; - - template - using ThreadLocalNullInitType = ThreadLocalInitNull; -#endif - -// Declare and extern TLS variable with initializer -#define DeclareInitTLS(type, var, init) \ - DeclareInitImplTLS(ThreadLocalInitType, type, var, init) -#define ExternInitTLS(type, var, init) \ - ExternInitImplTLS(ThreadLocalInitType, type, var, init) -// Declare and extern TLS variable w/o initializer -#define DeclareTLS(type, var) \ - DeclareImplTLS(ThreadLocalType, type, var) -#define ExternTLS(type, var) \ - ExternImplTLS(ThreadLocalType, type, var) -// Access a TLS variable -#define AccessTLS(var) \ - AccessImplTLS(var) - -// Declare and extern a variable with initializer that may or may not be TLS -#define DeclareInitVar(TLS, type, var, init) \ - DeclareInitImplTLS( \ - ThreadLocalInitType, type, var, init \ - ) -#define ExternInitVar(TLS, type, var, init) \ - ExternInitImplTLS( \ - ThreadLocalInitType, type, var, init \ - ) -#define AccessVar(var) \ - AccessImplTLS(var) - -// Variant for file-level static TLS variables -#define DeclareStaticTLS(type, var) \ - DeclareStImplTLS(ThreadLocalType, type, var) -#define DeclareStaticInitTLS(type, var, init) \ - DeclareStInitImplTLS(ThreadLocalInitType, type, var, init) - -// Variant for class level static TLS variables -// Declare class level static TLS variable w/o initializer -#define DeclareClassInsideTLS(cls, type, var) \ - DeclareClsInImplTLS(ThreadLocalType, cls, type, var) -#define DeclareClassOutsideTLS(cls, type, var) \ - DeclareClsOutImplTLS(ThreadLocalType, cls, type, var) - -// Declare class level static TLS variable w initializer -#define DeclareClassInsideInitTLS(cls, type, var, init) \ - DeclareClsInInitImplTLS(ThreadLocalInitType, cls, type, var, init) -#define DeclareClassOutsideInitTLS(cls, type, var, init) \ - DeclareClsOutInitImplTLS(ThreadLocalInitType, cls, type, var, init) - -// Access a static TLS variable in a class -#define AccessClassTLS(cls, var) \ - AccessClsImplTLS(cls, var) - -}}} /* end namespace vt::util::tls */ - -#include "vt/utils/tls/tls.impl.h" - -#endif /*INCLUDED_VT_UTILS_TLS_TLS_H*/ diff --git a/src/vt/utils/tls/tls.impl.h b/src/vt/utils/tls/tls.impl.h deleted file mode 100644 index 18b56ac860..0000000000 --- a/src/vt/utils/tls/tls.impl.h +++ /dev/null @@ -1,107 +0,0 @@ -/* -//@HEADER -// ***************************************************************************** -// -// tls.impl.h -// DARMA/vt => Virtual Transport -// -// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC -// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. -// Government retains certain rights in this software. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Questions? Contact darma@sandia.gov -// -// ***************************************************************************** -//@HEADER -*/ - -#if !defined INCLUDED_VT_UTILS_TLS_TLS_IMPL_H -#define INCLUDED_VT_UTILS_TLS_TLS_IMPL_H - -#include "vt/config.h" - -namespace vt { namespace util { namespace tls { - -#define TagAny(tag,var) tag##_##var##_ -#define TagTLS(var) TagAny(tls,var) -#define StrTLS(tag,var) TagAny(tls_static_str,var) -#define DeclareMakeStrTLS(tag, var) char StrTLS(tls,var)[] -#define MakeStrTLS(tag, var, INIT) DeclareMakeStrTLS(tag, var) INIT; -#define InitStrTLS(var) = #var -#define InitTempTLS(init) ,init - -#define InnerTLS(TLCLS, TYPE, VAR, INIT, INIT_STR, EXTERN, STATIC) \ - EXTERN STATIC constexpr MakeStrTLS(tls, VAR, INIT_STR) \ - EXTERN STATIC util::tls::TLCLS TagTLS(VAR); -#define DeclareInitImplTLS(tlcls, type, var, init) \ - InnerTLS(tlcls, type, var, InitTempTLS(init), InitStrTLS(var), , ) -#define DeclareImplTLS(tlcls, type, var) \ - InnerTLS(tlcls, type, var, , InitStrTLS(var), , ) -#define ExternInitImplTLS(tlcls, type, var, init) \ - InnerTLS(tlcls, type, var, InitTempTLS(init), , extern, ) -#define ExternImplTLS(tlcls, type, var) \ - InnerTLS(tlcls, type, var, , , extern, ) -#define AccessImplTLS(var) \ - TagTLS(var).get() - -// Variants for static file TLS variables -#define DeclareStImplTLS(tlcls, type, var) \ - InnerTLS(tlcls, type, var, , InitStrTLS(var), , static) -#define DeclareStInitImplTLS(tlcls, type, var, init) \ - InnerTLS(tlcls, type, var, InitTempTLS(init), InitStrTLS(var), , static) - -// Variants for static class TLS variables -#define DeclareMakeStrClsTLS(cls, tag, var, init) \ - char cls::StrTLS(tls,var)[] init; -#define MakeStrClsTLS(cls, tag, var, INIT) \ - DeclareMakeStrClsTLS(cls, tag, var) INIT; -#define InnerClsInTLS(TLCLS, CLS, TYPE, VAR, INIT, INIT_STR) \ - static DeclareMakeStrTLS(tls, VAR); \ - static util::tls::TLCLS TagTLS(VAR); -#define InnerClsOutTLS(TLCLS, CLS, TYPE, VAR, INIT, INIT_STR) \ - DeclareMakeStrClsTLS(CLS, tls, VAR, INIT_STR) \ - util::tls::TLCLS CLS::TagTLS(VAR); - -// Variant for static class TLS variables w/o init -#define DeclareClsInImplTLS(tlcls, cls, type, var) \ - InnerClsInTLS(tlcls, cls, type, var, , InitStrTLS(var)) -#define DeclareClsOutImplTLS(tlcls, cls, type, var) \ - InnerClsOutTLS(tlcls, cls, type, var, , InitStrTLS(var)) -// Variant for static class TLS variables w init -#define DeclareClsInInitImplTLS(tlcls, cls, type, var, init) \ - InnerClsInTLS(tlcls, cls, type, var, InitTempTLS(init), InitStrTLS(var)) -#define DeclareClsOutInitImplTLS(tlcls, cls, type, var, init) \ - InnerClsOutTLS(tlcls, cls, type, var, InitTempTLS(init), InitStrTLS(var)) -// Variant for static class TLS variables access -#define AccessClsImplTLS(cls, var) \ - cls::TagTLS(var).get() - -}}} /* end namespace vt::util::tls */ - -#endif /*INCLUDED_VT_UTILS_TLS_TLS_IMPL_H*/ diff --git a/src/vt/vrt/collection/active/active_funcs.h b/src/vt/vrt/collection/active/active_funcs.h index 86b196d506..3e7327f78b 100644 --- a/src/vt/vrt/collection/active/active_funcs.h +++ b/src/vt/vrt/collection/active/active_funcs.h @@ -51,12 +51,10 @@ namespace vt { namespace vrt { namespace collection { -using ActiveColFnPtrType = void(*)( - ::vt::BaseMessage*, UntypedCollection* -); +using ActiveColFnPtrType = void(*)(UntypedCollection*, ::vt::BaseMessage*); template -using ActiveColTypedFnType = void(MsgT*, ColT*); +using ActiveColTypedFnType = void(ColT*, MsgT*); using ActiveColMemberFnPtrType = void(UntypedCollection::*)(::vt::BaseMessage*); diff --git a/src/vt/vrt/collection/balance/col_lb_data.h b/src/vt/vrt/collection/balance/col_lb_data.h index d256748754..223fcdd52a 100644 --- a/src/vt/vrt/collection/balance/col_lb_data.h +++ b/src/vt/vrt/collection/balance/col_lb_data.h @@ -70,7 +70,7 @@ struct CollectionLBData : elm::ElementLBData { public: template - static void syncNextPhase(CollectStatsMsg* msg, ColT* col); + static void syncNextPhase(ColT* col, CollectStatsMsg* msg); friend struct collection::Migratable; diff --git a/src/vt/vrt/collection/balance/col_lb_data.impl.h b/src/vt/vrt/collection/balance/col_lb_data.impl.h index 271939ced9..fe968618d7 100644 --- a/src/vt/vrt/collection/balance/col_lb_data.impl.h +++ b/src/vt/vrt/collection/balance/col_lb_data.impl.h @@ -60,7 +60,7 @@ namespace vt { namespace vrt { namespace collection { namespace balance { template /*static*/ -void CollectionLBData::syncNextPhase(CollectStatsMsg* msg, ColT* col) { +void CollectionLBData::syncNextPhase(ColT* col, CollectStatsMsg* msg) { auto& lb_data = col->lb_data_; vt_debug_print( diff --git a/src/vt/vrt/collection/balance/lb_data_holder.cc b/src/vt/vrt/collection/balance/lb_data_holder.cc index 6f8f061629..8706a15a5f 100644 --- a/src/vt/vrt/collection/balance/lb_data_holder.cc +++ b/src/vt/vrt/collection/balance/lb_data_holder.cc @@ -80,7 +80,7 @@ std::unique_ptr LBDataHolder::toJson(PhaseType phase) const { ElementIDStruct id = elm.first; TimeType time = elm.second.whole_phase_load; j["tasks"][i]["resource"] = "cpu"; - j["tasks"][i]["node"] = theContext()->getNode(); + j["tasks"][i]["node"] = id.getCurrNode(); j["tasks"][i]["time"] = time; if (user_defined_json_.find(phase) != user_defined_json_.end()) { auto &user_def_this_phase = user_defined_json_.at(phase); @@ -183,7 +183,6 @@ LBDataHolder::LBDataHolder(nlohmann::json const& j) { auto etype = task["entity"]["type"]; vtAssertExpr(time.is_number()); vtAssertExpr(node.is_number()); - vtAssertExpr(node == this_node); if (etype == "object") { auto object = task["entity"]["id"]; diff --git a/src/vt/vrt/collection/balance/lb_data_restart_reader.cc b/src/vt/vrt/collection/balance/lb_data_restart_reader.cc index fffe3b17fa..d4219ea9b3 100644 --- a/src/vt/vrt/collection/balance/lb_data_restart_reader.cc +++ b/src/vt/vrt/collection/balance/lb_data_restart_reader.cc @@ -78,45 +78,22 @@ void LBDataRestartReader::startup() { readLBData(file_name); } -std::vector const& -LBDataRestartReader::getMoveList(PhaseType phase) const { - vtAssert(proc_move_list_.size() > phase, "Phase must exist"); - return proc_move_list_.at(phase); -} - -void LBDataRestartReader::clearMoveList(PhaseType phase) { - if (proc_move_list_.size() > phase) { - proc_move_list_.at(phase).clear(); - } -} - -bool LBDataRestartReader::needsLB(PhaseType phase) const { - if (proc_phase_runs_LB_.size() > phase) { - return proc_phase_runs_LB_.at(phase); - } else { - return false; - } -} - -std::deque> const& -LBDataRestartReader::getMigrationList() const { - return proc_move_list_; -} - -std::deque> LBDataRestartReader::readIntoElementHistory( - LBDataHolder const& lbdh -) { - std::deque> element_history; - for (PhaseType phase = 0; phase < lbdh.node_data_.size(); phase++) { - std::set buffer; - for (auto const& obj : lbdh.node_data_.at(phase)) { - if (obj.first.isMigratable()) { - buffer.insert(obj.first.id); +void LBDataRestartReader::readHistory(LBDataHolder const& lbdh) { + num_phases_ = lbdh.node_data_.size(); + for (PhaseType phase = 0; phase < num_phases_; phase++) { + auto iter = lbdh.node_data_.find(phase); + if (iter != lbdh.node_data_.end()) { + for (auto const& obj : iter->second) { + if (obj.first.isMigratable()) { + history_[phase].insert(obj.first); + } } + } else { + // We assume that all phases are dense all fully specified even if they + // don't change + vtAbort("Could not find data: phases must all be specified"); } - element_history.emplace_back(std::move(buffer)); } - return element_history; } void LBDataRestartReader::readLBDataFromStream(std::stringstream stream) { @@ -129,174 +106,95 @@ void LBDataRestartReader::readLBDataFromStream(std::stringstream stream) { ); json j = json::parse(c); auto lbdh = LBDataHolder(j); - - auto element_history = readIntoElementHistory(lbdh); - constructMoveList(std::move(element_history)); -} - -void LBDataRestartReader::readLBData(std::string const& fileName) { - // Read the input files - auto elements_history = inputLBDataFile(fileName); - constructMoveList(std::move(elements_history)); + readHistory(lbdh); + determinePhasesToMigrate(); } -void LBDataRestartReader::constructMoveList( - std::deque> element_history -) { - if (element_history.empty()) { - vtWarn("No element history provided"); - return; - } - - auto const num_iters = element_history.size() - 1; - proc_move_list_.resize(num_iters); - proc_phase_runs_LB_.resize(num_iters, true); - - if (theContext()->getNode() == 0) { - msgsReceived.resize(num_iters, 0); - totalMove.resize(num_iters); - } - - // Communicate the migration information - createMigrationInfo(element_history); -} - -std::deque> -LBDataRestartReader::inputLBDataFile(std::string const& fileName) { +void LBDataRestartReader::readLBData(std::string const& file) { using vt::util::json::Reader; using vt::vrt::collection::balance::LBDataHolder; - Reader r{fileName}; + Reader r{file}; auto json = r.readFile(); auto lbdh = LBDataHolder(*json); - - return readIntoElementHistory(lbdh); + readHistory(lbdh); + determinePhasesToMigrate(); } -void LBDataRestartReader::createMigrationInfo( - std::deque>& element_history -) { - const auto num_iters = element_history.size() - 1; - const auto myNodeID = static_cast(theContext()->getNode()); +void LBDataRestartReader::departing(DepartMsg* msg) { + auto m = promoteMsg(msg); + coordinate_[msg->phase][msg->elm].depart = m; + checkBothEnds(coordinate_[msg->phase][msg->elm]); +} - for (size_t ii = 0; ii < num_iters; ++ii) { - auto& elms = element_history[ii]; - auto& elmsNext = element_history[ii + 1]; - std::set diff; - std::set_difference(elmsNext.begin(), elmsNext.end(), elms.begin(), - elms.end(), std::inserter(diff, diff.begin())); - const size_t qi = diff.size(); - const size_t pi = elms.size() - (elmsNext.size() - qi); - auto& myList = proc_move_list_[ii]; - myList.reserve(3 * (pi + qi) + 1); - //--- Store the iteration number - myList.push_back(static_cast(ii)); - //--- Store partial migration information (i.e. nodes moving in) - for (auto iEle : diff) { - myList.push_back(iEle); //--- permID to receive - myList.push_back(no_element_id); // node moving from - myList.push_back(myNodeID); // node moving to - } - diff.clear(); - //--- Store partial migration information (i.e. nodes moving out) - std::set_difference(elms.begin(), elms.end(), elmsNext.begin(), - elmsNext.end(), std::inserter(diff, diff.begin())); - for (auto iEle : diff) { - myList.push_back(iEle); //--- permID to send - myList.push_back(myNodeID); // node migrating from - myList.push_back(no_element_id); // node migrating to - } - // - // Create a message storing the vector - // - proxy_[0].send(myList); - // - // Clear old distribution of elements - // - elms.clear(); - } +void LBDataRestartReader::arriving(ArriveMsg* msg) { + auto m = promoteMsg(msg); + coordinate_[msg->phase][msg->elm].arrive = m; + checkBothEnds(coordinate_[msg->phase][msg->elm]); +} +void LBDataRestartReader::update(UpdateMsg* msg) { + auto iter = history_[msg->phase].find(msg->elm); + vtAssert(iter != history_[msg->phase].end(), "Must exist"); + auto elm = *iter; + elm.curr_node = msg->curr_node; + history_[msg->phase].erase(iter); + history_[msg->phase].insert(elm); } -void LBDataRestartReader::gatherMsgs(VecMsg *msg) { - auto sentVec = msg->getTransfer(); - vtAssert(sentVec.size() % 3 == 1, "Expecting vector of length 3n+1"); - ElementIDType const phaseID = sentVec[0]; - // - // --- Combine the different pieces of information - // - msgsReceived[phaseID] += 1; - auto& migrate = totalMove[phaseID]; - for (size_t ii = 1; ii < sentVec.size(); ii += 3) { - auto const permID = sentVec[ii]; - auto const nodeFrom = static_cast(sentVec[ii + 1]); - auto const nodeTo = static_cast(sentVec[ii + 2]); - auto iptr = migrate.find(permID); - if (iptr == migrate.end()) { - migrate.insert(std::make_pair(permID, std::make_pair(nodeFrom, nodeTo))); - } - else { - auto &nodePair = iptr->second; - nodePair.first = std::max(nodePair.first, nodeFrom); - nodePair.second = std::max(nodePair.second, nodeTo); - } +void LBDataRestartReader::checkBothEnds(Coord& coord) { + if (coord.arrive != nullptr and coord.depart != nullptr) { + proxy_[coord.arrive->arrive_node].send< + UpdateMsg, &LBDataRestartReader::update + >(coord.depart->depart_node, coord.arrive->phase, coord.arrive->elm); } - // - // --- Check whether all the messages have been received - // - const NodeType numNodes = theContext()->getNumNodes(); - if (msgsReceived[phaseID] < static_cast(numNodes)) - return; - // - //--- Distribute the information when everything has been received - // - size_t const header = 2; - for (NodeType in = 0; in < numNodes; ++in) { - size_t iCount = 0; - for (auto iNode : migrate) { - if (iNode.second.first == in) - iCount += 1; - } - std::vector toMove(2 * iCount + header); - iCount = 0; - toMove[iCount++] = phaseID; - toMove[iCount++] = static_cast(migrate.size()); - for (auto iNode : migrate) { - if (iNode.second.first == in) { - toMove[iCount++] = iNode.first; - toMove[iCount++] = static_cast(iNode.second.second); +} + +void LBDataRestartReader::determinePhasesToMigrate() { + std::vector local_changed_distro; + local_changed_distro.resize(num_phases_ - 1); + + auto const this_node = theContext()->getNode(); + + runInEpochCollective("LBDataRestartReader::updateLocations", [&]{ + for (PhaseType i = 0; i < num_phases_ - 1; ++i) { + local_changed_distro[i] = history_[i] != history_[i+1]; + if (local_changed_distro[i]) { + std::set departing, arriving; + + std::set_difference( + history_[i+1].begin(), history_[i+1].end(), + history_[i].begin(), history_[i].end(), + std::inserter(arriving, arriving.begin()) + ); + + std::set_difference( + history_[i].begin(), history_[i].end(), + history_[i+1].begin(), history_[i+1].end(), + std::inserter(departing, departing.begin()) + ); + + for (auto&& d : departing) { + proxy_[d.getHomeNode()].send(this_node, i+1, d); + } + for (auto&& a : arriving) { + proxy_[a.getHomeNode()].send(this_node, i+1, a); + } } } - if (in > 0) { - proxy_[in].send(toMove); - } else { - proc_phase_runs_LB_[phaseID] = (!migrate.empty()); - auto& myList = proc_move_list_[phaseID]; - myList.resize(toMove.size() - header); - std::copy(&toMove[header], toMove.data() + toMove.size(), - myList.begin()); - } - } - migrate.clear(); + }); + + runInEpochCollective("LBDataRestartReader::computeDistributionChanges", [&]{ + auto cb = theCB()->makeBcast< + LBDataRestartReader,ReduceMsg,&LBDataRestartReader::reduceDistroChanges + >(proxy_); + auto msg = makeMessage(std::move(local_changed_distro)); + proxy_.reduce>>(msg, cb); + }); } -void LBDataRestartReader::scatterMsgs(VecMsg *msg) { - const size_t header = 2; - auto recvVec = msg->getTransfer(); - vtAssert((recvVec.size() -header) % 2 == 0, - "Expecting vector of length 2n+2"); - //--- Get the iteration number associated with the message - const ElementIDType phaseID = recvVec[0]; - //--- Check whether some migration will be done - proc_phase_runs_LB_[phaseID] = static_cast(recvVec[1] > 0); - auto &myList = proc_move_list_[phaseID]; - if (!proc_phase_runs_LB_[phaseID]) { - myList.clear(); - return; - } - //--- Copy the migration information - myList.resize(recvVec.size() - header); - std::copy(&recvVec[header], recvVec.data()+recvVec.size(), myList.begin()); +void LBDataRestartReader::reduceDistroChanges(ReduceMsg* msg) { + changed_distro_ = std::move(msg->getMoveVal()); } }}}} /* end namespace vt::vrt::collection::balance */ diff --git a/src/vt/vrt/collection/balance/lb_data_restart_reader.h b/src/vt/vrt/collection/balance/lb_data_restart_reader.h index 2f0f840f14..54e297e718 100644 --- a/src/vt/vrt/collection/balance/lb_data_restart_reader.h +++ b/src/vt/vrt/collection/balance/lb_data_restart_reader.h @@ -70,7 +70,7 @@ namespace vt { namespace vrt { namespace collection { namespace balance { * files. */ struct LBDataRestartReader : runtime::component::Component { - using VecMsg = lb::TransferMsg >; + using ReduceMsg = collective::ReduceTMsg>; public: LBDataRestartReader() = default; @@ -83,67 +83,147 @@ struct LBDataRestartReader : runtime::component::Component void startup() override; + /** + * \brief Read LB data from a string stream + * + * \param[in] stream the input stream + */ void readLBDataFromStream(std::stringstream stream); - void constructMoveList(std::deque> element_history); - + /** + * \brief Read LB data from the file specified + * + * \param[in] file the file + */ void readLBData(std::string const& fileName); - std::deque> readIntoElementHistory( - LBDataHolder const& lbdh - ); - - std::vector const& getMoveList(PhaseType phase) const; - - std::deque> const& getMigrationList() const; - - void clearMoveList(PhaseType phase); - - bool needsLB(PhaseType phase) const; + /** + * \brief Read the element history from an LB holder + * + * \param[in] lbdh the LB data holder + */ + void readHistory(LBDataHolder const& lbdh); + + /** + * \brief Return whether a phase needs LB + * + * \param[in] phase the phase + * + * \return whether it needs LB + */ + bool needsLB(PhaseType phase) const { + return changed_distro_.size() > phase ? changed_distro_.at(phase) : false; + } template void serialize(Serializer& s) { - s | msgsReceived - | totalMove - | proxy_ - | proc_move_list_ - | proc_phase_runs_LB_; + s | proxy_ + | changed_distro_ + | history_ + | num_phases_; } -private: - std::deque> inputLBDataFile( - std::string const& fileName - ); - - void createMigrationInfo( - std::deque>& element_history - ); + /** + * \brief Get the elements assigned for a given phase + * + * \param[in] phase the phase + * + * \return element assigned to this node + */ + std::set const& getDistro(PhaseType phase) { + auto iter = history_.find(phase); + vtAssert(iter != history_.end(), "Must have a valid phase"); + return iter->second; + } - void gatherMsgs(VecMsg *msg); + /** + * \brief Clear history for a given phase + * + * \param[in] phase the phase to clear + */ + void clearDistro(PhaseType phase) { + auto iter = history_.find(phase); + if (iter != history_.end()) { + history_.erase(iter); + } + } - void scatterMsgs(VecMsg *msg); +private: + /** + * \brief Reduce distribution changes globally to find where migrations need + * to occur + * + * \param[in] msg the reduction message + */ + void reduceDistroChanges(ReduceMsg* msg); + + /** + * \brief Determine which phases migrations must happen to follow the + * distribution + */ + void determinePhasesToMigrate(); private: - /// \brief Vector counting the received messages per iteration - /// \note Only node 0 will use this vector. - std::vector msgsReceived; - - /// \brief Queue for storing all the migrations per iteration. - /// \note Only node 0 will use this queue. - std::deque>> totalMove; - - /// \brief Proxy for communicating the migration information - objgroup::proxy::Proxy proxy_; - - /// \brief Queue of migrations for each iteration. - /// \note At each iteration, a vector of length 2 times (# of migrations) - /// is specified. The vector contains the "permanent" ID of the element - /// to migrate followed by the node ID to migrate to. - std::deque> proc_move_list_; - - /// \brief Vector of booleans to indicate whether the user-specified - /// map migrates elements for a specific iteration. - std::vector proc_phase_runs_LB_; + objgroup::proxy::Proxy proxy_; /**< Objgroup proxy */ + + /// Whether the distribution changed for a given phase and thus needs LB + std::vector changed_distro_; + + /// History of mapping that was read in from the data files + std::unordered_map> history_; + + struct DepartMsg : vt::Message { + DepartMsg(NodeType in_depart_node, PhaseType in_phase, ElementIDStruct in_elm) + : depart_node(in_depart_node), + phase(in_phase), + elm(in_elm) + { } + + NodeType depart_node = uninitialized_destination; + PhaseType phase = no_lb_phase; + ElementIDStruct elm; + }; + + struct ArriveMsg : vt::Message { + ArriveMsg(NodeType in_arrive_node, PhaseType in_phase, ElementIDStruct in_elm) + : arrive_node(in_arrive_node), + phase(in_phase), + elm(in_elm) + { } + + NodeType arrive_node = uninitialized_destination; + PhaseType phase = no_lb_phase; + ElementIDStruct elm; + }; + + struct UpdateMsg : vt::Message { + UpdateMsg(NodeType in_curr_node, PhaseType in_phase, ElementIDStruct in_elm) + : curr_node(in_curr_node), + phase(in_phase), + elm(in_elm) + { } + + NodeType curr_node = uninitialized_destination; + PhaseType phase = no_lb_phase; + ElementIDStruct elm; + }; + + struct Coord { + MsgSharedPtr arrive = nullptr; + MsgSharedPtr depart = nullptr; + }; + + void departing(DepartMsg* msg); + void arriving(ArriveMsg* msg); + void update(UpdateMsg* msg); + void checkBothEnds(Coord& coord); + + std::unordered_map< + PhaseType, std::unordered_map + > coordinate_; + + /// Number of phases read in + std::size_t num_phases_ = 0; }; }}}} /* end namespace vt::vrt::collection::balance */ diff --git a/src/vt/vrt/collection/balance/lb_invoke/lb_manager.cc b/src/vt/vrt/collection/balance/lb_invoke/lb_manager.cc index f6f8ce8ace..22577b6dcf 100644 --- a/src/vt/vrt/collection/balance/lb_invoke/lb_manager.cc +++ b/src/vt/vrt/collection/balance/lb_invoke/lb_manager.cc @@ -112,9 +112,12 @@ LBType LBManager::decideLBToRun(PhaseType phase, bool try_file) { } //--- User-specified map without any change, thus do not run - if ((theConfig()->vt_lb_name == get_lb_names()[LBType::OfflineLB]) and - not theLBDataReader()->needsLB(phase)) { - return LBType::NoLB; + if (theConfig()->vt_lb_name == get_lb_names()[LBType::OfflineLB]) { + if (theLBDataReader()->needsLB(phase)) { + return LBType::OfflineLB; + } else { + return LBType::NoLB; + } } auto& spec_file = theConfig()->vt_lb_file_name; @@ -756,8 +759,10 @@ void LBManager::createStatisticsFile() { using JSONAppender = util::json::Appender; if (not statistics_writer_) { + nlohmann::json metadata; + metadata["type"] = "LBStatsfile"; statistics_writer_ = std::make_unique( - "phases", "LBStatsfile", file_name, compress + "phases", metadata, file_name, compress ); } } diff --git a/src/vt/vrt/collection/balance/model/raw_data.cc b/src/vt/vrt/collection/balance/model/raw_data.cc index 47b30d0459..743499476e 100644 --- a/src/vt/vrt/collection/balance/model/raw_data.cc +++ b/src/vt/vrt/collection/balance/model/raw_data.cc @@ -103,7 +103,12 @@ TimeType RawData::getRawLoad(ElementIDStruct object, PhaseOffset offset) const { "RawData makes no predictions. Compose with NaivePersistence or some longer-range forecasting model as needed"); auto phase = getNumCompletedPhases() + offset.phases; - return proc_load_->at(phase).at(object).get(offset); + auto& phase_data = proc_load_->at(phase); + if (phase_data.find(object) != phase_data.end()) { + return phase_data.at(object).get(offset); + } else { + return 0; + } } unsigned int RawData::getNumPastPhasesNeeded(unsigned int look_back) const diff --git a/src/vt/vrt/collection/balance/node_lb_data.cc b/src/vt/vrt/collection/balance/node_lb_data.cc index bc363f32ae..6a5cd55182 100644 --- a/src/vt/vrt/collection/balance/node_lb_data.cc +++ b/src/vt/vrt/collection/balance/node_lb_data.cc @@ -194,8 +194,19 @@ void NodeLBData::createLBDataFile() { using JSONAppender = util::json::Appender; if (not lb_data_writer_) { + nlohmann::json metadata; + if (curRT->has_physical_node_info) { + nlohmann::json node_metadata; + node_metadata["id"] = curRT->physical_node_id; + node_metadata["size"] = curRT->physical_node_size; + node_metadata["rank"] = curRT->physical_node_rank; + node_metadata["num_nodes"] = curRT->physical_num_nodes; + metadata["shared_node"] = node_metadata; + } + metadata["type"] = "LBDatafile"; + metadata["rank"] = theContext()->getNode(); lb_data_writer_ = std::make_unique( - "phases", "LBDatafile", file_name, compress + "phases", metadata, file_name, compress ); } } diff --git a/src/vt/vrt/collection/balance/offlinelb/offlinelb.cc b/src/vt/vrt/collection/balance/offlinelb/offlinelb.cc index 2a6a12dd8d..cb0ba986f3 100644 --- a/src/vt/vrt/collection/balance/offlinelb/offlinelb.cc +++ b/src/vt/vrt/collection/balance/offlinelb/offlinelb.cc @@ -55,14 +55,11 @@ void OfflineLB::init(objgroup::proxy::Proxy in_proxy) { } void OfflineLB::runLB(TimeType) { - auto const& myNewList = theLBDataReader()->getMoveList(phase_); - for (size_t in = 0; in < myNewList.size(); in += 2) { - auto this_node = theContext()->getNode(); - ObjIDType id{myNewList[in], this_node}; - migrateObjectTo(id, myNewList[in+1]); + auto const& distro = theLBDataReader()->getDistro(phase_ + 1); + for (auto&& elm : distro) { + migrateObjectTo(elm, theContext()->getNode()); } - - theLBDataReader()->clearMoveList(phase_); + theLBDataReader()->clearDistro(phase_ + 1); } }}}} /* end namespace vt::vrt::collection::lb */ diff --git a/src/vt/vrt/collection/broadcast/broadcastable.h b/src/vt/vrt/collection/broadcast/broadcastable.h index 22c51eee2c..2c7061c317 100644 --- a/src/vt/vrt/collection/broadcast/broadcastable.h +++ b/src/vt/vrt/collection/broadcast/broadcastable.h @@ -50,6 +50,7 @@ #include "vt/vrt/collection/active/active_funcs.h" #include "vt/messaging/message/smart_ptr.h" #include "vt/messaging/pending_send.h" +#include "vt/utils/fntraits/fntraits.h" namespace vt { namespace vrt { namespace collection { @@ -195,6 +196,69 @@ struct Broadcastable : BaseProxyT { typename... Args > void invokeCollective(Args&&... args) const; + + /** + * \brief Rooted broadcast with action function handler + * \note Takes ownership of the supplied message + * + * \param[in] msg the message + * + * \return a pending send + */ + template + messaging::PendingSend broadcastMsg( + messaging::MsgPtrThief::MsgT> msg + ) const { + using MsgT = typename ObjFuncTraits::MsgT; + return broadcastMsg(msg); + } + + /** + * \brief Rooted broadcast with action function handler + * + * \param[in] args arguments needed for creteating the message + * + * \return a pending send + */ + template + messaging::PendingSend broadcast(Args&&... args) const; + + /** + * \brief Collective broadcast with action function handler + * \note Takes ownership of the supplied message + * + * \param[in] msg the message + * + * \return a pending send + */ + template + messaging::PendingSend broadcastCollectiveMsg( + messaging::MsgPtrThief::MsgT> msg + ) const { + using MsgT = typename ObjFuncTraits::MsgT; + return broadcastCollectiveMsg(msg); + } + + /** + * \brief Create message (with action function handler) and broadcast it in a + * collective manner to the collection + * + * \param[in] args arguments needed for creteating the message + * + * \return a pending send + */ + template + messaging::PendingSend broadcastCollective(Args&&... args) const; + + /** + * \brief Invoke member message handler on all collection elements + * The function will be invoked inline without going through scheduler + * + * \param[in] args arguments for creating the message + */ + template + void invokeCollective(Args&&... args) const; + }; }}} /* end namespace vt::vrt::collection */ diff --git a/src/vt/vrt/collection/broadcast/broadcastable.impl.h b/src/vt/vrt/collection/broadcast/broadcastable.impl.h index 89978f4dc3..f48672da5e 100644 --- a/src/vt/vrt/collection/broadcast/broadcastable.impl.h +++ b/src/vt/vrt/collection/broadcast/broadcastable.impl.h @@ -61,7 +61,7 @@ template template *f> messaging::PendingSend Broadcastable::broadcast(MsgT* msg) const { auto proxy = this->getProxy(); - return theCollection()->broadcastMsg(proxy,msg); + return theCollection()->broadcastMsg(proxy,msg); } template @@ -77,7 +77,7 @@ template < typename MsgT, ActiveColTypedFnType *f, typename... Args > messaging::PendingSend Broadcastable::broadcast(Args&&... args) const { - return broadcastMsg(makeMessage(std::forward(args)...)); + return broadcastMsg(makeMessage(std::forward(args)...)); } template @@ -86,7 +86,7 @@ messaging::PendingSend Broadcastable::broadcastMsg(messaging::MsgPtrThief msg) const { auto proxy = this->getProxy(); - return theCollection()->broadcastMsg(proxy, msg.msg_.get()); + return theCollection()->broadcastMsg(proxy, msg.msg_.get()); } template @@ -110,14 +110,14 @@ template f> messaging::PendingSend Broadcastable::broadcastMsg(messaging::MsgPtrThief msg) const { auto proxy = this->getProxy(); - return theCollection()->broadcastMsg(proxy, msg.msg_.get()); + return theCollection()->broadcastMsg(proxy, msg.msg_.get()); } template template f> messaging::PendingSend Broadcastable::broadcast(MsgT* msg) const { auto proxy = this->getProxy(); - return theCollection()->broadcastMsg(proxy, msg); + return theCollection()->broadcastMsg(proxy, msg); } template @@ -177,6 +177,73 @@ Broadcastable::invokeCollective(Args&&... args) const return theCollection()->invokeCollectiveMsg(proxy, msg); } +template +template +messaging::PendingSend +Broadcastable::broadcast(Params&&... params) const { + using MsgT = typename ObjFuncTraits::MsgT; + if constexpr (std::is_same_v) { + using Tuple = typename ObjFuncTraits::TupleType; + using SendMsgT = ParamColMsg; + auto msg = vt::makeMessage(std::forward(params)...); + auto han = auto_registry::makeAutoHandlerCollectionMemParam< + ColT, decltype(f), f, SendMsgT + >(); + auto proxy = this->getProxy(); + return theCollection()->broadcastMsgUntypedHandler( + proxy, msg.get(), han, true + ); + } else { + auto msg = makeMessage(std::forward(params)...); + return broadcastMsg(msg); + } + + // Silence nvcc warning (no longer needed for CUDA 11.7 and up) + return messaging::PendingSend{std::nullptr_t{}}; +} + +template +template +messaging::PendingSend +Broadcastable::broadcastCollective(Params&&... params) const { + using MsgT = typename ObjFuncTraits::MsgT; + if constexpr (std::is_same_v) { + using Tuple = typename ObjFuncTraits::TupleType; + using SendMsgT = ParamColMsg; + auto msg = vt::makeMessage(std::forward(params)...); + auto han = auto_registry::makeAutoHandlerCollectionMemParam< + ColT, decltype(f), f, SendMsgT + >(); + auto proxy = this->getProxy(); + msg->setVrtHandler(han); + return theCollection()->broadcastCollectiveMsgImpl( + proxy, msg, true + ); + } else { + auto msg = makeMessage(std::forward(params)...); + return broadcastCollectiveMsg(msg); + } + + // Silence nvcc warning (no longer needed for CUDA 11.7 and up) + return messaging::PendingSend{std::nullptr_t{}}; +} + +template +template +void +Broadcastable::invokeCollective(Params&&... params) const { + using MsgT = typename ObjFuncTraits::MsgT; + auto proxy = this->getProxy(); + if constexpr (std::is_same_v) { + theCollection()->invokeCollective( + proxy, std::forward(params)... + ); + } else { + auto msg = makeMessage(std::forward(params)...); + return theCollection()->invokeCollectiveMsg(proxy, msg); + } +} + }}} /* end namespace vt::vrt::collection */ #endif /*INCLUDED_VT_VRT_COLLECTION_BROADCAST_BROADCASTABLE_IMPL_H*/ diff --git a/src/vt/vrt/collection/invoke/invokable.h b/src/vt/vrt/collection/invoke/invokable.h index 3c774d7ed2..79b1ca0931 100644 --- a/src/vt/vrt/collection/invoke/invokable.h +++ b/src/vt/vrt/collection/invoke/invokable.h @@ -86,7 +86,7 @@ struct Invokable : BaseProxyT { * * \param[in] args function arguments */ - template + template decltype(auto) invoke(Args&&... args) const; }; diff --git a/src/vt/vrt/collection/invoke/invokable.impl.h b/src/vt/vrt/collection/invoke/invokable.impl.h index ed9ebb91fb..37980330ab 100644 --- a/src/vt/vrt/collection/invoke/invokable.impl.h +++ b/src/vt/vrt/collection/invoke/invokable.impl.h @@ -46,6 +46,7 @@ #include "vt/vrt/collection/invoke/invokable.h" #include "vt/vrt/collection/manager.h" +#include "vt/utils/fntraits/fntraits.h" namespace vt { namespace vrt { namespace collection { @@ -86,15 +87,21 @@ void Invokable::invoke(Args&&... args) const } template -template +template decltype(auto) Invokable::invoke(Args&&... args) const { auto const& proxy = VrtElmProxy( this->getCollectionProxy(), this->getElementProxy()); - return theCollection()->invoke( - proxy, std::forward(args)... - ); + using MsgT = typename ObjFuncTraits::MsgT; + if constexpr (std::is_same_v) { + return theCollection()->invoke( + proxy, std::forward(args)... + ); + } else { + auto msg = makeMessage(std::forward(args)...); + return theCollection()->invokeMsg(proxy, msg, true); + } } }}} /* end namespace vt::vrt::collection */ diff --git a/src/vt/vrt/collection/manager.h b/src/vt/vrt/collection/manager.h index f31dd7119e..3dd95b156d 100644 --- a/src/vt/vrt/collection/manager.h +++ b/src/vt/vrt/collection/manager.h @@ -74,6 +74,7 @@ #include "vt/context/runnable_context/lb_data.fwd.h" #include "vt/vrt/collection/param/construct_params.h" #include "vt/vrt/collection/param/construct_params_msg.h" +#include "vt/utils/fntraits/fntraits.h" #include #include @@ -134,15 +135,6 @@ struct CollectionManager std::is_default_constructible::value, CollectionProxyWrapType >; - template - using IsWrapType = std::enable_if_t< - std::is_same>::value,U - >; - template - using IsNotWrapType = std::enable_if_t< - !std::is_same>::value,U - >; - /** * \internal \brief System call to construct a collection manager */ @@ -493,6 +485,25 @@ struct CollectionManager VirtualElmProxyType const& proxy, MsgT *msg ); + /** + * \brief Send collection element a message from active function handler + * + * \param[in] proxy the collection proxy + * \param[in] msg the message + * + * \return a pending send + */ + template + messaging::PendingSend sendMsg( + VirtualElmProxyType< + typename ObjFuncTraits::MsgT::CollectionType + > const& proxy, + typename ObjFuncTraits::MsgT *msg + ) { + using MsgT = typename ObjFuncTraits::MsgT; + return sendMsg(proxy, msg); + } + /** * \brief Send collection element a message from active member handler * @@ -605,36 +616,6 @@ struct CollectionManager VirtualElmProxyType const& proxy, MsgT *msg ); - /** - * \internal \brief Deliver a message to a collection element with a promoted - * collection message that wrapped the user's non-collection message. - * - * \param[in] msg the message - * \param[in] col pointer to collection element - * \param[in] han the handler to invoke - * \param[in] from node that sent the message - */ - template - static IsWrapType collectionMsgDeliver( - MsgT* msg, CollectionBase* col, HandlerType han, - NodeType from - ); - - /** - * \internal \brief Deliver a message to a collection element with a normal - * collection message - * - * \param[in] msg the message - * \param[in] col pointer to collection element - * \param[in] han the handler to invoke - * \param[in] from node that sent the message - */ - template - static IsNotWrapType collectionMsgDeliver( - MsgT* msg, CollectionBase* col, HandlerType han, - NodeType from - ); - /** * \internal \brief Base collection message handler * @@ -665,37 +646,13 @@ struct CollectionManager static void recordLBData(ColT* col_ptr, MsgT* msg); /** - * \brief Invoke function 'f' (with copyable return type) inline without going - * through scheduler - * - * \param[in] proxy the collection proxy - * \param[in] args function params - */ - template - util::Copyable - invoke(VirtualElmProxyType const& proxy, Args... args); - - /** - * \brief Invoke function 'f' (with non-copyable return type) inline without - * going through scheduler - * - * \param[in] proxy the collection proxy - * \param[in] args function params - */ - template - util::NotCopyable - invoke(VirtualElmProxyType const& proxy, Args... args); - - /** - * \brief Invoke function 'f' (with void return type) inline without going - * through scheduler + * \brief Invoke function 'f' inline without going through scheduler * * \param[in] proxy the collection proxy * \param[in] args function params */ - template - util::IsVoidReturn - invoke(VirtualElmProxyType const& proxy, Args... args); + template + auto invoke(VirtualElmProxyType const& proxy, Args&&... args); /** * \brief Invoke message action function handler without going through @@ -712,6 +669,18 @@ struct CollectionManager messaging::MsgPtrThief msg ); + /** + * \brief Invoke function handler without going through scheduler for all + * elements + * + * \param[in] proxy the whole collection proxy + * \param[in] args the arguments + */ + template + void invokeCollective( + CollectionProxyWrapType const& proxy, Args&&... args + ); + /** * \brief Invoke message action function handler without going through * scheduler for all elements @@ -980,33 +949,17 @@ struct CollectionManager * * \return a pending send */ - template < - typename MsgT, - ActiveColTypedFnType *f - > - messaging::PendingSend broadcastMsg( - CollectionProxyWrapType const& proxy, - MsgT *msg, bool instrument = true - ); - - /** - * \brief Broadcast a message with action member handler - * - * \param[in] proxy the collection proxy - * \param[in] msg the message - * \param[in] instrument whether to instrument the broadcast for load - * balancing (some system calls use this to disable instrumentation) - * - * \return a pending send - */ - template < - typename MsgT, - ActiveColMemberTypedFnType f - > + template messaging::PendingSend broadcastMsg( - CollectionProxyWrapType const& proxy, - MsgT *msg, bool instrument = true - ); + CollectionProxyWrapType< + typename ObjFuncTraits::MsgT::CollectionType + > const& proxy, + typename ObjFuncTraits::MsgT *msg, + bool instrument = true + ) { + using MsgT = typename ObjFuncTraits::MsgT; + return broadcastMsg(proxy, msg, instrument); + } /** * \brief Broadcast a message with action function handler with collection @@ -1160,23 +1113,7 @@ struct CollectionManager public: /** - * \internal \brief Deliver a promoted/wrapped message to a collection element - * - * \param[in] msg the message - * \param[in] col the collection element pointer - * \param[in] han the handler to invoke - * \param[in] from the node that sent it - * \param[in] event the associated trace event - */ - template - static IsWrapType collectionAutoMsgDeliver( - MsgT* msg, Indexable* col, HandlerType han, - NodeType from, trace::TraceEventIDType event, bool immediate - ); - - /** - * \internal \brief Deliver a regular collection message to a collection - * element + * \internal \brief Deliver a message to a collection element * * \param[in] msg the message * \param[in] col the collection element pointer @@ -1184,8 +1121,8 @@ struct CollectionManager * \param[in] from the node that sent it * \param[in] event the associated trace event */ - template - static IsNotWrapType collectionAutoMsgDeliver( + template + static void collectionAutoMsgDeliver( MsgT* msg, Indexable* col, HandlerType han, NodeType from, trace::TraceEventIDType event, bool immediate ); @@ -1505,7 +1442,7 @@ struct CollectionManager * \param[in] msg the destroy message */ template - static void destroyElmHandler(DestroyElmMsg* msg, ColT*); + static void destroyElmHandler(ColT*, DestroyElmMsg* msg); /** * \brief Try to get a pointer to a collection element @@ -1684,55 +1621,18 @@ struct CollectionManager typename ColT::IndexType range, std::string const& file_base ); - /** - * \internal \struct RestoreMigrateMsg - * - * \brief Migrate elements to restore where it belongs based on the checkpoint - */ - template < - typename ColT, - typename MsgT = vt::Message, - typename IdxT = typename ColT::IndexType - > - struct RestoreMigrateMsg : MsgT { - RestoreMigrateMsg() = default; - RestoreMigrateMsg( - NodeType in_to_node, IdxT in_idx, CollectionProxyWrapType in_proxy - ) : to_node_(in_to_node), - idx_(in_idx), - proxy_(in_proxy) - { } - - NodeType to_node_ = uninitialized_destination; - IdxT idx_; - CollectionProxyWrapType proxy_; - }; - - /** - * \internal \struct RestoreMigrateColMsg - * - * \brief Migrate collection element to restore where it belongs - */ - template - struct RestoreMigrateColMsg - : RestoreMigrateMsg, IdxT> - { - RestoreMigrateColMsg() = default; - RestoreMigrateColMsg( - NodeType in_to_node, IdxT in_idx, CollectionProxyWrapType in_proxy - ) : RestoreMigrateMsg, IdxT>( - in_to_node, in_idx, in_proxy - ) - { } - }; - /** * \internal \brief Migrate element to restore location from checkpoint * - * \param[in] msg the migrate message + * \param[in] node the node + * \param[in] idx the element index + * \param[in] proxy the collection proxy */ template - static void migrateToRestoreLocation(RestoreMigrateMsg* msg); + static void migrateToRestoreLocation( + NodeType node, typename ColT::IndexType idx, + CollectionProxyWrapType proxy + ); /** * \brief Restore the collection (collective) from file on top of an existing diff --git a/src/vt/vrt/collection/manager.impl.h b/src/vt/vrt/collection/manager.impl.h index 342a848b32..3a1a965fc6 100644 --- a/src/vt/vrt/collection/manager.impl.h +++ b/src/vt/vrt/collection/manager.impl.h @@ -203,37 +203,8 @@ GroupType CollectionManager::createGroupCollection( return group_id; } -template -/*static*/ CollectionManager::IsWrapType -CollectionManager::collectionAutoMsgDeliver( - MsgT* msg, Indexable* base, HandlerType han, NodeType from, - trace::TraceEventIDType event, bool immediate -) { - auto user_msg = makeMessage(std::move(msg->getMsg())); - - // Expand out the index for tracing purposes; Projections takes up to - // 4-dimensions -#if vt_check_enabled(trace_enabled) - auto idx = base->getIndex(); - uint64_t const idx1 = idx.ndims() > 0 ? idx[0] : 0; - uint64_t const idx2 = idx.ndims() > 1 ? idx[1] : 0; - uint64_t const idx3 = idx.ndims() > 2 ? idx[2] : 0; - uint64_t const idx4 = idx.ndims() > 3 ? idx[3] : 0; -#endif - - runnable::makeRunnable(user_msg, true, han, from) - .withTDEpoch(theMsg()->getEpochContextMsg(msg)) - .withCollection(base) -#if vt_check_enabled(trace_enabled) - .withTraceIndex(event, idx1, idx2, idx3, idx4) -#endif - .withLBData(base, msg) - .runOrEnqueue(immediate); -} - -template -/*static*/ CollectionManager::IsNotWrapType -CollectionManager::collectionAutoMsgDeliver( +template +/*static*/ void CollectionManager::collectionAutoMsgDeliver( MsgT* msg, Indexable* base, HandlerType han, NodeType from, trace::TraceEventIDType event, bool immediate ) { @@ -248,6 +219,7 @@ CollectionManager::collectionAutoMsgDeliver( #endif auto m = promoteMsg(msg); + runnable::makeRunnable(m, true, han, from) .withTDEpoch(theMsg()->getEpochContextMsg(msg)) .withCollection(base) @@ -292,7 +264,7 @@ template #if vt_check_enabled(trace_enabled) trace_event = col_msg->getFromTraceEvent(); #endif - collectionAutoMsgDeliver( + collectionAutoMsgDeliver( msg, base, handler, from, trace_event, false ); }); @@ -355,7 +327,7 @@ template #if vt_check_enabled(trace_enabled) trace_event = col_msg->getFromTraceEvent(); #endif - collectionAutoMsgDeliver( + collectionAutoMsgDeliver( msg, col_ptr, sub_handler, from, trace_event, false ); theMsg()->popEpoch(cur_epoch); @@ -461,62 +433,37 @@ void CollectionManager::invokeCollectiveMsg( }); } -template -util::Copyable CollectionManager::invoke( - VirtualElmProxyType const& proxy, Args... args +template +void CollectionManager::invokeCollective( + CollectionProxyWrapType const& proxy, Args&&... args ) { - auto ptr = getCollectionPtrForInvoke(proxy); - - auto const this_node = theContext()->getNode(); - util::Copyable result; - - runnable::makeRunnableVoid(false, uninitialized_handler, this_node) - .withCollection(ptr) - .withLBDataVoidMsg(ptr) - .withExplicitTask([&]{ - result = runnable::invoke(ptr, std::forward(args)...); - }) - .runOrEnqueue(true); - - return result; -} - -template -util::NotCopyable CollectionManager::invoke( - VirtualElmProxyType const& proxy, Args... args -) { - auto ptr = getCollectionPtrForInvoke(proxy); + using IndexType = typename ColT::IndexType; + auto untyped_proxy = proxy.getProxy(); + auto elm_holder = findElmHolder(untyped_proxy); auto const this_node = theContext()->getNode(); - util::NotCopyable result; - runnable::makeRunnableVoid(false, uninitialized_handler, this_node) - .withCollection(ptr) - .withLBDataVoidMsg(ptr) - .withExplicitTask([&]{ - auto&& ret = runnable::invoke(ptr, std::forward(args)...); - result = std::move(ret); - }) - .runOrEnqueue(true); - - return std::move(result); + elm_holder->foreach([&](IndexType const& idx, Indexable* ptr) { + // be careful not to forward here as we are reusing args + runnable::makeRunnableVoid(false, uninitialized_handler, this_node) + .withCollection(ptr) + .withLBDataVoidMsg(ptr) + .runLambda(f, ptr, args...); + }); } -template -util::IsVoidReturn CollectionManager::invoke( - VirtualElmProxyType const& proxy, Args... args +template +auto CollectionManager::invoke( + VirtualElmProxyType const& proxy, Args&&... args ) { auto ptr = getCollectionPtrForInvoke(proxy); auto const this_node = theContext()->getNode(); - runnable::makeRunnableVoid(false, uninitialized_handler, this_node) + return runnable::makeRunnableVoid(false, uninitialized_handler, this_node) .withCollection(ptr) .withLBDataVoidMsg(ptr) - .withExplicitTask([&]{ - runnable::invoke(ptr, std::forward(args)...); - }) - .runOrEnqueue(true); + .runLambda(f, ptr, std::forward(args)...); } template < @@ -616,7 +563,7 @@ void CollectionManager::invokeMsgImpl( trace_event = theMsg()->makeTraceCreationSend(han, msg_size, is_bcast); #endif - collectionAutoMsgDeliver( + collectionAutoMsgDeliver( msg.get(), col_ptr, han, from, trace_event, true ); @@ -751,30 +698,6 @@ messaging::PendingSend CollectionManager::broadcastCollectiveMsgImpl( return messaging::PendingSend{nullptr}; } -template < - typename MsgT, - ActiveColMemberTypedFnType f -> -messaging::PendingSend CollectionManager::broadcastMsg( - CollectionProxyWrapType const& proxy, - MsgT *msg, bool instrument -) { - using ColT = typename MsgT::CollectionType; - return broadcastMsg(proxy,msg,instrument); -} - -template < - typename MsgT, - ActiveColTypedFnType *f -> -messaging::PendingSend CollectionManager::broadcastMsg( - CollectionProxyWrapType const& proxy, - MsgT *msg, bool instrument -) { - using ColT = typename MsgT::CollectionType; - return broadcastMsg(proxy,msg,instrument); -} - template *f> CollectionManager::IsColMsgType CollectionManager::broadcastMsg( @@ -1003,7 +926,7 @@ messaging::PendingSend CollectionManager::reduceMsgExpr( r = theCollective()->getReducerVrtProxy(col_proxy); } - r->reduceImmediate(root_node, msg.get(), cur_stamp, num_elms); + r->reduceImmediate(root_node, msg.get(), cur_stamp, num_elms); vt_debug_print( normal, vrt_coll, @@ -1190,6 +1113,7 @@ messaging::PendingSend CollectionManager::sendMsgUntypedHandler( msg->setFromNode(theContext()->getNode()); msg->setVrtHandler(handler); msg->setProxy(toProxy); + theMsg()->markAsCollectionMessage(msg); auto idx = elm_proxy.getIndex(); vt_debug_print( @@ -1199,18 +1123,19 @@ messaging::PendingSend CollectionManager::sendMsgUntypedHandler( col_proxy, cur_epoch, idx, handler, imm_context ); + auto home_node = theCollection()->getMappedNode(col_proxy, idx); + // route the message to the destination using the location manager + auto lm = theLocMan()->getCollectionLM(col_proxy); + vtAssert(lm != nullptr, "LM must exist"); + lm->template setupMessageForRouting< + MsgT, collectionMsgTypedHandler + >(idx, home_node, msg); + return messaging::PendingSend{ - msg, [=](MsgSharedPtr& inner_msg){ - theMsg()->pushEpoch(cur_epoch); - auto home_node = theCollection()->getMappedNode(col_proxy, idx); - // route the message to the destination using the location manager - auto lm = theLocMan()->getCollectionLM(col_proxy); - vtAssert(lm != nullptr, "LM must exist"); - theMsg()->markAsCollectionMessage(msg); - lm->template routeMsgHandler< - MsgT, collectionMsgTypedHandler - >(idx, home_node, msg); - theMsg()->popEpoch(cur_epoch); + msg, [](MsgSharedPtr& inner_msg){ + auto typed_msg = inner_msg.template to(); + auto lm2 = theLocMan()->getCollectionLM(typed_msg->getLocInst()); + lm2->template routePreparedMsgHandler(typed_msg); } }; } @@ -1809,7 +1734,7 @@ void CollectionManager::destroyElm( } else { // Otherwise, we send a destroy message that will be routed (eventually // arriving) where the element resides - proxy(idx).template send, destroyElmHandler>( + proxy(idx).template send>( untyped_proxy, idx, modify_epoch ); } @@ -1819,7 +1744,7 @@ void CollectionManager::destroyElm( template /*static*/ void CollectionManager::destroyElmHandler( - DestroyElmMsg* msg, ColT* + ColT*, DestroyElmMsg* msg ) { CollectionProxyWrapType proxy{msg->proxy_}; ModifierToken token{msg->modifier_epoch_}; @@ -2242,28 +2167,24 @@ void CollectionManager::checkpointToFile( namespace detail { template inline void restoreOffHomeElement( - CollectionManager::RestoreMigrateColMsg* msg, ColT* + ColT*, NodeType node, typename ColT::IndexType idx, + CollectionProxy proxy ) { - auto idx = msg->idx_; - auto node = msg->to_node_; - auto proxy = msg->proxy_; theCollection()->migrate(proxy(idx), node); } } /* end namespace detail */ template /*static*/ void CollectionManager::migrateToRestoreLocation( - RestoreMigrateMsg* msg + NodeType node, typename ColT::IndexType idx, + CollectionProxyWrapType proxy ) { - auto idx = msg->idx_; - auto node = msg->to_node_; - auto proxy = msg->proxy_; if (proxy(idx).tryGetLocalPtr() != nullptr) { theCollection()->migrate(proxy(idx), node); } else { - proxy(idx).template send< - RestoreMigrateColMsg, detail::restoreOffHomeElement - >(node, idx, proxy); + proxy(idx).template send>( + node, idx, proxy + ); } } @@ -2302,14 +2223,12 @@ void CollectionManager::restoreFromFileInPlace( vtAssertExpr(mapped_node != uninitialized_destination); auto this_node = theContext()->getNode(); - using MsgType = RestoreMigrateMsg; - auto msg = makeMessage(this_node, idx, proxy); if (mapped_node != this_node) { - theMsg()->sendMsg>( - mapped_node, msg + theMsg()->send>( + vt::Node{mapped_node}, this_node, idx, proxy ); } else { - migrateToRestoreLocation(msg.get()); + migrateToRestoreLocation(this_node, idx, proxy); } } } diff --git a/src/vt/worker/worker_openmp.h b/src/vt/vrt/collection/messages/param_col_msg.h similarity index 56% rename from src/vt/worker/worker_openmp.h rename to src/vt/vrt/collection/messages/param_col_msg.h index f100234b64..7c6cfbdd39 100644 --- a/src/vt/worker/worker_openmp.h +++ b/src/vt/vrt/collection/messages/param_col_msg.h @@ -2,7 +2,7 @@ //@HEADER // ***************************************************************************** // -// worker_openmp.h +// param_col_msg.h // DARMA/vt => Virtual Transport // // Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC @@ -41,71 +41,61 @@ //@HEADER */ -#if !defined INCLUDED_VT_WORKER_WORKER_OPENMP_H -#define INCLUDED_VT_WORKER_WORKER_OPENMP_H +#if !defined INCLUDED_VT_VRT_COLLECTION_MESSAGES_PARAM_COL_MSG_H +#define INCLUDED_VT_VRT_COLLECTION_MESSAGES_PARAM_COL_MSG_H -#include "vt/config.h" +#include "vt/vrt/collection/messages/user.h" +#include "vt/messaging/message/message_serialize.h" -#if vt_check_enabled(openmp) +namespace vt { namespace vrt { namespace collection { -#include "vt/worker/worker_common.h" -#include "vt/worker/worker_types.h" -#include "vt/utils/container/concurrent_deque.h" +template +struct ParamColMsg; -#include -#include +template +struct ParamColMsg< + Tuple, + ColT, + std::enable_if_t::value> +> : CollectionMessage { + ParamColMsg() = default; -namespace vt { namespace worker { + template + explicit ParamColMsg(Params&&... in_params) + : params(std::forward(in_params)...) + { } -struct OMPWorker { - using WorkerFunType = std::function; - using WorkUnitContainerType = util::container::ConcurrentDeque; + Tuple params; + Tuple& getTuple() { return params; } +}; - OMPWorker( - WorkerIDType const& in_worker_id_, WorkerCountType const& in_num_thds, - WorkerFinishedFnType finished_fn - ); - OMPWorker(OMPWorker const&) = delete; +template +struct ParamColMsg< + Tuple, + ColT, + std::enable_if_t::value> +> : CollectionMessage { + using MessageParentType = CollectionMessage; + vt_msg_serialize_if_needed_by_parent_or_type1(Tuple); // by params - void spawn(); - void join(); - void dispatch(WorkerFunType fun); - void enqueue(WorkUnitType const& work_unit); - void sendTerminateSignal(); - void progress(); + ParamColMsg() = default; + template + explicit ParamColMsg(Params&&... in_params) + : params(std::make_unique(std::forward(in_params)...)) + { } - template - void serialize(Serializer& s) { - s | should_terminate_ - | worker_id_ - | work_queue_ - | finished_fn_; - } + std::unique_ptr params; -private: - void scheduler(); + Tuple& getTuple() { return *params.get(); } -private: - bool should_terminate_= false; - WorkerIDType worker_id_ = no_worker_id; - WorkUnitContainerType work_queue_; - WorkerFinishedFnType finished_fn_ = nullptr; + template + void serialize(SerializerT& s) { + MessageParentType::serialize(s); + s | params; + } }; -}} /* end namespace vt::worker */ - -#include "vt/worker/worker_traits.h" - -namespace vt { namespace worker { - -static_assert( - WorkerTraits::is_worker, - "vt::worker::Worker must follow the Worker concept" -); - -}} /* end namespace vt::worker */ - -#endif /*vt_check_enabled(openmp)*/ +}}} /* end namespace vt::vrt::collection */ -#endif /*INCLUDED_VT_WORKER_WORKER_OPENMP_H*/ +#endif /*INCLUDED_VT_VRT_COLLECTION_MESSAGES_PARAM_COL_MSG_H*/ diff --git a/src/vt/vrt/collection/param/construct_params.h b/src/vt/vrt/collection/param/construct_params.h index 579a188c53..9689b18e1a 100644 --- a/src/vt/vrt/collection/param/construct_params.h +++ b/src/vt/vrt/collection/param/construct_params.h @@ -314,6 +314,7 @@ struct ConstructParams { */ template ThisType&& listInsertHere(Iter begin, Iter end) { + did_list_insert_here_ = true; for (auto&& iter = begin; iter != end; ++iter) { list_insert_here_.emplace_back(std::move(*iter)); } @@ -388,7 +389,7 @@ struct ConstructParams { has_bounds_ or (not has_bounds_ and bulk_inserts_.size() == 1) or (not has_bounds_ and - (list_inserts_.size() > 0 or list_insert_here_.size() > 0)), + (list_inserts_.size() > 0 or did_list_insert_here_)), "Must have valid bounds or exactly one bulk insert or use list insertion" ); } @@ -411,6 +412,7 @@ struct ConstructParams { | label_; s.skip(list_inserts_); s.skip(list_insert_here_); + s.skip(did_list_insert_here_); s.skip(cons_fn_); } @@ -420,6 +422,7 @@ struct ConstructParams { std::vector bulk_inserts_ = {}; std::vector list_inserts_ = {}; std::vector list_insert_here_ = {}; + bool did_list_insert_here_ = false; bool bulk_insert_bounds_ = false; ConstructFnType cons_fn_ = nullptr; bool dynamic_membership_ = false; diff --git a/src/vt/vrt/collection/send/sendable.h b/src/vt/vrt/collection/send/sendable.h index bbfecdeda5..fb9191eb90 100644 --- a/src/vt/vrt/collection/send/sendable.h +++ b/src/vt/vrt/collection/send/sendable.h @@ -48,6 +48,7 @@ #include "vt/vrt/collection/active/active_funcs.h" #include "vt/messaging/message/smart_ptr.h" #include "vt/messaging/pending_send.h" +#include "vt/utils/fntraits/fntraits.h" namespace vt { namespace vrt { namespace collection { @@ -121,6 +122,31 @@ struct Sendable : BaseProxyT { typename MsgT, ActiveColMemberTypedFnType f, typename... Args > messaging::PendingSend send(Args&&... args) const; + + /** + * \brief Create message (with action function handler) and send to collection element + * + * \param[in] args arguments needed for creteating the message + * + * \return a pending send + */ + template + messaging::PendingSend sendMsg( + messaging::MsgPtrThief::MsgT> msg + ) const { + using MsgT = typename ObjFuncTraits::MsgT; + return sendMsg(msg); + } + + /** + * \brief Create message (with action function handler) and send to collection element + * + * \param[in] args arguments needed for creteating the message + * + * \return a pending send + */ + template + messaging::PendingSend send(Args&&... args) const; }; }}} /* end namespace vt::vrt::collection */ diff --git a/src/vt/vrt/collection/send/sendable.impl.h b/src/vt/vrt/collection/send/sendable.impl.h index 96c7d906e8..9118a84884 100644 --- a/src/vt/vrt/collection/send/sendable.impl.h +++ b/src/vt/vrt/collection/send/sendable.impl.h @@ -47,6 +47,7 @@ #include "vt/config.h" #include "vt/vrt/collection/send/sendable.h" #include "vt/vrt/collection/manager.h" +#include "vt/vrt/collection/messages/param_col_msg.h" namespace vt { namespace vrt { namespace collection { @@ -129,6 +130,34 @@ messaging::PendingSend Sendable::send(Args&&... args) co return sendMsg(makeMessage(std::forward(args)...)); } +template +template +messaging::PendingSend Sendable::send(Params&&... params) const { + using FnTrait = ObjFuncTraits; + + using MsgT = typename FnTrait::MsgT; + if constexpr (std::is_same_v) { + using Tuple = typename FnTrait::TupleType; + using SendMsgT = ParamColMsg; + auto msg = vt::makeMessage(std::forward(params)...); + auto han = auto_registry::makeAutoHandlerCollectionMemParam< + ColT, decltype(f), f, SendMsgT + >(); + auto col_proxy = this->getCollectionProxy(); + auto elm_proxy = this->getElementProxy(); + auto proxy = VrtElmProxy(col_proxy, elm_proxy); + return theCollection()->sendMsgUntypedHandler( + proxy, msg.get(), han + ); + } else { + auto msg = makeMessage(std::forward(params)...); + return sendMsg(msg); + } + + // Silence nvcc warning (no longer needed for CUDA 11.7 and up) + return messaging::PendingSend{std::nullptr_t{}}; +} + }}} /* end namespace vt::vrt::collection */ diff --git a/src/vt/vrt/collection/traits/coll_msg.h b/src/vt/vrt/collection/traits/coll_msg.h index aeeb8afb2c..a3c7785c0b 100644 --- a/src/vt/vrt/collection/traits/coll_msg.h +++ b/src/vt/vrt/collection/traits/coll_msg.h @@ -46,7 +46,7 @@ #include "vt/config.h" -#include "detector_headers.h" +#include "checkpoint/detector.h" namespace vt { namespace vrt { namespace collection { diff --git a/src/vt/vrt/collection/types/base.h b/src/vt/vrt/collection/types/base.h index bd73d99515..263925cada 100644 --- a/src/vt/vrt/collection/types/base.h +++ b/src/vt/vrt/collection/types/base.h @@ -58,6 +58,7 @@ namespace vt { namespace vrt { namespace collection { template struct CollectionBase : Indexable { + using IsCollectionType = std::true_type; using ProxyType = VirtualElmProxyType; using CollectionProxyType = CollectionProxy; diff --git a/src/vt/vrt/context/context_vrt_funcs.h b/src/vt/vrt/context/context_vrt_funcs.h index 1790d55dfd..fa6f042bf7 100644 --- a/src/vt/vrt/context/context_vrt_funcs.h +++ b/src/vt/vrt/context/context_vrt_funcs.h @@ -51,10 +51,10 @@ namespace vt { namespace vrt { struct VirtualContext; -using ActiveVirtualFnPtrType = void(*)(BaseMessage *, VirtualContext*); +using ActiveVirtualFnPtrType = void(*)(VirtualContext*, BaseMessage*); template -using ActiveVrtTypedFnType = void(MessageT*, VirtualContextT*); +using ActiveVrtTypedFnType = void(VirtualContextT*, MessageT*); }} /* end namespace vt::context */ diff --git a/src/vt/vrt/context/context_vrtinfo.cc b/src/vt/vrt/context/context_vrtinfo.cc index 493a365353..38347a49b9 100644 --- a/src/vt/vrt/context/context_vrtinfo.cc +++ b/src/vt/vrt/context/context_vrtinfo.cc @@ -44,11 +44,8 @@ #include "vt/config.h" #include "vt/vrt/context/context_vrtinfo.h" #include "vt/vrt/context/context_vrtmessage.h" -#include "vt/utils/mutex/mutex.h" -#include "vt/utils/atomic/atomic.h" #include "vt/registry/auto/vc/auto_registry_vc.h" #include "vt/registry/auto/map/auto_registry_map.h" -#include "vt/worker/worker_headers.h" #include "vt/messaging/message.h" #include "vt/runnable/make_runnable.h" @@ -61,8 +58,7 @@ namespace vt { namespace vrt { VirtualInfo::VirtualInfo( VirtualPtrType in_vrt_ptr, VirtualProxyType const& proxy_in, bool needs_lock ) : proxy_(proxy_in), - is_constructed_(in_vrt_ptr != nullptr), - vrt_ptr_(is_constructed_ ? std::move(in_vrt_ptr) : nullptr), + vrt_ptr_(in_vrt_ptr != nullptr ? std::move(in_vrt_ptr) : nullptr), needs_lock_(needs_lock) { } @@ -70,7 +66,6 @@ void VirtualInfo::setVirtualContextPtr(VirtualPtrType in_vrt_ptr) { vtAssert(in_vrt_ptr != nullptr, "Must have a valid vrt ptr"); vrt_ptr_ = std::move(in_vrt_ptr); - is_constructed_ = true; vt_debug_print( verbose, vrt, @@ -78,16 +73,9 @@ void VirtualInfo::setVirtualContextPtr(VirtualPtrType in_vrt_ptr) { print_ptr(in_vrt_ptr.get()) ); - msg_buffer_.attach([this](VirtualMessage* msg){ - #if vt_threading_enabled - theWorkerGrp()->enqueueCommThread([this,msg]{ - enqueueWorkUnit(msg); - }); - #else - (void)this; + for(auto && msg : msg_buffer_) { enqueueWorkUnit(msg); - #endif - }); + } } bool VirtualInfo::enqueueWorkUnit(VirtualMessage* raw_msg) { @@ -110,39 +98,20 @@ bool VirtualInfo::enqueueWorkUnit(VirtualMessage* raw_msg) { .run(); }; - bool const has_workers = theContext()->hasWorkers(); - - if (has_workers) { - #if vt_threading_enabled - bool const execute_comm = msg->getExecuteCommThread(); - if (hasCoreMap() && !execute_comm) { - auto const core = getCore(); - theWorkerGrp()->enqueueForWorker(core, work_unit); - } else { - theWorkerGrp()->enqueueCommThread(work_unit); - } - #else - work_unit(); - #endif - return true; - } else { - work_unit(); - return false; - } + work_unit(); + return false; } void VirtualInfo::tryEnqueueWorkUnit(VirtualMessage* msg) { - bool const is_constructed = is_constructed_.load(); - vt_debug_print( verbose, vrt, - "tryEnqueueWorkUnit is_cons={}\n", print_bool(is_constructed) + "tryEnqueueWorkUnit \n" ); - if (is_constructed) { + if (vrt_ptr_ != nullptr) { enqueueWorkUnit(msg); } else { - msg_buffer_.push(msg); + msg_buffer_.push_back(msg); } } diff --git a/src/vt/vrt/context/context_vrtinfo.h b/src/vt/vrt/context/context_vrtinfo.h index 2286617111..8dc9121cec 100644 --- a/src/vt/vrt/context/context_vrtinfo.h +++ b/src/vt/vrt/context/context_vrtinfo.h @@ -48,12 +48,8 @@ #include "vt/vrt/context/context_vrt.h" #include "vt/vrt/context/context_vrtmessage.h" #include "vt/vrt/context/context_vrt_fwd.h" -#include "vt/utils/mutex/mutex.h" -#include "vt/utils/atomic/atomic.h" -#include "vt/utils/container/process_ready_buffer.h" #include "vt/registry/auto/vc/auto_registry_vc.h" #include "vt/registry/auto/map/auto_registry_map.h" -#include "vt/worker/worker_headers.h" #include #include @@ -61,11 +57,8 @@ namespace vt { namespace vrt { -using ::vt::util::atomic::AtomicType; -using ::vt::util::container::ProcessBuffer; - struct VirtualInfo { - using MsgBufferContainerType = ProcessBuffer; + using MsgBufferContainerType = std::vector; using VirtualPtrType = std::unique_ptr; VirtualInfo( @@ -85,26 +78,18 @@ struct VirtualInfo { VirtualContext *get() const; - bool isConstructed() const { return is_constructed_.load(); } VirtualProxyType getProxy() const { return proxy_; } - CoreType getCore() const { return default_core_; } NodeType getNode() const { return default_node_; } - void mapToCore(CoreType const& core) { default_core_ = core; } - void setCoreMap(HandlerType const han) { core_map_handle_ = han; } void setNodeMap(HandlerType const han) { node_map_handle_ = han; } - bool hasCoreMap() const { return core_map_handle_ != uninitialized_handler; } bool hasNodeMap() const { return node_map_handle_ != uninitialized_handler; } void setSeed(SeedType const seed) { seed_ = seed; } template void serialize(Serializer& s) { - s | core_map_handle_ - | node_map_handle_ - | default_core_ + s | node_map_handle_ | default_node_ | proxy_ - | is_constructed_ | vrt_ptr_ | needs_lock_ | seed_ @@ -112,13 +97,9 @@ struct VirtualInfo { } private: - HandlerType core_map_handle_ = uninitialized_handler; HandlerType node_map_handle_ = uninitialized_handler; - - CoreType default_core_ = uninitialized_destination; NodeType default_node_ = uninitialized_destination; VirtualProxyType proxy_ = no_vrt_proxy; - AtomicType is_constructed_ = {false}; VirtualPtrType vrt_ptr_ = nullptr; bool needs_lock_ = false; SeedType seed_ = no_seed; diff --git a/src/vt/vrt/context/context_vrtmanager.h b/src/vt/vrt/context/context_vrtmanager.h index f807540f73..77579fd9a8 100644 --- a/src/vt/vrt/context/context_vrtmanager.h +++ b/src/vt/vrt/context/context_vrtmanager.h @@ -140,13 +140,12 @@ struct VirtualContextManager VirtualProxyType makeVirtualPlaceholder(); void setupMappedVirutalContext( - VirtualProxyType const& proxy, SeedType const& seed, CoreType const& core, - HandlerType const map_handle + VirtualProxyType const& proxy, SeedType const& seed ); template VirtualProxyType makeVirtualMapComm( - SeedType const& seed, HandlerType const map_handle, Args&& ... args + SeedType const& seed, Args&& ... args ); template diff --git a/src/vt/vrt/context/context_vrtmanager.impl.h b/src/vt/vrt/context/context_vrtmanager.impl.h index 381be9ad96..39d3bad273 100644 --- a/src/vt/vrt/context/context_vrtmanager.impl.h +++ b/src/vt/vrt/context/context_vrtmanager.impl.h @@ -53,7 +53,6 @@ #include "vt/topos/location/manager.h" #include "vt/registry/auto/vc/auto_registry_vc.h" #include "vt/registry/auto/map/auto_registry_map.h" -#include "vt/worker/worker_headers.h" #include #include @@ -106,7 +105,7 @@ template auto send_msg = makeMessage( cons_node, req_node, request_id, new_proxy ); - theMsg()->sendMsg( + theMsg()->sendMsg( req_node, send_msg ); } @@ -139,66 +138,50 @@ messaging::PendingSend VirtualContextManager::sendSerialMsg( ) { auto base_msg = promoteMsg(msg).template to(); - if (theContext()->getWorker() == worker_id_comm_thread) { - NodeType const& home_node = VirtualProxyBuilder::getVirtualNode(toProxy); - // register the user's handler - HandlerType const han = auto_registry::makeAutoHandlerVC(); - // save the user's handler in the message - msg->setVrtHandler(han); - msg->setProxy(toProxy); - - vt_debug_print( - normal, vrt, - "sending serialized msg to VC: msg={}, han={}, home_node={}, toProxy={}\n", - print_ptr(msg), han, home_node, toProxy - ); + NodeType const& home_node = VirtualProxyBuilder::getVirtualNode(toProxy); + // register the user's handler + HandlerType const han = auto_registry::makeAutoHandlerVC(); + // save the user's handler in the message + msg->setVrtHandler(han); + msg->setProxy(toProxy); - using SerialMsgT = SerializedEagerMsg; - - // route the message to the destination using the location manager - messaging::PendingSend pending( - base_msg, [=](MsgPtr mymsg){ - // Uses special implementation overload not exposed in theMsg.. - MsgT* typed_msg = reinterpret_cast(mymsg.get()); - auto sendSerialHan = auto_registry::makeAutoHandler>(); - SerializedMessenger::sendSerialMsgSendImpl( - typed_msg, - sendSerialHan, - // custom send lambda to route the message - [=](MsgSharedPtr innermsg) -> messaging::PendingSend { - innermsg->setProxy(toProxy); - theLocMan()->vrtContextLoc->routeMsgHandler< - SerialMsgT, SerializedMessenger::payloadMsgHandler - >(toProxy, home_node, innermsg); - return messaging::PendingSend(nullptr); - }, - // custom data transfer lambda if above the eager threshold - [=](ActionNodeSendType action) -> messaging::PendingSend { - auto captured_action = [=](NodeType node){ action(node); }; - theLocMan()->vrtContextLoc->routeNonEagerAction( - toProxy, home_node, captured_action - ); - return messaging::PendingSend(nullptr); - } - ); - } - ); - return pending; - } else { - return messaging::PendingSend( - base_msg, [=](MsgPtr mymsg) { - #if vt_threading_enabled - theWorkerGrp()->enqueueCommThread([=]{ - auto typed_msg = reinterpret_cast(mymsg.get()); - theVirtualManager()->sendSerialMsg(toProxy, typed_msg); - }); - #else - auto typed_msg = reinterpret_cast(mymsg.get()); - theVirtualManager()->sendSerialMsg(toProxy, typed_msg); - #endif - } - ); - } + vt_debug_print( + normal, vrt, + "sending serialized msg to VC: msg={}, han={}, home_node={}, toProxy={}\n", + print_ptr(msg), han, home_node, toProxy + ); + + using SerialMsgT = SerializedEagerMsg; + + // route the message to the destination using the location manager + messaging::PendingSend pending( + base_msg, [=](MsgPtr mymsg){ + // Uses special implementation overload not exposed in theMsg.. + MsgT* typed_msg = reinterpret_cast(mymsg.get()); + auto sendSerialHan = auto_registry::makeAutoHandler>(); + SerializedMessenger::sendSerialMsgSendImpl( + typed_msg, + sendSerialHan, + // custom send lambda to route the message + [=](MsgSharedPtr innermsg) -> messaging::PendingSend { + innermsg->setProxy(toProxy); + theLocMan()->vrtContextLoc->routeMsgHandler< + SerialMsgT, SerializedMessenger::payloadMsgHandler + >(toProxy, home_node, innermsg); + return messaging::PendingSend(nullptr); + }, + // custom data transfer lambda if above the eager threshold + [=](ActionNodeSendType action) -> messaging::PendingSend { + auto captured_action = [=](NodeType node){ action(node); }; + theLocMan()->vrtContextLoc->routeNonEagerAction( + toProxy, home_node, captured_action + ); + return messaging::PendingSend(nullptr); + } + ); + } + ); + return pending; } template @@ -235,81 +218,40 @@ VirtualProxyType VirtualContextManager::makeVirtualRemote( sys_msg->info = *info.get(); - theMsg()->sendMsg>(dest, sys_msg); + theMsg()->sendMsg>(dest, sys_msg); return return_proxy; } inline void VirtualContextManager::setupMappedVirutalContext( - VirtualProxyType const& proxy, SeedType const& seed, CoreType const& core, - HandlerType const map_handle + VirtualProxyType const& proxy, SeedType const& seed ) { auto vrt_info = getVirtualInfoByProxy(proxy); vrt_info->setSeed(seed); - vrt_info->setCoreMap(map_handle); - vrt_info->mapToCore(core); } template VirtualProxyType VirtualContextManager::makeVirtualMapComm( - SeedType const& seed, HandlerType const map_handle, Args&& ... args + SeedType const& seed, Args&& ... args ) { auto const& proxy = makeVirtual( std::forward(args)... ); - setupMappedVirutalContext(proxy, seed, worker_id_comm_thread, map_handle); + setupMappedVirutalContext(proxy, seed); return proxy; } template VirtualProxyType VirtualContextManager::makeVirtualMap(Args... args) { SeedType next_seed = no_seed; - HandlerType core_map_handle = uninitialized_handler; - bool const& has_workers = theContext()->hasWorkers(); vt_debug_print( normal, vrt, - "makeVirtualMap: has_workers={}\n", print_bool(has_workers) + "makeVirtualMap\n" ); - if (has_workers) { - next_seed = cur_seed_++; - core_map_handle = auto_registry::makeAutoHandlerSeedMap(); - - auto const& num_workers = theContext()->getNumWorkers(); - auto const& mapped_core = fn(next_seed, num_workers); - - vt_debug_print( - verbose, vrt, - "seed={}, mapped_core={}, num_workers={}\n", - next_seed, mapped_core, num_workers - ); - - if (mapped_core != worker_id_comm_thread) { - using TupleType = std::tuple; - - auto proxy = makeVirtualPlaceholder(); - auto vrt_info = getVirtualInfoByProxy(proxy); - setupMappedVirutalContext(proxy, next_seed, mapped_core, core_map_handle); - - auto cl = new VirtualMakeClosure( - TupleType{std::forward(args)...}, proxy, vrt_info - ); - - // work to defer to the worker thread - auto work_unit = [=]{ cl->make(); delete cl; }; - #if vt_threading_enabled - theWorkerGrp()->enqueueForWorker(mapped_core, work_unit); - #else - work_unit(); - #endif - - return proxy; - } - } - return makeVirtualMapComm( - next_seed, core_map_handle, std::forward(args)... + next_seed, std::forward(args)... ); } diff --git a/src/vt/worker/worker.h b/src/vt/worker/worker.h deleted file mode 100644 index c354c20af1..0000000000 --- a/src/vt/worker/worker.h +++ /dev/null @@ -1,84 +0,0 @@ -/* -//@HEADER -// ***************************************************************************** -// -// worker.h -// DARMA/vt => Virtual Transport -// -// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC -// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. -// Government retains certain rights in this software. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Questions? Contact darma@sandia.gov -// -// ***************************************************************************** -//@HEADER -*/ - -#if !defined INCLUDED_VT_WORKER_WORKER_H -#define INCLUDED_VT_WORKER_WORKER_H - -#include "vt/config.h" -#include "vt/worker/worker_common.h" -#include "vt/worker/worker_types.h" - -#include - -namespace vt { namespace worker { - -struct Worker { - using WorkerFunType = std::function; - - Worker( - WorkerIDType const& in_worker_id_, WorkerCountType const& in_num_thds, - WorkerFinishedFnType finished_fn - ); - Worker(Worker const&) = delete; - - void spawn(); - void join(); - void dispatch(WorkerFunType fun); - void enqueue(WorkUnitType const& work_unit); - void progress(); -}; - -}} /* end namespace vt::worker */ - -#include "vt/worker/worker_traits.h" - -namespace vt { namespace worker { - -static_assert( - WorkerTraits::is_worker, - "vt::worker::Worker must follow the Worker concept" -); - -}} /* end namespace vt::worker */ - -#endif /*INCLUDED_VT_WORKER_WORKER_H*/ diff --git a/src/vt/worker/worker_common.h b/src/vt/worker/worker_common.h deleted file mode 100644 index 29cea9c104..0000000000 --- a/src/vt/worker/worker_common.h +++ /dev/null @@ -1,79 +0,0 @@ -/* -//@HEADER -// ***************************************************************************** -// -// worker_common.h -// DARMA/vt => Virtual Transport -// -// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC -// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. -// Government retains certain rights in this software. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Questions? Contact darma@sandia.gov -// -// ***************************************************************************** -//@HEADER -*/ - -#if !defined INCLUDED_VT_WORKER_WORKER_COMMON_H -#define INCLUDED_VT_WORKER_WORKER_COMMON_H - -#include "vt/config.h" - -#include -#include - -namespace vt { namespace worker { - -static constexpr WorkerCountType const num_default_workers = 4; -static constexpr WorkerCountType const num_default_comm = 1; - -using WorkerCommFnType = std::function; - -using WorkUnitCountType = int64_t; -static constexpr WorkUnitCountType const no_work_units = 1; - -enum eWorkerGroupEvent { - WorkersIdle = 1, - WorkersBusy = 2, - InvalidEvent = -1 -}; - -#define WORKER_GROUP_EVENT_STR(EVT) \ - EVT == eWorkerGroupEvent::WorkersIdle ? "WorkersIdle" : ( \ - EVT == eWorkerGroupEvent::WorkersBusy ? "WorkersBusy" : ( \ - EVT == eWorkerGroupEvent::InvalidEvent ? "InvalidEvent" : "Error" \ - ) \ - ) \ - -using WorkerFinishedFnType = std::function; - -}} /* end namespace vt::worker */ - -#endif /*INCLUDED_VT_WORKER_WORKER_COMMON_H*/ diff --git a/src/vt/worker/worker_group.h b/src/vt/worker/worker_group.h deleted file mode 100644 index 631ba6785e..0000000000 --- a/src/vt/worker/worker_group.h +++ /dev/null @@ -1,136 +0,0 @@ -/* -//@HEADER -// ***************************************************************************** -// -// worker_group.h -// DARMA/vt => Virtual Transport -// -// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC -// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. -// Government retains certain rights in this software. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Questions? Contact darma@sandia.gov -// -// ***************************************************************************** -//@HEADER -*/ - -#if !defined INCLUDED_VT_WORKER_WORKER_GROUP_H -#define INCLUDED_VT_WORKER_WORKER_GROUP_H - -#include "vt/config.h" -#include "vt/worker/worker_common.h" -#include "vt/worker/worker.h" -#include "vt/worker/worker_group_counter.h" -#include "vt/worker/worker_group_comm.h" -#include "vt/utils/atomic/atomic.h" -#include "vt/runtime/component/component_pack.h" - -#if vt_check_enabled(stdthread) - #include "vt/worker/worker_stdthread.h" -#elif vt_check_enabled(fcontext) - #include "vt/worker/worker_seq.h" -#endif - -#include -#include - -namespace vt { namespace worker { - -using ::vt::util::atomic::AtomicType; - -template -struct WorkerGroupAny - : runtime::component::PollableComponent>, - WorkerGroupCounter, WorkerGroupComm -{ - using WorkerType = WorkerT; - using WorkerPtrType = std::unique_ptr; - using WorkerContainerType = std::vector; - - WorkerGroupAny(); - WorkerGroupAny(WorkerCountType const& in_num_workers); - - virtual ~WorkerGroupAny(); - - void initialize() override; - void spawnWorkers(); - void spawnWorkersBlock(WorkerCommFnType fn); - void joinWorkers(); - int progress(TimeType current_time = 0.0) override; - - bool commScheduler(); - void enqueueCommThread(WorkUnitType const& work_unit); - void enqueueAnyWorker(WorkUnitType const& work_unit); - void enqueueForWorker( - WorkerIDType const& worker_id, WorkUnitType const& work_unit - ); - void enqueueAllWorkers(WorkUnitType const& work_unit); - - std::string name() override { return "WorkerGroup"; } - - template - void serialize(SerializerT& s) { - s | finished_fn_ - | initialized_ - | num_workers_ - | workers_; - } - -private: - WorkerFinishedFnType finished_fn_ = nullptr; - bool initialized_ = false; - WorkerCountType num_workers_ = 0; - WorkerContainerType workers_; -}; - -#if vt_check_enabled(stdthread) - using WorkerGroupSTD = WorkerGroupAny; -#elif vt_check_enabled(fcontext) - using WorkerGroupSeq = WorkerGroupAny; -#endif - -}} /* end namespace vt::worker */ - -#if vt_check_enabled(stdthread) - #include "vt/worker/worker_group_traits.h" - - namespace vt { namespace worker { - - static_assert( - WorkerGroupTraits::is_worker, - "WorkerGroupSTD must follow the WorkerGroup concept" - ); - - }} /* end namespace vt::worker */ -#endif /*vt_check_enabled(stdthread)*/ - -#include "vt/worker/worker_group.impl.h" - -#endif /*INCLUDED_VT_WORKER_WORKER_GROUP_H*/ diff --git a/src/vt/worker/worker_group.impl.h b/src/vt/worker/worker_group.impl.h deleted file mode 100644 index 12be86dba1..0000000000 --- a/src/vt/worker/worker_group.impl.h +++ /dev/null @@ -1,210 +0,0 @@ -/* -//@HEADER -// ***************************************************************************** -// -// worker_group.impl.h -// DARMA/vt => Virtual Transport -// -// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC -// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. -// Government retains certain rights in this software. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Questions? Contact darma@sandia.gov -// -// ***************************************************************************** -//@HEADER -*/ - -#if !defined INCLUDED_VT_WORKER_WORKER_GROUP_IMPL_H -#define INCLUDED_VT_WORKER_WORKER_GROUP_IMPL_H - -#include "vt/config.h" -#include "vt/context/context.h" -#include "vt/worker/worker_common.h" -#include "vt/worker/worker_group.h" - -#include -#include - -namespace vt { namespace worker { - -template -WorkerGroupAny::WorkerGroupAny() - : WorkerGroupAny(num_default_workers) -{ } - -template -WorkerGroupAny::WorkerGroupAny(WorkerCountType const& in_num_workers) - : num_workers_(in_num_workers) -{ - vt_debug_print( - normal, worker, - "WorkerGroup: constructing with default: num_workers_={}\n", - num_workers_ - ); - - initialize(); -} - -template -void WorkerGroupAny::initialize() { - namespace ph = std::placeholders; - finished_fn_ = std::bind(&WorkerGroupAny::finished, this, ph::_1, ph::_2); - - workers_.resize(num_workers_); -} - -template -bool WorkerGroupAny::commScheduler() { - return WorkerGroupComm::schedulerComm(finished_fn_); -} - -template -/*virtual*/ WorkerGroupAny::~WorkerGroupAny() { - if (workers_.size() > 0) { - joinWorkers(); - } -} - -template -void WorkerGroupAny::enqueueCommThread(WorkUnitType const& work_unit) { - vtAssert(initialized_, "Must be initialized to enqueue"); - this->enqueued(); - WorkerGroupComm::enqueueComm(work_unit); -} - -template -void WorkerGroupAny::enqueueAnyWorker(WorkUnitType const& work_unit) { - vtAssert(initialized_, "Must be initialized to enqueue"); - - this->enqueued(); - workers_[0].enqueue(work_unit); -} - -template -void WorkerGroupAny::enqueueForWorker( - WorkerIDType const& worker_id, WorkUnitType const& work_unit -) { - vtAssert(initialized_, "Must be initialized to enqueue"); - vtAssert( - static_cast(worker_id) < workers_.size(), - "Worker ID must be valid" - ); - - this->enqueued(); - workers_[worker_id]->enqueue(work_unit); -} - -template -void WorkerGroupAny::enqueueAllWorkers(WorkUnitType const& work_unit) { - vtAssert(initialized_, "Must be initialized to enqueue"); - - this->enqueued(num_workers_); - - for (auto&& elm : workers_) { - elm->enqueue(work_unit); - } -} - -template -int WorkerGroupAny::progress(TimeType /* current_time */) { - for (auto&& elm : workers_) { - elm->progress(); - } - - WorkerGroupCounter::progress(); - - return 0; -} - -template -void WorkerGroupAny::spawnWorkersBlock(WorkerCommFnType comm_fn) { - vt_debug_print( - verbose, worker, - "WorkerGroup: spawnWorkersBlock: num_workers_={}\n", num_workers_ - ); - - // spawn the workers - spawnWorkers(); - - // block the comm thread on the passed function - comm_fn(); -} - -template -void WorkerGroupAny::spawnWorkers() { - using namespace std::placeholders; - - vt_debug_print( - verbose, worker, - "WorkerGroup: spawnWorkers: num_workers_={}\n", num_workers_ - ); - - vtAssert( - workers_.size() >= static_cast(num_workers_), - "Must be correct size" - ); - - for (int i = 0; i < num_workers_; i++) { - WorkerIDType const worker_id = i; - workers_[i] = std::make_unique( - worker_id, num_workers_, finished_fn_ - ); - } - - for (auto&& elm : workers_) { - elm->spawn(); - } - - initialized_ = true; - - // Give every worker at least one work unit (for termination purposes) - auto initial_work_unit = []{}; - enqueueAllWorkers(initial_work_unit); -} - -template -void WorkerGroupAny::joinWorkers() { - vt_debug_print( - verbose, worker, - "WorkerGroup: joinWorkers: num_workers_={}\n", num_workers_ - ); - - for (auto&& elm : workers_) { - elm->join(); - } - - workers_.clear(); - - initialized_ = false; -} - -}} /* end namespace vt::worker */ - -#endif /*INCLUDED_VT_WORKER_WORKER_GROUP_IMPL_H*/ diff --git a/src/vt/worker/worker_group_comm.cc b/src/vt/worker/worker_group_comm.cc deleted file mode 100644 index ea5362782b..0000000000 --- a/src/vt/worker/worker_group_comm.cc +++ /dev/null @@ -1,80 +0,0 @@ -/* -//@HEADER -// ***************************************************************************** -// -// worker_group_comm.cc -// DARMA/vt => Virtual Transport -// -// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC -// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. -// Government retains certain rights in this software. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Questions? Contact darma@sandia.gov -// -// ***************************************************************************** -//@HEADER -*/ - -#include "vt/config.h" -#include "vt/context/context.h" -#include "vt/worker/worker_common.h" -#include "vt/worker/worker_group_comm.h" - -namespace vt { namespace worker { - -void WorkerGroupComm::enqueueComm(WorkUnitType const& work_unit) { - vt_debug_print( - normal, worker, - "WorkerGroupComm: enqueue comm thread size={}\n", comm_work_deque_.size() - ); - - comm_work_deque_.pushBack(work_unit); -} - -bool WorkerGroupComm::schedulerComm(WorkerFinishedFnType finished_fn) { - bool found = false; - if (comm_work_deque_.size() > 0) { - vt_debug_print( - normal, worker, - "WorkerGroupComm: scheduler executing size={}\n", comm_work_deque_.size() - ); - - auto work_unit = comm_work_deque_.front(); - comm_work_deque_.popFront(); - work_unit(); - found = true; - - if (finished_fn) { - finished_fn(worker_id_comm_thread, 1); - } - } - return found; -} - -}} /* end namespace vt::worker */ diff --git a/src/vt/worker/worker_group_comm.h b/src/vt/worker/worker_group_comm.h deleted file mode 100644 index 5e75d053bc..0000000000 --- a/src/vt/worker/worker_group_comm.h +++ /dev/null @@ -1,66 +0,0 @@ -/* -//@HEADER -// ***************************************************************************** -// -// worker_group_comm.h -// DARMA/vt => Virtual Transport -// -// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC -// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. -// Government retains certain rights in this software. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Questions? Contact darma@sandia.gov -// -// ***************************************************************************** -//@HEADER -*/ - -#if !defined INCLUDED_VT_WORKER_WORKER_GROUP_COMM_H -#define INCLUDED_VT_WORKER_WORKER_GROUP_COMM_H - -#include "vt/config.h" -#include "vt/worker/worker_common.h" -#include "vt/worker/worker_types.h" -#include "vt/utils/container/concurrent_deque.h" - -namespace vt { namespace worker { - -using ::vt::util::container::ConcurrentDeque; - -struct WorkerGroupComm { - void enqueueComm(WorkUnitType const& work_unit); - bool schedulerComm(WorkerFinishedFnType finished_fn); - -protected: - ConcurrentDeque comm_work_deque_; -}; - -}} /* end namespace vt::worker */ - -#endif /*INCLUDED_VT_WORKER_WORKER_GROUP_COMM_H*/ diff --git a/src/vt/worker/worker_group_counter.cc b/src/vt/worker/worker_group_counter.cc deleted file mode 100644 index c04c101a48..0000000000 --- a/src/vt/worker/worker_group_counter.cc +++ /dev/null @@ -1,189 +0,0 @@ -/* -//@HEADER -// ***************************************************************************** -// -// worker_group_counter.cc -// DARMA/vt => Virtual Transport -// -// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC -// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. -// Government retains certain rights in this software. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Questions? Contact darma@sandia.gov -// -// ***************************************************************************** -//@HEADER -*/ - -#include "vt/config.h" -#include "vt/context/context.h" -#include "vt/worker/worker_common.h" -#include "vt/worker/worker_group_counter.h" -#include "vt/termination/term_headers.h" - -#include -#include - -#define WORKER_COUNTER_VERBOSE 0 - -namespace vt { namespace worker { - -void WorkerGroupCounter::attachEnqueueProgressFn() { - namespace ph = std::placeholders; - auto fn = std::bind(&WorkerGroupCounter::enqueued, this, ph::_1); - enqueued_count_.attach(fn, worker_id_comm_thread); -} - -void WorkerGroupCounter::enqueued(WorkUnitCountType num) { - auto const is_comm = theContext()->getWorker() == worker_id_comm_thread; - if (is_comm) { - enqueuedComm(num); - } else { - enqueued_count_.push(num); - } -} - -void WorkerGroupCounter::enqueuedComm(WorkUnitCountType num) { - assertCommThread(); - - theTerm()->produce(term::any_epoch_sentinel, num); - - num_enqueued_ += num; - maybe_idle_.store(false); - - // Call progress to update in the case where state was previously reported as - // idle to the listeners - progress(); -} - -void WorkerGroupCounter::finished(WorkerIDType id, WorkUnitCountType num) { - #if WORKER_COUNTER_VERBOSE - vt_debug_print( - normal, worker, - "WorkerGroupCounter: completed: id={}, num={}\n", id, num - ); - #endif - - // This method may be called from multiple threads - auto const cur_finished = num_finished_.fetch_add(num) + num; - auto const cur_enqueued = num_enqueued_.load(); - bool const is_idle = cur_finished == cur_enqueued; - if (is_idle) { - maybe_idle_.store(is_idle); - } -} - -void WorkerGroupCounter::assertCommThread() { - // Sanity check to ensure single-threaded methods are only called by the - // communication thread - vtAssert( - theContext()->getWorker() == worker_id_comm_thread, - "This must only run on the communication thread" - ); -} - -void WorkerGroupCounter::registerIdleListener(IdleListenerType listener) { - assertCommThread(); - listeners_.push_back(listener); -} - -void WorkerGroupCounter::progress() { - bool const cur_maybe_idle = maybe_idle_.load(); - bool const last_event_idle = last_event_ == eWorkerGroupEvent::WorkersIdle; - - assertCommThread(); - - enqueued_count_.progress(); - - if (cur_maybe_idle || last_event_idle) { - auto const cur_finished = num_finished_.load(); - auto const cur_enqueued = num_enqueued_.load(); - bool const is_idle = cur_finished == cur_enqueued; - - #if WORKER_COUNTER_VERBOSE - vt_debug_print( - normal, worker, - "WorkerGroupCounter: progress: fin={}, enq={}, is_idle={}, " - "last_event={}, last_event_idle={}\n", - cur_finished, cur_enqueued, print_bool(is_idle), - WORKER_GROUP_EVENT_STR(last_event_), print_bool(last_event_idle) - ); - #endif - - if (is_idle && !last_event_idle) { - // trigger listeners - triggerListeners(eWorkerGroupEvent::WorkersIdle); - } else if (!is_idle) { - if (last_event_idle) { - triggerListeners(eWorkerGroupEvent::WorkersBusy); - } - maybe_idle_.store(is_idle); - } else if (is_idle && num_finished_.load() > num_consumed_) { - updateConsumedTerm(); - } - } -} - -void WorkerGroupCounter::updateConsumedTerm() { - auto const cur_finished = num_finished_.load(); - auto const cur_consumed = num_consumed_; - auto const num_to_consume = cur_finished - cur_consumed; - - num_consumed_ += num_to_consume; - - vt_debug_print( - normal, worker, - "WorkerGroupCounter: updating: num_fin={}, num_con={}, num_sub={}\n", - cur_finished, cur_consumed, num_to_consume - ); - - theTerm()->consume(term::any_epoch_sentinel, num_to_consume); -} - -void WorkerGroupCounter::triggerListeners(eWorkerGroupEvent event) { - #if WORKER_COUNTER_VERBOSE - vt_debug_print( - normal, worker, - "WorkerGroupCounter: triggering listeners: event={}\n", - WORKER_GROUP_EVENT_STR(event) - ); - #endif - - if (event == eWorkerGroupEvent::WorkersIdle) { - updateConsumedTerm(); - } - - last_event_ = event; - - for (auto&& elm : listeners_) { - elm(event); - } -} - -}} /* end namespace vt::worker */ diff --git a/src/vt/worker/worker_group_omp.cc b/src/vt/worker/worker_group_omp.cc deleted file mode 100644 index 4e4c696cad..0000000000 --- a/src/vt/worker/worker_group_omp.cc +++ /dev/null @@ -1,224 +0,0 @@ -/* -//@HEADER -// ***************************************************************************** -// -// worker_group_omp.cc -// DARMA/vt => Virtual Transport -// -// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC -// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. -// Government retains certain rights in this software. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Questions? Contact darma@sandia.gov -// -// ***************************************************************************** -//@HEADER -*/ - -#include "vt/config.h" -#include "vt/context/context.h" -#include "vt/context/context_attorney.h" -#include "vt/collective/collective_ops.h" - -#if vt_check_enabled(openmp) - -#include "vt/worker/worker_common.h" -#include "vt/worker/worker_group_omp.h" - -#include - -#include - -#define WORKER_OMP_VERBOSE 0 - -namespace vt { namespace worker { - -WorkerGroupOMP::WorkerGroupOMP() - : WorkerGroupOMP(num_default_workers) -{ } - -WorkerGroupOMP::WorkerGroupOMP(WorkerCountType const& in_num_workers) - : num_workers_(in_num_workers) -{ - initialize(); -} - -void WorkerGroupOMP::initialize() { - namespace ph = std::placeholders; - finished_fn_ = std::bind(&WorkerGroupOMP::finished, this, ph::_1, ph::_2); - - worker_state_.resize(num_workers_); -} - -bool WorkerGroupOMP::commScheduler() { - return WorkerGroupComm::schedulerComm(finished_fn_); -} - -int WorkerGroupOMP::progress(TimeType /*current_time*/) { - WorkerGroupCounter::progress(); - return 0; -} - -/*virtual*/ WorkerGroupOMP::~WorkerGroupOMP() { - worker_state_.clear(); -} - -void WorkerGroupOMP::enqueueCommThread(WorkUnitType const& work_unit) { - // if (theContext()->getWorker() != worker_id_comm_thread) { - // enqueue_worker_mutex_.lock(); - // } - this->enqueued(); - WorkerGroupComm::enqueueComm(work_unit); - // if (theContext()->getWorker() != worker_id_comm_thread) { - // enqueue_worker_mutex_.unlock(); - // } -} - -void WorkerGroupOMP::spawnWorkersBlock(WorkerCommFnType comm_fn) { - using ::vt::ctx::ContextAttorney; - - vt_debug_print( - normal, worker, - "Worker group OMP: launching num worker threads={}, num comm threads={}\n", - num_workers_, num_default_comm - ); - - initialized_ = true; - - vt_debug_print( - normal, worker, - "worker group OMP spawning={}\n", num_workers_ + 1 - ); - - #pragma omp parallel num_threads(num_workers_ + 1) - { - WorkerIDType const thd = omp_get_thread_num(); - WorkerIDType const nthds = omp_get_num_threads(); - - // For now, all workers to have direct access to the runtime - // TODO: this needs to change - CollectiveOps::setCurrentRuntimeTLS(); - - if (thd < num_workers_) { - // Set the thread-local worker in Context - ContextAttorney::setWorker(thd); - - vt_debug_print( - normal, worker, - "Worker group OMP: (worker) thd={}, num threads={}\n", thd, nthds - ); - - worker_state_[thd] = std::make_unique( - thd, nthds, finished_fn_ - ); - ready_++; - worker_state_[thd]->spawn(); - } else { - // Set the thread-local worker in Context - ContextAttorney::setWorker(worker_id_comm_thread); - - vt_debug_print( - normal, worker, - "Worker group OMP: (comm) thd={}, num threads={}\n", thd, nthds - ); - - // Wait until all the workers are created and have filled the - // worker_state_ vector - while (ready_.load() < num_workers_) ; - - // Enqueue an initial work unit for termination purposes - auto initial_work_unit = []{}; - enqueueAllWorkers(initial_work_unit); - - // launch comm function on the main communication thread - comm_fn(); - - // once the comm function exits the program is terminated - for (auto thr = 0; thr < num_workers_; thr++) { - vt_debug_print(normal, worker, "comm: calling join thd={}\n", thr ); - worker_state_[thr]->join(); - } - } - } -} - -void WorkerGroupOMP::spawnWorkers() { - vtAssert(0, "Not supported on OMP workers"); -} - -void WorkerGroupOMP::joinWorkers() { - for (int i = 0; i < num_workers_; i++) { - worker_state_[i]->sendTerminateSignal(); - } -} - -void WorkerGroupOMP::enqueueAnyWorker(WorkUnitType const& work_unit) { - vtAssert(initialized_, "Must be initialized to enqueue"); - - #if WORKER_OMP_VERBOSE - vt_debug_print(normal, worker, "WorkerGroupOMP: enqueue any worker\n"); - #endif - - this->enqueued(); - worker_state_[0]->enqueue(work_unit); -} - -void WorkerGroupOMP::enqueueForWorker( - WorkerIDType const& worker_id, WorkUnitType const& work_unit -) { - vtAssert(initialized_, "Must be initialized to enqueue"); - vtAssert( - static_cast(worker_id) < worker_state_.size(), - "Worker ID must be valid" - ); - - #if WORKER_OMP_VERBOSE - vt_debug_print(normal, worker, "WorkerGroupOMP: enqueue for id={}\n", worker_id); - #endif - - this->enqueued(); - worker_state_[worker_id]->enqueue(work_unit); -} - -void WorkerGroupOMP::enqueueAllWorkers(WorkUnitType const& work_unit) { - vtAssert(initialized_, "Must be initialized to enqueue"); - - #if WORKER_OMP_VERBOSE - vt_debug_print(normal, worker, "WorkerGroupOMP: enqueue all workers\n"); - #endif - - this->enqueued(num_workers_); - for (auto&& elm : worker_state_) { - elm->enqueue(work_unit); - } -} - -}} /* end namespace vt::worker */ - -#endif diff --git a/src/vt/worker/worker_group_omp.h b/src/vt/worker/worker_group_omp.h deleted file mode 100644 index 5e35ca48d5..0000000000 --- a/src/vt/worker/worker_group_omp.h +++ /dev/null @@ -1,133 +0,0 @@ -/* -//@HEADER -// ***************************************************************************** -// -// worker_group_omp.h -// DARMA/vt => Virtual Transport -// -// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC -// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. -// Government retains certain rights in this software. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Questions? Contact darma@sandia.gov -// -// ***************************************************************************** -//@HEADER -*/ - -#if !defined INCLUDED_VT_WORKER_WORKER_GROUP_OMP_H -#define INCLUDED_VT_WORKER_WORKER_GROUP_OMP_H - -#include "vt/config.h" - -#if vt_check_enabled(openmp) - -#include "vt/worker/worker_common.h" -#include "vt/worker/worker_types.h" -#include "vt/worker/worker_openmp.h" -#include "vt/worker/worker_group_counter.h" -#include "vt/worker/worker_group_comm.h" -#include "vt/utils/mutex/mutex.h" -#include "vt/runtime/component/component_pack.h" - -#include -#include -#include - -namespace vt { namespace worker { - -struct WorkerGroupOMP - : runtime::component::PollableComponent, - WorkerGroupCounter, WorkerGroupComm -{ - using WorkerType = OMPWorker; - using WorkerStateType = WorkerType; - using WorkerStatePtrType = std::unique_ptr; - using WorkerStateContainerType = std::vector; - using WorkerFunType = std::function; - using WorkUnitContainerType = util::container::ConcurrentDeque; - using MutexType = util::mutex::MutexType; - - WorkerGroupOMP(); - WorkerGroupOMP(WorkerCountType const& in_num_workers); - - virtual ~WorkerGroupOMP(); - - std::string name() override { return "WorkerGroupOMP"; } - - void initialize() override; - void spawnWorkers(); - void spawnWorkersBlock(WorkerCommFnType fn); - void joinWorkers(); - int progress(TimeType current_time = 0.0) override; - bool commScheduler(); - - // non-thread-safe comm and worker thread enqueue - void enqueueCommThread(WorkUnitType const& work_unit); - void enqueueAnyWorker(WorkUnitType const& work_unit); - void enqueueForWorker( - WorkerIDType const& worker_id, WorkUnitType const& work_unit - ); - void enqueueAllWorkers(WorkUnitType const& work_unit); - - template - void serialize(SerializerT& s) { - s | finished_fn_ - | ready_ - | initialized_ - | num_workers_ - | worker_state_ - | enqueue_worker_mutex_; - } - -private: - WorkerFinishedFnType finished_fn_ = nullptr; - AtomicType ready_ = {0}; - bool initialized_ = false; - WorkerCountType num_workers_ = 0; - WorkerStateContainerType worker_state_; - MutexType enqueue_worker_mutex_{}; -}; - -}} /* end namespace vt::worker */ - -#include "vt/worker/worker_group_traits.h" - -namespace vt { namespace worker { - -static_assert( - WorkerGroupTraits::is_worker, - "WorkerGroupOMP must follow the WorkerGroup concept" -); - -}} /* end namespace vt::worker */ - -#endif /*vt_check_enabled(openmp)*/ - -#endif /*INCLUDED_VT_WORKER_WORKER_GROUP_OMP_H*/ diff --git a/src/vt/worker/worker_group_traits.h b/src/vt/worker/worker_group_traits.h deleted file mode 100644 index 1e497ac5bd..0000000000 --- a/src/vt/worker/worker_group_traits.h +++ /dev/null @@ -1,144 +0,0 @@ -/* -//@HEADER -// ***************************************************************************** -// -// worker_group_traits.h -// DARMA/vt => Virtual Transport -// -// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC -// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. -// Government retains certain rights in this software. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Questions? Contact darma@sandia.gov -// -// ***************************************************************************** -//@HEADER -*/ - -#if !defined INCLUDED_VT_WORKER_WORKER_GROUP_TRAITS_H -#define INCLUDED_VT_WORKER_WORKER_GROUP_TRAITS_H - -#include "vt/config.h" -#include "vt/worker/worker_common.h" -#include "vt/worker/worker_types.h" - -#include "detector_headers.h" - -namespace vt { namespace worker { - -template -struct WorkerGroupTraits { - template - using WorkerType_t = typename U::WorkerType; - using has_WorkerType = detection::is_detected; - - template - using constructor_t = decltype(U(std::declval()...)); - using worker_cnt_t = WorkerCountType const&; - using has_constructor = detection::is_detected; - using has_default_constructor = detection::is_detected; - - template - using spawnWorkers_t = decltype(std::declval().spawnWorkers()); - using has_spawnWorkers = detection::is_detected; - - template - using spawnWorkersBlock_t = decltype(std::declval().spawnWorkersBlock( - std::declval() - )); - using has_spawnWorkersBlock = detection::is_detected; - - template - using joinWorkers_t = decltype(std::declval().joinWorkers()); - using has_joinWorkers = detection::is_detected; - - template - using progress_t = decltype(std::declval().progress()); - using has_progress = detection::is_detected; - - using worker_id_t = WorkerIDType const&; - using work_unit_t = WorkUnitType const&; - using work_unit_cnt_t = WorkUnitCountType; - - template - using finished_t = decltype(std::declval().finished( - std::declval(), - std::declval() - )); - using has_finished = detection::is_detected; - - template - using enqueueAnyWorker_t = decltype(std::declval().enqueueAnyWorker( - std::declval()) - ); - using has_enqueueAnyWorker = detection::is_detected; - - template - using enqueueForWorker_t = decltype(std::declval().enqueueForWorker( - std::declval(), - std::declval() - )); - using has_enqueueForWorker = detection::is_detected; - - template - using enqueueAllWorkers_t = decltype(std::declval().enqueueAllWorkers( - std::declval() - )); - using has_enqueueAllWorkers = detection::is_detected; - - template - using enqueueCommThread_t = decltype(std::declval().enqueueCommThread( - std::declval()) - ); - using has_enqueueCommThread = detection::is_detected; - - template - using commScheduler_t = decltype(std::declval().commScheduler()); - using has_commScheduler = detection::is_detected_convertible< - bool, commScheduler_t, T - >; - - // This defines what it means to be an `Worker' - static constexpr auto const is_worker = - // default constructor and copy constructor - has_constructor::value and has_default_constructor::value and - // using WorkerType - has_WorkerType::value and - // methods: spawnWorkers, spawnWorkersBlock, joinWorkers, enqueueAnyWorker, - // enqueueForWorker, enqueueAllWorkers, enqueueCommThread - has_spawnWorkers::value and has_spawnWorkersBlock::value and - has_joinWorkers::value and has_enqueueAnyWorker::value and - has_enqueueForWorker::value and has_enqueueAllWorkers::value and - has_progress::value and has_finished::value and has_commScheduler::value and - has_enqueueCommThread::value; -}; - -}} /* end namespace vt::worker */ - -#endif /*INCLUDED_VT_WORKER_WORKER_GROUP_TRAITS_H*/ diff --git a/src/vt/worker/worker_headers.h b/src/vt/worker/worker_headers.h deleted file mode 100644 index 40278dd69e..0000000000 --- a/src/vt/worker/worker_headers.h +++ /dev/null @@ -1,87 +0,0 @@ -/* -//@HEADER -// ***************************************************************************** -// -// worker_headers.h -// DARMA/vt => Virtual Transport -// -// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC -// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. -// Government retains certain rights in this software. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Questions? Contact darma@sandia.gov -// -// ***************************************************************************** -//@HEADER -*/ - -#if !defined INCLUDED_VT_WORKER_WORKER_HEADERS_H -#define INCLUDED_VT_WORKER_WORKER_HEADERS_H - -#if vt_threading_enabled - -#include "vt/worker/worker.h" -#include "vt/worker/worker_group.h" -#include "vt/worker/worker_types.h" - -#if vt_check_enabled(openmp) - #include "vt/worker/worker_group_omp.h" -#else - #include "vt/worker/worker_group.h" -#endif - -namespace vt { namespace worker { - -#if vt_check_enabled(openmp) - using WorkerGroupType = WorkerGroupOMP; -#elif vt_check_enabled(stdthread) - using WorkerGroupType = WorkerGroupSTD; -#elif vt_check_enabled(fcontext) - using WorkerGroupType = WorkerGroupSeq; -#endif - -#if vt_check_enabled(openmp) - using WorkerType = OMPWorker; -#elif vt_check_enabled(stdthread) - using WorkerType = StdThreadWorker; -#elif vt_check_enabled(fcontext) - using WorkerType = WorkerSeq; -#endif - -}} /* end namespace vt::worker */ - -namespace vt { - -extern worker::WorkerGroupType* theWorkerGrp(); - -} /* end namespace vt */ - -#endif /* vt_threading_enabled */ - -#endif /*INCLUDED_VT_WORKER_WORKER_HEADERS_H*/ diff --git a/src/vt/worker/worker_openmp.cc b/src/vt/worker/worker_openmp.cc deleted file mode 100644 index c8e7a42492..0000000000 --- a/src/vt/worker/worker_openmp.cc +++ /dev/null @@ -1,128 +0,0 @@ -/* -//@HEADER -// ***************************************************************************** -// -// worker_openmp.cc -// DARMA/vt => Virtual Transport -// -// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC -// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. -// Government retains certain rights in this software. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Questions? Contact darma@sandia.gov -// -// ***************************************************************************** -//@HEADER -*/ - -#include "vt/config.h" - -#if vt_check_enabled(openmp) - -#include "vt/context/context.h" -#include "vt/worker/worker_common.h" -#include "vt/worker/worker_openmp.h" - -#include -#include - -#include - -#define DEBUG_OMP_WORKER_SCHEDULER 0 - -namespace vt { namespace worker { - -OMPWorker::OMPWorker( - WorkerIDType const& in_worker_id_, WorkerIDType const& in_num_thds, - WorkerFinishedFnType finished_fn -) : worker_id_(in_worker_id_), finished_fn_(finished_fn) -{ } - -void OMPWorker::enqueue(WorkUnitType const& work_unit) { - work_queue_.pushBack(work_unit); -} - -void OMPWorker::progress() { - // Noop -} - -void OMPWorker::scheduler() { - bool should_term_local = false; - do { - if (work_queue_.size() > 0) { - #if DEBUG_OMP_WORKER_SCHEDULER - vt_debug_print( - normal, worker, - "OMPWorker: scheduler: size={}\n", work_queue_.size() - ); - #endif - - auto elm = work_queue_.popGetBack(); - elm(); - finished_fn_(worker_id_, 1); - } - - #pragma omp atomic read - should_term_local = should_terminate_; - } while (not should_term_local); -} - -void OMPWorker::sendTerminateSignal() { - #pragma omp atomic write - should_terminate_ = true; - - vt_debug_print(normal, worker, "OMPWorker: sendTerminateSignal\n"); -} - -void OMPWorker::spawn() { - vt_debug_print( - normal, worker, - "OMPWorker: spawn: spawning worker: id={}\n", worker_id_ - ); - - scheduler(); -} - -void OMPWorker::join() { - vt_debug_print( - normal, worker, - "OMPWorker: join: spawning worker: id={}\n", worker_id_ - ); - - // tell the worker to return from the scheduler loop - sendTerminateSignal(); -} - -void OMPWorker::dispatch(WorkerFunType fun) { - enqueue(fun); -} - -}} /* end namespace vt::worker */ - -#endif /*vt_check_enabled(openmp)*/ diff --git a/src/vt/worker/worker_seq.cc b/src/vt/worker/worker_seq.cc deleted file mode 100644 index 2c3e3905da..0000000000 --- a/src/vt/worker/worker_seq.cc +++ /dev/null @@ -1,162 +0,0 @@ -/* -//@HEADER -// ***************************************************************************** -// -// worker_seq.cc -// DARMA/vt => Virtual Transport -// -// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC -// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. -// Government retains certain rights in this software. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Questions? Contact darma@sandia.gov -// -// ***************************************************************************** -//@HEADER -*/ - -#include "vt/config.h" - -#if vt_check_enabled(fcontext) - -#include "vt/context/context.h" -#include "vt/context/context_attorney.h" -#include "vt/collective/collective_ops.h" -#include "vt/worker/worker_common.h" -#include "vt/worker/worker_seq.h" -#include "vt/utils/bits/bits_common.h" - -#include -#include - -#define WORKER_SEQ_VERBOSE 0 - -namespace vt { namespace worker { - -WorkerSeq::WorkerSeq( - WorkerIDType const& in_worker_id_, WorkerCountType const& in_num_thds, - WorkerFinishedFnType finished_fn -) : worker_id_(in_worker_id_), num_thds_(in_num_thds), finished_fn_(finished_fn), - stack(create_fcontext_stack()) -{ } - -void WorkerSeq::enqueue(WorkUnitType const& work_unit) { - work_queue_.pushBack(work_unit); -} - -void WorkerSeq::progress() { - #if WORKER_SEQ_VERBOSE - vt_debug_print(normal, worker, "WorkerSeq: progress: id={}\n", worker_id_); - #endif - - auto new_live = jump_fcontext(live.ctx); - live = new_live; -} - -/*static*/ void WorkerSeq::workerSeqSched(fcontext_transfer_t t) { - using ::vt::ctx::ContextAttorney; - - void* data = t.data; - WorkerSeq* seq = reinterpret_cast(data); - fcontext_transfer_t cur = t; - - #if WORKER_SEQ_VERBOSE - vt_debug_print(normal, worker, "workerSeqSched: id={}\n", seq->worker_id_); - #endif - - while (!seq->should_terminate_) { - ContextAttorney::setWorker(seq->worker_id_); - - if (seq->work_queue_.size() > 0) { - auto elm = seq->work_queue_.popGetBack(); - elm(); - seq->finished_fn_(seq->worker_id_, 1); - } - - #if WORKER_SEQ_VERBOSE - vt_debug_print(normal, worker, "seq sched: id={} jump out\n", seq->worker_id_); - #endif - - fcontext_transfer_t new_ctx = jump_fcontext(cur.ctx, nullptr); - cur = new_ctx; - - #if WORKER_SEQ_VERBOSE - vt_debug_print(normal, worker, "seq sched: id={} jump in\n", seq->worker_id_); - #endif - } - - vt_debug_print(normal, worker, "seq sched: id={} term\n", seq->worker_id_); - jump_fcontext(cur.ctx, nullptr); -} - -void WorkerSeq::startScheduler() { - vt_debug_print(normal, worker, "WorkerSeq: startScheduler: id={}\n", worker_id_); - - using ::vt::ctx::ContextAttorney; - - // Set the thread-local worker in the Context - ContextAttorney::setWorker(worker_id_); - - fctx = make_fcontext_stack(stack, workerSeqSched); - - #if WORKER_SEQ_VERBOSE - vt_debug_print(normal, worker, "WorkerSeq: jump context: id={}\n", worker_id_); - #endif - - live = jump_fcontext(fctx, this); - - #if WORKER_SEQ_VERBOSE - vt_debug_print(normal, worker, "WorkerSeq: jump context out: id={}\n", worker_id_); - #endif -} - -void WorkerSeq::sendTerminateSignal() { - should_terminate_ = true; -} - -void WorkerSeq::spawn() { - vt_debug_print(normal, worker, "WorkerSeq: spawn: id={}\n", worker_id_); - startScheduler(); -} - -void WorkerSeq::join() { - vt_debug_print(normal, worker, "WorkerSeq: join: id={}\n", worker_id_); - // tell the worker to return from the scheduler loop - sendTerminateSignal(); - progress(); -} - -void WorkerSeq::dispatch(WorkerFunType fun) { - enqueue(fun); -} - -}} /* end namespace vt::worker */ - -#endif /*backend_no_threading*/ - diff --git a/src/vt/worker/worker_seq.h b/src/vt/worker/worker_seq.h deleted file mode 100644 index 4b5fdab25b..0000000000 --- a/src/vt/worker/worker_seq.h +++ /dev/null @@ -1,110 +0,0 @@ -/* -//@HEADER -// ***************************************************************************** -// -// worker_seq.h -// DARMA/vt => Virtual Transport -// -// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC -// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. -// Government retains certain rights in this software. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Questions? Contact darma@sandia.gov -// -// ***************************************************************************** -//@HEADER -*/ - -#if !defined INCLUDED_VT_WORKER_WORKER_SEQ_H -#define INCLUDED_VT_WORKER_WORKER_SEQ_H - -#include "vt/config.h" - -#if vt_check_enabled(fcontext) - -#include "vt/worker/worker_common.h" -#include "vt/worker/worker_types.h" -#include "vt/utils/container/concurrent_deque.h" - -#include - -#include - -namespace vt { namespace worker { - -struct WorkerSeq { - using WorkerFunType = std::function; - using WorkUnitContainerType = util::container::ConcurrentDeque; - - WorkerSeq( - WorkerIDType const& in_worker_id_, WorkerCountType const& in_num_thds, - WorkerFinishedFnType finished_fn - ); - WorkerSeq(WorkerSeq const&) = delete; - - void spawn(); - void join(); - void dispatch(WorkerFunType fun); - void enqueue(WorkUnitType const& work_unit); - void sendTerminateSignal(); - void progress(); - -private: - void startScheduler(); - void continueScheduler(); - - static void workerSeqSched(fcontext_transfer_t t); - -private: - bool should_terminate_ = false; - WorkerIDType worker_id_ = no_worker_id; - WorkerCountType num_thds_ = no_workers; - WorkUnitContainerType work_queue_; - WorkerFinishedFnType finished_fn_ = nullptr; - fcontext_stack_t stack; - fcontext_t fctx; - fcontext_transfer_t live; -}; - -}} /* end namespace vt::worker */ - -#include "vt/worker/worker_traits.h" - -namespace vt { namespace worker { - -static_assert( - WorkerTraits::is_worker, - "vt::worker::Worker must follow the Worker concept" -); - -}} /* end namespace vt::worker */ - -#endif /*backend_no_threading*/ - -#endif /*INCLUDED_VT_WORKER_WORKER_SEQ_H*/ diff --git a/src/vt/worker/worker_stdthread.cc b/src/vt/worker/worker_stdthread.cc deleted file mode 100644 index f590e5cf2f..0000000000 --- a/src/vt/worker/worker_stdthread.cc +++ /dev/null @@ -1,126 +0,0 @@ -/* -//@HEADER -// ***************************************************************************** -// -// worker_stdthread.cc -// DARMA/vt => Virtual Transport -// -// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC -// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. -// Government retains certain rights in this software. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Questions? Contact darma@sandia.gov -// -// ***************************************************************************** -//@HEADER -*/ - -#include "vt/config.h" - -#if vt_check_enabled(stdthread) - -#include "vt/context/context.h" -#include "vt/context/context_attorney.h" -#include "vt/collective/collective.h" -#include "vt/worker/worker_common.h" -#include "vt/worker/worker_stdthread.h" - -#include -#include -#include - -namespace vt { namespace worker { - -StdThreadWorker::StdThreadWorker( - WorkerIDType const& in_worker_id_, WorkerCountType const&, - WorkerFinishedFnType finished_fn -) : worker_id_(in_worker_id_), finished_fn_(finished_fn) -{ } - -void StdThreadWorker::enqueue(WorkUnitType const& work_unit) { - work_queue_.pushBack(work_unit); -} - -void StdThreadWorker::progress() { - // Noop -} - -void StdThreadWorker::scheduler() { - using ::vt::ctx::ContextAttorney; - - // For now, all workers to have direct access to the runtime - // TODO: this needs to change - CollectiveOps::setCurrentRuntimeTLS(); - - // Set the thread-local worker in the Context - ContextAttorney::setWorker(worker_id_comm_thread); - - while (not should_terminate_.load()) { - if (work_queue_.size() > 0) { - auto elm = work_queue_.popGetBack(); - elm(); - finished_fn_(worker_id_, 1); - } - } -} - -void StdThreadWorker::sendTerminateSignal() { - should_terminate_.store(true); -} - -void StdThreadWorker::spawn() { - vt_debug_print( - normal, worker, - "StdThreadWorker: spawn: spawning worker: id={}\n", worker_id_ - ); - - auto sched_fn = std::bind(&StdThreadWorker::scheduler, this); - thd_ = std::make_unique(sched_fn); -} - -void StdThreadWorker::join() { - vt_debug_print( - normal, worker, - "StdThreadWorker: join: spawning worker: id={}\n", worker_id_ - ); - - // tell the worker to return from the scheduler loop - sendTerminateSignal(); - - // join the std::thread - thd_->join(); -} - -void StdThreadWorker::dispatch(WorkerFunType fun) { - enqueue(fun); -} - -}} /* end namespace vt::worker */ - -#endif /*vt_check_enabled(stdthread)*/ diff --git a/src/vt/worker/worker_stdthread.h b/src/vt/worker/worker_stdthread.h deleted file mode 100644 index 33a54b5e3b..0000000000 --- a/src/vt/worker/worker_stdthread.h +++ /dev/null @@ -1,116 +0,0 @@ -/* -//@HEADER -// ***************************************************************************** -// -// worker_stdthread.h -// DARMA/vt => Virtual Transport -// -// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC -// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. -// Government retains certain rights in this software. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Questions? Contact darma@sandia.gov -// -// ***************************************************************************** -//@HEADER -*/ - -#if !defined INCLUDED_VT_WORKER_WORKER_STDTHREAD_H -#define INCLUDED_VT_WORKER_WORKER_STDTHREAD_H - -#include "vt/config.h" - -#if vt_check_enabled(stdthread) - -#include "vt/worker/worker_common.h" -#include "vt/worker/worker_types.h" -#include "vt/utils/container/concurrent_deque.h" - -#include -#include -#include -#include - -namespace vt { namespace worker { - -struct StdThreadWorker { - using WorkerFunType = std::function; - using ThreadType = std::thread; - using ThreadPtrType = std::unique_ptr; - using WorkUnitContainerType = util::container::ConcurrentDeque; - - StdThreadWorker( - WorkerIDType const& in_worker_id_, WorkerCountType const&, - WorkerFinishedFnType finished_fn - ); - StdThreadWorker(StdThreadWorker const&) = delete; - - void spawn(); - void join(); - void dispatch(WorkerFunType fun); - void enqueue(WorkUnitType const& work_unit); - void sendTerminateSignal(); - void progress(); - - template - void serialize(Serializer& s) { - s | should_terminate_ - | worker_id_ - | work_queue_ - | thd_ - | finished_fn_; - } - -private: - void scheduler(); - -private: - std::atomic should_terminate_ = {false}; - WorkerIDType worker_id_ = no_worker_id; - WorkUnitContainerType work_queue_; - ThreadPtrType thd_ = nullptr; - WorkerFinishedFnType finished_fn_ = nullptr; -}; - -}} /* end namespace vt::worker */ - -#include "vt/worker/worker_traits.h" - -namespace vt { namespace worker { - -static_assert( - WorkerTraits::is_worker, - "vt::worker::Worker must follow the Worker concept" -); - -}} /* end namespace vt::worker */ - -#endif /*vt_check_enabled(stdthread)*/ - -#endif /*INCLUDED_VT_WORKER_WORKER_STDTHREAD_H*/ diff --git a/src/vt/worker/worker_traits.h b/src/vt/worker/worker_traits.h deleted file mode 100644 index 2fd93c541a..0000000000 --- a/src/vt/worker/worker_traits.h +++ /dev/null @@ -1,112 +0,0 @@ -/* -//@HEADER -// ***************************************************************************** -// -// worker_traits.h -// DARMA/vt => Virtual Transport -// -// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC -// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. -// Government retains certain rights in this software. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Questions? Contact darma@sandia.gov -// -// ***************************************************************************** -//@HEADER -*/ - -#if !defined INCLUDED_VT_WORKER_WORKER_TRAITS_H -#define INCLUDED_VT_WORKER_WORKER_TRAITS_H - -#include "vt/config.h" -#include "vt/worker/worker_common.h" -#include "vt/worker/worker_types.h" - -#include "detector_headers.h" - -namespace vt { namespace worker { - -template -struct WorkerTraits { - template - using WorkerFunType_t = typename U::WorkerFunType; - using has_WorkerFunType = detection::is_detected; - - template - using constructor_t = decltype(U(std::declval()...)); - using worker_id_t = WorkerIDType const&; - using worker_count_t = WorkerCountType const&; - using worker_finished_fn_t = WorkerFinishedFnType; - using has_constructor = detection::is_detected< - constructor_t, T, worker_id_t, worker_count_t, worker_finished_fn_t - >; - - template - using progress_t = decltype(std::declval().progress()); - using has_progress = detection::is_detected; - - template - using copy_constructor_t = decltype(U(std::declval())); - using has_copy_constructor = detection::is_detected; - - template - using spawn_t = decltype(std::declval().spawn()); - using has_spawn = detection::is_detected; - - template - using join_t = decltype(std::declval().join()); - using has_join = detection::is_detected; - - template - using dispatch_t = decltype(std::declval().dispatch( - std::declval()) - ); - using has_dispatch = detection::is_detected; - - template - using enqueue_t = decltype(std::declval().enqueue( - std::declval()) - ); - using has_enqueue = detection::is_detected; - - // This defines what it means to be an `Worker' - static constexpr auto const is_worker = - // default constructor and copy constructor - has_constructor::value and not has_copy_constructor::value and - // using WorkerFunType - has_WorkerFunType::value and - // methods: spawn(), join(), dispatch(WorkerFunType), enqueue(WorkUnitType), - // progress() - has_spawn::value and has_join::value and has_progress::value and - has_dispatch::value and has_enqueue::value; -}; - -}} /* end namespace vt::worker */ - -#endif /*INCLUDED_VT_WORKER_WORKER_TRAITS_H*/ diff --git a/src/vt/worker/worker_types.h b/src/vt/worker/worker_types.h deleted file mode 100644 index ff2a9cdab0..0000000000 --- a/src/vt/worker/worker_types.h +++ /dev/null @@ -1,57 +0,0 @@ -/* -//@HEADER -// ***************************************************************************** -// -// worker_types.h -// DARMA/vt => Virtual Transport -// -// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC -// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. -// Government retains certain rights in this software. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Questions? Contact darma@sandia.gov -// -// ***************************************************************************** -//@HEADER -*/ - -#if !defined INCLUDED_VT_WORKER_WORKER_TYPES_H -#define INCLUDED_VT_WORKER_WORKER_TYPES_H - -#include "vt/config.h" - -#include - -namespace vt { namespace worker { - -using WorkUnitType = std::function; - -}} /* end namespace vt::worker */ - -#endif /*INCLUDED_VT_WORKER_WORKER_TYPES_H*/ diff --git a/tests/perf/collection_local_send.cc b/tests/perf/collection_local_send.cc index 4dcf1ea66b..41d1df31da 100644 --- a/tests/perf/collection_local_send.cc +++ b/tests/perf/collection_local_send.cc @@ -94,7 +94,7 @@ struct NodeObj { void perfRunBenchmark() { for (int i = 0; i < num_iters; i++) { auto m = makeMessage(); - col_proxy[0].template sendMsg(m); + col_proxy[0].template sendMsg<&TestCol::han>(m); vt::theSched()->runSchedulerOnceImpl(); } } @@ -114,10 +114,10 @@ VT_PERF_TEST(MyTest, test_collection_local_send) { "test_collection_local_send", this ); - grp_proxy[my_node_].invoke(); + grp_proxy[my_node_].invoke<&NodeObj::initialize>(); if (theContext()->getNode() == 0) { - grp_proxy[my_node_].send(); + grp_proxy[my_node_].send<&NodeObj::perfMakeRunnable>(); } } diff --git a/tests/perf/collection_local_send_prealloc.cc b/tests/perf/collection_local_send_prealloc.cc index ea5ce19df7..32337253f8 100644 --- a/tests/perf/collection_local_send_prealloc.cc +++ b/tests/perf/collection_local_send_prealloc.cc @@ -98,7 +98,7 @@ struct NodeObj { void perfRunBenchmark() { for (int i = 0; i < num_iters; i++) { auto m = msgs[i]; - col_proxy[0].template sendMsg(m); + col_proxy[0].template sendMsg<&TestCol::han>(m); vt::theSched()->runSchedulerOnceImpl(); } } @@ -118,7 +118,7 @@ VT_PERF_TEST(MyTest, test_collection_local_send_preallocate) { "test_collection_local_send_preallocate", this ); - grp_proxy[my_node_].invoke(); + grp_proxy[my_node_].invoke<&NodeObj::initialize>(); if (theContext()->getNode() == 0) { grp_proxy[my_node_].send(); diff --git a/tests/perf/comm_cost_curve.cc b/tests/perf/comm_cost_curve.cc index d7cca1e673..c5366e4478 100644 --- a/tests/perf/comm_cost_curve.cc +++ b/tests/perf/comm_cost_curve.cc @@ -78,7 +78,7 @@ static void handler(PingMsg*) { count++; if (count == pings) { auto msg = vt::makeMessage(1); - vt::theMsg()->sendMsg(0, msg); + vt::theMsg()->sendMsg(0, msg); count = 0; } } @@ -88,7 +88,7 @@ void sender() { auto start = vt::timing::getCurrentTime(); for (int i = 0; i < pings; i++) { auto msg = vt::makeMessage(bytes); - vt::theMsg()->sendMsg(1, msg); + vt::theMsg()->sendMsg(1, msg); } vt::theSched()->runSchedulerWhile([]{return !is_done; }); diff --git a/tests/perf/common/test_harness.cc b/tests/perf/common/test_harness.cc index d38cb427d1..7fd028c779 100644 --- a/tests/perf/common/test_harness.cc +++ b/tests/perf/common/test_harness.cc @@ -178,7 +178,7 @@ void OutputToFile(std::string const& name, std::string const& content) { void PerfTestHarness::SetUp() { auto custom_argv = custom_args_.data(); auto custom_argc = static_cast(custom_args_.size()); - CollectiveOps::initialize(custom_argc, custom_argv, no_workers, true); + CollectiveOps::initialize(custom_argc, custom_argv, true); my_node_ = theContext()->getNode(); num_nodes_ = theContext()->getNumNodes(); } diff --git a/tests/perf/make_runnable_micro.cc b/tests/perf/make_runnable_micro.cc index c69434207f..9991d630e9 100644 --- a/tests/perf/make_runnable_micro.cc +++ b/tests/perf/make_runnable_micro.cc @@ -109,7 +109,7 @@ VT_PERF_TEST(MyTest, test_make_runnable_micro) { "test_make_runnable_micro", this ); - grp_proxy[my_node_].invoke(); + grp_proxy[my_node_].invoke<&NodeObj::initialize>(); if (theContext()->getNode() == 0) { grp_proxy[my_node_].send(); diff --git a/tests/perf/objgroup_local_send.cc b/tests/perf/objgroup_local_send.cc index 3debf9bab3..5cf25ac728 100644 --- a/tests/perf/objgroup_local_send.cc +++ b/tests/perf/objgroup_local_send.cc @@ -112,7 +112,7 @@ VT_PERF_TEST(MyTest, test_objgroup_local_send) { "test_objgroup_local_send", this ); - grp_proxy[my_node_].invoke(); + grp_proxy[my_node_].invoke<&NodeObj::initialize>(); if (theContext()->getNode() == 0) { grp_proxy[my_node_].send(); diff --git a/tests/perf/ping_pong.cc b/tests/perf/ping_pong.cc index 28194d1c92..8a2730b3b2 100644 --- a/tests/perf/ping_pong.cc +++ b/tests/perf/ping_pong.cc @@ -146,8 +146,7 @@ VT_PERF_TEST(MyTest, test_ping_pong) { auto grp_proxy = vt::theObjGroup()->makeCollective( "test_ping_pong", this ); - grp_proxy[my_node_] - .invoke(); + grp_proxy[my_node_].invoke<&NodeObj::initialize>(); if (theContext()->getNode() == 0) { theTerm()->disableTD(); diff --git a/tests/perf/ping_pong_am.cc b/tests/perf/ping_pong_am.cc index eef0b3f911..cecb2445ab 100644 --- a/tests/perf/ping_pong_am.cc +++ b/tests/perf/ping_pong_am.cc @@ -66,7 +66,7 @@ void handlerFinished(MyMsg* msg); void handler(MyMsg* in_msg) { auto msg = makeMessage(); - theMsg()->sendMsg(0, msg); + theMsg()->sendMsg<&handlerFinished>(0, msg); } struct NodeObj { @@ -88,7 +88,7 @@ struct NodeObj { void perfPingPong(MyMsg* in_msg) { test_obj_->StartTimer(fmt::format("{} ping-pong", i)); auto msg = makeMessage(); - theMsg()->sendMsg(1, msg); + theMsg()->sendMsg<&handler>(1, msg); } private: @@ -100,11 +100,11 @@ struct NodeObj { void handlerFinished(MyMsg* msg) { if (i >= num_iters) { - global_proxy[0].invoke(); + global_proxy[0].invoke<&NodeObj::complete>(); } else { i++; auto msg = makeMessage(); - theMsg()->sendMsg(1, msg); + theMsg()->sendMsg<&handler>(1, msg); } } @@ -117,7 +117,7 @@ VT_PERF_TEST(MyTest, test_ping_pong_am) { theTerm()->disableTD(); } - grp_proxy[my_node_].invoke(); + grp_proxy[my_node_].invoke<&NodeObj::initialize>(); if (theContext()->getNode() == 0) { grp_proxy[my_node_].send(); diff --git a/tests/perf/reduce.cc b/tests/perf/reduce.cc index bba65f31db..a551063035 100644 --- a/tests/perf/reduce.cc +++ b/tests/perf/reduce.cc @@ -99,7 +99,7 @@ VT_PERF_TEST(MyTest, test_reduce) { theTerm()->disableTD(); } - grp_proxy[my_node_].invoke(); + grp_proxy[my_node_].invoke<&NodeObj::initialize>(); using MsgType = typename NodeObj::MyMsg; grp_proxy[my_node_].send(); diff --git a/tests/unit/active/test_active_bcast_put.cc b/tests/unit/active/test_active_bcast_put.cc index 78a6ba4e21..046eb1f0cf 100644 --- a/tests/unit/active/test_active_bcast_put.cc +++ b/tests/unit/active/test_active_bcast_put.cc @@ -127,7 +127,7 @@ TEST_P(TestActiveBroadcastPut, test_type_safe_active_fn_bcast2) { for (int i = 0; i < num_msg_sent; i++) { auto msg = makeMessage(); msg->setPut(put_payload.data(), put_size * sizeof(int)); - theMsg()->broadcastMsg(msg); + theMsg()->broadcastMsg(msg); } } }); diff --git a/tests/unit/active/test_active_broadcast.cc b/tests/unit/active/test_active_broadcast.cc index 8eeeecc7ab..274ba5846a 100644 --- a/tests/unit/active/test_active_broadcast.cc +++ b/tests/unit/active/test_active_broadcast.cc @@ -104,7 +104,7 @@ TEST_P(TestActiveBroadcast, test_type_safe_active_fn_bcast2) { auto msg = makeMessage(); auto msg_hold = promoteMsg(msg.get()); - theMsg()->broadcastMsg(msg); + theMsg()->broadcastMsg(msg); EXPECT_TRUE(envelopeIsLocked(msg_hold->env)) << "Should be locked on send"; } } diff --git a/tests/unit/active/test_active_send.cc b/tests/unit/active/test_active_send.cc index f996b6b33f..8313daf0fe 100644 --- a/tests/unit/active/test_active_send.cc +++ b/tests/unit/active/test_active_send.cc @@ -163,7 +163,7 @@ TEST_F(TestActiveSend, test_type_safe_active_fn_send) { auto msg = makeMessage(); auto msg_hold = promoteMsg(msg.get()); - theMsg()->sendMsg(to_node, msg); + theMsg()->sendMsg(to_node, msg); EXPECT_TRUE(envelopeIsLocked(msg_hold->env)) << "Should be locked on send"; } } @@ -194,7 +194,7 @@ TEST_F(TestActiveSend, test_type_safe_active_fn_send_small_put) { #if DEBUG_TEST_HARNESS_PRINT fmt::print("{}: sendMsg: (put) i={}\n", my_node, i); #endif - theMsg()->sendMsg(to_node, msg); + theMsg()->sendMsg(to_node, msg); } } @@ -219,7 +219,7 @@ TEST_F(TestActiveSend, test_type_safe_active_fn_send_large_put) { #if DEBUG_TEST_HARNESS_PRINT fmt::print("{}: sendMsg: (put) i={}\n", my_node, i); #endif - theMsg()->sendMsg(to_node, msg); + theMsg()->sendMsg(to_node, msg); } } @@ -235,7 +235,7 @@ TEST_F(TestActiveSend, test_active_message_serialization) { auto msg = vt::makeMessage(); msg->data.resize(serialization::serialized_msg_eager_size); - theMsg()->sendMsg(this_node, msg); + theMsg()->sendMsg(this_node, msg); } }); diff --git a/tests/unit/active/test_active_send_large.cc b/tests/unit/active/test_active_send_large.cc index 16a70822b8..7833fd87a5 100644 --- a/tests/unit/active/test_active_send_large.cc +++ b/tests/unit/active/test_active_send_large.cc @@ -140,7 +140,7 @@ TYPED_TEST_P(TestActiveSendLarge, test_large_bytes_msg) { auto msg = makeMessage(); fillMsg(msg); msg->cb_ = cb; - theMsg()->sendMsg>(next_node, msg); + theMsg()->sendMsg>(next_node, msg); }); EXPECT_EQ(counter, 1); diff --git a/tests/unit/active/test_active_send_put.cc b/tests/unit/active/test_active_send_put.cc index 8cf89320f7..ba2c52551f 100644 --- a/tests/unit/active/test_active_send_put.cc +++ b/tests/unit/active/test_active_send_put.cc @@ -113,7 +113,7 @@ TEST_P(TestActiveSendPut, test_active_fn_send_put_param) { #if DEBUG_TEST_HARNESS_PRINT fmt::print("{}: sendMsg: (put) i={}\n", my_node, i); #endif - theMsg()->sendMsg(1, msg); + theMsg()->sendMsg(1, msg); } // Spin here so test_vec does not go out of scope before the send completes diff --git a/tests/unit/active/test_async_op_hip.cc b/tests/unit/active/test_async_op_hip.cc new file mode 100644 index 0000000000..b71eea58d3 --- /dev/null +++ b/tests/unit/active/test_async_op_hip.cc @@ -0,0 +1,211 @@ +/* +//@HEADER +// ***************************************************************************** +// +// test_async_op_hip.cc +// DARMA/vt => Virtual Transport +// +// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC +// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. +// Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from this +// software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact darma@sandia.gov +// +// ***************************************************************************** +//@HEADER +*/ + +#include "test_parallel_harness.h" + +#include +#include + +#include + + +namespace vt { namespace tests { namespace unit { + +#if __HIPCC__ + +using TestAsyncOp = TestParallelHarness; + +using MyMsg = Message; + + +inline void checkHipErrors( + hipError_t err, std::string const& additionalInfo, + bool skipOnFailure = false +) { + auto errorMsg = fmt::format( + "{} failed with error -> {}\n", additionalInfo, hipGetErrorString(err)); + + if (hipSuccess != err and skipOnFailure) { + GTEST_SKIP() << errorMsg; + } + + vtAbortIf(hipSuccess != err, errorMsg); +} + +__global__ void kernel(double* dst, double setVal) { + int row = blockIdx.y * blockDim.y + threadIdx.y; + int col = blockIdx.x * blockDim.x + threadIdx.x; + int tID = row * blockDim.y + col; + + dst[tID] = setVal; +} + +struct hipGroup { + hipGroup() { + auto const nBytes = dataSize_ * sizeof(double); + + // If first malloc fails, there's probably something wrong with HIP env + // so call GTEST_SKIP instead of failing the test + checkHipErrors( + hipMalloc((void**)&dataDevicePointer1_, nBytes), + "hipMalloc(dataDevicePointer1_)", true + ); + + checkHipErrors( + hipHostMalloc((void**)&dataHostPointer1_, nBytes), + "hipHostMalloc(dataHostPointer1_)" + ); + + checkHipErrors( + hipMalloc((void**)&dataDevicePointer2_, nBytes), + "hipMalloc(dataDevicePointer2_)" + ); + + checkHipErrors( + hipHostMalloc((void**)&dataHostPointer2_, nBytes), + "hipHostMalloc(dataHostPointer2_)" + ); + } + + ~hipGroup() { + checkHipErrors( + hipFree(dataDevicePointer1_), "hipFree(dataDevicePointer1_)" + ); + checkHipErrors( + hipFree(dataDevicePointer2_), "hipFree(dataDevicePointer1_)" + ); + + checkHipErrors( + hipHostFree(dataHostPointer1_), "hipHostFree(dataHostPointer1_)" + ); + checkHipErrors( + hipHostFree(dataHostPointer2_), "hipHostFree(dataHostPointer2_)" + ); + + checkHipErrors(hipStreamDestroy(stream1_), "hipStreamDestroy(stream1_)"); + checkHipErrors(hipStreamDestroy(stream2_), "hipStreamDestroy(stream2_)"); + } + + void hipHandler(MyMsg* msg) { + auto const nBytes = dataSize_ * sizeof(double); + + checkHipErrors(hipStreamCreate(&stream1_), "hipStreamCreate (stream1_)"); + kernel<<<1, dataSize_, 0, stream1_>>>(dataDevicePointer1_, 4.0); + checkHipErrors( + hipMemcpyAsync( + dataHostPointer1_, dataDevicePointer1_, nBytes, hipMemcpyDeviceToHost, + stream1_ + ), + "hipMemcpyAsync (stream1_)" + ); + + auto op1 = std::make_unique(stream1_); + + checkHipErrors(hipStreamCreate(&stream2_), "hipStreamCreate (stream2_)"); + kernel<<<1, dataSize_, 0, stream2_>>>(dataDevicePointer2_, 8.0); + checkHipErrors( + hipMemcpyAsync( + dataHostPointer2_, dataDevicePointer2_, nBytes, hipMemcpyDeviceToHost, + stream2_ + ), + "hipMemcpyAsync (stream2_)" + ); + + auto op2 = std::make_unique( + stream2_, [this] { done_ = true; } + ); + + // Register these async operations for polling; since these operations are + // enclosed in an epoch, they should inhibit the current epoch from + // terminating before they are done. + theMsg()->registerAsyncOp(std::move(op1)); + theMsg()->registerAsyncOp(std::move(op2)); + } + + void check() { + for (size_t i = 0; i < dataSize_; ++i) { + EXPECT_DOUBLE_EQ(dataHostPointer1_[i], 4.0); + EXPECT_DOUBLE_EQ(dataHostPointer2_[i], 8.0); + } + + EXPECT_TRUE(done_); + } + +private: + hipStream_t stream1_; + hipStream_t stream2_; + + double* dataDevicePointer1_; + double* dataHostPointer1_; + + double* dataDevicePointer2_; + double* dataHostPointer2_; + + bool done_ = false; + + size_t const dataSize_ = 32; +}; + +TEST_F(TestAsyncOp, test_async_op_hip) { + int driverVer; + if ( + (hipDriverGetVersion(&driverVer) == hipErrorInvalidValue) or + (driverVer == 0)) { + GTEST_SKIP() + << "Trying to run test_async_op_hip but HIP driver is not present!\n"; + } + + auto const this_node = theContext()->getNode(); + auto p = theObjGroup()->makeCollective("test_async_op_hip"); + auto ep = theTerm()->makeEpochRooted(term::UseDS{true}); + + // When this returns all the hip streams should be done + runInEpoch(ep, [p, this_node] { + p[this_node].send(); + }); + + p[this_node].get()->check(); +} +#endif // __HIPCC__ + +}}} // end namespace vt::tests::unit diff --git a/tests/unit/active/test_async_op_threads.cc b/tests/unit/active/test_async_op_threads.cc index a09a7aa6eb..0faf97c982 100644 --- a/tests/unit/active/test_async_op_threads.cc +++ b/tests/unit/active/test_async_op_threads.cc @@ -96,7 +96,7 @@ struct MyCol : vt::Collection { done_ = true; // stack should be the size before running this method since we haven't // resumed the thread yet! - EXPECT_EQ(theTerm()->getEpochStack().size(), size_stack_before_running_handler); + EXPECT_EQ(theTerm()->getEpochStack().size(), stack_size_before_running_handler); } ); @@ -161,7 +161,7 @@ struct MyCol : vt::Collection { ); auto p = getCollectionProxy(); - p[this_node].invoke(std::move(op1),std::move(op2)); + p[this_node].invoke<&MyCol::handlerToInvoke>(std::move(op1),std::move(op2)); } void handlerToInvoke( @@ -198,7 +198,7 @@ struct MyCol : vt::Collection { TEST_F(TestAsyncOpThreads, test_async_op_threads_1) { auto const this_node = theContext()->getNode(); - stack_size_before_running_handler = theTerm()->size_getEpochStack().size(); + stack_size_before_running_handler = theTerm()->getEpochStack().size(); vt::Index1D range(static_cast(theContext()->getNumNodes())); auto p = vt::makeCollection("test_async_op_threads_invoke") diff --git a/tests/unit/active/test_pending_send.cc b/tests/unit/active/test_pending_send.cc index ccb55513cc..9f320ddd5c 100644 --- a/tests/unit/active/test_pending_send.cc +++ b/tests/unit/active/test_pending_send.cc @@ -65,7 +65,7 @@ struct TestPendingSend : TestParallelHarness { auto const num_nodes = theContext()->getNumNodes(); auto prev = this_node - 1 >= 0 ? this_node - 1 : num_nodes - 1; auto msg = vt::makeMessage(); - theMsg()->sendMsg(prev, msg); + theMsg()->sendMsg(prev, msg); } static void handlerLocal(TestMsg* msg) { auto const this_node = theContext()->getNode(); @@ -93,7 +93,7 @@ TEST_F(TestPendingSend, test_pending_send_hold) { auto msg = vt::makeMessage(); auto msg_hold = promoteMsg(msg.get()); pending.emplace_back( - theMsg()->sendMsg(next, msg) + theMsg()->sendMsg(next, msg) ); // Must be stamped with the current epoch @@ -134,7 +134,7 @@ TEST_F(TestPendingSend, test_pending_broadcast_hold) { auto msg = vt::makeMessage(theContext()->getNode()); auto msg_hold = promoteMsg(msg.get()); - pending.emplace_back(theMsg()->broadcastMsg(msg)); + pending.emplace_back(theMsg()->broadcastMsg(msg)); // Must be stamped with the current epoch EXPECT_EQ(envelopeGetEpoch(msg_hold->env), ep); diff --git a/tests/unit/atomic/test_atomic.cc b/tests/unit/atomic/test_atomic.cc deleted file mode 100644 index c683c75047..0000000000 --- a/tests/unit/atomic/test_atomic.cc +++ /dev/null @@ -1,198 +0,0 @@ -/* -//@HEADER -// ***************************************************************************** -// -// test_atomic.cc -// DARMA/vt => Virtual Transport -// -// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC -// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. -// Government retains certain rights in this software. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Questions? Contact darma@sandia.gov -// -// ***************************************************************************** -//@HEADER -*/ - -#include - -#include "test_harness.h" -#include "test_parallel_harness.h" -#include "vt/utils/atomic/atomic.h" -#include "vt/utils/mutex/mutex.h" - -#if vt_check_enabled(openmp) - #include -#else - #include -#endif - -namespace vt { namespace tests { namespace unit { - -using namespace vt::tests::unit; - -using ::vt::util::atomic::AtomicType; - -struct TestAtomic : TestHarness { }; - -static constexpr int const num_vals = 128; -static constexpr int const init_val = 29; - -TEST_F(TestAtomic, basic_atomic_init_single_thd) { - AtomicType test1 = {init_val}; - EXPECT_EQ(test1.load(), init_val); -} - -TEST_F(TestAtomic, basic_atomic_load_single_thd) { - AtomicType test1 = {init_val}; - EXPECT_EQ(test1.load(), init_val); - auto val = test1.load(); - EXPECT_EQ(val, init_val); -} - -TEST_F(TestAtomic, basic_atomic_store_single_thd) { - AtomicType test1 = {init_val}; - EXPECT_EQ(test1.load(), init_val); - auto const store_val = init_val + 10; - test1.store(store_val); - auto val = test1.load(); - EXPECT_EQ(val, store_val); -} - -TEST_F(TestAtomic, basic_atomic_fetch_add_single_thd) { - AtomicType test1 = {0}; - for (int i = 0; i < num_vals; i++) { - auto val = test1.fetch_add(1); - EXPECT_EQ(val, i); - } -} - -TEST_F(TestAtomic, basic_atomic_fetch_sub_single_thd) { - AtomicType test1 = {0}; - for (int i = 0; i < num_vals; i++) { - auto val = test1.fetch_sub(1); - EXPECT_EQ(val, -i); - } -} - -using ::vt::util::mutex::MutexType; - -static constexpr WorkerCountType const num_workers = 8; -static MutexType test_mutex = {}; -static AtomicType atomic_test_val = {0}; -static AtomicType atomic_num = {0}; -static std::vector count(num_workers); - -#if vt_check_enabled(openmp) or vt_check_enabled(stdthread) -static void testAtomicMulti() { - auto val = atomic_test_val.fetch_add(1); - //fmt::print("val={}\n", val); - EXPECT_LE(val, num_workers); - test_mutex.lock(); - bool const cur_count_value = count[val]; - count[val] = true; - EXPECT_EQ(cur_count_value, false); - test_mutex.unlock(); - if (val == num_workers - 1) { - auto val2 = atomic_num.fetch_add(1); - EXPECT_EQ(val2, 0); - } -} -#endif /* vt_check_enabled(openmp) or vt_check_enabled(stdthread) */ - -static AtomicType atomic_test_cas = {0}; -static AtomicType atomic_test_slot = {0}; - -#if vt_check_enabled(openmp) or vt_check_enabled(stdthread) -static void testAtomicMultiCAS() { - int expected = atomic_test_slot.fetch_add(1); - int desired = expected + 1; - - //fmt::print("begin: expected={}, desired={}\n", expected, desired); - - bool result = false; - do { - result = atomic_test_cas.compare_exchange_strong(expected, desired); - } while (!result); - - //fmt::print("finished: expected={}, desired={}\n", expected, desired); -} -#endif /* vt_check_enabled(openmp) or vt_check_enabled(stdthread) */ - -TEST_F(TestAtomic, basic_atomic_fetch_add_multi_thd) { - count.resize(num_workers); - - #if vt_check_enabled(openmp) - #pragma omp parallel num_threads(num_workers) - testAtomicMulti(); - #elif vt_check_enabled(stdthread) - std::vector thds; - for (auto i = 0; i < num_workers; i++) { - thds.emplace_back(std::thread(testAtomicMulti)); - } - for (auto i = 0; i < num_workers; i++) { - thds[i].join(); - } - #endif - - #if !backend_no_threading - test_mutex.lock(); - for (auto&& elm : count) { - EXPECT_EQ(elm, true); - } - EXPECT_EQ(atomic_num.load(), 1); - EXPECT_EQ(atomic_test_val.load(), num_workers); - test_mutex.unlock(); - #endif -} - -TEST_F(TestAtomic, basic_atomic_cas_multi_thd) { - count.resize(num_workers); - - #if vt_check_enabled(openmp) - #pragma omp parallel num_threads(num_workers) - testAtomicMultiCAS(); - #elif vt_check_enabled(stdthread) - std::vector thds; - for (auto i = 0; i < num_workers; i++) { - thds.emplace_back(std::thread(testAtomicMultiCAS)); - } - for (auto i = 0; i < num_workers; i++) { - thds[i].join(); - } - #endif - - #if !backend_no_threading - EXPECT_EQ(atomic_test_slot.load(), num_workers); - EXPECT_EQ(atomic_test_cas.load(), num_workers); - #endif -} - -}}} // end namespace vt::tests::unit diff --git a/tests/unit/collection/test_broadcast.h b/tests/unit/collection/test_broadcast.h index c8f4c3fd4a..e2fccb8f67 100644 --- a/tests/unit/collection/test_broadcast.h +++ b/tests/unit/collection/test_broadcast.h @@ -98,7 +98,7 @@ template < typename TupleT = typename MessageT::TupleType > struct BroadcastHandlers { - static void handler(MessageT* msg, CollectionT* col) { + static void handler(CollectionT* col, MessageT* msg) { return execute(col,msg->tup); } template @@ -131,14 +131,13 @@ void test_broadcast_1(std::string const& label) { auto proxy = theCollection()->construct(range, label); proxy.template broadcast< - MsgType, BroadcastHandlers::handler >(args); auto msg = makeMessage(args); - theCollection()->broadcastMsg< - MsgType,BroadcastHandlers::handler - >(proxy, msg.get()); + proxy.template broadcastMsg< + BroadcastHandlers::handler + >(msg); } } diff --git a/tests/unit/collection/test_collection_construct_common.h b/tests/unit/collection/test_collection_construct_common.h index c597a0409c..f239434bad 100644 --- a/tests/unit/collection/test_collection_construct_common.h +++ b/tests/unit/collection/test_collection_construct_common.h @@ -71,7 +71,7 @@ struct ConstructHandlers { typename CollectionT, typename MessageT = typename CollectionT::MsgType > - static void handler(MessageT* msg, CollectionT* col) { + static void handler(CollectionT* col, MessageT* msg) { // fmt::print( // "{}: constructed TestCol: idx.x()={}\n", // theContext()->getNode(), col->getInex().x(), print_ptr(col) diff --git a/tests/unit/collection/test_collection_group.extended.cc b/tests/unit/collection/test_collection_group.extended.cc index 752aeb8f18..0d08a1e2c9 100644 --- a/tests/unit/collection/test_collection_group.extended.cc +++ b/tests/unit/collection/test_collection_group.extended.cc @@ -62,7 +62,6 @@ struct MyReduceMsg : collective::ReduceTMsg { }; struct ColA : Collection { - struct TestMsg : CollectionMessage { }; struct TestDataMsg : CollectionMessage { TestDataMsg(int32_t value) : value_(value) {} @@ -75,7 +74,7 @@ struct ColA : Collection { finished = true; } - void doReduce(TestMsg* msg) { + void doReduce() { auto const proxy = getCollectionProxy(); auto cb = theCB()->makeBcast(proxy); auto reduce_msg = makeMessage(getIndex().x()); @@ -99,8 +98,7 @@ struct ColA : Collection { bool reduce_test = false; }; -void colHandler( - ColA::TestDataMsg* msg, typename ColA::TestDataMsg::CollectionType* type) { +void colHandler(typename ColA::TestDataMsg::CollectionType* type, ColA::TestDataMsg*) { --elem_counter; } @@ -121,7 +119,7 @@ TEST_F(TestCollectionGroup, test_collection_group_1) { auto const proxy = theCollection()->construct( range, "test_collection_group_1" ); - proxy.broadcast(); + proxy.broadcast<&ColA::doReduce>(); } } diff --git a/tests/unit/collection/test_destroy.cc b/tests/unit/collection/test_destroy.cc index fae3de8273..cc8a8d00f8 100644 --- a/tests/unit/collection/test_destroy.cc +++ b/tests/unit/collection/test_destroy.cc @@ -69,7 +69,7 @@ struct DestroyTest : Collection { num_destroyed++; } - static void work(WorkMsg* msg, DestroyTest* col); + static void work(DestroyTest* col); }; struct WorkMsg : CollectionMessage {}; @@ -88,7 +88,7 @@ struct FinishedWork { } }; -/*static*/ void DestroyTest::work(WorkMsg* msg, DestroyTest* col) { +/*static*/ void DestroyTest::work(DestroyTest* col) { auto proxy = col->getCollectionProxy(); // ::fmt::print("work idx={}, proxy={:x}\n", col->getIndex(), proxy.getProxy()); auto reduce_msg = makeMessage(proxy); @@ -117,7 +117,7 @@ TEST_F(TestDestroy, test_destroy_1) { ); // ::fmt::print("broadcasting proxy={:x}\n", proxy.getProxy()); - proxy.broadcast(); + proxy.broadcast(); } }); // ::fmt::print("num destroyed={}\n", num_destroyed); diff --git a/tests/unit/collection/test_invoke.cc b/tests/unit/collection/test_invoke.cc index b4f6014cb1..76f9a50a30 100644 --- a/tests/unit/collection/test_invoke.cc +++ b/tests/unit/collection/test_invoke.cc @@ -104,10 +104,9 @@ TEST_F(TestCollectionInvoke, test_collection_invoke_1) { // Non-message function { auto const accumulate_result = - proxy[dest_elem] - .invoke( - dest_elem, std::vector{2, 4, 5} - ); + proxy[dest_elem].invoke<&TestCol::accumulateVec>( + dest_elem, std::vector{2, 4, 5} + ); EXPECT_EQ(accumulate_result, 11); EXPECT_EQ(handler_invoked, true); diff --git a/tests/unit/collection/test_lb.extended.cc b/tests/unit/collection/test_lb.extended.cc index 1f50cf8c09..bb92395840 100644 --- a/tests/unit/collection/test_lb.extended.cc +++ b/tests/unit/collection/test_lb.extended.cc @@ -83,10 +83,8 @@ struct MyCol : vt::Collection { double val = 0.0; }; -using MyMsg = vt::CollectionMessage; - // A dummy kernel that does some work depending on the index -void colHandler(MyMsg*, MyCol* col) { +void colHandler(MyCol* col) { for (int i = 0; i < 10; i++) { for (int j = 0; j < col->getIndex().x() * 20; j++) { col->val += (i*29+j*2)-4; @@ -134,7 +132,7 @@ void runTest(std::string const& lb_name, std::string const& label) { for (int phase = 0; phase < num_phases; phase++) { // Do some work. runInEpochCollective([&]{ - proxy.broadcastCollective(); + proxy.broadcastCollective(); }); // Go to the next phase. @@ -342,7 +340,7 @@ TEST_P(TestLBSpecFile, test_node_lb_data_dumping_with_spec_file) { for (int phase = 0; phase < num_phases; phase++) { // Do some work runInEpochCollective([&] { - proxy.broadcastCollective(); + proxy.broadcastCollective(); }); // Go to the next phase @@ -407,7 +405,7 @@ TEST_P(TestNodeLBDataDumper, test_node_lb_data_dumping_with_interval) { for (int phase = 0; phase < num_phases; phase++) { // Do some work runInEpochCollective([&] { - proxy.broadcastCollective(); + proxy.broadcastCollective(); }); // Go to the next phase @@ -501,8 +499,10 @@ getLBDataForPhase( using vt::vrt::collection::balance::LBDataHolder; using json = nlohmann::json; std::stringstream ss{std::ios_base::out | std::ios_base::in}; + nlohmann::json metadata; + metadata["type"] = "LBDatafile"; auto ap = std::make_unique( - "phases", "LBDatafile", std::move(ss), false + "phases", metadata, std::move(ss), false ); auto j = in.toJson(phase); ap->addElm(*j); @@ -691,8 +691,10 @@ getJsonStringForPhase( using vt::vrt::collection::balance::LBDataHolder; using JSONAppender = vt::util::json::Appender; std::stringstream ss{std::ios_base::out | std::ios_base::in}; + nlohmann::json metadata; + metadata["type"] = "LBDatafile"; auto ap = std::make_unique( - "phases", "LBDatafile", std::move(ss), false + "phases", metadata, std::move(ss), false ); auto j = in.toJson(phase); ap->addElm(*j); @@ -792,9 +794,7 @@ struct SerializationTestCol : vt::Collection int unpacked_on_node = -1; }; -using SerializationTestMsg = vt::CollectionMessage; - -void serializationColHandler(SerializationTestMsg *, SerializationTestCol *col) { +void serializationColHandler(SerializationTestCol *col) { auto const cur_phase = thePhase()->getCurrentPhase(); if (cur_phase < 2) { return; @@ -824,7 +824,7 @@ void runSerializationTest() { for (int phase = 0; phase < num_phases; ++phase) { runInEpochCollective([&] { - proxy.broadcastCollective(); + proxy.broadcastCollective(); }); thePhase()->nextPhaseCollective(); } diff --git a/tests/unit/collection/test_lb_data_retention.cc b/tests/unit/collection/test_lb_data_retention.cc index ec090748a1..c02bd745c4 100644 --- a/tests/unit/collection/test_lb_data_retention.cc +++ b/tests/unit/collection/test_lb_data_retention.cc @@ -57,15 +57,12 @@ namespace vt { namespace tests { namespace unit { -template -struct MyMsg : vt::CollectionMessage { }; - struct TestCol : vt::Collection { unsigned int prev_calls_ = 0; unsigned int prevCalls() { return prev_calls_++; } - static void colHandler(MyMsg* msg, TestCol* col) { + static void colHandler(TestCol* col) { auto& lb_data = col->lb_data_; auto load_phase_count = lb_data.getLoadPhaseCount(); @@ -148,7 +145,7 @@ TEST_F(TestLBDataRetention, test_lbdata_retention_last1) { for (int i=0; i, TestCol::colHandler>(); + proxy.broadcastCollective(); }); // Go to the next phase. vt::thePhase()->nextPhaseCollective(); @@ -182,7 +179,7 @@ TEST_F(TestLBDataRetention, test_lbdata_retention_last2) { for (int i=0; i, TestCol::colHandler>(); + proxy.broadcastCollective(); }); // Go to the next phase. vt::thePhase()->nextPhaseCollective(); @@ -216,7 +213,7 @@ TEST_F(TestLBDataRetention, test_lbdata_retention_last4) { for (int i=0; i, TestCol::colHandler>(); + proxy.broadcastCollective(); }); // Go to the next phase. vt::thePhase()->nextPhaseCollective(); diff --git a/tests/unit/collection/test_lb_lite.extended.cc b/tests/unit/collection/test_lb_lite.extended.cc index 18708043c9..6fdad450cc 100644 --- a/tests/unit/collection/test_lb_lite.extended.cc +++ b/tests/unit/collection/test_lb_lite.extended.cc @@ -87,7 +87,7 @@ struct LBTest : Collection { s | val1 | val2 | val3 | data_2; } - static void iterWork(IterMsg* msg, LBTest* col); + static void iterWork(LBTest* col, IterMsg* msg); public: double data_2 = 1.0; @@ -103,7 +103,7 @@ using ColProxyType = CollectionIndexProxy; static double weight = 1.0f; static int32_t num_iter = 8; -/*static*/ void LBTest::iterWork(IterMsg* msg, LBTest* col) { +/*static*/ void LBTest::iterWork(LBTest* col, IterMsg* msg) { double val = 0.1f; double val4 = 0.4f; auto const idx = col->getIndex().x(); diff --git a/tests/unit/collection/test_list_insert.cc b/tests/unit/collection/test_list_insert.cc index 47d78cdef5..7dd0504940 100644 --- a/tests/unit/collection/test_list_insert.cc +++ b/tests/unit/collection/test_list_insert.cc @@ -248,13 +248,13 @@ TEST_F(TestListInsert, test_bounded_list_insert_here_3) { num_work = 0; auto const num_nodes = theContext()->getNumNodes(); - + auto const this_node = theContext()->getNode(); auto const range = Index1D(num_nodes * num_elms_per_node); std::vector>> elms; for (int i = 0; i < range.x(); i++) { - if (i % num_nodes == 0) { + if (i % num_nodes == this_node) { Index1D ix{i}; elms.emplace_back( std::make_tuple(ix, std::make_unique()) @@ -282,11 +282,12 @@ TEST_F(TestListInsert, test_bounded_list_insert_here_no_default_constructor) { num_work = 0; auto const num_nodes = theContext()->getNumNodes(); + auto const this_node = theContext()->getNode(); auto const range = Index1D(num_nodes * num_elms_per_node); std::vector>> elms; for (int i = 0; i < range.x(); i++) { - if (i % num_nodes == 0) { + if (i % num_nodes == this_node) { Index1D ix{i}; elms.emplace_back( std::make_tuple(ix, std::make_unique(0)) @@ -314,13 +315,13 @@ TEST_F(TestListInsert, test_unbounded_list_insert_here_4) { num_work = 0; auto const num_nodes = theContext()->getNumNodes(); - + auto const this_node = theContext()->getNode(); auto const range = Index1D(num_nodes * num_elms_per_node); std::vector>> elms; for (int i = 0; i < range.x(); i++) { - if (i % num_nodes == 0) { + if (i % num_nodes == this_node) { Index1D ix{i}; elms.emplace_back( std::make_tuple(ix, std::make_unique()) @@ -348,11 +349,12 @@ TEST_F(TestListInsert, test_unbounded_list_insert_here_no_default_constructor) { num_work = 0; auto const num_nodes = theContext()->getNumNodes(); + auto const this_node = theContext()->getNode(); auto const range = Index1D(num_nodes * num_elms_per_node); std::vector>> elms; for (int i = 0; i < range.x(); i++) { - if (i % num_nodes == 0) { + if (i % num_nodes == this_node) { Index1D ix{i}; elms.emplace_back( std::make_tuple(ix, std::make_unique(0)) @@ -375,6 +377,51 @@ TEST_F(TestListInsert, test_unbounded_list_insert_here_no_default_constructor) { EXPECT_EQ(num_work, num_elms_per_node * num_nodes); } +TEST_F(TestListInsert, test_unbounded_list_insert_here_no_default_constructor_empty_rank) { + num_inserted = 0; + num_work = 0; + + auto const num_nodes = theContext()->getNumNodes(); + auto const this_node = theContext()->getNode(); + auto const range = Index1D((num_nodes - 1) * num_elms_per_node); + + std::vector>> elms; + for (int i = 0; i < range.x(); i++) { + if (i % (num_nodes - 1) == this_node) { + Index1D ix{i}; + elms.emplace_back( + std::make_tuple(ix, std::make_unique(0)) + ); + } + } + + auto proxy = vt::makeCollection( + "test_unbounded_list_insert_here_no_default_constructor_empty_rank" + ) + .collective(true) + .listInsertHere(std::move(elms)) + .template mapperObjGroupConstruct>() + .wait(); + + if (this_node < num_nodes - 1) { + EXPECT_EQ(num_inserted, num_elms_per_node); + } else { + EXPECT_EQ(num_inserted, 0); + } + num_inserted = 0; + + runInEpochCollective([&]{ + proxy.broadcast(); + }); + if (this_node < num_nodes - 1) { + // all ranks broadcast to all other ranks + EXPECT_EQ(num_work, num_elms_per_node * num_nodes); + } else { + // but there is nothing on the final rank to do work + EXPECT_EQ(num_work, 0); + } +} + TEST_F(TestListInsert, test_bounded_bulk_insert_no_default_constructor) { num_inserted = 0; num_work = 0; @@ -404,6 +451,7 @@ TEST_F(TestListInsert, test_bounded_mix_list_insert_no_default_constructor) { num_work = 0; auto const num_nodes = theContext()->getNumNodes(); + auto const this_node = theContext()->getNode(); auto const range = Index1D(num_nodes * num_elms_per_node); std::vector list_insert; @@ -413,7 +461,7 @@ TEST_F(TestListInsert, test_bounded_mix_list_insert_no_default_constructor) { std::vector>> elms; for (int i = range.x() / 2; i < range.x(); i++) { - if (i % num_nodes == 0) { + if (i % num_nodes == this_node) { Index1D ix{i}; elms.emplace_back( std::make_tuple(ix, std::make_unique(0)) diff --git a/tests/unit/collection/test_mapping.cc b/tests/unit/collection/test_mapping.cc index b5a5907364..eeff58ccc1 100644 --- a/tests/unit/collection/test_mapping.cc +++ b/tests/unit/collection/test_mapping.cc @@ -79,13 +79,10 @@ struct MyMapper : vt::mapping::BaseMapper { } }; -template -struct WorkMsg : CollectionMessage> {}; - static int32_t num_work = 0; template -void work(WorkMsg* msg, MappingTest* elm) { +void work(MappingTest* elm) { fmt::print( "node={}: num_work={}, idx={}\n", theContext()->getNode(), num_work, elm->getIndex() @@ -192,7 +189,7 @@ TYPED_TEST_P(TestMapping, test_custom_mapping_1) { .wait(); vt::runInEpochCollective([&]{ - proxy.template broadcastCollective, work>(); + proxy.template broadcastCollective>(); }); EXPECT_EQ(counter, num_work); @@ -204,7 +201,7 @@ TYPED_TEST_P(TestMapping, test_custom_mapping_1) { .wait(); vt::runInEpochCollective([&]{ - proxy2.template broadcastCollective, work>(); + proxy2.template broadcastCollective>(); }); EXPECT_EQ(counter, num_work); diff --git a/tests/unit/collection/test_model_per_collection.extended.cc b/tests/unit/collection/test_model_per_collection.extended.cc index 7f7d8841b7..2c539f0b53 100644 --- a/tests/unit/collection/test_model_per_collection.extended.cc +++ b/tests/unit/collection/test_model_per_collection.extended.cc @@ -82,13 +82,10 @@ struct ConstantTestModel : ComposedModel { VirtualProxyType proxy_ = 0; }; -template -struct MyMsg : vt::CollectionMessage { }; - std::unordered_map id_proxy_map; template -void colHandler(MyMsg*, ColT* col) { +void colHandler(ColT* col) { // do nothing, except setting up our map using the temp ID, which will hit // every node id_proxy_map[col->getElmID()] = col->getProxy(); @@ -141,8 +138,8 @@ TEST_F(TestModelPerCollection, test_model_per_collection_1) { // Do some work. runInEpochCollective([&]{ - proxy1.broadcastCollective, colHandler>(); - proxy2.broadcastCollective, colHandler>(); + proxy1.broadcastCollective>(); + proxy2.broadcastCollective>(); }); // Add a hook for after LB runs, but before instrumentation is cleared diff --git a/src/vt/utils/mutex/omp_mutex.h b/tests/unit/collection/test_promote.cc similarity index 63% rename from src/vt/utils/mutex/omp_mutex.h rename to tests/unit/collection/test_promote.cc index bbdb04ba45..95d9ba0156 100644 --- a/src/vt/utils/mutex/omp_mutex.h +++ b/tests/unit/collection/test_promote.cc @@ -2,7 +2,7 @@ //@HEADER // ***************************************************************************** // -// omp_mutex.h +// test_promote.cc // DARMA/vt => Virtual Transport // // Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC @@ -41,55 +41,51 @@ //@HEADER */ -#if !defined INCLUDED_VT_UTILS_MUTEX_OMP_MUTEX_H -#define INCLUDED_VT_UTILS_MUTEX_OMP_MUTEX_H +#include "test_parallel_harness.h" -#include "vt/config.h" +#include "vt/vrt/collection/manager.h" -#if vt_check_enabled(openmp) +#include -#include +namespace vt { namespace tests { namespace unit { namespace invoke { -#include +struct TestMsg : vt::Message { + using MessageParentType = ::vt::Message; + vt_msg_serialize_required(); // for string -namespace vt { namespace util { namespace mutex { + TestMsg() = default; + explicit TestMsg(std::string in_str) + : str(in_str) + { } -struct OMPMutex { - omp_lock_t omp_lock; - - OMPMutex(); - OMPMutex(OMPMutex const&) = delete; - - virtual ~OMPMutex(); - - void lock(); - void unlock(); - bool try_lock(); - - template < - typename SerializerT, - typename = std::enable_if_t< - std::is_same::value - > - > + template void serialize(SerializerT& s) { - s | omp_lock; + MessageParentType::serialize(s); + s | str; } -}; -}}} /* end namespace vt::util::mutex */ - -#include "vt/utils/mutex/mutex_traits.h" + std::string str; +}; -namespace vt { namespace util { namespace mutex { +struct Hello : vt::Collection { + void doWork(TestMsg* msg) { + EXPECT_EQ(msg->str, "hello there"); + } +}; -static_assert( - MutexTraits::is_mutex, - "OMPMutex must follow the mutex concept" -); +struct TestCollectionPromoteMsg : TestParallelHarness {}; -}}} // end namespace vt::util::mutex +TEST_F(TestCollectionPromoteMsg, test_collection_promote_1) { + auto const this_node = theContext()->getNode(); + auto const num_nodes = theContext()->getNumNodes(); + auto const num_elems = Index1D{static_cast(num_nodes*4)}; -#endif // vt_check_enabled(openmp) + auto proxy = theCollection()->constructCollective( + num_elems, "test_collection_promote_1" + ); + if (this_node == 0) { + proxy.broadcast("hello there"); + } +} -#endif /*INCLUDED_VT_UTILS_MUTEX_OMP_MUTEX_H*/ +}}}} // end namespace vt::tests::unit::invoke diff --git a/tests/unit/collection/test_reduce_collection.cc b/tests/unit/collection/test_reduce_collection.cc index 0588d8e030..231a0bd43e 100644 --- a/tests/unit/collection/test_reduce_collection.cc +++ b/tests/unit/collection/test_reduce_collection.cc @@ -60,16 +60,16 @@ TEST_P(TestReduceCollection, test_reduce_op) { auto proxy = theCollection()->construct(range, "test_reduce_op"); switch (reduce_case) { - case 0: proxy.broadcast(my_node); break; - case 1: proxy.broadcast(my_node); break; - case 2: proxy.broadcast(my_node); break; - case 3: proxy.broadcast(my_node); break; - case 4: proxy.broadcast(my_node); break; + case 0: proxy.broadcast(); break; + case 1: proxy.broadcast(); break; + case 2: proxy.broadcast(); break; + case 3: proxy.broadcast(); break; + case 4: proxy.broadcast(); break; #if ENABLE_REDUCE_EXPR_CALLBACK - case 5: proxy.broadcast(my_node); break; - case 6: proxy.broadcast(my_node); break; - case 7: proxy.broadcast(my_node); break; + case 5: proxy.broadcast(); break; + case 6: proxy.broadcast(); break; + case 7: proxy.broadcast(); break; #endif default: vtAbort("Failure: should not be reached"); } diff --git a/tests/unit/collection/test_reduce_collection_handler.h b/tests/unit/collection/test_reduce_collection_handler.h index e43da68286..b5acedcded 100644 --- a/tests/unit/collection/test_reduce_collection_handler.h +++ b/tests/unit/collection/test_reduce_collection_handler.h @@ -51,7 +51,7 @@ namespace vt { namespace tests { namespace unit { namespace reduce { -void colHanBasic(ColMsg* msg, MyCol* col) { +void colHanBasic(MyCol* col) { auto const& idx = col->getIndex(); vt_debug_print( @@ -71,7 +71,7 @@ void colHanBasic(ColMsg* msg, MyCol* col) { >(proxy, reduce_msg.get()); } -void colHanVec(ColMsg* msg, MyCol* col) { +void colHanVec(MyCol* col) { auto const& idx = col->getIndex(); vt_debug_print( normal, reduce, @@ -93,7 +93,7 @@ void colHanVec(ColMsg* msg, MyCol* col) { >(proxy, reduce_msg.get()); } -void colHanVecProxy(ColMsg* msg, MyCol* col) { +void colHanVecProxy(MyCol* col) { auto const& idx = col->getIndex(); vt_debug_print( normal, reduce, @@ -110,7 +110,7 @@ void colHanVecProxy(ColMsg* msg, MyCol* col) { proxy.reduce, CheckVec>(reduce_msg.get()); } -void colHanVecProxyCB(ColMsg* msg, MyCol* col) { +void colHanVecProxyCB(MyCol* col) { auto const& idx = col->getIndex(); vt_debug_print( normal, reduce, @@ -130,7 +130,7 @@ void colHanVecProxyCB(ColMsg* msg, MyCol* col) { proxy.reduce>(reduce_msg.get(),cb); } -void colHanNoneCB(ColMsg* msg, MyCol* col) { +void colHanNoneCB(MyCol* col) { auto const& idx = col->getIndex(); vt_debug_print( normal, reduce, @@ -148,7 +148,7 @@ void colHanNoneCB(ColMsg* msg, MyCol* col) { // Using reduceExpr with callback is broken and has fundamental flaws. // These tests are disabled for now. #if ENABLE_REDUCE_EXPR_CALLBACK -void colHanPartial(ColMsg* msg, MyCol* col) { +void colHanPartial(MyCol* col) { auto const& idx = col->getIndex(); vt_debug_print( @@ -172,7 +172,7 @@ void colHanPartial(ColMsg* msg, MyCol* col) { ); } -void colHanPartialMulti(ColMsg* msg, MyCol* col) { +void colHanPartialMulti(MyCol* col) { auto const& idx = col->getIndex(); auto const& grouping = idx.x() % index_tresh; @@ -204,7 +204,7 @@ void colHanPartialMulti(ColMsg* msg, MyCol* col) { ); } -void colHanPartialProxy(ColMsg* msg, MyCol* col) { +void colHanPartialProxy(MyCol* col) { auto const& idx = col->getIndex(); vt_debug_print( diff --git a/tests/unit/collection/test_reduce_collection_race.cc b/tests/unit/collection/test_reduce_collection_race.cc index 0043728681..37459a7bc6 100644 --- a/tests/unit/collection/test_reduce_collection_race.cc +++ b/tests/unit/collection/test_reduce_collection_race.cc @@ -49,7 +49,6 @@ namespace vt { namespace tests { namespace unit { namespace race { using TestReduceCollectionRace = TestParallelHarnessParam; struct MyCol : vt::Collection {}; -struct TestMsg : vt::CollectionMessage {}; using ReduceMsg = vt::collective::ReduceTMsg; static int multipler = 0; @@ -63,7 +62,7 @@ struct ReduceFunctor { } }; -static void handler(TestMsg*, MyCol* col) { +static void handler(MyCol* col) { auto proxy = col->getCollectionProxy(); auto msg = vt::makeMessage(static_cast(col->getIndex().x())); auto cb = vt::theCB()->makeSend(0); @@ -79,11 +78,11 @@ TEST_P(TestReduceCollectionRace, test_reduce_race_1) { range, "test_reduce_race_1" ); - proxy.broadcastCollective(); - proxy.broadcastCollective(); - proxy.broadcastCollective(); - proxy.broadcastCollective(); - proxy.broadcastCollective(); + proxy.broadcastCollective<&handler>(); + proxy.broadcastCollective<&handler>(); + proxy.broadcastCollective<&handler>(); + proxy.broadcastCollective<&handler>(); + proxy.broadcastCollective<&handler>(); } INSTANTIATE_TEST_SUITE_P( diff --git a/tests/unit/collection/test_send.h b/tests/unit/collection/test_send.h index 4d1551a3f1..d6b629e06c 100644 --- a/tests/unit/collection/test_send.h +++ b/tests/unit/collection/test_send.h @@ -135,7 +135,7 @@ template < typename TupleT = typename MessageT::TupleType > struct SendHandlers { - static void handler(MessageT* msg, CollectionT* col) { + static void handler(CollectionT* col, MessageT* msg) { return execute(col,msg->tup); } template @@ -158,7 +158,7 @@ template < > struct SendSzHandlers : SendHandlers { using BaseT = SendHandlers; - static void handler(MessageT* msg, CollectionT* col) { + static void handler(CollectionT* col, MessageT* msg) { // Verify payload size is correct EXPECT_EQ(msg->buff_size, sizeof(PayloadT)); auto smart_ptr = vt::MsgSharedPtr(msg); @@ -195,11 +195,7 @@ void test_collection_send_1(std::string const& label) { auto msg = makeMessage(args); EXPECT_EQ(msg.size(), sizeof(MsgType)); if (i % 2 == 0) { - proxy[i].template sendMsg::handler>(msg.get()); - } else { - theCollection()->sendMsg::handler>( - proxy[i], msg.get() - ); + proxy[i].template sendMsg::handler>(msg.get()); } } } @@ -222,7 +218,7 @@ void test_collection_send_sz_1() { EXPECT_EQ(msg.size(), sizeof(MsgType) + sizeof(PayloadType)); msg->buff_size = sizeof(PayloadType); std::memcpy(reinterpret_cast(msg->payload()), &args, msg->buff_size); - proxy[i].template sendMsg::handler>(msg); + proxy[i].template sendMsg::handler>(msg); } } } @@ -241,13 +237,7 @@ void test_collection_send_ptm_1(std::string const& label) { for (int i = 0; i < col_size; i++) { auto msg = makeMessage(args); //proxy[i].template send::handler>(msg); - if (i % 2 == 0) { - proxy[i].template sendMsg(msg.get()); - } else { - theCollection()->sendMsg( - proxy[i], msg.get() - ); - } + proxy[i].template sendMsg<&ColType::handler>(msg.get()); } } } diff --git a/tests/unit/collectives/test_collectives_reduce.cc b/tests/unit/collectives/test_collectives_reduce.cc index 910125e349..070c3e8695 100644 --- a/tests/unit/collectives/test_collectives_reduce.cc +++ b/tests/unit/collectives/test_collectives_reduce.cc @@ -58,7 +58,7 @@ TEST_F(TestReduce, test_reduce_op) { auto msg = makeMessage(my_node); vt_debug_print(normal, reduce, "msg->num={}\n", msg->num); - theCollective()->global()->reduce(root, msg.get()); + theCollective()->global()->reduce(root, msg.get()); } using ReduceMsg = vt::collective::ReduceTMsg; diff --git a/tests/unit/collectives/test_collectives_scatter.extended.cc b/tests/unit/collectives/test_collectives_scatter.extended.cc index 5d11dd6a1d..4350a7aa14 100644 --- a/tests/unit/collectives/test_collectives_scatter.extended.cc +++ b/tests/unit/collectives/test_collectives_scatter.extended.cc @@ -86,7 +86,7 @@ TEST_F(TestScatter, test_scatter_1) { if (this_node == 0) { auto const& elm_size = sizeof(int) * num_elms; auto const& total_size = elm_size * num_nodes; - theCollective()->scatter( + theCollective()->scatter( total_size,elm_size,nullptr,[](NodeType node, void* ptr){ auto ptr_out = reinterpret_cast(ptr); for (std::size_t i = 0; i < num_elms; i++) { diff --git a/tests/unit/collectives/test_mpi_collective.cc b/tests/unit/collectives/test_mpi_collective.cc index 6b6cdbcf42..f137195344 100644 --- a/tests/unit/collectives/test_mpi_collective.cc +++ b/tests/unit/collectives/test_mpi_collective.cc @@ -257,7 +257,7 @@ TEST_F(TestMPICollective, test_mpi_collective_4) { // Broadcast out node 0's order to confirm with all other nodes if (this_node == 0) { auto msg = makeMessage(run_order); - theMsg()->broadcastMsg(msg); + theMsg()->broadcastMsg(msg); } } diff --git a/tests/unit/group/test_group.cc b/tests/unit/group/test_group.cc index 17056a224e..d3c425ae03 100644 --- a/tests/unit/group/test_group.cc +++ b/tests/unit/group/test_group.cc @@ -88,7 +88,7 @@ TEST_F(TestGroup, test_group_range_construct_1) { fmt::print("Group is created: group={:x}\n", group); auto msg = makeMessage(); envelopeSetGroup(msg->env, group); - theMsg()->broadcastMsg(msg); + theMsg()->broadcastMsg(msg); } ); } @@ -118,7 +118,7 @@ TEST_F(TestGroup, test_group_range_construct_2) { fmt::print("Group is created: group={:x}\n", group); auto msg = makeMessage(); envelopeSetGroup(msg->env, group); - theMsg()->broadcastMsg(msg); + theMsg()->broadcastMsg(msg); } ); } @@ -146,7 +146,7 @@ TEST_F(TestGroup, test_group_collective_construct_1) { EXPECT_EQ(is_default_group, false); auto msg = makeMessage(); envelopeSetGroup(msg->env, group); - theMsg()->broadcastMsg(msg); + theMsg()->broadcastMsg(msg); } ); }); diff --git a/tests/unit/group/test_group.extended.cc b/tests/unit/group/test_group.extended.cc index d28897bb50..a222164da0 100644 --- a/tests/unit/group/test_group.extended.cc +++ b/tests/unit/group/test_group.extended.cc @@ -83,7 +83,7 @@ static inline void activeMessageGroupCollective() { if (my_node == 1) { auto msg = makeMessage(); envelopeSetGroup(msg->env, group_id); - theMsg()->broadcastMsg(msg); + theMsg()->broadcastMsg(msg); } } ); diff --git a/tests/unit/lb/test_lb_data_comm.cc b/tests/unit/lb/test_lb_data_comm.cc index 42c17f35e0..9fa555fadf 100644 --- a/tests/unit/lb/test_lb_data_comm.cc +++ b/tests/unit/lb/test_lb_data_comm.cc @@ -77,8 +77,10 @@ LBDataHolder getLBDataForPhase(vt::PhaseType phase) { using vt::vrt::collection::balance::LBDataHolder; using json = nlohmann::json; std::stringstream ss{std::ios_base::out | std::ios_base::in}; + nlohmann::json metadata; + metadata["type"] = "LBDatafile"; auto ap = std::make_unique( - "phases", "LBDatafile", std::move(ss), true + "phases", metadata, std::move(ss), true ); auto j = vt::theNodeLBData()->getLBData()->toJson(phase); ap->addElm(*j); @@ -150,7 +152,7 @@ struct ProxyMsg : vt::CollectionMessage { ProxyType obj_proxy; }; -void handler2(MyMsg* msg, MyCol* col) {} +void handler2(MyCol* col, MyMsg*) {} void MyObj::simulateObjGroupColTSends(ColProxyMsg* msg) { auto proxy = msg->proxy; @@ -162,7 +164,7 @@ void MyObj::simulateObjGroupColTSends(ColProxyMsg* msg) { auto node = vt::theCollection()->getMappedNode(proxy, idx); if (node == next) { for (int j = 0; j < num_sends; j++) { - proxy(idx).template send(); + proxy(idx).template send(); } } } @@ -178,16 +180,16 @@ void MyObj::simulateObjGroupObjGroupSends(ProxyMsg* msg) { } } -void simulateColTColTSends(MyMsg* msg, MyCol* col) { +void simulateColTColTSends(MyCol* col) { auto proxy = col->getCollectionProxy(); auto index = col->getIndex(); auto next = (index.x() + 1) % dim1; for (int i = 0; i < num_sends; i++) { - proxy(next).template send(); + proxy(next).template send(); } } -void simulateColTObjGroupSends(ProxyMsg* msg, MyCol* col) { +void simulateColTObjGroupSends(MyCol* col, ProxyMsg* msg) { auto obj_proxy = msg->obj_proxy; auto this_node = theContext()->getNode(); auto num_nodes = theContext()->getNumNodes(); @@ -199,13 +201,13 @@ void simulateColTObjGroupSends(ProxyMsg* msg, MyCol* col) { void bareDummyHandler(MyObjMsg* msg) {} -void simulateColTHandlerSends(MyMsg* msg, MyCol* col) { +void simulateColTHandlerSends(MyCol* col) { auto this_node = theContext()->getNode(); auto num_nodes = theContext()->getNumNodes(); auto next = (this_node + 1) % num_nodes; for (int i = 0; i < num_sends; i++) { auto msg2 = makeMessage(); - vt::theMsg()->sendMsg(next, msg2); + vt::theMsg()->sendMsg(next, msg2); } } @@ -215,7 +217,7 @@ void MyObj::simulateObjGroupHandlerSends(MyMsg* msg) { auto next = (this_node + 1) % num_nodes; for (int i = 0; i < num_sends; i++) { auto msg2 = makeMessage(); - vt::theMsg()->sendMsg(next, msg2); + vt::theMsg()->sendMsg(next, msg2); } } @@ -229,7 +231,7 @@ void simulateHandlerColTSends(ColProxyMsg* msg) { auto node = vt::theCollection()->getMappedNode(proxy, idx); if (node == next) { for (int j = 0; j < num_sends; j++) { - proxy(idx).template send(); + proxy(idx).template send(); } } } @@ -251,7 +253,7 @@ void simulateHandlerHandlerSends(MyMsg* msg) { auto next = (this_node + 1) % num_nodes; for (int i = 0; i < num_sends; i++) { auto msg2 = makeMessage(); - vt::theMsg()->sendMsg(next, msg2); + vt::theMsg()->sendMsg(next, msg2); } } @@ -263,7 +265,7 @@ auto idxToElmID = [](vt::Index1D i) -> vt::elm::ElementIDType { void recvElementIDs(ReduceMsg* msg) { all_elms = msg->getVal().elms; } -void doReduce(MyMsg*, MyCol* col) { +void doReduce(MyCol* col) { auto proxy = col->getCollectionProxy(); auto index = col->getIndex(); auto cb = theCB()->makeBcast(); @@ -282,7 +284,7 @@ TEST_F(TestLBDataComm, test_lb_data_comm_col_to_col_send) { vt::runInEpochCollective("simulateColTColTSends", [&]{ for (int i = 0; i < dim1; i++) { if (proxy(i).tryGetLocalPtr()) { - proxy(i).invoke(); + proxy(i).invoke(); } } }); @@ -292,7 +294,7 @@ TEST_F(TestLBDataComm, test_lb_data_comm_col_to_col_send) { vt::runInEpochCollective("doReduce", [&]{ for (int i = 0; i < dim1; i++) { if (proxy(i).tryGetLocalPtr()) { - proxy(i).invoke(); + proxy(i).invoke(); } } }); @@ -342,7 +344,7 @@ TEST_F(TestLBDataComm, test_lb_data_comm_col_to_objgroup_send) { vt::runInEpochCollective("simulateColTObjGroupSends", [&]{ for (int i = 0; i < dim1; i++) { if (proxy(i).tryGetLocalPtr()) { - proxy(i).invoke(obj_proxy); + proxy(i).invoke(obj_proxy); } } }); @@ -352,7 +354,7 @@ TEST_F(TestLBDataComm, test_lb_data_comm_col_to_objgroup_send) { vt::runInEpochCollective("doReduce", [&]{ for (int i = 0; i < dim1; i++) { if (proxy(i).tryGetLocalPtr()) { - proxy(i).invoke(); + proxy(i).invoke(); } } }); @@ -416,7 +418,7 @@ TEST_F(TestLBDataComm, test_lb_data_comm_objgroup_to_col_send) { vt::runInEpochCollective("doReduce", [&]{ for (int i = 0; i < dim1; i++) { if (proxy(i).tryGetLocalPtr()) { - proxy(i).invoke(); + proxy(i).invoke(); } } }); @@ -520,7 +522,7 @@ TEST_F(TestLBDataComm, test_lb_data_comm_handler_to_col_send) { auto num_nodes = theContext()->getNumNodes(); auto next = (this_node + 1) % num_nodes; auto msg = makeMessage(proxy); - theMsg()->sendMsg(next, msg); + theMsg()->sendMsg(next, msg); }); vt::thePhase()->nextPhaseCollective(); @@ -528,7 +530,7 @@ TEST_F(TestLBDataComm, test_lb_data_comm_handler_to_col_send) { vt::runInEpochCollective("doReduce", [&]{ for (int i = 0; i < dim1; i++) { if (proxy(i).tryGetLocalPtr()) { - proxy(i).invoke(); + proxy(i).invoke(); } } }); @@ -578,7 +580,7 @@ TEST_F(TestLBDataComm, test_lb_data_comm_col_to_handler_send) { vt::runInEpochCollective("simulateColTHandlerSends", [&]{ for (int i = 0; i < dim1; i++) { if (proxy(i).tryGetLocalPtr()) { - proxy(i).invoke(); + proxy(i).invoke(); } } }); @@ -588,7 +590,7 @@ TEST_F(TestLBDataComm, test_lb_data_comm_col_to_handler_send) { vt::runInEpochCollective("doReduce", [&]{ for (int i = 0; i < dim1; i++) { if (proxy(i).tryGetLocalPtr()) { - proxy(i).invoke(); + proxy(i).invoke(); } } }); @@ -683,7 +685,7 @@ TEST_F(TestLBDataComm, test_lb_data_comm_handler_to_objgroup_send) { auto num_nodes = theContext()->getNumNodes(); auto next = (this_node + 1) % num_nodes; auto msg = makeMessage(obj_proxy_a); - theMsg()->sendMsg(next, msg); + theMsg()->sendMsg(next, msg); }); vt::thePhase()->nextPhaseCollective(); @@ -724,7 +726,7 @@ TEST_F(TestLBDataComm, test_lb_data_comm_handler_to_handler_send) { auto num_nodes = theContext()->getNumNodes(); auto next = (this_node + 1) % num_nodes; auto msg = makeMessage(); - theMsg()->sendMsg(next, msg); + theMsg()->sendMsg(next, msg); }); vt::thePhase()->nextPhaseCollective(); diff --git a/tests/unit/lb/test_lb_data_reader.cc b/tests/unit/lb/test_lb_data_reader.cc deleted file mode 100644 index 72ad1dc36f..0000000000 --- a/tests/unit/lb/test_lb_data_reader.cc +++ /dev/null @@ -1,197 +0,0 @@ -/* -//@HEADER -// ***************************************************************************** -// -// test_lb_data_reader.cc -// DARMA/vt => Virtual Transport -// -// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC -// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. -// Government retains certain rights in this software. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Questions? Contact darma@sandia.gov -// -// ***************************************************************************** -//@HEADER -*/ - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "test_parallel_harness.h" -#include "data_message.h" - -namespace vt { namespace tests { namespace unit { - -struct TestLBDataReader : TestParallelHarness { }; -using ElementIDType = uint64_t; - -TEST_F(TestLBDataReader, test_lb_data_read_1) { - - // Iter 0 - // Node 0 -> [0, 1, 2, 3, 4] // local ID - // Node 1 -> [0, 1, 2, 3, 4] // local ID - // Node 2 -> [0, 1, 2, 3, 4] // local ID - - // Iter 1 (send most elements to the last node) - // Node 0 -> [0] // local ID - // Node 1 -> [0] // local ID - // Node 2 -> [0, 1, 2, 3, 4, {1,0}, {2, 0}, ...] - - // Iter 2 (send the elements back to their initial node) - // Node 0 -> [0, 1, 2, 3, 4] // local ID - // Node 1 -> [0, 1, 2, 3, 4] // local ID - // Node 2 -> [0, 1, 2, 3, 4] // local ID - - auto const& this_node = theContext()->getNode(); - auto const& num_nodes = theContext()->getNumNodes(); - - using vt::vrt::collection::balance::ElementIDStruct; - - const size_t numElements = 5; - std::vector myElemList(numElements); - - for (size_t ii = 0; ii < numElements; ++ii) { - myElemList[ii] = elm::ElmIDBits::createCollectionImpl( - true, ii+1, this_node, this_node - ); - } - - using JSONAppender = vt::util::json::Appender; - - std::stringstream stream{std::ios_base::out | std::ios_base::in}; - auto ap = std::make_unique( - "phases", "LBDatafile", std::move(stream), true - ); - - using vt::vrt::collection::balance::LBDataHolder; - auto lbdh = std::make_unique(); - - PhaseType phase = 0; - double tval = 0.0; - - //--- Iteration 0 - for (auto&& elmID : myElemList) { - //--- Use a dummy time value as it is not used. - lbdh->node_data_[phase][elmID].whole_phase_load = tval; - } - - //--- Iteration 1 - phase += 1; - if (this_node != num_nodes - 1) { - lbdh->node_data_[phase][myElemList[0]].whole_phase_load = tval; - } else { - for (auto&& elmID : myElemList) { - lbdh->node_data_[phase][elmID].whole_phase_load = tval; - } - for (NodeType in = 0; in+1 < num_nodes; ++in) { - for (uint64_t elmID = 1; elmID < numElements; ++elmID) { - auto permID = elm::ElmIDBits::createCollectionImpl( - true, elmID+1, in, in - ); - lbdh->node_data_[phase][permID].whole_phase_load = tval; - } - } - } - - //--- Iteration 2 - phase += 1; - for (auto&& elmID : myElemList) { - lbdh->node_data_[phase][elmID].whole_phase_load = tval; - } - - phase += 1; - - // Write the LB data - for (PhaseType p = 0; p < phase; p++) { - auto json = lbdh->toJson(p); - ap->addElm(*json); - } - - stream = ap->finish(); - - //--- Start the testing - auto ptr = vrt::collection::balance::LBDataRestartReader::construct(); - ptr->readLBDataFromStream(std::move(stream)); - - //--- Spin here so the test does not end before the communications complete - vt::theSched()->runSchedulerWhile([]{ return !rt->isTerminated(); }); - - //--- Check the read values - - auto const &migrationList = ptr->getMigrationList(); - auto const numIters = migrationList.size(); - - EXPECT_TRUE(numIters == phase - 1); - - //--- Iteration 0 -> 1 - size_t phaseID = 0; - auto myList = migrationList[phaseID]; - EXPECT_TRUE(myList.size() % 2 == 0); - if (myList.size() > 0) { - for (size_t ii = 1; ii < numElements; ++ii) { - auto myPermID = myElemList[ii]; - auto it = std::find(myList.begin(), myList.end(), myPermID.id); - EXPECT_TRUE(it != myList.end()); - size_t shift = static_cast(it - myList.begin()); - EXPECT_EQ(myList[shift+1], static_cast(num_nodes - 1)); - } - } - - //--- Iteration 1 -> 2 - phaseID = 1; - myList = migrationList[phaseID]; - if (this_node != num_nodes - 1) { - EXPECT_TRUE(myList.size() == 0); - } - else { - EXPECT_TRUE(myList.size() % 2 == 0); - for (NodeType in = 0; in+1 < num_nodes; ++in) { - for (ElementIDType elmID = 1; elmID < numElements; ++elmID) { - ElementIDType permID = elm::ElmIDBits::createCollectionImpl( - true, elmID+1, in, in - ).id; - auto it = std::find(myList.begin(), myList.end(), permID); - EXPECT_TRUE(it != myList.end()); - size_t shift = static_cast(it - myList.begin()); - EXPECT_TRUE(myList[shift+1] == static_cast(in)); - } - } - } - -} - -}}} // end namespace vt::tests::unit diff --git a/tests/unit/lb/test_offlinelb.cc b/tests/unit/lb/test_offlinelb.cc new file mode 100644 index 0000000000..981e09d801 --- /dev/null +++ b/tests/unit/lb/test_offlinelb.cc @@ -0,0 +1,154 @@ +/* +//@HEADER +// ***************************************************************************** +// +// test_offlinelb.cc +// DARMA/vt => Virtual Transport +// +// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC +// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. +// Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from this +// software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact darma@sandia.gov +// +// ***************************************************************************** +//@HEADER +*/ + +#include +#include +#include + +#include + +#include "test_parallel_harness.h" + +namespace vt { namespace tests { namespace unit { namespace lb { + +#if vt_check_enabled(lblite) + +using TestOfflineLB = TestParallelHarness; + +struct SimCol : vt::Collection { + struct Msg : vt::CollectionMessage { + PhaseType iter = 0; + explicit Msg(PhaseType in_iter) : iter(in_iter) { } + }; + void handler(Msg* m) { + auto const this_node = theContext()->getNode(); + auto const num_nodes = theContext()->getNumNodes(); + auto const next_node = (this_node + 1) % num_nodes; + auto const prev_node = this_node - 1 >= 0 ? this_node - 1 : num_nodes - 1; + vt_debug_print(terse, lb, "handler: idx={}: elm={}\n", getIndex(), getElmID()); + if (m->iter == 0 or m->iter == 3 or m->iter == 6) { + EXPECT_EQ(getIndex().x() / 2, this_node); + } else if (m->iter == 1 or m-> iter == 2) { + EXPECT_EQ(getIndex().x() / 2, prev_node); + } else if (m->iter == 4 or m-> iter == 5) { + EXPECT_EQ(getIndex().x() / 2, next_node); + } + } +}; + +TEST_F(TestOfflineLB, test_offlinelb_1) { + using LBDataHolder = vt::vrt::collection::balance::LBDataHolder; + using ElementIDStruct = vt::vrt::collection::balance::ElementIDStruct; + using LoadSummary = vt::vrt::collection::balance::LoadSummary; + using LBDataRestartReader = vt::vrt::collection::balance::LBDataRestartReader; + + auto const this_node = theContext()->getNode(); + auto const num_nodes = theContext()->getNumNodes(); + auto const next_node = (this_node + 1) % num_nodes; + auto const prev_node = this_node - 1 >= 0 ? this_node - 1 : num_nodes - 1; + + std::unordered_map> ids; + int len = 2; + PhaseType num_phases = 7; + for (int i = 0; i < len; i++) { + auto id = elm::ElmIDBits::createCollectionImpl(true, i+1, this_node, this_node); + id.curr_node = this_node; + ids[0].push_back(id); + id.curr_node = next_node; + ids[3].push_back(id); + id.curr_node = prev_node; + ids[6].push_back(id); + } + + for (int i = 0; i < len; i++) { + auto pid = elm::ElmIDBits::createCollectionImpl(true, i+1, prev_node, this_node); + auto nid = elm::ElmIDBits::createCollectionImpl(true, i+1, next_node, this_node); + ids[1].push_back(pid); + ids[2].push_back(pid); + ids[4].push_back(nid); + ids[5].push_back(nid); + } + + LBDataHolder dh; + for (PhaseType i = 0; i < num_phases; i++) { + for (auto&& elm : ids[i]) { + dh.node_data_[i][elm] = LoadSummary{3}; + } + } + + using JSONAppender = util::json::Appender; + std::stringstream stream{std::ios_base::out | std::ios_base::in}; + nlohmann::json metadata; + metadata["type"] = "LBDatafile"; + auto w = std::make_unique( + "phases", metadata, std::move(stream), true + ); + for (PhaseType i = 0; i < num_phases; i++) { + auto j = dh.toJson(i); + w->addElm(*j); + } + stream = w->finish(); + + theConfig()->vt_lb = true; + theConfig()->vt_lb_name = "OfflineLB"; + auto up = LBDataRestartReader::construct(); + curRT->theLBDataReader = up.get(); + theLBDataReader()->readLBDataFromStream(std::move(stream)); + + vt::Index1D range{2*num_nodes}; + auto proxy = vt::makeCollection("simcol") + .bounds(range) + .bulkInsert() + .wait(); + + for (PhaseType i = 0; i < num_phases; i++) { + runInEpochCollective("run handler", [&]{ + proxy.broadcastCollective(i); + }); + thePhase()->nextPhaseCollective(); + } +} + +#endif + +}}}} /* end namespace vt::tests::unit::lb */ diff --git a/tests/unit/location/test_location.cc b/tests/unit/location/test_location.cc index 8be5b21aff..190cd2e50d 100644 --- a/tests/unit/location/test_location.cc +++ b/tests/unit/location/test_location.cc @@ -341,7 +341,7 @@ TYPED_TEST_P(TestLocationRoute, test_route_entity) { using MsgType = location::EntityMsg; bool is_long = std::is_same::value; auto msg = vt::makeMessage(entity, my_node, is_long); - vt::theMsg()->broadcastMsg>(msg); + vt::theMsg()->broadcastMsg>(msg); vt::theSched()->runSchedulerWhile([&msg_count, nb_nodes]{ return msg_count < nb_nodes; }); diff --git a/tests/unit/mapping/test_mapping_registry.cc b/tests/unit/mapping/test_mapping_registry.cc index 7606188a0a..2d998ac7c6 100644 --- a/tests/unit/mapping/test_mapping_registry.cc +++ b/tests/unit/mapping/test_mapping_registry.cc @@ -108,11 +108,11 @@ TEST_F(TestMappingRegistry, test_mapping_block_1d_registry) { auto map_han = auto_registry::makeAutoHandlerMap(); auto msg = makeMessage(map_han); msg->is_block = true; - theMsg()->broadcastMsg(msg); + theMsg()->broadcastMsg(msg); auto map_han2 = auto_registry::makeAutoHandlerMap(); auto msg2 = makeMessage(map_han2); - theMsg()->broadcastMsg(msg2); + theMsg()->broadcastMsg(msg2); } } diff --git a/tests/unit/memory/test_memory_active.cc b/tests/unit/memory/test_memory_active.cc index 7ef27df03f..53ce419e4a 100644 --- a/tests/unit/memory/test_memory_active.cc +++ b/tests/unit/memory/test_memory_active.cc @@ -85,7 +85,7 @@ TYPED_TEST_P(TestMemoryActive, test_memory_remote_send) { for (int i = 0; i < num_msg_sent; i++) { auto msg = makeMessage(); msgs.push_back(msg); - theMsg()->sendMsg::test_handler>( + theMsg()->sendMsg::test_handler>( to_node, msg.get() ); } @@ -116,7 +116,7 @@ TYPED_TEST_P(TestMemoryActive, test_memory_remote_broadcast) { for (int i = 0; i < num_msg_sent; i++) { auto msg = makeMessage(); msgs.push_back(msg); - theMsg()->broadcastMsg::test_handler>( + theMsg()->broadcastMsg::test_handler>( msg.get() ); } diff --git a/tests/unit/memory/test_memory_lifetime.cc b/tests/unit/memory/test_memory_lifetime.cc index 90596e984c..8ab52b14c4 100644 --- a/tests/unit/memory/test_memory_lifetime.cc +++ b/tests/unit/memory/test_memory_lifetime.cc @@ -143,7 +143,7 @@ TEST_F(TestMemoryLifetime, test_active_bcast_serial_lifetime) { runInEpochCollective([&]{ for (int i = 0; i < num_msgs_sent; i++) { auto msg = makeMessage(); - theMsg()->broadcastMsg(msg); + theMsg()->broadcastMsg(msg); } }); @@ -165,7 +165,7 @@ TEST_F(TestMemoryLifetime, test_active_send_normal_lifetime_msgptr) { EXPECT_EQ(envelopeGetRef(msg->env), 1); auto msg_hold = promoteMsg(msg.get()); EXPECT_EQ(envelopeGetRef(msg_hold->env), 2); - theMsg()->sendMsg(next_node, msg); + theMsg()->sendMsg(next_node, msg); theTerm()->addAction([msg_hold]{ // Call event cleanup all pending MPI requests to clear theEvent()->finalize(); @@ -190,7 +190,7 @@ TEST_F(TestMemoryLifetime, test_active_bcast_normal_lifetime_msgptr) { EXPECT_EQ(envelopeGetRef(msg->env), 1); auto msg_hold = promoteMsg(msg.get()); EXPECT_EQ(envelopeGetRef(msg_hold->env), 2); - theMsg()->broadcastMsg(msg); + theMsg()->broadcastMsg(msg); theTerm()->addAction([msg_hold]{ // Call event cleanup all pending MPI requests to clear theEvent()->finalize(); @@ -227,7 +227,7 @@ TEST_F(TestMemoryLifetime, test_active_send_callback_lifetime_1) { for (int i = 0; i < num_msgs_sent; i++) { auto msg = makeMessage>(cb); auto msg_hold = promoteMsg(msg.get()); - theMsg()->broadcastMsg, callbackHan>(msg); + theMsg()->broadcastMsg(msg); theTerm()->addAction([msg_hold]{ // Call event cleanup all pending MPI requests to clear theEvent()->finalize(); diff --git a/tests/unit/objgroup/test_objgroup.cc b/tests/unit/objgroup/test_objgroup.cc index 2eebc58357..572e6c238c 100644 --- a/tests/unit/objgroup/test_objgroup.cc +++ b/tests/unit/objgroup/test_objgroup.cc @@ -181,8 +181,8 @@ TEST_F(TestObjGroup, test_proxy_schedule) { runInEpochCollective([&]{ // self-send a message and then broadcast - proxy[my_node].send(); - proxy.broadcast(); + proxy[my_node].send<&MyObjA::handler>(); + proxy.broadcast<&MyObjA::handler>(); obj = proxy.get(); vt_debug_print( @@ -212,12 +212,12 @@ TEST_F(TestObjGroup, test_proxy_callbacks) { auto proxy3 = vt::theObjGroup()->makeCollective("test_proxy_callbacks"); if (my_node == 0) { - proxy1[0].send(); - proxy1[0].send(); - proxy1[1].send(); + proxy1[0].send<&MyObjA::handler>(); + proxy1[0].send<&MyObjA::handler>(); + proxy1[1].send<&MyObjA::handler>(); } else if (my_node == 1) { - proxy2.broadcast(); - proxy3[0].send(); + proxy2.broadcast<&MyObjB::handler>(); + proxy3[0].send<&MyObjA::handler>(); } // check received messages for each group @@ -287,12 +287,22 @@ TEST_F(TestObjGroup, test_proxy_invoke) { // Non-message function auto const accumulate_result = - proxy[this_node] - .invoke( - std::vector{2, 4, 5}); + proxy[this_node].invoke<&MyObjA::accumulateVec>( + std::vector{2, 4, 5} + ); EXPECT_EQ(accumulate_result, 11); EXPECT_EQ(proxy.get()->recv_, 2); + + // Non-copyable + std::unique_ptr s{}; + auto result = proxy[this_node].invoke<&MyObjA::modifyNonCopyableStruct>( + std::move(s) + ); + + EXPECT_TRUE(result); + EXPECT_EQ(*result, 10); + EXPECT_EQ(proxy.get()->recv_, 3); } TEST_F(TestObjGroup, test_pending_send) { @@ -303,14 +313,14 @@ TEST_F(TestObjGroup, test_pending_send) { runInEpochCollective([&]{ // self-send a message and then broadcast - auto pending = proxy[my_node].send(); + auto pending = proxy[my_node].send<&MyObjA::handler>(); EXPECT_EQ(obj->recv_, 0); runInEpochCollective([&]{ pending.release(); } ); EXPECT_EQ(obj->recv_, 1 ); - auto pending2 = proxy.broadcast(); + auto pending2 = proxy.broadcast<&MyObjA::handlerOnlyFromSelf>(); EXPECT_EQ(obj->recv_, 1 ); diff --git a/tests/unit/objgroup/test_objgroup_common.h b/tests/unit/objgroup/test_objgroup_common.h index 931a8f4491..eafc12d033 100644 --- a/tests/unit/objgroup/test_objgroup_common.h +++ b/tests/unit/objgroup/test_objgroup_common.h @@ -97,6 +97,13 @@ struct MyObjA { return std::accumulate(std::begin(vec), std::end(vec), 0); } + std::unique_ptr modifyNonCopyableStruct(std::unique_ptr i) { + recv_++; + i = std::make_unique(10); + + return i; + } + int id_ = -1; int recv_ = 0; static int next_id; diff --git a/tests/unit/phase/test_phase_insertions.cc b/tests/unit/phase/test_phase_insertions.cc index 1627118504..615ab7c3b0 100644 --- a/tests/unit/phase/test_phase_insertions.cc +++ b/tests/unit/phase/test_phase_insertions.cc @@ -83,7 +83,7 @@ struct MyCol : vt::Collection { using MyMsg = vt::CollectionMessage; // A dummy kernel that does some work depending on the index -void colHandler(MyMsg*, MyCol* col) { +void colHandler(MyCol* col) { fmt::print("running colHandler: idx={}, phase={}\n", col->getIndex(), col->getPhase()); for (int i = 0; i < 10; i++) { for (int j = 0; j < col->getIndex().x() * 20; j++) { @@ -130,7 +130,7 @@ TEST_F(TestPhaseInsertions, test_phase_insertions_1) { // Do some work. runInEpochCollective([&]{ if (this_node == 0) { - proxy.broadcast(); + proxy.broadcast(); } }); diff --git a/tests/unit/pipe/test_callback_bcast.cc b/tests/unit/pipe/test_callback_bcast.cc index 27043b7069..3ebf52983d 100644 --- a/tests/unit/pipe/test_callback_bcast.cc +++ b/tests/unit/pipe/test_callback_bcast.cc @@ -160,7 +160,7 @@ TEST_F(TestCallbackBcast, test_callback_bcast_remote_1) { auto next = this_node + 1 < num_nodes ? this_node + 1 : 0; auto cb = theCB()->makeBcast(); auto msg = makeMessage(cb); - theMsg()->sendMsg(next, msg); + theMsg()->sendMsg(next, msg); }); EXPECT_EQ(called, 100 * theContext()->getNumNodes()); @@ -178,7 +178,7 @@ TEST_F(TestCallbackBcast, test_callback_bcast_remote_2) { auto next = this_node + 1 < num_nodes ? this_node + 1 : 0; auto cb = theCB()->makeBcast(); auto msg = makeMessage(cb); - theMsg()->sendMsg(next, msg); + theMsg()->sendMsg(next, msg); }); EXPECT_EQ(called, 200 * theContext()->getNumNodes()); @@ -196,7 +196,7 @@ TEST_F(TestCallbackBcast, test_callback_bcast_remote_3) { auto next = this_node + 1 < num_nodes ? this_node + 1 : 0; auto cb = theCB()->makeBcast(); auto msg = makeMessage(cb); - theMsg()->sendMsg(next, msg); + theMsg()->sendMsg(next, msg); }); EXPECT_EQ(called, 300 * theContext()->getNumNodes()); diff --git a/tests/unit/pipe/test_callback_bcast_collection.extended.cc b/tests/unit/pipe/test_callback_bcast_collection.extended.cc index 8987da8a5b..ca31be1ebe 100644 --- a/tests/unit/pipe/test_callback_bcast_collection.extended.cc +++ b/tests/unit/pipe/test_callback_bcast_collection.extended.cc @@ -119,7 +119,7 @@ struct TestCol : vt::Collection { bool other = false; }; -static void cb3(DataMsg* msg, TestCol* col) { +static void cb3(TestCol* col, DataMsg* msg) { EXPECT_EQ(msg->a, 8); EXPECT_EQ(msg->b, 9); EXPECT_EQ(msg->c, 10); @@ -177,7 +177,7 @@ TEST_F(TestCallbackBcastCollection, test_callback_bcast_collection_2) { auto next = this_node + 1 < num_nodes ? this_node + 1 : 0; auto cb = theCB()->makeBcast(proxy); auto msg = makeMessage(cb); - theMsg()->sendMsg(next, msg); + theMsg()->sendMsg(next, msg); } }); @@ -211,7 +211,7 @@ TEST_F(TestCallbackBcastCollection, test_callback_bcast_collection_3) { auto next = this_node + 1 < num_nodes ? this_node + 1 : 0; auto cb = theCB()->makeBcast(proxy); auto msg = makeMessage(cb); - theMsg()->sendMsg(next, msg); + theMsg()->sendMsg(next, msg); } }); diff --git a/tests/unit/pipe/test_callback_func.cc b/tests/unit/pipe/test_callback_func.cc index 83c7078f92..a9603faa1c 100644 --- a/tests/unit/pipe/test_callback_func.cc +++ b/tests/unit/pipe/test_callback_func.cc @@ -93,7 +93,7 @@ TEST_F(TestCallbackFunc, test_callback_func_2) { vt::pipe::LifetimeEnum::Once, []{ called = 400; } ); auto msg = makeMessage(cb); - theMsg()->sendMsg(1, msg); + theMsg()->sendMsg(1, msg); } }); diff --git a/tests/unit/pipe/test_callback_func_ctx.cc b/tests/unit/pipe/test_callback_func_ctx.cc index d067146e66..09054798b6 100644 --- a/tests/unit/pipe/test_callback_func_ctx.cc +++ b/tests/unit/pipe/test_callback_func_ctx.cc @@ -131,7 +131,7 @@ TEST_F(TestCallbackFuncCtx, test_callback_func_ctx_2) { }); // fmt::print("{}: next={}\n", this_node, next); auto msg = makeMessage(cb); - theMsg()->sendMsg(next, msg); + theMsg()->sendMsg(next, msg); }); // fmt::print("{}: called={}\n", this_node, called); diff --git a/tests/unit/pipe/test_callback_send.cc b/tests/unit/pipe/test_callback_send.cc index 5e8f37a2f8..be1a577957 100644 --- a/tests/unit/pipe/test_callback_send.cc +++ b/tests/unit/pipe/test_callback_send.cc @@ -155,7 +155,7 @@ TEST_F(TestCallbackSend, test_callback_send_remote_1) { auto next = this_node + 1 < num_nodes ? this_node + 1 : 0; auto cb = theCB()->makeSend(this_node); auto msg = makeMessage(cb); - theMsg()->sendMsg(next, msg); + theMsg()->sendMsg(next, msg); }); EXPECT_EQ(called, 100); @@ -171,7 +171,7 @@ TEST_F(TestCallbackSend, test_callback_send_remote_2) { auto next = this_node + 1 < num_nodes ? this_node + 1 : 0; auto cb = theCB()->makeSend(this_node); auto msg = makeMessage(cb); - theMsg()->sendMsg(next, msg); + theMsg()->sendMsg(next, msg); }); EXPECT_EQ(called, 200); @@ -187,7 +187,7 @@ TEST_F(TestCallbackSend, test_callback_send_remote_3) { auto next = this_node + 1 < num_nodes ? this_node + 1 : 0; auto cb = theCB()->makeSend(this_node); auto msg = makeMessage(cb); - theMsg()->sendMsg(next, msg); + theMsg()->sendMsg(next, msg); }); EXPECT_EQ(called, 300); diff --git a/tests/unit/pipe/test_callback_send_collection.extended.cc b/tests/unit/pipe/test_callback_send_collection.extended.cc index 473ebc9149..5dfad65c5c 100644 --- a/tests/unit/pipe/test_callback_send_collection.extended.cc +++ b/tests/unit/pipe/test_callback_send_collection.extended.cc @@ -116,7 +116,7 @@ struct TestCol : vt::Collection { int32_t val = 17; }; -static void cb3(DataMsg* msg, TestCol* col) { +static void cb3(TestCol* col, DataMsg* msg) { EXPECT_EQ(msg->a, 8); EXPECT_EQ(msg->b, 9); EXPECT_EQ(msg->c, 10); @@ -186,12 +186,12 @@ TEST_F(TestCallbackSendCollection, test_callback_send_collection_2) { auto cb = theCB()->makeSend(proxy(i)); auto msg = makeMessage(cb); - theMsg()->sendMsg(next, msg); + theMsg()->sendMsg(next, msg); } else { auto cb = theCB()->makeSend(proxy(i)); auto msg = makeMessage(cb); - theMsg()->sendMsg(next, msg); + theMsg()->sendMsg(next, msg); } } } diff --git a/tests/unit/pipe/test_signal_cleanup.cc b/tests/unit/pipe/test_signal_cleanup.cc index d650b8bb96..01bf454ac6 100644 --- a/tests/unit/pipe/test_signal_cleanup.cc +++ b/tests/unit/pipe/test_signal_cleanup.cc @@ -86,7 +86,7 @@ TEST_F(TestSignalCleanup, test_signal_cleanup_3) { } ); auto msg = makeMessage(cb); - theMsg()->sendMsg(1, msg); + theMsg()->sendMsg(1, msg); } // run until termination @@ -113,7 +113,7 @@ TEST_F(TestSignalCleanup, test_signal_cleanup_3) { } ); auto msg = makeMessage(cb); - theMsg()->sendMsg(1, msg); + theMsg()->sendMsg(1, msg); } // run until termination diff --git a/tests/unit/runtime/test_initialization.cc b/tests/unit/runtime/test_initialization.cc index 0f04a3d129..95e0498e0d 100644 --- a/tests/unit/runtime/test_initialization.cc +++ b/tests/unit/runtime/test_initialization.cc @@ -72,7 +72,7 @@ TEST_F(TestInitialization, test_initialize_with_args) { EXPECT_EQ(custom_argc, 3); - vt::initialize(custom_argc, custom_argv, no_workers, true, &comm); + vt::initialize(custom_argc, custom_argv, &comm); EXPECT_EQ(theConfig()->prog_name, "vt_program"); EXPECT_EQ(theConfig()->vt_no_terminate, true); @@ -104,7 +104,7 @@ TEST_F(TestInitialization, test_initialize_with_appconfig) { appConfig.vt_lb_name = "RotateLB"; appConfig.vt_lb_data = true; - vt::initialize(custom_argc, custom_argv, no_workers, true, &comm, &appConfig); + vt::initialize(custom_argc, custom_argv, &comm, &appConfig); EXPECT_EQ(theConfig()->prog_name, "vt_program"); EXPECT_EQ(theConfig()->vt_epoch_graph_on_hang, false); @@ -147,7 +147,7 @@ TEST_F(TestInitialization, test_initialize_with_args_and_appconfig) { appConfig.vt_lb_data = true; appConfig.vt_no_detect_hang = false; - vt::initialize(custom_argc, custom_argv, no_workers, true, &comm, &appConfig); + vt::initialize(custom_argc, custom_argv, &comm, &appConfig); EXPECT_EQ(theConfig()->prog_name, "vt_program"); EXPECT_EQ(theConfig()->vt_color, false); @@ -198,7 +198,7 @@ TEST_F(TestInitialization, test_initialize_with_file_and_args) { } MPI_Barrier(comm); - vt::initialize(custom_argc, custom_argv, no_workers, true, &comm); + vt::initialize(custom_argc, custom_argv, &comm); EXPECT_EQ(theConfig()->prog_name, "vt_program"); EXPECT_EQ(theConfig()->vt_no_terminate, true); @@ -247,7 +247,7 @@ TEST_F(TestInitialization, test_initialize_with_file_args_and_appconfig) { } MPI_Barrier(comm); - vt::initialize(custom_argc, custom_argv, no_workers, true, &comm, &appConfig); + vt::initialize(custom_argc, custom_argv, &comm, &appConfig); EXPECT_EQ(theConfig()->prog_name, "vt_program"); EXPECT_EQ(theConfig()->vt_no_terminate, true); diff --git a/tests/unit/runtime/test_mpi_access_guards.cc b/tests/unit/runtime/test_mpi_access_guards.cc index d1e6e17535..4f63a80427 100644 --- a/tests/unit/runtime/test_mpi_access_guards.cc +++ b/tests/unit/runtime/test_mpi_access_guards.cc @@ -90,7 +90,7 @@ void testMpiAccess(bool access_allowed, bool grant_access) { // Sending message for common-case of attempting MPI access within // a message handler; it applies to all cases through the scheduler. auto msg = vt::makeMessage(); - theMsg()->sendMsg(1, msg); + theMsg()->sendMsg(1, msg); } } diff --git a/tests/unit/runtime/test_preconfig.nompi.cc b/tests/unit/runtime/test_preconfig.nompi.cc index 57b745690d..1ae2658a39 100644 --- a/tests/unit/runtime/test_preconfig.nompi.cc +++ b/tests/unit/runtime/test_preconfig.nompi.cc @@ -51,8 +51,10 @@ namespace vt { namespace tests { namespace unit { struct TestPreconfig : TestHarness { }; -#if not vt_check_enabled(production_build) TEST_F(TestPreconfig, test_vt_assert) { +#if vt_check_enabled(production_build) or defined(__INTEL_COMPILER) + GTEST_SKIP(); +#else EXPECT_EQ(vt::debug::preConfig()->vt_throw_on_abort, true) << "vt_throw_on_abort should be enabled by default"; @@ -60,8 +62,8 @@ TEST_F(TestPreconfig, test_vt_assert) { vtAssert(false, "Should throw."), std::runtime_error ); -} #endif +} TEST_F(TestPreconfig, test_vt_abort) { EXPECT_EQ(vt::debug::preConfig()->vt_throw_on_abort, true) diff --git a/tests/unit/scheduler/test_scheduler_loop.cc b/tests/unit/scheduler/test_scheduler_loop.cc index fee8f98c7f..c39304ec6b 100644 --- a/tests/unit/scheduler/test_scheduler_loop.cc +++ b/tests/unit/scheduler/test_scheduler_loop.cc @@ -88,7 +88,7 @@ static void message_handler_with_nested_loop(TestMsg* msg) { auto next_msg = vt::makeMessage(); next_msg->action_ = next_depth; - theMsg()->sendMsg(target_node, next_msg); + theMsg()->sendMsg(target_node, next_msg); // ..run scheduler until someone also passed us the message. if ("nested" == action) { @@ -117,7 +117,7 @@ TEST_F(TestSchedulerLoop, test_scheduler_loop_nesting_1) { auto msg = vt::makeMessage(); msg->action_ = 1; - theMsg()->sendMsg(target_node, msg); + theMsg()->sendMsg(target_node, msg); done = false; theSched()->runSchedulerWhile([]{ return not done; }); diff --git a/tests/unit/scheduler/test_scheduler_timings.cc b/tests/unit/scheduler/test_scheduler_timings.cc new file mode 100644 index 0000000000..3521cd7973 --- /dev/null +++ b/tests/unit/scheduler/test_scheduler_timings.cc @@ -0,0 +1,152 @@ +/* +//@HEADER +// ***************************************************************************** +// +// test_scheduler_timings.cc +// DARMA/vt => Virtual Transport +// +// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC +// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. +// Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from this +// software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact darma@sandia.gov +// +// ***************************************************************************** +//@HEADER +*/ + +#include + +#include "vt/scheduler/scheduler.h" +#include "vt/elm/elm_id_bits.h" + +#include "test_parallel_harness.h" +#include "test_helpers.h" + +#include +#include + +namespace vt { namespace tests { namespace unit { + +struct TestSchedTimings : TestParallelHarness { }; + +struct MyMsg : vt::Message { + int ms = 0; +}; + +int count = 0; + +void myHandler(MyMsg* msg) { + fmt::print("running myHandler: ms={}\n", msg->ms); + std::this_thread::sleep_for(std::chrono::milliseconds{msg->ms}); + count++; +} +#if vt_check_enabled(lblite) + TEST_F(TestSchedTimings, test_sched_lb) { + + auto sched = std::make_unique(); + + auto const this_node = theContext()->getNode(); + + std::vector>> v; + + int const num_iter = 10; + + + for (int i = 0; i < num_iter; i++) { + int time = i*50; + v.emplace_back(time, std::make_unique()); + + auto id = elm::ElmIDBits::createCollection(true, this_node); + auto handler = auto_registry::makeAutoHandler(); + auto msg = vt::makeMessage(); + msg->ms = time; + auto maker = vt::runnable::makeRunnable(msg, false, handler, 0) + .withLBData(std::get<1>(v[i]).get(), id); + auto runnable = maker.getRunnableImpl(); + runnable->setupHandler(handler); + sched->enqueue(false, runnable); + } + + sched->runSchedulerWhile([&]{ return count < num_iter; }); + //To appease CI just ask for more comparisons to be good than bad + int num_pass =0; + for (auto& [time, data] : v) { + auto load = 1000.0* data->getLoad(0); + fmt::print("expected time={}, observed time={}\n", time, load); + double margin = 30+ time*0.20; + if ((time - load)< margin) { num_pass++; } + } + EXPECT_GT (num_pass, num_iter - num_pass); + + } +#endif +TEST_F(TestSchedTimings, test_sched_msg) { + + auto sched = std::make_unique(); + + int const num_iter = 10; + int const ms_delay = 50; + count = 0; + auto start_time = vt::timing::getCurrentTime(); + + for (int i = 0; i < num_iter; i++) { + + auto next_msg = vt::makeMessage(); + next_msg->ms = ms_delay; + + auto handler = auto_registry::makeAutoHandler(); + + auto maker = vt::runnable::makeRunnable(next_msg, false, handler, 0); + + auto runnable = maker.getRunnableImpl(); + runnable->setupHandler(handler); + sched->enqueue(false, runnable); + } + + sched->runSchedulerWhile([&]{ return count < num_iter; }); + double const fudge = 0.8; + auto observed_time = 1000.0 *(vt::timing::getCurrentTime() - start_time); + + // This ought to take close to a second (with ms_delay = 100) + EXPECT_GT( + observed_time, + vt::theConfig()->vt_sched_progress_sec * fudge + ); + + auto sum_time = num_iter *ms_delay; + fmt::print("expected time={}, observed time={}\n", sum_time, observed_time); + //double margin =30+ sum_time*0.2; + //EXPECT_NEAR(sum_time, observed_time, margin ); + EXPECT_GT(observed_time, sum_time); + +} + + +}}} /* vt::tests::unit */ diff --git a/tests/unit/serialization/test_serialize_messenger_virtual.extended.cc b/tests/unit/serialization/test_serialize_messenger_virtual.extended.cc index 2053b7878b..fa0040c4be 100644 --- a/tests/unit/serialization/test_serialize_messenger_virtual.extended.cc +++ b/tests/unit/serialization/test_serialize_messenger_virtual.extended.cc @@ -94,7 +94,7 @@ struct DataMsg : vt::vrt::VirtualMessage { struct TestSerialMessengerVirtual : TestParallelHarness { using TestMsg = TestStaticBytesShortMsg<4>; - static void testHandler(DataMsg* msg, TestCtx* ctx) { + static void testHandler(TestCtx* ctx, DataMsg* msg) { msg->check(); } }; diff --git a/tests/unit/termination/test_epoch_guard.cc b/tests/unit/termination/test_epoch_guard.cc index b828127475..e58360898e 100644 --- a/tests/unit/termination/test_epoch_guard.cc +++ b/tests/unit/termination/test_epoch_guard.cc @@ -74,7 +74,7 @@ struct TestEpochGuard : TestParallelHarness { EXPECT_EQ(theMsg()->getEpoch(), ep); auto node = theContext()->getNode(); if (0 == node) { - theMsg()->sendMsg(1, msg); + theMsg()->sendMsg(1, msg); } } @@ -91,7 +91,7 @@ struct TestEpochGuard : TestParallelHarness { EXPECT_EQ(theMsg()->getEpoch(), ep); auto node = theContext()->getNode(); if (0 == node) { - theMsg()->sendMsg(1, msg); + theMsg()->sendMsg(1, msg); } guard.pop(); diff --git a/tests/unit/termination/test_term_chaining.cc b/tests/unit/termination/test_term_chaining.cc index 42d1a6f760..4627e3e96a 100644 --- a/tests/unit/termination/test_term_chaining.cc +++ b/tests/unit/termination/test_term_chaining.cc @@ -79,7 +79,7 @@ struct TestTermChaining : TestParallelHarness { EXPECT_EQ(theContext()->getNode(), 1); auto msg2 = makeMessage(); - theMsg()->sendMsg(0, msg2); + theMsg()->sendMsg(0, msg2); } static void test_handler_response(TestMsg* msg) { @@ -96,7 +96,7 @@ struct TestTermChaining : TestParallelHarness { EXPECT_EQ(handler_count, 12); handler_count++; auto msg2 = makeMessage(); - theMsg()->sendMsg(0, msg2); + theMsg()->sendMsg(0, msg2); } static void test_handler_chained(TestMsg* msg) { @@ -140,7 +140,7 @@ struct TestTermChaining : TestParallelHarness { vt::theMsg()->pushEpoch(epoch1); auto msg = makeMessage(); chain.add( - epoch1, theMsg()->sendMsg(1, msg) + epoch1, theMsg()->sendMsg(1, msg) ); vt::theMsg()->popEpoch(epoch1); vt::theTerm()->finishedEpoch(epoch1); @@ -149,7 +149,7 @@ struct TestTermChaining : TestParallelHarness { vt::theMsg()->pushEpoch(epoch2); auto msg2 = makeMessage(); chain.add( - epoch2, theMsg()->sendMsg(1, msg2) + epoch2, theMsg()->sendMsg(1, msg2) ); vt::theMsg()->popEpoch(epoch2); vt::theTerm()->finishedEpoch(epoch2); @@ -165,7 +165,7 @@ struct TestTermChaining : TestParallelHarness { vt::theMsg()->pushEpoch(epoch1); auto msg = makeMessage(); chain.add( - epoch1, theMsg()->sendMsg(1, msg.get())); + epoch1, theMsg()->sendMsg(1, msg.get())); vt::theMsg()->popEpoch(epoch1); vt::theTerm()->finishedEpoch(epoch1); } @@ -182,7 +182,7 @@ struct TestTermChaining : TestParallelHarness { vt::theMsg()->pushEpoch(epoch3); auto msg3 = makeMessage(); chain.add( - epoch3, theMsg()->broadcastMsg(msg3.get())); + epoch3, theMsg()->broadcastMsg(msg3.get())); vt::theMsg()->popEpoch(epoch3); vt::theTerm()->finishedEpoch(epoch3); diff --git a/tests/unit/termination/test_term_cleanup.cc b/tests/unit/termination/test_term_cleanup.cc index a67e27c5b6..57f779f8a5 100644 --- a/tests/unit/termination/test_term_cleanup.cc +++ b/tests/unit/termination/test_term_cleanup.cc @@ -79,7 +79,7 @@ TEST_F(TestTermCleanup, test_termination_cleanup_1) { auto msg = makeMessage(); envelopeSetEpoch(msg->env, epoch); - theMsg()->sendMsg(next, msg); + theMsg()->sendMsg(next, msg); theTerm()->finishedEpoch(epoch); vt::runSchedulerThrough(epoch); @@ -123,17 +123,17 @@ TEST_F(TestTermCleanup, test_termination_cleanup_2) { for (int j = 0; j < 5; j++) { auto msg = makeMessage(); envelopeSetEpoch(msg->env, coll_epoch); - theMsg()->sendMsg(next, msg); + theMsg()->sendMsg(next, msg); } for (int j = 0; j < 5; j++) { auto msg = makeMessage(); envelopeSetEpoch(msg->env, root_epoch); - theMsg()->sendMsg(next, msg); + theMsg()->sendMsg(next, msg); } for (int j = 0; j < 5; j++) { auto msg = makeMessage(); envelopeSetEpoch(msg->env, wave_epoch); - theMsg()->sendMsg(next, msg); + theMsg()->sendMsg(next, msg); } theTerm()->finishedEpoch(coll_epoch); diff --git a/tests/unit/termination/test_termination_action_common.impl.h b/tests/unit/termination/test_termination_action_common.impl.h index 5dd8e61beb..ddd38219af 100644 --- a/tests/unit/termination/test_termination_action_common.impl.h +++ b/tests/unit/termination/test_termination_action_common.impl.h @@ -170,7 +170,7 @@ inline void add(vt::EpochType const& epoch, int order){ EXPECT_TRUE(channel::hasEnded(epoch)); channel::ok = true; auto msg = vt::makeMessage(); - vt::theMsg()->broadcastMsg(msg); + vt::theMsg()->broadcastMsg<&setOk>(msg); }); } } diff --git a/tests/unit/termination/test_termination_channel_counting.impl.h b/tests/unit/termination/test_termination_channel_counting.impl.h index b089b6b989..0991ee9ffd 100644 --- a/tests/unit/termination/test_termination_channel_counting.impl.h +++ b/tests/unit/termination/test_termination_channel_counting.impl.h @@ -55,7 +55,7 @@ void sendMsg(vt::NodeType dst, int count, vt::EpochType ep) { if (ep != vt::no_epoch) { vt::envelopeSetEpoch(msg->env,ep); } - vt::theMsg()->sendMsg(dst, msg); + vt::theMsg()->sendMsg(dst, msg); } // note: only for basic messages, @@ -68,7 +68,7 @@ void broadcast(int count, vt::EpochType ep) { if (ep != vt::no_epoch) { vt::envelopeSetEpoch(msg->env,ep); } - vt::theMsg()->broadcastMsg(msg); + vt::theMsg()->broadcastMsg(msg); for (auto&& active : data[ep].count_) { auto const& dst = active.first; diff --git a/tests/unit/termination/test_termination_reset.cc b/tests/unit/termination/test_termination_reset.cc index af7e42868e..2300e7b491 100644 --- a/tests/unit/termination/test_termination_reset.cc +++ b/tests/unit/termination/test_termination_reset.cc @@ -73,7 +73,7 @@ TEST_F(TestTermReset, test_termination_reset_1) { if (this_node == 0) { auto msg = makeMessage(); - theMsg()->broadcastMsg(msg); + theMsg()->broadcastMsg(msg); } else if (this_node == 1) { theTerm()->addAction([=]{ EXPECT_EQ(handler_count, 10); @@ -89,7 +89,7 @@ TEST_F(TestTermReset, test_termination_reset_1) { if (this_node == 1) { auto msg = makeMessage(); - theMsg()->broadcastMsg(msg); + theMsg()->broadcastMsg(msg); } else if (this_node == 0) { theTerm()->addAction([=]{ EXPECT_EQ(handler_count, 10); diff --git a/tests/unit/test_parallel_harness.h b/tests/unit/test_parallel_harness.h index 2b2581db60..a8c95c3eda 100644 --- a/tests/unit/test_parallel_harness.h +++ b/tests/unit/test_parallel_harness.h @@ -88,7 +88,7 @@ struct TestParallelHarnessAny : TestHarnessAny { "The value of argv[argc] should always be 0" ); // communicator is duplicated. - CollectiveOps::initialize(custom_argc, custom_argv, no_workers, true, &comm); + CollectiveOps::initialize(custom_argc, custom_argv, true, &comm); #if DEBUG_TEST_HARNESS_PRINT auto const& my_node = theContext()->getNode(); diff --git a/tests/unit/tls/test_tls.nompi.cc b/tests/unit/tls/test_tls.nompi.cc deleted file mode 100644 index 6a565a1faf..0000000000 --- a/tests/unit/tls/test_tls.nompi.cc +++ /dev/null @@ -1,396 +0,0 @@ -/* -//@HEADER -// ***************************************************************************** -// -// test_tls.nompi.cc -// DARMA/vt => Virtual Transport -// -// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC -// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. -// Government retains certain rights in this software. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Questions? Contact darma@sandia.gov -// -// ***************************************************************************** -//@HEADER -*/ - -#include -#include - -#include - -#include "test_harness.h" -#include "test_parallel_harness.h" - -#include "vt/utils/tls/tls.h" - -#if vt_check_enabled(openmp) - #include -#else - #include -#endif - -namespace vt { namespace tests { namespace unit { - -using namespace vt::tests::unit; - -struct TestTLS : TestHarness { }; - -static constexpr int const num_vals = 128; - -// Test TLS: w/o initializer, single thread, global variable -DeclareTLS(int, test_noinit_single_thd) -#define IS_TLS 0 -DeclareInitVar(IS_TLS, int, test_var_noinit_single_thd, 0) - -TEST_F(TestTLS, basic_tls_noinit_single_thd) { - using namespace vt::util::tls; - - for (int i = 0; i < num_vals; i++) { - AccessTLS(test_noinit_single_thd) = i; - EXPECT_EQ(AccessTLS(test_noinit_single_thd), i); - } -} - -TEST_F(TestTLS, basic_var_tls_noinit_single_thd) { - using namespace vt::util::tls; - - for (int i = 0; i < num_vals; i++) { - AccessVar(test_var_noinit_single_thd) = i; - EXPECT_EQ(AccessVar(test_var_noinit_single_thd), i); - } -} - -// Test TLS: w/o initializer, single thread, static global variable -DeclareStaticTLS(int, test_noinit_static_single_thd) - -TEST_F(TestTLS, basic_tls_noinit_static_single_thd) { - using namespace vt::util::tls; - - for (int i = 0; i < num_vals; i++) { - AccessTLS(test_noinit_static_single_thd) = i; - EXPECT_EQ(AccessTLS(test_noinit_static_single_thd), i); - } -} - -// Test TLS: w/o initializer, single thread, class static variable -struct TestClsStatic { - DeclareClassInsideTLS(TestClsStatic, int, test_noinit_class_single_thd) -}; -DeclareClassOutsideTLS(TestClsStatic, int, test_noinit_class_single_thd) - -TEST_F(TestTLS, basic_tls_noinit_class_single_thd) { - using namespace vt::util::tls; - - for (int i = 0; i < num_vals; i++) { - AccessClassTLS(TestClsStatic, test_noinit_class_single_thd) = i; - EXPECT_EQ(AccessClassTLS(TestClsStatic, test_noinit_class_single_thd), i); - } -} - - -static constexpr int const init_val = 29; - -// Test TLS: w/initializer, single thread, class static variable -struct TestClsStaticInit { - DeclareClassInsideInitTLS(TestClsStaticInit, int, test_init_class_single_thd, init_val) -}; -DeclareClassOutsideInitTLS(TestClsStaticInit, int, test_init_class_single_thd, init_val) - -TEST_F(TestTLS, basic_tls_init_class_single_thd) { - using namespace vt::util::tls; - - EXPECT_EQ(AccessClassTLS(TestClsStaticInit, test_init_class_single_thd), init_val); - - for (int i = 0; i < num_vals; i++) { - AccessClassTLS(TestClsStaticInit, test_init_class_single_thd) = i; - EXPECT_EQ(AccessClassTLS(TestClsStaticInit, test_init_class_single_thd), i); - } -} - -// Test TLS: w/initializer, single thread, global variable -DeclareInitTLS(int, test_init_single_thd, init_val) - -TEST_F(TestTLS, basic_tls_init_single_thd) { - using namespace vt::util::tls; - - EXPECT_EQ(AccessTLS(test_init_single_thd), init_val); - - for (int i = 0; i < num_vals; i++) { - AccessTLS(test_init_single_thd) = i; - EXPECT_EQ(AccessTLS(test_init_single_thd), i); - } -} - -// Test TLS: w/initializer, single thread, static global variable -DeclareStaticInitTLS(int, test_init_static_single_thd, init_val) - -TEST_F(TestTLS, basic_tls_init_static_single_thd) { - using namespace vt::util::tls; - - EXPECT_EQ(AccessTLS(test_init_static_single_thd), init_val); - - for (int i = 0; i < num_vals; i++) { - AccessTLS(test_init_static_single_thd) = i; - EXPECT_EQ(AccessTLS(test_init_static_single_thd), i); - } -} - -// Test TLS: w/o initializer, single thread, class static variable -struct TestClsMultiStatic { - DeclareClassInsideTLS(TestClsMultiStatic, int, test_noinit_class_multi_thd) -}; -DeclareClassOutsideTLS(TestClsMultiStatic, int, test_noinit_class_multi_thd) - -// Test TLS: winitializer, single thread, class static variable -struct TestClsMultiInitStatic { - DeclareClassInsideInitTLS(TestClsMultiInitStatic, int, test_init_class_multi_thd, init_val) -}; -DeclareClassOutsideInitTLS(TestClsMultiInitStatic, int, test_init_class_multi_thd, init_val) - -#if vt_check_enabled(openmp) or vt_check_enabled(stdthread) - -static constexpr WorkerCountType const num_workers = 8; - -// Test TLS: w/o initializer, multi thread, global variable -DeclareTLS(int, test_noinit_multi_thd) - -// Test TLS: w/initializer, multi thread, global variable -DeclareInitTLS(int, test_init_multi_thd, init_val) - -// Test TLS: w/o initializer, multi thread, static global variable -DeclareStaticTLS(int, test_noinit_static_multi_thd) - -// Test TLS: w/initializer, multi thread, static global variable -DeclareStaticInitTLS(int, test_init_static_multi_thd, init_val) - -static void testTLSMulti( - bool const is_static, bool const is_init, bool const is_class = false -) { - if (is_init) { - if (is_static) { - EXPECT_EQ(AccessTLS(test_init_static_multi_thd), init_val); - } else if (is_class) { - EXPECT_EQ(AccessClassTLS(TestClsMultiInitStatic, test_init_class_multi_thd), init_val); - } else { - EXPECT_EQ(AccessTLS(test_init_multi_thd), init_val); - } - } - - if (is_init) { - if (is_static) { - for (int i = 0; i < num_vals; i++) { - AccessTLS(test_init_static_multi_thd) = i; - EXPECT_EQ(AccessTLS(test_init_static_multi_thd), i); - } - } else if (is_class) { - for (int i = 0; i < num_vals; i++) { - AccessClassTLS(TestClsMultiInitStatic, test_init_class_multi_thd) = i; - EXPECT_EQ(AccessClassTLS(TestClsMultiInitStatic, test_init_class_multi_thd), i); - } - } else { - for (int i = 0; i < num_vals; i++) { - AccessTLS(test_init_multi_thd) = i; - EXPECT_EQ(AccessTLS(test_init_multi_thd), i); - } - } - } else { - if (is_static) { - for (int i = 0; i < num_vals; i++) { - AccessTLS(test_noinit_static_multi_thd) = i; - EXPECT_EQ(AccessTLS(test_noinit_static_multi_thd), i); - } - } else if (is_class) { - for (int i = 0; i < num_vals; i++) { - AccessClassTLS(TestClsMultiStatic, test_noinit_class_multi_thd) = i; - EXPECT_EQ(AccessClassTLS(TestClsMultiStatic, test_noinit_class_multi_thd), i); - } - } else { - for (int i = 0; i < num_vals; i++) { - AccessTLS(test_noinit_multi_thd) = i; - EXPECT_EQ(AccessTLS(test_noinit_multi_thd), i); - } - } - } -} -#endif /* vt_check_enabled(openmp) or vt_check_enabled(stdthread) */ - -#if vt_check_enabled(openmp) - -TEST_F(TestTLS, basic_tls_noinit_multi_thd_openmp) { - using namespace vt::util::tls; - - #pragma omp parallel num_threads(num_workers + 1) - { - testTLSMulti(false, false); - } -} - -TEST_F(TestTLS, basic_tls_init_multi_thd_openmp) { - using namespace vt::util::tls; - - #pragma omp parallel num_threads(num_workers + 1) - { - testTLSMulti(false, true); - } -} - -TEST_F(TestTLS, basic_tls_noinit_static_multi_thd_openmp) { - using namespace vt::util::tls; - - #pragma omp parallel num_threads(num_workers + 1) - { - testTLSMulti(true, false); - } -} - -TEST_F(TestTLS, basic_tls_init_static_multi_thd_openmp) { - using namespace vt::util::tls; - - #pragma omp parallel num_threads(num_workers + 1) - { - testTLSMulti(true, true); - } -} - -TEST_F(TestTLS, basic_tls_noinit_class_multi_thd_openmp) { - using namespace vt::util::tls; - - #pragma omp parallel num_threads(num_workers + 1) - { - testTLSMulti(false, false, true); - } -} - -TEST_F(TestTLS, basic_tls_init_class_multi_thd_openmp) { - using namespace vt::util::tls; - - #pragma omp parallel num_threads(num_workers + 1) - { - testTLSMulti(false, true, true); - } -} - -#elif vt_check_enabled(stdthread) - -static void testTLSMultiNoInit() { testTLSMulti(false, false, false); } -static void testTLSMultiInit() { testTLSMulti(false, true, false); } -static void testTLSMultiStaticNoInit() { testTLSMulti(true, false, false); } -static void testTLSMultiStaticInit() { testTLSMulti(true, true, false); } -static void testTLSMultiClassNoInit() { testTLSMulti(false, false, true); } -static void testTLSMultiClassInit() { testTLSMulti(false, true, true); } - -TEST_F(TestTLS, basic_tls_noinit_multi_thd_std) { - using namespace vt::util::tls; - - std::vector thds; - for (auto i = 0; i < num_workers; i++) { - thds.emplace_back(std::thread(testTLSMultiNoInit)); - } - testTLSMultiNoInit(); - - for (auto i = 0; i < num_workers; i++) { - thds[i].join(); - } -} - -TEST_F(TestTLS, basic_tls_init_multi_thd_std) { - using namespace vt::util::tls; - - std::vector thds; - for (auto i = 0; i < num_workers; i++) { - thds.emplace_back(std::thread(testTLSMultiInit)); - } - testTLSMultiInit(); - - for (auto i = 0; i < num_workers; i++) { - thds[i].join(); - } -} - -TEST_F(TestTLS, basic_tls_noinit_static_multi_thd_std) { - using namespace vt::util::tls; - - std::vector thds; - for (auto i = 0; i < num_workers; i++) { - thds.emplace_back(std::thread(testTLSMultiStaticNoInit)); - } - testTLSMultiStaticNoInit(); - - for (auto i = 0; i < num_workers; i++) { - thds[i].join(); - } -} - -TEST_F(TestTLS, basic_tls_init_static_multi_thd_std) { - using namespace vt::util::tls; - - std::vector thds; - for (auto i = 0; i < num_workers; i++) { - thds.emplace_back(std::thread(testTLSMultiStaticInit)); - } - testTLSMultiStaticInit(); - - for (auto i = 0; i < num_workers; i++) { - thds[i].join(); - } -} - -TEST_F(TestTLS, basic_tls_noinit_class_multi_thd_std) { - using namespace vt::util::tls; - - std::vector thds; - for (auto i = 0; i < num_workers; i++) { - thds.emplace_back(std::thread(testTLSMultiClassNoInit)); - } - testTLSMultiClassNoInit(); - - for (auto i = 0; i < num_workers; i++) { - thds[i].join(); - } -} - -TEST_F(TestTLS, basic_tls_init_class_multi_thd_std) { - using namespace vt::util::tls; - - std::vector thds; - for (auto i = 0; i < num_workers; i++) { - thds.emplace_back(std::thread(testTLSMultiClassInit)); - } - testTLSMultiClassInit(); - - for (auto i = 0; i < num_workers; i++) { - thds[i].join(); - } -} - -#endif - -}}} // end namespace vt::tests::unit diff --git a/tutorial/tutorial_1b.h b/tutorial/tutorial_1b.h index b8b3ed1cba..94c4a959fc 100644 --- a/tutorial/tutorial_1b.h +++ b/tutorial/tutorial_1b.h @@ -117,7 +117,7 @@ static inline void activeMessageNode() { if (this_node == 0) { NodeType const to_node = 1; auto msg = ::vt::makeMessage(29,32); - ::vt::theMsg()->sendMsg(to_node, msg); + ::vt::theMsg()->sendMsg(to_node, msg); } } diff --git a/tutorial/tutorial_1c.h b/tutorial/tutorial_1c.h index 9aade203ba..f7e9946974 100644 --- a/tutorial/tutorial_1c.h +++ b/tutorial/tutorial_1c.h @@ -137,7 +137,7 @@ static inline void activeMessageSerialization() { auto msg = ::vt::makeMessage(1,2,3); msg->particles.push_back(Particle{10,11,12}); msg->particles.push_back(Particle{13,14,15}); - ::vt::theMsg()->sendMsg(to_node, msg); + ::vt::theMsg()->sendMsg(to_node, msg); } } diff --git a/tutorial/tutorial_1e.h b/tutorial/tutorial_1e.h index 839af157c7..bd21eacbf8 100644 --- a/tutorial/tutorial_1e.h +++ b/tutorial/tutorial_1e.h @@ -78,7 +78,7 @@ static inline void activeMessageGroupRoot() { fmt::print("Group is created: id={:x}\n", group_id); auto msg = makeMessage(); envelopeSetGroup(msg->env, group_id); - theMsg()->broadcastMsg(msg); + theMsg()->broadcastMsg(msg); }); // The `id' that is returned from the newGroup invocation, can be used // anywhere in the system to broadcast (multicast) to this group. diff --git a/tutorial/tutorial_1f.h b/tutorial/tutorial_1f.h index 0924fe1b78..fc6a79742c 100644 --- a/tutorial/tutorial_1f.h +++ b/tutorial/tutorial_1f.h @@ -84,7 +84,7 @@ static inline void activeMessageGroupCollective() { if (my_node == 1) { auto msg = makeMessage(); envelopeSetGroup(msg->env, group_id); - theMsg()->broadcastMsg(msg); + theMsg()->broadcastMsg(msg); } } ); diff --git a/tutorial/tutorial_1g.h b/tutorial/tutorial_1g.h index 4ba5ddc263..7379d165cf 100644 --- a/tutorial/tutorial_1g.h +++ b/tutorial/tutorial_1g.h @@ -113,21 +113,21 @@ static inline void activeMessageCallback() { { auto cb = ::vt::theCB()->makeFunc(vt::pipe::LifetimeEnum::Once, void_fn); auto msg = ::vt::makeMessage(cb); - ::vt::theMsg()->sendMsg(to_node, msg); + ::vt::theMsg()->sendMsg(to_node, msg); } // Example of active message handler callback with send node { auto cb = ::vt::theCB()->makeSend(cb_node); auto msg = ::vt::makeMessage(cb); - ::vt::theMsg()->sendMsg(to_node, msg); + ::vt::theMsg()->sendMsg(to_node, msg); } // Example of active message handler callback with broadcast { auto cb = ::vt::theCB()->makeBcast(); auto msg = ::vt::makeMessage(cb); - ::vt::theMsg()->sendMsg(to_node, msg); + ::vt::theMsg()->sendMsg(to_node, msg); } // Example of context callback @@ -136,7 +136,7 @@ static inline void activeMessageCallback() { vt::pipe::LifetimeEnum::Once, &ctx, callbackCtx ); auto msg = ::vt::makeMessage(cb); - ::vt::theMsg()->sendMsg(to_node, msg); + ::vt::theMsg()->sendMsg(to_node, msg); } } } diff --git a/tutorial/tutorial_3a.h b/tutorial/tutorial_3a.h index c1b37536f3..346b2e553e 100644 --- a/tutorial/tutorial_3a.h +++ b/tutorial/tutorial_3a.h @@ -78,7 +78,7 @@ static inline void activeMessageTerm() { if (this_node == 0) { auto msg = vt::makeMessage(8); envelopeSetEpoch(msg->env, new_epoch); - vt::theMsg()->sendMsg(this_node+1, msg); + vt::theMsg()->sendMsg(this_node+1, msg); } // Any node that wishes to have a notification on termination for a given @@ -116,7 +116,7 @@ static void recurHandler(ExampleMsg* msg) { ); auto msg_send = vt::makeMessage(msg->ttl); - vt::theMsg()->sendMsg(next_node, msg_send); + vt::theMsg()->sendMsg(next_node, msg_send); } } }