Merge remote-tracking branch 'origin/master' into add_hdf5_reader

This commit is contained in:
Oliver Ruebel 2022-09-20 00:07:40 -07:00
commit b0952365f6
508 changed files with 13844 additions and 13229 deletions

@ -106,7 +106,7 @@
- .docker_image
.ubuntu2004_hip_kokkos: &ubuntu2004_hip_kokkos
image: "kitware/vtkm:ci-ubuntu2004_hip_kokkos-20210827"
image: "kitware/vtkm:ci-ubuntu2004_hip_kokkos-20220620"
extends:
- .docker_image
@ -126,9 +126,9 @@
when: on_success
- when: never
.run_master: &run_master
.run_upstream_branches: &run_upstream_branches
rules:
- if: '$CI_PROJECT_PATH == "vtk/vtk-m" && $CI_COMMIT_BRANCH == "master"'
- if: '$CI_PROJECT_PATH == "vtk/vtk-m" && $CI_MERGE_REQUEST_ID == null'
when: on_success
- when: never
@ -164,8 +164,9 @@ stages:
interruptible: true
before_script:
- *install_cmake
- .gitlab/ci/config/sccache.sh
- "cmake -VV -P .gitlab/ci/config/ninja.cmake"
- export PATH=$PWD/.gitlab:$PATH
- .gitlab/ci/config/sccache.sh
- SCCACHE_IDLE_TIMEOUT=0 sccache --start-server
- sccache --show-stats
- .gitlab/ci/config/google_benchmarks.sh
@ -185,6 +186,8 @@ stages:
interruptible: true
before_script:
- *install_cmake
- "cmake -VV -P .gitlab/ci/config/ninja.cmake"
- export PATH=$PWD/.gitlab:$PATH
script:
- "ctest $CTEST_TIMEOUT -VV -S .gitlab/ci/ctest_test.cmake"
extends:
@ -246,12 +249,13 @@ stages:
include:
- local: '/.gitlab/ci/ascent.yml'
- local: '/.gitlab/ci/centos7.yml'
- local: '/.gitlab/ci/centos8.yml'
- local: '/.gitlab/ci/doxygen.yml'
- local: '/.gitlab/ci/macos.yml'
- local: '/.gitlab/ci/rhel8.yml'
- local: '/.gitlab/ci/ubuntu1604.yml'
- local: '/.gitlab/ci/ubuntu1804.yml'
- local: '/.gitlab/ci/ubuntu2004.yml'
- local: '/.gitlab/ci/windows10.yml'
- local: '/.gitlab/ci/ascent.yml'

@ -74,14 +74,6 @@ test:ascent_gcc_cuda:
# Tests errors to address due to different env/arch in Ascent
# Refer to issue: https://gitlab.kitware.com/vtk/vtk-m/-/issues/652
CTEST_EXCLUSIONS: >-
UnitTestMathSERIAL
UnitTestMathCUDA
UnitTestSerialDeviceAdapter
UnitTestAverageByKeySERIAL
UnitTestKeysSERIAL
UnitTestWorkletReduceByKeySERIAL
RegressionTestAmrArraysSERIAL
RegressionTestAmrArraysCUDA
before_script:
# Prep the environment

@ -0,0 +1,61 @@
##============================================================================
## Copyright (c) Kitware, Inc.
## All rights reserved.
## See LICENSE.txt for details.
##
## This software is distributed WITHOUT ANY WARRANTY; without even
## the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
## PURPOSE. See the above copyright notice for more information.
##============================================================================
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
set(version 4.6.1)
set(arch x86_64)
if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux")
set(sha256sum da1e1781bc1c4b019216fa16391af3e1daaee7e7f49a8ec9b0cdc8a1d05c50e2)
set(base_url https://github.com/ccache/ccache/releases/download)
set(platform linux)
set(extension tar.xz)
elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
set(sha256sum 3e36ba8c80fbf7f2b95fe0227b9dd1ca6143d721aab052caf0d5729769138059)
set(full_url https://gitlab.kitware.com/utils/ci-utilities/-/package_files/534/download)
set(filename ccache)
set(extension tar.gz)
elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
set(sha256sum a6c6311973aa3d2aae22424895f2f968e5d661be003b25f1bd854a5c0cd57563)
set(base_url https://github.com/ccache/ccache/releases/download)
set(platform windows)
set(extension zip)
else()
message(FATAL_ERROR "Unrecognized platform ${CMAKE_HOST_SYSTEM_NAME}")
endif()
if(NOT DEFINED filename)
set(filename "ccache-${version}-${platform}-${arch}")
endif()
set(tarball "${filename}.${extension}")
if(NOT DEFINED full_url)
set(full_url "${base_url}/v${version}/${tarball}")
endif()
file(DOWNLOAD
"${full_url}" .gitlab/${tarball}
EXPECTED_HASH SHA256=${sha256sum}
SHOW_PROGRESS
)
execute_process(
COMMAND ${CMAKE_COMMAND} -E tar xf ${tarball}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/.gitlab
RESULT_VARIABLE extract_results
)
if(extract_results)
message(FATAL_ERROR "Extracting `${tarball}` failed: ${extract_results}.")
endif()
file(RENAME .gitlab/${filename} .gitlab/ccache)

@ -5,28 +5,27 @@ set -x
version="${1:-3.21.1}"
# We require CMake >= 3.13 in the CI to support CUDA builds
readonly -A linuxParamsByVersion=(
['3.13.5']='e2fd0080a6f0fc1ec84647acdcd8e0b4019770f48d83509e6a5b0b6ea27e5864 Linux'
['3.21.1']='bf496ce869d0aa8c1f57e4d1a2e50c8f2fb12a6cd7ccb37ad743bb88f6b76a1e linux'
)
if [ -z "${linuxParamsByVersion[$version]}" ]
then
echo "Given version ($version) is unsupported"
exit 1
fi
case "$( uname -s )" in
Linux)
shatool="sha256sum"
# We require CMake >= 3.13 in the CI to support CUDA builds
readonly -A linuxParamsByVersion=(
['3.13.5']='e2fd0080a6f0fc1ec84647acdcd8e0b4019770f48d83509e6a5b0b6ea27e5864 Linux'
['3.21.1']='bf496ce869d0aa8c1f57e4d1a2e50c8f2fb12a6cd7ccb37ad743bb88f6b76a1e linux'
)
if [ -z "${linuxParamsByVersion[$version]}" ]
then
echo "Given version ($version) is unsupported"
exit 1
fi
sha256sum=$(cut -f 1 <<<"${linuxParamsByVersion[$version]}")
platform=$(cut -f 2 <<<"${linuxParamsByVersion[$version]}")
arch="x86_64"
;;
Darwin)
shatool="shasum -a 256"
sha256sum="20dbede1d80c1ac80be2966172f8838c3d899951ac4467372f806b386d42ad3c"
sha256sum="9dc2978c4d94a44f71336fa88c15bb0eee47cf44b6ece51b10d1dfae95f82279"
platform="macos"
arch="universal"
;;

@ -101,7 +101,11 @@ foreach(option IN LISTS options)
# From turing we set the architecture using the cannonical
# CMAKE_CUDA_ARCHITECTURES
elseif(turing STREQUAL option)
set(CMAKE_CUDA_ARCHITECTURES "75" CACHE STRING "")
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.18)
set(CMAKE_CUDA_ARCHITECTURES "75" CACHE STRING "")
else()
set(VTKm_CUDA_Architecture "turing" CACHE STRING "")
endif()
elseif(hip STREQUAL option)
if(CMAKE_VERSION VERSION_LESS_EQUAL 3.20)
@ -140,6 +144,9 @@ foreach(option IN LISTS options)
if(VTKm_ENABLE_CUDA)
set(CMAKE_CUDA_COMPILER_LAUNCHER "${CCACHE_COMMAND}" CACHE STRING "")
endif()
if(VTKm_ENABLE_KOKKOS_HIP)
set(CMAKE_HIP_COMPILER_LAUNCHER "${CCACHE_COMMAND}" CACHE STRING "")
endif()
else()
message(FATAL_ERROR "CCACHE version [${CCACHE_VERSION}] is <= 4")
endif()
@ -161,10 +168,6 @@ if(SCCACHE_COMMAND)
set(CMAKE_C_COMPILER_LAUNCHER "${SCCACHE_COMMAND}" CACHE STRING "")
set(CMAKE_CXX_COMPILER_LAUNCHER "${SCCACHE_COMMAND}" CACHE STRING "")
if(DEFINED VTKm_ENABLE_KOKKOS_HIP)
set(CMAKE_HIP_COMPILER_LAUNCHER "${SCCACHE_COMMAND}" CACHE STRING "")
endif()
# Use VTKm_CUDA_Architecture to determine if we need CUDA sccache setup
# since this will also capture when kokkos is being used with CUDA backing
if(DEFINED VTKm_CUDA_Architecture OR DEFINED CMAKE_CUDA_ARCHITECTURES)

@ -0,0 +1,44 @@
##============================================================================
## Copyright (c) Kitware, Inc.
## All rights reserved.
## See LICENSE.txt for details.
##
## This software is distributed WITHOUT ANY WARRANTY; without even
## the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
## PURPOSE. See the above copyright notice for more information.
##============================================================================
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
set(version 1.11.0)
if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux")
set(sha256sum 9726e730d5b8599f82654dc80265e64a10a8a817552c34153361ed0c017f9f02)
set(platform linux)
elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
set(sha256sum 21915277db59756bfc61f6f281c1f5e3897760b63776fd3d360f77dd7364137f)
set(platform mac)
elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
set(sha256sum d0ee3da143211aa447e750085876c9b9d7bcdd637ab5b2c5b41349c617f22f3b)
set(platform win)
else()
message(FATAL_ERROR "Unrecognized platform ${CMAKE_HOST_SYSTEM_NAME}")
endif()
set(tarball "ninja-${platform}.zip")
file(DOWNLOAD
"https://github.com/ninja-build/ninja/releases/download/v${version}/${tarball}" .gitlab/${tarball}
EXPECTED_HASH SHA256=${sha256sum}
SHOW_PROGRESS
)
execute_process(
COMMAND ${CMAKE_COMMAND} -E tar xf ${tarball}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/.gitlab
RESULT_VARIABLE extract_results
)
if(extract_results)
message(FATAL_ERROR "Extracting `${tarball}` failed: ${extract_results}.")
endif()

@ -2,24 +2,35 @@ FROM rocm/dev-ubuntu-20.04
LABEL maintainer "Vicente Adolfo Bolea Sanchez<vicente.bolea@kitware.com>"
# Base dependencies for building VTK-m projects
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
cmake \
curl \
g++ \
git \
git-lfs \
libmpich-dev \
libomp-dev \
mpich \
ninja-build \
rsync \
ssh \
software-properties-common
RUN apt update && \
DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends \
curl \
g++ \
git \
git-lfs \
libmpich-dev \
libomp-dev \
mpich \
ninja-build \
rsync \
ssh \
&& \
apt clean
# Need to run git-lfs install manually on ubuntu based images when using the
# system packaged version
RUN git-lfs install
# Provide CCACHE
ENV CCACHE_DIR "/ccache"
ENV PATH "/opt/ccache/bin:${PATH}"
ARG CCACHE_VERSION=4.6.1
RUN mkdir /opt/ccache/ && \
curl -L https://github.com/ccache/ccache/releases/download/v$CCACHE_VERSION/ccache-$CCACHE_VERSION-linux-x86_64.tar.xz | tar -vxJ && \
make -C ccache-$CCACHE_VERSION-linux-x86_64 install prefix=/opt/ccache && \
rm -rf ccache-$CCACHE_VERSION-linux-x86_64 && \
ccache -z && ccache -s
# Provide CMake
ARG CMAKE_VERSION=3.21.1
RUN mkdir /opt/cmake/ && \
@ -33,11 +44,10 @@ ENV CMAKE_PREFIX_PATH "/opt/rocm/lib/cmake:/opt/rocm/lib:${CMAKE_PREFIX_PATH}"
ENV CMAKE_GENERATOR "Ninja"
# Build and install Kokkos
ARG KOKKOS_VERSION=3.4.01
ARG KOKKOS_VERSION=3.6.00
COPY kokkos_cmake_config.cmake kokkos_cmake_config.cmake
RUN curl -L https://github.com/kokkos/kokkos/archive/refs/tags/$KOKKOS_VERSION.tar.gz | tar -xzf - && \
cmake -S kokkos-$KOKKOS_VERSION -B build -C kokkos_cmake_config.cmake && \
cmake --build build -v && \
sudo cmake --install build
RUN rm -rf build
cmake -S kokkos-$KOKKOS_VERSION -B build -C kokkos_cmake_config.cmake && \
cmake --build build -v && \
cmake --install build && \
rm -rf build kokkos-$KOKKOS_VERSION

83
.gitlab/ci/macos.yml Normal file

@ -0,0 +1,83 @@
# Ad-hoc build that runs in macos machines
build:macos_xcode13:
extends:
- .macos_xcode13
- .macos_build_tags
- .cmake_build_macos
- .run_automatically
test:macos_xcode13:
extends:
- .macos_xcode13
- .macos_build_tags
- .cmake_test_macos
- .run_automatically
needs:
- build:macos_xcode13
dependencies:
- build:macos_xcode13
.macos_xcode13:
variables:
CMAKE_BUILD_TYPE: RelWithDebInfo
CMAKE_GENERATOR: Ninja
CC: gcc
CXX: g++
DEVELOPER_DIR: "/Applications/Xcode-13.3.app/Contents/Developer"
VTKM_SETTINGS: "64bit_floats+shared+ccache"
.cmake_build_macos:
stage: build
interruptible: true
variables:
CCACHE_BASEDIR: "$CI_PROJECT_DIR"
CCACHE_DIR: "$CI_PROJECT_DIR/ccache"
# -isystem= is not affected by CCACHE_BASEDIR, thus we must ignore it
CCACHE_IGNOREOPTIONS: "-isystem=*"
CCACHE_COMPILERCHECK: "content"
CCACHE_NOHASHDIR: "true"
CCACHE_RESHARE: "true"
before_script:
- .gitlab/ci/config/cmake.sh
- export PATH=$PWD/.gitlab/cmake/bin:$PATH
- "cmake -VV -P .gitlab/ci/config/ccache.cmake"
- export PATH=$PWD/.gitlab/ccache:$PATH
- "cmake -VV -P .gitlab/ci/config/ninja.cmake"
- export PATH=$PWD/.gitlab:$PATH
- "cmake --version"
- "ccache --version"
- "ninja --version"
- "cmake -V -P .gitlab/ci/config/fetch_vtkm_tags.cmake"
- "cmake -V -P .gitlab/ci/config/gitlab_ci_setup.cmake"
- "ctest -VV -S .gitlab/ci/ctest_configure.cmake"
script:
- "ctest -VV -S .gitlab/ci/ctest_build.cmake"
after_script:
- ccache -v -s
- ccache -z
extends:
- .cmake_build_artifacts
.cmake_test_macos:
stage: test
interruptible: true
before_script:
- .gitlab/ci/config/cmake.sh
- export PATH=.gitlab/cmake/bin:$PATH
- "cmake -VV -P .gitlab/ci/config/ninja.cmake"
- export PATH=$PWD/.gitlab:$PATH
- cmake --version
- ninja --version
script:
- "ctest $CTEST_TIMEOUT -VV -S .gitlab/ci/ctest_test.cmake"
extends:
- .cmake_test_artifacts
.macos_build_tags:
tags:
- vtk-m
- macos
- xcode-13.3
- nonconcurrent

@ -50,7 +50,7 @@ build:ubuntu1604_gcc5_2:
extends:
- .ubuntu1604_cuda
- .cmake_build_linux
- .run_master
- .run_upstream_branches
- .use_minimum_supported_cmake
variables:
CC: "gcc-5"
@ -69,7 +69,7 @@ test:ubuntu1804_test_ubuntu1604_gcc5_2:
extends:
- .ubuntu1804_cuda
- .cmake_test_linux
- .run_master
- .run_upstream_branches
variables:
CTEST_EXCLUSIONS: "built_against_test_install"
dependencies:

@ -91,7 +91,7 @@ build:ubuntu1804_clang_cuda:
- .ubuntu1804_cuda
- .cmake_build_linux
- .run_automatically
# - .run_master
# - .run_upstream_branches
variables:
CC: "clang-8"
CXX: "clang++-8"
@ -110,7 +110,7 @@ test:ubuntu1804_clang_cuda:
- .ubuntu1804_cuda
- .cmake_test_linux
- .run_automatically
# - .run_master
# - .run_upstream_branches
dependencies:
- build:ubuntu1804_clang_cuda
needs:

@ -69,13 +69,23 @@ build:ubuntu2004_hip_kokkos:
extends:
- .ubuntu2004_hip_kokkos
- .cmake_build_linux
- .run_scheduled
- .run_upstream_branches
variables:
CMAKE_BUILD_TYPE: RelWithDebInfo
VTKM_SETTINGS: "benchmarks+kokkos+hip+no_virtual+no_rendering"
VTKM_SETTINGS: "benchmarks+kokkos+hip+no_virtual+no_rendering+ccache"
CMAKE_PREFIX_PATH: "/opt/rocm/lib/cmake"
CTEST_MAX_PARALLELISM: "1"
timeout: 12 hours
CCACHE_BASEDIR: "$CI_PROJECT_DIR"
# -isystem= is not affected by CCACHE_BASEDIR, thus we must ignore it
CCACHE_IGNOREOPTIONS: "-isystem=*"
CCACHE_COMPILERCHECK: "content"
CCACHE_NOHASHDIR: "true"
CCACHE_RESHARE: "true"
after_script:
- ccache -v -s
- ccache -z
timeout: 10 hours
test:ubuntu2004_hip_kokkos:
tags:
@ -86,7 +96,7 @@ test:ubuntu2004_hip_kokkos:
extends:
- .ubuntu2004_hip_kokkos
- .cmake_test_linux
- .run_scheduled
- .run_upstream_branches
variables:
CTEST_TIMEOUT: "30"
dependencies:

@ -29,8 +29,12 @@
- Invoke-Expression -Command .gitlab/ci/config/cmake.ps1
- Invoke-Expression -Command .gitlab/ci/config/vcvarsall.ps1
- $pwdpath = $pwd.Path
- Set-Item -Force -Path "env:PATH" -Value "$pwdpath\.gitlab;$pwdpath\.gitlab\cmake\bin;$env:PATH"
- Set-Item -Force -Path "env:PATH" -Value "$pwdpath\.gitlab\cmake\bin;$env:PATH"
- "cmake --version"
- "cmake -V -P .gitlab/ci/config/ccache.cmake"
- Set-Item -Force -Path "env:PATH" -Value "$pwdpath\.gitlab\ccache;$env:PATH"
- "cmake -V -P .gitlab/ci/config/ninja.cmake"
- Set-Item -Force -Path "env:PATH" -Value "$pwdpath\.gitlab;$env:PATH"
- "cmake -V -P .gitlab/ci/config/gitlab_ci_setup.cmake"
- "ctest -VV -S .gitlab/ci/ctest_configure.cmake"
script:
@ -67,7 +71,10 @@
- Invoke-Expression -Command .gitlab/ci/config/cmake.ps1
- Invoke-Expression -Command .gitlab/ci/config/vcvarsall.ps1
- $pwdpath = $pwd.Path
- Set-Item -Force -Path "env:PATH" -Value "$pwdpath\.gitlab;$pwdpath\.gitlab\cmake\bin;$env:PATH"
- Set-Item -Force -Path "env:PATH" -Value "$pwdpath\.gitlab\cmake\bin;$env:PATH"
- "cmake --version"
- "cmake -V -P .gitlab/ci/config/ninja.cmake"
- Set-Item -Force -Path "env:PATH" -Value "$pwdpath\.gitlab;$env:PATH"
script:
- "ctest -VV -S .gitlab/ci/ctest_test.cmake"

@ -21,31 +21,44 @@ git submodule update --recursive --init
## Create update branch
- [ ] Create update branch `git checkout -b update-to-v@VERSION@`
<!-- if @RC@ == "-rc1"
<!-- if @RC@ == "-rc1"-->
- [ ] Bring as a second parent the history of master (Solve conflicts always
taking master's version)
```
git merge --no-ff origin/master
```
-->
<!-- endif -->
<!-- Do we have new release notes?
<!-- if not a patch release -->
- [ ] Update the major and minor version in `version.txt`:
```
echo "@MAJOR@.@MINOR@.9999" > version.txt
git add version.txt`
```
<!-- endif -->
- [ ] Update the version (not in patch releases) and date in the LICENSE.md
file `git add LICENSE.md`.
- [ ] Create commit that updates the License (and version.txt if modified):
```
git commit -m 'release: update version and License'
```
<!-- Do we have new release notes? -->
- [ ] Craft or update [changelog](#generate-change-log)
`docs/changelog/@VERSION@/release-notes.md` file.
- [ ] Create release notes commit.
```
git add docs/changelog/@VERSION@/release-notes.md
git rm docs/changelog/*.md
git commit -m 'Add release notes for @VERSION@@RC@'
git commit -m 'release: @VERSION@@RC@ release notes'
```
-->
- [ ] Update the version (not in patch releases) and date in the LICENSE.md
file `git add LICENSE.md`.
<!-- endif -->
- [ ] Create update version commit:
```
echo @VERSION@@RC@ > version.txt
git add version.txt
# Create commit with the following template
# Nth is counted by the number of final release tags
@ -59,6 +72,13 @@ The major changes to VTK-m from (previous release) can be found in:
- Integrate changes to `release` branch
- [ ] Create a MR using the [release-mr script][1]
(see [notes](#notes-about-update-mr)).
<!-- if not patch release -->
- [ ] Add (or ensure) at the bottom of the description of the merge request:
`Backport: master:HEAD~1`
<!-- elseif patch release -->
- [ ] Remove (or ensure) that at the bottom of the description of the merge
request there is no `Backport` instruction.
<!-- endif -->
- [ ] Get +1
- [ ] `Do: merge`
- Push tags
@ -74,6 +94,10 @@ The major changes to VTK-m from (previous release) can be found in:
- [ ] Tag new version of the [VTK-m User Guide][2].
<!-- endif -->
- [ ] Post an [Email Announcements](#email-announcements) VTK-m mailing list.
<!-- if not patch release -->
- [ ] Ensure that the content of `version.txt` in master is
`[@MAJOR@ @MINOR@](@MAJOR@.@MINOR@.9999)`.
<!-- endif release -->
---
@ -155,6 +179,16 @@ to the relevant `release-notes` section.
Lastly, `update-mr` can be used multiple times with different commit in the same
branch.
## Notes about version.txt
Master and release branch do not share the same version.txt scheme. In the
release branch the patch and release-candidate version is observed whereas in
master the patch field is fixed to _9999_ indicating that each of its commit is
a developing release.
- Master: `@MAJOR@.@MINOR@.9999`
- Release: `@MAJOR@.@MINOR@.@PATCH@@RC@`
## Email Announcements
Announce the new VTK-m release on the mailing list. You will need to compute

@ -70,32 +70,29 @@
# Use TBBConfig.cmake if possible.
# Disabling this as it running the TBBConfig.cmake on dragnipur is
# causing a CMake error. I don't know if this is an install problem
# or an issue with version 2018.0.
# set(_tbb_find_quiet)
# if (TBB_FIND_QUIETLY)
# set(_tbb_find_quiet QUIET)
# endif ()
# set(_tbb_find_components)
# set(_tbb_find_optional_components)
# foreach (_tbb_find_component IN LISTS TBB_FIND_COMPONENTS)
# if (TBB_FIND_REQUIRED_${_tbb_find_component})
# list(APPEND _tbb_find_components "${_tbb_find_component}")
# else ()
# list(APPEND _tbb_find_optional_components "${_tbb_find_component}")
# endif ()
# endforeach ()
# unset(_tbb_find_component)
# find_package(TBB CONFIG ${_tbb_find_quiet}
# COMPONENTS ${_tbb_find_components}
# OPTIONAL_COMPONENTS ${_tbb_find_optional_components})
# unset(_tbb_find_quiet)
# unset(_tbb_find_components)
# unset(_tbb_find_optional_components)
# if (TBB_FOUND)
# return ()
# endif ()
set(_tbb_find_quiet)
if (TBB_FIND_QUIETLY)
set(_tbb_find_quiet QUIET)
endif ()
set(_tbb_find_components)
set(_tbb_find_optional_components)
foreach (_tbb_find_component IN LISTS TBB_FIND_COMPONENTS)
if (TBB_FIND_REQUIRED_${_tbb_find_component})
list(APPEND _tbb_find_components "${_tbb_find_component}")
else ()
list(APPEND _tbb_find_optional_components "${_tbb_find_component}")
endif ()
endforeach ()
unset(_tbb_find_component)
find_package(TBB CONFIG ${_tbb_find_quiet}
COMPONENTS ${_tbb_find_components}
OPTIONAL_COMPONENTS ${_tbb_find_optional_components})
unset(_tbb_find_quiet)
unset(_tbb_find_components)
unset(_tbb_find_optional_components)
if (TBB_FOUND)
return ()
endif ()
#====================================================
# Fix the library path in case it is a linker script

@ -42,7 +42,11 @@ function(vtkm_extract_real_library library real_library)
endfunction()
if(VTKm_ENABLE_TBB AND NOT TARGET vtkm::tbb)
find_package(TBB REQUIRED)
# Skip find_package(TBB) if we already have it
if (NOT TARGET TBB::tbb)
find_package(TBB REQUIRED)
endif()
add_library(vtkmTBB INTERFACE)
add_library(vtkm::tbb ALIAS vtkmTBB)
target_link_libraries(vtkmTBB INTERFACE TBB::tbb)

@ -114,6 +114,8 @@ function(do_verify root_dir prefix)
set(file_exceptions
thirdparty/diy/vtkmdiy/cmake/mpi_types.h
thirdparty/lodepng/vtkmlodepng/lodepng.h
thirdparty/loguru/vtkmloguru/loguru.hpp
# Ignore deprecated virtual classes (which are not installed if VTKm_NO_DEPRECATED_VIRTUAL
# is on). These exceptions can be removed when these files are completely removed.

@ -13,11 +13,11 @@ include(VTKmWrappers)
function(vtkm_create_test_executable
prog_name
sources
device_sources
libraries
defines
is_mpi_test
use_mpi
enable_all_backends
use_job_pool)
vtkm_diy_use_mpi_push()
@ -41,23 +41,12 @@ function(vtkm_create_test_executable
#the creation of the test source list needs to occur before the labeling as
#cuda. This is so that we get the correctly named entry points generated
create_test_sourcelist(test_sources ${prog}.cxx ${sources} ${extraArgs})
create_test_sourcelist(test_sources ${prog}.cxx ${sources} ${device_sources} ${extraArgs})
add_executable(${prog} ${prog}.cxx ${sources})
add_executable(${prog} ${test_sources})
vtkm_add_drop_unused_function_flags(${prog})
target_compile_definitions(${prog} PRIVATE ${defines})
#determine if we have a device that requires a separate compiler enabled
set(device_lang_enabled FALSE)
if( (TARGET vtkm::cuda) OR (TARGET vtkm::kokkos_cuda) OR (TARGET vtkm::kokkos_hip))
set(device_lang_enabled TRUE)
endif()
#if all backends are enabled, we can use the device compiler to handle all possible backends.
set(device_sources)
if(device_lang_enabled AND (enable_all_backends OR (TARGET vtkm::kokkos_hip)))
set(device_sources ${sources})
endif()
vtkm_add_target_information(${prog} DEVICE_SOURCES ${device_sources})
if(NOT VTKm_USE_DEFAULT_SYMBOL_VISIBILITY)
@ -83,68 +72,89 @@ endfunction()
# (package, module, whatever you call it). Usage:
#
# vtkm_unit_tests(
# NAME
# [ NAME <name> ]
# SOURCES <source_list>
# LIBRARIES <dependent_library_list>
# DEFINES <target_compile_definitions>
# TEST_ARGS <argument_list>
# MPI
# ALL_BACKENDS
# USE_VTKM_JOB_POOL
# <options>
# [ DEVICE_SOURCES <source_list> ]
# [ LIBRARIES <dependent_library_list> ]
# [ DEFINES <target_compile_definitions> ]
# [ TEST_ARGS <argument_list> ]
# [ MPI ]
# [ BACKEND <device> ]
# [ ALL_BACKENDS ]
# [ USE_VTKM_JOB_POOL ]
# )
#
# [LIBRARIES] : extra libraries that this set of tests need to link too
# NAME : Specify the name of the testing executable. If not specified,
# UnitTests_<kitname> is used.
#
# [DEFINES] : extra defines that need to be set for all unit test sources
# SOURCES: A list of the source files. Each file is expected to contain a
# function with the same name as the source file. For example, if SOURCES
# contains `UnitTestFoo.cxx`, then `UnitTestFoo.cxx` should contain a
# function named `UnitTestFoo`. A test with this name is also added to ctest.
#
# [LABEL] : CTest Label to associate to this set of tests
# LIBRARIES: Extra libraries that this set of tests need to link to.
#
# [TEST_ARGS] : arguments that should be passed on the command line to the
# test executable
# DEFINES: Extra defines to be set for all unit test sources.
#
# [MPI] : when specified, the tests should be run in parallel if
# MPI is enabled. The tests should also be able to build and run
# When MPI is not available, i.e., they should not make explicit
# use of MPI and instead completely rely on DIY.
# [ALL_BACKENDS] : when specified, the tests would test against all enabled
# backends. Otherwise we expect the tests to manage the
# backends at runtime.
# TEST_ARGS: Arguments that should be passed on the command line to the
# test executable when executed by ctest.
#
# MPI: When specified, the tests should be run in parallel if MPI is enabled.
# The tests should also be able to build and run when MPI is not available,
# i.e., they should not make explicit use of MPI and instead completely rely
# on DIY.
#
# BACKEND: When used, a specific backend will be forced for the device.
# A `--vtkm-device` flag will be given to the command line argument with the
# specified device. When not used, a backend will be chosen.
#
# ALL_BACKENDS: When used, a separate ctest test is created for each device
# that VTK-m is compiled for. The call will add the `--vtkm-device` flag when
# running the test to force the test for a particular backend.
#
function(vtkm_unit_tests)
set(options)
set(global_options ${options} USE_VTKM_JOB_POOL MPI ALL_BACKENDS)
set(oneValueArgs BACKEND NAME LABEL)
set(multiValueArgs SOURCES LIBRARIES DEFINES TEST_ARGS)
set(multiValueArgs SOURCES DEVICE_SOURCES LIBRARIES DEFINES TEST_ARGS)
cmake_parse_arguments(VTKm_UT
"${global_options}" "${oneValueArgs}" "${multiValueArgs}"
${ARGN}
)
vtkm_parse_test_options(VTKm_UT_SOURCES "${options}" ${VTKm_UT_SOURCES})
set(per_device_command_line_arguments "NONE")
set(per_device_suffix "")
set(per_device_timeout 180)
set(per_device_serial FALSE)
set(per_device_command_line_arguments)
set(per_device_suffix)
set(per_device_timeout)
set(per_device_serial)
set(enable_all_backends ${VTKm_UT_ALL_BACKENDS})
if(enable_all_backends)
set(per_device_command_line_arguments --vtkm-device=serial)
set(per_device_suffix "SERIAL")
if (VTKm_ENABLE_CUDA)
if(NOT VTKm_UT_BACKEND)
set(enable_all_backends ${VTKm_UT_ALL_BACKENDS})
# If ALL_BACKENDS is specified, add a test for each backend. If it is not
# specified, pick a backend to use. Pick the most "specific" backend so
# that different CI builds will use different backends. This ensures that
# we do not have a test that always drops down to serial.
if(VTKm_ENABLE_CUDA AND (enable_all_backends OR NOT per_device_suffix))
list(APPEND per_device_command_line_arguments --vtkm-device=cuda)
list(APPEND per_device_suffix "CUDA")
#CUDA tests generally require more time because of kernel generation.
list(APPEND per_device_timeout 1500)
list(APPEND per_device_serial FALSE)
endif()
if (VTKm_ENABLE_TBB)
if(VTKm_ENABLE_KOKKOS AND (enable_all_backends OR NOT per_device_suffix))
list(APPEND per_device_command_line_arguments --vtkm-device=kokkos)
list(APPEND per_device_suffix "KOKKOS")
#may require more time because of kernel generation.
list(APPEND per_device_timeout 1500)
list(APPEND per_device_serial FALSE)
endif()
if(VTKm_ENABLE_TBB AND (enable_all_backends OR NOT per_device_suffix))
list(APPEND per_device_command_line_arguments --vtkm-device=tbb)
list(APPEND per_device_suffix "TBB")
list(APPEND per_device_timeout 180)
list(APPEND per_device_serial FALSE)
endif()
if (VTKm_ENABLE_OPENMP)
if(VTKm_ENABLE_OPENMP AND (enable_all_backends OR NOT per_device_suffix))
list(APPEND per_device_command_line_arguments --vtkm-device=openmp)
list(APPEND per_device_suffix "OPENMP")
list(APPEND per_device_timeout 180)
@ -154,13 +164,26 @@ function(vtkm_unit_tests)
#serially
list(APPEND per_device_serial TRUE)
endif()
if (VTKm_ENABLE_KOKKOS)
list(APPEND per_device_command_line_arguments --vtkm-device=kokkos)
list(APPEND per_device_suffix "KOKKOS")
#may require more time because of kernel generation.
list(APPEND per_device_timeout 1500)
if(enable_all_backends OR NOT per_device_suffix)
list(APPEND per_device_command_line_arguments --vtkm-device=serial)
list(APPEND per_device_suffix "SERIAL")
list(APPEND per_device_timeout 180)
list(APPEND per_device_serial FALSE)
endif()
if(NOT enable_all_backends)
# If not enabling all backends, exactly one backend should have been added.
list(LENGTH per_device_suffix number_of_devices)
if(NOT number_of_devices EQUAL 1)
message(FATAL_ERROR "Expected to pick one backend")
endif()
endif()
else()
# A specific backend was requested.
set(per_device_command_line_arguments --vtkm-device=${VTKm_UT_BACKEND})
set(per_device_suffix ${VTKm_UT_BACKEND})
set(per_device_timeout 180)
# Some devices don't like multiple tests run at the same time.
set(per_device_serial TRUE)
endif()
set(test_prog)
@ -188,33 +211,33 @@ function(vtkm_unit_tests)
vtkm_create_test_executable(
${test_prog}
"${VTKm_UT_SOURCES}"
"${VTKm_UT_DEVICE_SOURCES}"
"${VTKm_UT_LIBRARIES}"
"${VTKm_UT_DEFINES}"
ON # is_mpi_test
ON # use_mpi
${enable_all_backends}
${VTKm_UT_USE_VTKM_JOB_POOL})
endif()
if ((NOT VTKm_ENABLE_MPI) OR VTKm_ENABLE_DIY_NOMPI)
vtkm_create_test_executable(
${test_prog}
"${VTKm_UT_SOURCES}"
"${VTKm_UT_DEVICE_SOURCES}"
"${VTKm_UT_LIBRARIES}"
"${VTKm_UT_DEFINES}"
ON # is_mpi_test
OFF # use_mpi
${enable_all_backends}
${VTKm_UT_USE_VTKM_JOB_POOL})
endif()
else()
vtkm_create_test_executable(
${test_prog}
"${VTKm_UT_SOURCES}"
"${VTKm_UT_DEVICE_SOURCES}"
"${VTKm_UT_LIBRARIES}"
"${VTKm_UT_DEFINES}"
OFF # is_mpi_test
OFF # use_mpi
${enable_all_backends}
${VTKm_UT_USE_VTKM_JOB_POOL})
endif()
@ -225,19 +248,16 @@ function(vtkm_unit_tests)
#exclusive on the end ( e.g. for(i=0; i < n; ++i))
break()
endif()
if(per_device_command_line_arguments STREQUAL "NONE")
set(device_command_line_argument)
set(upper_backend ${per_device_suffix})
set(timeout ${per_device_timeout})
set(run_serial ${per_device_serial})
else()
list(GET per_device_command_line_arguments ${index} device_command_line_argument)
if(enable_all_backends)
list(GET per_device_suffix ${index} upper_backend)
list(GET per_device_timeout ${index} timeout)
list(GET per_device_serial ${index} run_serial)
else()
set(upper_backend)
endif()
list(GET per_device_command_line_arguments ${index} device_command_line_argument)
list(GET per_device_timeout ${index} timeout)
list(GET per_device_serial ${index} run_serial)
foreach (test ${VTKm_UT_SOURCES})
foreach (test ${VTKm_UT_SOURCES} ${VTKm_UT_DEVICE_SOURCES})
get_filename_component(tname ${test} NAME_WE)
if(VTKm_UT_MPI)
if (VTKm_ENABLE_MPI)

@ -413,7 +413,7 @@ extend or revise the topic.
2. Get the new version from gitlab
$ git gitlab-sync -f
$ git gitlab-sync
If you do not wish to have the "Kitware Robot" automatically reformat your

@ -14,7 +14,10 @@
#include <sstream>
#include <vtkm/ImplicitFunction.h>
#include <vtkm/Particle.h>
#include <vtkm/cont/Algorithm.h>
#include <vtkm/cont/ArrayCopy.h>
#include <vtkm/cont/BoundsCompute.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/cont/FieldRangeCompute.h>
@ -25,9 +28,9 @@
#include <vtkm/cont/internal/OptionParser.h>
#include <vtkm/filter/Streamline.h>
#include <vtkm/filter/contour/Contour.h>
#include <vtkm/filter/contour/Slice.h>
#include <vtkm/filter/flow/Streamline.h>
#include <vtkm/filter/geometry_refinement/Tetrahedralize.h>
#include <vtkm/filter/geometry_refinement/Tube.h>
#include <vtkm/filter/vector_analysis/Gradient.h>
@ -423,7 +426,7 @@ void AddField(vtkm::cont::PartitionedDataSet& input,
}
template <typename DataSetType>
DataSetType RunStreamlinesHelper(vtkm::filter::Streamline& filter, const DataSetType& input)
DataSetType RunStreamlinesHelper(vtkm::filter::flow::Streamline& filter, const DataSetType& input)
{
auto dataSetBounds = vtkm::cont::BoundsCompute(input);
vtkm::cont::ArrayHandle<vtkm::Particle> seedArray;
@ -457,7 +460,7 @@ void BenchStreamlines(::benchmark::State& state)
BuildInputDataSet(cycle, isStructured, isMultiBlock, DataSetDim);
inputGenTimer.Stop();
vtkm::filter::Streamline streamline;
vtkm::filter::flow::Streamline streamline;
streamline.SetStepSize(0.1f);
streamline.SetNumberOfSteps(1000);
streamline.SetActiveField(PointVectorsName);

@ -10,17 +10,14 @@
#include "Benchmarker.h"
#include <vtkm/Particle.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/cont/DataSetBuilderUniform.h>
#include <vtkm/cont/ErrorInternal.h>
#include <vtkm/cont/Logging.h>
#include <vtkm/cont/RuntimeDeviceTracker.h>
#include <vtkm/cont/Timer.h>
#include <vtkm/cont/internal/OptionParser.h>
#include <vtkm/filter/ParticleAdvection.h>
#include <vtkm/worklet/particleadvection/EulerIntegrator.h>
#include <vtkm/worklet/particleadvection/RK4Integrator.h>
#include <vtkm/filter/flow/ParticleAdvection.h>
namespace
{
@ -50,7 +47,7 @@ void BenchParticleAdvection(::benchmark::State& state)
vtkm::Particle(vtkm::Vec3f(.2f, 2.0f, .2f), 1),
vtkm::Particle(vtkm::Vec3f(.2f, 3.0f, .2f), 2) });
vtkm::filter::ParticleAdvection particleAdvection;
vtkm::filter::flow::ParticleAdvection particleAdvection;
particleAdvection.SetStepSize(vtkm::FloatDefault(1) / state.range(0));
particleAdvection.SetNumberOfSteps(static_cast<vtkm::Id>(state.range(0)));

@ -27,6 +27,5 @@ Libs: -L${libdir} \
-lvtkm_worklet-@VTKm_VERSION@ \
-lvtkm_source-@VTKm_VERSION@ \
-lvtkm_io-@VTKm_VERSION@ \
-lvtkm_lodepng-@VTKm_VERSION@ \
-lvtkm_cont-@VTKm_VERSION@ \
-lvtkmdiympi_nompi

@ -34,6 +34,5 @@ VTKm_LIB_FLAGS = -L $(VTKm_DIR)/lib \
-lvtkm_worklet-$(VTKM_VERSION) \
-lvtkm_source-$(VTKM_VERSION) \
-lvtkm_io-$(VTKM_VERSION) \
-lvtkm_lodepng-$(VTKM_VERSION) \
-lvtkm_cont-$(VTKM_VERSION) \
-lvtkmdiympi_nompi

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7a569aff0c6872611ef75a4dcb597e1320cb966b80f840a0dbd76a29b2760dbb
size 50335052

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:671345bdb045aeadc8e9fa1060de51e53286c74929c6c8c60a529b318f02bbfc
size 3795

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6372aec0eb79ee7c99de0e1546ff946dcfac2ea0eb7fb575fddc80decf0a438b
size 572

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a272a8d800bca5bc879d52cb4999562378c5ac108d953634b1dbad7ad07d8c8a
size 1031

23
docs/ReleaseRoadmap.md Normal file

@ -0,0 +1,23 @@
# Minor Release Roadmap
| Version | Date | Delay (days) | Life-cycle (*planned) | End of Support |
| --------- | ------------ | ------- | ----------- | ---------------- |
| 1.7.0 | 2021-12-01 | +8 | Long Term | 2022-12-01 |
| 1.8.0 | 2022-06-01 | +14 | Long Term | 2023-06-01 |
| 1.9.0 | 2022-09-01 | | Short Term* | TBD |
| 2.0.0 | 2022-12-01 | | Long Term* | TBD |
| 2.1.0 | 2023-03-01 | | Short Term* | TBD |
| 2.2.0 | 2023-06-01 | | Long Term* | TBD |
## Legend
- Version: Only counts major and minor versions, patch releases are released
unscheduled as needed.
- Date: Scheduled date for the Final Release of the corresponding release.
- Delay: Days of delay between scheduled date and release date.
- Life-cycle: The duration of the support:
- Long Term, usually maintained for one natural year, it might use a
specific-release support branch if it is not the latest release.
- Short Term, usually maintained until the next minor release, usually 3-6
months.

@ -0,0 +1,14 @@
# Add test for array and datas that are cleaned up after finalize
It is the case that arrays might be deallocated from a device after the
device is closed. This can happen, for example, when an `ArrayHandle` is
declared globally. It gets constructed before VTK-m is initialized. This
is OK as long as you do not otherwise use it until VTK-m is initialized.
However, if you use that `ArrayHandle` to move data to a device and that
data is left on the device when the object closes, then the
`ArrayHandle` will be left holding a reference to invalid device memory
once the device is shut down. This can cause problems when the
`ArrayHandle` destructs itself and attempts to release this memory.
The VTK-m devices should gracefully handle deallocations that happen
after device shutdown.

@ -0,0 +1,30 @@
# Allow ArrayHandle to have a runtime selectable number of buffers
Previously, the number of buffers held by an `ArrayHandle` had to be
determined statically at compile time by the storage. Most of the time this
is fine. However, there are some exceptions where the number of buffers
need to be selected at runtime. For example, the `ArrayHandleRecombineVec`
does not specify the number of components it uses, and it needed a hack
where it stored buffers in the metadata of another buffer, which is bad.
This change allows the number of buffers to vary at runtime (at least at
construction). The buffers were already managed in a `std::vector`. It now
no longer forces the vector to be a specific size. `GetNumberOfBuffers` was
removed from the `Storage`. Instead, if the number of buffers was not
specified at construction, an allocation of size 0 is done to create
default buffers.
The biggest change is to the interface of the storage object methods, which
now take `std::vector` instead of pointers to `Buffer` objects. This adds a
little hassle in having to copy subsets of this `vector` when a storage
object has multiple sub-arrays. But it does simplify some of the
templating.
Other changes to the `Storage` structure include requiring all objects to
include a `CreateBuffers` method that accepts no arguments. This method
will be used by `ArrayHandle` in its default constructor. Previously,
`ArrayHandle` would create the `vector` of `Buffer` objects itself, but it
now must call this method in the `Storage` to do this. (It also has a nice
side effect of allowing the `Storage` to initialize the buffer objects if
necessary. Another change was to remove the `GetNumberOfBuffers` method
(which no longer has meaning).

@ -0,0 +1,10 @@
# Added DEVICE_SOURCES to vtkm_unit_tests
The `vtkm_unit_tests` function in the CMake build now allows you to specify
which files need to be compiled with a device compiler using the
`DEVICE_SOURCES` argument. Previously, the only way to specify that unit
tests needed to be compiled with a device compiler was to use the
`ALL_BACKENDS` argument, which would automatically compile everything with
the device compiler as well as test the code on all backends.
`ALL_BACKENDS` is still supported, but it no longer changes the sources to
be compiled with the device compiler.

@ -0,0 +1,5 @@
# Add Variant::IsType
The `Variant` class was missing a way to check the type. You could do it
indirectly using `variant.GetIndex() == variant.GetIndexOf<T>()`, but
having this convenience function is more clear.

@ -0,0 +1,7 @@
# Fix bug with voxels in legacy vtk files
The legacy VTK file reader for unstructured grids had a bug when reading
cells of type voxel. VTK-m does not support the voxel cell type in
unstructured grids (i.e. explicit cell sets), so it has to convert them to
hexahedron cells. A bug in the reader was mangling the cell array index
during this conversion.

@ -15,7 +15,3 @@ find_package(VTKm REQUIRED QUIET)
add_executable(Clipping Clipping.cxx)
target_link_libraries(Clipping PRIVATE vtkm_filter vtkm_io)
vtkm_add_target_information(Clipping
DROP_UNUSED_SYMBOLS MODIFY_CUDA_FLAGS
DEVICE_SOURCES Clipping.cxx)

@ -18,9 +18,3 @@ target_link_libraries(ContourTreeMesh2D vtkm_filter)
add_executable(ContourTreeMesh3D ContourTreeMesh3D.cxx)
target_link_libraries(ContourTreeMesh3D vtkm_filter)
vtkm_add_target_information(ContourTreeMesh2D ContourTreeMesh3D
DROP_UNUSED_SYMBOLS
MODIFY_CUDA_FLAGS
DEVICE_SOURCES
ContourTreeMesh2D.cxx ContourTreeMesh3D.cxx)

@ -548,14 +548,8 @@ int main(int argc, char* argv[])
static_cast<vtkm::Id>(dims[1]),
static_cast<vtkm::Id>(0));
vtkm::cont::ArrayHandle<vtkm::Id3> localBlockIndices;
vtkm::cont::ArrayHandle<vtkm::Id3> localBlockOrigins;
vtkm::cont::ArrayHandle<vtkm::Id3> localBlockSizes;
localBlockIndices.Allocate(blocksPerRank);
localBlockOrigins.Allocate(blocksPerRank);
localBlockSizes.Allocate(blocksPerRank);
auto localBlockIndicesPortal = localBlockIndices.WritePortal();
auto localBlockOriginsPortal = localBlockOrigins.WritePortal();
auto localBlockSizesPortal = localBlockSizes.WritePortal();
{
vtkm::Id lastDimSize =
@ -604,30 +598,29 @@ int main(int argc, char* argv[])
vtkm::Vec<ValueType, 2> origin(0, blockIndex * blockSize);
vtkm::Vec<ValueType, 2> spacing(1, 1);
ds = dsb.Create(vdims, origin, spacing);
vtkm::cont::CellSetStructured<2> cs;
cs.SetPointDimensions(vdims);
cs.SetGlobalPointDimensions(vtkm::Id2{ globalSize[0], globalSize[1] });
cs.SetGlobalPointIndexStart(vtkm::Id2{ 0, blockIndex * blockSize });
ds.SetCellSet(cs);
localBlockIndicesPortal.Set(localBlockIndex, vtkm::Id3(blockIndex, 0, 0));
localBlockOriginsPortal.Set(localBlockIndex,
vtkm::Id3((blockStart / blockSliceSize), 0, 0));
localBlockSizesPortal.Set(localBlockIndex,
vtkm::Id3(currBlockSize, static_cast<vtkm::Id>(dims[0]), 0));
localBlockIndicesPortal.Set(localBlockIndex, vtkm::Id3(0, blockIndex, 0));
}
// 3D data
else
{
vtkm::Id3 vdims;
vdims[0] = static_cast<vtkm::Id>(dims[1]);
vdims[1] = static_cast<vtkm::Id>(dims[0]);
vdims[0] = static_cast<vtkm::Id>(dims[0]);
vdims[1] = static_cast<vtkm::Id>(dims[1]);
vdims[2] = static_cast<vtkm::Id>(currBlockSize);
vtkm::Vec<ValueType, 3> origin(0, 0, (blockIndex * blockSize));
vtkm::Vec<ValueType, 3> origin(0, 0, blockIndex * blockSize);
vtkm::Vec<ValueType, 3> spacing(1, 1, 1);
ds = dsb.Create(vdims, origin, spacing);
localBlockIndicesPortal.Set(localBlockIndex, vtkm::Id3(0, 0, blockIndex));
localBlockOriginsPortal.Set(localBlockIndex,
vtkm::Id3(0, 0, (blockStart / blockSliceSize)));
localBlockSizesPortal.Set(
localBlockIndex,
vtkm::Id3(static_cast<vtkm::Id>(dims[0]), static_cast<vtkm::Id>(dims[1]), currBlockSize));
vtkm::cont::CellSetStructured<3> cs;
cs.SetPointDimensions(vdims);
cs.SetGlobalPointDimensions(globalSize);
cs.SetGlobalPointIndexStart(vtkm::Id3{ 0, 0, blockIndex * blockSize });
ds.SetCellSet(cs);
}
std::vector<vtkm::Float32> subValues((values.begin() + blockStart),
@ -648,8 +641,7 @@ int main(int argc, char* argv[])
computeRegularStructure);
#ifdef WITH_MPI
filter.SetSpatialDecomposition(
blocksPerDim, globalSize, localBlockIndices, localBlockOrigins, localBlockSizes);
filter.SetBlockIndices(blocksPerDim, localBlockIndices);
#endif
filter.SetActiveField("values");

@ -490,14 +490,8 @@ int main(int argc, char* argv[])
vtkm::Id3 globalSize;
vtkm::Id3 blocksPerDim;
vtkm::cont::ArrayHandle<vtkm::Id3> localBlockIndices;
vtkm::cont::ArrayHandle<vtkm::Id3> localBlockOrigins;
vtkm::cont::ArrayHandle<vtkm::Id3> localBlockSizes;
localBlockIndices.Allocate(blocksPerRank);
localBlockOrigins.Allocate(blocksPerRank);
localBlockSizes.Allocate(blocksPerRank);
auto localBlockIndicesPortal = localBlockIndices.WritePortal();
auto localBlockOriginsPortal = localBlockOrigins.WritePortal();
auto localBlockSizesPortal = localBlockSizes.WritePortal();
// Read the pre-split data files
bool readOk = true;
@ -514,8 +508,6 @@ int main(int argc, char* argv[])
globalSize,
blocksPerDim,
localBlockIndices,
localBlockOrigins,
localBlockSizes,
// output timers
dataReadTime,
buildDatasetTime);
@ -541,8 +533,6 @@ int main(int argc, char* argv[])
useDataSet,
globalSize,
localBlockIndices,
localBlockOrigins,
localBlockSizes,
// output timers
dataReadTime,
buildDatasetTime);
@ -567,8 +557,6 @@ int main(int argc, char* argv[])
globalSize,
blocksPerDim,
localBlockIndices,
localBlockOrigins,
localBlockSizes,
// output timers
dataReadTime,
buildDatasetTime);
@ -598,7 +586,7 @@ int main(int argc, char* argv[])
<< nDims << "D. "
<< "Contour tree using marching cubes is only supported for 3D data.");
// If we found any errors in the setttings than finalize MPI and exit the execution
// If we found any errors in the settings than finalize MPI and exit the execution
if (invalidMCOption)
{
MPI_Finalize();
@ -615,26 +603,23 @@ int main(int argc, char* argv[])
prevTime = currTime;
// Log information of the (first) local data block
// TODO: Get localBlockSize and localBlockOrigins from the cell set to log results
VTKM_LOG_S(vtkm::cont::LogLevel::Info,
"" << std::setw(42) << std::left << "blockSize"
<< ":" << localBlockSizesPortal.Get(0) << std::endl
<< std::setw(42) << std::left << "blockOrigin=" << localBlockOriginsPortal.Get(0)
<< std::endl
<< std::setw(42) << std::left << "blockIndices=" << localBlockIndicesPortal.Get(0)
<< std::endl
<< std::setw(42) << std::left << "blocksPerDim=" << blocksPerDim << std::endl
<< std::setw(42) << std::left << "globalSize=" << globalSize << std::endl
"" //<< std::setw(42) << std::left << "blockSize"
//<< ":" << localBlockSizesPortal.Get(0) << std::endl
//<< std::setw(42) << std::left << "blockOrigin=" << localBlockOriginsPortal.Get(0)
//<< std::endl
<< std::setw(42) << std::left << "blockIndices=" << localBlockIndicesPortal.Get(0)
<< std::endl
<< std::setw(42) << std::left << "blocksPerDim=" << blocksPerDim << std::endl
<< std::setw(42) << std::left << "globalSize=" << globalSize << std::endl
);
// Convert the mesh of values into contour tree, pairs of vertex ids
vtkm::filter::ContourTreeUniformDistributed filter(blocksPerDim,
globalSize,
localBlockIndices,
localBlockOrigins,
localBlockSizes,
timingsLogLevel,
treeLogLevel);
vtkm::filter::scalar_topology::ContourTreeUniformDistributed filter(timingsLogLevel,
treeLogLevel);
filter.SetBlockIndices(blocksPerDim, localBlockIndices);
filter.SetUseBoundaryExtremaOnly(useBoundaryExtremaOnly);
filter.SetUseMarchingCubes(useMarchingCubes);
filter.SetAugmentHierarchicalTree(augmentHierarchicalTree);
@ -658,8 +643,7 @@ int main(int argc, char* argv[])
vtkm::cont::PartitionedDataSet bd_result;
if (computeHierarchicalVolumetricBranchDecomposition)
{
vtkm::filter::scalar_topology::DistributedBranchDecompositionFilter bd_filter(
blocksPerDim, globalSize, localBlockIndices, localBlockOrigins, localBlockSizes);
vtkm::filter::scalar_topology::DistributedBranchDecompositionFilter bd_filter;
bd_result = bd_filter.Execute(result);
}
currTime = totalTime.GetElapsedTime();

@ -16,6 +16,6 @@ if (VTKm_ENABLE_MPI)
add_executable(Histogram Histogram.cxx HistogramMPI.h HistogramMPI.hxx)
target_link_libraries(Histogram PRIVATE vtkm_filter MPI::MPI_CXX)
vtkm_add_target_information(Histogram
DROP_UNUSED_SYMBOLS MODIFY_CUDA_FLAGS
DEVICE_SOURCES Histogram.cxx)
DROP_UNUSED_SYMBOLS MODIFY_CUDA_FLAGS
DEVICE_SOURCES Histogram.cxx)
endif()

@ -37,7 +37,7 @@ public:
VTKM_CONT
vtkm::Id GetNumberOfBins() const { return this->NumberOfBins; }
//@{
///@{
/// Get/Set the range to use to generate the HistogramMPI. If range is set to
/// empty, the field's global range (computed using `vtkm::cont::FieldRangeGlobalCompute`)
/// will be used.
@ -46,7 +46,7 @@ public:
VTKM_CONT
const vtkm::Range& GetRange() const { return this->Range; }
//@}
///@}
/// Returns the bin delta of the last computed field.
VTKM_CONT
@ -64,7 +64,7 @@ public:
const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy);
//@{
///@{
/// when operating on vtkm::cont::PartitionedDataSet, we
/// want to do processing across ranks as well. Just adding pre/post handles
/// for the same does the trick.
@ -76,7 +76,7 @@ public:
VTKM_CONT void PostExecute(const vtkm::cont::PartitionedDataSet& input,
vtkm::cont::PartitionedDataSet& output,
const vtkm::filter::PolicyBase<DerivedPolicy>&);
//@}
///@}
private:
vtkm::Id NumberOfBins;

@ -27,11 +27,3 @@ find_package(VTKm REQUIRED QUIET)
add_executable(MeshQuality MeshQuality.cxx)
target_link_libraries(MeshQuality PRIVATE vtkm_filter vtkm_io)
if(TARGET vtkm::tbb)
target_compile_definitions(MeshQuality PRIVATE BUILDING_TBB_VERSION)
endif()
vtkm_add_target_information(MeshQuality
DROP_UNUSED_SYMBOLS MODIFY_CUDA_FLAGS
DEVICE_SOURCES MeshQuality.cxx)

@ -15,6 +15,3 @@ find_package(VTKm REQUIRED QUIET)
add_executable(Oscillator Oscillator.cxx)
target_link_libraries(Oscillator PRIVATE vtkm_source)
vtkm_add_target_information(Oscillator
DROP_UNUSED_SYMBOLS MODIFY_CUDA_FLAGS
DEVICE_SOURCES Oscillator.cxx)

@ -9,19 +9,13 @@
//============================================================================
#include <algorithm>
#include <cctype>
#include <fstream>
#include <iostream>
#include <sstream>
#include <vtkm/Math.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/DataSetBuilderUniform.h>
#include <vtkm/cont/Initialize.h>
#include <vtkm/filter/FilterDataSet.h>
#include <vtkm/cont/TryExecute.h>
#include <vtkm/source/Oscillator.h>
#if !defined(_WIN32) || defined(__CYGWIN__)

@ -14,10 +14,4 @@ project(ParticleAdvection CXX)
find_package(VTKm REQUIRED QUIET)
add_executable(Particle_Advection ParticleAdvection.cxx)
target_link_libraries(Particle_Advection PRIVATE vtkm_filter vtkm_io)
vtkm_add_target_information(Particle_Advection
DROP_UNUSED_SYMBOLS MODIFY_CUDA_FLAGS
DEVICE_SOURCES ParticleAdvection.cxx)
if(TARGET vtkm::tbb)
target_compile_definitions(Particle_Advection PRIVATE BUILDING_TBB_VERSION)
endif()
target_link_libraries(Particle_Advection PRIVATE vtkm_filter_flow vtkm_io)

@ -8,9 +8,10 @@
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#include <vtkm/Particle.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/cont/Initialize.h>
#include <vtkm/filter/Streamline.h>
#include <vtkm/filter/flow/Streamline.h>
#include <vtkm/io/VTKDataSetReader.h>
#include <vtkm/io/VTKDataSetWriter.h>
@ -74,7 +75,7 @@ int main(int argc, char** argv)
auto seedArray = vtkm::cont::make_ArrayHandle(seeds, vtkm::CopyFlag::Off);
//compute streamlines
vtkm::filter::Streamline streamline;
vtkm::filter::flow::Streamline streamline;
streamline.SetStepSize(stepSize);
streamline.SetNumberOfSteps(numSteps);

@ -13,8 +13,8 @@ project(PolyLineArchimedeanHelix CXX)
find_package(VTKm REQUIRED QUIET)
if (VTKm_ENABLE_RENDERING)
add_executable(PolyLineArchimedeanHelix PolyLineArchimedeanHelix.cxx)
vtkm_add_target_information(PolyLineArchimedeanHelix
DROP_UNUSED_SYMBOLS MODIFY_CUDA_FLAGS
DEVICE_SOURCES PolyLineArchimedeanHelix.cxx)
target_link_libraries(PolyLineArchimedeanHelix PRIVATE vtkm_filter vtkm_rendering)
vtkm_add_target_information(PolyLineArchimedeanHelix
DROP_UNUSED_SYMBOLS MODIFY_CUDA_FLAGS
DEVICE_SOURCES PolyLineArchimedeanHelix.cxx)
endif()

@ -16,12 +16,5 @@ find_package(VTKm REQUIRED QUIET)
if (VTKm_ENABLE_MPI)
add_executable(StreamlineMPI StreamlineMPI.cxx)
target_compile_definitions(StreamlineMPI PRIVATE "MPI_ENABLED")
target_link_libraries(StreamlineMPI PRIVATE vtkm_filter vtkm_io MPI::MPI_CXX)
vtkm_add_target_information(StreamlineMPI
DROP_UNUSED_SYMBOLS MODIFY_CUDA_FLAGS
DEVICE_SOURCES StreamlineMPI.cxx)
target_link_libraries(StreamlineMPI PRIVATE vtkm_filter_flow vtkm_io MPI::MPI_CXX)
endif()
#if(TARGET vtkm::tbb)
# target_compile_definitions(streamline_mpi PRIVATE BUILDING_TBB_VERSION)
#endif()

@ -8,13 +8,14 @@
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#include <vtkm/Particle.h>
#include <vtkm/cont/AssignerPartitionedDataSet.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/cont/EnvironmentTracker.h>
#include <vtkm/cont/Field.h>
#include <vtkm/cont/Initialize.h>
#include <vtkm/cont/PartitionedDataSet.h>
#include <vtkm/filter/Streamline.h>
#include <vtkm/filter/flow/ParticleAdvection.h>
#include <vtkm/io/VTKDataSetReader.h>
#include <vtkm/io/VTKDataSetWriter.h>
#include <vtkm/io/reader/VTKDataSetReader.h>
@ -23,12 +24,6 @@
#include <vtkm/thirdparty/diy/diy.h>
#include <vtkm/thirdparty/diy/mpi-cast.h>
#include <vtkm/filter/ParticleAdvection.h>
#include <vtkm/filter/particleadvection/BoundsMap.h>
#include <vtkm/filter/particleadvection/ParticleMessenger.h>
void LoadData(std::string& fname, std::vector<vtkm::cont::DataSet>& dataSets, int rank, int nRanks)
{
std::string buff;
@ -99,7 +94,7 @@ int main(int argc, char** argv)
std::vector<vtkm::cont::DataSet> dataSets;
LoadData(dataFile, dataSets, rank, size);
vtkm::filter::ParticleAdvection pa;
vtkm::filter::flow::ParticleAdvection pa;
vtkm::cont::ArrayHandle<vtkm::Particle> seedArray;
seedArray = vtkm::cont::make_ArrayHandle({ vtkm::Particle(vtkm::Vec3f(.1f, .1f, .9f), 0),

@ -12,11 +12,14 @@
#include <string>
#include <vector>
#include <vtkm/Particle.h>
//#include <vtkm/cont/Algorithm.h>
#include <vtkm/cont/ArrayCopy.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/cont/Initialize.h>
#include <vtkm/cont/Timer.h>
//#include <vtkm/cont/Timer.h>
#include <vtkm/filter/Pathline.h>
#include <vtkm/filter/flow/Pathline.h>
#include <vtkm/io/VTKDataSetReader.h>
#include <vtkm/io/VTKDataSetWriter.h>
@ -91,7 +94,7 @@ int main(int argc, char** argv)
// Instantiate the filter by providing necessary parameters.
// Necessary parameters are :
vtkm::filter::Pathline pathlineFilter;
vtkm::filter::flow::Pathline pathlineFilter;
pathlineFilter.SetActiveField(fieldName);
// 1. The current and next time slice. The current time slice is passed
// through the parameter to the Execute method.

@ -18,9 +18,3 @@ target_link_libraries(Tetrahedralize PRIVATE vtkm_filter vtkm_io)
add_executable(Triangulate Triangulate.cxx)
target_link_libraries(Triangulate PRIVATE vtkm_filter vtkm_io)
vtkm_add_target_information(Tetrahedralize Triangulate
DROP_UNUSED_SYMBOLS
MODIFY_CUDA_FLAGS
DEVICE_SOURCES
Tetrahedralize.cxx Triangulate.cxx)

@ -127,11 +127,11 @@ VTKM_CONT bool DoMapField(
{
vtkm::cont::Field outputField;
if (inputField.IsFieldPoint())
if (inputField.IsPointField())
{
outputField = inputField; // pass through
}
else if (inputField.IsFieldCell())
else if (inputField.IsCellField())
{
vtkm::cont::Field permuted;
vtkm::filter::MapFieldPermutation(inputField, OutputToInputCellMap, permuted);

@ -1 +1 @@
1.8.0
1.8.9999

@ -55,6 +55,16 @@ public:
VTKM_EXEC_CONT void ClearInGhostCell() { this->reset(this->IN_GHOST_CELL_BIT); }
VTKM_EXEC_CONT bool CheckInGhostCell() const { return this->test(this->IN_GHOST_CELL_BIT); }
VTKM_EXEC_CONT void SetZeroVelocity() { this->set(this->ZERO_VELOCITY); }
VTKM_EXEC_CONT void ClearZeroVelocity() { this->reset(this->ZERO_VELOCITY); }
VTKM_EXEC_CONT bool CheckZeroVelocity() const { return this->test(this->ZERO_VELOCITY); }
VTKM_EXEC_CONT bool CanContinue() const
{
return this->CheckOk() && !this->CheckTerminate() && !this->CheckSpatialBounds() &&
!this->CheckTemporalBounds() && !this->CheckInGhostCell() && !this->CheckZeroVelocity();
}
private:
static constexpr vtkm::Id SUCCESS_BIT = 0;
static constexpr vtkm::Id TERMINATE_BIT = 1;
@ -62,6 +72,7 @@ private:
static constexpr vtkm::Id TEMPORAL_BOUNDS_BIT = 3;
static constexpr vtkm::Id TOOK_ANY_STEPS_BIT = 4;
static constexpr vtkm::Id IN_GHOST_CELL_BIT = 5;
static constexpr vtkm::Id ZERO_VELOCITY = 6;
};
inline VTKM_CONT std::ostream& operator<<(std::ostream& s, const vtkm::ParticleStatus& status)
@ -71,6 +82,7 @@ inline VTKM_CONT std::ostream& operator<<(std::ostream& s, const vtkm::ParticleS
s << " spat= " << status.CheckSpatialBounds();
s << " temp= " << status.CheckTemporalBounds();
s << " ghst= " << status.CheckInGhostCell();
s << " zvel= " << status.CheckZeroVelocity();
s << "]";
return s;
}
@ -142,6 +154,17 @@ public:
vtkm::Id NumSteps = 0;
vtkm::ParticleStatus Status;
vtkm::FloatDefault Time = 0;
static size_t Sizeof()
{
constexpr std::size_t sz = sizeof(vtkm::Vec3f) // Pos
+ sizeof(vtkm::Id) // ID
+ sizeof(vtkm::Id) // NumSteps
+ sizeof(vtkm::UInt8) // Status
+ sizeof(vtkm::FloatDefault); // Time
return sz;
}
};
class ChargedParticle
@ -153,9 +176,9 @@ public:
VTKM_EXEC_CONT
ChargedParticle(const vtkm::Vec3f& position,
const vtkm::Id& id,
const vtkm::FloatDefault& mass,
const vtkm::FloatDefault& charge,
const vtkm::FloatDefault& weighting,
const vtkm::Float64& mass,
const vtkm::Float64& charge,
const vtkm::Float64& weighting,
const vtkm::Vec3f& momentum,
const vtkm::Id& numSteps = 0,
const vtkm::ParticleStatus& status = vtkm::ParticleStatus(),
@ -173,16 +196,16 @@ public:
}
VTKM_EXEC_CONT
vtkm::FloatDefault Gamma(vtkm::Vec3f momentum, bool reciprocal = false) const
vtkm::Float64 Gamma(vtkm::Vec3f momentum, bool reciprocal = false) const
{
constexpr vtkm::FloatDefault c2 = SPEED_OF_LIGHT * SPEED_OF_LIGHT;
const auto fMom2 = vtkm::MagnitudeSquared(momentum);
const auto m2 = this->Mass * this->Mass;
const auto m2_c2_reci = 1.0 / (m2 * c2);
const vtkm::Float64 fMom2 = vtkm::MagnitudeSquared(momentum);
const vtkm::Float64 m2 = this->Mass * this->Mass;
const vtkm::Float64 m2_c2_reci = 1.0 / (m2 * c2);
if (reciprocal)
return static_cast<vtkm::FloatDefault>(vtkm::RSqrt(1.0 + fMom2 * m2_c2_reci));
return vtkm::RSqrt(1.0 + fMom2 * m2_c2_reci);
else
return static_cast<vtkm::FloatDefault>(vtkm::Sqrt(1.0 + fMom2 * m2_c2_reci));
return vtkm::Sqrt(1.0 + fMom2 * m2_c2_reci);
}
VTKM_EXEC_CONT
@ -197,11 +220,11 @@ public:
vtkm::Vec3f eField = vectors[0];
vtkm::Vec3f bField = vectors[1];
const vtkm::FloatDefault QoM = this->Charge / this->Mass;
const vtkm::Float64 QoM = this->Charge / this->Mass;
const vtkm::Vec3f mom_minus = this->Momentum + (0.5 * this->Charge * eField * length);
// Get reciprocal of Gamma
vtkm::Vec3f gamma_reci = this->Gamma(mom_minus, true);
vtkm::Vec3f gamma_reci = static_cast<vtkm::FloatDefault>(this->Gamma(mom_minus, true));
const vtkm::Vec3f t = 0.5 * QoM * length * bField * gamma_reci;
const vtkm::Vec3f s = 2.0f * t * (1.0 / (1.0 + vtkm::Magnitude(t)));
const vtkm::Vec3f mom_prime = mom_minus + vtkm::Cross(mom_minus, t);
@ -228,6 +251,14 @@ public:
return this->Pos + translation;
}
inline VTKM_CONT friend std::ostream& operator<<(std::ostream& out,
const vtkm::ChargedParticle& p)
{
out << "v(" << p.Time << ") = " << p.Pos << ", ID: " << p.ID << ", NumSteps: " << p.NumSteps
<< ", Status: " << p.Status;
return out;
}
vtkm::Vec3f Pos;
vtkm::Id ID = -1;
vtkm::Id NumSteps = 0;
@ -235,14 +266,30 @@ public:
vtkm::FloatDefault Time = 0;
private:
vtkm::FloatDefault Mass;
vtkm::FloatDefault Charge;
vtkm::FloatDefault Weighting;
vtkm::Float64 Mass;
vtkm::Float64 Charge;
vtkm::Float64 Weighting;
vtkm::Vec3f Momentum;
constexpr static vtkm::FloatDefault SPEED_OF_LIGHT =
static_cast<vtkm::FloatDefault>(2.99792458e8);
friend struct mangled_diy_namespace::Serialization<vtkm::ChargedParticle>;
public:
static size_t Sizeof()
{
constexpr std::size_t sz = sizeof(vtkm::Vec3f) // Pos
+ sizeof(vtkm::Id) // ID
+ sizeof(vtkm::Id) // NumSteps
+ sizeof(vtkm::UInt8) // Status
+ sizeof(vtkm::FloatDefault) // Time
+ sizeof(vtkm::Float64) //Mass
+ sizeof(vtkm::Float64) //Charge
+ sizeof(vtkm::Float64) //Weighting
+ sizeof(vtkm::Vec3f); //Momentum
return sz;
}
};
} //namespace vtkm

@ -314,7 +314,7 @@ public:
/// Constructs an empty ArrayHandle.
///
VTKM_CONT ArrayHandle()
: Buffers(static_cast<std::size_t>(StorageType::GetNumberOfBuffers()))
: Buffers(StorageType::CreateBuffers())
{
}
@ -349,17 +349,10 @@ public:
VTKM_CONT ArrayHandle(const std::vector<vtkm::cont::internal::Buffer>& buffers)
: Buffers(buffers)
{
VTKM_ASSERT(static_cast<vtkm::IdComponent>(this->Buffers.size()) == this->GetNumberOfBuffers());
}
VTKM_CONT ArrayHandle(std::vector<vtkm::cont::internal::Buffer>&& buffers) noexcept
: Buffers(std::move(buffers))
{
VTKM_ASSERT(static_cast<vtkm::IdComponent>(this->Buffers.size()) == this->GetNumberOfBuffers());
}
VTKM_CONT ArrayHandle(const vtkm::cont::internal::Buffer* buffers)
: Buffers(buffers, buffers + StorageType::GetNumberOfBuffers())
{
}
///@}
@ -420,9 +413,10 @@ public:
return true; // different valuetype and/or storage
}
VTKM_CONT static constexpr vtkm::IdComponent GetNumberOfBuffers()
VTKM_DEPRECATED(1.9, "Use the size of the std::vector returned from GetBuffers.")
VTKM_CONT constexpr vtkm::IdComponent GetNumberOfBuffers()
{
return StorageType::GetNumberOfBuffers();
return static_cast<vtkm::IdComponent>(this->GetBuffers().size());
}
/// Get the storage.
@ -776,9 +770,15 @@ public:
}
}
/// Returns the internal `Buffer` structures that hold the data.
/// \brief Returns the internal `Buffer` structures that hold the data.
///
VTKM_CONT vtkm::cont::internal::Buffer* GetBuffers() const { return this->Buffers.data(); }
/// Note that great care should be taken when modifying buffers outside of the ArrayHandle.
///
VTKM_CONT const std::vector<vtkm::cont::internal::Buffer>& GetBuffers() const
{
return this->Buffers;
}
VTKM_CONT std::vector<vtkm::cont::internal::Buffer>& GetBuffers() { return this->Buffers; }
private:
mutable std::vector<vtkm::cont::internal::Buffer> Buffers;
@ -789,11 +789,13 @@ protected:
this->Buffers[static_cast<std::size_t>(index)] = buffer;
}
// BufferContainer must be an iteratable container of Buffer objects.
template <typename BufferContainer>
VTKM_CONT void SetBuffers(const BufferContainer& buffers)
VTKM_CONT void SetBuffers(const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
std::copy(buffers.begin(), buffers.end(), this->Iterators->Buffers.begin());
this->Buffers = buffers;
}
VTKM_CONT void SetBuffers(std::vector<vtkm::cont::internal::Buffer>&& buffers)
{
this->Buffers = std::move(buffers);
}
};
@ -915,6 +917,25 @@ namespace internal
namespace detail
{
VTKM_CONT inline void CreateBuffersImpl(std::vector<vtkm::cont::internal::Buffer>&);
template <typename T, typename S, typename... Args>
VTKM_CONT inline void CreateBuffersImpl(std::vector<vtkm::cont::internal::Buffer>& buffers,
const vtkm::cont::ArrayHandle<T, S>& array,
const Args&... args);
template <typename... Args>
VTKM_CONT inline void CreateBuffersImpl(std::vector<vtkm::cont::internal::Buffer>& buffers,
const vtkm::cont::internal::Buffer& buffer,
const Args&... args);
template <typename... Args>
VTKM_CONT inline void CreateBuffersImpl(std::vector<vtkm::cont::internal::Buffer>& buffers,
const std::vector<vtkm::cont::internal::Buffer>& addbuffs,
const Args&... args);
template <typename Arg0, typename... Args>
VTKM_CONT inline void CreateBuffersImpl(std::vector<vtkm::cont::internal::Buffer>& buffers,
const Arg0& arg0,
const Args&... args);
VTKM_CONT inline void CreateBuffersImpl(std::vector<vtkm::cont::internal::Buffer>&)
{
// Nothing left to add.
@ -925,9 +946,7 @@ VTKM_CONT inline void CreateBuffersImpl(std::vector<vtkm::cont::internal::Buffer
const vtkm::cont::ArrayHandle<T, S>& array,
const Args&... args)
{
vtkm::cont::internal::Buffer* arrayBuffers = array.GetBuffers();
buffers.insert(buffers.end(), arrayBuffers, arrayBuffers + array.GetNumberOfBuffers());
CreateBuffersImpl(buffers, args...);
CreateBuffersImpl(buffers, array.GetBuffers(), args...);
}
template <typename... Args>
@ -948,11 +967,6 @@ VTKM_CONT inline void CreateBuffersImpl(std::vector<vtkm::cont::internal::Buffer
CreateBuffersImpl(buffers, args...);
}
template <typename Arg0, typename... Args>
VTKM_CONT inline void CreateBuffersImpl(std::vector<vtkm::cont::internal::Buffer>& buffers,
const Arg0& arg0,
const Args&... args);
template <typename T, typename S, typename... Args>
VTKM_CONT inline void CreateBuffersResolveArrays(std::vector<vtkm::cont::internal::Buffer>& buffers,
std::true_type,
@ -1001,7 +1015,7 @@ VTKM_CONT inline void CreateBuffersImpl(std::vector<vtkm::cont::internal::Buffer
/// - `ArrayHandle`: The buffers from the `ArrayHandle` are added to the list.
/// - `Buffer`: A copy of the buffer is added to the list.
/// - `std::vector<Buffer>`: A copy of all buffers in this vector are added to the list.
/// - Anything else: A buffer with the given object attached as metadata is
/// - Anything else: A buffer with the given object attached as metadata is added to the list.
///
template <typename... Args>
VTKM_CONT inline std::vector<vtkm::cont::internal::Buffer> CreateBuffers(const Args&... args)

@ -35,10 +35,13 @@ public:
using ReadPortalType = vtkm::internal::ArrayPortalBasicRead<T>;
using WritePortalType = vtkm::internal::ArrayPortalBasicWrite<T>;
VTKM_CONT constexpr static vtkm::IdComponent GetNumberOfBuffers() { return 1; }
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers()
{
return std::vector<vtkm::cont::internal::Buffer>(1);
}
VTKM_CONT static void ResizeBuffers(vtkm::Id numValues,
vtkm::cont::internal::Buffer* buffers,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::CopyFlag preserve,
vtkm::cont::Token& token)
{
@ -46,36 +49,43 @@ public:
vtkm::internal::NumberOfValuesToNumberOfBytes<T>(numValues), preserve, token);
}
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return static_cast<vtkm::Id>(buffers->GetNumberOfBytes() /
VTKM_ASSERT(buffers.size() == 1);
return static_cast<vtkm::Id>(buffers[0].GetNumberOfBytes() /
static_cast<vtkm::BufferSizeType>(sizeof(T)));
}
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer* buffers,
VTKM_CONT static void Fill(const std::vector<vtkm::cont::internal::Buffer>& buffers,
const T& fillValue,
vtkm::Id startIndex,
vtkm::Id endIndex,
vtkm::cont::Token& token)
{
VTKM_ASSERT(buffers.size() == 1);
constexpr vtkm::BufferSizeType fillValueSize =
static_cast<vtkm::BufferSizeType>(sizeof(fillValue));
buffers[0].Fill(
&fillValue, fillValueSize, startIndex * fillValueSize, endIndex * fillValueSize, token);
}
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
VTKM_ASSERT(buffers.size() == 1);
return ReadPortalType(reinterpret_cast<const T*>(buffers[0].ReadPointerDevice(device, token)),
GetNumberOfValues(buffers));
}
VTKM_CONT static WritePortalType CreateWritePortal(vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static WritePortalType CreateWritePortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
VTKM_ASSERT(buffers.size() == 1);
return WritePortalType(reinterpret_cast<T*>(buffers[0].WritePointerDevice(device, token)),
GetNumberOfValues(buffers));
}
@ -345,7 +355,8 @@ struct Serialization<vtkm::cont::ArrayHandleBasic<T>>
vtkm::cont::internal::Buffer buffer;
vtkmdiy::load(bb, buffer);
obj = vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagBasic>(&buffer);
obj = vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagBasic>(
vtkm::cont::internal::CreateBuffers(buffer));
}
};

@ -82,10 +82,13 @@ public:
using ReadPortalType = vtkm::cont::internal::ArrayPortalBitField<BitPortalConstType>;
using WritePortalType = vtkm::cont::internal::ArrayPortalBitField<BitPortalType>;
VTKM_CONT constexpr static vtkm::IdComponent GetNumberOfBuffers() { return 1; }
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers()
{
return std::vector<vtkm::cont::internal::Buffer>(1);
}
VTKM_CONT static void ResizeBuffers(vtkm::Id numberOfBits,
vtkm::cont::internal::Buffer* buffers,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::CopyFlag preserve,
vtkm::cont::Token& token)
{
@ -102,20 +105,23 @@ public:
buffers[0].GetMetaData<vtkm::cont::internal::BitFieldMetaData>().NumberOfBits = numberOfBits;
}
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
VTKM_ASSERT(buffers.size() == 1);
vtkm::Id numberOfBits =
buffers[0].GetMetaData<vtkm::cont::internal::BitFieldMetaData>().NumberOfBits;
VTKM_ASSERT((buffers[0].GetNumberOfBytes() * CHAR_BIT) >= numberOfBits);
return numberOfBits;
}
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer* buffers,
VTKM_CONT static void Fill(const std::vector<vtkm::cont::internal::Buffer>& buffers,
bool fillValue,
vtkm::Id startBit,
vtkm::Id endBit,
vtkm::cont::Token& token)
{
VTKM_ASSERT(buffers.size() == 1);
constexpr vtkm::BufferSizeType wordTypeSize =
static_cast<vtkm::BufferSizeType>(sizeof(WordType));
constexpr vtkm::BufferSizeType wordNumBits = wordTypeSize * CHAR_BIT;
@ -141,10 +147,12 @@ public:
}
}
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
VTKM_ASSERT(buffers.size() == 1);
vtkm::Id numberOfBits = GetNumberOfValues(buffers);
VTKM_ASSERT((buffers[0].GetNumberOfBytes() * CHAR_BIT) >= numberOfBits);
@ -152,10 +160,12 @@ public:
BitPortalConstType(buffers[0].ReadPointerDevice(device, token), numberOfBits));
}
VTKM_CONT static WritePortalType CreateWritePortal(const vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static WritePortalType CreateWritePortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
VTKM_ASSERT(buffers.size() == 1);
vtkm::Id numberOfBits = GetNumberOfValues(buffers);
VTKM_ASSERT((buffers[0].GetNumberOfBytes() * CHAR_BIT) >= numberOfBits);

@ -17,6 +17,8 @@
#include <vtkm/cont/ErrorBadAllocation.h>
#include <vtkm/cont/Token.h>
#include <array>
namespace vtkm
{
namespace internal
@ -199,26 +201,27 @@ struct ArrayHandleCartesianProductTraits
template <typename T, typename ST1, typename ST2, typename ST3>
class Storage<vtkm::Vec<T, 3>, vtkm::cont::StorageTagCartesianProduct<ST1, ST2, ST3>>
{
struct Info
{
std::array<std::size_t, 4> BufferOffset;
};
using Storage1 = vtkm::cont::internal::Storage<T, ST1>;
using Storage2 = vtkm::cont::internal::Storage<T, ST2>;
using Storage3 = vtkm::cont::internal::Storage<T, ST3>;
template <typename Buffs>
VTKM_CONT constexpr static Buffs* Buffers1(Buffs* buffers)
{
return buffers;
}
using Array1 = vtkm::cont::ArrayHandle<T, ST1>;
using Array2 = vtkm::cont::ArrayHandle<T, ST2>;
using Array3 = vtkm::cont::ArrayHandle<T, ST3>;
template <typename Buffs>
VTKM_CONT constexpr static Buffs* Buffers2(Buffs* buffers)
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> GetBuffers(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
std::size_t subArray)
{
return buffers + Storage1::GetNumberOfBuffers();
}
template <typename Buffs>
VTKM_CONT constexpr static Buffs* Buffers3(Buffs* buffers)
{
return buffers + Storage1::GetNumberOfBuffers() + Storage2::GetNumberOfBuffers();
Info info = buffers[0].GetMetaData<Info>();
return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() +
info.BufferOffset[subArray - 1],
buffers.begin() + info.BufferOffset[subArray]);
}
public:
@ -235,20 +238,15 @@ public:
typename Storage2::WritePortalType,
typename Storage3::WritePortalType>;
VTKM_CONT constexpr static vtkm::IdComponent GetNumberOfBuffers()
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return Storage1::GetNumberOfBuffers() + Storage2::GetNumberOfBuffers() +
Storage3::GetNumberOfBuffers();
return (Storage1::GetNumberOfValues(GetBuffers(buffers, 1)) *
Storage2::GetNumberOfValues(GetBuffers(buffers, 2)) *
Storage3::GetNumberOfValues(GetBuffers(buffers, 3)));
}
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
{
return (Storage1::GetNumberOfValues(Buffers1(buffers)) *
Storage2::GetNumberOfValues(Buffers2(buffers)) *
Storage3::GetNumberOfValues(Buffers3(buffers)));
}
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer* buffers,
VTKM_CONT static void Fill(const std::vector<vtkm::cont::internal::Buffer>& buffers,
const vtkm::Vec<T, 3>& fillValue,
vtkm::Id startIndex,
vtkm::Id endIndex,
@ -259,46 +257,63 @@ public:
throw vtkm::cont::ErrorBadValue(
"Fill for ArrayHandleCartesianProduct can only be used to fill entire array.");
}
Storage1::Fill(
Buffers1(buffers), fillValue[0], 0, Storage1::GetNumberOfValues(Buffers1(buffers)), token);
Storage2::Fill(
Buffers2(buffers), fillValue[1], 0, Storage2::GetNumberOfValues(Buffers2(buffers)), token);
Storage3::Fill(
Buffers3(buffers), fillValue[2], 0, Storage3::GetNumberOfValues(Buffers3(buffers)), token);
auto subBuffers = GetBuffers(buffers, 1);
Storage1::Fill(subBuffers, fillValue[0], 0, Storage1::GetNumberOfValues(subBuffers), token);
subBuffers = GetBuffers(buffers, 2);
Storage2::Fill(subBuffers, fillValue[1], 0, Storage2::GetNumberOfValues(subBuffers), token);
subBuffers = GetBuffers(buffers, 3);
Storage3::Fill(subBuffers, fillValue[2], 0, Storage3::GetNumberOfValues(subBuffers), token);
}
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return ReadPortalType(Storage1::CreateReadPortal(Buffers1(buffers), device, token),
Storage2::CreateReadPortal(Buffers2(buffers), device, token),
Storage3::CreateReadPortal(Buffers3(buffers), device, token));
return ReadPortalType(Storage1::CreateReadPortal(GetBuffers(buffers, 1), device, token),
Storage2::CreateReadPortal(GetBuffers(buffers, 2), device, token),
Storage3::CreateReadPortal(GetBuffers(buffers, 3), device, token));
}
VTKM_CONT static WritePortalType CreateWritePortal(vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static WritePortalType CreateWritePortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return WritePortalType(Storage1::CreateWritePortal(Buffers1(buffers), device, token),
Storage2::CreateWritePortal(Buffers2(buffers), device, token),
Storage3::CreateWritePortal(Buffers3(buffers), device, token));
return WritePortalType(Storage1::CreateWritePortal(GetBuffers(buffers, 1), device, token),
Storage2::CreateWritePortal(GetBuffers(buffers, 2), device, token),
Storage3::CreateWritePortal(GetBuffers(buffers, 3), device, token));
}
VTKM_CONT static vtkm::cont::ArrayHandle<T, ST1> GetArrayHandle1(
const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static Array1 GetArrayHandle1(const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return vtkm::cont::ArrayHandle<T, ST1>(Buffers1(buffers));
return Array1(GetBuffers(buffers, 1));
}
VTKM_CONT static vtkm::cont::ArrayHandle<T, ST2> GetArrayHandle2(
const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static Array2 GetArrayHandle2(const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return vtkm::cont::ArrayHandle<T, ST2>(Buffers2(buffers));
return Array2(GetBuffers(buffers, 2));
}
VTKM_CONT static vtkm::cont::ArrayHandle<T, ST3> GetArrayHandle3(
const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static Array3 GetArrayHandle3(const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return vtkm::cont::ArrayHandle<T, ST3>(Buffers3(buffers));
return Array3(GetBuffers(buffers, 3));
}
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers(
const Array1& array1 = Array1{},
const Array2& array2 = Array2{},
const Array3& array3 = Array3{})
{
const std::vector<vtkm::cont::internal::Buffer>& buffers1 = array1.GetBuffers();
const std::vector<vtkm::cont::internal::Buffer>& buffers2 = array2.GetBuffers();
const std::vector<vtkm::cont::internal::Buffer>& buffers3 = array3.GetBuffers();
Info info;
info.BufferOffset[0] = 1;
info.BufferOffset[1] = info.BufferOffset[0] + buffers1.size();
info.BufferOffset[2] = info.BufferOffset[1] + buffers2.size();
info.BufferOffset[3] = info.BufferOffset[2] + buffers3.size();
return vtkm::cont::internal::CreateBuffers(info, buffers1, buffers2, buffers3);
}
};
} // namespace internal
@ -335,7 +350,7 @@ public:
ArrayHandleCartesianProduct(const FirstHandleType& firstArray,
const SecondHandleType& secondArray,
const ThirdHandleType& thirdArray)
: Superclass(vtkm::cont::internal::CreateBuffers(firstArray, secondArray, thirdArray))
: Superclass(StorageType::CreateBuffers(firstArray, secondArray, thirdArray))
{
}

@ -20,6 +20,7 @@
#include <vtkmstd/integer_sequence.h>
#include <numeric>
#include <type_traits>
namespace vtkm
@ -169,31 +170,6 @@ struct VerifyArrayHandle
"must be a list of ArrayHandle types.");
};
template <std::size_t I>
struct BufferIndexImpl
{
template <typename... Ts>
static constexpr vtkm::IdComponent Value(vtkm::IdComponent n, Ts... remaining)
{
return n + BufferIndexImpl<I - 1>::Value(remaining...);
}
};
template <>
struct BufferIndexImpl<0>
{
template <typename... Ts>
static constexpr vtkm::IdComponent Value(Ts...)
{
return 0;
}
};
template <std::size_t I, typename... StorageTypes>
constexpr vtkm::IdComponent BufferIndex()
{
return BufferIndexImpl<I>::Value(StorageTypes::GetNumberOfBuffers()...);
}
} // end namespace compvec
} // namespace internal
@ -226,21 +202,31 @@ class Storage<vtkm::Vec<T, static_cast<vtkm::IdComponent>(sizeof...(StorageTags)
{
using ValueType = vtkm::Vec<T, static_cast<vtkm::IdComponent>(sizeof...(StorageTags))>;
struct Info
{
std::array<std::size_t, sizeof...(StorageTags) + 1> BufferOffset;
};
template <typename S>
using StorageFor = vtkm::cont::internal::Storage<T, S>;
using StorageTuple = vtkm::Tuple<StorageFor<StorageTags>...>;
template <std::size_t I>
VTKM_CONT static constexpr vtkm::IdComponent BufferIndex()
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> GetBuffers(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
std::size_t subArray)
{
return compvec::BufferIndex<I, StorageFor<StorageTags>...>();
Info info = buffers[0].GetMetaData<Info>();
return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() + info.BufferOffset[subArray],
buffers.begin() +
info.BufferOffset[subArray + 1]);
}
template <std::size_t I, typename Buff>
VTKM_CONT static Buff* Buffers(Buff* buffers)
template <std::size_t I>
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> Buffers(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return buffers + BufferIndex<I>();
return GetBuffers(buffers, I);
}
using IndexList = vtkmstd::make_index_sequence<sizeof...(StorageTags)>;
@ -255,19 +241,21 @@ private:
template <std::size_t... Is>
static void ResizeBuffersImpl(vtkmstd::index_sequence<Is...>,
vtkm::Id numValues,
vtkm::cont::internal::Buffer* buffers,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::CopyFlag preserve,
vtkm::cont::Token& token)
{
std::vector<std::vector<vtkm::cont::internal::Buffer>> bufferPartitions = { Buffers<Is>(
buffers)... };
auto init_list = { (vtkm::tuple_element_t<Is, StorageTuple>::ResizeBuffers(
numValues, Buffers<Is>(buffers), preserve, token),
numValues, bufferPartitions[Is], preserve, token),
false)... };
(void)init_list;
}
template <std::size_t... Is>
static void FillImpl(vtkmstd::index_sequence<Is...>,
vtkm::cont::internal::Buffer* buffers,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
const ValueType& fillValue,
vtkm::Id startIndex,
vtkm::Id endIndex,
@ -284,45 +272,43 @@ private:
}
template <std::size_t... Is>
static ReadPortalType CreateReadPortalImpl(vtkmstd::index_sequence<Is...>,
const vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
static ReadPortalType CreateReadPortalImpl(
vtkmstd::index_sequence<Is...>,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return ReadPortalType(vtkm::tuple_element_t<Is, StorageTuple>::CreateReadPortal(
Buffers<Is>(buffers), device, token)...);
}
template <std::size_t... Is>
static WritePortalType CreateWritePortalImpl(vtkmstd::index_sequence<Is...>,
vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
static WritePortalType CreateWritePortalImpl(
vtkmstd::index_sequence<Is...>,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return WritePortalType(vtkm::tuple_element_t<Is, StorageTuple>::CreateWritePortal(
Buffers<Is>(buffers), device, token)...);
}
public:
VTKM_CONT constexpr static vtkm::IdComponent GetNumberOfBuffers()
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return BufferIndex<sizeof...(StorageTags)>();
}
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
{
return vtkm::TupleElement<0, StorageTuple>::GetNumberOfValues(buffers);
return vtkm::TupleElement<0, StorageTuple>::GetNumberOfValues(Buffers<0>(buffers));
}
VTKM_CONT static void ResizeBuffers(vtkm::Id numValues,
vtkm::cont::internal::Buffer* buffers,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::CopyFlag preserve,
vtkm::cont::Token& token)
{
ResizeBuffersImpl(IndexList{}, numValues, buffers, preserve, token);
}
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer* buffers,
VTKM_CONT static void Fill(const std::vector<vtkm::cont::internal::Buffer>& buffers,
const ValueType& fillValue,
vtkm::Id startIndex,
vtkm::Id endIndex,
@ -331,65 +317,51 @@ public:
FillImpl(IndexList{}, buffers, fillValue, startIndex, endIndex, token);
}
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return CreateReadPortalImpl(IndexList{}, buffers, device, token);
}
VTKM_CONT static WritePortalType CreateWritePortal(vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static WritePortalType CreateWritePortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return CreateWritePortalImpl(IndexList{}, buffers, device, token);
}
private:
template <typename ArrayType>
VTKM_CONT static bool CopyBuffers(const ArrayType& array,
vtkm::cont::internal::Buffer* destBuffers)
{
vtkm::IdComponent numBuffers = array.GetNumberOfBuffers();
const vtkm::cont::internal::Buffer* srcBuffers = array.GetBuffers();
for (vtkm::IdComponent buffIndex = 0; buffIndex < numBuffers; ++buffIndex)
{
destBuffers[buffIndex] = srcBuffers[buffIndex];
}
return false; // Return value does not matter. Hopefully just thrown away by compiler.
}
template <std::size_t... Is, typename... ArrayTs>
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffersImpl(
vtkmstd::index_sequence<Is...>,
const ArrayTs... arrays)
{
std::vector<vtkm::cont::internal::Buffer> buffers(
static_cast<std::size_t>(GetNumberOfBuffers()));
auto init_list = { CopyBuffers(arrays, Buffers<Is>(&buffers.front()))... };
(void)init_list;
return buffers;
}
public:
template <typename... ArrayTs>
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers(const ArrayTs... arrays)
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers(
const vtkm::cont::ArrayHandle<T, StorageTags>&... arrays)
{
return CreateBuffersImpl(IndexList{}, arrays...);
auto numBuffers = { std::size_t{ 1 }, arrays.GetBuffers().size()... };
Info info;
std::partial_sum(numBuffers.begin(), numBuffers.end(), info.BufferOffset.begin());
return vtkm::cont::internal::CreateBuffers(info, arrays...);
}
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers()
{
return CreateBuffers(vtkm::cont::ArrayHandle<T, StorageTags>{}...);
}
private:
using ArrayTupleType = vtkm::Tuple<vtkm::cont::ArrayHandle<T, StorageTags>...>;
template <std::size_t... Is>
VTKM_CONT static ArrayTupleType GetArrayTupleImpl(vtkmstd::index_sequence<Is...>,
const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static ArrayTupleType GetArrayTupleImpl(
vtkmstd::index_sequence<Is...>,
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return ArrayTupleType(vtkm::cont::ArrayHandle<T, StorageTags>(Buffers<Is>(buffers))...);
}
public:
VTKM_CONT static ArrayTupleType GetArrayTuple(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static ArrayTupleType GetArrayTuple(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return GetArrayTupleImpl(IndexList{}, buffers);
}
@ -400,13 +372,13 @@ template <typename T, typename StorageTag>
struct Storage<T, vtkm::cont::StorageTagCompositeVec<StorageTag>> : Storage<T, StorageTag>
{
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers(
const vtkm::cont::ArrayHandle<T, StorageTag>& array)
const vtkm::cont::ArrayHandle<T, StorageTag>& array = vtkm::cont::ArrayHandle<T, StorageTag>{})
{
return vtkm::cont::internal::CreateBuffers(array);
}
VTKM_CONT static vtkm::Tuple<vtkm::cont::ArrayHandle<T, StorageTag>> GetArrayTuple(
const vtkm::cont::internal::Buffer* buffers)
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return vtkm::cont::ArrayHandle<T, StorageTag>(buffers);
}

@ -169,16 +169,26 @@ class Storage<T, StorageTagConcatenate<ST1, ST2>>
using ArrayHandleType1 = typename detail::ConcatinateTypeArg<T, ST1>::ArrayHandle;
using ArrayHandleType2 = typename detail::ConcatinateTypeArg<T, ST2>::ArrayHandle;
template <typename Buff>
VTKM_CONT static Buff* Buffers1(Buff* buffers)
struct Info
{
return buffers;
std::size_t NumBuffers1;
std::size_t NumBuffers2;
};
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> Buffers1(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
Info info = buffers[0].GetMetaData<Info>();
return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() + 1,
buffers.begin() + 1 + info.NumBuffers1);
}
template <typename Buff>
VTKM_CONT static Buff* Buffers2(Buff* buffers)
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> Buffers2(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return buffers + SourceStorage1::GetNumberOfBuffers();
Info info = buffers[0].GetMetaData<Info>();
return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() + 1 + info.NumBuffers1,
buffers.end());
}
public:
@ -191,18 +201,14 @@ public:
vtkm::internal::ArrayPortalConcatenate<typename SourceStorage1::WritePortalType,
typename SourceStorage2::WritePortalType>;
VTKM_CONT static constexpr vtkm::IdComponent GetNumberOfBuffers()
{
return (SourceStorage1::GetNumberOfBuffers() + SourceStorage2::GetNumberOfBuffers());
}
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return (SourceStorage1::GetNumberOfValues(Buffers1(buffers)) +
SourceStorage2::GetNumberOfValues(Buffers2(buffers)));
}
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer* buffers,
VTKM_CONT static void Fill(const std::vector<vtkm::cont::internal::Buffer>& buffers,
const T& fillValue,
vtkm::Id startIndex,
vtkm::Id endIndex,
@ -225,35 +231,42 @@ public:
}
}
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return ReadPortalType(SourceStorage1::CreateReadPortal(Buffers1(buffers), device, token),
SourceStorage2::CreateReadPortal(Buffers2(buffers), device, token));
}
VTKM_CONT static WritePortalType CreateWritePortal(vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static WritePortalType CreateWritePortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return WritePortalType(SourceStorage1::CreateWritePortal(Buffers1(buffers), device, token),
SourceStorage2::CreateWritePortal(Buffers2(buffers), device, token));
}
VTKM_CONT static auto CreateBuffers(const ArrayHandleType1& array1,
const ArrayHandleType2& array2)
VTKM_CONT static auto CreateBuffers(const ArrayHandleType1& array1 = ArrayHandleType1{},
const ArrayHandleType2& array2 = ArrayHandleType2{})
-> decltype(vtkm::cont::internal::CreateBuffers())
{
return vtkm::cont::internal::CreateBuffers(array1, array2);
Info info;
info.NumBuffers1 = array1.GetBuffers().size();
info.NumBuffers2 = array2.GetBuffers().size();
return vtkm::cont::internal::CreateBuffers(info, array1, array2);
}
VTKM_CONT static const ArrayHandleType1 GetArray1(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static const ArrayHandleType1 GetArray1(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return ArrayHandleType1(Buffers1(buffers));
}
VTKM_CONT static const ArrayHandleType2 GetArray2(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static const ArrayHandleType2 GetArray2(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return ArrayHandleType2(Buffers2(buffers));
}

@ -24,6 +24,7 @@
#include <vtkmstd/integer_sequence.h>
#include <numeric>
#include <type_traits>
#include <utility>
@ -306,35 +307,22 @@ using GetWritePortalList =
std::declval<vtkm::cont::DeviceAdapterId>(),
std::declval<vtkm::cont::Token&>())))...>;
template <vtkm::IdComponent I, typename ArrayTupleType>
struct BufferIndexImpl
{
static constexpr vtkm::IdComponent Value()
{
return BufferIndexImpl<I - 1, ArrayTupleType>::Value() +
vtkm::TupleElement<I - 1, ArrayTupleType>::GetNumberOfBuffers();
}
};
template <typename ArrayTupleType>
struct BufferIndexImpl<0, ArrayTupleType>
{
static constexpr vtkm::IdComponent Value()
{
// One buffer reserved for metadata.
return 1;
}
};
template <typename DecoratorImplT>
template <typename DecoratorImplT, std::size_t NumArrays>
struct DecoratorMetaData
{
DecoratorImplT Implementation;
vtkm::Id NumberOfValues = 0;
std::array<std::size_t, NumArrays + 1> BufferOffsets;
DecoratorMetaData(const DecoratorImplT& implementation, vtkm::Id numValues)
template <typename... ArrayTs>
DecoratorMetaData(const DecoratorImplT& implementation,
vtkm::Id numValues,
const ArrayTs... arrays)
: Implementation(implementation)
, NumberOfValues(numValues)
{
auto numBuffers = { std::size_t{ 1 }, arrays.GetBuffers().size()... };
std::partial_sum(numBuffers.begin(), numBuffers.end(), this->BufferOffsets.begin());
}
DecoratorMetaData() = default;
@ -363,26 +351,22 @@ struct DecoratorStorageTraits
// size_t integral constants that index ArrayTs:
using IndexList = vtkmstd::make_index_sequence<sizeof...(ArrayTs)>;
// Returns the index into the buffers array for the array at the given index.
template <vtkm::IdComponent I>
static constexpr vtkm::IdComponent BufferIndex()
using MetaData = DecoratorMetaData<DecoratorImplT, sizeof...(ArrayTs)>;
static MetaData& GetMetaData(const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return BufferIndexImpl<I, ArrayTupleType>::Value();
return buffers[0].GetMetaData<MetaData>();
}
// Converts a buffers array to the ArrayHandle at the given index.
template <vtkm::IdComponent I>
static vtkm::TupleElement<I, ArrayTupleType> BuffersToArray(
const vtkm::cont::internal::Buffer* buffers)
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return vtkm::TupleElement<I, ArrayTupleType>(buffers + BufferIndex<I>());
}
using MetaData = DecoratorMetaData<DecoratorImplT>;
static MetaData& GetMetaData(const vtkm::cont::internal::Buffer* buffers)
{
return buffers[0].GetMetaData<MetaData>();
const MetaData& metaData = GetMetaData(buffers);
std::vector<vtkm::cont::internal::Buffer> subBuffers(
buffers.begin() + metaData.BufferOffsets[I], buffers.begin() + metaData.BufferOffsets[I + 1]);
return vtkm::TupleElement<I, ArrayTupleType>(std::move(subBuffers));
}
// true_type/false_type depending on whether the decorator supports Allocate:
@ -440,7 +424,7 @@ struct DecoratorStorageTraits
// Static dispatch for calling AllocateSourceArrays on supported implementations:
VTKM_CONT [[noreturn]] static void CallAllocate(std::false_type,
vtkm::Id,
vtkm::cont::internal::Buffer*,
const std::vector<vtkm::cont::internal::Buffer>&,
vtkm::CopyFlag,
vtkm::cont::Token&,
ArrayTs...)
@ -450,7 +434,7 @@ struct DecoratorStorageTraits
VTKM_CONT static void CallAllocate(std::true_type,
vtkm::Id newSize,
vtkm::cont::internal::Buffer* buffers,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::CopyFlag preserve,
vtkm::cont::Token& token,
ArrayTs... arrays)
@ -463,11 +447,12 @@ struct DecoratorStorageTraits
// Portal construction methods. These actually create portals.
template <std::size_t... Indices>
VTKM_CONT static WritePortalType CreateWritePortal(const vtkm::cont::internal::Buffer* buffers,
vtkm::Id numValues,
vtkmstd::index_sequence<Indices...>,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static WritePortalType CreateWritePortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::Id numValues,
vtkmstd::index_sequence<Indices...>,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return CreatePortalDecorator<WritePortalType>(
numValues,
@ -476,11 +461,12 @@ struct DecoratorStorageTraits
}
template <std::size_t... Indices>
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
vtkm::Id numValues,
vtkmstd::index_sequence<Indices...>,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::Id numValues,
vtkmstd::index_sequence<Indices...>,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return CreatePortalDecorator<ReadPortalType>(
numValues,
@ -489,11 +475,12 @@ struct DecoratorStorageTraits
}
template <std::size_t... Indices>
VTKM_CONT static void AllocateSourceArrays(vtkm::Id numValues,
vtkm::cont::internal::Buffer* buffers,
vtkm::CopyFlag preserve,
vtkm::cont::Token& token,
vtkmstd::index_sequence<Indices...>)
VTKM_CONT static void AllocateSourceArrays(
vtkm::Id numValues,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::CopyFlag preserve,
vtkm::cont::Token& token,
vtkmstd::index_sequence<Indices...>)
{
CallAllocate(
IsAllocatable{}, numValues, buffers, preserve, token, BuffersToArray<Indices>(buffers)...);
@ -519,18 +506,14 @@ public:
using ReadPortalType = typename Traits::ReadPortalType;
using WritePortalType = typename Traits::WritePortalType;
VTKM_CONT constexpr static vtkm::IdComponent GetNumberOfBuffers()
{
return Traits::template BufferIndex<static_cast<vtkm::IdComponent>(sizeof...(ArrayTs))>();
}
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return Traits::GetMetaData(buffers).NumberOfValues;
}
VTKM_CONT static void ResizeBuffers(vtkm::Id numValues,
vtkm::cont::internal::Buffer* buffers,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::CopyFlag preserve,
vtkm::cont::Token& token)
{
@ -545,17 +528,19 @@ public:
}
}
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return Traits::CreateReadPortal(
buffers, GetNumberOfValues(buffers), IndexList{}, device, token);
}
VTKM_CONT static WritePortalType CreateWritePortal(vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static WritePortalType CreateWritePortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return Traits::CreateWritePortal(
buffers, GetNumberOfValues(buffers), IndexList{}, device, token);
@ -564,7 +549,13 @@ public:
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer>
CreateBuffers(const DecoratorImplT& implementation, vtkm::Id numValues, const ArrayTs&... arrays)
{
return vtkm::cont::internal::CreateBuffers(MetaData(implementation, numValues), arrays...);
return vtkm::cont::internal::CreateBuffers(MetaData(implementation, numValues, arrays...),
arrays...);
}
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers()
{
return CreateBuffers(DecoratorImplT{}, 0, ArrayTs{}...);
}
};

@ -103,10 +103,15 @@ public:
// you actually try to use this read portal.
using ReadPortalType = vtkm::exec::internal::ArrayPortalDiscard<ValueType>;
VTKM_CONT constexpr static vtkm::IdComponent GetNumberOfBuffers() { return 1; }
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers()
{
DiscardMetaData metaData;
metaData.NumberOfValues = 0;
return vtkm::cont::internal::CreateBuffers(metaData);
}
VTKM_CONT static void ResizeBuffers(vtkm::Id numValues,
vtkm::cont::internal::Buffer* buffers,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::CopyFlag,
vtkm::cont::Token&)
{
@ -114,12 +119,13 @@ public:
buffers[0].GetMetaData<DiscardMetaData>().NumberOfValues = numValues;
}
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return buffers[0].GetMetaData<DiscardMetaData>().NumberOfValues;
}
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer*,
VTKM_CONT static void Fill(const std::vector<vtkm::cont::internal::Buffer>&,
const ValueType&,
vtkm::Id,
vtkm::Id,
@ -128,16 +134,17 @@ public:
// Fill is a NO-OP.
}
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer*,
VTKM_CONT static ReadPortalType CreateReadPortal(const std::vector<vtkm::cont::internal::Buffer>&,
vtkm::cont::DeviceAdapterId,
vtkm::cont::Token&)
{
throw vtkm::cont::ErrorBadValue("Cannot read from ArrayHandleDiscard.");
}
VTKM_CONT static WritePortalType CreateWritePortal(vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId,
vtkm::cont::Token&)
VTKM_CONT static WritePortalType CreateWritePortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId,
vtkm::cont::Token&)
{
return WritePortalType(GetNumberOfValues(buffers));
}

@ -44,13 +44,8 @@ public:
{
}
// Copy constructor
VTKM_EXEC_CONT ArrayPortalExtractComponent(const ArrayPortalExtractComponent<PortalType>& src)
: Portal(src.Portal)
, Component(src.Component)
{
}
ArrayPortalExtractComponent(const ArrayPortalExtractComponent&) = default;
ArrayPortalExtractComponent(ArrayPortalExtractComponent&&) = default;
ArrayPortalExtractComponent& operator=(const ArrayPortalExtractComponent&) = default;
ArrayPortalExtractComponent& operator=(ArrayPortalExtractComponent&&) = default;
@ -103,15 +98,16 @@ class Storage<typename vtkm::VecTraits<typename ArrayHandleType::ValueType>::Com
using SourceStorage = vtkm::cont::internal::Storage<SourceValueType, SourceStorageTag>;
public:
VTKM_CONT static vtkm::IdComponent ComponentIndex(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::IdComponent ComponentIndex(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return buffers[0].GetMetaData<vtkm::IdComponent>();
}
template <typename Buff>
VTKM_CONT static Buff* SourceBuffers(Buff* buffers)
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> SourceBuffers(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return buffers + 1;
return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() + 1, buffers.end());
}
using ReadPortalType =
@ -119,17 +115,13 @@ public:
using WritePortalType =
vtkm::internal::ArrayPortalExtractComponent<typename SourceStorage::WritePortalType>;
VTKM_CONT constexpr static vtkm::IdComponent GetNumberOfBuffers()
{
return SourceStorage::GetNumberOfBuffers() + 1;
}
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return SourceStorage::GetNumberOfValues(SourceBuffers(buffers));
}
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer*,
VTKM_CONT static void Fill(const std::vector<vtkm::cont::internal::Buffer>&,
const ValueType&,
vtkm::Id,
vtkm::Id,
@ -139,31 +131,33 @@ public:
}
VTKM_CONT static void ResizeBuffers(vtkm::Id numValues,
vtkm::cont::internal::Buffer* buffers,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::CopyFlag preserve,
vtkm::cont::Token& token)
{
SourceStorage::ResizeBuffers(numValues, SourceBuffers(buffers), preserve, token);
}
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return ReadPortalType(SourceStorage::CreateReadPortal(SourceBuffers(buffers), device, token),
ComponentIndex(buffers));
}
VTKM_CONT static WritePortalType CreateWritePortal(vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static WritePortalType CreateWritePortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return WritePortalType(SourceStorage::CreateWritePortal(SourceBuffers(buffers), device, token),
ComponentIndex(buffers));
}
VTKM_CONT static auto CreateBuffers(vtkm::IdComponent componentIndex,
const ArrayHandleType& array)
VTKM_CONT static auto CreateBuffers(vtkm::IdComponent componentIndex = 0,
const ArrayHandleType& array = ArrayHandleType{})
-> decltype(vtkm::cont::internal::CreateBuffers())
{
return vtkm::cont::internal::CreateBuffers(componentIndex, array);

@ -128,26 +128,27 @@ public:
vtkm::internal::ArrayPortalGroupVec<typename ComponentsStorage::WritePortalType,
NUM_COMPONENTS>;
VTKM_CONT constexpr static vtkm::IdComponent GetNumberOfBuffers()
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers()
{
return ComponentsStorage::GetNumberOfBuffers();
return ComponentsStorage::CreateBuffers();
}
VTKM_CONT static void ResizeBuffers(vtkm::Id numValues,
vtkm::cont::internal::Buffer* buffers,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::CopyFlag preserve,
vtkm::cont::Token& token)
{
ComponentsStorage::ResizeBuffers(NUM_COMPONENTS * numValues, buffers, preserve, token);
}
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
vtkm::Id componentsSize = ComponentsStorage::GetNumberOfValues(buffers);
return componentsSize / NUM_COMPONENTS;
}
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer*,
VTKM_CONT static void Fill(const std::vector<vtkm::cont::internal::Buffer>&,
const ValueType&,
vtkm::Id,
vtkm::Id,
@ -156,9 +157,10 @@ public:
throw vtkm::cont::ErrorBadType("Fill not supported for ArrayHandleGroupVec.");
}
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
if ((ComponentsStorage::GetNumberOfValues(buffers) % NUM_COMPONENTS) != 0)
{
@ -168,9 +170,10 @@ public:
return ReadPortalType(ComponentsStorage::CreateReadPortal(buffers, device, token));
}
VTKM_CONT static WritePortalType CreateWritePortal(vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static WritePortalType CreateWritePortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
if ((ComponentsStorage::GetNumberOfValues(buffers) % NUM_COMPONENTS) != 0)
{

@ -122,20 +122,32 @@ class Storage<vtkm::VecFromPortal<ComponentsPortal>,
using ComponentsStorage = vtkm::cont::internal::Storage<ComponentType, ComponentsStorageTag>;
using OffsetsStorage = vtkm::cont::internal::Storage<vtkm::Id, OffsetsStorageTag>;
using ComponentsArray = vtkm::cont::ArrayHandle<ComponentType, ComponentsStorageTag>;
using OffsetsArray = vtkm::cont::ArrayHandle<vtkm::Id, OffsetsStorageTag>;
VTKM_STATIC_ASSERT_MSG(
(std::is_same<ComponentsPortal, typename ComponentsStorage::WritePortalType>::value),
"Used invalid ComponentsPortal type with expected ComponentsStorageTag.");
template <typename Buff>
VTKM_CONT static Buff* ComponentsBuffers(Buff* buffers)
struct Info
{
return buffers;
std::size_t OffsetsBuffersOffset;
};
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> ComponentsBuffers(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
Info info = buffers[0].GetMetaData<Info>();
return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() + 1,
buffers.begin() + info.OffsetsBuffersOffset);
}
template <typename Buff>
VTKM_CONT static Buff* OffsetsBuffers(Buff* buffers)
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> OffsetsBuffers(
const std::vector<vtkm::cont::internal::Buffer> buffers)
{
return buffers + ComponentsStorage::GetNumberOfBuffers();
Info info = buffers[0].GetMetaData<Info>();
return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() + info.OffsetsBuffersOffset,
buffers.end());
}
public:
@ -148,17 +160,13 @@ public:
vtkm::internal::ArrayPortalGroupVecVariable<typename ComponentsStorage::WritePortalType,
typename OffsetsStorage::ReadPortalType>;
VTKM_CONT static vtkm::IdComponent GetNumberOfBuffers()
{
return ComponentsStorage::GetNumberOfBuffers() + OffsetsStorage::GetNumberOfBuffers();
}
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return OffsetsStorage::GetNumberOfValues(OffsetsBuffers(buffers)) - 1;
}
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer*,
VTKM_CONT static void Fill(const std::vector<vtkm::cont::internal::Buffer>&,
const vtkm::VecFromPortal<ComponentsPortal>&,
vtkm::Id,
vtkm::Id,
@ -167,18 +175,20 @@ public:
throw vtkm::cont::ErrorBadType("Fill not supported for ArrayHandleGroupVecVariable.");
}
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return ReadPortalType(
ComponentsStorage::CreateReadPortal(ComponentsBuffers(buffers), device, token),
OffsetsStorage::CreateReadPortal(OffsetsBuffers(buffers), device, token));
}
VTKM_CONT static WritePortalType CreateWritePortal(vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static WritePortalType CreateWritePortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return WritePortalType(
ComponentsStorage::CreateWritePortal(ComponentsBuffers(buffers), device, token),
@ -186,31 +196,24 @@ public:
}
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers(
const vtkm::cont::ArrayHandle<ComponentType, ComponentsStorageTag>& componentsArray,
const vtkm::cont::ArrayHandle<vtkm::Id, OffsetsStorageTag>& offsetsArray)
const ComponentsArray& componentsArray = ComponentsArray{},
const OffsetsArray& offsetsArray = OffsetsArray{})
{
std::vector<vtkm::cont::internal::Buffer> destBuffer(
static_cast<std::size_t>(GetNumberOfBuffers()));
auto destIter = destBuffer.begin();
destIter =
std::copy_n(componentsArray.GetBuffers(), ComponentsStorage::GetNumberOfBuffers(), destIter);
destIter =
std::copy_n(offsetsArray.GetBuffers(), OffsetsStorage::GetNumberOfBuffers(), destIter);
return destBuffer;
Info info;
info.OffsetsBuffersOffset = 1 + componentsArray.GetBuffers().size();
return vtkm::cont::internal::CreateBuffers(info, componentsArray, offsetsArray);
}
VTKM_CONT static vtkm::cont::ArrayHandle<ComponentType, ComponentsStorageTag> GetComponentsArray(
const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static ComponentsArray GetComponentsArray(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return vtkm::cont::ArrayHandle<ComponentType, ComponentsStorageTag>(ComponentsBuffers(buffers));
return ComponentsArray(ComponentsBuffers(buffers));
}
VTKM_CONT static vtkm::cont::ArrayHandle<vtkm::Id, OffsetsStorageTag> GetOffsetsArray(
const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static OffsetsArray GetOffsetsArray(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return vtkm::cont::ArrayHandle<vtkm::Id, OffsetsStorageTag>(OffsetsBuffers(buffers));
return OffsetsArray(OffsetsBuffers(buffers));
}
};

@ -91,34 +91,6 @@ struct VTKM_ALWAYS_EXPORT StorageTagImplicit
namespace internal
{
template <class ArrayPortalType>
struct VTKM_ALWAYS_EXPORT
Storage<typename ArrayPortalType::ValueType, StorageTagImplicit<ArrayPortalType>>
{
VTKM_IS_TRIVIALLY_COPYABLE(ArrayPortalType);
VTKM_STORAGE_NO_RESIZE;
VTKM_STORAGE_NO_WRITE_PORTAL;
using ReadPortalType = ArrayPortalType;
// Implicit array has one buffer that should be empty (NumberOfBytes = 0), but holds
// the metadata for the array.
VTKM_CONT constexpr static vtkm::IdComponent GetNumberOfBuffers() { return 1; }
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
{
return buffers[0].GetMetaData<ArrayPortalType>().GetNumberOfValues();
}
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId,
vtkm::cont::Token&)
{
return buffers[0].GetMetaData<ArrayPortalType>();
}
};
/// Given an array portal, returns the buffers for the `ArrayHandle` with a storage that
/// is (or is compatible with) a storage tag of `StorageTagImplicit<PortalType>`.
template <typename PortalType>
@ -141,6 +113,37 @@ VTKM_CONT inline std::vector<vtkm::cont::internal::Buffer> FunctorToArrayHandleI
vtkm::internal::ArrayPortalImplicit<FunctorType>(functor, numValues));
}
template <class ArrayPortalType>
struct VTKM_ALWAYS_EXPORT
Storage<typename ArrayPortalType::ValueType, StorageTagImplicit<ArrayPortalType>>
{
VTKM_IS_TRIVIALLY_COPYABLE(ArrayPortalType);
VTKM_STORAGE_NO_RESIZE;
VTKM_STORAGE_NO_WRITE_PORTAL;
using ReadPortalType = ArrayPortalType;
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers()
{
return vtkm::cont::internal::PortalToArrayHandleImplicitBuffers(ArrayPortalType{});
}
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return buffers[0].GetMetaData<ArrayPortalType>().GetNumberOfValues();
}
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId,
vtkm::cont::Token&)
{
return buffers[0].GetMetaData<ArrayPortalType>();
}
};
} // namespace internal
namespace detail

@ -151,7 +151,8 @@ namespace detail
struct MultiplexerGetNumberOfValuesFunctor
{
template <typename StorageType>
VTKM_CONT vtkm::Id operator()(StorageType, const vtkm::cont::internal::Buffer* buffers) const
VTKM_CONT vtkm::Id operator()(StorageType,
const std::vector<vtkm::cont::internal::Buffer>& buffers) const
{
return StorageType::GetNumberOfValues(buffers);
}
@ -162,7 +163,7 @@ struct MultiplexerResizeBuffersFunctor
template <typename StorageType>
VTKM_CONT void operator()(StorageType,
vtkm::Id numValues,
vtkm::cont::internal::Buffer* buffers,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::CopyFlag preserve,
vtkm::cont::Token& token) const
{
@ -174,7 +175,7 @@ struct MultiplexerFillFunctor
{
template <typename ValueType, typename StorageType>
VTKM_CONT void operator()(StorageType,
vtkm::cont::internal::Buffer* buffers,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
const ValueType& fillValue,
vtkm::Id startIndex,
vtkm::Id endIndex,
@ -189,7 +190,7 @@ struct MultiplexerCreateReadPortalFunctor
{
template <typename StorageType>
VTKM_CONT ReadPortalType operator()(StorageType,
const vtkm::cont::internal::Buffer* buffers,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token) const
{
@ -202,7 +203,7 @@ struct MultiplexerCreateWritePortalFunctor
{
template <typename StorageType>
VTKM_CONT WritePortalType operator()(StorageType,
vtkm::cont::internal::Buffer* buffers,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token) const
{
@ -217,7 +218,7 @@ struct MultiplexerArrayHandleVariantFunctor
template <typename StorageTag>
VTKM_CONT VariantType operator()(vtkm::cont::internal::Storage<T, StorageTag>,
const vtkm::cont::internal::Buffer* buffers)
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return VariantType(vtkm::cont::ArrayHandle<T, StorageTag>(buffers));
}
@ -233,15 +234,15 @@ class Storage<ValueType, StorageTagMultiplexer<StorageTags...>>
using StorageVariant = vtkm::cont::internal::Variant<StorageFor<StorageTags>...>;
VTKM_CONT static StorageVariant Variant(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static StorageVariant Variant(const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return buffers[0].GetMetaData<StorageVariant>();
}
template <typename Buff>
VTKM_CONT static Buff* ArrayBuffers(Buff* buffers)
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> ArrayBuffers(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return buffers + 1;
return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() + 1, buffers.end());
}
public:
@ -250,19 +251,15 @@ public:
using WritePortalType =
vtkm::internal::ArrayPortalMultiplexer<typename StorageFor<StorageTags>::WritePortalType...>;
VTKM_CONT static constexpr vtkm::IdComponent GetNumberOfBuffers()
{
return std::max({ StorageFor<StorageTags>::GetNumberOfBuffers()... }) + 1;
}
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return Variant(buffers).CastAndCall(detail::MultiplexerGetNumberOfValuesFunctor{},
ArrayBuffers(buffers));
}
VTKM_CONT static void ResizeBuffers(vtkm::Id numValues,
vtkm::cont::internal::Buffer* buffers,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::CopyFlag preserve,
vtkm::cont::Token& token)
{
@ -270,7 +267,7 @@ public:
detail::MultiplexerResizeBuffersFunctor{}, numValues, ArrayBuffers(buffers), preserve, token);
}
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer* buffers,
VTKM_CONT static void Fill(const std::vector<vtkm::cont::internal::Buffer>& buffers,
const ValueType& fillValue,
vtkm::Id startIndex,
vtkm::Id endIndex,
@ -284,9 +281,10 @@ public:
token);
}
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return Variant(buffers).CastAndCall(
detail::MultiplexerCreateReadPortalFunctor<ReadPortalType>{},
@ -295,9 +293,10 @@ public:
token);
}
VTKM_CONT static WritePortalType CreateWritePortal(vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static WritePortalType CreateWritePortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return Variant(buffers).CastAndCall(
detail::MultiplexerCreateWritePortalFunctor<WritePortalType>{},
@ -306,7 +305,7 @@ public:
token);
}
VTKM_CONT static bool IsValid(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static bool IsValid(const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return Variant(buffers).IsValid();
}
@ -315,21 +314,17 @@ public:
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers(const ArrayType& array)
{
VTKM_IS_ARRAY_HANDLE(ArrayType);
std::vector<vtkm::cont::internal::Buffer> buffers =
vtkm::cont::internal::CreateBuffers(StorageVariant{ array.GetStorage() }, array);
return vtkm::cont::internal::CreateBuffers(StorageVariant{ array.GetStorage() }, array);
}
// Some arrays will require different numbers of buffers. Make sure we size the buffers
// array to accomodate any such one to avoid any troubles.
std::size_t numBuffers = static_cast<std::size_t>(GetNumberOfBuffers());
VTKM_ASSERT(numBuffers >= buffers.size());
buffers.resize(numBuffers);
return buffers;
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers()
{
return vtkm::cont::internal::CreateBuffers(StorageVariant{});
}
VTKM_CONT static
typename detail::MultiplexerArrayHandleVariantFunctor<ValueType, StorageTags...>::VariantType
GetArrayHandleVariant(const vtkm::cont::internal::Buffer* buffers)
GetArrayHandleVariant(const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return Variant(buffers).CastAndCall(
detail::MultiplexerArrayHandleVariantFunctor<ValueType, StorageTags...>{},

@ -71,12 +71,13 @@ public:
using ReadPortalType =
vtkm::internal::ArrayPortalOffsetsToNumComponents<typename OffsetsStorage::ReadPortalType>;
VTKM_CONT static constexpr vtkm::IdComponent GetNumberOfBuffers()
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers()
{
return OffsetsStorage::GetNumberOfBuffers();
return OffsetsStorage::CreateBuffers();
}
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
vtkm::Id numOffsets = OffsetsStorage::GetNumberOfValues(buffers);
if (numOffsets < 1)
@ -87,9 +88,10 @@ public:
return numOffsets - 1;
}
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
VTKM_ASSERT(OffsetsStorage::GetNumberOfValues(buffers) > 0);
return ReadPortalType(OffsetsStorage::CreateReadPortal(buffers, device, token));

@ -109,15 +109,27 @@ class Storage<T, vtkm::cont::StorageTagPermutation<IndexStorageTag, ValueStorage
using IndexStorage = vtkm::cont::internal::Storage<vtkm::Id, IndexStorageTag>;
using ValueStorage = vtkm::cont::internal::Storage<T, ValueStorageTag>;
template <typename Buff>
VTKM_CONT constexpr static Buff* IndexBuffers(Buff* buffers)
using IndexArray = vtkm::cont::ArrayHandle<vtkm::Id, IndexStorageTag>;
using ValueArray = vtkm::cont::ArrayHandle<T, ValueStorageTag>;
struct Info
{
return buffers;
std::size_t ValueBufferOffset;
};
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> IndexBuffers(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
Info info = buffers[0].GetMetaData<Info>();
return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() + 1,
buffers.begin() + info.ValueBufferOffset);
}
template <typename Buff>
VTKM_CONT constexpr static Buff* ValueBuffers(Buff* buffers)
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> ValueBuffers(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return buffers + IndexStorage::GetNumberOfBuffers();
Info info = buffers[0].GetMetaData<Info>();
return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() + info.ValueBufferOffset,
buffers.end());
}
public:
@ -130,17 +142,13 @@ public:
vtkm::internal::ArrayPortalPermutation<typename IndexStorage::ReadPortalType,
typename ValueStorage::WritePortalType>;
VTKM_CONT constexpr static vtkm::IdComponent GetNumberOfBuffers()
{
return (IndexStorage::GetNumberOfBuffers() + ValueStorage::GetNumberOfBuffers());
}
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return IndexStorage::GetNumberOfValues(IndexBuffers(buffers));
}
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer*,
VTKM_CONT static void Fill(const std::vector<vtkm::cont::internal::Buffer>&,
const T&,
vtkm::Id,
vtkm::Id,
@ -149,33 +157,44 @@ public:
throw vtkm::cont::ErrorBadType("Fill not supported for ArrayHandlePermutation.");
}
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return ReadPortalType(IndexStorage::CreateReadPortal(IndexBuffers(buffers), device, token),
ValueStorage::CreateReadPortal(ValueBuffers(buffers), device, token));
}
VTKM_CONT static WritePortalType CreateWritePortal(vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static WritePortalType CreateWritePortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
// Note: the index portal is always a read-only portal.
return WritePortalType(IndexStorage::CreateReadPortal(IndexBuffers(buffers), device, token),
ValueStorage::CreateWritePortal(ValueBuffers(buffers), device, token));
}
VTKM_CONT static vtkm::cont::ArrayHandle<vtkm::Id, IndexStorageTag> GetIndexArray(
const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers(
const IndexArray& indexArray = IndexArray{},
const ValueArray& valueArray = ValueArray{})
{
return vtkm::cont::ArrayHandle<vtkm::Id, IndexStorageTag>(IndexBuffers(buffers));
Info info;
info.ValueBufferOffset = 1 + indexArray.GetBuffers().size();
return vtkm::cont::internal::CreateBuffers(info, indexArray, valueArray);
}
VTKM_CONT static vtkm::cont::ArrayHandle<T, ValueStorageTag> GetValueArray(
const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static IndexArray GetIndexArray(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return vtkm::cont::ArrayHandle<T, ValueStorageTag>(ValueBuffers(buffers));
return IndexArray(IndexBuffers(buffers));
}
VTKM_CONT static ValueArray GetValueArray(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return ValueArray(ValueBuffers(buffers));
}
};
@ -236,7 +255,7 @@ public:
VTKM_CONT
ArrayHandlePermutation(const IndexArrayHandleType& indexArray,
const ValueArrayHandleType& valueArray)
: Superclass(vtkm::cont::internal::CreateBuffers(indexArray, valueArray))
: Superclass(StorageType::CreateBuffers(indexArray, valueArray))
{
}

@ -355,18 +355,10 @@ struct StorageTagRecombineVec
namespace detail
{
// Note: Normally a decorating ArrayHandle holds the buffers of the arrays it is decorating
// in its list of arrays. However, the numbers of buffers is expected to be compile-time static
// and ArrayHandleRecombineVec needs to set the number of buffers at runtime. We cheat around
// this by stuffing the decorated buffers in the metadata. To make sure deep copies work
// right, a copy of the metadata results in a deep copy of the contained buffers. The
// vtkm::cont::internal::Buffer holding the metadata is not supposed to copy the metadata
// except for a deep copy (and when it is first set). If this behavior changes, there could
// be a performance degredation.
struct RecombineVecMetaData
{
mutable std::vector<vtkm::cont::internal::Buffer> PortalBuffers;
std::vector<std::vector<vtkm::cont::internal::Buffer>> ArrayBuffers;
std::vector<std::size_t> ArrayBufferOffsets;
RecombineVecMetaData() = default;
@ -374,17 +366,7 @@ struct RecombineVecMetaData
RecombineVecMetaData& operator=(const RecombineVecMetaData& src)
{
this->ArrayBuffers.resize(src.ArrayBuffers.size());
for (std::size_t arrayIndex = 0; arrayIndex < src.ArrayBuffers.size(); ++arrayIndex)
{
this->ArrayBuffers[arrayIndex].resize(src.ArrayBuffers[arrayIndex].size());
for (std::size_t bufferIndex = 0; bufferIndex < src.ArrayBuffers[arrayIndex].size();
++bufferIndex)
{
this->ArrayBuffers[arrayIndex][bufferIndex].DeepCopyFrom(
src.ArrayBuffers[arrayIndex][bufferIndex]);
}
}
this->ArrayBufferOffsets = src.ArrayBufferOffsets;
this->PortalBuffers.clear();
// Intentionally not copying portals. Portals will be recreated from proper array when requsted.
@ -414,13 +396,15 @@ class Storage<vtkm::internal::RecombineVec<ReadWritePortal>,
VTKM_STATIC_ASSERT(
(std::is_same<ReadWritePortal, detail::RecombinedPortalType<ComponentType>>::value));
template <typename Buff>
VTKM_CONT static Buff* BuffersForComponent(Buff* buffers, vtkm::IdComponent componentIndex)
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> BuffersForComponent(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::IdComponent componentIndex)
{
return buffers[0]
.template GetMetaData<detail::RecombineVecMetaData>()
.ArrayBuffers[componentIndex]
.data();
auto& metaData = buffers[0].GetMetaData<detail::RecombineVecMetaData>();
std::size_t index = static_cast<std::size_t>(componentIndex);
return std::vector<vtkm::cont::internal::Buffer>(
buffers.begin() + metaData.ArrayBufferOffsets[index],
buffers.begin() + metaData.ArrayBufferOffsets[index + 1]);
}
public:
@ -429,20 +413,20 @@ public:
using ReadPortalType = vtkm::internal::ArrayPortalRecombineVec<ReadWritePortal>;
using WritePortalType = vtkm::internal::ArrayPortalRecombineVec<ReadWritePortal>;
VTKM_CONT static vtkm::IdComponent NumberOfComponents(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::IdComponent NumberOfComponents(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return static_cast<vtkm::IdComponent>(
buffers[0].GetMetaData<detail::RecombineVecMetaData>().ArrayBuffers.size());
buffers[0].GetMetaData<detail::RecombineVecMetaData>().ArrayBufferOffsets.size() - 1);
}
VTKM_CONT static vtkm::IdComponent GetNumberOfBuffers() { return 1; }
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return SourceStorage::GetNumberOfValues(BuffersForComponent(buffers, 0));
}
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer*,
VTKM_CONT static void Fill(const std::vector<vtkm::cont::internal::Buffer>&,
const vtkm::internal::RecombineVec<ReadWritePortal>&,
vtkm::Id,
vtkm::Id,
@ -451,9 +435,10 @@ public:
throw vtkm::cont::ErrorBadType("Fill not supported for ArrayHandleRecombineVec.");
}
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
vtkm::IdComponent numComponents = NumberOfComponents(buffers);
@ -488,9 +473,10 @@ public:
numComponents);
}
VTKM_CONT static WritePortalType CreateWritePortal(vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static WritePortalType CreateWritePortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
vtkm::IdComponent numComponents = NumberOfComponents(buffers);
@ -525,19 +511,28 @@ public:
numComponents);
}
VTKM_CONT static ArrayType ArrayForComponent(const vtkm::cont::internal::Buffer* buffers,
vtkm::IdComponent componentIndex)
VTKM_CONT static ArrayType ArrayForComponent(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::IdComponent componentIndex)
{
return ArrayType(BuffersForComponent(buffers, componentIndex));
}
VTKM_CONT static void AppendComponent(vtkm::cont::internal::Buffer* buffers,
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers()
{
detail::RecombineVecMetaData metaData;
metaData.ArrayBufferOffsets.push_back(1);
return vtkm::cont::internal::CreateBuffers(metaData);
}
VTKM_CONT static void AppendComponent(std::vector<vtkm::cont::internal::Buffer>& buffers,
const ArrayType& array)
{
std::vector<vtkm::cont::internal::Buffer> arrayBuffers(
array.GetBuffers(), array.GetBuffers() + SourceStorage::GetNumberOfBuffers());
buffers[0].GetMetaData<detail::RecombineVecMetaData>().ArrayBuffers.push_back(
std::move(arrayBuffers));
// Add buffers of new array to our list of buffers.
buffers.insert(buffers.end(), array.GetBuffers().begin(), array.GetBuffers().end());
// Update metadata for new offset to end.
buffers[0].GetMetaData<detail::RecombineVecMetaData>().ArrayBufferOffsets.push_back(
buffers.size());
}
};
@ -588,7 +583,9 @@ public:
void AppendComponentArray(
const vtkm::cont::ArrayHandle<ComponentType, vtkm::cont::StorageTagStride>& array)
{
StorageType::AppendComponent(this->GetBuffers(), array);
std::vector<vtkm::cont::internal::Buffer> buffers = this->GetBuffers();
StorageType::AppendComponent(buffers, array);
this->SetBuffers(std::move(buffers));
}
};

@ -128,25 +128,26 @@ public:
using ReadPortalType = ArrayPortalReverse<typename ArrayHandleType::ReadPortalType>;
using WritePortalType = ArrayPortalReverse<typename ArrayHandleType::WritePortalType>;
VTKM_CONT constexpr static vtkm::IdComponent GetNumberOfBuffers()
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers()
{
return SourceStorage::GetNumberOfBuffers();
return SourceStorage::CreateBuffers();
}
VTKM_CONT static void ResizeBuffers(vtkm::Id numValues,
vtkm::cont::internal::Buffer* buffers,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::CopyFlag preserve,
vtkm::cont::Token& token)
{
SourceStorage::ResizeBuffers(numValues, buffers, preserve, token);
}
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return SourceStorage::GetNumberOfValues(buffers);
}
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer* buffers,
VTKM_CONT static void Fill(const std::vector<vtkm::cont::internal::Buffer>& buffers,
const T& fillValue,
vtkm::Id startIndex,
vtkm::Id endIndex,
@ -156,16 +157,18 @@ public:
SourceStorage::Fill(buffers, fillValue, numValues - endIndex, numValues - startIndex, token);
}
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return ReadPortalType(SourceStorage::CreateReadPortal(buffers, device, token));
}
VTKM_CONT static WritePortalType CreateWritePortal(vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static WritePortalType CreateWritePortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return WritePortalType(SourceStorage::CreateWritePortal(buffers, device, token));
}

@ -140,10 +140,13 @@ public:
using WritePortalType =
vtkm::internal::ArrayPortalSOA<ValueType, vtkm::internal::ArrayPortalBasicWrite<ComponentType>>;
VTKM_CONT constexpr static vtkm::IdComponent GetNumberOfBuffers() { return NUM_COMPONENTS; }
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers()
{
return std::vector<vtkm::cont::internal::Buffer>(static_cast<std::size_t>(NUM_COMPONENTS));
}
VTKM_CONT static void ResizeBuffers(vtkm::Id numValues,
vtkm::cont::internal::Buffer* buffers,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::CopyFlag preserve,
vtkm::cont::Token& token)
{
@ -155,14 +158,15 @@ public:
}
}
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
// Assume all buffers are the same size.
return static_cast<vtkm::Id>(buffers[0].GetNumberOfBytes()) /
static_cast<vtkm::Id>(sizeof(ComponentType));
}
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer* buffers,
VTKM_CONT static void Fill(const std::vector<vtkm::cont::internal::Buffer>& buffers,
const ValueType& fillValue,
vtkm::Id startIndex,
vtkm::Id endIndex,
@ -179,9 +183,10 @@ public:
}
}
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
vtkm::Id numValues = GetNumberOfValues(buffers);
ReadPortalType portal(numValues);
@ -197,9 +202,10 @@ public:
return portal;
}
VTKM_CONT static WritePortalType CreateWritePortal(vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static WritePortalType CreateWritePortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
vtkm::Id numValues = GetNumberOfValues(buffers);
WritePortalType portal(numValues);
@ -401,7 +407,7 @@ public:
VTKM_CONT vtkm::cont::ArrayHandleBasic<ComponentType> GetArray(vtkm::IdComponent index) const
{
return ComponentArrayType(&this->GetBuffers()[index]);
return ComponentArrayType({ this->GetBuffers()[index] });
}
VTKM_CONT void SetArray(vtkm::IdComponent index, const ComponentArrayType& array)

@ -163,19 +163,18 @@ public:
using ReadPortalType = vtkm::internal::ArrayPortalStrideRead<T>;
using WritePortalType = vtkm::internal::ArrayPortalStrideWrite<T>;
VTKM_CONT static StrideInfo& GetInfo(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static StrideInfo& GetInfo(const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return buffers[0].GetMetaData<StrideInfo>();
}
VTKM_CONT static vtkm::IdComponent GetNumberOfBuffers() { return 2; }
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return GetInfo(buffers).NumberOfValues;
}
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer*,
VTKM_CONT static void Fill(const std::vector<vtkm::cont::internal::Buffer>&,
const T&,
vtkm::Id,
vtkm::Id,
@ -184,32 +183,35 @@ public:
throw vtkm::cont::ErrorBadType("Fill not supported for ArrayHandleStride.");
}
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return ReadPortalType(reinterpret_cast<const T*>(buffers[1].ReadPointerDevice(device, token)),
GetInfo(buffers));
}
VTKM_CONT static WritePortalType CreateWritePortal(vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static WritePortalType CreateWritePortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return WritePortalType(reinterpret_cast<T*>(buffers[1].WritePointerDevice(device, token)),
GetInfo(buffers));
}
static std::vector<vtkm::cont::internal::Buffer> CreateBuffers(
const vtkm::cont::internal::Buffer& sourceBuffer,
vtkm::internal::ArrayStrideInfo&& info)
const vtkm::cont::internal::Buffer& sourceBuffer = vtkm::cont::internal::Buffer{},
vtkm::internal::ArrayStrideInfo&& info = vtkm::internal::ArrayStrideInfo{})
{
return vtkm::cont::internal::CreateBuffers(info, sourceBuffer);
}
static vtkm::cont::ArrayHandleBasic<T> GetBasicArray(const vtkm::cont::internal::Buffer* buffers)
static vtkm::cont::ArrayHandleBasic<T> GetBasicArray(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagBasic>(buffers + 1);
return vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagBasic>({ buffers[1] });
}
};

@ -249,7 +249,11 @@ class Storage<typename StorageTagTransform<ArrayHandleType, FunctorType>::ValueT
using SourceStorage =
Storage<typename ArrayHandleType::ValueType, typename ArrayHandleType::StorageTag>;
static constexpr vtkm::IdComponent NUM_METADATA_BUFFERS = 1;
static std::vector<vtkm::cont::internal::Buffer> SourceBuffers(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() + 1, buffers.end());
}
public:
VTKM_STORAGE_NO_RESIZE;
@ -260,54 +264,51 @@ public:
typename ArrayHandleType::ReadPortalType,
typename FunctorManager::FunctorType>;
VTKM_CONT static vtkm::IdComponent GetNumberOfBuffers()
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return SourceStorage::GetNumberOfBuffers() + NUM_METADATA_BUFFERS;
return SourceStorage::GetNumberOfValues(SourceBuffers(buffers));
}
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
{
return SourceStorage::GetNumberOfValues(buffers + NUM_METADATA_BUFFERS);
}
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
if (device == vtkm::cont::DeviceAdapterTagUndefined{})
{
return ReadPortalType(
SourceStorage::CreateReadPortal(buffers + NUM_METADATA_BUFFERS, device, token),
buffers[0].GetMetaData<FunctorManager>().PrepareForControl());
return ReadPortalType(SourceStorage::CreateReadPortal(SourceBuffers(buffers), device, token),
buffers[0].GetMetaData<FunctorManager>().PrepareForControl());
}
else
{
return ReadPortalType(
SourceStorage::CreateReadPortal(buffers + NUM_METADATA_BUFFERS, device, token),
SourceStorage::CreateReadPortal(SourceBuffers(buffers), device, token),
buffers[0].GetMetaData<FunctorManager>().PrepareForExecution(device, token));
}
}
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers(
const ArrayHandleType& handle,
const ArrayHandleType& handle = ArrayHandleType{},
const FunctorType& functor = FunctorType())
{
return vtkm::cont::internal::CreateBuffers(FunctorManager(functor), handle);
}
VTKM_CONT static ArrayHandleType GetArray(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static ArrayHandleType GetArray(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return vtkm::cont::ArrayHandle<typename ArrayHandleType::ValueType,
typename ArrayHandleType::StorageTag>(buffers +
NUM_METADATA_BUFFERS);
typename ArrayHandleType::StorageTag>(SourceBuffers(buffers));
}
VTKM_CONT static FunctorType GetFunctor(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static FunctorType GetFunctor(const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return buffers[0].GetMetaData<FunctorManager>().Functor;
}
VTKM_CONT static NullFunctorType GetInverseFunctor(const vtkm::cont::internal::Buffer*)
VTKM_CONT static NullFunctorType GetInverseFunctor(
const std::vector<vtkm::cont::internal::Buffer>&)
{
return NullFunctorType{};
}
@ -325,7 +326,11 @@ class Storage<
using SourceStorage =
Storage<typename ArrayHandleType::ValueType, typename ArrayHandleType::StorageTag>;
static constexpr vtkm::IdComponent NUM_METADATA_BUFFERS = 2;
static std::vector<vtkm::cont::internal::Buffer> SourceBuffers(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() + 2, buffers.end());
}
public:
using ReadPortalType =
@ -339,56 +344,54 @@ public:
typename FunctorManager::FunctorType,
typename InverseFunctorManager::FunctorType>;
VTKM_CONT constexpr static vtkm::IdComponent GetNumberOfBuffers()
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return SourceStorage::GetNumberOfBuffers() + NUM_METADATA_BUFFERS;
}
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
{
return SourceStorage::GetNumberOfValues(buffers + NUM_METADATA_BUFFERS);
return SourceStorage::GetNumberOfValues(SourceBuffers(buffers));
}
VTKM_CONT static void ResizeBuffers(vtkm::Id numValues,
vtkm::cont::internal::Buffer* buffers,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::CopyFlag preserve,
vtkm::cont::Token& token)
{
SourceStorage::ResizeBuffers(numValues, buffers + NUM_METADATA_BUFFERS, preserve, token);
std::vector<vtkm::cont::internal::Buffer> sourceBuffers = SourceBuffers(buffers);
SourceStorage::ResizeBuffers(numValues, sourceBuffers, preserve, token);
}
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
if (device == vtkm::cont::DeviceAdapterTagUndefined{})
{
return ReadPortalType(
SourceStorage::CreateReadPortal(buffers + NUM_METADATA_BUFFERS, device, token),
buffers[0].GetMetaData<FunctorManager>().PrepareForControl(),
buffers[1].GetMetaData<InverseFunctorManager>().PrepareForControl());
return ReadPortalType(SourceStorage::CreateReadPortal(SourceBuffers(buffers), device, token),
buffers[0].GetMetaData<FunctorManager>().PrepareForControl(),
buffers[1].GetMetaData<InverseFunctorManager>().PrepareForControl());
}
else
{
return ReadPortalType(
SourceStorage::CreateReadPortal(buffers + NUM_METADATA_BUFFERS, device, token),
SourceStorage::CreateReadPortal(SourceBuffers(buffers), device, token),
buffers[0].GetMetaData<FunctorManager>().PrepareForExecution(device, token),
buffers[1].GetMetaData<InverseFunctorManager>().PrepareForExecution(device, token));
}
}
VTKM_CONT static WritePortalType CreateWritePortal(vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static WritePortalType CreateWritePortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return WritePortalType(
SourceStorage::CreateWritePortal(buffers + NUM_METADATA_BUFFERS, device, token),
SourceStorage::CreateWritePortal(SourceBuffers(buffers), device, token),
buffers[0].GetMetaData<FunctorManager>().PrepareForExecution(device, token),
buffers[1].GetMetaData<InverseFunctorManager>().PrepareForExecution(device, token));
}
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers(
const ArrayHandleType& handle,
const ArrayHandleType& handle = ArrayHandleType{},
const FunctorType& functor = FunctorType(),
const InverseFunctorType& inverseFunctor = InverseFunctorType())
{
@ -396,19 +399,20 @@ public:
FunctorManager(functor), InverseFunctorManager(inverseFunctor), handle);
}
VTKM_CONT static ArrayHandleType GetArray(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static ArrayHandleType GetArray(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return vtkm::cont::ArrayHandle<typename ArrayHandleType::ValueType,
typename ArrayHandleType::StorageTag>(buffers +
NUM_METADATA_BUFFERS);
typename ArrayHandleType::StorageTag>(SourceBuffers(buffers));
}
VTKM_CONT static FunctorType GetFunctor(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static FunctorType GetFunctor(const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return buffers[0].GetMetaData<FunctorManager>().Functor;
}
VTKM_CONT static InverseFunctorType GetInverseFunctor(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static InverseFunctorType GetInverseFunctor(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return buffers[1].GetMetaData<InverseFunctorManager>().Functor;
}

@ -143,6 +143,12 @@ class Storage<T, StorageTagView<ST>>
using ArrayHandleType = typename detail::ViewTypeArg<T, ST>::ArrayHandle;
using SourceStorage = Storage<T, ST>;
static std::vector<vtkm::cont::internal::Buffer> SourceBuffers(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() + 1, buffers.end());
}
public:
VTKM_STORAGE_NO_RESIZE;
@ -150,25 +156,23 @@ public:
using WritePortalType =
vtkm::internal::ArrayPortalView<typename ArrayHandleType::WritePortalType>;
VTKM_CONT static constexpr vtkm::IdComponent GetNumberOfBuffers()
{
return SourceStorage::GetNumberOfBuffers() + 1;
}
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return buffers[0].GetMetaData<vtkm::internal::ViewIndices>().NumberOfValues;
}
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
vtkm::internal::ViewIndices indices = buffers[0].GetMetaData<vtkm::internal::ViewIndices>();
return ReadPortalType(SourceStorage::CreateReadPortal(buffers + 1, device, token), indices);
return ReadPortalType(SourceStorage::CreateReadPortal(SourceBuffers(buffers), device, token),
indices);
}
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer* buffers,
VTKM_CONT static void Fill(const std::vector<vtkm::cont::internal::Buffer>& buffers,
const T& fillValue,
vtkm::Id startIndex,
vtkm::Id endIndex,
@ -179,30 +183,36 @@ public:
vtkm::Id adjustedEndIndex = (endIndex < indices.NumberOfValues)
? endIndex + indices.StartIndex
: indices.NumberOfValues + indices.StartIndex;
SourceStorage::Fill(buffers + 1, fillValue, adjustedStartIndex, adjustedEndIndex, token);
SourceStorage::Fill(
SourceBuffers(buffers), fillValue, adjustedStartIndex, adjustedEndIndex, token);
}
VTKM_CONT static WritePortalType CreateWritePortal(vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static WritePortalType CreateWritePortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
vtkm::internal::ViewIndices indices = buffers[0].GetMetaData<vtkm::internal::ViewIndices>();
return WritePortalType(SourceStorage::CreateWritePortal(buffers + 1, device, token), indices);
return WritePortalType(SourceStorage::CreateWritePortal(SourceBuffers(buffers), device, token),
indices);
}
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer>
CreateBuffers(vtkm::Id startIndex, vtkm::Id numValues, const ArrayHandleType& array)
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers(
vtkm::Id startIndex = 0,
vtkm::Id numValues = 0,
const ArrayHandleType& array = ArrayHandleType{})
{
return vtkm::cont::internal::CreateBuffers(vtkm::internal::ViewIndices(startIndex, numValues),
array);
}
VTKM_CONT static ArrayHandleType GetSourceArray(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static ArrayHandleType GetSourceArray(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return ArrayHandleType(buffers + 1);
return ArrayHandleType(SourceBuffers(buffers));
}
VTKM_CONT static vtkm::Id GetStartIndex(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetStartIndex(const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return buffers[0].GetMetaData<vtkm::internal::ViewIndices>().StartIndex;
}

@ -170,60 +170,61 @@ class XGCCoordinatesStorageImpl
using SourceStorage = Storage<T, StorageTagBasic>; // only allow input AH to use StorageTagBasic
using MetaData = XGCCoordinatesMetaData;
static MetaData& GetMetaData(const vtkm::cont::internal::Buffer* buffers)
static MetaData& GetMetaData(const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return buffers[0].GetMetaData<MetaData>();
}
// Used to skip the metadata buffer and return only actual data buffers
template <typename Buffs>
VTKM_CONT constexpr static Buffs* SourceBuffers(Buffs* buffers)
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> SourceBuffers(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return buffers + 1;
return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() + 1, buffers.end());
}
public:
using ReadPortalType =
vtkm::internal::ArrayPortalXGCCoordinates<typename SourceStorage::ReadPortalType>;
VTKM_CONT constexpr static vtkm::IdComponent GetNumberOfBuffers()
{
return SourceStorage::GetNumberOfBuffers() + 1; // To account for metadata
}
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return GetNumberOfValuesPerPlane(buffers) * GetNumberOfPlanesOwned(buffers);
}
VTKM_CONT static vtkm::Id GetNumberOfValuesPerPlane(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetNumberOfValuesPerPlane(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return SourceStorage::GetNumberOfValues(SourceBuffers(buffers)) / 2;
}
VTKM_CONT static vtkm::Id GetNumberOfPlanes(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetNumberOfPlanes(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return GetMetaData(buffers).NumberOfPlanes;
}
VTKM_CONT static vtkm::Id GetNumberOfPlanesOwned(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetNumberOfPlanesOwned(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return GetMetaData(buffers).NumberOfPlanesOwned;
}
VTKM_CONT static vtkm::Id GetPlaneStartId(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetPlaneStartId(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return GetMetaData(buffers).PlaneStartId;
}
VTKM_CONT static bool GetUseCylindrical(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static bool GetUseCylindrical(const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return GetMetaData(buffers).UseCylindrical;
}
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return ReadPortalType(SourceStorage::CreateReadPortal(SourceBuffers(buffers), device, token),
GetNumberOfPlanes(buffers),
@ -233,7 +234,7 @@ public:
}
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers(
vtkm::cont::ArrayHandle<T> array,
const vtkm::cont::ArrayHandle<T>& array,
vtkm::Id numberOfPlanes,
vtkm::Id numberOfPlanesOwned,
vtkm::Id planeStartId,
@ -243,8 +244,13 @@ public:
MetaData(numberOfPlanes, numberOfPlanesOwned, planeStartId, useCylindrical), array);
}
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers()
{
return CreateBuffers(vtkm::cont::ArrayHandle<T>{}, 0, 0, 0, false);
}
VTKM_CONT static vtkm::cont::ArrayHandle<T> GetArrayHandle(
const vtkm::cont::internal::Buffer* buffers)
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return vtkm::cont::ArrayHandle<T>(SourceBuffers(buffers));
}

@ -129,6 +129,10 @@ struct ArrayHandleZipTraits
using Tag =
StorageTagZip<typename FirstHandleType::StorageTag, typename SecondHandleType::StorageTag>;
/// The storage type.
///
using Storage = vtkm::cont::internal::Storage<ValueType, Tag>;
/// The superclass for ArrayHandleZip.
///
using Superclass = vtkm::cont::ArrayHandle<ValueType, Tag>;
@ -141,15 +145,27 @@ class Storage<vtkm::Pair<T1, T2>, vtkm::cont::StorageTagZip<ST1, ST2>>
using SecondStorage = Storage<T2, ST2>;
using ValueType = vtkm::Pair<T1, T2>;
template <typename BufferType>
VTKM_CONT static BufferType* FirstArrayBuffers(BufferType* buffers)
using FirstArrayType = vtkm::cont::ArrayHandle<T1, ST1>;
using SecondArrayType = vtkm::cont::ArrayHandle<T2, ST2>;
struct Info
{
return buffers;
std::size_t SecondBuffersOffset;
};
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> FirstArrayBuffers(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
const Info& info = buffers[0].GetMetaData<Info>();
return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() + 1,
buffers.begin() + info.SecondBuffersOffset);
}
template <typename BufferType>
VTKM_CONT static BufferType* SecondArrayBuffers(BufferType* buffers)
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> SecondArrayBuffers(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return buffers + FirstStorage::GetNumberOfBuffers();
const Info& info = buffers[0].GetMetaData<Info>();
return std::vector<vtkm::cont::internal::Buffer>(buffers.begin() + info.SecondBuffersOffset,
buffers.end());
}
public:
@ -160,13 +176,17 @@ public:
vtkm::exec::internal::ArrayPortalZip<typename FirstStorage::WritePortalType,
typename SecondStorage::WritePortalType>;
VTKM_CONT static constexpr vtkm::IdComponent GetNumberOfBuffers()
static std::vector<vtkm::cont::internal::Buffer> CreateBuffers(
const FirstArrayType& firstArray = FirstArrayType{},
const SecondArrayType& secondArray = SecondArrayType{})
{
return FirstStorage::GetNumberOfBuffers() + SecondStorage::GetNumberOfBuffers();
Info info;
info.SecondBuffersOffset = 1 + firstArray.GetBuffers().size();
return vtkm::cont::internal::CreateBuffers(info, firstArray, secondArray);
}
VTKM_CONT static void ResizeBuffers(vtkm::Id numValues,
vtkm::cont::internal::Buffer* buffers,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::CopyFlag preserve,
vtkm::cont::Token& token)
{
@ -174,14 +194,15 @@ public:
SecondStorage::ResizeBuffers(numValues, SecondArrayBuffers(buffers), preserve, token);
}
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
vtkm::Id numValues = FirstStorage::GetNumberOfValues(FirstArrayBuffers(buffers));
VTKM_ASSERT(numValues == SecondStorage::GetNumberOfValues(SecondArrayBuffers(buffers)));
return numValues;
}
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer* buffers,
VTKM_CONT static void Fill(const std::vector<vtkm::cont::internal::Buffer>& buffers,
const ValueType& fillValue,
vtkm::Id startIndex,
vtkm::Id endIndex,
@ -191,29 +212,31 @@ public:
SecondStorage::Fill(SecondArrayBuffers(buffers), fillValue.second, startIndex, endIndex, token);
}
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return ReadPortalType(
FirstStorage::CreateReadPortal(FirstArrayBuffers(buffers), device, token),
SecondStorage::CreateReadPortal(SecondArrayBuffers(buffers), device, token));
}
VTKM_CONT static WritePortalType CreateWritePortal(vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static WritePortalType CreateWritePortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
return WritePortalType(
FirstStorage::CreateWritePortal(FirstArrayBuffers(buffers), device, token),
SecondStorage::CreateWritePortal(SecondArrayBuffers(buffers), device, token));
}
vtkm::cont::ArrayHandle<T1, ST1> GetFirstArray(const vtkm::cont::internal::Buffer* buffers)
static FirstArrayType GetFirstArray(const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return { FirstArrayBuffers(buffers) };
}
vtkm::cont::ArrayHandle<T2, ST2> GetSecondArray(const vtkm::cont::internal::Buffer* buffers)
static SecondArrayType GetSecondArray(const std::vector<vtkm::cont::internal::Buffer>& buffers)
{
return { SecondArrayBuffers(buffers) };
}
@ -236,6 +259,9 @@ class ArrayHandleZip
// template argument is not a valid ArrayHandle type.
VTKM_IS_ARRAY_HANDLE(SecondHandleType);
using StorageType =
typename internal::ArrayHandleZipTraits<FirstHandleType, SecondHandleType>::Storage;
public:
VTKM_ARRAY_HANDLE_SUBCLASS(
ArrayHandleZip,
@ -244,17 +270,14 @@ public:
VTKM_CONT
ArrayHandleZip(const FirstHandleType& firstArray, const SecondHandleType& secondArray)
: Superclass(vtkm::cont::internal::CreateBuffers(firstArray, secondArray))
: Superclass(StorageType::CreateBuffers(firstArray, secondArray))
{
}
FirstHandleType GetFirstArray() const
{
return this->GetStorage().GetFirstArray(this->GetBuffers());
}
FirstHandleType GetFirstArray() const { return StorageType::GetFirstArray(this->GetBuffers()); }
SecondHandleType GetSecondArray() const
{
return this->GetStorage().GetSecondArray(this->GetBuffers());
return StorageType::GetSecondArray(this->GetBuffers());
}
};

@ -68,7 +68,7 @@ public:
VTKM_CONT
int rank(int gid) const override;
//@}
///@}
private:
std::vector<vtkm::Id> IScanPartitionCounts;
};

@ -595,7 +595,8 @@ public:
VTKM_CONT VTKM_DEPRECATED(1.6, "BitField now uses a Buffer to store data.")
ArrayHandle<vtkm::WordTypeDefault, StorageTagBasic> GetData() const
{
return vtkm::cont::ArrayHandle<vtkm::WordTypeDefault, StorageTagBasic>(&this->Buffer);
return vtkm::cont::ArrayHandle<vtkm::WordTypeDefault, StorageTagBasic>(
std::vector<vtkm::cont::internal::Buffer>(1, this->Buffer));
}
/// Return the number of bits stored by this BitField.

@ -166,6 +166,7 @@ set(sources
FieldRangeGlobalCompute.cxx
internal/DeviceAdapterMemoryManager.cxx
internal/DeviceAdapterMemoryManagerShared.cxx
internal/FieldCollection.cxx
internal/RuntimeDeviceConfiguration.cxx
internal/RuntimeDeviceConfigurationOptions.cxx
internal/RuntimeDeviceOption.cxx

@ -39,6 +39,7 @@ public:
vtkm::ListTransform<SupportedCellSets, vtkm::exec::CellLocatorBoundingIntervalHierarchy>;
using ExecObjType = vtkm::ListApply<CellLocatorExecList, vtkm::exec::CellLocatorMultiplexer>;
using LastCell = typename ExecObjType::LastCell;
VTKM_CONT
CellLocatorBoundingIntervalHierarchy(vtkm::IdComponent numPlanes = 4,

@ -54,6 +54,7 @@ public:
vtkm::cont::internal::ExecutionObjectType<vtkm::cont::CellLocatorTwoLevel>>;
using ExecObjType = vtkm::ListApply<ExecLocatorList, vtkm::exec::CellLocatorMultiplexer>;
using LastCell = typename ExecObjType::LastCell;
VTKM_CONT ExecObjType PrepareForExecution(vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token) const;

@ -36,6 +36,8 @@ public:
~CellLocatorRectilinearGrid() = default;
using LastCell = vtkm::exec::CellLocatorRectilinearGrid::LastCell;
VTKM_CONT vtkm::exec::CellLocatorRectilinearGrid PrepareForExecution(
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token) const;

@ -58,6 +58,7 @@ public:
vtkm::ListTransform<CellExecObjectList, vtkm::exec::CellLocatorTwoLevel>;
using ExecObjType = vtkm::ListApply<CellLocatorExecList, vtkm::exec::CellLocatorMultiplexer>;
using LastCell = typename ExecObjType::LastCell;
CellLocatorTwoLevel()
: DensityL1(32.0f)

@ -25,6 +25,8 @@ class VTKM_CONT_EXPORT CellLocatorUniformGrid
using Superclass = vtkm::cont::internal::CellLocatorBase<CellLocatorUniformGrid>;
public:
using LastCell = vtkm::exec::CellLocatorUniformGrid::LastCell;
VTKM_CONT vtkm::exec::CellLocatorUniformGrid PrepareForExecution(
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token) const;

@ -51,6 +51,11 @@ public:
this->Structure.SetPointDimensions(dimensions);
}
void SetGlobalPointDimensions(SchedulingRangeType dimensions)
{
this->Structure.SetGlobalPointDimensions(dimensions);
}
void SetGlobalPointIndexStart(SchedulingRangeType start)
{
this->Structure.SetGlobalPointIndexStart(start);
@ -58,8 +63,18 @@ public:
SchedulingRangeType GetPointDimensions() const { return this->Structure.GetPointDimensions(); }
SchedulingRangeType GetGlobalPointDimensions() const
{
return this->Structure.GetGlobalPointDimensions();
}
SchedulingRangeType GetCellDimensions() const { return this->Structure.GetCellDimensions(); }
SchedulingRangeType GetGlobalCellDimensions() const
{
return this->Structure.GetGlobalCellDimensions();
}
SchedulingRangeType GetGlobalPointIndexStart() const
{
return this->Structure.GetGlobalPointIndexStart();
@ -225,17 +240,20 @@ public:
static VTKM_CONT void save(BinaryBuffer& bb, const Type& cs)
{
vtkmdiy::save(bb, cs.GetPointDimensions());
vtkmdiy::save(bb, cs.GetGlobalPointDimensions());
vtkmdiy::save(bb, cs.GetGlobalPointIndexStart());
}
static VTKM_CONT void load(BinaryBuffer& bb, Type& cs)
{
typename Type::SchedulingRangeType dims, start;
typename Type::SchedulingRangeType dims, gdims, start;
vtkmdiy::load(bb, dims);
vtkmdiy::load(bb, gdims);
vtkmdiy::load(bb, start);
cs = Type{};
cs.SetPointDimensions(dims);
cs.SetGlobalPointDimensions(gdims);
cs.SetGlobalPointIndexStart(start);
}
};

@ -14,10 +14,27 @@ namespace vtkm
{
namespace cont
{
VTKM_CONT std::string& GlobalGhostCellFieldName() noexcept
{
static std::string GhostCellName("vtkGhostCells");
return GhostCellName;
}
VTKM_CONT const std::string& GetGlobalGhostCellFieldName() noexcept
{
return GlobalGhostCellFieldName();
}
VTKM_CONT void SetGlobalGhostCellFieldName(const std::string& name) noexcept
{
GlobalGhostCellFieldName() = name;
}
void DataSet::Clear()
{
this->CoordSystems.clear();
this->Fields.clear();
this->Fields.Clear();
this->CellSet = this->CellSet.NewInstance();
}
@ -39,36 +56,7 @@ void DataSet::CopyStructure(const vtkm::cont::DataSet& source)
{
this->CoordSystems = source.CoordSystems;
this->CellSet = source.CellSet;
}
const vtkm::cont::Field& DataSet::GetField(vtkm::Id index) const
{
VTKM_ASSERT((index >= 0) && (index < this->GetNumberOfFields()));
auto it = this->Fields.cbegin();
std::advance(it, index);
return it->second;
}
vtkm::cont::Field& DataSet::GetField(vtkm::Id index)
{
VTKM_ASSERT((index >= 0) && (index < this->GetNumberOfFields()));
auto it = this->Fields.begin();
std::advance(it, index);
return it->second;
}
vtkm::Id DataSet::GetFieldIndex(const std::string& name, vtkm::cont::Field::Association assoc) const
{
bool found;
vtkm::Id index = this->FindFieldIndex(name, assoc, found);
if (found)
{
return index;
}
else
{
throw vtkm::cont::ErrorBadValue("No field with requested name: " + name);
}
this->GhostCellName = source.GhostCellName;
}
const vtkm::cont::CoordinateSystem& DataSet::GetCoordinateSystem(vtkm::Id index) const
@ -150,27 +138,6 @@ void DataSet::PrintSummary(std::ostream& out) const
out.flush();
}
vtkm::Id DataSet::FindFieldIndex(const std::string& name,
vtkm::cont::Field::Association association,
bool& found) const
{
const auto it = this->Fields.find({ name, association });
if (it != this->Fields.end())
{
found = true;
return static_cast<vtkm::Id>(std::distance(this->Fields.begin(), it));
}
found = false;
return -1;
}
VTKM_CONT void DataSet::AddField(const Field& field)
{
// map::insert will not replace the duplicated element
this->Fields[{ field.GetName(), field.GetAssociation() }] = field;
}
void DataSet::ConvertToExpected()
{
for (vtkm::IdComponent coordIndex = 0; coordIndex < this->GetNumberOfCoordinateSystems();

@ -18,15 +18,32 @@
#include <vtkm/cont/Field.h>
#include <vtkm/cont/UnknownArrayHandle.h>
#include <vtkm/cont/UnknownCellSet.h>
#include <vtkm/cont/internal/FieldCollection.h>
namespace vtkm
{
namespace cont
{
VTKM_CONT_EXPORT VTKM_CONT std::string& GlobalGhostCellFieldName() noexcept;
VTKM_CONT_EXPORT VTKM_CONT const std::string& GetGlobalGhostCellFieldName() noexcept;
VTKM_CONT_EXPORT VTKM_CONT void SetGlobalGhostCellFieldName(const std::string& name) noexcept;
class VTKM_CONT_EXPORT DataSet
{
public:
DataSet() = default;
DataSet(vtkm::cont::DataSet&&) = default;
DataSet(const vtkm::cont::DataSet&) = default;
vtkm::cont::DataSet& operator=(vtkm::cont::DataSet&&) = default;
vtkm::cont::DataSet& operator=(const vtkm::cont::DataSet&) = default;
VTKM_CONT void Clear();
/// Get the number of cells contained in this DataSet
@ -38,37 +55,57 @@ public:
/// to have the same number of points.
VTKM_CONT vtkm::Id GetNumberOfPoints() const;
VTKM_CONT void AddField(const Field& field);
VTKM_CONT void AddField(const Field& field) { this->Fields.AddField(field); }
VTKM_CONT
const vtkm::cont::Field& GetField(vtkm::Id index) const;
const vtkm::cont::Field& GetField(vtkm::Id index) const { return this->Fields.GetField(index); }
VTKM_CONT
vtkm::cont::Field& GetField(vtkm::Id index);
vtkm::cont::Field& GetField(vtkm::Id index) { return this->Fields.GetField(index); }
VTKM_CONT
bool HasField(const std::string& name,
vtkm::cont::Field::Association assoc = vtkm::cont::Field::Association::Any) const
{
bool found = false;
this->FindFieldIndex(name, assoc, found);
return found;
return this->Fields.HasField(name, assoc);
}
VTKM_CONT
bool HasCellField(const std::string& name) const
{
bool found = false;
this->FindFieldIndex(name, vtkm::cont::Field::Association::Cells, found);
return found;
return (this->Fields.GetFieldIndex(name, vtkm::cont::Field::Association::Cells) != -1);
}
VTKM_CONT
bool HasGhostCellField() const
{
if (this->GhostCellName)
{
return this->HasCellField(*this->GhostCellName);
}
else
{
return false;
}
}
VTKM_CONT
const std::string& GetGhostCellFieldName() const
{
if (this->HasGhostCellField())
{
return *this->GhostCellName;
}
else
{
throw vtkm::cont::ErrorBadValue("No Ghost Cell Field Name");
}
}
VTKM_CONT
bool HasPointField(const std::string& name) const
{
bool found = false;
this->FindFieldIndex(name, vtkm::cont::Field::Association::Points, found);
return found;
return (this->Fields.GetFieldIndex(name, vtkm::cont::Field::Association::Points) != -1);
}
@ -77,31 +114,35 @@ public:
VTKM_CONT
vtkm::Id GetFieldIndex(
const std::string& name,
vtkm::cont::Field::Association assoc = vtkm::cont::Field::Association::Any) const;
vtkm::cont::Field::Association assoc = vtkm::cont::Field::Association::Any) const
{
return this->Fields.GetFieldIndex(name, assoc);
}
/// Returns the field that matches the provided name and association
/// Will throw an exception if no match is found
//@{
///@{
VTKM_CONT
const vtkm::cont::Field& GetField(
const std::string& name,
vtkm::cont::Field::Association assoc = vtkm::cont::Field::Association::Any) const
{
return this->GetField(this->GetFieldIndex(name, assoc));
return this->Fields.GetField(name, assoc);
}
VTKM_CONT
vtkm::cont::Field& GetField(
const std::string& name,
vtkm::cont::Field::Association assoc = vtkm::cont::Field::Association::Any)
{
return this->GetField(this->GetFieldIndex(name, assoc));
return this->Fields.GetField(name, assoc);
}
//@}
///@}
/// Returns the first cell field that matches the provided name.
/// Will throw an exception if no match is found
//@{
///@{
VTKM_CONT
const vtkm::cont::Field& GetCellField(const std::string& name) const
{
@ -113,11 +154,28 @@ public:
{
return this->GetField(name, vtkm::cont::Field::Association::Cells);
}
//@}
///@}
/// Returns the first cell field that matches the provided name.
/// Will throw an exception if no match is found
///@{
VTKM_CONT
const vtkm::cont::Field& GetGhostCellField() const
{
if (this->HasGhostCellField())
{
return this->GetCellField(*(this->GhostCellName));
}
else
{
throw vtkm::cont::ErrorBadValue("No Ghost Cell Field");
}
}
///@}
/// Returns the first point field that matches the provided name.
/// Will throw an exception if no match is found
//@{
///@{
VTKM_CONT
const vtkm::cont::Field& GetPointField(const std::string& name) const
{
@ -129,7 +187,7 @@ public:
{
return this->GetField(name, vtkm::cont::Field::Association::Points);
}
//@}
///@}
VTKM_CONT
void AddPointField(const std::string& fieldName, const vtkm::cont::UnknownArrayHandle& field)
@ -165,6 +223,25 @@ public:
this->AddField(make_FieldCell(fieldName, field));
}
VTKM_CONT
void AddGhostCellField(const std::string& fieldName, const vtkm::cont::UnknownArrayHandle& field)
{
this->GhostCellName.reset(new std::string(fieldName));
this->AddField(make_FieldCell(fieldName, field));
}
VTKM_CONT
void AddGhostCellField(const vtkm::cont::UnknownArrayHandle& field)
{
this->AddGhostCellField(GetGlobalGhostCellFieldName(), field);
}
VTKM_CONT
void AddGhostCellField(const vtkm::cont::Field& field)
{
this->AddGhostCellField(field.GetName(), field.GetData());
}
template <typename T, typename Storage>
VTKM_CONT void AddCellField(const std::string& fieldName,
const vtkm::cont::ArrayHandle<T, Storage>& field)
@ -213,13 +290,13 @@ public:
/// Returns the first CoordinateSystem that matches the provided name.
/// Will throw an exception if no match is found
//@{
///@{
VTKM_CONT
const vtkm::cont::CoordinateSystem& GetCoordinateSystem(const std::string& name) const;
VTKM_CONT
vtkm::cont::CoordinateSystem& GetCoordinateSystem(const std::string& name);
//@}
///@}
/// Returns an `std::vector` of `CoordinateSystem`s held in this `DataSet`.
///
@ -243,10 +320,7 @@ public:
vtkm::cont::UnknownCellSet& GetCellSet() { return this->CellSet; }
VTKM_CONT
vtkm::IdComponent GetNumberOfFields() const
{
return static_cast<vtkm::IdComponent>(this->Fields.size());
}
vtkm::IdComponent GetNumberOfFields() const { return this->Fields.GetNumberOfFields(); }
VTKM_CONT
vtkm::IdComponent GetNumberOfCoordinateSystems() const
@ -278,29 +352,13 @@ public:
void PrintSummary(std::ostream& out) const;
private:
struct FieldCompare
{
using Key = std::pair<std::string, vtkm::cont::Field::Association>;
template <typename T>
bool operator()(const T& a, const T& b) const
{
if (a.first == b.first)
return a.second < b.second && a.second != vtkm::cont::Field::Association::Any &&
b.second != vtkm::cont::Field::Association::Any;
return a.first < b.first;
}
};
std::vector<vtkm::cont::CoordinateSystem> CoordSystems;
std::map<FieldCompare::Key, vtkm::cont::Field, FieldCompare> Fields;
vtkm::cont::UnknownCellSet CellSet;
vtkm::cont::internal::FieldCollection Fields{ vtkm::cont::Field::Association::WholeDataSet,
vtkm::cont::Field::Association::Points,
vtkm::cont::Field::Association::Cells };
VTKM_CONT
vtkm::Id FindFieldIndex(const std::string& name,
vtkm::cont::Field::Association association,
bool& found) const;
vtkm::cont::UnknownCellSet CellSet;
std::shared_ptr<std::string> GhostCellName;
};
} // namespace cont

@ -88,8 +88,8 @@ void Field::PrintSummary(std::ostream& out) const
case Association::Any:
out << "Any ";
break;
case Association::WholeMesh:
out << "Mesh ";
case Association::WholeDataSet:
out << "WholeDataSet ";
break;
case Association::Points:
out << "Points ";
@ -97,6 +97,12 @@ void Field::PrintSummary(std::ostream& out) const
case Association::Cells:
out << "Cells ";
break;
case Association::Partitions:
out << "Partitions ";
break;
case Association::Global:
out << "Global ";
break;
}
this->Data.PrintSummary(out);
}

@ -34,13 +34,18 @@ public:
enum struct Association
{
Any,
WholeMesh,
WholeDataSet,
Points,
Cells,
Partitions,
Global,
ANY VTKM_DEPRECATED(1.8, "Use vtkm::cont::Field::Association::Any.") = Any,
WHOLE_MESH VTKM_DEPRECATED(1.8, "Use vtkm::cont::Field::Association::WholeMesh.") = WholeMesh,
WHOLE_MESH VTKM_DEPRECATED(1.8, "Use vtkm::cont::Field::Association::WholeDataSet.") =
WholeDataSet,
POINTS VTKM_DEPRECATED(1.8, "Use vtkm::cont::Field::Association::Points.") = Points,
CELL_SET VTKM_DEPRECATED(1.8, "Use vtkm::cont::Field::Association::Cells.") = Cells
CELL_SET VTKM_DEPRECATED(1.8, "Use vtkm::cont::Field::Association::Cells.") = Cells,
WholeMesh VTKM_DEPRECATED(1.9, "Use vtkm::cont::Field::Association::WholeDataSet.") =
WholeDataSet
};
VTKM_CONT
@ -65,9 +70,27 @@ public:
VTKM_CONT Field& operator=(const vtkm::cont::Field& src);
VTKM_CONT Field& operator=(vtkm::cont::Field&& src) noexcept;
VTKM_CONT bool IsFieldCell() const { return this->FieldAssociation == Association::Cells; }
VTKM_CONT bool IsFieldPoint() const { return this->FieldAssociation == Association::Points; }
VTKM_CONT bool IsFieldGlobal() const { return this->FieldAssociation == Association::WholeMesh; }
VTKM_CONT bool IsCellField() const { return this->FieldAssociation == Association::Cells; }
VTKM_CONT bool IsPointField() const { return this->FieldAssociation == Association::Points; }
VTKM_CONT bool IsWholeDataSetField() const
{
return this->FieldAssociation == Association::WholeDataSet;
}
VTKM_CONT bool IsPartitionsField() const
{
return this->FieldAssociation == Association::Partitions;
}
VTKM_CONT bool IsGlobalField() const { return this->FieldAssociation == Association::Global; }
VTKM_DEPRECATED(1.9, "Use IsCellField.")
VTKM_CONT bool IsFieldCell() const { return this->IsCellField(); }
VTKM_DEPRECATED(1.9, "Use IsPointField.")
VTKM_CONT bool IsFieldPoint() const { return this->IsPointField(); }
VTKM_DEPRECATED(1.9, "Use IsWholeDataSetField. Note that meaning of `Global` has changed!")
VTKM_CONT bool IsFieldGlobal() const
{
return this->FieldAssociation == Association::WholeDataSet;
}
/// Returns true if the array of the field has a value type that matches something in
/// `VTKM_FIELD_TYPE_LIST` and a storage that matches something in `VTKM_FIELD_STORAGE_LIST`.

@ -13,8 +13,14 @@
#include <vtkm/cont/DataSet.h>
#include <vtkm/cont/EnvironmentTracker.h>
#include <vtkm/cont/ErrorBadValue.h>
#include <vtkm/cont/Field.h>
#include <vtkm/cont/PartitionedDataSet.h>
#include <vtkm/internal/Configure.h>
// clang-format off
VTKM_THIRDPARTY_PRE_INCLUDE
#include <vtkm/thirdparty/diy/diy.h>
VTKM_THIRDPARTY_POST_INCLUDE
// clang-format on
namespace vtkm
{
@ -27,12 +33,6 @@ PartitionedDataSet::PartitionedDataSet(const vtkm::cont::DataSet& ds)
this->Partitions.insert(this->Partitions.end(), ds);
}
VTKM_CONT
PartitionedDataSet::PartitionedDataSet(const vtkm::cont::PartitionedDataSet& src)
{
this->Partitions = src.GetPartitions();
}
VTKM_CONT
PartitionedDataSet::PartitionedDataSet(const std::vector<vtkm::cont::DataSet>& partitions)
{
@ -46,21 +46,8 @@ PartitionedDataSet::PartitionedDataSet(vtkm::Id size)
}
VTKM_CONT
PartitionedDataSet::PartitionedDataSet() {}
VTKM_CONT
PartitionedDataSet::~PartitionedDataSet() {}
VTKM_CONT
PartitionedDataSet& PartitionedDataSet::operator=(const vtkm::cont::PartitionedDataSet& src)
{
this->Partitions = src.GetPartitions();
return *this;
}
VTKM_CONT
vtkm::cont::Field PartitionedDataSet::GetField(const std::string& field_name,
int partition_index) const
vtkm::cont::Field PartitionedDataSet::GetFieldFromPartition(const std::string& field_name,
int partition_index) const
{
assert(partition_index >= 0);
assert(static_cast<std::size_t>(partition_index) < this->Partitions.size());
@ -73,6 +60,19 @@ vtkm::Id PartitionedDataSet::GetNumberOfPartitions() const
return static_cast<vtkm::Id>(this->Partitions.size());
}
VTKM_CONT
vtkm::Id PartitionedDataSet::GetGlobalNumberOfPartitions() const
{
#ifdef VTKM_ENABLE_MPI
auto comm = vtkm::cont::EnvironmentTracker::GetCommunicator();
vtkm::Id globalSize = 0;
vtkmdiy::mpi::all_reduce(comm, GetNumberOfPartitions(), globalSize, std::plus<vtkm::Id>{});
return globalSize;
#else
return GetNumberOfPartitions();
#endif
}
VTKM_CONT
const vtkm::cont::DataSet& PartitionedDataSet::GetPartition(vtkm::Id blockId) const
{
@ -123,6 +123,12 @@ void PartitionedDataSet::ReplacePartition(vtkm::Id index, const vtkm::cont::Data
}
}
VTKM_CONT
void PartitionedDataSet::CopyPartitions(const vtkm::cont::PartitionedDataSet& source)
{
this->Partitions = source.Partitions;
}
VTKM_CONT
void PartitionedDataSet::PrintSummary(std::ostream& stream) const
{
@ -133,6 +139,12 @@ void PartitionedDataSet::PrintSummary(std::ostream& stream) const
stream << "Partition " << part << ":\n";
this->Partitions[part].PrintSummary(stream);
}
stream << " Fields[" << this->GetNumberOfFields() << "]\n";
for (vtkm::Id index = 0; index < this->GetNumberOfFields(); index++)
{
this->GetField(index).PrintSummary(stream);
}
}
}
} // namespace vtkm::cont

@ -15,6 +15,7 @@
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/cont/Field.h>
#include <vtkm/cont/internal/FieldCollection.h>
namespace vtkm
{
@ -32,61 +33,188 @@ public:
using reference = typename StorageVec::reference;
using const_reference = typename StorageVec::const_reference;
/// create a new PartitionedDataSet containng a single DataSet @a ds
/// Create a new PartitionedDataSet containng a single DataSet @a ds.
VTKM_CONT
PartitionedDataSet(const vtkm::cont::DataSet& ds);
/// create a new PartitionedDataSet with the existing one @a src
VTKM_CONT
PartitionedDataSet(const vtkm::cont::PartitionedDataSet& src);
/// create a new PartitionedDataSet with a DataSet vector @a partitions.
/// Create a new PartitionedDataSet with a DataSet vector @a partitions.
VTKM_CONT
explicit PartitionedDataSet(const std::vector<vtkm::cont::DataSet>& partitions);
/// create a new PartitionedDataSet with the capacity set to be @a size
/// Create a new PartitionedDataSet with the capacity set to be @a size.
VTKM_CONT
explicit PartitionedDataSet(vtkm::Id size);
VTKM_CONT
PartitionedDataSet();
PartitionedDataSet() = default;
VTKM_CONT
PartitionedDataSet& operator=(const vtkm::cont::PartitionedDataSet& src);
VTKM_DEPRECATED(1.9, "Renamed to GetFieldFromPartition.")
VTKM_CONT vtkm::cont::Field GetField(const std::string& field_name, int partition_index) const
{
return this->GetFieldFromPartition(field_name, partition_index);
}
/// Get the field @a field_name from partition @a partition_index.
VTKM_CONT
~PartitionedDataSet();
/// get the field @a field_name from partition @a partition_index
VTKM_CONT
vtkm::cont::Field GetField(const std::string& field_name, int partition_index) const;
vtkm::cont::Field GetFieldFromPartition(const std::string& field_name, int partition_index) const;
/// Get number of DataSet objects stored in this PartitionedDataSet.
VTKM_CONT
vtkm::Id GetNumberOfPartitions() const;
/// Get number of partations across all MPI ranks.
/// @warning This method requires global communication (MPI_Allreduce) if MPI is enabled.
VTKM_CONT
vtkm::Id GetGlobalNumberOfPartitions() const;
/// Get the DataSet @a partId.
VTKM_CONT
const vtkm::cont::DataSet& GetPartition(vtkm::Id partId) const;
/// Get an STL vector of all DataSet objects stored in PartitionedDataSet.
VTKM_CONT
const std::vector<vtkm::cont::DataSet>& GetPartitions() const;
/// add DataSet @a ds to the end of the contained DataSet vector
/// Add DataSet @a ds to the end of the contained DataSet vector.
VTKM_CONT
void AppendPartition(const vtkm::cont::DataSet& ds);
/// add DataSet @a ds to position @a index of the contained DataSet vector
/// Add DataSet @a ds to position @a index of the contained DataSet vector.
VTKM_CONT
void InsertPartition(vtkm::Id index, const vtkm::cont::DataSet& ds);
/// replace the @a index positioned element of the contained DataSet vector
/// with @a ds
/// Replace the @a index positioned element of the contained DataSet vector
/// with @a ds.
VTKM_CONT
void ReplacePartition(vtkm::Id index, const vtkm::cont::DataSet& ds);
/// append the DataSet vector "partitions" to the end of the contained one
/// Append the DataSet vector @a partitions to the end of the contained one.
VTKM_CONT
void AppendPartitions(const std::vector<vtkm::cont::DataSet>& partitions);
///@{
/// Methods to Add and Get fields on a PartitionedDataSet
VTKM_CONT
vtkm::IdComponent GetNumberOfFields() const { return this->Fields.GetNumberOfFields(); }
//Fields on partitions.
VTKM_CONT void AddField(const Field& field) { this->Fields.AddField(field); }
template <typename T, typename Storage>
VTKM_CONT void AddGlobalField(const std::string& fieldName,
const vtkm::cont::ArrayHandle<T, Storage>& field)
{
this->AddField(vtkm::cont::Field(fieldName, vtkm::cont::Field::Association::Global, field));
}
template <typename T>
VTKM_CONT void AddGlobalField(const std::string& fieldName, const std::vector<T>& field)
{
this->AddField(
make_Field(fieldName, vtkm::cont::Field::Association::Global, field, vtkm::CopyFlag::On));
}
template <typename T>
VTKM_CONT void AddGlobalField(const std::string& fieldName, const T* field, const vtkm::Id& n)
{
this->AddField(
make_Field(fieldName, vtkm::cont::Field::Association::Global, field, n, vtkm::CopyFlag::On));
}
template <typename T, typename Storage>
VTKM_CONT void AddPartitionsField(const std::string& fieldName,
const vtkm::cont::ArrayHandle<T, Storage>& field)
{
this->AddField(vtkm::cont::Field(fieldName, vtkm::cont::Field::Association::Partitions, field));
}
template <typename T>
VTKM_CONT void AddPartitionsField(const std::string& fieldName, const std::vector<T>& field)
{
this->AddField(
make_Field(fieldName, vtkm::cont::Field::Association::Partitions, field, vtkm::CopyFlag::On));
}
template <typename T>
VTKM_CONT void AddPartitionsField(const std::string& fieldName, const T* field, const vtkm::Id& n)
{
this->AddField(make_Field(
fieldName, vtkm::cont::Field::Association::Partitions, field, n, vtkm::CopyFlag::On));
}
VTKM_CONT
const vtkm::cont::Field& GetField(vtkm::Id index) const { return this->Fields.GetField(index); }
VTKM_CONT
vtkm::cont::Field& GetField(vtkm::Id index) { return this->Fields.GetField(index); }
VTKM_CONT
const vtkm::cont::Field& GetField(
const std::string& name,
vtkm::cont::Field::Association assoc = vtkm::cont::Field::Association::Any) const
{
return this->Fields.GetField(name, assoc);
}
VTKM_CONT
vtkm::cont::Field& GetField(
const std::string& name,
vtkm::cont::Field::Association assoc = vtkm::cont::Field::Association::Any)
{
return this->Fields.GetField(name, assoc);
}
VTKM_CONT
const vtkm::cont::Field& GetGlobalField(const std::string& name) const
{
return this->GetField(name, vtkm::cont::Field::Association::Global);
}
VTKM_CONT
const vtkm::cont::Field& GetPartitionsField(const std::string& name) const
{
return this->GetField(name, vtkm::cont::Field::Association::Partitions);
}
VTKM_CONT
vtkm::cont::Field& GetGlobalField(const std::string& name)
{
return this->GetField(name, vtkm::cont::Field::Association::Global);
}
VTKM_CONT
vtkm::cont::Field& GetPartitionsField(const std::string& name)
{
return this->GetField(name, vtkm::cont::Field::Association::Partitions);
}
VTKM_CONT
bool HasField(const std::string& name,
vtkm::cont::Field::Association assoc = vtkm::cont::Field::Association::Any) const
{
return this->Fields.HasField(name, assoc);
}
VTKM_CONT
bool HasGlobalField(const std::string& name) const
{
return (this->Fields.GetFieldIndex(name, vtkm::cont::Field::Association::Global) != -1);
}
VTKM_CONT
bool HasPartitionsField(const std::string& name) const
{
return (this->Fields.GetFieldIndex(name, vtkm::cont::Field::Association::Partitions) != -1);
}
///@}
/// Copies the partitions from the source. The fields on the PartitionedDataSet are not copied.
VTKM_CONT
void CopyPartitions(const vtkm::cont::PartitionedDataSet& source);
VTKM_CONT
void PrintSummary(std::ostream& stream) const;
//@{
///@{
/// API to support range-based for loops on partitions.
VTKM_CONT
iterator begin() noexcept { return this->Partitions.begin(); }
@ -100,9 +228,13 @@ public:
const_iterator cbegin() const noexcept { return this->Partitions.cbegin(); }
VTKM_CONT
const_iterator cend() const noexcept { return this->Partitions.cend(); }
//@}
///@}
private:
std::vector<vtkm::cont::DataSet> Partitions;
vtkm::cont::internal::FieldCollection Fields{ vtkm::cont::Field::Association::Partitions,
vtkm::cont::Field::Association::Global };
};
}
} // namespace vtkm::cont

@ -28,8 +28,42 @@ namespace detail
struct RuntimeDeviceTrackerInternals
{
RuntimeDeviceTrackerInternals() = default;
RuntimeDeviceTrackerInternals(const RuntimeDeviceTrackerInternals* v) { this->CopyFrom(v); }
RuntimeDeviceTrackerInternals& operator=(const RuntimeDeviceTrackerInternals* v)
{
this->CopyFrom(v);
return *this;
}
bool GetRuntimeAllowed(std::size_t deviceId) const { return this->RuntimeAllowed[deviceId]; }
void SetRuntimeAllowed(std::size_t deviceId, bool flag) { this->RuntimeAllowed[deviceId] = flag; }
bool GetThreadFriendlyMemAlloc() const { return this->ThreadFriendlyMemAlloc; }
void SetThreadFriendlyMemAlloc(bool flag) { this->ThreadFriendlyMemAlloc = flag; }
void ResetRuntimeAllowed()
{
std::fill_n(this->RuntimeAllowed, VTKM_MAX_DEVICE_ADAPTER_ID, false);
}
void Reset() { this->ResetRuntimeAllowed(); }
private:
void CopyFrom(const RuntimeDeviceTrackerInternals* v)
{
std::copy(std::cbegin(v->RuntimeAllowed),
std::cend(v->RuntimeAllowed),
std::begin(this->RuntimeAllowed));
this->SetThreadFriendlyMemAlloc(v->GetThreadFriendlyMemAlloc());
}
bool RuntimeAllowed[VTKM_MAX_DEVICE_ADAPTER_ID];
bool ThreadFriendlyMemAlloc = false;
};
}
VTKM_CONT
@ -65,7 +99,7 @@ bool RuntimeDeviceTracker::CanRunOn(vtkm::cont::DeviceAdapterId deviceId) const
{ //If at least a single device is enabled, than any device is enabled
for (vtkm::Int8 i = 1; i < VTKM_MAX_DEVICE_ADAPTER_ID; ++i)
{
if (this->Internals->RuntimeAllowed[static_cast<std::size_t>(i)])
if (this->Internals->GetRuntimeAllowed(static_cast<std::size_t>(i)))
{
return true;
}
@ -75,18 +109,29 @@ bool RuntimeDeviceTracker::CanRunOn(vtkm::cont::DeviceAdapterId deviceId) const
else
{
this->CheckDevice(deviceId);
return this->Internals->RuntimeAllowed[deviceId.GetValue()];
return this->Internals->GetRuntimeAllowed(deviceId.GetValue());
}
}
VTKM_CONT
bool RuntimeDeviceTracker::GetThreadFriendlyMemAlloc() const
{
return this->Internals->GetThreadFriendlyMemAlloc();
}
VTKM_CONT
void RuntimeDeviceTracker::SetDeviceState(vtkm::cont::DeviceAdapterId deviceId, bool state)
{
this->CheckDevice(deviceId);
this->Internals->RuntimeAllowed[deviceId.GetValue()] = state;
this->Internals->SetRuntimeAllowed(deviceId.GetValue(), state);
}
VTKM_CONT
void RuntimeDeviceTracker::SetThreadFriendlyMemAlloc(bool state)
{
this->Internals->SetThreadFriendlyMemAlloc(state);
}
VTKM_CONT void RuntimeDeviceTracker::ResetDevice(vtkm::cont::DeviceAdapterId deviceId)
{
@ -106,7 +151,7 @@ VTKM_CONT void RuntimeDeviceTracker::ResetDevice(vtkm::cont::DeviceAdapterId dev
VTKM_CONT
void RuntimeDeviceTracker::Reset()
{
std::fill_n(this->Internals->RuntimeAllowed, VTKM_MAX_DEVICE_ADAPTER_ID, false);
this->Internals->Reset();
// We use this instead of calling CheckDevice/SetDeviceState so that
// when we use logging we get better messages stating we are reseting
@ -118,7 +163,7 @@ void RuntimeDeviceTracker::Reset()
if (device.IsValueValid())
{
const bool state = runtimeDevice.Exists(device);
this->Internals->RuntimeAllowed[device.GetValue()] = state;
this->Internals->SetRuntimeAllowed(device.GetValue(), state);
}
}
this->LogEnabledDevices();
@ -128,7 +173,7 @@ VTKM_CONT void RuntimeDeviceTracker::DisableDevice(vtkm::cont::DeviceAdapterId d
{
if (deviceId == vtkm::cont::DeviceAdapterTagAny{})
{
std::fill_n(this->Internals->RuntimeAllowed, VTKM_MAX_DEVICE_ADAPTER_ID, false);
this->Internals->ResetRuntimeAllowed();
}
else
{
@ -157,18 +202,15 @@ void RuntimeDeviceTracker::ForceDevice(DeviceAdapterId deviceId)
throw vtkm::cont::ErrorBadValue(message.str());
}
std::fill_n(this->Internals->RuntimeAllowed, VTKM_MAX_DEVICE_ADAPTER_ID, false);
this->Internals->RuntimeAllowed[deviceId.GetValue()] = runtimeExists;
this->Internals->ResetRuntimeAllowed();
this->Internals->SetRuntimeAllowed(deviceId.GetValue(), runtimeExists);
this->LogEnabledDevices();
}
}
VTKM_CONT void RuntimeDeviceTracker::CopyStateFrom(const vtkm::cont::RuntimeDeviceTracker& tracker)
{
std::copy(std::cbegin(tracker.Internals->RuntimeAllowed),
std::cend(tracker.Internals->RuntimeAllowed),
std::begin(this->Internals->RuntimeAllowed));
*(this->Internals) = tracker.Internals;
}
VTKM_CONT
@ -208,11 +250,9 @@ VTKM_CONT
ScopedRuntimeDeviceTracker::ScopedRuntimeDeviceTracker(vtkm::cont::DeviceAdapterId device,
RuntimeDeviceTrackerMode mode)
: RuntimeDeviceTracker(GetRuntimeDeviceTracker().Internals, false)
, SavedState(new detail::RuntimeDeviceTrackerInternals())
, SavedState(new detail::RuntimeDeviceTrackerInternals(this->Internals))
{
VTKM_LOG_S(vtkm::cont::LogLevel::DevicesEnabled, "Entering scoped runtime region");
std::copy_n(
this->Internals->RuntimeAllowed, VTKM_MAX_DEVICE_ADAPTER_ID, this->SavedState->RuntimeAllowed);
if (mode == RuntimeDeviceTrackerMode::Force)
{
@ -234,11 +274,10 @@ ScopedRuntimeDeviceTracker::ScopedRuntimeDeviceTracker(
RuntimeDeviceTrackerMode mode,
const vtkm::cont::RuntimeDeviceTracker& tracker)
: RuntimeDeviceTracker(tracker.Internals, false)
, SavedState(new detail::RuntimeDeviceTrackerInternals())
, SavedState(new detail::RuntimeDeviceTrackerInternals(this->Internals))
{
VTKM_LOG_S(vtkm::cont::LogLevel::DevicesEnabled, "Entering scoped runtime region");
std::copy_n(
this->Internals->RuntimeAllowed, VTKM_MAX_DEVICE_ADAPTER_ID, this->SavedState->RuntimeAllowed);
if (mode == RuntimeDeviceTrackerMode::Force)
{
this->ForceDevice(device);
@ -257,19 +296,17 @@ VTKM_CONT
ScopedRuntimeDeviceTracker::ScopedRuntimeDeviceTracker(
const vtkm::cont::RuntimeDeviceTracker& tracker)
: RuntimeDeviceTracker(tracker.Internals, false)
, SavedState(new detail::RuntimeDeviceTrackerInternals())
, SavedState(new detail::RuntimeDeviceTrackerInternals(this->Internals))
{
VTKM_LOG_S(vtkm::cont::LogLevel::DevicesEnabled, "Entering scoped runtime region");
std::copy_n(
this->Internals->RuntimeAllowed, VTKM_MAX_DEVICE_ADAPTER_ID, this->SavedState->RuntimeAllowed);
}
VTKM_CONT
ScopedRuntimeDeviceTracker::~ScopedRuntimeDeviceTracker()
{
VTKM_LOG_S(vtkm::cont::LogLevel::DevicesEnabled, "Leaving scoped runtime region");
std::copy_n(
this->SavedState->RuntimeAllowed, VTKM_MAX_DEVICE_ADAPTER_ID, this->Internals->RuntimeAllowed);
*(this->Internals) = this->SavedState.get();
this->LogEnabledDevices();
}

@ -110,7 +110,13 @@ public:
///
VTKM_CONT void ForceDevice(DeviceAdapterId deviceId);
/// \brief Copyies the state from the given device.
/// \brief Get/Set use of thread-friendly memory allocation for a device.
///
///
VTKM_CONT bool GetThreadFriendlyMemAlloc() const;
VTKM_CONT void SetThreadFriendlyMemAlloc(bool state);
/// \brief Copies the state from the given device.
///
/// This is a convenient way to allow the `RuntimeDeviceTracker` on one thread
/// copy the behavior from another thread.

@ -118,25 +118,30 @@ public:
///
using WritePortalType = vtkm::internal::ArrayPortalBasicWrite<T>;
/// \brief Returns the number of buffers required for this storage.
/// \brief Create the buffers for an empty array.
///
VTKM_CONT constexpr static vtkm::IdComponent GetNumberOfBuffers();
/// This is used by the `ArrayHandle` base class when constructed with no arguments.
/// A convenience subclass may construct the buffers in a different way based on
/// some provided objects.
///
VTKM_CONT static std::vector<vtkm::cont::internal::Buffer> CreateBuffers();
/// \brief Resizes the array by changing the size of the buffers.
///
/// Can also modify any metadata attached to the buffers.
///
VTKM_CONT static void ResizeBuffers(vtkm::Id numValues,
vtkm::cont::internal::Buffer* buffers,
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::CopyFlag preserve,
vtkm::cont::Token& token);
/// \brief Returns the number of entries allocated in the array.
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers);
VTKM_CONT static vtkm::Id GetNumberOfValues(
const std::vector<vtkm::cont::internal::Buffer>& buffers);
/// \brief Fills the array with the given value starting and ending at the given indices.
///
VTKM_CONT static void Fill(vtkm::cont::internal::Buffer* buffers,
VTKM_CONT static void Fill(const std::vector<vtkm::cont::internal::Buffer>& buffers,
const ValueType& fillValue,
vtkm::Id startIndex,
vtkm::Id endIndex,
@ -144,15 +149,17 @@ public:
/// \brief Create a read-only portal on the specified device.
///
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token);
VTKM_CONT static ReadPortalType CreateReadPortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token);
/// \brief Create a read/write portal on the specified device.
///
VTKM_CONT static WritePortalType CreateWritePortal(vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
VTKM_CONT static WritePortalType CreateWritePortal(
const std::vector<vtkm::cont::internal::Buffer>& buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
};
#endif // VTKM_DOXYGEN_ONLY
@ -175,22 +182,24 @@ struct StorageTraits<vtkm::cont::internal::Storage<T, S>>
using Tag = S;
};
#define VTKM_STORAGE_NO_RESIZE \
VTKM_CONT static void ResizeBuffers( \
vtkm::Id numValues, vtkm::cont::internal::Buffer* buffers, vtkm::CopyFlag, vtkm::cont::Token&) \
{ \
vtkm::cont::internal::detail::StorageNoResizeImpl( \
GetNumberOfValues(buffers), \
numValues, \
vtkm::cont::TypeToString<typename vtkm::cont::internal::StorageTraits<Storage>::Tag>()); \
} \
#define VTKM_STORAGE_NO_RESIZE \
VTKM_CONT static void ResizeBuffers(vtkm::Id numValues, \
const std::vector<vtkm::cont::internal::Buffer>& buffers, \
vtkm::CopyFlag, \
vtkm::cont::Token&) \
{ \
vtkm::cont::internal::detail::StorageNoResizeImpl( \
GetNumberOfValues(buffers), \
numValues, \
vtkm::cont::TypeToString<typename vtkm::cont::internal::StorageTraits<Storage>::Tag>()); \
} \
using ResizeBuffersEatComma = void
#define VTKM_STORAGE_NO_WRITE_PORTAL \
using WritePortalType = vtkm::internal::ArrayPortalDummy< \
typename vtkm::cont::internal::StorageTraits<Storage>::ValueType>; \
VTKM_CONT static void Fill( \
vtkm::cont::internal::Buffer*, \
const std::vector<vtkm::cont::internal::Buffer>&, \
const typename vtkm::cont::internal::StorageTraits<Storage>::ValueType&, \
vtkm::Id, \
vtkm::Id, \
@ -201,7 +210,9 @@ struct StorageTraits<vtkm::cont::internal::Storage<T, S>>
vtkm::cont::TypeToString<typename vtkm::cont::internal::StorageTraits<Storage>::Tag>()); \
} \
VTKM_CONT static WritePortalType CreateWritePortal( \
vtkm::cont::internal::Buffer*, vtkm::cont::DeviceAdapterId, vtkm::cont::Token&) \
const std::vector<vtkm::cont::internal::Buffer>&, \
vtkm::cont::DeviceAdapterId, \
vtkm::cont::Token&) \
{ \
throw vtkm::cont::ErrorBadAllocation( \
"Cannot write to arrays with storage type of " + \

@ -7,6 +7,7 @@
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#include <vtkm/cont/Algorithm.h>
#include <vtkm/cont/DeviceAdapter.h>
#include <vtkm/cont/DeviceAdapterList.h>
#include <vtkm/cont/Logging.h>
@ -326,5 +327,11 @@ vtkm::Float64 Timer::GetElapsedTime() const
return functor.ElapsedTime;
}
void Timer::Synchronize() const
{
vtkm::cont::Algorithm::Synchronize(this->Device);
}
}
} // namespace vtkm::cont

@ -73,15 +73,25 @@ public:
vtkm::Float64 GetElapsedTime() const;
/// Returns the device for which this timer is synchronized. If the device adapter has the same
/// id as DeviceAdapterTagAny, then the timer will synchronize all devices.
/// id as `DeviceAdapterTagAny`, then the timer will synchronize all devices.
VTKM_CONT vtkm::cont::DeviceAdapterId GetDevice() const { return this->Device; }
/// Synchronize the device(s) that this timer is monitoring without starting or stopping the
/// timer. This is useful for ensuring that external events are synchronized to this timer.
///
/// Note that this method will allways block until the device(s) finish even if the
/// `Start`/`Stop` methods do not actually block. For example, the timer for CUDA does not
/// actually wait for asynchronous operations to finish. Rather, it inserts a fence and
/// records the time as fences are encounted. But regardless, this `Synchronize` method
/// will block for the CUDA device.
VTKM_CONT void Synchronize() const;
private:
/// Some timers are ill-defined when copied, so disallow that for all timers.
VTKM_CONT Timer(const Timer&) = delete;
VTKM_CONT void operator=(const Timer&) = delete;
DeviceAdapterId Device;
vtkm::cont::DeviceAdapterId Device;
std::unique_ptr<detail::EnabledDeviceTimerImpls> Internal;
};
}

@ -95,7 +95,17 @@ bool UnknownAHComponentInfo::operator==(const UnknownAHComponentInfo& rhs)
else
{
// Needs optimization based on platform. OSX cannot compare typeid across translation units?
return this->Type == rhs.Type;
bool typesEqual = (this->Type == rhs.Type);
// Could use optimization based on platform. OSX cannot compare typeid across translation
// units, so we have to also check the names. (Why doesn't the == operator above do that?)
// Are there other platforms that behave similarly?
if (!typesEqual)
{
typesEqual = (std::strcmp(this->Type.name(), rhs.Type.name()) == 0);
}
return typesEqual;
}
}
@ -151,7 +161,7 @@ VTKM_CONT bool UnknownArrayHandle::IsBaseComponentTypeImpl(
return false;
}
// Needs optimization based on platform. OSX cannot compare typeid across translation units?
// Note that detail::UnknownAHComponentInfo has a custom operator==
return this->Container->BaseComponentType == type;
}

@ -136,8 +136,7 @@ UnknownAHExtractComponent(void* mem, vtkm::IdComponent componentIndex, vtkm::Cop
using AH = vtkm::cont::ArrayHandle<T, S>;
AH* arrayHandle = reinterpret_cast<AH*>(mem);
auto componentArray = vtkm::cont::ArrayExtractComponent(*arrayHandle, componentIndex, allowCopy);
vtkm::cont::internal::Buffer* buffers = componentArray.GetBuffers();
return std::vector<vtkm::cont::internal::Buffer>(buffers, buffers + 2);
return componentArray.GetBuffers();
}
template <typename T, typename S>

@ -364,7 +364,7 @@ public:
return VariantArrayHandleBase<NewTypeList>(*this);
}
//@{
///@{
/// \brief Call a functor using the underlying array type.
///
/// `CastAndCall` attempts to cast the held array to a specific value type,
@ -398,7 +398,7 @@ public:
{
this->CastAndCallImpl(std::false_type(), std::forward<Functor>(f));
}
//@}
///@}
/// \brief Create a new array of the same type as this array.
///

@ -10,16 +10,19 @@
set(unit_tests
UnitTestControlSignatureTag.cxx
UnitTestTransportArrayIn.cxx
UnitTestTransportArrayInOut.cxx
UnitTestTransportArrayOut.cxx
UnitTestTransportCellSetIn.cxx
UnitTestTransportExecObject.cxx
UnitTestTransportWholeArray.cxx
UnitTestTypeCheckArray.cxx
UnitTestTypeCheckCellSet.cxx
UnitTestTypeCheckExecObject.cxx
UnitTestTypeCheckKeys.cxx
)
vtkm_unit_tests(SOURCES ${unit_tests} DEFINES VTKM_NO_ERROR_ON_MIXED_CUDA_CXX_TAG)
set(unit_tests_device
UnitTestTransportArrayIn.cxx
UnitTestTransportArrayInOut.cxx
UnitTestTransportArrayOut.cxx
UnitTestTransportCellSetIn.cxx
UnitTestTransportExecObject.cxx
UnitTestTransportWholeArray.cxx
)
vtkm_unit_tests(SOURCES ${unit_tests} DEVICE_SOURCES ${unit_tests_device})

@ -8,6 +8,9 @@
// PURPOSE. See the above copyright notice for more information.
//============================================================================
// This test does not really need a device compiler
#define VTKM_NO_ERROR_ON_MIXED_CUDA_CXX_TAG
#include <vtkm/worklet/WorkletMapField.h>
#include <vtkm/cont/testing/Testing.h>

@ -13,7 +13,8 @@
#include <vtkm/exec/FunctorBase.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/serial/DeviceAdapterSerial.h>
#include <vtkm/cont/DeviceAdapter.h>
#include <vtkm/cont/TryExecute.h>
#include <vtkm/cont/testing/Testing.h>
@ -68,15 +69,16 @@ struct TryArrayInType
};
template <typename Device>
void TryArrayInTransport(Device)
bool TryArrayInTransport(Device device)
{
std::cout << "Trying ArrayIn transport with " << device.GetName() << std::endl;
vtkm::testing::Testing::TryTypes(TryArrayInType<Device>());
return true;
}
void TestArrayInTransport()
{
std::cout << "Trying ArrayIn transport with serial device." << std::endl;
TryArrayInTransport(vtkm::cont::DeviceAdapterTagSerial());
VTKM_TEST_ASSERT(vtkm::cont::TryExecute([](auto device) { return TryArrayInTransport(device); }));
}
} // Anonymous namespace

Some files were not shown because too many files have changed in this diff Show More