mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-16 17:22:55 +00:00
Merge branch 'master' of https://gitlab.kitware.com/vtk/vtk-m into pa_storage
This commit is contained in:
commit
bdab4a56d2
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -17,3 +17,4 @@ data/** filter=lfs diff=lfs merge=lfs -text
|
||||
vtkm/thirdparty/diy/vtkmdiy/** -format.clang-format -whitespace
|
||||
vtkm/thirdparty/optionparser/vtkmoptionparser/** -format.clang-format -whitespace
|
||||
vtkm/thirdparty/lodepng/vtkmlodepng/** -format.clang-format -whitespace
|
||||
vtkm/thirdparty/lcl/vtkmlcl/** -format.clang-format -whitespace
|
||||
|
@ -1,539 +0,0 @@
|
||||
##============================================================================
|
||||
## 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.
|
||||
##============================================================================
|
||||
|
||||
#.rst:
|
||||
# FindOpenMP
|
||||
# ----------
|
||||
#
|
||||
# Finds OpenMP support
|
||||
#
|
||||
# This module can be used to detect OpenMP support in a compiler. If
|
||||
# the compiler supports OpenMP, the flags required to compile with
|
||||
# OpenMP support are returned in variables for the different languages.
|
||||
# The variables may be empty if the compiler does not need a special
|
||||
# flag to support OpenMP.
|
||||
#
|
||||
# Variables
|
||||
# ^^^^^^^^^
|
||||
#
|
||||
# The module exposes the components ``C``, ``CXX``, and ``Fortran``.
|
||||
# Each of these controls the various languages to search OpenMP support for.
|
||||
#
|
||||
# Depending on the enabled components the following variables will be set:
|
||||
#
|
||||
# ``OpenMP_FOUND``
|
||||
# Variable indicating that OpenMP flags for all requested languages have been found.
|
||||
# If no components are specified, this is true if OpenMP settings for all enabled languages
|
||||
# were detected.
|
||||
# ``OpenMP_VERSION``
|
||||
# Minimal version of the OpenMP standard detected among the requested languages,
|
||||
# or all enabled languages if no components were specified.
|
||||
#
|
||||
# This module will set the following variables per language in your
|
||||
# project, where ``<lang>`` is one of C, CXX, or Fortran:
|
||||
#
|
||||
# ``OpenMP_<lang>_FOUND``
|
||||
# Variable indicating if OpenMP support for ``<lang>`` was detected.
|
||||
# ``OpenMP_<lang>_FLAGS``
|
||||
# OpenMP compiler flags for ``<lang>``, separated by spaces.
|
||||
#
|
||||
# For linking with OpenMP code written in ``<lang>``, the following
|
||||
# variables are provided:
|
||||
#
|
||||
# ``OpenMP_<lang>_LIB_NAMES``
|
||||
# :ref:`;-list <CMake Language Lists>` of libraries for OpenMP programs for ``<lang>``.
|
||||
# ``OpenMP_<libname>_LIBRARY``
|
||||
# Location of the individual libraries needed for OpenMP support in ``<lang>``.
|
||||
# ``OpenMP_<lang>_LIBRARIES``
|
||||
# A list of libraries needed to link with OpenMP code written in ``<lang>``.
|
||||
#
|
||||
# Additionally, the module provides :prop_tgt:`IMPORTED` targets:
|
||||
#
|
||||
# ``OpenMP::OpenMP_<lang>``
|
||||
# Target for using OpenMP from ``<lang>``.
|
||||
#
|
||||
# Specifically for Fortran, the module sets the following variables:
|
||||
#
|
||||
# ``OpenMP_Fortran_HAVE_OMPLIB_HEADER``
|
||||
# Boolean indicating if OpenMP is accessible through ``omp_lib.h``.
|
||||
# ``OpenMP_Fortran_HAVE_OMPLIB_MODULE``
|
||||
# Boolean indicating if OpenMP is accessible through the ``omp_lib`` Fortran module.
|
||||
#
|
||||
# The module will also try to provide the OpenMP version variables:
|
||||
#
|
||||
# ``OpenMP_<lang>_SPEC_DATE``
|
||||
# Date of the OpenMP specification implemented by the ``<lang>`` compiler.
|
||||
# ``OpenMP_<lang>_VERSION_MAJOR``
|
||||
# Major version of OpenMP implemented by the ``<lang>`` compiler.
|
||||
# ``OpenMP_<lang>_VERSION_MINOR``
|
||||
# Minor version of OpenMP implemented by the ``<lang>`` compiler.
|
||||
# ``OpenMP_<lang>_VERSION``
|
||||
# OpenMP version implemented by the ``<lang>`` compiler.
|
||||
#
|
||||
# The specification date is formatted as given in the OpenMP standard:
|
||||
# ``yyyymm`` where ``yyyy`` and ``mm`` represents the year and month of
|
||||
# the OpenMP specification implemented by the ``<lang>`` compiler.
|
||||
|
||||
cmake_policy(PUSH)
|
||||
cmake_policy(SET CMP0012 NEW) # if() recognizes numbers and booleans
|
||||
cmake_policy(SET CMP0054 NEW) # if() quoted variables not dereferenced
|
||||
cmake_policy(SET CMP0057 NEW) # if IN_LIST
|
||||
|
||||
function(_OPENMP_FLAG_CANDIDATES LANG)
|
||||
if(NOT OpenMP_${LANG}_FLAG)
|
||||
unset(OpenMP_FLAG_CANDIDATES)
|
||||
|
||||
set(OMP_FLAG_GNU "-fopenmp")
|
||||
set(OMP_FLAG_Clang "-fopenmp=libomp" "-fopenmp=libiomp5" "-fopenmp")
|
||||
set(OMP_FLAG_AppleClang "-Xclang -fopenmp")
|
||||
set(OMP_FLAG_HP "+Oopenmp")
|
||||
if(WIN32)
|
||||
set(OMP_FLAG_Intel "-Qopenmp")
|
||||
elseif(CMAKE_${LANG}_COMPILER_ID STREQUAL "Intel" AND
|
||||
"${CMAKE_${LANG}_COMPILER_VERSION}" VERSION_LESS "15.0.0.20140528")
|
||||
set(OMP_FLAG_Intel "-openmp")
|
||||
else()
|
||||
set(OMP_FLAG_Intel "-qopenmp")
|
||||
endif()
|
||||
set(OMP_FLAG_MIPSpro "-mp")
|
||||
set(OMP_FLAG_MSVC "-openmp")
|
||||
set(OMP_FLAG_PathScale "-openmp")
|
||||
set(OMP_FLAG_NAG "-openmp")
|
||||
set(OMP_FLAG_Absoft "-openmp")
|
||||
set(OMP_FLAG_PGI "-mp")
|
||||
set(OMP_FLAG_Flang "-fopenmp")
|
||||
set(OMP_FLAG_SunPro "-xopenmp")
|
||||
set(OMP_FLAG_XL "-qsmp=omp")
|
||||
# Cray compiler activate OpenMP with -h omp, which is enabled by default.
|
||||
set(OMP_FLAG_Cray " " "-h omp")
|
||||
|
||||
# If we know the correct flags, use those
|
||||
if(DEFINED OMP_FLAG_${CMAKE_${LANG}_COMPILER_ID})
|
||||
set(OpenMP_FLAG_CANDIDATES "${OMP_FLAG_${CMAKE_${LANG}_COMPILER_ID}}")
|
||||
# Fall back to reasonable default tries otherwise
|
||||
else()
|
||||
set(OpenMP_FLAG_CANDIDATES "-openmp" "-fopenmp" "-mp" " ")
|
||||
endif()
|
||||
set(OpenMP_${LANG}_FLAG_CANDIDATES "${OpenMP_FLAG_CANDIDATES}" PARENT_SCOPE)
|
||||
else()
|
||||
set(OpenMP_${LANG}_FLAG_CANDIDATES "${OpenMP_${LANG}_FLAG}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# sample openmp source code to test
|
||||
set(OpenMP_C_CXX_TEST_SOURCE
|
||||
"
|
||||
#include <omp.h>
|
||||
int main() {
|
||||
#ifdef _OPENMP
|
||||
int n = omp_get_max_threads();
|
||||
return 0;
|
||||
#else
|
||||
breaks_on_purpose
|
||||
#endif
|
||||
}
|
||||
")
|
||||
|
||||
# in Fortran, an implementation may provide an omp_lib.h header
|
||||
# or omp_lib module, or both (OpenMP standard, section 3.1)
|
||||
# Furthmore !$ is the Fortran equivalent of #ifdef _OPENMP (OpenMP standard, 2.2.2)
|
||||
# Without the conditional compilation, some compilers (e.g. PGI) might compile OpenMP code
|
||||
# while not actually enabling OpenMP, building code sequentially
|
||||
set(OpenMP_Fortran_TEST_SOURCE
|
||||
"
|
||||
program test
|
||||
@OpenMP_Fortran_INCLUDE_LINE@
|
||||
!$ integer :: n
|
||||
n = omp_get_num_threads()
|
||||
end program test
|
||||
"
|
||||
)
|
||||
|
||||
function(_OPENMP_WRITE_SOURCE_FILE LANG SRC_FILE_CONTENT_VAR SRC_FILE_NAME SRC_FILE_FULLPATH)
|
||||
set(WORK_DIR ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindOpenMP)
|
||||
if("${LANG}" STREQUAL "C")
|
||||
set(SRC_FILE "${WORK_DIR}/${SRC_FILE_NAME}.c")
|
||||
file(WRITE "${SRC_FILE}" "${OpenMP_C_CXX_${SRC_FILE_CONTENT_VAR}}")
|
||||
elseif("${LANG}" STREQUAL "CXX")
|
||||
set(SRC_FILE "${WORK_DIR}/${SRC_FILE_NAME}.cpp")
|
||||
file(WRITE "${SRC_FILE}" "${OpenMP_C_CXX_${SRC_FILE_CONTENT_VAR}}")
|
||||
elseif("${LANG}" STREQUAL "Fortran")
|
||||
set(SRC_FILE "${WORK_DIR}/${SRC_FILE_NAME}.f90")
|
||||
file(WRITE "${SRC_FILE}_in" "${OpenMP_Fortran_${SRC_FILE_CONTENT_VAR}}")
|
||||
configure_file("${SRC_FILE}_in" "${SRC_FILE}" @ONLY)
|
||||
endif()
|
||||
set(${SRC_FILE_FULLPATH} "${SRC_FILE}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
include(CMakeParseImplicitLinkInfo)
|
||||
|
||||
function(_OPENMP_GET_FLAGS LANG FLAG_MODE OPENMP_FLAG_VAR OPENMP_LIB_NAMES_VAR)
|
||||
_OPENMP_FLAG_CANDIDATES("${LANG}")
|
||||
_OPENMP_WRITE_SOURCE_FILE("${LANG}" "TEST_SOURCE" OpenMPTryFlag _OPENMP_TEST_SRC)
|
||||
|
||||
unset(OpenMP_VERBOSE_COMPILE_OPTIONS)
|
||||
separate_arguments(OpenMP_VERBOSE_OPTIONS NATIVE_COMMAND "${CMAKE_${LANG}_VERBOSE_FLAG}")
|
||||
foreach(_VERBOSE_OPTION IN LISTS OpenMP_VERBOSE_OPTIONS)
|
||||
if(NOT _VERBOSE_OPTION MATCHES "^-Wl,")
|
||||
list(APPEND OpenMP_VERBOSE_COMPILE_OPTIONS ${_VERBOSE_OPTION})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
foreach(OPENMP_FLAG IN LISTS OpenMP_${LANG}_FLAG_CANDIDATES)
|
||||
set(OPENMP_FLAGS_TEST "${OPENMP_FLAG}")
|
||||
if(OpenMP_VERBOSE_COMPILE_OPTIONS)
|
||||
string(APPEND OPENMP_FLAGS_TEST " ${OpenMP_VERBOSE_COMPILE_OPTIONS}")
|
||||
endif()
|
||||
string(REGEX REPLACE "[-/=+]" "" OPENMP_PLAIN_FLAG "${OPENMP_FLAG}")
|
||||
try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG} ${CMAKE_BINARY_DIR} ${_OPENMP_TEST_SRC}
|
||||
CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAGS_TEST}"
|
||||
LINK_LIBRARIES ${CMAKE_${LANG}_VERBOSE_FLAG}
|
||||
OUTPUT_VARIABLE OpenMP_TRY_COMPILE_OUTPUT
|
||||
)
|
||||
|
||||
if(OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG})
|
||||
set("${OPENMP_FLAG_VAR}" "${OPENMP_FLAG}" PARENT_SCOPE)
|
||||
|
||||
if(CMAKE_${LANG}_VERBOSE_FLAG)
|
||||
unset(OpenMP_${LANG}_IMPLICIT_LIBRARIES)
|
||||
unset(OpenMP_${LANG}_IMPLICIT_LINK_DIRS)
|
||||
unset(OpenMP_${LANG}_IMPLICIT_FWK_DIRS)
|
||||
unset(OpenMP_${LANG}_LOG_VAR)
|
||||
|
||||
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
|
||||
"Detecting ${LANG} OpenMP compiler ABI info compiled with the following output:\n${OpenMP_TRY_COMPILE_OUTPUT}\n\n")
|
||||
|
||||
cmake_parse_implicit_link_info("${OpenMP_TRY_COMPILE_OUTPUT}"
|
||||
OpenMP_${LANG}_IMPLICIT_LIBRARIES
|
||||
OpenMP_${LANG}_IMPLICIT_LINK_DIRS
|
||||
OpenMP_${LANG}_IMPLICIT_FWK_DIRS
|
||||
OpenMP_${LANG}_LOG_VAR
|
||||
"${CMAKE_${LANG}_IMPLICIT_OBJECT_REGEX}"
|
||||
)
|
||||
|
||||
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
|
||||
"Parsed ${LANG} OpenMP implicit link information from above output:\n${OpenMP_${LANG}_LOG_VAR}\n\n")
|
||||
|
||||
unset(_OPENMP_LIB_NAMES)
|
||||
foreach(_OPENMP_IMPLICIT_LIB IN LISTS OpenMP_${LANG}_IMPLICIT_LIBRARIES)
|
||||
get_filename_component(_OPENMP_IMPLICIT_LIB_DIR "${_OPENMP_IMPLICIT_LIB}" DIRECTORY)
|
||||
get_filename_component(_OPENMP_IMPLICIT_LIB_NAME "${_OPENMP_IMPLICIT_LIB}" NAME)
|
||||
get_filename_component(_OPENMP_IMPLICIT_LIB_PLAIN "${_OPENMP_IMPLICIT_LIB}" NAME_WE)
|
||||
string(REGEX REPLACE "([][+.*?()^$])" "\\\\\\1" _OPENMP_IMPLICIT_LIB_PLAIN_ESC "${_OPENMP_IMPLICIT_LIB_PLAIN}")
|
||||
string(REGEX REPLACE "([][+.*?()^$])" "\\\\\\1" _OPENMP_IMPLICIT_LIB_PATH_ESC "${_OPENMP_IMPLICIT_LIB}")
|
||||
if(NOT ( "${_OPENMP_IMPLICIT_LIB}" IN_LIST CMAKE_${LANG}_IMPLICIT_LINK_LIBRARIES
|
||||
OR "${CMAKE_${LANG}_STANDARD_LIBRARIES}" MATCHES "(^| )(-Wl,)?(-l)?(${_OPENMP_IMPLICIT_LIB_PLAIN_ESC}|${_OPENMP_IMPLICIT_LIB_PATH_ESC})( |$)"
|
||||
OR "${CMAKE_${LANG}_LINK_EXECUTABLE}" MATCHES "(^| )(-Wl,)?(-l)?(${_OPENMP_IMPLICIT_LIB_PLAIN_ESC}|${_OPENMP_IMPLICIT_LIB_PATH_ESC})( |$)" ) )
|
||||
if(_OPENMP_IMPLICIT_LIB_DIR)
|
||||
set(OpenMP_${_OPENMP_IMPLICIT_LIB_PLAIN}_LIBRARY "${_OPENMP_IMPLICIT_LIB}" CACHE FILEPATH
|
||||
"Path to the ${_OPENMP_IMPLICIT_LIB_PLAIN} library for OpenMP")
|
||||
else()
|
||||
find_library(OpenMP_${_OPENMP_IMPLICIT_LIB_PLAIN}_LIBRARY
|
||||
NAMES "${_OPENMP_IMPLICIT_LIB_NAME}"
|
||||
DOC "Path to the ${_OPENMP_IMPLICIT_LIB_PLAIN} library for OpenMP"
|
||||
HINTS ${OpenMP_${LANG}_IMPLICIT_LINK_DIRS}
|
||||
CMAKE_FIND_ROOT_PATH_BOTH
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
endif()
|
||||
mark_as_advanced(OpenMP_${_OPENMP_IMPLICIT_LIB_PLAIN}_LIBRARY)
|
||||
list(APPEND _OPENMP_LIB_NAMES ${_OPENMP_IMPLICIT_LIB_PLAIN})
|
||||
endif()
|
||||
endforeach()
|
||||
set("${OPENMP_LIB_NAMES_VAR}" "${_OPENMP_LIB_NAMES}" PARENT_SCOPE)
|
||||
else()
|
||||
# We do not know how to extract implicit OpenMP libraries for this compiler.
|
||||
# Assume that it handles them automatically, e.g. the Intel Compiler on
|
||||
# Windows should put the dependency in its object files.
|
||||
set("${OPENMP_LIB_NAMES_VAR}" "" PARENT_SCOPE)
|
||||
endif()
|
||||
break()
|
||||
elseif(CMAKE_${LANG}_COMPILER_ID STREQUAL "AppleClang"
|
||||
AND CMAKE_${LANG}_COMPILER_VERSION VERSION_GREATER_EQUAL "7.0")
|
||||
|
||||
# Check for separate OpenMP library on AppleClang 7+
|
||||
find_library(OpenMP_libomp_LIBRARY
|
||||
NAMES omp gomp iomp5
|
||||
HINTS ${CMAKE_${LANG}_IMPLICIT_LINK_DIRECTORIES}
|
||||
)
|
||||
mark_as_advanced(OpenMP_libomp_LIBRARY)
|
||||
|
||||
if(OpenMP_libomp_LIBRARY)
|
||||
try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG} ${CMAKE_BINARY_DIR} ${_OPENMP_TEST_SRC}
|
||||
CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAGS_TEST}"
|
||||
LINK_LIBRARIES ${CMAKE_${LANG}_VERBOSE_FLAG} ${OpenMP_libomp_LIBRARY}
|
||||
OUTPUT_VARIABLE OpenMP_TRY_COMPILE_OUTPUT
|
||||
)
|
||||
if(OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG})
|
||||
set("${OPENMP_FLAG_VAR}" "${OPENMP_FLAG}" PARENT_SCOPE)
|
||||
set("${OPENMP_LIB_NAMES_VAR}" "libomp" PARENT_SCOPE)
|
||||
break()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
set("${OPENMP_LIB_NAMES_VAR}" "NOTFOUND" PARENT_SCOPE)
|
||||
set("${OPENMP_FLAG_VAR}" "NOTFOUND" PARENT_SCOPE)
|
||||
endforeach()
|
||||
|
||||
unset(OpenMP_VERBOSE_COMPILE_OPTIONS)
|
||||
endfunction()
|
||||
|
||||
set(OpenMP_C_CXX_CHECK_VERSION_SOURCE
|
||||
"
|
||||
#include <stdio.h>
|
||||
#include <omp.h>
|
||||
const char ompver_str[] = { 'I', 'N', 'F', 'O', ':', 'O', 'p', 'e', 'n', 'M',
|
||||
'P', '-', 'd', 'a', 't', 'e', '[',
|
||||
('0' + ((_OPENMP/100000)%10)),
|
||||
('0' + ((_OPENMP/10000)%10)),
|
||||
('0' + ((_OPENMP/1000)%10)),
|
||||
('0' + ((_OPENMP/100)%10)),
|
||||
('0' + ((_OPENMP/10)%10)),
|
||||
('0' + ((_OPENMP/1)%10)),
|
||||
']', '\\0' };
|
||||
int main()
|
||||
{
|
||||
puts(ompver_str);
|
||||
return 0;
|
||||
}
|
||||
")
|
||||
|
||||
set(OpenMP_Fortran_CHECK_VERSION_SOURCE
|
||||
"
|
||||
program omp_ver
|
||||
@OpenMP_Fortran_INCLUDE_LINE@
|
||||
integer, parameter :: zero = ichar('0')
|
||||
integer, parameter :: ompv = openmp_version
|
||||
character, dimension(24), parameter :: ompver_str =&
|
||||
(/ 'I', 'N', 'F', 'O', ':', 'O', 'p', 'e', 'n', 'M', 'P', '-',&
|
||||
'd', 'a', 't', 'e', '[',&
|
||||
char(zero + mod(ompv/100000, 10)),&
|
||||
char(zero + mod(ompv/10000, 10)),&
|
||||
char(zero + mod(ompv/1000, 10)),&
|
||||
char(zero + mod(ompv/100, 10)),&
|
||||
char(zero + mod(ompv/10, 10)),&
|
||||
char(zero + mod(ompv/1, 10)), ']' /)
|
||||
print *, ompver_str
|
||||
end program omp_ver
|
||||
")
|
||||
|
||||
function(_OPENMP_GET_SPEC_DATE LANG SPEC_DATE)
|
||||
_OPENMP_WRITE_SOURCE_FILE("${LANG}" "CHECK_VERSION_SOURCE" OpenMPCheckVersion _OPENMP_TEST_SRC)
|
||||
|
||||
set(BIN_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/FindOpenMP/ompver_${LANG}.bin")
|
||||
string(REGEX REPLACE "[-/=+]" "" OPENMP_PLAIN_FLAG "${OPENMP_FLAG}")
|
||||
try_compile(OpenMP_SPECTEST_${LANG}_${OPENMP_PLAIN_FLAG} "${CMAKE_BINARY_DIR}" "${_OPENMP_TEST_SRC}"
|
||||
CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OpenMP_${LANG}_FLAGS}"
|
||||
COPY_FILE ${BIN_FILE})
|
||||
|
||||
if(${OpenMP_SPECTEST_${LANG}_${OPENMP_PLAIN_FLAG}})
|
||||
file(STRINGS ${BIN_FILE} specstr LIMIT_COUNT 1 REGEX "INFO:OpenMP-date")
|
||||
set(regex_spec_date ".*INFO:OpenMP-date\\[0*([^]]*)\\].*")
|
||||
if("${specstr}" MATCHES "${regex_spec_date}")
|
||||
set(${SPEC_DATE} "${CMAKE_MATCH_1}" PARENT_SCOPE)
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
macro(_OPENMP_SET_VERSION_BY_SPEC_DATE LANG)
|
||||
set(OpenMP_SPEC_DATE_MAP
|
||||
# Preview versions
|
||||
"201611=5.0" # OpenMP 5.0 preview 1
|
||||
# Combined versions, 2.5 onwards
|
||||
"201511=4.5"
|
||||
"201307=4.0"
|
||||
"201107=3.1"
|
||||
"200805=3.0"
|
||||
"200505=2.5"
|
||||
# C/C++ version 2.0
|
||||
"200203=2.0"
|
||||
# Fortran version 2.0
|
||||
"200011=2.0"
|
||||
# Fortran version 1.1
|
||||
"199911=1.1"
|
||||
# C/C++ version 1.0 (there's no 1.1 for C/C++)
|
||||
"199810=1.0"
|
||||
# Fortran version 1.0
|
||||
"199710=1.0"
|
||||
)
|
||||
|
||||
if(OpenMP_${LANG}_SPEC_DATE)
|
||||
string(REGEX MATCHALL "${OpenMP_${LANG}_SPEC_DATE}=([0-9]+)\\.([0-9]+)" _version_match "${OpenMP_SPEC_DATE_MAP}")
|
||||
else()
|
||||
set(_version_match "")
|
||||
endif()
|
||||
if(NOT _version_match STREQUAL "")
|
||||
set(OpenMP_${LANG}_VERSION_MAJOR ${CMAKE_MATCH_1})
|
||||
set(OpenMP_${LANG}_VERSION_MINOR ${CMAKE_MATCH_2})
|
||||
set(OpenMP_${LANG}_VERSION "${OpenMP_${LANG}_VERSION_MAJOR}.${OpenMP_${LANG}_VERSION_MINOR}")
|
||||
else()
|
||||
unset(OpenMP_${LANG}_VERSION_MAJOR)
|
||||
unset(OpenMP_${LANG}_VERSION_MINOR)
|
||||
unset(OpenMP_${LANG}_VERSION)
|
||||
endif()
|
||||
unset(_version_match)
|
||||
unset(OpenMP_SPEC_DATE_MAP)
|
||||
endmacro()
|
||||
|
||||
foreach(LANG IN ITEMS C CXX)
|
||||
if(CMAKE_${LANG}_COMPILER_LOADED)
|
||||
if(NOT DEFINED OpenMP_${LANG}_FLAGS OR "${OpenMP_${LANG}_FLAGS}" STREQUAL "NOTFOUND"
|
||||
OR NOT DEFINED OpenMP_${LANG}_LIB_NAMES OR "${OpenMP_${LANG}_LIB_NAMES}" STREQUAL "NOTFOUND")
|
||||
_OPENMP_GET_FLAGS("${LANG}" "${LANG}" OpenMP_${LANG}_FLAGS_WORK OpenMP_${LANG}_LIB_NAMES_WORK)
|
||||
endif()
|
||||
|
||||
set(OpenMP_${LANG}_FLAGS "${OpenMP_${LANG}_FLAGS_WORK}"
|
||||
CACHE STRING "${LANG} compiler flags for OpenMP parallelization")
|
||||
set(OpenMP_${LANG}_LIB_NAMES "${OpenMP_${LANG}_LIB_NAMES_WORK}"
|
||||
CACHE STRING "${LANG} compiler libraries for OpenMP parallelization")
|
||||
mark_as_advanced(OpenMP_${LANG}_FLAGS OpenMP_${LANG}_LIB_NAMES)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(CMAKE_Fortran_COMPILER_LOADED)
|
||||
if(NOT DEFINED OpenMP_Fortran_FLAGS OR "${OpenMP_Fortran_FLAGS}" STREQUAL "NOTFOUND"
|
||||
OR NOT DEFINED OpenMP_Fortran_LIB_NAMES OR "${OpenMP_Fortran_LIB_NAMES}" STREQUAL "NOTFOUND"
|
||||
OR NOT DEFINED OpenMP_Fortran_HAVE_OMPLIB_MODULE)
|
||||
set(OpenMP_Fortran_INCLUDE_LINE "use omp_lib\n implicit none")
|
||||
_OPENMP_GET_FLAGS("Fortran" "FortranHeader" OpenMP_Fortran_FLAGS_WORK OpenMP_Fortran_LIB_NAMES_WORK)
|
||||
if(OpenMP_Fortran_FLAGS_WORK)
|
||||
set(OpenMP_Fortran_HAVE_OMPLIB_MODULE TRUE CACHE BOOL INTERNAL "")
|
||||
endif()
|
||||
|
||||
set(OpenMP_Fortran_FLAGS "${OpenMP_Fortran_FLAGS_WORK}"
|
||||
CACHE STRING "Fortran compiler flags for OpenMP parallelization")
|
||||
set(OpenMP_Fortran_LIB_NAMES "${OpenMP_Fortran_LIB_NAMES_WORK}"
|
||||
CACHE STRING "Fortran compiler libraries for OpenMP parallelization")
|
||||
mark_as_advanced(OpenMP_Fortran_FLAGS OpenMP_Fortran_LIB_NAMES)
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED OpenMP_Fortran_FLAGS OR "${OpenMP_Fortran_FLAGS}" STREQUAL "NOTFOUND"
|
||||
OR NOT DEFINED OpenMP_Fortran_LIB_NAMES OR "${OpenMP_Fortran_LIB_NAMES}" STREQUAL "NOTFOUND"
|
||||
OR NOT DEFINED OpenMP_Fortran_HAVE_OMPLIB_HEADER)
|
||||
set(OpenMP_Fortran_INCLUDE_LINE "implicit none\n include 'omp_lib.h'")
|
||||
_OPENMP_GET_FLAGS("Fortran" "FortranModule" OpenMP_Fortran_FLAGS_WORK OpenMP_Fortran_LIB_NAMES_WORK)
|
||||
if(OpenMP_Fortran_FLAGS_WORK)
|
||||
set(OpenMP_Fortran_HAVE_OMPLIB_HEADER TRUE CACHE BOOL INTERNAL "")
|
||||
endif()
|
||||
|
||||
set(OpenMP_Fortran_FLAGS "${OpenMP_Fortran_FLAGS_WORK}"
|
||||
CACHE STRING "Fortran compiler flags for OpenMP parallelization")
|
||||
|
||||
set(OpenMP_Fortran_LIB_NAMES "${OpenMP_Fortran_LIB_NAMES}"
|
||||
CACHE STRING "Fortran compiler libraries for OpenMP parallelization")
|
||||
endif()
|
||||
|
||||
if(OpenMP_Fortran_HAVE_OMPLIB_MODULE)
|
||||
set(OpenMP_Fortran_INCLUDE_LINE "use omp_lib\n implicit none")
|
||||
else()
|
||||
set(OpenMP_Fortran_INCLUDE_LINE "implicit none\n include 'omp_lib.h'")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT OpenMP_FIND_COMPONENTS)
|
||||
set(OpenMP_FINDLIST C CXX Fortran)
|
||||
else()
|
||||
set(OpenMP_FINDLIST ${OpenMP_FIND_COMPONENTS})
|
||||
endif()
|
||||
|
||||
unset(_OpenMP_MIN_VERSION)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
foreach(LANG IN LISTS OpenMP_FINDLIST)
|
||||
if(CMAKE_${LANG}_COMPILER_LOADED)
|
||||
if (NOT OpenMP_${LANG}_SPEC_DATE AND OpenMP_${LANG}_FLAGS)
|
||||
_OPENMP_GET_SPEC_DATE("${LANG}" OpenMP_${LANG}_SPEC_DATE_INTERNAL)
|
||||
set(OpenMP_${LANG}_SPEC_DATE "${OpenMP_${LANG}_SPEC_DATE_INTERNAL}" CACHE
|
||||
INTERNAL "${LANG} compiler's OpenMP specification date")
|
||||
_OPENMP_SET_VERSION_BY_SPEC_DATE("${LANG}")
|
||||
endif()
|
||||
|
||||
set(OpenMP_${LANG}_FIND_QUIETLY ${OpenMP_FIND_QUIETLY})
|
||||
set(OpenMP_${LANG}_FIND_REQUIRED ${OpenMP_FIND_REQUIRED})
|
||||
set(OpenMP_${LANG}_FIND_VERSION ${OpenMP_FIND_VERSION})
|
||||
set(OpenMP_${LANG}_FIND_VERSION_EXACT ${OpenMP_FIND_VERSION_EXACT})
|
||||
|
||||
set(_OPENMP_${LANG}_REQUIRED_VARS OpenMP_${LANG}_FLAGS)
|
||||
if("${OpenMP_${LANG}_LIB_NAMES}" STREQUAL "NOTFOUND")
|
||||
set(_OPENMP_${LANG}_REQUIRED_LIB_VARS OpenMP_${LANG}_LIB_NAMES)
|
||||
else()
|
||||
foreach(_OPENMP_IMPLICIT_LIB IN LISTS OpenMP_${LANG}_LIB_NAMES)
|
||||
list(APPEND _OPENMP_${LANG}_REQUIRED_LIB_VARS OpenMP_${_OPENMP_IMPLICIT_LIB}_LIBRARY)
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
find_package_handle_standard_args(OpenMP_${LANG}
|
||||
REQUIRED_VARS OpenMP_${LANG}_FLAGS ${_OPENMP_${LANG}_REQUIRED_LIB_VARS}
|
||||
VERSION_VAR OpenMP_${LANG}_VERSION
|
||||
)
|
||||
|
||||
if(OpenMP_${LANG}_FOUND)
|
||||
if(DEFINED OpenMP_${LANG}_VERSION)
|
||||
if(NOT _OpenMP_MIN_VERSION OR _OpenMP_MIN_VERSION VERSION_GREATER OpenMP_${LANG}_VERSION)
|
||||
set(_OpenMP_MIN_VERSION OpenMP_${LANG}_VERSION)
|
||||
endif()
|
||||
endif()
|
||||
set(OpenMP_${LANG}_LIBRARIES "")
|
||||
foreach(_OPENMP_IMPLICIT_LIB IN LISTS OpenMP_${LANG}_LIB_NAMES)
|
||||
list(APPEND OpenMP_${LANG}_LIBRARIES "${OpenMP_${_OPENMP_IMPLICIT_LIB}_LIBRARY}")
|
||||
endforeach()
|
||||
|
||||
if(NOT TARGET OpenMP::OpenMP_${LANG})
|
||||
add_library(OpenMP::OpenMP_${LANG} INTERFACE IMPORTED)
|
||||
endif()
|
||||
if(OpenMP_${LANG}_FLAGS)
|
||||
separate_arguments(_OpenMP_${LANG}_OPTIONS NATIVE_COMMAND "${OpenMP_${LANG}_FLAGS}")
|
||||
set_property(TARGET OpenMP::OpenMP_${LANG} PROPERTY
|
||||
INTERFACE_COMPILE_OPTIONS "$<$<COMPILE_LANGUAGE:${LANG}>:${_OpenMP_${LANG}_OPTIONS}>")
|
||||
unset(_OpenMP_${LANG}_OPTIONS)
|
||||
endif()
|
||||
if(OpenMP_${LANG}_LIBRARIES)
|
||||
set_property(TARGET OpenMP::OpenMP_${LANG} PROPERTY
|
||||
INTERFACE_LINK_LIBRARIES "${OpenMP_${LANG}_LIBRARIES}")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
unset(_OpenMP_REQ_VARS)
|
||||
foreach(LANG IN ITEMS C CXX Fortran)
|
||||
if((NOT OpenMP_FIND_COMPONENTS AND CMAKE_${LANG}_COMPILER_LOADED) OR LANG IN_LIST OpenMP_FIND_COMPONENTS)
|
||||
list(APPEND _OpenMP_REQ_VARS "OpenMP_${LANG}_FOUND")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
find_package_handle_standard_args(OpenMP
|
||||
REQUIRED_VARS ${_OpenMP_REQ_VARS}
|
||||
VERSION_VAR ${_OpenMP_MIN_VERSION}
|
||||
HANDLE_COMPONENTS)
|
||||
|
||||
set(OPENMP_FOUND ${OpenMP_FOUND})
|
||||
|
||||
if(CMAKE_Fortran_COMPILER_LOADED AND OpenMP_Fortran_FOUND)
|
||||
if(NOT DEFINED OpenMP_Fortran_HAVE_OMPLIB_MODULE)
|
||||
set(OpenMP_Fortran_HAVE_OMPLIB_MODULE FALSE CACHE BOOL INTERNAL "")
|
||||
endif()
|
||||
if(NOT DEFINED OpenMP_Fortran_HAVE_OMPLIB_HEADER)
|
||||
set(OpenMP_Fortran_HAVE_OMPLIB_HEADER FALSE CACHE BOOL INTERNAL "")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT ( CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED OR CMAKE_Fortran_COMPILER_LOADED ))
|
||||
message(SEND_ERROR "FindOpenMP requires the C, CXX or Fortran languages to be enabled")
|
||||
endif()
|
||||
|
||||
unset(OpenMP_C_CXX_TEST_SOURCE)
|
||||
unset(OpenMP_Fortran_TEST_SOURCE)
|
||||
unset(OpenMP_C_CXX_CHECK_VERSION_SOURCE)
|
||||
unset(OpenMP_Fortran_CHECK_VERSION_SOURCE)
|
||||
unset(OpenMP_Fortran_INCLUDE_LINE)
|
||||
|
||||
cmake_policy(POP)
|
@ -14,7 +14,9 @@
|
||||
#
|
||||
# vtkm_rendering Target that contains all the rendering code
|
||||
#
|
||||
# vtkm_filter Target that contains all of VTK-m filters
|
||||
# vtkm_filter Target that contains all of VTK-m pre-built filters
|
||||
#
|
||||
# vtkm_source Target that contains all of VTK-m pre-built sources
|
||||
#
|
||||
# vtkm::tbb Target that contains tbb related link information
|
||||
# implicitly linked to by `vtkm_cont` if tbb is enabled
|
||||
|
@ -86,7 +86,7 @@ endif()
|
||||
|
||||
|
||||
if(VTKm_ENABLE_OPENMP AND NOT TARGET vtkm::openmp)
|
||||
cmake_minimum_required(VERSION 3.9...3.15 FATAL_ERROR)
|
||||
cmake_minimum_required(VERSION 3.12...3.15 FATAL_ERROR)
|
||||
find_package(OpenMP 4.0 REQUIRED COMPONENTS CXX QUIET)
|
||||
|
||||
add_library(vtkm::openmp INTERFACE IMPORTED GLOBAL)
|
||||
|
@ -110,6 +110,33 @@ function(vtkm_declare_headers)
|
||||
vtkm_install_headers("${dir_prefix}" ${ARGN})
|
||||
endfunction(vtkm_declare_headers)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
function(vtkm_setup_job_pool)
|
||||
# The VTK-m job pool is only used for components that use large amounts
|
||||
# of memory such as worklet tests, filters, and filter tests
|
||||
get_property(vtkm_pool_established
|
||||
GLOBAL PROPERTY VTKM_JOB_POOL_ESTABLISHED SET)
|
||||
if(NOT vtkm_pool_established)
|
||||
# The VTK-m filters uses large amounts of memory to compile as it does lots
|
||||
# of template expansion. To reduce the amount of tension on the machine when
|
||||
# using generators such as ninja we restrict the number of VTK-m enabled
|
||||
# compilation units to be built at the same time.
|
||||
#
|
||||
# We try to allocate a pool size where we presume each compilation process
|
||||
# will require 4GB of memory. To allow for other NON VTK-m jobs we leave at
|
||||
# least 8GB of memory as 'slop'.
|
||||
cmake_host_system_information(RESULT vtkm_mem_ QUERY TOTAL_PHYSICAL_MEMORY)
|
||||
math(EXPR vtkm_pool_size "(${vtkm_mem_}/4096)-2")
|
||||
if (vtkm_pool_size EQUAL 0)
|
||||
set(vtkm_pool_size 1)
|
||||
endif ()
|
||||
set_property(GLOBAL APPEND
|
||||
PROPERTY
|
||||
JOB_POOLS vtkm_pool=${vtkm_pool_size})
|
||||
set_property(GLOBAL PROPERTY VTKM_JOB_POOL_ESTABLISHED TRUE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# FORWARD FACING API
|
||||
|
||||
@ -313,10 +340,11 @@ endfunction()
|
||||
# SOURCES <source_list>
|
||||
# TEMPLATE_SOURCES <.hxx >
|
||||
# HEADERS <header list>
|
||||
# USE_VTKM_JOB_POOL
|
||||
# [ DEVICE_SOURCES <source_list> ]
|
||||
# )
|
||||
function(vtkm_library)
|
||||
set(options OBJECT STATIC SHARED)
|
||||
set(options OBJECT STATIC SHARED USE_VTKM_JOB_POOL)
|
||||
set(oneValueArgs NAME)
|
||||
set(multiValueArgs SOURCES HEADERS TEMPLATE_SOURCES DEVICE_SOURCES)
|
||||
cmake_parse_arguments(VTKm_LIB
|
||||
@ -357,7 +385,6 @@ function(vtkm_library)
|
||||
set_property(TARGET ${lib_name} PROPERTY LIBRARY_OUTPUT_DIRECTORY ${VTKm_LIBRARY_OUTPUT_PATH})
|
||||
set_property(TARGET ${lib_name} PROPERTY RUNTIME_OUTPUT_DIRECTORY ${VTKm_EXECUTABLE_OUTPUT_PATH})
|
||||
|
||||
|
||||
# allow the static cuda runtime find the driver (libcuda.dyllib) at runtime.
|
||||
if(APPLE)
|
||||
set_property(TARGET ${lib_name} PROPERTY BUILD_RPATH ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES})
|
||||
@ -402,4 +429,9 @@ function(vtkm_library)
|
||||
RUNTIME DESTINATION ${VTKm_INSTALL_BIN_DIR}
|
||||
)
|
||||
|
||||
if(VTKm_LIB_USE_VTKM_JOB_POOL)
|
||||
vtkm_setup_job_pool()
|
||||
set_property(TARGET ${lib_name} PROPERTY JOB_POOL_COMPILE vtkm_pool)
|
||||
endif()
|
||||
|
||||
endfunction(vtkm_library)
|
||||
|
@ -22,6 +22,7 @@ include(VTKmWrappers)
|
||||
# TEST_ARGS <argument_list>
|
||||
# MPI
|
||||
# ALL_BACKENDS
|
||||
# USE_VTKM_JOB_POOL
|
||||
# <options>
|
||||
# )
|
||||
#
|
||||
@ -46,7 +47,7 @@ function(vtkm_unit_tests)
|
||||
endif()
|
||||
|
||||
set(options)
|
||||
set(global_options ${options} MPI ALL_BACKENDS)
|
||||
set(global_options ${options} USE_VTKM_JOB_POOL MPI ALL_BACKENDS)
|
||||
set(oneValueArgs BACKEND NAME LABEL)
|
||||
set(multiValueArgs SOURCES LIBRARIES DEFINES TEST_ARGS)
|
||||
cmake_parse_arguments(VTKm_UT
|
||||
@ -137,6 +138,11 @@ function(vtkm_unit_tests)
|
||||
|
||||
target_link_libraries(${test_prog} PRIVATE vtkm_cont ${VTKm_UT_LIBRARIES})
|
||||
|
||||
if(VTKm_UT_USE_VTKM_JOB_POOL)
|
||||
vtkm_setup_job_pool()
|
||||
set_property(TARGET ${test_prog} PROPERTY JOB_POOL_COMPILE vtkm_pool)
|
||||
endif()
|
||||
|
||||
list(LENGTH per_device_command_line_arguments number_of_devices)
|
||||
foreach(index RANGE ${number_of_devices})
|
||||
if(index EQUAL number_of_devices)
|
||||
@ -145,7 +151,7 @@ function(vtkm_unit_tests)
|
||||
break()
|
||||
endif()
|
||||
if(per_device_command_line_arguments STREQUAL "NONE")
|
||||
set(device_command_line_argument ${per_device_command_line_arguments})
|
||||
set(device_command_line_argument)
|
||||
set(upper_backend ${per_device_suffix})
|
||||
set(timeout ${per_device_timeout})
|
||||
set(run_serial ${per_device_serial})
|
||||
|
@ -250,7 +250,6 @@ if(NOT VTKm_INSTALL_ONLY_LIBRARIES)
|
||||
${VTKm_SOURCE_DIR}/CMake/FindTBB.cmake
|
||||
${VTKm_SOURCE_DIR}/CMake/FindMPI.cmake
|
||||
${VTKm_SOURCE_DIR}/CMake/FindOpenGL.cmake
|
||||
${VTKm_SOURCE_DIR}/CMake/FindOpenMP.cmake
|
||||
DESTINATION ${VTKm_INSTALL_CMAKE_MODULE_DIR}
|
||||
)
|
||||
|
||||
|
@ -65,8 +65,8 @@ VTK-m Requires:
|
||||
+ Intel 17.0.4+
|
||||
+ [CMake](http://www.cmake.org/download/)
|
||||
+ CMake 3.8+
|
||||
+ CMake 3.9+ (for OpenMP support)
|
||||
+ CMake 3.11+ (for Visual Studio generator)
|
||||
+ CMake 3.12+ (for OpenMP support)
|
||||
+ CMake 3.13+ (for CUDA support)
|
||||
|
||||
Optional dependencies are:
|
||||
|
@ -46,8 +46,8 @@
|
||||
|
||||
#include <vtkm/io/reader/VTKDataSetReader.h>
|
||||
|
||||
#include <vtkm/source/Wavelet.h>
|
||||
#include <vtkm/worklet/DispatcherMapField.h>
|
||||
#include <vtkm/worklet/WaveletGenerator.h>
|
||||
#include <vtkm/worklet/WorkletMapField.h>
|
||||
|
||||
#include <cctype> // for std::tolower
|
||||
@ -142,7 +142,6 @@ using UnstructuredCellList =
|
||||
|
||||
using AllCellList = vtkm::ListTagJoin<StructuredCellList, UnstructuredCellList>;
|
||||
|
||||
using CoordinateList = vtkm::ListTagBase<vtkm::Vec3f_32, vtkm::Vec3f_64>;
|
||||
|
||||
class BenchmarkFilterPolicy : public vtkm::filter::PolicyBase<BenchmarkFilterPolicy>
|
||||
{
|
||||
@ -152,8 +151,6 @@ public:
|
||||
using StructuredCellSetList = StructuredCellList;
|
||||
using UnstructuredCellSetList = UnstructuredCellList;
|
||||
using AllCellSetList = AllCellList;
|
||||
|
||||
using CoordinateTypeList = CoordinateList;
|
||||
};
|
||||
|
||||
// Class implementing all filter benchmarks:
|
||||
@ -307,7 +304,7 @@ class BenchmarkFilters
|
||||
{
|
||||
Timer timer{ DeviceAdapter() };
|
||||
timer.Start();
|
||||
auto result = this->Filter.Execute(InputDataSet, BenchmarkFilterPolicy());
|
||||
auto result = this->Filter.Execute(InputDataSet);
|
||||
(void)result;
|
||||
return timer.GetElapsedTime();
|
||||
}
|
||||
@ -374,7 +371,7 @@ class BenchmarkFilters
|
||||
{
|
||||
Timer timer{ DeviceAdapter() };
|
||||
timer.Start();
|
||||
auto result = this->Filter.Execute(InputDataSet, BenchmarkFilterPolicy());
|
||||
auto result = this->Filter.Execute(InputDataSet);
|
||||
(void)result;
|
||||
return timer.GetElapsedTime();
|
||||
}
|
||||
@ -400,7 +397,7 @@ class BenchmarkFilters
|
||||
{
|
||||
Timer timer{ DeviceAdapter() };
|
||||
timer.Start();
|
||||
auto result = this->Filter.Execute(InputDataSet, BenchmarkFilterPolicy());
|
||||
auto result = this->Filter.Execute(InputDataSet);
|
||||
(void)result;
|
||||
return timer.GetElapsedTime();
|
||||
}
|
||||
@ -501,7 +498,7 @@ class BenchmarkFilters
|
||||
{
|
||||
Timer timer{ DeviceAdapter() };
|
||||
timer.Start();
|
||||
auto result = this->Filter.Execute(InputDataSet, BenchmarkFilterPolicy());
|
||||
auto result = this->Filter.Execute(InputDataSet);
|
||||
(void)result;
|
||||
return timer.GetElapsedTime();
|
||||
}
|
||||
@ -547,7 +544,7 @@ class BenchmarkFilters
|
||||
{
|
||||
Timer timer{ DeviceAdapter() };
|
||||
timer.Start();
|
||||
auto result = this->Filter.Execute(InputDataSet, BenchmarkFilterPolicy());
|
||||
auto result = this->Filter.Execute(InputDataSet);
|
||||
(void)result;
|
||||
return timer.GetElapsedTime();
|
||||
}
|
||||
@ -649,11 +646,11 @@ class BenchmarkFilters
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4>
|
||||
VTKM_CONT void operator()(const vtkm::cont::CellSetExplicit<T1, T2, T3, T4>& cellSet) const
|
||||
template <typename T1, typename T2, typename T3>
|
||||
VTKM_CONT void operator()(const vtkm::cont::CellSetExplicit<T1, T2, T3>& cellSet) const
|
||||
{
|
||||
{ // Why does CastAndCall insist on making the cellset const?
|
||||
using CellSetT = vtkm::cont::CellSetExplicit<T1, T2, T3, T4>;
|
||||
using CellSetT = vtkm::cont::CellSetExplicit<T1, T2, T3>;
|
||||
CellSetT& mcellSet = const_cast<CellSetT&>(cellSet);
|
||||
mcellSet.ResetConnectivity(vtkm::TopologyElementTagPoint{},
|
||||
vtkm::TopologyElementTagCell{});
|
||||
@ -954,7 +951,7 @@ void CreateFields(bool needPointScalars, bool needCellScalars, bool needPointVec
|
||||
vtkm::filter::PointAverage avg;
|
||||
avg.SetActiveField(CellScalarsName, vtkm::cont::Field::Association::CELL_SET);
|
||||
avg.SetOutputFieldName("GeneratedPointScalars");
|
||||
auto outds = avg.Execute(InputDataSet, BenchmarkFilterPolicy());
|
||||
auto outds = avg.Execute(InputDataSet);
|
||||
InputDataSet.AddField(
|
||||
outds.GetField("GeneratedPointScalars", vtkm::cont::Field::Association::POINTS));
|
||||
PointScalarsName = "GeneratedPointScalars";
|
||||
@ -977,7 +974,7 @@ void CreateFields(bool needPointScalars, bool needCellScalars, bool needPointVec
|
||||
vtkm::filter::VectorMagnitude mag;
|
||||
mag.SetActiveField(PointVectorsName, vtkm::cont::Field::Association::POINTS);
|
||||
mag.SetOutputFieldName("GeneratedPointScalars");
|
||||
auto outds = mag.Execute(InputDataSet, BenchmarkFilterPolicy());
|
||||
auto outds = mag.Execute(InputDataSet);
|
||||
InputDataSet.AddField(
|
||||
outds.GetField("GeneratedPointScalars", vtkm::cont::Field::Association::POINTS));
|
||||
PointScalarsName = "GeneratedPointScalars";
|
||||
@ -999,7 +996,7 @@ void CreateFields(bool needPointScalars, bool needCellScalars, bool needPointVec
|
||||
vtkm::filter::CellAverage avg;
|
||||
avg.SetActiveField(PointScalarsName, vtkm::cont::Field::Association::POINTS);
|
||||
avg.SetOutputFieldName("GeneratedCellScalars");
|
||||
auto outds = avg.Execute(InputDataSet, BenchmarkFilterPolicy());
|
||||
auto outds = avg.Execute(InputDataSet);
|
||||
InputDataSet.AddField(
|
||||
outds.GetField("GeneratedCellScalars", vtkm::cont::Field::Association::CELL_SET));
|
||||
CellScalarsName = "GeneratedCellScalars";
|
||||
@ -1357,10 +1354,10 @@ int BenchmarkBody(int argc, char** argv, const vtkm::cont::InitializeResult& con
|
||||
{
|
||||
std::cout << "Generating " << waveletDim << "x" << waveletDim << "x" << waveletDim
|
||||
<< " wavelet...\n";
|
||||
vtkm::worklet::WaveletGenerator gen;
|
||||
gen.SetExtent({ 0 }, { waveletDim });
|
||||
vtkm::source::Wavelet source;
|
||||
source.SetExtent({ 0 }, { waveletDim });
|
||||
|
||||
InputDataSet = gen.GenerateDataSet(config.Device);
|
||||
InputDataSet = source.Execute();
|
||||
}
|
||||
|
||||
if (tetra)
|
||||
|
@ -42,7 +42,7 @@ set(benchmarks
|
||||
)
|
||||
|
||||
foreach (benchmark ${benchmarks})
|
||||
add_benchmark(NAME ${benchmark} FILE ${benchmark}.cxx LIBS vtkm_filter)
|
||||
add_benchmark(NAME ${benchmark} FILE ${benchmark}.cxx LIBS vtkm_source vtkm_filter)
|
||||
endforeach ()
|
||||
|
||||
if(TARGET vtkm_rendering)
|
||||
|
193
docs/ReleaseProcess.md
Normal file
193
docs/ReleaseProcess.md
Normal file
@ -0,0 +1,193 @@
|
||||
Release Process
|
||||
===============
|
||||
|
||||
# High level view
|
||||
1. Craft Release Branch
|
||||
- Generate change log
|
||||
- Commit change log
|
||||
- Commit update to version.txt
|
||||
- Merge release branch
|
||||
2. Tag release
|
||||
3. Add Gitlab Release Notes
|
||||
4. Announce
|
||||
|
||||
|
||||
# Craft Release Branch
|
||||
|
||||
Construct a git branch named `release_X.Y`
|
||||
|
||||
## Generate change log
|
||||
Construct a `docs/changelog/X.Y/` folder.
|
||||
Construct a `docs/changelog/X.Y/release-notes.md` file
|
||||
|
||||
Use the following template for `release-notes.md`:
|
||||
|
||||
```md
|
||||
VTK-m N Release Notes
|
||||
=======================
|
||||
|
||||
# Table of Contents
|
||||
1. [Core](#Core)
|
||||
- Core change 1
|
||||
2. [ArrayHandle](#ArrayHandle)
|
||||
3. [Control Environment](#Control-Environment)
|
||||
4. [Execution Environment](#Execution-Environment)
|
||||
5. [Worklets and Filters](#Worklets-and-Filters)
|
||||
6. [Build](#Build)
|
||||
7. [Other](#Other)
|
||||
|
||||
|
||||
# Core
|
||||
|
||||
## Core change 1 ##
|
||||
|
||||
changes in core 1
|
||||
|
||||
# ArrayHandle
|
||||
|
||||
# Control Enviornment
|
||||
|
||||
# Execution Environment
|
||||
|
||||
# Execution Environment
|
||||
|
||||
# Worklets and Filters
|
||||
|
||||
# Build
|
||||
|
||||
|
||||
# Other
|
||||
```
|
||||
|
||||
For each individual file in `docs/changelog` move them
|
||||
to the relevant `release-notes` section.
|
||||
|
||||
- Make sure each title and entry in the table of contents use full vtkm names `vtkm::cont::Field` instead of Field
|
||||
- Make sure each title and entry DOESNT have a peroid at the end
|
||||
- Make sure any sub-heading as part of the changelog is transformed from `##` to `###`.
|
||||
- Entries for `Core` are reserved for large changes that significantly improve VTK-m users life, or are
|
||||
major breaking changes.
|
||||
|
||||
## Commit change log
|
||||
|
||||
Remove each individual change log file from the git repository
|
||||
using `git rm docs/changelog/*.md`
|
||||
|
||||
Add the changelog to the git history using `git add changelog/X.Y/release-notes.md`
|
||||
|
||||
make a commit with the message:
|
||||
```
|
||||
Add release notes for vX.Y.Z
|
||||
```
|
||||
|
||||
## Commit update to version.txt
|
||||
|
||||
Add a second commit to the `release_X.Y` branch that contains the update
|
||||
of the `version.txt` file to the correct version. The commit diff should look like:
|
||||
```
|
||||
--- a/version.txt
|
||||
+++ b/version.txt
|
||||
@@ -1 +1 @@
|
||||
-1.4.0
|
||||
+1.5.0
|
||||
```
|
||||
|
||||
The commit message should read:
|
||||
```
|
||||
X.Y.0 is our Nth official release of VTK-m.
|
||||
|
||||
The major changes to VTK-m from A.B.C can be found in:
|
||||
docs/changelog/X.Y/release-notes.md
|
||||
```
|
||||
|
||||
## Merge release branch
|
||||
|
||||
At this point you should be ready to merge this branch.
|
||||
So push to the `release_X.Y` branch to gitlab and open a merge request.
|
||||
The dashboards should produce a configure warning that the new release git tag
|
||||
can't be found. This is to be expected.
|
||||
|
||||
Before completing the merge it is a good idea to review the rendered markdown of the release notes to ensure that they display properly.
|
||||
On the merge request page, click on the Changes tab and then for the `release.X.Y` file click the View file button in the upper right.
|
||||
|
||||
# Tag Release
|
||||
|
||||
Once the merge request is merged we can add the tag.
|
||||
VTK-m marks the commit that contains the modifications to `version.txt` as the tag location, not the merge commit.
|
||||
After the merge this would be the second commit shown by git log as shown below:
|
||||
|
||||
```
|
||||
git checkout master
|
||||
git pull
|
||||
git log -n2
|
||||
Merge: d3d3e441 f66d980d
|
||||
commit f66d980d (HEAD -> release_X.Y.0, gitlab/release_X.Y.0, master)
|
||||
```
|
||||
|
||||
To place the tag at the correct location you will use the following command:
|
||||
```
|
||||
git tag -a -f vX.Y.Z SHA1
|
||||
```
|
||||
|
||||
For the above example the `SHA1` would be `f66d980d`
|
||||
|
||||
This should prompt you to add a message to the tag. The message should be identical to the one
|
||||
you used in the commit.
|
||||
|
||||
## Push git tags
|
||||
|
||||
Now you will need to push the tag back to gitlab so you will need to do the following:
|
||||
|
||||
```
|
||||
git remote add origin_update_tags git@gitlab.kitware.com:vtk/vtk-m.git
|
||||
git push --tags origin_update_tags
|
||||
git remote rm origin_update_tags
|
||||
|
||||
```
|
||||
|
||||
# Add Gitlab Release Notes
|
||||
|
||||
Now that the VTK-m release is on gitlab we have to add the associated changelog to the release
|
||||
entry on gitlab.
|
||||
|
||||
Go to `https://gitlab.kitware.com/vtk/vtk-m/-/tags/vX.Y.Z/release/edit` to edit the release page.
|
||||
Copy the contents of `docs/changelog/X.Y/release-notes.md`
|
||||
|
||||
# Email Announcements
|
||||
|
||||
Announce the new VTK-m release on the mailing list. You will need to compute
|
||||
the number of merge requests, changelog entries, and maybe # of authors.
|
||||
|
||||
To compute the number of unique committers
|
||||
```
|
||||
git log --format="%an" v1.4.0..v1.5.0 | sort -u | wc -l
|
||||
```
|
||||
|
||||
To compute the number of merge requests
|
||||
```
|
||||
git log v1.4.0..v1.5.0 | grep 'Merge | wc -l
|
||||
```
|
||||
|
||||
A standard template to use is:
|
||||
|
||||
|
||||
```
|
||||
Hi All,
|
||||
|
||||
VTK-m 1.5.0 is now released, and a special thanks to everyone that has
|
||||
contributed to VTK-m since our last release. The 1.5.0 release contains
|
||||
over 100000 merge requests, and 100000 entries to the changelog .
|
||||
|
||||
Below are all the entries in the changelog, with more details at (
|
||||
https://gitlab.kitware.com/vtk/vtk-m/tags/vX.Y.0 ) or in the vtkm
|
||||
repository at `docs/X.Y/release-notes.md`
|
||||
|
||||
1. Core
|
||||
- Core change 1
|
||||
2. ArrayHandle
|
||||
3. Control Environment
|
||||
4. Execution Environment
|
||||
5. Worklets and Filters
|
||||
6. Build
|
||||
7. Other
|
||||
```
|
@ -1,7 +0,0 @@
|
||||
# 0-sample-topic
|
||||
|
||||
This is a sample release note for the change in a topic.
|
||||
Developers should add similar notes for each topic branch
|
||||
making a noteworthy change. Each document should be named
|
||||
and titled to match the topic name to avoid merge conflicts.
|
||||
|
1367
docs/changelog/1.5/release-notes.md
Normal file
1367
docs/changelog/1.5/release-notes.md
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,145 +0,0 @@
|
||||
Add ability to test exact neighbor offset locations in BoundaryState.
|
||||
|
||||
The following methods:
|
||||
```
|
||||
BoundaryState::InXBoundary
|
||||
BoundaryState::InYBoundary
|
||||
BoundaryState::InZBoundary
|
||||
BoundaryState::InBoundary
|
||||
```
|
||||
|
||||
have been renamed to:
|
||||
|
||||
```
|
||||
BoundaryState::IsRadiusInXBoundary
|
||||
BoundaryState::IsRadiusInYBoundary
|
||||
BoundaryState::IsRadiusInZBoundary
|
||||
BoundaryState::IsRadiusInBoundary
|
||||
```
|
||||
|
||||
to distinguish them from the new methods:
|
||||
|
||||
```
|
||||
BoundaryState::IsNeighborInXBoundary
|
||||
BoundaryState::IsNeighborInYBoundary
|
||||
BoundaryState::IsNeighborInZBoundary
|
||||
BoundaryState::IsNeighborInBoundary
|
||||
```
|
||||
|
||||
which check a specific neighbor sample offset instead of a full radius.
|
||||
|
||||
The method `BoundaryState::ClampNeighborIndex` has also been added, which clamps
|
||||
a 3D neighbor offset vector to the dataset boundaries.
|
||||
|
||||
This allows iteration through only the valid points in a neighborhood using
|
||||
either of the following patterns:
|
||||
|
||||
Using `ClampNeighborIndex` to restrict the iteration space:
|
||||
```
|
||||
struct MyWorklet : public vtkm::worklet::WorkletPointNeighborhood
|
||||
{
|
||||
public:
|
||||
using ControlSignature = void(CellSetIn, FieldInNeighborhood, FieldOut);
|
||||
using ExecutionSignature = void(_2, Boundary, _3);
|
||||
|
||||
template <typename InNeighborhoodT, typename OutDataT>
|
||||
VTKM_EXEC void operator()(const InNeighborhoodT& inData,
|
||||
const vtkm::exec::BoundaryState &boundary,
|
||||
OutDataT& outData) const
|
||||
{
|
||||
// Clamp the radius to the dataset bounds (discard out-of-bounds points).
|
||||
const auto minRadius = boundary.ClampNeighborIndex({-10, -10, -10});
|
||||
const auto maxRadius = boundary.ClampNeighborIndex({10, 10, 10});
|
||||
|
||||
for (vtkm::IdComponent k = minRadius[2]; k <= maxRadius[2]; ++k)
|
||||
{
|
||||
for (vtkm::IdComponent j = minRadius[1]; j <= maxRadius[1]; ++j)
|
||||
{
|
||||
for (vtkm::IdComponent i = minRadius[0]; i <= maxRadius[0]; ++i)
|
||||
{
|
||||
outData = doSomeConvolution(i, j, k, outdata, inData.Get(i, j, k));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
or, using `IsNeighborInBoundary` methods to skip out-of-bounds loops:
|
||||
|
||||
```
|
||||
struct MyWorklet : public vtkm::worklet::WorkletPointNeighborhood
|
||||
{
|
||||
public:
|
||||
using ControlSignature = void(CellSetIn, FieldInNeighborhood, FieldOut);
|
||||
using ExecutionSignature = void(_2, Boundary, _3);
|
||||
|
||||
template <typename InNeighborhoodT, typename OutDataT>
|
||||
VTKM_EXEC void operator()(const InNeighborhoodT& inData,
|
||||
const vtkm::exec::BoundaryState &boundary,
|
||||
OutDataT& outData) const
|
||||
{
|
||||
for (vtkm::IdComponent k = -10; k <= 10; ++k)
|
||||
{
|
||||
if (!boundary.IsNeighborInZBoundary(k))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (vtkm::IdComponent j = -10; j <= 10; ++j)
|
||||
{
|
||||
if (!boundary.IsNeighborInYBoundary(j))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (vtkm::IdComponent i = -10; i <= 10; ++i)
|
||||
{
|
||||
if (!boundary.IsNeighborInXBoundary(i))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
outData = doSomeConvolution(i, j, k, outdata, inData.Get(i, j, k));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
The latter is useful for implementing a convolution that substitutes a constant
|
||||
value for out-of-bounds indices:
|
||||
|
||||
```
|
||||
struct MyWorklet : public vtkm::worklet::WorkletPointNeighborhood
|
||||
{
|
||||
public:
|
||||
using ControlSignature = void(CellSetIn, FieldInNeighborhood, FieldOut);
|
||||
using ExecutionSignature = void(_2, Boundary, _3);
|
||||
|
||||
template <typename InNeighborhoodT, typename OutDataT>
|
||||
VTKM_EXEC void operator()(const InNeighborhoodT& inData,
|
||||
const vtkm::exec::BoundaryState &boundary,
|
||||
OutDataT& outData) const
|
||||
{
|
||||
for (vtkm::IdComponent k = -10; k <= 10; ++k)
|
||||
{
|
||||
for (vtkm::IdComponent j = -10; j <= 10; ++j)
|
||||
{
|
||||
for (vtkm::IdComponent i = -10; i <= 10; ++i)
|
||||
{
|
||||
if (boundary.IsNeighborInBoundary({i, j, k}))
|
||||
{
|
||||
outData = doSomeConvolution(i, j, k, outdata, inData.Get(i, j, k));
|
||||
}
|
||||
else
|
||||
{ // substitute zero for out-of-bounds samples:
|
||||
outData = doSomeConvolution(i, j, k, outdata, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
@ -1,47 +0,0 @@
|
||||
# Add ability to get an array from a Field for a particular type
|
||||
|
||||
Previously, whenever you got an array from a `Field` object from a call to
|
||||
an `ApplyPolicy`, you would get back a `VariantArrayHandle` that allows you
|
||||
to cast to multiple types. To use that, you then have to cast it to
|
||||
multiple different types and multiple different storage.
|
||||
|
||||
Often, this is what you want. If you are operating on a field, then you
|
||||
want to cast to the native type. But there are also cases where you know a
|
||||
specific type you want. For example, if you are operating on two fields, it
|
||||
makes sense to find the exact type for the first field and then cast the
|
||||
second field to that type if necessary rather than pointlessly unroll
|
||||
templates for the cross of every possible combination. Also, we are not
|
||||
unrolling for different storage types or attempting to create a virtual
|
||||
array. Instead, we are using an `ArrayHandleMultiplexer` so that you only
|
||||
have to compile for this array once.
|
||||
|
||||
This is done through a new version of `ApplyPolicy`. This version takes a
|
||||
type of the array as its first template argument, which must be specified.
|
||||
|
||||
This requires having a list of potential storage to try. It will use that
|
||||
to construct an `ArrayHandleMultiplexer` containing all potential types.
|
||||
This list of storages comes from the policy. A `StorageList` item was added
|
||||
to the policy. It is also sometimes necessary for a filter to provide its
|
||||
own special storage types. Thus, an `AdditionalFieldStorage` type was added
|
||||
to `Filter` which is set to a `ListTag` of storage types that should be
|
||||
added to those specified by the policy.
|
||||
|
||||
Types are automatically converted. So if you ask for a `vtkm::Float64` and
|
||||
field contains a `vtkm::Float32`, it will the array wrapped in an
|
||||
`ArrayHandleCast` to give the expected type.
|
||||
|
||||
Here is an example where you are doing an operation on a field and
|
||||
coordinate system. The superclass finds the correct type of the field. Your
|
||||
result is just going to follow the type of the field.
|
||||
|
||||
``` cpp
|
||||
template <typename T, typename StorageType, typename DerivedPolicy>
|
||||
inline VTKM_CONT vtkm::cont::DataSet MyFilter::DoExecute(
|
||||
const vtkm::cont::DataSet& inDataSet,
|
||||
const vtkm::cont::ArrayHandle<T, StorageType>& field,
|
||||
const vtkm::filter::FieldMetadata& fieldMetadata,
|
||||
vtkm::filter::PolicyBase<DerivedPolicy> policy)
|
||||
{
|
||||
vtkm::cont::CoordinateSystem coords = inDataSet.GetCoordianteSystem();
|
||||
auto coordsArray = vtkm::filter::ApplyPolicy<T>(coords, policy, *this);
|
||||
```
|
@ -1,42 +0,0 @@
|
||||
# Add ArrayGetValues to retrieve a subset of ArrayHandle values from a device.
|
||||
|
||||
An algorithm will often want to pull just a single value (or small subset of
|
||||
values) back from a device to check the results of a computation. Previously,
|
||||
there was no easy way to do this, and algorithm developers would often
|
||||
transfer vast quantities of data back to the host just to check a single value.
|
||||
|
||||
The new `vtkm::cont::ArrayGetValue` and `vtkm::cont::ArrayGetValues` functions
|
||||
simplify this operations and provide a method to just retrieve a portion of an
|
||||
array.
|
||||
|
||||
This utility provides several convenient overloads:
|
||||
|
||||
A single id may be passed into ArrayGetValue, or multiple ids may be specified
|
||||
to ArrayGetValues as an ArrayHandle<vtkm::Id>, a std::vector<vtkm::Id>, a
|
||||
c-array (pointer and size), or as a brace-enclosed initializer list.
|
||||
|
||||
The single result from ArrayGetValue may be returned or written to an output
|
||||
argument. Multiple results from ArrayGetValues may be returned as an
|
||||
std::vector<T>, or written to an output argument as an ArrayHandle<T> or a
|
||||
std::vector<T>.
|
||||
|
||||
Examples:
|
||||
|
||||
```
|
||||
vtkm::cont::ArrayHandle<T> data = ...;
|
||||
|
||||
// Fetch the first value in an array handle:
|
||||
T firstVal = vtkm::cont::ArrayGetValue(0, data);
|
||||
|
||||
// Fetch the first and third values in an array handle:
|
||||
std::vector<T> firstAndThird = vtkm::cont::ArrayGetValues({0, 2}, data);
|
||||
|
||||
// Fetch the first and last values in an array handle:
|
||||
std::vector<T> firstAndLast =
|
||||
vtkm::cont::ArrayGetValues({0, data.GetNumberOfValues() - 1}, data);
|
||||
|
||||
// Fetch the first 4 values into an array handle:
|
||||
const std::vector<vtkm::Id> ids{0, 1, 2, 3};
|
||||
vtkm::cont::ArrayHandle<T> firstFour;
|
||||
vtkm::cont::ArrayGetValues(ids, data, firstFour);
|
||||
```
|
@ -1,244 +0,0 @@
|
||||
# Add `ArrayHandleDecorator`.
|
||||
|
||||
`ArrayHandleDecorator` is given a `DecoratorImpl` class and a list of one or
|
||||
more source `ArrayHandle`s. There are no restrictions on the size or type of
|
||||
the source `ArrayHandle`s.
|
||||
|
||||
|
||||
The decorator implementation class is described below:
|
||||
|
||||
```
|
||||
struct ExampleDecoratorImplementation
|
||||
{
|
||||
|
||||
// Takes one portal for each source array handle (only two shown).
|
||||
// Returns a functor that defines:
|
||||
//
|
||||
// ValueType operator()(vtkm::Id id) const;
|
||||
//
|
||||
// which takes an index and returns a value which should be produced by
|
||||
// the source arrays somehow. This ValueType will be the ValueType of the
|
||||
// ArrayHandleDecorator.
|
||||
//
|
||||
// Both SomeFunctor::operator() and CreateFunctor must be const.
|
||||
//
|
||||
template <typename Portal1Type, typename Portal2Type>
|
||||
SomeFunctor CreateFunctor(Portal1Type portal1, Portal2Type portal2) const;
|
||||
|
||||
// Takes one portal for each source array handle (only two shown).
|
||||
// Returns a functor that defines:
|
||||
//
|
||||
// void operator()(vtkm::Id id, ValueType val) const;
|
||||
//
|
||||
// which takes an index and a value, which should be used to modify one
|
||||
// or more of the source arrays.
|
||||
//
|
||||
// CreateInverseFunctor is optional; if not provided, the
|
||||
// ArrayHandleDecorator will be read-only. In addition, if all of the
|
||||
// source ArrayHandles are read-only, the inverse functor will not be used
|
||||
// and the ArrayHandleDecorator will be read only.
|
||||
//
|
||||
// Both SomeInverseFunctor::operator() and CreateInverseFunctor must be
|
||||
// const.
|
||||
//
|
||||
template <typename Portal1Type, typename Portal2Type>
|
||||
SomeInverseFunctor CreateInverseFunctor(Portal1Type portal1,
|
||||
Portal2Type portal2) const;
|
||||
|
||||
};
|
||||
```
|
||||
|
||||
Some example implementation classes are provided below:
|
||||
|
||||
Reverse a ScanExtended:
|
||||
```
|
||||
// Decorator implementation that reverses the ScanExtended operation.
|
||||
//
|
||||
// The resulting ArrayHandleDecorator will take an array produced by the
|
||||
// ScanExtended algorithm and return the original ScanExtended input.
|
||||
//
|
||||
// Some interesting things about this:
|
||||
// - The ArrayHandleDecorator's ValueType will not be the same as the
|
||||
// ScanPortal's ValueType. The Decorator ValueType is determined by the
|
||||
// return type of Functor::operator().
|
||||
// - The ScanPortal has more values than the ArrayHandleDecorator. The
|
||||
// number of values the ArrayHandleDecorator should hold is set during
|
||||
// construction and may differ from the arrays it holds.
|
||||
template <typename ValueType>
|
||||
struct ScanExtendedToNumIndicesDecorImpl
|
||||
{
|
||||
template <typename ScanPortalType>
|
||||
struct Functor
|
||||
{
|
||||
ScanPortalType ScanPortal;
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
ValueType operator()(vtkm::Id idx) const
|
||||
{
|
||||
return static_cast<ValueType>(this->ScanPortal.Get(idx + 1) -
|
||||
this->ScanPortal.Get(idx));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ScanPortalType>
|
||||
Functor<ScanPortalType> CreateFunctor(ScanPortalType portal) const
|
||||
{
|
||||
return {portal};
|
||||
}
|
||||
};
|
||||
|
||||
auto numIndicesOrig = vtkm::cont::make_ArrayHandleCounting(ValueType{0},
|
||||
ValueType{1},
|
||||
ARRAY_SIZE);
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> scan;
|
||||
vtkm::cont::Algorithm::ScanExtended(
|
||||
vtkm::cont::make_ArrayHandleCast<vtkm::Id>(numIndicesOrig),
|
||||
scan);
|
||||
auto numIndicesDecor = vtkm::cont::make_ArrayHandleDecorator(
|
||||
ARRAY_SIZE,
|
||||
ScanExtendedToNumIndicesDecorImpl<ValueType>{},
|
||||
scan);
|
||||
```
|
||||
|
||||
Combine two other `ArrayHandle`s using an arbitrary binary operation:
|
||||
```
|
||||
// Decorator implementation that demonstrates how to create functors that
|
||||
// hold custom state. Here, the functors have a customizable Operation
|
||||
// member.
|
||||
//
|
||||
// This implementation is used to create a read-only ArrayHandleDecorator
|
||||
// that combines the values in two other ArrayHandles using an arbitrary
|
||||
// binary operation (e.g. vtkm::Maximum, vtkm::Add, etc).
|
||||
template <typename ValueType, typename OperationType>
|
||||
struct BinaryOperationDecorImpl
|
||||
{
|
||||
OperationType Operation;
|
||||
|
||||
// The functor use to read values. Note that it holds extra state in
|
||||
// addition to the portals.
|
||||
template <typename Portal1Type, typename Portal2Type>
|
||||
struct Functor
|
||||
{
|
||||
Portal1Type Portal1;
|
||||
Portal2Type Portal2;
|
||||
OperationType Operation;
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
ValueType operator()(vtkm::Id idx) const
|
||||
{
|
||||
return this->Operation(static_cast<ValueType>(this->Portal1.Get(idx)),
|
||||
static_cast<ValueType>(this->Portal2.Get(idx)));
|
||||
}
|
||||
};
|
||||
|
||||
// A non-variadic example of a factory function to produce a functor. This
|
||||
// is where the extra state is passed into the functor.
|
||||
template <typename P1T, typename P2T>
|
||||
Functor<P1T, P2T> CreateFunctor(P1T p1, P2T p2) const
|
||||
{
|
||||
return {p1, p2, this->Operation};
|
||||
}
|
||||
};
|
||||
|
||||
BinaryOperationDecorImpl<ValueType, vtkm::Maximum> factory{vtkm::Maximum{}};
|
||||
auto decorArray = vtkm::cont::make_ArrayHandleDecorator(ARRAY_SIZE,
|
||||
factory,
|
||||
array1,
|
||||
array2);
|
||||
```
|
||||
|
||||
A factory that does a complex and invertible operation on three portals:
|
||||
|
||||
```
|
||||
// Decorator implemenation that demonstrates how to write invertible functors
|
||||
// that combine three array handles with complex access logic. The resulting
|
||||
// ArrayHandleDecorator can be both read from and written to.
|
||||
//
|
||||
// Constructs functors that take three portals.
|
||||
//
|
||||
// The first portal's values are accessed in reverse order.
|
||||
// The second portal's values are accessed in normal order.
|
||||
// The third portal's values are accessed via ((idx + 3) % size).
|
||||
//
|
||||
// Functor will return the max of the first two added to the third.
|
||||
//
|
||||
// InverseFunctor will update the third portal such that the Functor would
|
||||
// return the indicated value.
|
||||
struct InvertibleDecorImpl
|
||||
{
|
||||
|
||||
// The functor used for reading data from the three portals.
|
||||
template <typename Portal1Type, typename Portal2Type, typename Portal3Type>
|
||||
struct Functor
|
||||
{
|
||||
using ValueType = typename Portal1Type::ValueType;
|
||||
|
||||
Portal1Type Portal1;
|
||||
Portal2Type Portal2;
|
||||
Portal3Type Portal3;
|
||||
|
||||
VTKM_EXEC_CONT ValueType operator()(vtkm::Id idx) const
|
||||
{
|
||||
const auto idx1 = this->Portal1.GetNumberOfValues() - idx - 1;
|
||||
const auto idx2 = idx;
|
||||
const auto idx3 = (idx + 3) % this->Portal3.GetNumberOfValues();
|
||||
|
||||
const auto v1 = this->Portal1.Get(idx1);
|
||||
const auto v2 = this->Portal2.Get(idx2);
|
||||
const auto v3 = this->Portal3.Get(idx3);
|
||||
|
||||
return vtkm::Max(v1, v2) + v3;
|
||||
}
|
||||
};
|
||||
|
||||
// The functor used for writing. Only Portal3 is written to, the other
|
||||
// portals may be read-only.
|
||||
template <typename Portal1Type, typename Portal2Type, typename Portal3Type>
|
||||
struct InverseFunctor
|
||||
{
|
||||
using ValueType = typename Portal1Type::ValueType;
|
||||
|
||||
Portal1Type Portal1;
|
||||
Portal2Type Portal2;
|
||||
Portal3Type Portal3;
|
||||
|
||||
VTKM_EXEC_CONT void operator()(vtkm::Id idx, const ValueType &vIn) const
|
||||
{
|
||||
const auto v1 = this->Portal1.Get(this->Portal1.GetNumberOfValues() - idx - 1);
|
||||
const auto v2 = this->Portal2.Get(idx);
|
||||
const auto vNew = static_cast<ValueType>(vIn - vtkm::Max(v1, v2));
|
||||
this->Portal3.Set((idx + 3) % this->Portal3.GetNumberOfValues(), vNew);
|
||||
}
|
||||
};
|
||||
|
||||
// Factory function that takes 3 portals as input and creates an instance
|
||||
// of Functor with them. Variadic template parameters are used here, but are
|
||||
// not necessary.
|
||||
template <typename... PortalTs>
|
||||
Functor<typename std::decay<PortalTs>::type...>
|
||||
CreateFunctor(PortalTs&&... portals) const
|
||||
{
|
||||
VTKM_STATIC_ASSERT(sizeof...(PortalTs) == 3);
|
||||
return {std::forward<PortalTs>(portals)...};
|
||||
}
|
||||
|
||||
// Factory function that takes 3 portals as input and creates an instance
|
||||
// of InverseFunctor with them. Variadic template parameters are used here,
|
||||
// but are not necessary.
|
||||
template <typename... PortalTs>
|
||||
InverseFunctor<typename std::decay<PortalTs>::type...>
|
||||
CreateInverseFunctor(PortalTs&&... portals) const
|
||||
{
|
||||
VTKM_STATIC_ASSERT(sizeof...(PortalTs) == 3);
|
||||
return {std::forward<PortalTs>(portals)...};
|
||||
}
|
||||
};
|
||||
|
||||
// Note that only ah3 must be writable for ahInv to be writable. ah1 and ah2
|
||||
// may be read-only arrays.
|
||||
auto ahInv = vtkm::cont::make_ArrayHandleDecorator(ARRAY_SIZE,
|
||||
InvertibleDecorImpl{},
|
||||
ah1,
|
||||
ah2,
|
||||
ah3);
|
||||
```
|
@ -1,183 +0,0 @@
|
||||
# Add ArrayHandleMultiplexer
|
||||
|
||||
`vtkm::cont::ArrayHandleMultiplexer` is a fancy `ArrayHandle` that can
|
||||
mimic being any one of a list of other `ArrayHandle`s. When declared, a set
|
||||
of a list of `ArrayHandle`s is given to `ArrayHandleMultiplexer`. To use
|
||||
the `ArrayHandleMultiplexer` it is set to an instance of one of these other
|
||||
`ArrayHandle`s. Thus, once you compile code to use an
|
||||
`ArrayHandleMultiplexer`, you can at runtime select any of the types it
|
||||
supports.
|
||||
|
||||
The intention is convert the data from a `vtkm::cont::VariantArrayHandle`
|
||||
to a `vtkm::cont::ArrayHandleMultiplexer` of some known types. The
|
||||
`ArrayHandleMultiplexer` can be compiled statically (that is, no virtual
|
||||
methods are needed). Although the compiler must implement all possible
|
||||
implementations of the multiplexer, two or more `ArrayHandleMultiplexer`s
|
||||
can be used together without having to compile every possible combination
|
||||
of all of them.
|
||||
|
||||
## Motivation
|
||||
|
||||
`ArrayHandle` is a very flexible templated class that allows us to use the
|
||||
compiler to adapt our code to pretty much any type of memory layout or
|
||||
on-line processing. Unfortunately, the template approach requires the code
|
||||
to know the exact type during compile time.
|
||||
|
||||
That is a problem when retrieving data from a
|
||||
`vtkm::cont::VariantArrayHandle`, which is the case, for example, when
|
||||
getting data from a `vtkm::cont::DataSet`. The actual type of the array
|
||||
stored in a `vtkm::cont::VariantArrayHandle` is generally not known at
|
||||
compile time at the code location where the data is pulled.
|
||||
|
||||
Our first approach to this problem was to use metatemplate programming to
|
||||
iterate over all possible types in the `VariantArrayHandle`. Although this
|
||||
works, it means that if two or more `VariantArrayHandle`s are dispatched in
|
||||
a function call, the compiler needs to generate all possible combinations
|
||||
of the two. This causes long compile times and large executable sizes. It
|
||||
has lead us to limit the number of types we support, which causes problems
|
||||
with unsupported arrays.
|
||||
|
||||
Our second approach to this problem was to create `ArrayHandleVirtual` to
|
||||
hide the array type behind a virtual method. This works very well, but is
|
||||
causing us significant problems on accelerators. Although virtual methods
|
||||
are supported by CUDA, there are numerous problems that can come up with
|
||||
the compiled code (such as unknown stack depths or virtual methods
|
||||
extending across libraries). It is also unknown what problems we will
|
||||
encounter with other accelerator architectures.
|
||||
|
||||
`ArrayHandleMultiplexer` is meant to be a compromise between these two
|
||||
approaches. Although we are still using metatemplate programming tricks to
|
||||
iterate over multiple implementations, this compiler looping is localized
|
||||
to the code to lookup values in the array. This, it is a small amount of
|
||||
code that needs to be created for each version supported by the
|
||||
`ArrayHandle`. Also, the code paths can be created independently for each
|
||||
`ArrayHandleMultiplexer`. Thus, you do not get into the problem of a
|
||||
combinatorial explosion of types that need to be addressed.
|
||||
|
||||
Although `ArrayHandleMultiplexer` still has the problem of being unable to
|
||||
store a type that is not explicitly listed, the localized expression should
|
||||
allow us to support many types. By default, we are adding lots of
|
||||
`ArrayHandleCast`s to the list of supported types. The intention of this is
|
||||
to allow a filter to specify a value type it operates on and then cast
|
||||
everything to that type. This further allows us to reduce combination of
|
||||
types that we have to support.
|
||||
|
||||
## Use
|
||||
|
||||
The `ArrayHandleMultiplexer` templated class takes a variable number of
|
||||
template parameters. All the template parameters are expected to be types
|
||||
of `ArrayHandle`s that the `ArrayHandleMultiplexer` can assume.
|
||||
|
||||
For example, let's say we have a use case where we need an array of
|
||||
indices. Normally, the indices are sequential (0, 1, 2,...), but sometimes
|
||||
we need to define a custom set of indices. When the indices are sequential,
|
||||
then an `ArrayHandleIndex` is the best representation. Normally if you also
|
||||
need to support general arrays you would first have to deep copy the
|
||||
indices into a physical array. However, with an `ArrayHandleMultiplexer`
|
||||
you can support both.
|
||||
|
||||
``` cpp
|
||||
vtkm::cont::ArrayHandleMultiplexer<vtkm::cont::ArrayHandleIndex,
|
||||
vtkm::cont::ArrayHandle<vtkm::Id>> indices;
|
||||
indices = vtkm::cont::ArrayHandleIndex(ARRAY_SIZE);
|
||||
```
|
||||
|
||||
`indices` can now be used like any other `ArrayHandle`, but for now is
|
||||
behaving like an `ArrayHandleIndex`. That is, it takes (almost) no actual
|
||||
space. But if you need to use explicit indices, you can set the `indices`
|
||||
array to an actual array of indices
|
||||
|
||||
``` cpp
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> indicesInMemory;
|
||||
// Fill indicesInMemory...
|
||||
|
||||
indices = indicesInMemory;
|
||||
```
|
||||
|
||||
All the code that uses `indices` will continue to work.
|
||||
|
||||
## Variant
|
||||
|
||||
To implement `ArrayHandleMultiplexer`, the class `vtkm::internal::Variant`
|
||||
was introduced. Although this is an internal class that is not exposed
|
||||
through the array handle, it is worth documenting its addition as it will
|
||||
be useful to implement other multiplexing type of objects (such as for
|
||||
cell sets and locators).
|
||||
|
||||
`vtkm::internal::Variant` is a simplified version of C++17's `std::variant`
|
||||
or boost's `variant`. One of the significant differences between VTK-m's
|
||||
`Variant` and these other versions is that VTK-m's version does not throw
|
||||
exceptions on error. Instead, behavior becomes undefined. This is
|
||||
intentional as not all platforms support exceptions and there could be
|
||||
consequences on just the possibility for those that do.
|
||||
|
||||
Like the aforementioned classes that `vtkm::internal::Variant` is based on,
|
||||
it behaves much like a `union` of a set of types. Those types are listed as
|
||||
the `Variant`'s template parameters. The `Variant` can be set to any one of
|
||||
these types either through construction or assignment. You can also use the
|
||||
`Emplace` method to construct the object in a `Variant`.
|
||||
|
||||
``` cpp
|
||||
vtkm::internal::Variant<int, float, std::string> variant(5);
|
||||
// variant is now an int.
|
||||
|
||||
variant = 5.0f;
|
||||
// variant is now a float.
|
||||
|
||||
variant.Emplace<std::string>("Hello world");
|
||||
// variant is now an std::string.
|
||||
```
|
||||
|
||||
The `Variant` maintains the index of which type it is holding. It has
|
||||
several helpful items to manage the type and index of contained objects:
|
||||
|
||||
* `GetIndex()`: A method to retrieve the template parameter index of the
|
||||
type currently held. In the previous example, the index starts at 0,
|
||||
becomes 1, then becomes 2.
|
||||
* `GetIndexOf<T>()`: A static method that returns a `constexpr` of the
|
||||
index of a given type. In the previous example,
|
||||
`variant.GetIndexOf<float>()` would return 1.
|
||||
* `Get<T or I>()`: Given a type, returns the contained object as that
|
||||
type. Given a number, returns the contained object as a type of the
|
||||
corresponding index. In the previous example, either `variant.Get<1>()`
|
||||
or `variant.Get<float>()` would return the `float` value. The behavior
|
||||
is undefined if the object is not the requested type.
|
||||
* `IsValid()`: A method that can be used to determine whether the
|
||||
`Variant` holds an object that can be operated on.
|
||||
* `Reset()`: A method to remove any contained object and restore to an
|
||||
invalid state.
|
||||
|
||||
Finally, `Variant` contains a `CastAndCall` method. This method takes a
|
||||
functor followed by a list of optional arguments. The contained object is
|
||||
cast to the appropriate type and the functor is called with the cast object
|
||||
followed by the provided arguments. If the functor returns a value, that
|
||||
value is returned by `CastAndCall`.
|
||||
|
||||
`CastAndCall` is an important functionality that makes it easy to wrap
|
||||
multiplexer objects around a `Variant`. For example, here is how you could
|
||||
implement executing the `Value` method in an implicit function multiplexer.
|
||||
|
||||
``` cpp
|
||||
class ImplicitFunctionMultiplexer
|
||||
{
|
||||
vtkm::internal::Variant<Box, Plane, Sphere> ImplicitFunctionVariant;
|
||||
|
||||
// ...
|
||||
|
||||
struct ValueFunctor
|
||||
{
|
||||
template <typename ImplicitFunctionType>
|
||||
vtkm::FloatDefault operator()(const ImplicitFunctionType& implicitFunction,
|
||||
const vtkm::Vec<vtkm::FloatDefault, 3>& point)
|
||||
{
|
||||
return implicitFunction.Value(point);
|
||||
}
|
||||
};
|
||||
|
||||
vtkm::FloatDefault Value(const vtkm::Vec<vtkm::FloatDefault, 3>& point) const
|
||||
{
|
||||
return this->ImplicitFunctionVariant.CastAndCall(ValueFunctor{}, point);
|
||||
}
|
||||
|
||||
```
|
||||
|
@ -1,61 +0,0 @@
|
||||
# Added ArrayHandleSOA
|
||||
|
||||
`ArrayHandleSOA` behaves like a regular `ArrayHandle` (with a basic
|
||||
storage) except that if you specify a `ValueType` of a `Vec` or a
|
||||
`Vec`-like, it will actually store each component in a separate physical
|
||||
array. When data are retrieved from the array, they are reconstructed into
|
||||
`Vec` objects as expected.
|
||||
|
||||
The intention of this array type is to help cover the most common ways data
|
||||
is lain out in memory. Typically, arrays of data are either an "array of
|
||||
structures" like the basic storage where you have a single array of
|
||||
structures (like `Vec`) or a "structure of arrays" where you have an array
|
||||
of a basic type (like `float`) for each component of the data being
|
||||
represented. The `ArrayHandleSOA` makes it easy to cover this second case
|
||||
without creating special types.
|
||||
|
||||
`ArrayHandleSOA` can be constructed from a collection of `ArrayHandle` with
|
||||
basic storage. This allows you to construct `Vec` arrays from components
|
||||
without deep copies.
|
||||
|
||||
``` cpp
|
||||
std::vector<vtkm::Float32> accel0;
|
||||
std::vector<vtkm::Float32> accel1;
|
||||
std::vector<vtkm::Float32> accel2;
|
||||
|
||||
// Let's say accel arrays are set to some field of acceleration vectors by
|
||||
// some other software.
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32> accelHandle0 = vtkm::cont::make_ArrayHandle(accel0);
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32> accelHandle1 = vtkm::cont::make_ArrayHandle(accel1);
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32> accelHandle2 = vtkm::cont::make_ArrayHandle(accel2);
|
||||
|
||||
vtkm::cont::ArrayHandleSOA<vtkm::Vec3f_32> accel = { accelHandle0, accelHandle1, accelHandle2 };
|
||||
```
|
||||
|
||||
Also provided are constructors and versions of `make_ArrayHandleSOA` that
|
||||
take `std::vector` or C arrays as either initializer lists or variable
|
||||
arguments.
|
||||
|
||||
``` cpp
|
||||
std::vector<vtkm::Float32> accel0;
|
||||
std::vector<vtkm::Float32> accel1;
|
||||
std::vector<vtkm::Float32> accel2;
|
||||
|
||||
// Let's say accel arrays are set to some field of acceleration vectors by
|
||||
// some other software.
|
||||
|
||||
vtkm::cont::ArrayHandleSOA<vtkm::Vec3f_32> accel = { accel0, accel1, accel2 };
|
||||
```
|
||||
|
||||
However, setting arrays is a little awkward because you also have to
|
||||
specify the length. This is done either outside the initializer list or as
|
||||
the first argument.
|
||||
|
||||
``` cpp
|
||||
vtkm::cont::make_ArrayHandleSOA({ array0, array1, array2 }, ARRAY_SIZE);
|
||||
```
|
||||
|
||||
``` cpp
|
||||
vtkm::cont::make_ArrayHandleSOA(ARRAY_SIZE, array0, array1, array2);
|
||||
```
|
@ -1,15 +0,0 @@
|
||||
# Updating structured cell locators
|
||||
|
||||
VTK-m will mow allow locating containing cells for a point using `CellLocatorUniformGrid`
|
||||
and `CellLocatorRectilinearGrid` for 2D grids.
|
||||
|
||||
Users are required to create the locator objects as they normally would.
|
||||
However, the `FindCell` method in `vtkm::exec::CellLocator` still requires users
|
||||
to pass a 3D point as an input.
|
||||
|
||||
Further, the structured grid locators no longer use the `vtkm::exec::WorldToParametricCoordinates`
|
||||
method to return parametric coordinates, instead they use fast paths for locating
|
||||
points in a cell of an axis-aligned grid.
|
||||
|
||||
Another change for the `CellLocatorRectilinearGrid` is that now it uses binary search
|
||||
on individual component arrays to search for a point.
|
@ -1,8 +0,0 @@
|
||||
# CellSets now don't have a name
|
||||
|
||||
The requirement that `vtkm::cont::CellSets` have a name was so
|
||||
cell based `vtkm::cont::Field`'s could be associated with the
|
||||
correct CellSet in a `vtkm::cont::DataSet`.
|
||||
|
||||
Now that `DataSet`'s don't support multiple CellSets, we can remove
|
||||
the `CellSet` name member variable.
|
@ -1,11 +0,0 @@
|
||||
# DataSet queries for CoordinateSystem Indices don't throw
|
||||
|
||||
Asking for the index of a `vtkm::cont::CoordinateSystem` by
|
||||
name now returns a `-1` when no matching item has been found instead of throwing
|
||||
an exception.
|
||||
|
||||
This was done to make the interface of `vtkm::cont::DataSet` to follow the guideline
|
||||
"Only unrepresentable things should raise exceptions". The index of a non-existent item
|
||||
is representable by `-1` and therefore we shouldn't throw, like wise the methods that return
|
||||
references can still throw exceptions as you can't have a reference to an non-existent item.
|
||||
|
@ -1,29 +0,0 @@
|
||||
# DataSet only has a single vtkm::cont::CellSet
|
||||
|
||||
Multiple `vtkm::cont::CellSets` on a datasets increased the
|
||||
complexity of using VTK-m correctly without any significant
|
||||
benefits.
|
||||
|
||||
It had the effect that `vtkm::cont::Fields` that representing
|
||||
cell fields needed to be associated with a given cellset. This
|
||||
has to be a loose coupling to allow for filters to generate
|
||||
new output cellsets. At the same time it introduced errors when
|
||||
that output had a different name.
|
||||
|
||||
It raised questions about how should filters propagate cell fields.
|
||||
Should a filter drop all cell fields not associated with the active
|
||||
CellSet, or is that too aggressive given the fact that maybe the
|
||||
algorithm just mistakenly named the field, or the IO routine added
|
||||
a field with the wrong cellset name.
|
||||
|
||||
It increased the complexity of filters, as the developer needed to
|
||||
determine if the algorithm should support execution on a single `CellSet` or
|
||||
execution over all `CellSets`.
|
||||
|
||||
Given these issues it was deemed that removing multiple `CellSets` was
|
||||
the correct way forward. People using multiple `CellSets` will need to
|
||||
move over to `vtkm::cont::MultiBlock` which supports shared points and
|
||||
fields between multiple blocks.
|
||||
|
||||
|
||||
|
@ -1,16 +0,0 @@
|
||||
# Added Source class hierarchy
|
||||
|
||||
A new class hierarchy for dataset source was added. The intention is to
|
||||
consolidate and refactor various (procedural) dataset generators for unit
|
||||
tests, especially the multiple copy&past-ed implementations of the Tangle
|
||||
field. As they are compiled into a library rather than as header files,
|
||||
we also expect the overall compile time to decrease.
|
||||
|
||||
The public interface of dataset source is modeled after Filter. A new DataSet
|
||||
is returned by calling the Execute() method of the dataset source, for example:
|
||||
|
||||
```cpp
|
||||
vtkm::Id3 dims(4, 4, 4);
|
||||
vtkm::source::Tangle tangle(dims);
|
||||
vtkm::cont::DataSet dataSet = tangle.Execute();
|
||||
```
|
97
docs/changelog/deprecation.md
Normal file
97
docs/changelog/deprecation.md
Normal file
@ -0,0 +1,97 @@
|
||||
# Add VTKM_DEPRECATED macro
|
||||
|
||||
The `VTKM_DEPRECATED` macro allows us to remove (and usually replace)
|
||||
features from VTK-m in minor releases while still following the conventions
|
||||
of semantic versioning. The idea is that when we want to remove or replace
|
||||
a feature, we first mark the old feature as deprecated. The old feature
|
||||
will continue to work, but compilers that support it will start to issue a
|
||||
warning that the use is deprecated and should stop being used. The
|
||||
deprecated features should remain viable until at least the next major
|
||||
version. At the next major version, deprecated features from the previous
|
||||
version may be removed.
|
||||
|
||||
## Declaring things deprecated
|
||||
|
||||
Classes and methods are marked deprecated using the `VTKM_DEPRECATED`
|
||||
macro. The first argument of `VTKM_DEPRECATED` should be set to the first
|
||||
version in which the feature is deprecated. For example, if the last
|
||||
released version of VTK-m was 1.5, and on the master branch a developer
|
||||
wants to deprecate a class foo, then the `VTKM_DEPRECATED` release version
|
||||
should be given as 1.6, which will be the next minor release of VTK-m. The
|
||||
second argument of `VTKM_DEPRECATED`, which is optional but highly
|
||||
encouraged, is a short message that should clue developers on how to update
|
||||
their code to the new changes. For example, it could point to the
|
||||
replacement class or method for the changed feature.
|
||||
|
||||
`VTKM_DEPRECATED` can be used to deprecate a class by adding it between the
|
||||
`struct` or `class` keyword and the class name.
|
||||
|
||||
``` cpp
|
||||
struct VTKM_DEPRECATED(1.6, "OldClass replaced with NewClass.") OldClass
|
||||
{
|
||||
};
|
||||
```
|
||||
|
||||
Aliases can similarly be depreciated, except the `VTKM_DEPRECATED` macro
|
||||
goes after the name in this case.
|
||||
|
||||
``` cpp
|
||||
using OldAlias VTKM_DEPRECATED(1.6, "Use NewClass instead.") = NewClass;
|
||||
```
|
||||
|
||||
Functions and methods are marked as deprecated by adding `VTKM_DEPRECATED`
|
||||
as a modifier before the return value.
|
||||
|
||||
``` cpp
|
||||
VTKM_EXEC_CONT
|
||||
VTKM_DEPRECATED(1.6, "You must now specify a tolerance.") void ImportantMethod(double x)
|
||||
{
|
||||
this->ImportantMethod(x, 1e-6);
|
||||
}
|
||||
```
|
||||
|
||||
`enum`s can be deprecated like classes using similar syntax.
|
||||
|
||||
``` cpp
|
||||
enum struct VTKM_DEPRECATED(1.7, "Use NewEnum instead.") OldEnum
|
||||
{
|
||||
OLD_VALUE
|
||||
};
|
||||
```
|
||||
|
||||
Individual items in an `enum` can also be marked as deprecated and
|
||||
intermixed with regular items.
|
||||
|
||||
``` cpp
|
||||
enum struct NewEnum
|
||||
{
|
||||
OLD_VALUE1 VTKM_DEPRECATED(1.7, "Use NEW_VALUE instead."),
|
||||
NEW_VALUE,
|
||||
OLD_VALUE2 VTKM_DEPRECATED(1.7) = 42
|
||||
};
|
||||
```
|
||||
|
||||
## Using deprecated items
|
||||
|
||||
Using deprecated items should work, but the compiler will give a warning.
|
||||
That is the point. However, sometimes you need to legitimately use a
|
||||
deprecated item without a warning. This is usually because you are
|
||||
implementing another deprecated item or because you have a test for a
|
||||
deprecated item (that can be easily removed with the deprecated bit). To
|
||||
support this a pair of macros, `VTKM_DEPRECATED_SUPPRESS_BEGIN` and
|
||||
`VTKM_DEPRECATED_SUPPRESS_END` are provided. Code that legitimately uses
|
||||
deprecated items should be wrapped in these macros.
|
||||
|
||||
``` cpp
|
||||
VTKM_EXEC_CONT
|
||||
VTKM_DEPRECATED(1.6, "You must now specify both a value and tolerance.")
|
||||
void ImportantMethod()
|
||||
{
|
||||
// It can be the case that to implement a deprecated method you need to
|
||||
// use other deprecated features. To do that, just temporarily suppress
|
||||
// those warnings.
|
||||
VTKM_DEPRECATED_SUPPRESS_BEGIN
|
||||
this->ImportantMethod(0.0);
|
||||
VTKM_DEPRECATED_SUPPRESS_END
|
||||
}
|
||||
```
|
@ -1,5 +0,0 @@
|
||||
# Fields now don't require the associated CellSet name
|
||||
|
||||
Now that `vtkm::cont::DataSet` can only have a single `vtkm::cont::CellSet`
|
||||
the requirement that cell based `vtkm::cont::Field`s need a CellSet name
|
||||
has been lifted.
|
@ -1,4 +0,0 @@
|
||||
# vtkm::cont::Filter now don't have an active cell set
|
||||
|
||||
`vtkm::filter::FilterField` has removed the concept of `ActiveCellSetIndex`. This
|
||||
has been done as `vtkm::cont::DataSet` now only contains a single `vtkm::cont::CellSet`.
|
@ -1,9 +0,0 @@
|
||||
# FilterField now provides all functionality of FilterCell
|
||||
|
||||
The FilterCell was a subclass of `vtkm::filter::FilterField` and behaves essentially the same
|
||||
but provided the pair of methods `SetActiveCellSetIndex` and `GetActiveCellSetIndex`.
|
||||
It was a common misconception that `FilterCell` was meant for Cell based algorithms, instead of
|
||||
algorithms that required access to the active `vtkm::cont::CellSet`.
|
||||
|
||||
By moving `SetActiveCellSetIndex` and `GetActiveCellSetIndex` to FilterField, we remove this confusion.
|
||||
|
@ -1,19 +0,0 @@
|
||||
# Fix cell derivatives for polygon cell shape
|
||||
|
||||
For polygon cell shapes (that are not triangles or quadrilaterals),
|
||||
interpolations are done by finding the center point and creating a triangle
|
||||
fan around that point. Previously, the gradient was computed in the same
|
||||
way as interpolation: identifying the correct triangle and computing the
|
||||
gradient for that triangle.
|
||||
|
||||
The problem with that approach is that makes the gradient discontinuous at
|
||||
the boundaries of this implicit triangle fan. To make things worse, this
|
||||
discontinuity happens right at each vertex where gradient calculations
|
||||
happen frequently. This means that when you ask for the gradient at the
|
||||
vertex, you might get wildly different answers based on floating point
|
||||
imprecision.
|
||||
|
||||
Get around this problem by creating a small triangle around the point in
|
||||
question, interpolating values to that triangle, and use that for the
|
||||
gradient. This makes for a smoother gradient transition around these
|
||||
internal boundaries.
|
@ -1,43 +0,0 @@
|
||||
# Invoker now a member of all vtkm::filters
|
||||
|
||||
To simplify how vtkm filters are written we have made each vtkm::filter
|
||||
have a `vtkm::cont::Invoker` as member variable. The goal with this change
|
||||
is provide an uniform API for launching all worklets from within a filter.
|
||||
|
||||
Lets consider the PointElevation filter. Previous to these changes the
|
||||
`DoExecute` would need to construct the correct dispatcher with the
|
||||
correct parameters as seen below:
|
||||
|
||||
```cpp
|
||||
template <typename T, typename StorageType, typename DerivedPolicy>
|
||||
inline VTKM_CONT vtkm::cont::DataSet PointElevation::DoExecute(
|
||||
const vtkm::cont::DataSet& inDataSet,
|
||||
const vtkm::cont::ArrayHandle<T, StorageType>& field,
|
||||
const vtkm::filter::FieldMetadata& fieldMetadata,
|
||||
vtkm::filter::PolicyBase<DerivedPolicy>)
|
||||
{
|
||||
vtkm::cont::ArrayHandle<vtkm::Float64> outArray;
|
||||
|
||||
vtkm::worklet::DispatcherMapField<vtkm::worklet::PointElevation> dispatcher(this->Worklet);
|
||||
dispatcher.Invoke(field, outArray);
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
With these changes the filter can instead use `this->Invoke` and have
|
||||
the correct dispatcher executed. This makes it easier to teach and
|
||||
learn how to write new filters.
|
||||
```cpp
|
||||
template <typename T, typename StorageType, typename DerivedPolicy>
|
||||
inline VTKM_CONT vtkm::cont::DataSet PointElevation::DoExecute(
|
||||
const vtkm::cont::DataSet& inDataSet,
|
||||
const vtkm::cont::ArrayHandle<T, StorageType>& field,
|
||||
const vtkm::filter::FieldMetadata& fieldMetadata,
|
||||
vtkm::filter::PolicyBase<DerivedPolicy>)
|
||||
{
|
||||
vtkm::cont::ArrayHandle<vtkm::Float64> outArray;
|
||||
|
||||
this->Invoke(this->Worklet, field, outArray);
|
||||
...
|
||||
}
|
||||
```
|
@ -1,6 +0,0 @@
|
||||
# Invoker moved to vtkm::cont
|
||||
|
||||
Previously, `Invoker` was located in the `vtkm::worklet` namespace to convey
|
||||
it was a replacement for using `vtkm::worklet::Dispatcher*`. In actuality
|
||||
it should be in `vtkm::cont` as it is the proper way to launch worklets
|
||||
for execution, and that shouldn't exist inside the `worklet` namespace.
|
@ -1,13 +0,0 @@
|
||||
# Lagrangian Coherent Strucutres (LCS) Filter for VTK-m
|
||||
|
||||
The new filter `vtkm::filter::LagrangianStructures` is meant for Finite Time
|
||||
Lyapunov Exponent (FTLE) calculation using VTK-m.
|
||||
The filter allows users to calculate FTLE in two ways
|
||||
1. Provide a dataset with a vector field, which will be used to generate a flow
|
||||
map.
|
||||
2. Provide a dataset containing a flow map, which can be readily used for the
|
||||
FTLE field calculation.
|
||||
|
||||
The filter returns a dataset with a point field named FTLE.
|
||||
Is the input is strucutred and an auxiliary grid was not used, the filter will
|
||||
add the field to the original dataset set, else a new structured dataset is returned.
|
29
docs/changelog/list-tag-remove-if.md
Normal file
29
docs/changelog/list-tag-remove-if.md
Normal file
@ -0,0 +1,29 @@
|
||||
# Add `ListTagRemoveIf`
|
||||
|
||||
It is sometimes useful to remove types from `ListTag`s. This is especially
|
||||
the case when combining lists of types together where some of the type
|
||||
combinations may be invalid and should be removed. To handle this
|
||||
situation, a new `ListTag` type is added: `ListTagRemoveIf`.
|
||||
|
||||
`ListTagRemoveIf` is a template structure that takes two arguments. The
|
||||
first argument is another `ListTag` type to operate on. The second argument
|
||||
is a template that acts as a predicate. The predicate takes a type and
|
||||
declares a Boolean `value` that should be `true` if the type should be
|
||||
removed and `false` if the type should remain.
|
||||
|
||||
Here is an example of using `ListTagRemoveIf` to get basic types that hold
|
||||
only integral values.
|
||||
|
||||
``` cpp
|
||||
template <typename T>
|
||||
using IsRealValue =
|
||||
std::is_same<
|
||||
typename vtkm::TypeTraits<typename vtkm::VecTraits<T>::BaseComponentType>::NumericTag,
|
||||
vtkm::TypeTraitsRealTag>;
|
||||
|
||||
using MixedTypes =
|
||||
vtkm::ListTagBase<vtkm::Id, vtkm::FloatDefault, vtkm::Id3, vtkm::Vec3f>;
|
||||
|
||||
using IntegralTypes = vtkm::ListTagRemoveIf<MixedTypes, IsRealValue>;
|
||||
// IntegralTypes now equivalent to vtkm::ListTagBase<vtkm::Id, vtkm::Id3>
|
||||
```
|
@ -1,16 +0,0 @@
|
||||
# `MultiBlock` renamed to `PartitionedDataSet`
|
||||
|
||||
The `MultiBlock` class has been renamed to `PartitionedDataSet`, and its API
|
||||
has been refactored to refer to "partitions", rather than "blocks".
|
||||
Additionally, the `AddBlocks` method has been changed to `AppendPartitions` to
|
||||
more accurately reflect the operation performed. The associated
|
||||
`AssignerMultiBlock` class has also been renamed to
|
||||
`AssignerPartitionedDataSet`.
|
||||
|
||||
This change is motivated towards unifying VTK-m's data model with VTK. VTK has
|
||||
started to move away from `vtkMultiBlockDataSet`, which is a hierarchical tree
|
||||
of nested datasets, to `vtkPartitionedDataSet`, which is always a flat vector
|
||||
of datasets used to assist geometry distribution in multi-process environments.
|
||||
This simplifies traversal during processing and clarifies the intent of the
|
||||
container: The component datasets are partitions for distribution, not
|
||||
organizational groupings (e.g. materials).
|
@ -1,18 +0,0 @@
|
||||
# `SurfaceNormals` filter can now orient normals.
|
||||
|
||||
The `OrientNormals` worklet has been added to the `SurfaceNormals` filter, and
|
||||
is enabled by turning on the `AutoOrientNormals` option. This feature ensures
|
||||
that all normals generated by the filter will point out of the dataset (or
|
||||
inward if the `FlipNormals` option is true). In addition,
|
||||
`SurfaceNormals` now has a `Consistency` option that forces all triangle
|
||||
windings to be consistent with the cell normal direction (the cell points are
|
||||
specified in counter-clockwise order around the normal).
|
||||
|
||||
This functionality is provided by the following new worklets:
|
||||
|
||||
* OrientNormals
|
||||
* RunOrientCellNormals
|
||||
* RunOrientPointNormals
|
||||
* RunOrientPointAndCellNormals
|
||||
* RunFlipNormals
|
||||
* TriangleWinding
|
@ -1,20 +0,0 @@
|
||||
# Updating particle status for advection
|
||||
|
||||
There are now special statuses for Particle, Integrator, and Evaluator.
|
||||
|
||||
The particle advection modules only supported statuses for particles and made it
|
||||
difficult to handle advanced integtator statuses.
|
||||
Now each of the three important modules return their own statuses
|
||||
|
||||
Particles have `vtkm::worklet::particleadvection::ParticleStatus`,
|
||||
Integrators have `vtkm::worklet::particleadvection::IntegratorStatus`, and
|
||||
Evaluators have `vtkm::worklet::particleadvection::EvaluatorStatus`.
|
||||
|
||||
Further, names of the statuses in `vtkm::worklet::particleadvection::ParticleStatus`
|
||||
have changed
|
||||
|
||||
`ParticleStatus::STATUS_OK` is now `ParticleStatus::SUCCESS`, and there is another
|
||||
status `ParticleStatus::TOOK_ANY_STEPS` which is active if the particle has taken
|
||||
at least one step with the current data.
|
||||
|
||||
There are few more changes that allow particle advection in 2D structured grids.
|
@ -1,80 +0,0 @@
|
||||
# CMake vtkm_add_target_information() makes using vtk-m easier
|
||||
|
||||
This higher order function allow build-systems that use VTK-m
|
||||
to use `add_library` or `add_executable` calls but still have an
|
||||
easy to way to get the required information to have VTK-m using
|
||||
compilation units compile correctly.
|
||||
|
||||
```cmake
|
||||
vtkm_add_target_information(
|
||||
target[s]
|
||||
[ DROP_UNUSED_SYMBOLS ]
|
||||
[ MODIFY_CUDA_FLAGS ]
|
||||
[ EXTENDS_VTKM ]
|
||||
[ DEVICE_SOURCES <source_list> ]
|
||||
)
|
||||
```
|
||||
Usage:
|
||||
```cmake
|
||||
add_library(lib_that_uses_vtkm STATIC a.cxx)
|
||||
vtkm_add_target_information(lib_that_uses_vtkm
|
||||
MODIFY_CUDA_FLAGS
|
||||
DEVICE_SOURCES a.cxx
|
||||
)
|
||||
target_link_libraries(lib_that_uses_vtkm PRIVATE vtkm_filter)
|
||||
```
|
||||
|
||||
## Options to vtkm_add_target_information
|
||||
|
||||
- DROP_UNUSED_SYMBOLS: If enabled will apply the appropiate link
|
||||
flags to drop unused VTK-m symbols. This works as VTK-m is compiled with
|
||||
-ffunction-sections which allows for the linker to remove unused functions.
|
||||
If you are building a program that loads runtime plugins that can call
|
||||
VTK-m this most likely shouldn't be used as symbols the plugin expects
|
||||
to exist will be removed.
|
||||
Enabling this will help keep library sizes down when using static builds
|
||||
of VTK-m as only the functions you call will be kept. This can have a
|
||||
dramatic impact on the size of the resulting executable / shared library.
|
||||
- MODIFY_CUDA_FLAGS: If enabled will add the required -arch=<ver> flags
|
||||
that VTK-m was compiled with. If you have multiple libraries that use
|
||||
VTK-m calling `vtkm_add_target_information` multiple times with
|
||||
`MODIFY_CUDA_FLAGS` will cause duplicate compiler flags. To resolve this issue
|
||||
you can; pass all targets and sources to a single `vtkm_add_target_information`
|
||||
call, have the first one use `MODIFY_CUDA_FLAGS`, or use the provided
|
||||
standalone `vtkm_get_cuda_flags` function.
|
||||
|
||||
- DEVICE_SOURCES: The collection of source files that are used by `target(s)` that
|
||||
need to be marked as going to a special compiler for certain device adapters
|
||||
such as CUDA.
|
||||
|
||||
- EXTENDS_VTKM: Some programming models have restrictions on how types can be used,
|
||||
passed across library boundaries, and derived from.
|
||||
For example CUDA doesn't allow device side calls across dynamic library boundaries,
|
||||
and requires all polymorphic classes to be reachable at dynamic library/executable
|
||||
link time.
|
||||
To accommodate these restrictions we need to handle the following allowable
|
||||
use-cases:
|
||||
- Object library: do nothing, zero restrictions
|
||||
- Executable: do nothing, zero restrictions
|
||||
- Static library: do nothing, zero restrictions
|
||||
- Dynamic library:
|
||||
- Wanting to use VTK-m as implementation detail, doesn't expose VTK-m
|
||||
types to consumers. This is supported no matter if CUDA is enabled.
|
||||
- Wanting to extend VTK-m and provide these types to consumers.
|
||||
This is only supported when CUDA isn't enabled. Otherwise we need to ERROR!
|
||||
- Wanting to pass known VTK-m types across library boundaries for others
|
||||
to use in filters/worklets. This is only supported when CUDA isn't enabled. Otherwise we need to ERROR!
|
||||
|
||||
For most consumers they can ignore the `EXTENDS_VTKM` property as the default will be correct.
|
||||
|
||||
The `vtkm_add_target_information` higher order function leverages the `vtkm_add_drop_unused_function_flags` and
|
||||
`vtkm_get_cuda_flags` functions which can be used by VTK-m consuming applications.
|
||||
|
||||
The `vtkm_add_drop_unused_function_flags` function implements all the behavior of `DROP_UNUSED_SYMBOLS` for a single
|
||||
target.
|
||||
|
||||
The `vtkm_get_cuda_flags` function implements a general form of `MODIFY_CUDA_FLAGS` but instead of modiyfing
|
||||
the `CMAKE_CUDA_FLAGS` it will add the flags to any variable passed to it.
|
||||
|
||||
|
||||
|
@ -1,35 +0,0 @@
|
||||
# Refactor topology mappings to clarify meaning.
|
||||
|
||||
The `From` and `To` nomenclature for topology mapping has been confusing for
|
||||
both users and developers, especially at lower levels where the intention of
|
||||
mapping attributes from one element to another is easily conflated with the
|
||||
concept of mapping indices (which maps in the exact opposite direction).
|
||||
|
||||
These identifiers have been renamed to `VisitTopology` and `IncidentTopology`
|
||||
to clarify the direction of the mapping. The order in which these template
|
||||
parameters are specified for `WorkletMapTopology` have also been reversed,
|
||||
since eventually there may be more than one `IncidentTopology`, and having
|
||||
`IncidentTopology` at the end will allow us to replace it with a variadic
|
||||
template parameter pack in the future.
|
||||
|
||||
Other implementation details supporting these worklets, include `Fetch` tags,
|
||||
`Connectivity` classes, and methods on the various `CellSet` classes (such as
|
||||
`PrepareForInput` have also reversed their template arguments. These will need
|
||||
to be cautiously updated.
|
||||
|
||||
The convenience implementations of `WorkletMapTopology` have been renamed for
|
||||
clarity as follows:
|
||||
|
||||
```
|
||||
WorkletMapPointToCell --> WorkletVisitCellsWithPoints
|
||||
WorkletMapCellToPoint --> WorkletVisitPointsWithCells
|
||||
```
|
||||
|
||||
The `ControlSignature` tags have been renamed as follows:
|
||||
|
||||
```
|
||||
FieldInTo --> FieldInVisit
|
||||
FieldInFrom --> FieldInMap
|
||||
FromCount --> IncidentElementCount
|
||||
FromIndices --> IncidentElementIndices
|
||||
```
|
@ -1,10 +0,0 @@
|
||||
# Remove ArrayPortalShrink, behavior subsumed by ArrayHandleView
|
||||
|
||||
ArrayPortalShrink originaly allowed a user to pass in a delegate array portal
|
||||
and then shrink the reported array size without actually modifying the
|
||||
underlying allocation. An iterator was also provided that would
|
||||
correctly iterate over the shrunken size of the stored array.
|
||||
|
||||
Instead of directly shrinking the original array, it is prefered
|
||||
to create an ArrayHandleView from an ArrayHandle and then specify the
|
||||
number of values to use in the ArrayHandleView constructor.
|
@ -1,29 +0,0 @@
|
||||
# A `ScanExtended` device algorithm has been added.
|
||||
|
||||
This new scan algorithm produces an array that contains both an inclusive scan
|
||||
and an exclusive scan in the same array:
|
||||
|
||||
```
|
||||
#include <vtkm/cont/Algorithm.h>
|
||||
#include <vtkm/cont/ArrayGetValue.h>
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
#include <vtkm/cont/ArrayHandleView.h>
|
||||
|
||||
vtkm::cont::ArrayHandle<T> inputData = ...;
|
||||
const vtkm::Id size = inputData.GetNumberOfValues();
|
||||
|
||||
vtkm::cont::ArrayHandle<T> extendedScan;
|
||||
vtkm::cont::Algorithm::ScanExtended(inputData, extendedScan);
|
||||
|
||||
// The exclusive scan is the first `inputSize` values starting at index 0:
|
||||
auto exclusiveScan = vtkm::cont::make_ArrayHandleView(extendedScan, 0, size);
|
||||
|
||||
// The inclusive scan is the first `inputSize` values starting at index 1:
|
||||
auto inclusiveScan = vtkm::cont::make_ArrayHandleView(extendedScan, 1, size);
|
||||
|
||||
// The total sum of the input data is the last value in the extended scan.
|
||||
const T totalSum = vtkm::cont::ArrayGetValue(size, extendedScan);
|
||||
```
|
||||
|
||||
This can also be thought of as an exclusive scan that appends the total sum,
|
||||
rather than returning it.
|
@ -1,21 +0,0 @@
|
||||
# Simplify creating Fields from ArrayHandles
|
||||
|
||||
VTK-m now offers `make_FieldPoint` and `make_FieldCell` functions
|
||||
that reduce the complexity of construction `vtkm::cont::Fields`
|
||||
from `vtkm::cont::ArrayHandles`.
|
||||
|
||||
Previously to construct a point and cell fields you would do:
|
||||
```cpp
|
||||
vtkm::cont::ArrayHandle<int> pointHandle;
|
||||
vtkm::cont::ArrayHandle<int> cellHandle;
|
||||
vtkm::cont::Field pointField("p", vtkm::cont::Field::Association::POINTS, pointHandle);
|
||||
vtkm::cont::Field cellField("c", vtkm::cont::Field::Association::CELL_SET, "cells", cellHandle);
|
||||
```
|
||||
|
||||
Now with the new `make_` functions you can do:
|
||||
```cpp
|
||||
vtkm::cont::ArrayHandle<int> pointHandle;
|
||||
vtkm::cont::ArrayHandle<int> cellHandle;
|
||||
auto pointField = vtkm::cont::make_FieldPoint("p", pointHandle);
|
||||
auto cellField = vtkm::cont::make_FieldCell("c", "cells", cellHandle);
|
||||
```
|
@ -1,27 +0,0 @@
|
||||
# Simplify creating results for Filters
|
||||
|
||||
As part of the process of making VTK-m filters easier to write for newcomers
|
||||
whe have a couple of changes to make constructing the output `vtkm::cont::DataSet`
|
||||
easier.
|
||||
|
||||
First we have moved the `CreateResult` functions out of the internals namespace
|
||||
and directly into `vtkm::filter`. This makes it clearer to developers that this
|
||||
was the 'proper' way to construct the output DataSet.
|
||||
|
||||
Second we have streamlined the collection of `vtkm::filter::CreateResult` methods to
|
||||
require the user to provide less information and provide clearer names explaing what
|
||||
they do.
|
||||
|
||||
To construct output identical to the input but with a new field you now just pass
|
||||
the `vtkm::filter::FieldMetadata` as a paramter instead of explictly stating
|
||||
the field association, and the possible cell set name:
|
||||
```cpp
|
||||
return CreateResult(input, newField, name, fieldMetadata);
|
||||
```
|
||||
|
||||
To construct output identical to the input but with a cell field added you
|
||||
can now pass the `vtkm::cont::CellSet` as a paramter instead of explictly stating
|
||||
the field association, and the cell set name:
|
||||
```cpp
|
||||
return CreateResultFieldCell(input, newCellField, name, cellset);
|
||||
```
|
@ -1,7 +0,0 @@
|
||||
# Simplify examples
|
||||
|
||||
Lots of the examples were out of date or way too verbose. The examples have
|
||||
been simplified and brought up to modern VTK-m conventions.
|
||||
|
||||
We have also added a "hello worklet" example to be a minimal example of
|
||||
creating a working algorithm (wrapped in a filter) in VTK-m (and used).
|
@ -1,31 +0,0 @@
|
||||
# Provide a simplified way to state allowed value types for VTK-m filters
|
||||
|
||||
Previously VTK-m filters used a specialization of `vtkm::filter::FilterTraits<>` to control
|
||||
the acceptable input value types. For example if the `WarpVector` filter want to only allow
|
||||
`vtkm::Vec3f_32` and `vtkm::Vec3f_64` it would use:
|
||||
|
||||
```cpp
|
||||
namespace vtkm { namespace filter {
|
||||
template <>
|
||||
class FilterTraits<WarpVector>
|
||||
{
|
||||
public:
|
||||
// WarpVector can only applies to Float and Double Vec3 arrays
|
||||
using InputFieldTypeList = vtkm::TypeListTagFieldVec3;
|
||||
};
|
||||
}}
|
||||
```
|
||||
|
||||
This increase the complexity of writing filters. To make this easier VTK-m now looks for
|
||||
a `SupportedTypes` define on the filter when a `vtkm::filter::FilterTraits` specialization
|
||||
doesn't exist. This allows filters to succinctly specify supported types, such as seen below
|
||||
for the `WarpVector` filter.
|
||||
|
||||
```cpp
|
||||
class WarpVector : public vtkm::filter::FilterField<WarpVector>
|
||||
{
|
||||
public:
|
||||
using SupportedTypes = vtkm::TypeListTagFieldVec3;
|
||||
...
|
||||
};
|
||||
```
|
@ -1,21 +0,0 @@
|
||||
# Copy Threshold output to a CellSetExplicit
|
||||
|
||||
Perhaps a better title for this change would be "Make the Threshold filter
|
||||
not totally useless."
|
||||
|
||||
A long standing issue with the Threshold filter is that its output CellSet
|
||||
was stored in a CellSetPermutation. This made Threshold hyper- efficient
|
||||
because it required hardly any data movement to implement. However, the
|
||||
problem was that any other unit that had to use the CellSet failed. To have
|
||||
VTK-m handle that output correctly in other filters and writers, they all
|
||||
would have to check for the existance of CellSetPermutation. And
|
||||
CellSetPermutation is templated on the CellSet type it is permuting, so all
|
||||
units would have to compile special cases for all these combinations. This
|
||||
is not likely to be feasible in any static solution.
|
||||
|
||||
The simple solution, implemented here, is to deep copy the cells to a
|
||||
CellSetExplicit, which is a known type that is already used everywhere in
|
||||
VTK-m. The solution is a bit disappointing since it requires more memory
|
||||
and time to build. But it is on par with solutions in other libraries (like
|
||||
VTK). And it really does not matter how efficient the old solution was if
|
||||
it was useless.
|
@ -1,39 +0,0 @@
|
||||
# Recursive base component queries to VecTraits
|
||||
|
||||
This change adds a recursive `BaseComponentType` to `VecTraits` that
|
||||
recursively finds the base (non-`Vec`) type of a `Vec`. This is useful when
|
||||
dealing with potentially nested `Vec`s (e.g. `Vec<Vec<T, M>, N>`) and you
|
||||
want to know the precision of the math being defined.
|
||||
|
||||
``` cpp
|
||||
using NestedVec = vtkm::Vec<vtkm::Vec<vtkm::Float32, 3>, 8>;
|
||||
|
||||
// ComponentType becomes vtkm::Vec<vtkm::Float32, 3>
|
||||
using ComponentType = typename vtkm::VecTraits<NestedVec>::ComponentType;
|
||||
|
||||
// BaseComponentType becomes vtkm::Float32
|
||||
using BaseComponentType = typename vtkm::VecTraits<NestedVec>::BaseComponentType;
|
||||
```
|
||||
|
||||
Also added the ability to `VecTraits` to change the component type of a
|
||||
vector. The template `RepalceComponentType` resolves to a `Vec` of the same
|
||||
type with the component replaced with a new type. The template
|
||||
`ReplaceBaseComponentType` traverses down a nested type and replaces the
|
||||
base type.
|
||||
|
||||
``` cpp
|
||||
using NestedVec = vtkm::Vec<vtkm::Vec<vtkm::Float32, 3>, 8>;
|
||||
|
||||
// NewVec1 becomes vtkm::Vec<vtkm::Float64, 8>
|
||||
using NewVec1 =
|
||||
typename vtkm::VecTraits<NestedVec>::template ReplaceComponentType<vtkm::Float64>;
|
||||
|
||||
// NewVec2 becomes vtkm::Vec<vtkm::Vec<vtkm::Float64, 3>, 8>
|
||||
using NewVec1 =
|
||||
typename vtkm::VecTraits<NestedVec>::template ReplaceBaseComponentType<vtkm::Float64>;
|
||||
```
|
||||
|
||||
This functionality replaces the functionality in `vtkm::BaseComponent`. Unfortunately,
|
||||
`vtkm::BaseComponent` did not have the ability to replace the base component and
|
||||
there was no straightforward way to implement that outside of `VecTraits`.
|
||||
|
@ -1,22 +0,0 @@
|
||||
# Add aliases for common Vec types
|
||||
|
||||
Specifying `Vec` types can be verbose. For example, to simply express a
|
||||
vector in 3-space, you would need a declaration like this:
|
||||
|
||||
``` cpp
|
||||
vtkm::Vec<vtkm::FloatDefault, 3>
|
||||
```
|
||||
|
||||
This is very verbose and frankly confusing to users. To make things easier,
|
||||
we have introduced several aliases for common `Vec` types. For example, the
|
||||
above type can now be referenced simply with `vtkm::Vec3f`, which is a
|
||||
3-vec of floating point values of the default width. If you want to specify
|
||||
the width, then you can use either `vtkm::Vec3f_32` or `vtkm::Vec3f_64`.
|
||||
|
||||
There are likewise types introduced for integers and unsigned integers
|
||||
(e.g. `vtkm::Vec3i` and `vtkm::Vec3ui`). You can specify the width of these
|
||||
all the way down to 8 bit (e.g. `vtkm::Vec3ui_8`, `vtkm::Vec3ui_16`,
|
||||
`vtkm::Vec3ui_32`, and `vtkm::Vec3ui_64`).
|
||||
|
||||
For completeness, `vtkm::Id4` was added as well as `vtkm::IdComponent2`,
|
||||
`vtkm::IdComponent3`, and `vtkm::IdComponent4`.
|
@ -1,11 +0,0 @@
|
||||
# vtkm::Vec const& operator[] is now `constexpr`
|
||||
|
||||
|
||||
This was done to allow for developers to write normal operations on vtkm::Vec but have
|
||||
the resolved at compile time, allowing for both readible code and no runtime cost.
|
||||
|
||||
Now you can do things such as:
|
||||
```cxx
|
||||
constexpr vtkm::Id2 dims(16,16);
|
||||
constexpr vtkm::Float64 dx = vtkm::Float64(4.0 * vtkm::Pi()) / vtkm::Float64(dims[0] - 1);
|
||||
```
|
@ -1,12 +0,0 @@
|
||||
# Enable writing to ArrayHandleCast
|
||||
|
||||
Previously, `ArrayHandleCast` was considered a read-only array handle.
|
||||
However, it is trivial to reverse the cast (now that `ArrayHandleTransform`
|
||||
supports an inverse transform). So now you can write to a cast array
|
||||
(assuming the underlying array is writable).
|
||||
|
||||
One trivial consequence of this change is that you can no longer make a
|
||||
cast that cannot be reversed. For example, it was possible to cast a simple
|
||||
scalar to a `Vec` even though it is not possible to convert a `Vec` to a
|
||||
scalar value. This was of dubious correctness (it is more of a construction
|
||||
than a cast) and is easy to recreate with `ArrayHandleTransform`.
|
@ -139,14 +139,11 @@ public:
|
||||
std::string getOption(const std::string& option) const
|
||||
{
|
||||
std::size_t index = static_cast<std::size_t>(this->findOption(option));
|
||||
if (index >= 0)
|
||||
std::string val = this->mCLOptions[index];
|
||||
auto valPos = val.find("=");
|
||||
if (valPos)
|
||||
{
|
||||
std::string val = this->mCLOptions[index];
|
||||
auto valPos = val.find("=");
|
||||
if (valPos)
|
||||
{
|
||||
return val.substr(valPos + 1);
|
||||
}
|
||||
return val.substr(valPos + 1);
|
||||
}
|
||||
return std::string("");
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ find_package(VTKm REQUIRED QUIET)
|
||||
|
||||
if(TARGET vtkm_rendering)
|
||||
add_executable(Demo Demo.cxx)
|
||||
target_link_libraries(Demo PRIVATE vtkm_rendering)
|
||||
target_link_libraries(Demo PRIVATE vtkm_filter vtkm_rendering)
|
||||
vtkm_add_target_information(Demo
|
||||
DROP_UNUSED_SYMBOLS MODIFY_CUDA_FLAGS
|
||||
DEVICE_SOURCES Demo.cxx)
|
||||
|
@ -29,7 +29,6 @@ namespace worklet
|
||||
struct HelloWorklet : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
using ControlSignature = void(FieldIn inVector, FieldOut outMagnitude);
|
||||
using ExecutionSignature = void(_1, _2);
|
||||
|
||||
VTKM_EXEC void operator()(const vtkm::Vec3f& inVector, vtkm::FloatDefault& outMagnitude) const
|
||||
{
|
||||
|
@ -199,8 +199,9 @@ inline vtkm::cont::DataSet Make3DExplicitDataSet()
|
||||
return dataSet;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
int TestMetrics(const char* outFileName, vtkm::cont::DataSet data, T filter)
|
||||
int TestMetrics(const char* outFileName,
|
||||
vtkm::cont::DataSet data,
|
||||
vtkm::filter::MeshQuality& filter)
|
||||
{
|
||||
vtkm::cont::DataSet outputData;
|
||||
try
|
||||
@ -255,22 +256,10 @@ int main(int argc, char* argv[])
|
||||
vtkm::io::reader::VTKDataSetReader reader(argv[1]);
|
||||
|
||||
|
||||
//Assign a cell metric to compute for each different
|
||||
//shape type that may exist in the input dataset. If no metric
|
||||
//is specified for a shape type, then it is assumed to be EMPTY
|
||||
//and no metric is computed.
|
||||
std::vector<vtkm::Pair<vtkm::UInt8, vtkm::filter::CellMetric>> shapeMetrics{
|
||||
vtkm::make_Pair(vtkm::CELL_SHAPE_LINE, vtkm::filter::CellMetric::VOLUME),
|
||||
vtkm::make_Pair(vtkm::CELL_SHAPE_TRIANGLE, vtkm::filter::CellMetric::VOLUME),
|
||||
vtkm::make_Pair(vtkm::CELL_SHAPE_POLYGON, vtkm::filter::CellMetric::VOLUME),
|
||||
vtkm::make_Pair(vtkm::CELL_SHAPE_TETRA, vtkm::filter::CellMetric::VOLUME),
|
||||
vtkm::make_Pair(vtkm::CELL_SHAPE_HEXAHEDRON, vtkm::filter::CellMetric::VOLUME),
|
||||
vtkm::make_Pair(vtkm::CELL_SHAPE_WEDGE, vtkm::filter::CellMetric::VOLUME),
|
||||
vtkm::make_Pair(vtkm::CELL_SHAPE_QUAD, vtkm::filter::CellMetric::VOLUME),
|
||||
vtkm::make_Pair(vtkm::CELL_SHAPE_PYRAMID, vtkm::filter::CellMetric::VOLUME)
|
||||
};
|
||||
// A cell metric is now computed for every shape type that exists in the
|
||||
// input dataset.
|
||||
vtkm::filter::CellMetric shapeMetric = vtkm::filter::CellMetric::VOLUME;
|
||||
|
||||
vtkm::filter::MeshQuality filter(shapeMetrics);
|
||||
try
|
||||
{
|
||||
input = reader.ReadDataSet(); //FIELD not supported errors here, but doesnt affect data
|
||||
@ -281,6 +270,8 @@ int main(int argc, char* argv[])
|
||||
std::cerr << "Error occured while reading input. Exiting" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
vtkm::filter::MeshQuality filter(shapeMetric);
|
||||
TestMetrics(outFileName, input, filter);
|
||||
return 0;
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ project(Oscillator CXX)
|
||||
find_package(VTKm REQUIRED QUIET)
|
||||
|
||||
add_executable(Oscillator Oscillator.cxx)
|
||||
target_link_libraries(Oscillator PRIVATE vtkm_filter)
|
||||
target_link_libraries(Oscillator PRIVATE vtkm_source)
|
||||
vtkm_add_target_information(Oscillator
|
||||
DROP_UNUSED_SYMBOLS MODIFY_CUDA_FLAGS
|
||||
DEVICE_SOURCES Oscillator.cxx)
|
||||
|
@ -22,7 +22,7 @@
|
||||
|
||||
#include <vtkm/cont/TryExecute.h>
|
||||
|
||||
#include <vtkm/filter/OscillatorSource.h>
|
||||
#include <vtkm/source/Oscillator.h>
|
||||
|
||||
#if !defined(_WIN32) || defined(__CYGWIN__)
|
||||
#include <unistd.h> /* unlink */
|
||||
@ -58,7 +58,7 @@ static inline std::string& trim(std::string& s)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void read_oscillators(std::string filePath, vtkm::filter::OscillatorSource& filter)
|
||||
void read_oscillators(std::string filePath, vtkm::source::Oscillator& source)
|
||||
{
|
||||
std::ifstream in(filePath);
|
||||
if (!in)
|
||||
@ -87,15 +87,15 @@ void read_oscillators(std::string filePath, vtkm::filter::OscillatorSource& filt
|
||||
|
||||
if (stype == "damped")
|
||||
{
|
||||
filter.AddDamped(x, y, z, r, omega0, zeta);
|
||||
source.AddDamped(x, y, z, r, omega0, zeta);
|
||||
}
|
||||
else if (stype == "decaying")
|
||||
{
|
||||
filter.AddDecaying(x, y, z, r, omega0, zeta);
|
||||
source.AddDecaying(x, y, z, r, omega0, zeta);
|
||||
}
|
||||
else if (stype == "periodic")
|
||||
{
|
||||
filter.AddPeriodic(x, y, z, r, omega0, zeta);
|
||||
source.AddPeriodic(x, y, z, r, omega0, zeta);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -303,22 +303,19 @@ int main(int argc, char** argv)
|
||||
std::cout << " - end: " << endTime << std::endl;
|
||||
std::cout << "=======================================\n" << std::endl;
|
||||
|
||||
vtkm::cont::DataSetBuilderUniform builder;
|
||||
vtkm::cont::DataSet dataset = builder.Create(vtkm::Id3(sizeX, sizeY, sizeZ));
|
||||
|
||||
vtkm::filter::OscillatorSource filter;
|
||||
read_oscillators(oscillatorConfigFile, filter);
|
||||
vtkm::source::Oscillator source(vtkm::Id3{ sizeX, sizeY, sizeZ });
|
||||
read_oscillators(oscillatorConfigFile, source);
|
||||
|
||||
std::cout << "=========== start computation ============" << std::endl;
|
||||
int count = 0;
|
||||
while (currentTime < endTime)
|
||||
{
|
||||
filter.SetTime(currentTime);
|
||||
vtkm::cont::DataSet rdata = filter.Execute(dataset);
|
||||
source.SetTime(currentTime);
|
||||
vtkm::cont::DataSet rdata = source.Execute();
|
||||
if (generateOutput)
|
||||
{
|
||||
vtkm::cont::ArrayHandle<vtkm::Float64> tmp;
|
||||
rdata.GetField("oscillation", vtkm::cont::Field::Association::POINTS).GetData().CopyTo(tmp);
|
||||
rdata.GetField("scalars", vtkm::cont::Field::Association::POINTS).GetData().CopyTo(tmp);
|
||||
double* values = tmp.GetStorage().GetArray();
|
||||
writeData(outputDirectory, count++, sizeX, sizeY, sizeZ, values);
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
1.4.0
|
||||
1.5.0
|
||||
|
@ -25,6 +25,7 @@ set(headers
|
||||
CellClassification.h
|
||||
CellShape.h
|
||||
CellTraits.h
|
||||
Deprecated.h
|
||||
Flags.h
|
||||
Geometry.h
|
||||
Hash.h
|
||||
@ -77,6 +78,8 @@ if(VTKm_ENABLE_LOGGING)
|
||||
endif()
|
||||
add_subdirectory(thirdparty/optionparser)
|
||||
add_subdirectory(thirdparty/taotuple)
|
||||
add_subdirectory(thirdparty/lcl)
|
||||
|
||||
add_subdirectory(testing)
|
||||
add_subdirectory(internal)
|
||||
|
||||
|
@ -13,6 +13,17 @@
|
||||
#include <vtkm/StaticAssert.h>
|
||||
#include <vtkm/Types.h>
|
||||
|
||||
#include <lcl/Polygon.h>
|
||||
#include <lcl/Shapes.h>
|
||||
|
||||
// Vtk-c does not have tags for Empty and PolyLine. Define dummy tags here to
|
||||
// avoid compilation errors. These tags are not used anywhere.
|
||||
namespace lcl
|
||||
{
|
||||
struct Empty;
|
||||
struct PolyLine;
|
||||
}
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
|
||||
@ -22,21 +33,21 @@ namespace vtkm
|
||||
enum CellShapeIdEnum
|
||||
{
|
||||
// Linear cells
|
||||
CELL_SHAPE_EMPTY = 0,
|
||||
CELL_SHAPE_VERTEX = 1,
|
||||
CELL_SHAPE_EMPTY = lcl::ShapeId::EMPTY,
|
||||
CELL_SHAPE_VERTEX = lcl::ShapeId::VERTEX,
|
||||
//CELL_SHAPE_POLY_VERTEX = 2,
|
||||
CELL_SHAPE_LINE = 3,
|
||||
CELL_SHAPE_LINE = lcl::ShapeId::LINE,
|
||||
CELL_SHAPE_POLY_LINE = 4,
|
||||
CELL_SHAPE_TRIANGLE = 5,
|
||||
CELL_SHAPE_TRIANGLE = lcl::ShapeId::TRIANGLE,
|
||||
//CELL_SHAPE_TRIANGLE_STRIP = 6,
|
||||
CELL_SHAPE_POLYGON = 7,
|
||||
CELL_SHAPE_POLYGON = lcl::ShapeId::POLYGON,
|
||||
//CELL_SHAPE_PIXEL = 8,
|
||||
CELL_SHAPE_QUAD = 9,
|
||||
CELL_SHAPE_TETRA = 10,
|
||||
CELL_SHAPE_QUAD = lcl::ShapeId::QUAD,
|
||||
CELL_SHAPE_TETRA = lcl::ShapeId::TETRA,
|
||||
//CELL_SHAPE_VOXEL = 11,
|
||||
CELL_SHAPE_HEXAHEDRON = 12,
|
||||
CELL_SHAPE_WEDGE = 13,
|
||||
CELL_SHAPE_PYRAMID = 14,
|
||||
CELL_SHAPE_HEXAHEDRON = lcl::ShapeId::HEXAHEDRON,
|
||||
CELL_SHAPE_WEDGE = lcl::ShapeId::WEDGE,
|
||||
CELL_SHAPE_PYRAMID = lcl::ShapeId::PYRAMID,
|
||||
|
||||
NUMBER_OF_CELL_SHAPES
|
||||
};
|
||||
@ -58,6 +69,10 @@ struct CellShapeTagCheck : std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
/// Convert VTK-m tag to VTK-c tag
|
||||
template <typename VtkmCellShapeTag>
|
||||
struct CellShapeTagVtkmToVtkc;
|
||||
|
||||
} // namespace internal
|
||||
|
||||
/// Checks that the argument is a proper cell shape tag. This is a handy
|
||||
@ -94,6 +109,11 @@ struct CellShapeIdToTag
|
||||
struct CellShapeTagCheck<vtkm::CellShapeTag##name> : std::true_type \
|
||||
{ \
|
||||
}; \
|
||||
template <> \
|
||||
struct CellShapeTagVtkmToVtkc<vtkm::CellShapeTag##name> \
|
||||
{ \
|
||||
using Type = lcl::name; \
|
||||
}; \
|
||||
} \
|
||||
static inline VTKM_EXEC_CONT const char* GetCellShapeName(vtkm::CellShapeTag##name) \
|
||||
{ \
|
||||
@ -140,6 +160,35 @@ struct CellShapeTagGeneric
|
||||
vtkm::UInt8 Id;
|
||||
};
|
||||
|
||||
namespace internal
|
||||
{
|
||||
|
||||
template <typename VtkmCellShapeTag>
|
||||
VTKM_EXEC_CONT inline typename CellShapeTagVtkmToVtkc<VtkmCellShapeTag>::Type make_VtkcCellShapeTag(
|
||||
const VtkmCellShapeTag&,
|
||||
vtkm::IdComponent numPoints = 0)
|
||||
{
|
||||
using VtkcCellShapeTag = typename CellShapeTagVtkmToVtkc<VtkmCellShapeTag>::Type;
|
||||
static_cast<void>(numPoints); // unused
|
||||
return VtkcCellShapeTag{};
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
inline lcl::Polygon make_VtkcCellShapeTag(const vtkm::CellShapeTagPolygon&,
|
||||
vtkm::IdComponent numPoints = 0)
|
||||
{
|
||||
return lcl::Polygon(numPoints);
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
inline lcl::Cell make_VtkcCellShapeTag(const vtkm::CellShapeTagGeneric& tag,
|
||||
vtkm::IdComponent numPoints = 0)
|
||||
{
|
||||
return lcl::Cell(static_cast<std::int8_t>(tag.Id), numPoints);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
#define vtkmGenericCellShapeMacroCase(cellShapeId, call) \
|
||||
case vtkm::cellShapeId: \
|
||||
{ \
|
||||
|
138
vtkm/Deprecated.h
Normal file
138
vtkm/Deprecated.h
Normal file
@ -0,0 +1,138 @@
|
||||
//============================================================================
|
||||
// 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.
|
||||
//============================================================================
|
||||
#ifndef vtk_m_Deprecated_h
|
||||
#define vtk_m_Deprecated_h
|
||||
|
||||
#include <vtkm/StaticAssert.h>
|
||||
#include <vtkm/Types.h>
|
||||
|
||||
#define VTK_M_DEPRECATED_MAKE_MESSAGE(...) \
|
||||
VTKM_EXPAND(VTK_M_DEPRECATED_MAKE_MESSAGE_IMPL(__VA_ARGS__, "", vtkm::internal::NullType{}))
|
||||
#define VTK_M_DEPRECATED_MAKE_MESSAGE_IMPL(version, message, ...) \
|
||||
message " Deprecated in version " #version "."
|
||||
|
||||
/// \def VTKM_DEPRECATED(version, message)
|
||||
///
|
||||
/// Classes and methods are marked deprecated using the `VTKM_DEPRECATED`
|
||||
/// macro. The first argument of `VTKM_DEPRECATED` should be set to the first
|
||||
/// version in which the feature is deprecated. For example, if the last
|
||||
/// released version of VTK-m was 1.5, and on the master branch a developer
|
||||
/// wants to deprecate a class foo, then the `VTKM_DEPRECATED` release version
|
||||
/// should be given as 1.6, which will be the next minor release of VTK-m. The
|
||||
/// second argument of `VTKM_DEPRECATED`, which is optional but highly
|
||||
/// encouraged, is a short message that should clue developers on how to update
|
||||
/// their code to the new changes. For example, it could point to the
|
||||
/// replacement class or method for the changed feature.
|
||||
///
|
||||
|
||||
/// \def VTKM_DEPRECATED_SUPPRESS_BEGIN
|
||||
///
|
||||
/// Begins a region of code in which warnings about using deprecated code are ignored.
|
||||
/// Such suppression is usually helpful when implementing other deprecated features.
|
||||
/// (You would think if one deprecated method used another deprecated method this
|
||||
/// would not be a warning, but it is.)
|
||||
///
|
||||
/// Any use of `VTKM_DEPRECATED_SUPPRESS_BEGIN` must be paired with a
|
||||
/// `VTKM_DEPRECATED_SUPPRESS_END`, which will re-enable warnings in subsequent code.
|
||||
///
|
||||
/// Do not use a semicolon after this macro.
|
||||
///
|
||||
|
||||
/// \def VTKM_DEPRECATED_SUPPRESS_ENDS
|
||||
///
|
||||
/// Ends a region of code in which warnings about using deprecated code are ignored.
|
||||
/// Any use of `VTKM_DEPRECATED_SUPPRESS_BEGIN` must be paired with a
|
||||
/// `VTKM_DEPRECATED_SUPPRESS_END`.
|
||||
///
|
||||
/// Do not use a semicolon after this macro.
|
||||
///
|
||||
|
||||
// Determine whether the [[deprecated]] attribute is supported. Note that we are not
|
||||
// using other older compiler features such as __attribute__((__deprecated__)) because
|
||||
// they do not all support all [[deprecated]] uses (such as uses in enums). If
|
||||
// [[deprecated]] is supported, then VTK_M_DEPRECATED_ATTRIBUTE_SUPPORTED will get defined.
|
||||
#ifndef VTK_M_DEPRECATED_ATTRIBUTE_SUPPORTED
|
||||
|
||||
#if __cplusplus >= 201402L
|
||||
|
||||
// C++14 and better supports [[deprecated]]
|
||||
#define VTK_M_DEPRECATED_ATTRIBUTE_SUPPORTED
|
||||
|
||||
#elif defined(VTKM_GCC)
|
||||
|
||||
// GCC has supported [[deprecated]] since version 5.0, but using it on enum was not
|
||||
// supported until 6.0. So we have to make a special case to only use it for high
|
||||
// enough revisions.
|
||||
#if __GNUC__ >= 6
|
||||
#define VTK_M_DEPRECATED_ATTRIBUTE_SUPPORTED
|
||||
#endif // Too old GCC
|
||||
|
||||
#elif defined(__has_cpp_attribute)
|
||||
|
||||
#if __has_cpp_attribute(deprecated)
|
||||
// Compiler not fully C++14 compliant, but it reports to support [[deprecated]]
|
||||
#define VTK_M_DEPRECATED_ATTRIBUTE_SUPPORTED
|
||||
#endif // __has_cpp_attribute(deprecated)
|
||||
|
||||
#elif defined(VTKM_MSVC) && _MSC_VER >= 1900
|
||||
|
||||
#define VTK_M_DEPRECATED_ATTRIBUTE_SUPPORTED
|
||||
|
||||
#endif // no known compiler support for [[deprecated]]
|
||||
|
||||
#endif // VTK_M_DEPRECATED_ATTRIBUTE_SUPPORTED check
|
||||
|
||||
// Determine how to turn deprecated warnings on and off, generally with pragmas. If
|
||||
// deprecated warnings can be turned off and on, then VTK_M_DEPRECATED_SUPPRESS_SUPPORTED
|
||||
// is defined and the pair VTKM_DEPRECATED_SUPPRESS_BEGIN and VTKM_DEPRECATED_SUPRESS_END
|
||||
// are defined to the pragmas to disable and restore these warnings. If this support
|
||||
// cannot be determined, VTK_M_DEPRECATED_SUPPRESS_SUPPORTED is _not_ define whereas
|
||||
// VTKM_DEPRECATED_SUPPRESS_BEGIN and VTKM_DEPRECATED_SUPPRESS_END are defined to be
|
||||
// empty.
|
||||
#ifndef VTKM_DEPRECATED_SUPPRESS_SUPPORTED
|
||||
|
||||
#if defined(VTKM_GCC) || defined(VTKM_CLANG)
|
||||
|
||||
#define VTKM_DEPRECATED_SUPPRESS_SUPPORTED
|
||||
#define VTKM_DEPRECATED_SUPPRESS_BEGIN \
|
||||
_Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
|
||||
#define VTKM_DEPRECATED_SUPPRESS_END _Pragma("GCC diagnostic pop")
|
||||
|
||||
#elif defined(VTKM_MSVC)
|
||||
|
||||
#define VTKM_DEPRECATED_SUPPRESS_SUPPORTED
|
||||
#define VTKM_DEPRECATED_SUPPRESS_BEGIN __pragma(warning(push)) __pragma(warning(disable : 4996))
|
||||
#define VTKM_DEPRECATED_SUPPRESS_END __pragma(warning(pop))
|
||||
|
||||
#else
|
||||
|
||||
// Other compilers probably have different pragmas for turning warnings off and on.
|
||||
// Adding more compilers to this list is fine, but the above probably capture most
|
||||
// developers and should be covered on dashboards.
|
||||
#define VTKM_DEPRECATED_SUPPRESS_BEGIN
|
||||
#define VTKM_DEPRECATED_SUPPRESS_END
|
||||
|
||||
#endif
|
||||
|
||||
#endif // VTKM_DEPRECATED_SUPPRESS_SUPPORTED check
|
||||
|
||||
#if !defined(VTKM_DEPRECATED_SUPPRESS_BEGIN) || !defined(VTKM_DEPRECATED_SUPPRESS_END)
|
||||
#error VTKM_DEPRECATED_SUPPRESS macros not properly defined.
|
||||
#endif
|
||||
|
||||
// Only actually use the [[deprecated]] attribute if the compiler supports it AND
|
||||
// we know how to suppress deprecations when necessary.
|
||||
#if defined(VTK_M_DEPRECATED_ATTRIBUTE_SUPPORTED) && defined(VTKM_DEPRECATED_SUPPRESS_SUPPORTED)
|
||||
#define VTKM_DEPRECATED(...) [[deprecated(VTK_M_DEPRECATED_MAKE_MESSAGE(__VA_ARGS__))]]
|
||||
#else
|
||||
#define VTKM_DEPRECATED(...)
|
||||
#endif
|
||||
|
||||
#endif // vtk_m_Deprecated_h
|
@ -150,6 +150,27 @@ struct ListTagTransform : detail::ListRoot
|
||||
brigand::bind<Transform, brigand::_1>>;
|
||||
};
|
||||
|
||||
/// A list tag that takes an existing ListTag and a predicate template that is applied to
|
||||
/// each type in the ListTag. Any type in the ListTag that has a value element equal to true
|
||||
/// (the equivalent of std::true_type), that item will be removed from the list. For example
|
||||
/// the following type
|
||||
///
|
||||
/// ```cpp
|
||||
/// vtkm::ListTagRemoveIf<vtkm::ListTagBase<int, float, long long, double>, std::is_integral>
|
||||
/// ```
|
||||
///
|
||||
/// resolves to a ListTag that is equivalent to `vtkm::ListTag<float, double>` because
|
||||
/// `std::is_integral<int>` and `std::is_integral<long long>` resolve to `std::true_type`
|
||||
/// whereas `std::is_integral<float>` and `std::is_integral<double>` resolve to
|
||||
/// `std::false_type`.
|
||||
template <typename ListTag, template <typename> class Predicate>
|
||||
struct ListTagRemoveIf : detail::ListRoot
|
||||
{
|
||||
VTKM_IS_LIST_TAG(ListTag);
|
||||
using list = brigand::remove_if<internal::ListTagAsBrigandList<ListTag>,
|
||||
brigand::bind<Predicate, brigand::_1>>;
|
||||
};
|
||||
|
||||
/// \brief Determines the number of types in the given list.
|
||||
///
|
||||
/// There is a static member named \c value that is set to the length of the list.
|
||||
|
@ -183,18 +183,18 @@ struct VTKM_NEVER_EXPORT VecTraits<const T> : VecTraits<T>
|
||||
{
|
||||
};
|
||||
|
||||
#if defined(VTKM_GCC) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 8)
|
||||
#if defined(VTKM_GCC) && (__GNUC__ <= 5)
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <typename NewT, vtkm::IdComponent Size>
|
||||
struct VecReplaceComponentTypeGCC48
|
||||
struct VecReplaceComponentTypeGCC4or5
|
||||
{
|
||||
using type = vtkm::Vec<NewT, Size>;
|
||||
};
|
||||
|
||||
template <typename T, vtkm::IdComponent Size, typename NewT>
|
||||
struct VecReplaceBaseComponentTypeGCC48
|
||||
struct VecReplaceBaseComponentTypeGCC4or5
|
||||
{
|
||||
using type =
|
||||
vtkm::Vec<typename vtkm::VecTraits<T>::template ReplaceBaseComponentType<NewT>, Size>;
|
||||
@ -274,12 +274,12 @@ struct VTKM_NEVER_EXPORT VecTraits<vtkm::Vec<T, Size>>
|
||||
/// This replacement is not recursive. So VecTraits<Vec<Vec<T, M>, N>::ReplaceComponentType<T2>
|
||||
/// is vtkm::Vec<T2, N>.
|
||||
///@{
|
||||
#if defined(VTKM_GCC) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 8)
|
||||
// Silly workaround for bug in GCC 4.8
|
||||
#if defined(VTKM_GCC) && (__GNUC__ <= 5)
|
||||
// Silly workaround for bug in GCC <= 5
|
||||
template <typename NewComponentType>
|
||||
using ReplaceComponentType =
|
||||
typename detail::VecReplaceComponentTypeGCC48<NewComponentType, Size>::type;
|
||||
#else // !GCC 4.8
|
||||
typename detail::VecReplaceComponentTypeGCC4or5<NewComponentType, Size>::type;
|
||||
#else // !GCC <= 5
|
||||
template <typename NewComponentType>
|
||||
using ReplaceComponentType = vtkm::Vec<NewComponentType, Size>;
|
||||
#endif
|
||||
@ -291,12 +291,12 @@ struct VTKM_NEVER_EXPORT VecTraits<vtkm::Vec<T, Size>>
|
||||
/// is recursive for nested types. For example,
|
||||
/// VecTraits<Vec<Vec<T, M>, N>::ReplaceComponentType<T2> is Vec<Vec<T2, M>, N>.
|
||||
///@{
|
||||
#if defined(VTKM_GCC) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 8)
|
||||
// Silly workaround for bug in GCC 4.8
|
||||
#if defined(VTKM_GCC) && (__GNUC__ <= 5)
|
||||
// Silly workaround for bug in GCC <= 5
|
||||
template <typename NewComponentType>
|
||||
using ReplaceBaseComponentType =
|
||||
typename detail::VecReplaceBaseComponentTypeGCC48<T, Size, NewComponentType>::type;
|
||||
#else // !GCC 4.8
|
||||
typename detail::VecReplaceBaseComponentTypeGCC4or5<T, Size, NewComponentType>::type;
|
||||
#else // !GCC <= 5
|
||||
template <typename NewComponentType>
|
||||
using ReplaceBaseComponentType = vtkm::Vec<
|
||||
typename vtkm::VecTraits<ComponentType>::template ReplaceBaseComponentType<NewComponentType>,
|
||||
|
@ -594,7 +594,7 @@ struct Algorithm
|
||||
template <typename WordType>
|
||||
VTKM_CONT static void Fill(vtkm::cont::BitField& bits, WordType word)
|
||||
{
|
||||
FillBitField(vtkm::cont::DeviceAdapterTagAny{}, bits, word);
|
||||
Fill(vtkm::cont::DeviceAdapterTagAny{}, bits, word);
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
|
@ -57,24 +57,18 @@ class VTKM_CONT_EXPORT ArrayHandleBase
|
||||
/// with C++11 type_traits.
|
||||
///
|
||||
template <typename T, typename StorageTag>
|
||||
struct IsValidArrayHandle
|
||||
: std::integral_constant<bool,
|
||||
!(std::is_base_of<vtkm::cont::internal::UndefinedStorage,
|
||||
vtkm::cont::internal::Storage<T, StorageTag>>::value)>
|
||||
{
|
||||
};
|
||||
using IsValidArrayHandle =
|
||||
std::integral_constant<bool,
|
||||
!(std::is_base_of<vtkm::cont::internal::UndefinedStorage,
|
||||
vtkm::cont::internal::Storage<T, StorageTag>>::value)>;
|
||||
|
||||
/// Checks to see if the given type and storage forms a invalid array handle
|
||||
/// (some storage objects cannot support all types). This check is compatible
|
||||
/// with C++11 type_traits.
|
||||
///
|
||||
template <typename T, typename StorageTag>
|
||||
struct IsInValidArrayHandle
|
||||
: std::integral_constant<bool,
|
||||
(std::is_base_of<vtkm::cont::internal::UndefinedStorage,
|
||||
vtkm::cont::internal::Storage<T, StorageTag>>::value)>
|
||||
{
|
||||
};
|
||||
using IsInValidArrayHandle =
|
||||
std::integral_constant<bool, !IsValidArrayHandle<T, StorageTag>::value>;
|
||||
|
||||
/// Checks to see if the ArrayHandle allows writing, as some ArrayHandles
|
||||
/// (Implicit) don't support writing. These will be defined as either
|
||||
|
@ -17,6 +17,8 @@
|
||||
|
||||
#include <vtkmtaotuple/include/Tuple.h>
|
||||
|
||||
#include <vtkm/internal/brigand.hpp>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace vtkm
|
||||
@ -373,11 +375,18 @@ struct ArraySizeValidator
|
||||
}
|
||||
};
|
||||
|
||||
template <typename PortalList>
|
||||
using AllPortalsAreWritable =
|
||||
typename brigand::all<PortalList,
|
||||
brigand::bind<vtkm::internal::PortalSupportsSets, brigand::_1>>::type;
|
||||
|
||||
} // end namespace compvec
|
||||
|
||||
template <typename PortalTuple>
|
||||
class VTKM_ALWAYS_EXPORT ArrayPortalCompositeVector
|
||||
{
|
||||
using Writable = compvec::AllPortalsAreWritable<PortalTuple>;
|
||||
|
||||
public:
|
||||
using ValueType = typename compvec::GetValueType<PortalTuple>::ValueType;
|
||||
|
||||
@ -459,8 +468,9 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
void Set(vtkm::Id index, const ValueType& value) const
|
||||
template <typename Writable_ = Writable,
|
||||
typename = typename std::enable_if<Writable_::value>::type>
|
||||
VTKM_EXEC_CONT void Set(vtkm::Id index, const ValueType& value) const
|
||||
{
|
||||
SetImpl<0, PortalTuple>::Exec(this->Portals, value, index);
|
||||
}
|
||||
|
@ -22,6 +22,10 @@ namespace internal
|
||||
template <typename PortalType1, typename PortalType2>
|
||||
class VTKM_ALWAYS_EXPORT ArrayPortalConcatenate
|
||||
{
|
||||
using WritableP1 = vtkm::internal::PortalSupportsSets<PortalType1>;
|
||||
using WritableP2 = vtkm::internal::PortalSupportsSets<PortalType2>;
|
||||
using Writable = std::integral_constant<bool, WritableP1::value && WritableP2::value>;
|
||||
|
||||
public:
|
||||
using ValueType = typename PortalType1::ValueType;
|
||||
|
||||
@ -58,18 +62,27 @@ public:
|
||||
ValueType Get(vtkm::Id index) const
|
||||
{
|
||||
if (index < this->portal1.GetNumberOfValues())
|
||||
{
|
||||
return this->portal1.Get(index);
|
||||
}
|
||||
else
|
||||
{
|
||||
return this->portal2.Get(index - this->portal1.GetNumberOfValues());
|
||||
}
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
void Set(vtkm::Id index, const ValueType& value) const
|
||||
template <typename Writable_ = Writable,
|
||||
typename = typename std::enable_if<Writable_::value>::type>
|
||||
VTKM_EXEC_CONT void Set(vtkm::Id index, const ValueType& value) const
|
||||
{
|
||||
if (index < this->portal1.GetNumberOfValues())
|
||||
{
|
||||
this->portal1.Set(index, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->portal2.Set(index - this->portal1.GetNumberOfValues(), value);
|
||||
}
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
|
@ -20,10 +20,19 @@
|
||||
#include <vtkm/internal/brigand.hpp>
|
||||
|
||||
#include <vtkmtaotuple/include/Tuple.h>
|
||||
#include <vtkmtaotuple/include/tao/seq/make_integer_sequence.hpp>
|
||||
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
// MSVC and CUDA and Xcode < 10 and Clang < 5 have issues with tao integer sequences
|
||||
#if defined(VTKM_MSVC) || defined(VTKM_CUDA_DEVICE_PASS) || \
|
||||
(defined(__apple_build_version__) && (__apple_build_version__ < 10000000)) || \
|
||||
(defined(VTKM_CLANG) && (__clang_major__ < 5))
|
||||
#define VTKM_USE_BRIGAND_SEQ
|
||||
#endif
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
@ -67,9 +76,9 @@ public:
|
||||
|
||||
VTKM_CONT
|
||||
ArrayPortalDecorator(FunctorType func, InverseFunctorType iFunc, vtkm::Id numValues)
|
||||
: Functor{ func }
|
||||
, InverseFunctor{ iFunc }
|
||||
, NumberOfValues{ numValues }
|
||||
: Functor(func)
|
||||
, InverseFunctor(iFunc)
|
||||
, NumberOfValues(numValues)
|
||||
{
|
||||
}
|
||||
|
||||
@ -349,8 +358,12 @@ struct DecoratorStorageTraits
|
||||
|
||||
using ArrayTupleType = vtkmstd::tuple<ArrayTs...>;
|
||||
|
||||
// size_t integral constants that index ArrayTs:
|
||||
// size_t integral constants that index ArrayTs:
|
||||
#ifdef VTKM_USE_BRIGAND_SEQ
|
||||
using IndexList = brigand::make_sequence<brigand::size_t<0>, sizeof...(ArrayTs)>;
|
||||
#else // VTKM_USE_BRIGAND_SEQ
|
||||
using IndexList = tao::seq::make_index_sequence<sizeof...(ArrayTs)>;
|
||||
#endif // VTKM_USE_BRIGAND_SEQ
|
||||
|
||||
// Portal lists:
|
||||
// NOTE we have to pass the parameter pack here instead of using ArrayList
|
||||
@ -429,6 +442,7 @@ struct DecoratorStorageTraits
|
||||
return { impl.CreateFunctor(portals...), impl.CreateInverseFunctor(portals...), numVals };
|
||||
}
|
||||
|
||||
#ifdef VTKM_USE_BRIGAND_SEQ
|
||||
// Portal construction methods. These actually create portals.
|
||||
template <template <typename...> class List, typename... Indices>
|
||||
VTKM_CONT static PortalControlType MakePortalControl(const DecoratorImplT& impl,
|
||||
@ -508,6 +522,62 @@ struct DecoratorStorageTraits
|
||||
// note in MakePortalControl.
|
||||
GetPortalOutput(vtkmstd::get<Indices{}.value>(arrays), dev)...);
|
||||
}
|
||||
|
||||
#else // VTKM_USE_BRIGAND_SEQ
|
||||
// Portal construction methods. These actually create portals.
|
||||
template <template <typename, std::size_t...> class List, std::size_t... Indices>
|
||||
VTKM_CONT static PortalControlType MakePortalControl(const DecoratorImplT& impl,
|
||||
ArrayTupleType& arrays,
|
||||
vtkm::Id numValues,
|
||||
List<std::size_t, Indices...>)
|
||||
{
|
||||
return CreatePortalDecorator<PortalControlType>(
|
||||
numValues, impl, GetPortalControl(vtkmstd::get<Indices>(arrays))...);
|
||||
}
|
||||
|
||||
template <template <typename, std::size_t...> class List, std::size_t... Indices>
|
||||
VTKM_CONT static PortalConstControlType MakePortalConstControl(const DecoratorImplT& impl,
|
||||
const ArrayTupleType& arrays,
|
||||
vtkm::Id numValues,
|
||||
List<std::size_t, Indices...>)
|
||||
{
|
||||
return CreatePortalDecorator<PortalConstControlType>(
|
||||
numValues, impl, GetPortalConstControl(vtkmstd::get<Indices>(arrays))...);
|
||||
}
|
||||
|
||||
template <template <typename, std::size_t...> class List, std::size_t... Indices, typename Device>
|
||||
VTKM_CONT static PortalConstExecutionType<Device> MakePortalInput(const DecoratorImplT& impl,
|
||||
const ArrayTupleType& arrays,
|
||||
vtkm::Id numValues,
|
||||
List<std::size_t, Indices...>,
|
||||
Device dev)
|
||||
{
|
||||
return CreatePortalDecorator<PortalConstExecutionType<Device>>(
|
||||
numValues, impl, GetPortalInput(vtkmstd::get<Indices>(arrays), dev)...);
|
||||
}
|
||||
|
||||
template <template <typename, std::size_t...> class List, std::size_t... Indices, typename Device>
|
||||
VTKM_CONT static PortalExecutionType<Device> MakePortalInPlace(const DecoratorImplT& impl,
|
||||
ArrayTupleType& arrays,
|
||||
vtkm::Id numValues,
|
||||
List<std::size_t, Indices...>,
|
||||
Device dev)
|
||||
{
|
||||
return CreatePortalDecorator<PortalExecutionType<Device>>(
|
||||
numValues, impl, GetPortalInPlace(vtkmstd::get<Indices>(arrays), dev)...);
|
||||
}
|
||||
|
||||
template <template <typename, std::size_t...> class List, std::size_t... Indices, typename Device>
|
||||
VTKM_CONT static PortalExecutionType<Device> MakePortalOutput(const DecoratorImplT& impl,
|
||||
ArrayTupleType& arrays,
|
||||
vtkm::Id numValues,
|
||||
List<std::size_t, Indices...>,
|
||||
Device dev)
|
||||
{
|
||||
return CreatePortalDecorator<PortalExecutionType<Device>>(
|
||||
numValues, impl, GetPortalOutput(vtkmstd::get<Indices>(arrays), dev)...);
|
||||
}
|
||||
#endif // VTKM_USE_BRIGAND_SEQ
|
||||
};
|
||||
|
||||
} // end namespace decor
|
||||
@ -538,7 +608,7 @@ public:
|
||||
|
||||
VTKM_CONT
|
||||
Storage(const DecoratorImplT& impl, const ArrayTupleType& arrayTuple, vtkm::Id numValues)
|
||||
: Implementation{ impl }
|
||||
: Implementation(impl)
|
||||
, ArrayTuple{ arrayTuple }
|
||||
, NumberOfValues(numValues)
|
||||
, Valid{ true }
|
||||
@ -824,4 +894,6 @@ make_ArrayHandleDecorator(vtkm::Id numValues, DecoratorImplT&& f, ArrayTs&&... a
|
||||
}
|
||||
} // namespace vtkm::cont
|
||||
|
||||
#undef VTKM_USE_BRIGAND_SEQ
|
||||
|
||||
#endif //vtk_m_ArrayHandleDecorator_h
|
||||
|
@ -23,6 +23,8 @@ namespace internal
|
||||
template <typename PortalType>
|
||||
class VTKM_ALWAYS_EXPORT ArrayPortalExtractComponent
|
||||
{
|
||||
using Writable = vtkm::internal::PortalSupportsSets<PortalType>;
|
||||
|
||||
public:
|
||||
using VectorType = typename PortalType::ValueType;
|
||||
using Traits = vtkm::VecTraits<VectorType>;
|
||||
@ -49,6 +51,9 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
ArrayPortalExtractComponent& operator=(const ArrayPortalExtractComponent& src) = default;
|
||||
ArrayPortalExtractComponent& operator=(ArrayPortalExtractComponent&& src) = default;
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
vtkm::Id GetNumberOfValues() const { return this->Portal.GetNumberOfValues(); }
|
||||
|
||||
@ -58,8 +63,9 @@ public:
|
||||
return Traits::GetComponent(this->Portal.Get(index), this->Component);
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
void Set(vtkm::Id index, const ValueType& value) const
|
||||
template <typename Writable_ = Writable,
|
||||
typename = typename std::enable_if<Writable_::value>::type>
|
||||
VTKM_EXEC_CONT void Set(vtkm::Id index, const ValueType& value) const
|
||||
{
|
||||
VectorType vec = this->Portal.Get(index);
|
||||
Traits::SetComponent(vec, this->Component, value);
|
||||
|
@ -25,6 +25,8 @@ namespace internal
|
||||
template <typename PortalType, vtkm::IdComponent N_COMPONENTS>
|
||||
class VTKM_ALWAYS_EXPORT ArrayPortalGroupVec
|
||||
{
|
||||
using Writable = vtkm::internal::PortalSupportsSets<PortalType>;
|
||||
|
||||
public:
|
||||
static constexpr vtkm::IdComponent NUM_COMPONENTS = N_COMPONENTS;
|
||||
using SourcePortalType = PortalType;
|
||||
@ -79,8 +81,9 @@ public:
|
||||
}
|
||||
|
||||
VTKM_SUPPRESS_EXEC_WARNINGS
|
||||
VTKM_EXEC_CONT
|
||||
void Set(vtkm::Id index, const ValueType& value) const
|
||||
template <typename Writable_ = Writable,
|
||||
typename = typename std::enable_if<Writable_::value>::type>
|
||||
VTKM_EXEC_CONT void Set(vtkm::Id index, const ValueType& value) const
|
||||
{
|
||||
vtkm::Id sourceIndex = index * NUM_COMPONENTS;
|
||||
for (vtkm::IdComponent componentIndex = 0; componentIndex < NUM_COMPONENTS; componentIndex++)
|
||||
|
@ -24,6 +24,8 @@ namespace internal
|
||||
template <typename IndexPortalType, typename ValuePortalType>
|
||||
class VTKM_ALWAYS_EXPORT ArrayPortalPermutation
|
||||
{
|
||||
using Writable = vtkm::internal::PortalSupportsSets<ValuePortalType>;
|
||||
|
||||
public:
|
||||
using ValueType = typename ValuePortalType::ValueType;
|
||||
|
||||
@ -69,8 +71,9 @@ public:
|
||||
}
|
||||
|
||||
VTKM_SUPPRESS_EXEC_WARNINGS
|
||||
VTKM_EXEC
|
||||
void Set(vtkm::Id index, const ValueType& value) const
|
||||
template <typename Writable_ = Writable,
|
||||
typename = typename std::enable_if<Writable_::value>::type>
|
||||
VTKM_EXEC void Set(vtkm::Id index, const ValueType& value) const
|
||||
{
|
||||
vtkm::Id permutedIndex = this->IndexPortal.Get(index);
|
||||
this->ValuePortal.Set(permutedIndex, value);
|
||||
|
@ -26,6 +26,8 @@ namespace internal
|
||||
template <typename PortalType>
|
||||
class VTKM_ALWAYS_EXPORT ArrayPortalReverse
|
||||
{
|
||||
using Writable = vtkm::internal::PortalSupportsSets<PortalType>;
|
||||
|
||||
public:
|
||||
using ValueType = typename PortalType::ValueType;
|
||||
|
||||
@ -56,8 +58,9 @@ public:
|
||||
return this->portal.Get(portal.GetNumberOfValues() - index - 1);
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
void Set(vtkm::Id index, const ValueType& value) const
|
||||
template <typename Writable_ = Writable,
|
||||
typename = typename std::enable_if<Writable_::value>::type>
|
||||
VTKM_EXEC_CONT void Set(vtkm::Id index, const ValueType& value) const
|
||||
{
|
||||
this->portal.Set(portal.GetNumberOfValues() - index - 1, value);
|
||||
}
|
||||
|
@ -23,6 +23,8 @@ namespace internal
|
||||
template <typename P>
|
||||
class VTKM_ALWAYS_EXPORT ArrayPortalStreaming
|
||||
{
|
||||
using Writable = vtkm::internal::PortalSupportsSets<P>;
|
||||
|
||||
public:
|
||||
using PortalType = P;
|
||||
using ValueType = typename PortalType::ValueType;
|
||||
@ -66,8 +68,9 @@ public:
|
||||
return this->InputPortal.Get(this->BlockIndex * this->BlockSize + index);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
void Set(vtkm::Id index, const ValueType& value) const
|
||||
template <typename Writable_ = Writable,
|
||||
typename = typename std::enable_if<Writable_::value>::type>
|
||||
VTKM_CONT void Set(vtkm::Id index, const ValueType& value) const
|
||||
{
|
||||
this->InputPortal.Set(this->BlockIndex * this->BlockSize + index, value);
|
||||
}
|
||||
|
@ -117,6 +117,7 @@ template <typename PortalType, typename ArrayHandleType, vtkm::IdComponent OutSi
|
||||
class VTKM_ALWAYS_EXPORT ArrayPortalSwizzle
|
||||
{
|
||||
using Traits = internal::ArrayHandleSwizzleTraits<ArrayHandleType, OutSize>;
|
||||
using Writable = vtkm::internal::PortalSupportsSets<PortalType>;
|
||||
|
||||
public:
|
||||
using MapType = typename Traits::MapType;
|
||||
@ -143,6 +144,9 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
ArrayPortalSwizzle& operator=(const ArrayPortalSwizzle& src) = default;
|
||||
ArrayPortalSwizzle& operator=(ArrayPortalSwizzle&& src) = default;
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
vtkm::Id GetNumberOfValues() const { return this->Portal.GetNumberOfValues(); }
|
||||
|
||||
@ -154,8 +158,9 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
void Set(vtkm::Id index, const ValueType& value) const
|
||||
template <typename Writable_ = Writable,
|
||||
typename = typename std::enable_if<Writable_::value>::type>
|
||||
VTKM_EXEC_CONT void Set(vtkm::Id index, const ValueType& value) const
|
||||
{
|
||||
if (Traits::AllCompsUsed)
|
||||
{ // No need to prefetch the value, all values overwritten
|
||||
|
@ -90,16 +90,6 @@ public:
|
||||
VTKM_EXEC_CONT
|
||||
ValueType Get(vtkm::Id index) const { return this->Functor(this->Portal.Get(index)); }
|
||||
|
||||
VTKM_SUPPRESS_EXEC_WARNINGS
|
||||
VTKM_EXEC_CONT
|
||||
void Set(vtkm::Id vtkmNotUsed(index), const ValueType& vtkmNotUsed(value)) const
|
||||
{
|
||||
#if !(defined(VTKM_MSVC) && defined(VTKM_CUDA))
|
||||
VTKM_ASSERT(false &&
|
||||
"Cannot write to read-only transform array. (No inverse transform given.)");
|
||||
#endif
|
||||
}
|
||||
|
||||
VTKM_SUPPRESS_EXEC_WARNINGS
|
||||
VTKM_EXEC_CONT
|
||||
const PortalType& GetPortal() const { return this->Portal; }
|
||||
@ -120,6 +110,8 @@ template <typename ValueType_,
|
||||
class VTKM_ALWAYS_EXPORT ArrayPortalTransform
|
||||
: public ArrayPortalTransform<ValueType_, PortalType_, FunctorType_, NullFunctorType>
|
||||
{
|
||||
using Writable = vtkm::internal::PortalSupportsSets<PortalType_>;
|
||||
|
||||
public:
|
||||
using Superclass = ArrayPortalTransform<ValueType_, PortalType_, FunctorType_, NullFunctorType>;
|
||||
using PortalType = PortalType_;
|
||||
@ -147,11 +139,11 @@ public:
|
||||
}
|
||||
|
||||
VTKM_SUPPRESS_EXEC_WARNINGS
|
||||
VTKM_EXEC_CONT
|
||||
void Set(vtkm::Id index, const ValueType& value) const
|
||||
template <typename Writable_ = Writable,
|
||||
typename = typename std::enable_if<Writable_::value>::type>
|
||||
VTKM_EXEC_CONT void Set(vtkm::Id index, const ValueType& value) const
|
||||
{
|
||||
using call_supported_t = typename vtkm::internal::PortalSupportsSets<PortalType>::type;
|
||||
this->Set(call_supported_t(), index, value);
|
||||
this->Portal.Set(index, this->InverseFunctor(value));
|
||||
}
|
||||
|
||||
VTKM_SUPPRESS_EXEC_WARNINGS
|
||||
@ -160,14 +152,6 @@ public:
|
||||
|
||||
private:
|
||||
InverseFunctorType InverseFunctor;
|
||||
|
||||
VTKM_SUPPRESS_EXEC_WARNINGS
|
||||
VTKM_EXEC_CONT
|
||||
inline void Set(std::true_type, vtkm::Id index, const ValueType& value) const
|
||||
{
|
||||
this->Portal.Set(index, this->InverseFunctor(value));
|
||||
}
|
||||
VTKM_EXEC_CONT inline void Set(std::false_type, vtkm::Id, const ValueType&) const {}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,8 @@ namespace internal
|
||||
template <typename TargetPortalType>
|
||||
class ArrayPortalView
|
||||
{
|
||||
using Writable = vtkm::internal::PortalSupportsSets<TargetPortalType>;
|
||||
|
||||
public:
|
||||
using ValueType = typename TargetPortalType::ValueType;
|
||||
|
||||
@ -59,8 +61,9 @@ public:
|
||||
ValueType Get(vtkm::Id index) const { return this->TargetPortal.Get(index + this->StartIndex); }
|
||||
|
||||
VTKM_SUPPRESS_EXEC_WARNINGS
|
||||
VTKM_EXEC_CONT
|
||||
void Set(vtkm::Id index, const ValueType& value) const
|
||||
template <typename Writable_ = Writable,
|
||||
typename = typename std::enable_if<Writable_::value>::type>
|
||||
VTKM_EXEC_CONT void Set(vtkm::Id index, const ValueType& value) const
|
||||
{
|
||||
this->TargetPortal.Set(index + this->StartIndex, value);
|
||||
}
|
||||
|
@ -26,6 +26,14 @@ namespace internal
|
||||
template <typename ValueType_, typename PortalTypeFirst_, typename PortalTypeSecond_>
|
||||
class ArrayPortalZip
|
||||
{
|
||||
using ReadableP1 = vtkm::internal::PortalSupportsGets<PortalTypeFirst_>;
|
||||
using ReadableP2 = vtkm::internal::PortalSupportsGets<PortalTypeSecond_>;
|
||||
using WritableP1 = vtkm::internal::PortalSupportsSets<PortalTypeFirst_>;
|
||||
using WritableP2 = vtkm::internal::PortalSupportsSets<PortalTypeSecond_>;
|
||||
|
||||
using Readable = std::integral_constant<bool, ReadableP1::value && ReadableP2::value>;
|
||||
using Writable = std::integral_constant<bool, WritableP1::value && WritableP2::value>;
|
||||
|
||||
public:
|
||||
using ValueType = ValueType_;
|
||||
using T = typename ValueType::FirstType;
|
||||
@ -64,23 +72,19 @@ public:
|
||||
VTKM_EXEC_CONT
|
||||
vtkm::Id GetNumberOfValues() const { return this->PortalFirst.GetNumberOfValues(); }
|
||||
|
||||
VTKM_EXEC
|
||||
ValueType Get(vtkm::Id index) const
|
||||
template <typename Readable_ = Readable,
|
||||
typename = typename std::enable_if<Readable_::value>::type>
|
||||
VTKM_EXEC_CONT ValueType Get(vtkm::Id index) const noexcept
|
||||
{
|
||||
using call_supported_t1 = typename vtkm::internal::PortalSupportsGets<PortalTypeFirst>::type;
|
||||
using call_supported_t2 = typename vtkm::internal::PortalSupportsGets<PortalTypeSecond>::type;
|
||||
|
||||
return vtkm::make_Pair(this->GetFirst(call_supported_t1(), index),
|
||||
this->GetSecond(call_supported_t2(), index));
|
||||
return vtkm::make_Pair(this->PortalFirst.Get(index), this->PortalSecond.Get(index));
|
||||
}
|
||||
|
||||
VTKM_EXEC
|
||||
void Set(vtkm::Id index, const ValueType& value) const
|
||||
template <typename Writable_ = Writable,
|
||||
typename = typename std::enable_if<Writable_::value>::type>
|
||||
VTKM_EXEC_CONT void Set(vtkm::Id index, const ValueType& value) const noexcept
|
||||
{
|
||||
using call_supported_t1 = typename vtkm::internal::PortalSupportsSets<PortalTypeFirst>::type;
|
||||
using call_supported_t2 = typename vtkm::internal::PortalSupportsSets<PortalTypeSecond>::type;
|
||||
this->SetFirst(call_supported_t1(), index, value.first);
|
||||
this->SetSecond(call_supported_t2(), index, value.second);
|
||||
this->PortalFirst.Set(index, value.first);
|
||||
this->PortalSecond.Set(index, value.second);
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
@ -90,28 +94,6 @@ public:
|
||||
const PortalTypeSecond& GetSecondPortal() const { return this->PortalSecond; }
|
||||
|
||||
private:
|
||||
VTKM_EXEC inline T GetFirst(std::true_type, vtkm::Id index) const noexcept
|
||||
{
|
||||
return this->PortalFirst.Get(index);
|
||||
}
|
||||
VTKM_EXEC inline T GetFirst(std::false_type, vtkm::Id) const noexcept { return T{}; }
|
||||
VTKM_EXEC inline U GetSecond(std::true_type, vtkm::Id index) const noexcept
|
||||
{
|
||||
return this->PortalSecond.Get(index);
|
||||
}
|
||||
VTKM_EXEC inline U GetSecond(std::false_type, vtkm::Id) const noexcept { return U{}; }
|
||||
|
||||
VTKM_EXEC inline void SetFirst(std::true_type, vtkm::Id index, const T& value) const noexcept
|
||||
{
|
||||
this->PortalFirst.Set(index, value);
|
||||
}
|
||||
VTKM_EXEC inline void SetFirst(std::false_type, vtkm::Id, const T&) const noexcept {}
|
||||
VTKM_EXEC inline void SetSecond(std::true_type, vtkm::Id index, const U& value) const noexcept
|
||||
{
|
||||
this->PortalSecond.Set(index, value);
|
||||
}
|
||||
VTKM_EXEC inline void SetSecond(std::false_type, vtkm::Id, const U&) const noexcept {}
|
||||
|
||||
PortalTypeFirst PortalFirst;
|
||||
PortalTypeSecond PortalSecond;
|
||||
};
|
||||
|
@ -45,6 +45,12 @@ namespace cont
|
||||
/// Although portals are defined in the execution environment, they are also
|
||||
/// used in the control environment for accessing data on the host.
|
||||
///
|
||||
/// Since utilities like IsWritableArrayHandle checks for the existence of a Set
|
||||
/// method on a portal, if the portal is backed by a read-only ArrayHandle, the
|
||||
/// Set method must not be defined. If the portal may or may not be writable
|
||||
/// (e.g., ArrayHandleCast may be casting a read-only OR read-write array), the
|
||||
/// Set method may be conditionally removed using SFINAE.
|
||||
///
|
||||
template <typename T>
|
||||
class ArrayPortal
|
||||
{
|
||||
@ -65,8 +71,7 @@ public:
|
||||
ValueType Get(vtkm::Id index) const;
|
||||
|
||||
/// Sets a value in the array. If it is not possible to set a value in the
|
||||
/// array, this method may error out (for example with a VTKM_ASSERT). In
|
||||
/// this case the behavior is undefined.
|
||||
/// array, this method must not be defined.
|
||||
///
|
||||
VTKM_EXEC_CONT
|
||||
void Set(vtkm::Id index, const ValueType& value) const;
|
||||
|
@ -211,7 +211,7 @@ if(TARGET vtkm::openmp)
|
||||
endif()
|
||||
|
||||
target_link_libraries(vtkm_cont PUBLIC vtkm_compiler_flags ${backends})
|
||||
target_link_libraries(vtkm_cont PUBLIC vtkm_taotuple vtkm_optionparser vtkm_diy)
|
||||
target_link_libraries(vtkm_cont PUBLIC vtkm_taotuple vtkm_optionparser vtkm_diy vtkm_lcl)
|
||||
if(TARGET vtkm_loguru)
|
||||
target_link_libraries(vtkm_cont PRIVATE vtkm_loguru)
|
||||
endif()
|
||||
|
@ -29,7 +29,7 @@ template <vtkm::IdComponent>
|
||||
class CellSetStructured;
|
||||
template <typename T>
|
||||
class CellSetSingleType;
|
||||
template <typename T, typename S, typename U, typename V>
|
||||
template <typename T, typename S, typename U>
|
||||
class CellSetExplicit;
|
||||
template <typename T, typename S>
|
||||
class CellSetPermutation;
|
||||
@ -88,10 +88,8 @@ void CastAndCall(const vtkm::cont::CellSetSingleType<ConnectivityStorageTag>& ce
|
||||
/// A specialization of CastAndCall for basic CellSetExplicit types,
|
||||
/// Since the type is already known no deduction is needed.
|
||||
/// This specialization is used to simplify numerous worklet algorithms
|
||||
template <typename T, typename S, typename U, typename V, typename Functor, typename... Args>
|
||||
void CastAndCall(const vtkm::cont::CellSetExplicit<T, S, U, V>& cellset,
|
||||
Functor&& f,
|
||||
Args&&... args)
|
||||
template <typename T, typename S, typename U, typename Functor, typename... Args>
|
||||
void CastAndCall(const vtkm::cont::CellSetExplicit<T, S, U>& cellset, Functor&& f, Args&&... args)
|
||||
{
|
||||
f(cellset, std::forward<Args>(args)...);
|
||||
}
|
||||
|
@ -19,7 +19,6 @@ namespace cont
|
||||
template class VTKM_CONT_EXPORT CellSetExplicit<>; // default
|
||||
template class VTKM_CONT_EXPORT
|
||||
CellSetExplicit<typename vtkm::cont::ArrayHandleConstant<vtkm::UInt8>::StorageTag,
|
||||
typename vtkm::cont::ArrayHandleConstant<vtkm::IdComponent>::StorageTag,
|
||||
VTKM_DEFAULT_CONNECTIVITY_STORAGE_TAG,
|
||||
typename vtkm::cont::ArrayHandleCounting<vtkm::Id>::StorageTag>;
|
||||
}
|
||||
|
@ -12,8 +12,11 @@
|
||||
|
||||
#include <vtkm/CellShape.h>
|
||||
#include <vtkm/TopologyElementTag.h>
|
||||
#include <vtkm/cont/ArrayGetValues.h>
|
||||
#include <vtkm/cont/ArrayHandleCast.h>
|
||||
#include <vtkm/cont/ArrayHandleConstant.h>
|
||||
#include <vtkm/cont/ArrayHandleCounting.h>
|
||||
#include <vtkm/cont/ArrayHandleDecorator.h>
|
||||
#include <vtkm/cont/CellSet.h>
|
||||
#include <vtkm/cont/internal/ConnectivityExplicitInternals.h>
|
||||
#include <vtkm/exec/ConnectivityExplicit.h>
|
||||
@ -34,14 +37,35 @@ struct CellSetExplicitConnectivityChooser
|
||||
using ConnectivityType = vtkm::cont::internal::ConnectivityExplicitInternals<>;
|
||||
};
|
||||
|
||||
// Used with ArrayHandleDecorator to recover the NumIndices array from the
|
||||
// offsets.
|
||||
struct NumIndicesDecorator
|
||||
{
|
||||
template <typename OffsetsPortal>
|
||||
struct Functor
|
||||
{
|
||||
OffsetsPortal Offsets;
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
vtkm::IdComponent operator()(vtkm::Id cellId) const
|
||||
{
|
||||
return static_cast<vtkm::IdComponent>(this->Offsets.Get(cellId + 1) -
|
||||
this->Offsets.Get(cellId));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename OffsetsPortal>
|
||||
static VTKM_CONT Functor<typename std::decay<OffsetsPortal>::type> CreateFunctor(
|
||||
OffsetsPortal&& portal)
|
||||
{
|
||||
return { std::forward<OffsetsPortal>(portal) };
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
#ifndef VTKM_DEFAULT_SHAPE_STORAGE_TAG
|
||||
#define VTKM_DEFAULT_SHAPE_STORAGE_TAG VTKM_DEFAULT_STORAGE_TAG
|
||||
#endif
|
||||
|
||||
#ifndef VTKM_DEFAULT_NUM_INDICES_STORAGE_TAG
|
||||
#define VTKM_DEFAULT_NUM_INDICES_STORAGE_TAG VTKM_DEFAULT_STORAGE_TAG
|
||||
#ifndef VTKM_DEFAULT_SHAPES_STORAGE_TAG
|
||||
#define VTKM_DEFAULT_SHAPES_STORAGE_TAG VTKM_DEFAULT_STORAGE_TAG
|
||||
#endif
|
||||
|
||||
#ifndef VTKM_DEFAULT_CONNECTIVITY_STORAGE_TAG
|
||||
@ -52,51 +76,89 @@ struct CellSetExplicitConnectivityChooser
|
||||
#define VTKM_DEFAULT_OFFSETS_STORAGE_TAG VTKM_DEFAULT_STORAGE_TAG
|
||||
#endif
|
||||
|
||||
template <typename ShapeStorageTag = VTKM_DEFAULT_SHAPE_STORAGE_TAG,
|
||||
typename NumIndicesStorageTag = VTKM_DEFAULT_NUM_INDICES_STORAGE_TAG,
|
||||
template <typename S1, typename S2>
|
||||
void ConvertNumIndicesToOffsets(const vtkm::cont::ArrayHandle<vtkm::Id, S1>& numIndices,
|
||||
vtkm::cont::ArrayHandle<vtkm::Id, S2>& offsets)
|
||||
{
|
||||
vtkm::cont::Algorithm::ScanExtended(numIndices, offsets);
|
||||
}
|
||||
|
||||
template <typename T, typename S1, typename S2>
|
||||
void ConvertNumIndicesToOffsets(const vtkm::cont::ArrayHandle<T, S1>& numIndices,
|
||||
vtkm::cont::ArrayHandle<vtkm::Id, S2>& offsets)
|
||||
{
|
||||
const auto castCounts = vtkm::cont::make_ArrayHandleCast<vtkm::Id>(numIndices);
|
||||
ConvertNumIndicesToOffsets(castCounts, offsets);
|
||||
}
|
||||
|
||||
template <typename T, typename S1, typename S2>
|
||||
void ConvertNumIndicesToOffsets(const vtkm::cont::ArrayHandle<T, S1>& numIndices,
|
||||
vtkm::cont::ArrayHandle<vtkm::Id, S2>& offsets,
|
||||
vtkm::Id& connectivitySize /* outparam */)
|
||||
{
|
||||
ConvertNumIndicesToOffsets(numIndices, offsets);
|
||||
connectivitySize = vtkm::cont::ArrayGetValue(offsets.GetNumberOfValues() - 1, offsets);
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> ConvertNumIndicesToOffsets(
|
||||
const vtkm::cont::ArrayHandle<T, S>& numIndices)
|
||||
{
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> offsets;
|
||||
ConvertNumIndicesToOffsets(numIndices, offsets);
|
||||
return offsets;
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> ConvertNumIndicesToOffsets(
|
||||
const vtkm::cont::ArrayHandle<T, S>& numIndices,
|
||||
vtkm::Id& connectivityLength /* outparam */)
|
||||
{
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> offsets;
|
||||
ConvertNumIndicesToOffsets(numIndices, offsets, connectivityLength);
|
||||
return offsets;
|
||||
}
|
||||
|
||||
template <typename ShapesStorageTag = VTKM_DEFAULT_SHAPES_STORAGE_TAG,
|
||||
typename ConnectivityStorageTag = VTKM_DEFAULT_CONNECTIVITY_STORAGE_TAG,
|
||||
typename OffsetsStorageTag = VTKM_DEFAULT_OFFSETS_STORAGE_TAG>
|
||||
class VTKM_ALWAYS_EXPORT CellSetExplicit : public CellSet
|
||||
{
|
||||
using Thisclass = CellSetExplicit<ShapeStorageTag,
|
||||
NumIndicesStorageTag,
|
||||
ConnectivityStorageTag,
|
||||
OffsetsStorageTag>;
|
||||
using Thisclass = CellSetExplicit<ShapesStorageTag, ConnectivityStorageTag, OffsetsStorageTag>;
|
||||
|
||||
template <typename VisitTopology, typename IncidentTopology>
|
||||
struct ConnectivityChooser
|
||||
{
|
||||
using ConnectivityType =
|
||||
typename detail::CellSetExplicitConnectivityChooser<Thisclass,
|
||||
VisitTopology,
|
||||
IncidentTopology>::ConnectivityType;
|
||||
private:
|
||||
using Chooser = typename detail::CellSetExplicitConnectivityChooser<Thisclass,
|
||||
VisitTopology,
|
||||
IncidentTopology>;
|
||||
|
||||
using ShapeArrayType = typename ConnectivityType::ShapeArrayType;
|
||||
using NumIndicesArrayType = typename ConnectivityType::NumIndicesArrayType;
|
||||
public:
|
||||
using ConnectivityType = typename Chooser::ConnectivityType;
|
||||
using ShapesArrayType = typename ConnectivityType::ShapesArrayType;
|
||||
using ConnectivityArrayType = typename ConnectivityType::ConnectivityArrayType;
|
||||
using IndexOffsetArrayType = typename ConnectivityType::IndexOffsetArrayType;
|
||||
using OffsetsArrayType = typename ConnectivityType::OffsetsArrayType;
|
||||
|
||||
using NumIndicesArrayType =
|
||||
vtkm::cont::ArrayHandleDecorator<detail::NumIndicesDecorator, OffsetsArrayType>;
|
||||
};
|
||||
|
||||
using VisitCellsWithPointsInternalsType =
|
||||
typename ConnectivityChooser<vtkm::TopologyElementTagCell,
|
||||
vtkm::TopologyElementTagPoint>::ConnectivityType;
|
||||
using ConnTypes =
|
||||
ConnectivityChooser<vtkm::TopologyElementTagCell, vtkm::TopologyElementTagPoint>;
|
||||
using RConnTypes =
|
||||
ConnectivityChooser<vtkm::TopologyElementTagPoint, vtkm::TopologyElementTagCell>;
|
||||
|
||||
using VisitPointsWithCellsInternalsType =
|
||||
typename ConnectivityChooser<vtkm::TopologyElementTagPoint,
|
||||
vtkm::TopologyElementTagCell>::ConnectivityType;
|
||||
using CellPointIdsType = typename ConnTypes::ConnectivityType;
|
||||
using PointCellIdsType = typename RConnTypes::ConnectivityType;
|
||||
|
||||
public:
|
||||
using SchedulingRangeType = vtkm::Id;
|
||||
|
||||
//point to cell is used when iterating cells and asking for point properties
|
||||
using VisitCellsWithPointsConnectivityType =
|
||||
ConnectivityChooser<vtkm::TopologyElementTagCell, vtkm::TopologyElementTagPoint>;
|
||||
|
||||
using ShapeArrayType = typename VisitCellsWithPointsConnectivityType::ShapeArrayType;
|
||||
using NumIndicesArrayType = typename VisitCellsWithPointsConnectivityType::NumIndicesArrayType;
|
||||
using ConnectivityArrayType =
|
||||
typename VisitCellsWithPointsConnectivityType::ConnectivityArrayType;
|
||||
using IndexOffsetArrayType = typename VisitCellsWithPointsConnectivityType::IndexOffsetArrayType;
|
||||
using ShapesArrayType = typename CellPointIdsType::ShapesArrayType;
|
||||
using ConnectivityArrayType = typename CellPointIdsType::ConnectivityArrayType;
|
||||
using OffsetsArrayType = typename CellPointIdsType::OffsetsArrayType;
|
||||
using NumIndicesArrayType = typename ConnTypes::NumIndicesArrayType;
|
||||
|
||||
VTKM_CONT CellSetExplicit();
|
||||
VTKM_CONT CellSetExplicit(const Thisclass& src);
|
||||
@ -105,28 +167,29 @@ public:
|
||||
VTKM_CONT Thisclass& operator=(const Thisclass& src);
|
||||
VTKM_CONT Thisclass& operator=(Thisclass&& src) noexcept;
|
||||
|
||||
virtual ~CellSetExplicit();
|
||||
VTKM_CONT virtual ~CellSetExplicit();
|
||||
|
||||
vtkm::Id GetNumberOfCells() const override;
|
||||
vtkm::Id GetNumberOfPoints() const override;
|
||||
vtkm::Id GetNumberOfFaces() const override;
|
||||
vtkm::Id GetNumberOfEdges() const override;
|
||||
void PrintSummary(std::ostream& out) const override;
|
||||
void ReleaseResourcesExecution() override;
|
||||
VTKM_CONT vtkm::Id GetNumberOfCells() const override;
|
||||
VTKM_CONT vtkm::Id GetNumberOfPoints() const override;
|
||||
VTKM_CONT vtkm::Id GetNumberOfFaces() const override;
|
||||
VTKM_CONT vtkm::Id GetNumberOfEdges() const override;
|
||||
VTKM_CONT void PrintSummary(std::ostream& out) const override;
|
||||
|
||||
std::shared_ptr<CellSet> NewInstance() const override;
|
||||
void DeepCopy(const CellSet* src) override;
|
||||
VTKM_CONT void ReleaseResourcesExecution() override;
|
||||
|
||||
VTKM_CONT std::shared_ptr<CellSet> NewInstance() const override;
|
||||
VTKM_CONT void DeepCopy(const CellSet* src) override;
|
||||
|
||||
VTKM_CONT vtkm::Id GetSchedulingRange(vtkm::TopologyElementTagCell) const;
|
||||
VTKM_CONT vtkm::Id GetSchedulingRange(vtkm::TopologyElementTagPoint) const;
|
||||
|
||||
VTKM_CONT vtkm::IdComponent GetNumberOfPointsInCell(vtkm::Id cellIndex) const override;
|
||||
void GetCellPointIds(vtkm::Id id, vtkm::Id* ptids) const override;
|
||||
VTKM_CONT vtkm::IdComponent GetNumberOfPointsInCell(vtkm::Id cellid) const override;
|
||||
VTKM_CONT void GetCellPointIds(vtkm::Id id, vtkm::Id* ptids) const override;
|
||||
|
||||
VTKM_CONT vtkm::UInt8 GetCellShape(vtkm::Id cellIndex) const override;
|
||||
VTKM_CONT vtkm::UInt8 GetCellShape(vtkm::Id cellid) const override;
|
||||
|
||||
template <vtkm::IdComponent ItemTupleLength>
|
||||
VTKM_CONT void GetIndices(vtkm::Id index, vtkm::Vec<vtkm::Id, ItemTupleLength>& ids) const;
|
||||
template <vtkm::IdComponent NumIndices>
|
||||
VTKM_CONT void GetIndices(vtkm::Id index, vtkm::Vec<vtkm::Id, NumIndices>& ids) const;
|
||||
|
||||
VTKM_CONT void GetIndices(vtkm::Id index, vtkm::cont::ArrayHandle<vtkm::Id>& ids) const;
|
||||
|
||||
@ -143,74 +206,69 @@ public:
|
||||
/// the way you can fill the memory from another system without copying
|
||||
VTKM_CONT
|
||||
void Fill(vtkm::Id numPoints,
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8, ShapeStorageTag>& cellTypes,
|
||||
const vtkm::cont::ArrayHandle<vtkm::IdComponent, NumIndicesStorageTag>& numIndices,
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8, ShapesStorageTag>& cellTypes,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id, ConnectivityStorageTag>& connectivity,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id, OffsetsStorageTag>& offsets =
|
||||
vtkm::cont::ArrayHandle<vtkm::Id, OffsetsStorageTag>());
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id, OffsetsStorageTag>& offsets);
|
||||
|
||||
template <typename DeviceAdapter, typename VisitTopology, typename IncidentTopology>
|
||||
template <typename Device, typename VisitTopology, typename IncidentTopology>
|
||||
struct ExecutionTypes
|
||||
{
|
||||
VTKM_IS_DEVICE_ADAPTER_TAG(DeviceAdapter);
|
||||
private:
|
||||
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
||||
VTKM_IS_TOPOLOGY_ELEMENT_TAG(VisitTopology);
|
||||
VTKM_IS_TOPOLOGY_ELEMENT_TAG(IncidentTopology);
|
||||
|
||||
using ConnectivityTypes = ConnectivityChooser<VisitTopology, IncidentTopology>;
|
||||
using Chooser = ConnectivityChooser<VisitTopology, IncidentTopology>;
|
||||
|
||||
using ShapePortalType = typename ConnectivityTypes::ShapeArrayType::template ExecutionTypes<
|
||||
DeviceAdapter>::PortalConst;
|
||||
using IndicePortalType =
|
||||
typename ConnectivityTypes::NumIndicesArrayType::template ExecutionTypes<
|
||||
DeviceAdapter>::PortalConst;
|
||||
using ConnectivityPortalType =
|
||||
typename ConnectivityTypes::ConnectivityArrayType::template ExecutionTypes<
|
||||
DeviceAdapter>::PortalConst;
|
||||
using IndexOffsetPortalType =
|
||||
typename ConnectivityTypes::IndexOffsetArrayType::template ExecutionTypes<
|
||||
DeviceAdapter>::PortalConst;
|
||||
using ShapesAT = typename Chooser::ShapesArrayType;
|
||||
using ConnAT = typename Chooser::ConnectivityArrayType;
|
||||
using OffsetsAT = typename Chooser::OffsetsArrayType;
|
||||
|
||||
using ExecObjectType = vtkm::exec::ConnectivityExplicit<ShapePortalType,
|
||||
IndicePortalType,
|
||||
ConnectivityPortalType,
|
||||
IndexOffsetPortalType>;
|
||||
using ShapesET = typename ShapesAT::template ExecutionTypes<Device>;
|
||||
using ConnET = typename ConnAT::template ExecutionTypes<Device>;
|
||||
using OffsetsET = typename OffsetsAT::template ExecutionTypes<Device>;
|
||||
|
||||
public:
|
||||
using ShapesPortalType = typename ShapesET::PortalConst;
|
||||
using ConnectivityPortalType = typename ConnET::PortalConst;
|
||||
using OffsetsPortalType = typename OffsetsET::PortalConst;
|
||||
|
||||
using ExecObjectType =
|
||||
vtkm::exec::ConnectivityExplicit<ShapesPortalType, ConnectivityPortalType, OffsetsPortalType>;
|
||||
};
|
||||
|
||||
template <typename Device, typename VisitTopology, typename IncidentTopology>
|
||||
typename ExecutionTypes<Device, VisitTopology, IncidentTopology>::ExecObjectType
|
||||
VTKM_CONT typename ExecutionTypes<Device, VisitTopology, IncidentTopology>::ExecObjectType
|
||||
PrepareForInput(Device, VisitTopology, IncidentTopology) const;
|
||||
|
||||
template <typename VisitTopology, typename IncidentTopology>
|
||||
VTKM_CONT const typename ConnectivityChooser<VisitTopology, IncidentTopology>::ShapeArrayType&
|
||||
VTKM_CONT const typename ConnectivityChooser<VisitTopology, IncidentTopology>::ShapesArrayType&
|
||||
GetShapesArray(VisitTopology, IncidentTopology) const;
|
||||
|
||||
template <typename VisitTopology, typename IncidentTopology>
|
||||
VTKM_CONT const typename ConnectivityChooser<VisitTopology,
|
||||
IncidentTopology>::NumIndicesArrayType&
|
||||
GetNumIndicesArray(VisitTopology, IncidentTopology) const;
|
||||
|
||||
template <typename VisitTopology, typename IncidentTopology>
|
||||
VTKM_CONT const typename ConnectivityChooser<VisitTopology,
|
||||
IncidentTopology>::ConnectivityArrayType&
|
||||
GetConnectivityArray(VisitTopology, IncidentTopology) const;
|
||||
|
||||
template <typename VisitTopology, typename IncidentTopology>
|
||||
VTKM_CONT const typename ConnectivityChooser<VisitTopology,
|
||||
IncidentTopology>::IndexOffsetArrayType&
|
||||
GetIndexOffsetArray(VisitTopology, IncidentTopology) const;
|
||||
VTKM_CONT const typename ConnectivityChooser<VisitTopology, IncidentTopology>::OffsetsArrayType&
|
||||
GetOffsetsArray(VisitTopology, IncidentTopology) const;
|
||||
|
||||
// Can be used to check if e.g. CellToPoint table is built.
|
||||
template <typename VisitTopology, typename IncidentTopology>
|
||||
VTKM_CONT bool HasConnectivity(VisitTopology from, IncidentTopology to) const
|
||||
VTKM_CONT typename ConnectivityChooser<VisitTopology, IncidentTopology>::NumIndicesArrayType
|
||||
GetNumIndicesArray(VisitTopology, IncidentTopology) const;
|
||||
|
||||
template <typename VisitTopology, typename IncidentTopology>
|
||||
VTKM_CONT bool HasConnectivity(VisitTopology visit, IncidentTopology incident) const
|
||||
{
|
||||
return this->HasConnectivityImpl(from, to);
|
||||
return this->HasConnectivityImpl(visit, incident);
|
||||
}
|
||||
|
||||
// Can be used to reset a connectivity table, mostly useful for benchmarking.
|
||||
template <typename VisitTopology, typename IncidentTopology>
|
||||
VTKM_CONT void ResetConnectivity(VisitTopology from, IncidentTopology to)
|
||||
VTKM_CONT void ResetConnectivity(VisitTopology visit, IncidentTopology incident)
|
||||
{
|
||||
this->ResetConnectivityImpl(from, to);
|
||||
this->ResetConnectivityImpl(visit, incident);
|
||||
}
|
||||
|
||||
protected:
|
||||
@ -225,20 +283,20 @@ protected:
|
||||
VTKM_CONT bool HasConnectivityImpl(vtkm::TopologyElementTagCell,
|
||||
vtkm::TopologyElementTagPoint) const
|
||||
{
|
||||
return this->Data->VisitCellsWithPoints.ElementsValid;
|
||||
return this->Data->CellPointIds.ElementsValid;
|
||||
}
|
||||
|
||||
VTKM_CONT bool HasConnectivityImpl(vtkm::TopologyElementTagPoint,
|
||||
vtkm::TopologyElementTagCell) const
|
||||
{
|
||||
return this->Data->VisitPointsWithCells.ElementsValid;
|
||||
return this->Data->PointCellIds.ElementsValid;
|
||||
}
|
||||
|
||||
VTKM_CONT void ResetConnectivityImpl(vtkm::TopologyElementTagCell, vtkm::TopologyElementTagPoint)
|
||||
{
|
||||
// Reset entire cell set
|
||||
this->Data->VisitCellsWithPoints = VisitCellsWithPointsInternalsType{};
|
||||
this->Data->VisitPointsWithCells = VisitPointsWithCellsInternalsType{};
|
||||
this->Data->CellPointIds = CellPointIdsType{};
|
||||
this->Data->PointCellIds = PointCellIdsType{};
|
||||
this->Data->ConnectivityAdded = -1;
|
||||
this->Data->NumberOfCellsAdded = -1;
|
||||
this->Data->NumberOfPoints = 0;
|
||||
@ -246,15 +304,15 @@ protected:
|
||||
|
||||
VTKM_CONT void ResetConnectivityImpl(vtkm::TopologyElementTagPoint, vtkm::TopologyElementTagCell)
|
||||
{
|
||||
this->Data->VisitPointsWithCells = VisitPointsWithCellsInternalsType{};
|
||||
this->Data->PointCellIds = PointCellIdsType{};
|
||||
}
|
||||
|
||||
// Store internals in a shared pointer so shallow copies stay consistent.
|
||||
// See #2268.
|
||||
struct Internals
|
||||
{
|
||||
VisitCellsWithPointsInternalsType VisitCellsWithPoints;
|
||||
VisitPointsWithCellsInternalsType VisitPointsWithCells;
|
||||
CellPointIdsType CellPointIds;
|
||||
PointCellIdsType PointCellIds;
|
||||
|
||||
// These are used in the AddCell and related methods to incrementally add
|
||||
// cells. They need to be protected as subclasses of CellSetExplicit
|
||||
@ -275,42 +333,45 @@ protected:
|
||||
std::shared_ptr<Internals> Data;
|
||||
|
||||
private:
|
||||
const VisitCellsWithPointsInternalsType& GetConnectivity(vtkm::TopologyElementTagCell,
|
||||
vtkm::TopologyElementTagPoint) const
|
||||
VTKM_CONT
|
||||
const CellPointIdsType& GetConnectivity(vtkm::TopologyElementTagCell,
|
||||
vtkm::TopologyElementTagPoint) const
|
||||
{
|
||||
return this->Data->VisitCellsWithPoints;
|
||||
return this->Data->CellPointIds;
|
||||
}
|
||||
|
||||
const VisitCellsWithPointsInternalsType& GetConnectivity(vtkm::TopologyElementTagCell,
|
||||
vtkm::TopologyElementTagPoint)
|
||||
VTKM_CONT
|
||||
const CellPointIdsType& GetConnectivity(vtkm::TopologyElementTagCell,
|
||||
vtkm::TopologyElementTagPoint)
|
||||
{
|
||||
return this->Data->VisitCellsWithPoints;
|
||||
return this->Data->CellPointIds;
|
||||
}
|
||||
|
||||
const VisitPointsWithCellsInternalsType& GetConnectivity(vtkm::TopologyElementTagPoint,
|
||||
vtkm::TopologyElementTagCell) const
|
||||
VTKM_CONT
|
||||
const PointCellIdsType& GetConnectivity(vtkm::TopologyElementTagPoint,
|
||||
vtkm::TopologyElementTagCell) const
|
||||
{
|
||||
return this->Data->VisitPointsWithCells;
|
||||
return this->Data->PointCellIds;
|
||||
}
|
||||
|
||||
const VisitPointsWithCellsInternalsType& GetConnectivity(vtkm::TopologyElementTagPoint,
|
||||
vtkm::TopologyElementTagCell)
|
||||
VTKM_CONT
|
||||
const PointCellIdsType& GetConnectivity(vtkm::TopologyElementTagPoint,
|
||||
vtkm::TopologyElementTagCell)
|
||||
{
|
||||
return this->Data->VisitPointsWithCells;
|
||||
return this->Data->PointCellIds;
|
||||
}
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <typename Storage1, typename Storage2, typename Storage3, typename Storage4>
|
||||
struct CellSetExplicitConnectivityChooser<
|
||||
vtkm::cont::CellSetExplicit<Storage1, Storage2, Storage3, Storage4>,
|
||||
vtkm::TopologyElementTagCell,
|
||||
vtkm::TopologyElementTagPoint>
|
||||
template <typename Storage1, typename Storage2, typename Storage3>
|
||||
struct CellSetExplicitConnectivityChooser<vtkm::cont::CellSetExplicit<Storage1, Storage2, Storage3>,
|
||||
vtkm::TopologyElementTagCell,
|
||||
vtkm::TopologyElementTagPoint>
|
||||
{
|
||||
using ConnectivityType =
|
||||
vtkm::cont::internal::ConnectivityExplicitInternals<Storage1, Storage2, Storage3, Storage4>;
|
||||
vtkm::cont::internal::ConnectivityExplicitInternals<Storage1, Storage2, Storage3>;
|
||||
};
|
||||
|
||||
template <typename CellSetType>
|
||||
@ -332,7 +393,6 @@ struct CellSetExplicitConnectivityChooser<CellSetType,
|
||||
extern template class VTKM_CONT_TEMPLATE_EXPORT CellSetExplicit<>; // default
|
||||
extern template class VTKM_CONT_TEMPLATE_EXPORT CellSetExplicit<
|
||||
typename vtkm::cont::ArrayHandleConstant<vtkm::UInt8>::StorageTag,
|
||||
typename vtkm::cont::ArrayHandleConstant<vtkm::IdComponent>::StorageTag,
|
||||
VTKM_DEFAULT_CONNECTIVITY_STORAGE_TAG,
|
||||
typename vtkm::cont::ArrayHandleCounting<vtkm::Id>::StorageTag>; // CellSetSingleType base
|
||||
#endif
|
||||
@ -348,17 +408,15 @@ namespace vtkm
|
||||
namespace cont
|
||||
{
|
||||
|
||||
template <typename ShapeST, typename CountST, typename ConnectivityST, typename OffsetST>
|
||||
struct SerializableTypeString<
|
||||
vtkm::cont::CellSetExplicit<ShapeST, CountST, ConnectivityST, OffsetST>>
|
||||
template <typename SST, typename CST, typename OST>
|
||||
struct SerializableTypeString<vtkm::cont::CellSetExplicit<SST, CST, OST>>
|
||||
{
|
||||
static VTKM_CONT const std::string& Get()
|
||||
{
|
||||
static std::string name = "CS_Explicit<" +
|
||||
SerializableTypeString<vtkm::cont::ArrayHandle<vtkm::UInt8, ShapeST>>::Get() + "_ST," +
|
||||
SerializableTypeString<vtkm::cont::ArrayHandle<vtkm::IdComponent, CountST>>::Get() + "_ST," +
|
||||
SerializableTypeString<vtkm::cont::ArrayHandle<vtkm::Id, ConnectivityST>>::Get() + "_ST," +
|
||||
SerializableTypeString<vtkm::cont::ArrayHandle<vtkm::Id, OffsetST>>::Get() + "_ST>";
|
||||
SerializableTypeString<vtkm::cont::ArrayHandle<vtkm::UInt8, SST>>::Get() + "_ST," +
|
||||
SerializableTypeString<vtkm::cont::ArrayHandle<vtkm::Id, CST>>::Get() + "_ST," +
|
||||
SerializableTypeString<vtkm::cont::ArrayHandle<vtkm::Id, OST>>::Get() + "_ST>";
|
||||
|
||||
return name;
|
||||
}
|
||||
@ -369,11 +427,11 @@ struct SerializableTypeString<
|
||||
namespace mangled_diy_namespace
|
||||
{
|
||||
|
||||
template <typename ShapeST, typename CountST, typename ConnectivityST, typename OffsetST>
|
||||
struct Serialization<vtkm::cont::CellSetExplicit<ShapeST, CountST, ConnectivityST, OffsetST>>
|
||||
template <typename SST, typename CST, typename OST>
|
||||
struct Serialization<vtkm::cont::CellSetExplicit<SST, CST, OST>>
|
||||
{
|
||||
private:
|
||||
using Type = vtkm::cont::CellSetExplicit<ShapeST, CountST, ConnectivityST, OffsetST>;
|
||||
using Type = vtkm::cont::CellSetExplicit<SST, CST, OST>;
|
||||
|
||||
public:
|
||||
static VTKM_CONT void save(BinaryBuffer& bb, const Type& cs)
|
||||
@ -381,29 +439,25 @@ public:
|
||||
vtkmdiy::save(bb, cs.GetNumberOfPoints());
|
||||
vtkmdiy::save(
|
||||
bb, cs.GetShapesArray(vtkm::TopologyElementTagCell{}, vtkm::TopologyElementTagPoint{}));
|
||||
vtkmdiy::save(
|
||||
bb, cs.GetNumIndicesArray(vtkm::TopologyElementTagCell{}, vtkm::TopologyElementTagPoint{}));
|
||||
vtkmdiy::save(
|
||||
bb, cs.GetConnectivityArray(vtkm::TopologyElementTagCell{}, vtkm::TopologyElementTagPoint{}));
|
||||
vtkmdiy::save(
|
||||
bb, cs.GetIndexOffsetArray(vtkm::TopologyElementTagCell{}, vtkm::TopologyElementTagPoint{}));
|
||||
bb, cs.GetOffsetsArray(vtkm::TopologyElementTagCell{}, vtkm::TopologyElementTagPoint{}));
|
||||
}
|
||||
|
||||
static VTKM_CONT void load(BinaryBuffer& bb, Type& cs)
|
||||
{
|
||||
vtkm::Id numberOfPoints = 0;
|
||||
vtkmdiy::load(bb, numberOfPoints);
|
||||
vtkm::cont::ArrayHandle<vtkm::UInt8, ShapeST> shapes;
|
||||
vtkm::cont::ArrayHandle<vtkm::UInt8, SST> shapes;
|
||||
vtkmdiy::load(bb, shapes);
|
||||
vtkm::cont::ArrayHandle<vtkm::IdComponent, CountST> counts;
|
||||
vtkmdiy::load(bb, counts);
|
||||
vtkm::cont::ArrayHandle<vtkm::Id, ConnectivityST> connectivity;
|
||||
vtkm::cont::ArrayHandle<vtkm::Id, CST> connectivity;
|
||||
vtkmdiy::load(bb, connectivity);
|
||||
vtkm::cont::ArrayHandle<vtkm::Id, OffsetST> offsets;
|
||||
vtkm::cont::ArrayHandle<vtkm::Id, OST> offsets;
|
||||
vtkmdiy::load(bb, offsets);
|
||||
|
||||
cs = Type{};
|
||||
cs.Fill(numberOfPoints, shapes, counts, connectivity, offsets);
|
||||
cs.Fill(numberOfPoints, shapes, connectivity, offsets);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -10,302 +10,267 @@
|
||||
#ifndef vtk_m_cont_CellSetExplicit_hxx
|
||||
#define vtk_m_cont_CellSetExplicit_hxx
|
||||
|
||||
#include <vtkm/cont/CellSetExplicit.h>
|
||||
|
||||
#include <vtkm/cont/ArrayCopy.h>
|
||||
#include <vtkm/cont/ArrayGetValues.h>
|
||||
#include <vtkm/cont/ArrayHandleDecorator.h>
|
||||
#include <vtkm/cont/Logging.h>
|
||||
#include <vtkm/cont/RuntimeDeviceTracker.h>
|
||||
#include <vtkm/cont/TryExecute.h>
|
||||
|
||||
// This file uses a lot of very verbose identifiers and the clang formatted
|
||||
// code quickly becomes unreadable. Stick with manual formatting for now.
|
||||
//
|
||||
// clang-format off
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
|
||||
template <typename ShapeStorageTag,
|
||||
typename NumIndicesStorageTag,
|
||||
typename ConnectivityStorageTag,
|
||||
typename OffsetsStorageTag>
|
||||
VTKM_CONT CellSetExplicit<ShapeStorageTag,
|
||||
NumIndicesStorageTag,
|
||||
ConnectivityStorageTag,
|
||||
OffsetsStorageTag>::CellSetExplicit()
|
||||
template <typename SST, typename CST, typename OST>
|
||||
VTKM_CONT
|
||||
CellSetExplicit<SST, CST, OST>::CellSetExplicit()
|
||||
: CellSet()
|
||||
, Data(std::make_shared<Internals>())
|
||||
{
|
||||
}
|
||||
|
||||
template <typename ShapeStorageTag,
|
||||
typename NumIndicesStorageTag,
|
||||
typename ConnectivityStorageTag,
|
||||
typename OffsetsStorageTag>
|
||||
VTKM_CONT CellSetExplicit<ShapeStorageTag,
|
||||
NumIndicesStorageTag,
|
||||
ConnectivityStorageTag,
|
||||
OffsetsStorageTag>::CellSetExplicit(const Thisclass& src)
|
||||
template <typename SST, typename CST, typename OST>
|
||||
VTKM_CONT
|
||||
CellSetExplicit<SST, CST, OST>::CellSetExplicit(const Thisclass& src)
|
||||
: CellSet(src)
|
||||
, Data(src.Data)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename ShapeStorageTag,
|
||||
typename NumIndicesStorageTag,
|
||||
typename ConnectivityStorageTag,
|
||||
typename OffsetsStorageTag>
|
||||
VTKM_CONT CellSetExplicit<ShapeStorageTag,
|
||||
NumIndicesStorageTag,
|
||||
ConnectivityStorageTag,
|
||||
OffsetsStorageTag>::CellSetExplicit(Thisclass &&src) noexcept
|
||||
: CellSet(std::forward<CellSet>(src)),
|
||||
Data(std::move(src.Data))
|
||||
template <typename SST, typename CST, typename OST>
|
||||
VTKM_CONT
|
||||
CellSetExplicit<SST, CST, OST>::CellSetExplicit(Thisclass &&src) noexcept
|
||||
: CellSet(std::forward<CellSet>(src))
|
||||
, Data(std::move(src.Data))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename ShapeStorageTag,
|
||||
typename NumIndicesStorageTag,
|
||||
typename ConnectivityStorageTag,
|
||||
typename OffsetsStorageTag>
|
||||
VTKM_CONT auto
|
||||
CellSetExplicit<ShapeStorageTag, NumIndicesStorageTag, ConnectivityStorageTag, OffsetsStorageTag>::
|
||||
operator=(const Thisclass& src) -> Thisclass&
|
||||
template <typename SST, typename CST, typename OST>
|
||||
VTKM_CONT
|
||||
auto CellSetExplicit<SST, CST, OST>::operator=(const Thisclass& src)
|
||||
-> Thisclass&
|
||||
{
|
||||
this->CellSet::operator=(src);
|
||||
this->Data = src.Data;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename ShapeStorageTag,
|
||||
typename NumIndicesStorageTag,
|
||||
typename ConnectivityStorageTag,
|
||||
typename OffsetsStorageTag>
|
||||
VTKM_CONT auto
|
||||
CellSetExplicit<ShapeStorageTag, NumIndicesStorageTag, ConnectivityStorageTag, OffsetsStorageTag>::
|
||||
operator=(Thisclass&& src) noexcept -> Thisclass&
|
||||
template <typename SST, typename CST, typename OST>
|
||||
VTKM_CONT
|
||||
auto CellSetExplicit<SST, CST, OST>::operator=(Thisclass&& src) noexcept
|
||||
-> Thisclass&
|
||||
{
|
||||
this->CellSet::operator=(std::forward<CellSet>(src));
|
||||
this->Data = std::move(src.Data);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename ShapeStorageTag,
|
||||
typename NumIndicesStorageTag,
|
||||
typename ConnectivityStorageTag,
|
||||
typename OffsetsStorageTag>
|
||||
CellSetExplicit<ShapeStorageTag, NumIndicesStorageTag, ConnectivityStorageTag, OffsetsStorageTag>::
|
||||
~CellSetExplicit()
|
||||
// explicitly define instead of '=default' to workaround an intel compiler bug
|
||||
// (see #179)
|
||||
template <typename SST, typename CST, typename OST>
|
||||
VTKM_CONT
|
||||
CellSetExplicit<SST, CST, OST>::~CellSetExplicit()
|
||||
{
|
||||
// explicitly define instead of '=default' to workaround an intel compiler bug
|
||||
// (see #179)
|
||||
}
|
||||
|
||||
template <typename ShapeStorageTag,
|
||||
typename NumIndicesStorageTag,
|
||||
typename ConnectivityStorageTag,
|
||||
typename OffsetsStorageTag>
|
||||
void CellSetExplicit<ShapeStorageTag,
|
||||
NumIndicesStorageTag,
|
||||
ConnectivityStorageTag,
|
||||
OffsetsStorageTag>::PrintSummary(std::ostream& out) const
|
||||
template <typename SST, typename CST, typename OST>
|
||||
VTKM_CONT
|
||||
void CellSetExplicit<SST, CST, OST>::PrintSummary(std::ostream& out) const
|
||||
{
|
||||
out << " ExplicitCellSet: " << std::endl;
|
||||
out << " VisitCellsWithPoints: " << std::endl;
|
||||
this->Data->VisitCellsWithPoints.PrintSummary(out);
|
||||
out << " VisitPointsWithCells: " << std::endl;
|
||||
this->Data->VisitPointsWithCells.PrintSummary(out);
|
||||
out << " ExplicitCellSet:" << std::endl;
|
||||
out << " CellPointIds:" << std::endl;
|
||||
this->Data->CellPointIds.PrintSummary(out);
|
||||
out << " PointCellIds:" << std::endl;
|
||||
this->Data->PointCellIds.PrintSummary(out);
|
||||
}
|
||||
|
||||
template <typename ShapeStorageTag,
|
||||
typename NumIndicesStorageTag,
|
||||
typename ConnectivityStorageTag,
|
||||
typename OffsetStorageTag>
|
||||
void CellSetExplicit<ShapeStorageTag,
|
||||
NumIndicesStorageTag,
|
||||
ConnectivityStorageTag,
|
||||
OffsetStorageTag>::ReleaseResourcesExecution()
|
||||
template <typename SST, typename CST, typename OST>
|
||||
VTKM_CONT
|
||||
void CellSetExplicit<SST, CST, OST>::ReleaseResourcesExecution()
|
||||
{
|
||||
this->Data->VisitCellsWithPoints.ReleaseResourcesExecution();
|
||||
this->Data->VisitPointsWithCells.ReleaseResourcesExecution();
|
||||
this->Data->CellPointIds.ReleaseResourcesExecution();
|
||||
this->Data->PointCellIds.ReleaseResourcesExecution();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
template <typename ShapeStorageTag,
|
||||
typename NumIndicesStorageTag,
|
||||
typename ConnectivityStorageTag,
|
||||
typename OffsetsStorageTag>
|
||||
vtkm::Id CellSetExplicit<ShapeStorageTag,
|
||||
NumIndicesStorageTag,
|
||||
ConnectivityStorageTag,
|
||||
OffsetsStorageTag>::GetNumberOfCells() const
|
||||
template <typename SST, typename CST, typename OST>
|
||||
VTKM_CONT
|
||||
vtkm::Id CellSetExplicit<SST, CST, OST>::GetNumberOfCells() const
|
||||
{
|
||||
return this->Data->VisitCellsWithPoints.GetNumberOfElements();
|
||||
return this->Data->CellPointIds.GetNumberOfElements();
|
||||
}
|
||||
|
||||
template <typename ShapeStorageTag,
|
||||
typename NumIndicesStorageTag,
|
||||
typename ConnectivityStorageTag,
|
||||
typename OffsetsStorageTag>
|
||||
vtkm::Id CellSetExplicit<ShapeStorageTag,
|
||||
NumIndicesStorageTag,
|
||||
ConnectivityStorageTag,
|
||||
OffsetsStorageTag>::GetNumberOfPoints() const
|
||||
template <typename SST, typename CST, typename OST>
|
||||
VTKM_CONT
|
||||
vtkm::Id CellSetExplicit<SST, CST, OST>::GetNumberOfPoints() const
|
||||
{
|
||||
return this->Data->NumberOfPoints;
|
||||
}
|
||||
|
||||
template <typename ShapeStorageTag,
|
||||
typename NumIndicesStorageTag,
|
||||
typename ConnectivityStorageTag,
|
||||
typename OffsetsStorageTag>
|
||||
vtkm::Id CellSetExplicit<ShapeStorageTag,
|
||||
NumIndicesStorageTag,
|
||||
ConnectivityStorageTag,
|
||||
OffsetsStorageTag>::GetNumberOfFaces() const
|
||||
template <typename SST, typename CST, typename OST>
|
||||
VTKM_CONT
|
||||
vtkm::Id CellSetExplicit<SST, CST, OST>::GetNumberOfFaces() const
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
template <typename ShapeStorageTag,
|
||||
typename NumIndicesStorageTag,
|
||||
typename ConnectivityStorageTag,
|
||||
typename OffsetsStorageTag>
|
||||
vtkm::Id CellSetExplicit<ShapeStorageTag,
|
||||
NumIndicesStorageTag,
|
||||
ConnectivityStorageTag,
|
||||
OffsetsStorageTag>::GetNumberOfEdges() const
|
||||
template <typename SST, typename CST, typename OST>
|
||||
VTKM_CONT
|
||||
vtkm::Id CellSetExplicit<SST, CST, OST>::GetNumberOfEdges() const
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
template <typename ShapeStorageTag,
|
||||
typename NumIndicesStorageTag,
|
||||
typename ConnectivityStorageTag,
|
||||
typename OffsetsStorageTag>
|
||||
void CellSetExplicit<ShapeStorageTag,
|
||||
NumIndicesStorageTag,
|
||||
ConnectivityStorageTag,
|
||||
OffsetsStorageTag>::GetCellPointIds(vtkm::Id id, vtkm::Id* ptids) const
|
||||
template <typename SST, typename CST, typename OST>
|
||||
VTKM_CONT
|
||||
void CellSetExplicit<SST, CST, OST>::GetCellPointIds(vtkm::Id cellId,
|
||||
vtkm::Id* ptids) const
|
||||
{
|
||||
auto arrayWrapper = vtkm::cont::make_ArrayHandle(ptids, this->GetNumberOfPointsInCell(id));
|
||||
this->GetIndices(id, arrayWrapper);
|
||||
const auto offPortal = this->Data->CellPointIds.Offsets.GetPortalConstControl();
|
||||
const vtkm::Id start = offPortal.Get(cellId);
|
||||
const vtkm::Id end = offPortal.Get(cellId + 1);
|
||||
const vtkm::IdComponent numIndices = static_cast<vtkm::IdComponent>(end - start);
|
||||
auto connPortal = this->Data->CellPointIds.Connectivity.GetPortalConstControl();
|
||||
for (vtkm::IdComponent i = 0; i < numIndices; i++)
|
||||
{
|
||||
ptids[i] = connPortal.Get(start + i);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
template <typename ShapeStorageTag,
|
||||
typename NumIndicesStorageTag,
|
||||
typename ConnectivityStorageTag,
|
||||
typename OffsetsStorageTag>
|
||||
VTKM_CONT vtkm::Id
|
||||
CellSetExplicit<ShapeStorageTag,
|
||||
NumIndicesStorageTag,
|
||||
ConnectivityStorageTag,
|
||||
OffsetsStorageTag>::GetSchedulingRange(vtkm::TopologyElementTagCell) const
|
||||
template <typename SST, typename CST, typename OST>
|
||||
VTKM_CONT
|
||||
vtkm::Id CellSetExplicit<SST, CST, OST>
|
||||
::GetSchedulingRange(vtkm::TopologyElementTagCell) const
|
||||
{
|
||||
return this->GetNumberOfCells();
|
||||
}
|
||||
|
||||
template <typename ShapeStorageTag,
|
||||
typename NumIndicesStorageTag,
|
||||
typename ConnectivityStorageTag,
|
||||
typename OffsetsStorageTag>
|
||||
VTKM_CONT vtkm::Id
|
||||
CellSetExplicit<ShapeStorageTag,
|
||||
NumIndicesStorageTag,
|
||||
ConnectivityStorageTag,
|
||||
OffsetsStorageTag>::GetSchedulingRange(vtkm::TopologyElementTagPoint) const
|
||||
template <typename SST, typename CST, typename OST>
|
||||
VTKM_CONT
|
||||
vtkm::Id CellSetExplicit<SST, CST, OST>
|
||||
::GetSchedulingRange(vtkm::TopologyElementTagPoint) const
|
||||
{
|
||||
return this->GetNumberOfPoints();
|
||||
}
|
||||
|
||||
template <typename ShapeStorageTag,
|
||||
typename NumIndicesStorageTag,
|
||||
typename ConnectivityStorageTag,
|
||||
typename OffsetsStorageTag>
|
||||
VTKM_CONT vtkm::IdComponent
|
||||
CellSetExplicit<ShapeStorageTag, NumIndicesStorageTag, ConnectivityStorageTag, OffsetsStorageTag>::
|
||||
GetNumberOfPointsInCell(vtkm::Id cellIndex) const
|
||||
template <typename SST, typename CST, typename OST>
|
||||
VTKM_CONT
|
||||
vtkm::IdComponent CellSetExplicit<SST, CST, OST>
|
||||
::GetNumberOfPointsInCell(vtkm::Id cellid) const
|
||||
{
|
||||
return this->Data->VisitCellsWithPoints.NumIndices.GetPortalConstControl().Get(cellIndex);
|
||||
const auto portal = this->Data->CellPointIds.Offsets.GetPortalConstControl();
|
||||
return static_cast<vtkm::IdComponent>(portal.Get(cellid + 1) -
|
||||
portal.Get(cellid));
|
||||
}
|
||||
|
||||
template <typename ShapeStorageTag,
|
||||
typename NumIndicesStorageTag,
|
||||
typename ConnectivityStorageTag,
|
||||
typename OffsetsStorageTag>
|
||||
VTKM_CONT vtkm::UInt8 CellSetExplicit<ShapeStorageTag,
|
||||
NumIndicesStorageTag,
|
||||
ConnectivityStorageTag,
|
||||
OffsetsStorageTag>::GetCellShape(vtkm::Id cellIndex) const
|
||||
template <typename SST, typename CST, typename OST>
|
||||
VTKM_CONT
|
||||
vtkm::UInt8 CellSetExplicit<SST, CST, OST>
|
||||
::GetCellShape(vtkm::Id cellid) const
|
||||
{
|
||||
return this->Data->VisitCellsWithPoints.Shapes.GetPortalConstControl().Get(cellIndex);
|
||||
return this->Data->CellPointIds.Shapes.GetPortalConstControl().Get(cellid);
|
||||
}
|
||||
|
||||
template <typename ShapeStorageTag,
|
||||
typename NumIndicesStorageTag,
|
||||
typename ConnectivityStorageTag,
|
||||
typename OffsetsStorageTag>
|
||||
template <vtkm::IdComponent ItemTupleLength>
|
||||
VTKM_CONT void
|
||||
CellSetExplicit<ShapeStorageTag, NumIndicesStorageTag, ConnectivityStorageTag, OffsetsStorageTag>::
|
||||
GetIndices(vtkm::Id index, vtkm::Vec<vtkm::Id, ItemTupleLength>& ids) const
|
||||
template <typename SST, typename CST, typename OST>
|
||||
template <vtkm::IdComponent NumVecIndices>
|
||||
VTKM_CONT
|
||||
void CellSetExplicit<SST, CST, OST>
|
||||
::GetIndices(vtkm::Id cellId, vtkm::Vec<vtkm::Id, NumVecIndices>& ids) const
|
||||
{
|
||||
this->Data->VisitCellsWithPoints.BuildIndexOffsets(vtkm::cont::DeviceAdapterTagAny{});
|
||||
vtkm::IdComponent numIndices = this->GetNumberOfPointsInCell(index);
|
||||
vtkm::Id start = this->Data->VisitCellsWithPoints.IndexOffsets.GetPortalConstControl().Get(index);
|
||||
for (vtkm::IdComponent i = 0; i < numIndices && i < ItemTupleLength; i++)
|
||||
const auto offPortal = this->Data->CellPointIds.Offsets.GetPortalConstControl();
|
||||
const vtkm::Id start = offPortal.Get(cellId);
|
||||
const vtkm::Id end = offPortal.Get(cellId + 1);
|
||||
const auto numCellIndices = static_cast<vtkm::IdComponent>(end - start);
|
||||
const auto connPortal = this->Data->CellPointIds.Connectivity.GetPortalConstControl();
|
||||
|
||||
VTKM_LOG_IF_S(vtkm::cont::LogLevel::Warn,
|
||||
numCellIndices != NumVecIndices,
|
||||
"GetIndices given a " << NumVecIndices
|
||||
<< "-vec to fetch a cell with " << numCellIndices << "points. "
|
||||
"Truncating result.");
|
||||
|
||||
const vtkm::IdComponent numIndices = vtkm::Min(NumVecIndices, numCellIndices);
|
||||
|
||||
for (vtkm::IdComponent i = 0; i < numIndices; i++)
|
||||
{
|
||||
ids[i] = this->Data->VisitCellsWithPoints.Connectivity.GetPortalConstControl().Get(start + i);
|
||||
ids[i] = connPortal.Get(start + i);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename ShapeStorageTag,
|
||||
typename NumIndicesStorageTag,
|
||||
typename ConnectivityStorageTag,
|
||||
typename OffsetsStorageTag>
|
||||
VTKM_CONT void
|
||||
CellSetExplicit<ShapeStorageTag, NumIndicesStorageTag, ConnectivityStorageTag, OffsetsStorageTag>::
|
||||
GetIndices(vtkm::Id index, vtkm::cont::ArrayHandle<vtkm::Id>& ids) const
|
||||
template <typename SST, typename CST, typename OST>
|
||||
VTKM_CONT
|
||||
void CellSetExplicit<SST, CST, OST>
|
||||
::GetIndices(vtkm::Id cellId, vtkm::cont::ArrayHandle<vtkm::Id>& ids) const
|
||||
{
|
||||
this->Data->VisitCellsWithPoints.BuildIndexOffsets(vtkm::cont::DeviceAdapterTagAny{});
|
||||
vtkm::IdComponent numIndices = this->GetNumberOfPointsInCell(index);
|
||||
const auto offPortal = this->Data->CellPointIds.Offsets.GetPortalConstControl();
|
||||
const vtkm::Id start = offPortal.Get(cellId);
|
||||
const vtkm::Id end = offPortal.Get(cellId + 1);
|
||||
const vtkm::IdComponent numIndices = static_cast<vtkm::IdComponent>(end - start);
|
||||
ids.Allocate(numIndices);
|
||||
vtkm::Id start = this->Data->VisitCellsWithPoints.IndexOffsets.GetPortalConstControl().Get(index);
|
||||
vtkm::cont::ArrayHandle<vtkm::Id>::PortalControl idPortal = ids.GetPortalControl();
|
||||
auto PtCellPortal = this->Data->VisitCellsWithPoints.Connectivity.GetPortalConstControl();
|
||||
auto connPortal = this->Data->CellPointIds.Connectivity.GetPortalConstControl();
|
||||
|
||||
for (vtkm::IdComponent i = 0; i < numIndices && i < numIndices; i++)
|
||||
auto outIdPortal = ids.GetPortalControl();
|
||||
|
||||
for (vtkm::IdComponent i = 0; i < numIndices; i++)
|
||||
{
|
||||
idPortal.Set(i, PtCellPortal.Get(start + i));
|
||||
outIdPortal.Set(i, connPortal.Get(start + i));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
template <typename ShapeStorageTag,
|
||||
typename NumIndicesStorageTag,
|
||||
typename ConnectivityStorageTag,
|
||||
typename OffsetsStorageTag>
|
||||
VTKM_CONT void CellSetExplicit<ShapeStorageTag,
|
||||
NumIndicesStorageTag,
|
||||
ConnectivityStorageTag,
|
||||
OffsetsStorageTag>::PrepareToAddCells(vtkm::Id numCells,
|
||||
vtkm::Id connectivityMaxLen)
|
||||
namespace internal
|
||||
{
|
||||
this->Data->VisitCellsWithPoints.Shapes.Allocate(numCells);
|
||||
this->Data->VisitCellsWithPoints.NumIndices.Allocate(numCells);
|
||||
this->Data->VisitCellsWithPoints.Connectivity.Allocate(connectivityMaxLen);
|
||||
this->Data->VisitCellsWithPoints.IndexOffsets.Allocate(numCells);
|
||||
|
||||
// Sets the first value of the array to zero if the handle is writable,
|
||||
// otherwise do nothing:
|
||||
template <typename ArrayType>
|
||||
typename std::enable_if<vtkm::cont::internal::IsWritableArrayHandle<ArrayType>::value>::type
|
||||
SetFirstToZeroIfWritable(ArrayType&& array)
|
||||
{
|
||||
using ValueType = typename std::decay<ArrayType>::type::ValueType;
|
||||
using Traits = vtkm::TypeTraits<ValueType>;
|
||||
array.GetPortalControl().Set(0, Traits::ZeroInitialization());
|
||||
}
|
||||
|
||||
template <typename ArrayType>
|
||||
typename std::enable_if<!vtkm::cont::internal::IsWritableArrayHandle<ArrayType>::value>::type
|
||||
SetFirstToZeroIfWritable(ArrayType&&)
|
||||
{ /* no-op */ }
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
template <typename SST, typename CST, typename OST>
|
||||
VTKM_CONT
|
||||
void CellSetExplicit<SST, CST, OST>
|
||||
::PrepareToAddCells(vtkm::Id numCells,
|
||||
vtkm::Id connectivityMaxLen)
|
||||
{
|
||||
this->Data->CellPointIds.Shapes.Allocate(numCells);
|
||||
this->Data->CellPointIds.Connectivity.Allocate(connectivityMaxLen);
|
||||
this->Data->CellPointIds.Offsets.Allocate(numCells + 1);
|
||||
internal::SetFirstToZeroIfWritable(this->Data->CellPointIds.Offsets);
|
||||
this->Data->NumberOfCellsAdded = 0;
|
||||
this->Data->ConnectivityAdded = 0;
|
||||
}
|
||||
|
||||
template <typename ShapeStorageTag,
|
||||
typename NumIndicesStorageTag,
|
||||
typename ConnectivityStorageTag,
|
||||
typename OffsetsStorageTag>
|
||||
template <typename SST, typename CST, typename OST>
|
||||
template <typename IdVecType>
|
||||
VTKM_CONT void
|
||||
CellSetExplicit<ShapeStorageTag, NumIndicesStorageTag, ConnectivityStorageTag, OffsetsStorageTag>::
|
||||
AddCell(vtkm::UInt8 cellType, vtkm::IdComponent numVertices, const IdVecType& ids)
|
||||
VTKM_CONT
|
||||
void CellSetExplicit<SST, CST, OST>::AddCell(vtkm::UInt8 cellType,
|
||||
vtkm::IdComponent numVertices,
|
||||
const IdVecType& ids)
|
||||
{
|
||||
using Traits = vtkm::VecTraits<IdVecType>;
|
||||
VTKM_STATIC_ASSERT_MSG((std::is_same<typename Traits::ComponentType, vtkm::Id>::value),
|
||||
@ -313,48 +278,45 @@ CellSetExplicit<ShapeStorageTag, NumIndicesStorageTag, ConnectivityStorageTag, O
|
||||
|
||||
if (Traits::GetNumberOfComponents(ids) < numVertices)
|
||||
{
|
||||
throw vtkm::cont::ErrorBadValue("Not enough indices given to CellSetSingleType::AddCell.");
|
||||
throw vtkm::cont::ErrorBadValue("Not enough indices given to CellSetExplicit::AddCell.");
|
||||
}
|
||||
|
||||
if (this->Data->NumberOfCellsAdded >= this->Data->VisitCellsWithPoints.Shapes.GetNumberOfValues())
|
||||
if (this->Data->NumberOfCellsAdded >= this->Data->CellPointIds.Shapes.GetNumberOfValues())
|
||||
{
|
||||
throw vtkm::cont::ErrorBadValue("Added more cells then expected.");
|
||||
}
|
||||
if (this->Data->ConnectivityAdded + numVertices >
|
||||
this->Data->VisitCellsWithPoints.Connectivity.GetNumberOfValues())
|
||||
this->Data->CellPointIds.Connectivity.GetNumberOfValues())
|
||||
{
|
||||
throw vtkm::cont::ErrorBadValue(
|
||||
"Connectivity increased passed estimated maximum connectivity.");
|
||||
"Connectivity increased past estimated maximum connectivity.");
|
||||
}
|
||||
|
||||
this->Data->VisitCellsWithPoints.Shapes.GetPortalControl().Set(this->Data->NumberOfCellsAdded,
|
||||
cellType);
|
||||
this->Data->VisitCellsWithPoints.NumIndices.GetPortalControl().Set(this->Data->NumberOfCellsAdded,
|
||||
numVertices);
|
||||
auto shapes = this->Data->CellPointIds.Shapes.GetPortalControl();
|
||||
auto conn = this->Data->CellPointIds.Connectivity.GetPortalControl();
|
||||
auto offsets = this->Data->CellPointIds.Offsets.GetPortalControl();
|
||||
|
||||
shapes.Set(this->Data->NumberOfCellsAdded, cellType);
|
||||
for (vtkm::IdComponent iVec = 0; iVec < numVertices; ++iVec)
|
||||
{
|
||||
this->Data->VisitCellsWithPoints.Connectivity.GetPortalControl().Set(
|
||||
this->Data->ConnectivityAdded + iVec, Traits::GetComponent(ids, iVec));
|
||||
conn.Set(this->Data->ConnectivityAdded + iVec,
|
||||
Traits::GetComponent(ids, iVec));
|
||||
}
|
||||
this->Data->VisitCellsWithPoints.IndexOffsets.GetPortalControl().Set(
|
||||
this->Data->NumberOfCellsAdded, this->Data->ConnectivityAdded);
|
||||
|
||||
this->Data->NumberOfCellsAdded++;
|
||||
this->Data->ConnectivityAdded += numVertices;
|
||||
|
||||
// Set the end offset for the added cell:
|
||||
offsets.Set(this->Data->NumberOfCellsAdded, this->Data->ConnectivityAdded);
|
||||
}
|
||||
|
||||
template <typename ShapeStorageTag,
|
||||
typename NumIndicesStorageTag,
|
||||
typename ConnectivityStorageTag,
|
||||
typename OffsetsStorageTag>
|
||||
VTKM_CONT void CellSetExplicit<ShapeStorageTag,
|
||||
NumIndicesStorageTag,
|
||||
ConnectivityStorageTag,
|
||||
OffsetsStorageTag>::CompleteAddingCells(vtkm::Id numPoints)
|
||||
template <typename SST, typename CST, typename OST>
|
||||
VTKM_CONT
|
||||
void CellSetExplicit<SST, CST, OST>::CompleteAddingCells(vtkm::Id numPoints)
|
||||
{
|
||||
this->Data->NumberOfPoints = numPoints;
|
||||
this->Data->VisitCellsWithPoints.Connectivity.Shrink(this->Data->ConnectivityAdded);
|
||||
this->Data->VisitCellsWithPoints.ElementsValid = true;
|
||||
this->Data->VisitCellsWithPoints.IndexOffsetsValid = true;
|
||||
this->Data->CellPointIds.Connectivity.Shrink(this->Data->ConnectivityAdded);
|
||||
this->Data->CellPointIds.ElementsValid = true;
|
||||
|
||||
if (this->Data->NumberOfCellsAdded != this->GetNumberOfCells())
|
||||
{
|
||||
@ -367,159 +329,132 @@ VTKM_CONT void CellSetExplicit<ShapeStorageTag,
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
template <typename ShapeStorageTag,
|
||||
typename NumIndicesStorageTag,
|
||||
typename ConnectivityStorageTag,
|
||||
typename OffsetsStorageTag>
|
||||
VTKM_CONT void
|
||||
CellSetExplicit<ShapeStorageTag, NumIndicesStorageTag, ConnectivityStorageTag, OffsetsStorageTag>::
|
||||
Fill(vtkm::Id numPoints,
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8, ShapeStorageTag>& cellTypes,
|
||||
const vtkm::cont::ArrayHandle<vtkm::IdComponent, NumIndicesStorageTag>& numIndices,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id, ConnectivityStorageTag>& connectivity,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id, OffsetsStorageTag>& offsets)
|
||||
template <typename SST, typename CST, typename OST>
|
||||
VTKM_CONT
|
||||
void CellSetExplicit<SST, CST, OST>
|
||||
::Fill(vtkm::Id numPoints,
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8, SST>& shapes,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id, CST>& connectivity,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id, OST>& offsets)
|
||||
{
|
||||
// Validate inputs:
|
||||
// Even for an empty cellset, offsets must contain a single 0:
|
||||
VTKM_ASSERT(offsets.GetNumberOfValues() > 0);
|
||||
// Must be [numCells + 1] offsets and [numCells] shapes
|
||||
VTKM_ASSERT(offsets.GetNumberOfValues() == shapes.GetNumberOfValues() + 1);
|
||||
// The last offset must be the size of the connectivity array.
|
||||
VTKM_ASSERT(vtkm::cont::ArrayGetValue(offsets.GetNumberOfValues() - 1,
|
||||
offsets) ==
|
||||
connectivity.GetNumberOfValues());
|
||||
|
||||
this->Data->NumberOfPoints = numPoints;
|
||||
this->Data->VisitCellsWithPoints.Shapes = cellTypes;
|
||||
this->Data->VisitCellsWithPoints.NumIndices = numIndices;
|
||||
this->Data->VisitCellsWithPoints.Connectivity = connectivity;
|
||||
this->Data->CellPointIds.Shapes = shapes;
|
||||
this->Data->CellPointIds.Connectivity = connectivity;
|
||||
this->Data->CellPointIds.Offsets = offsets;
|
||||
|
||||
this->Data->VisitCellsWithPoints.ElementsValid = true;
|
||||
|
||||
if (offsets.GetNumberOfValues() == cellTypes.GetNumberOfValues())
|
||||
{
|
||||
this->Data->VisitCellsWithPoints.IndexOffsets = offsets;
|
||||
this->Data->VisitCellsWithPoints.IndexOffsetsValid = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->Data->VisitCellsWithPoints.IndexOffsetsValid = false;
|
||||
if (offsets.GetNumberOfValues() != 0)
|
||||
{
|
||||
throw vtkm::cont::ErrorBadValue("Explicit cell offsets array unexpected size. "
|
||||
"Use an empty array to automatically generate.");
|
||||
}
|
||||
}
|
||||
this->Data->CellPointIds.ElementsValid = true;
|
||||
|
||||
this->ResetConnectivity(TopologyElementTagPoint{}, TopologyElementTagCell{});
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
template <typename ShapeStorageTag,
|
||||
typename NumIndicesStorageTag,
|
||||
typename ConnectivityStorageTag,
|
||||
typename OffsetsStorageTag>
|
||||
template <typename SST, typename CST, typename OST>
|
||||
template <typename Device, typename VisitTopology, typename IncidentTopology>
|
||||
auto CellSetExplicit<ShapeStorageTag,
|
||||
NumIndicesStorageTag,
|
||||
ConnectivityStorageTag,
|
||||
OffsetsStorageTag>::PrepareForInput(Device,
|
||||
VisitTopology,
|
||||
IncidentTopology) const ->
|
||||
typename ExecutionTypes<Device, VisitTopology, IncidentTopology>::ExecObjectType
|
||||
VTKM_CONT
|
||||
auto CellSetExplicit<SST, CST, OST>
|
||||
::PrepareForInput(Device, VisitTopology, IncidentTopology) const
|
||||
-> typename ExecutionTypes<Device,
|
||||
VisitTopology,
|
||||
IncidentTopology>::ExecObjectType
|
||||
{
|
||||
this->BuildConnectivity(Device{}, VisitTopology(), IncidentTopology());
|
||||
this->BuildConnectivity(Device{}, VisitTopology{}, IncidentTopology{});
|
||||
|
||||
const auto& connectivity = this->GetConnectivity(VisitTopology(), IncidentTopology());
|
||||
const auto& connectivity = this->GetConnectivity(VisitTopology{},
|
||||
IncidentTopology{});
|
||||
VTKM_ASSERT(connectivity.ElementsValid);
|
||||
|
||||
using ExecObjType =
|
||||
typename ExecutionTypes<Device, VisitTopology, IncidentTopology>::ExecObjectType;
|
||||
return ExecObjType(connectivity.Shapes.PrepareForInput(Device()),
|
||||
connectivity.NumIndices.PrepareForInput(Device()),
|
||||
connectivity.Connectivity.PrepareForInput(Device()),
|
||||
connectivity.IndexOffsets.PrepareForInput(Device()));
|
||||
using ExecObjType = typename ExecutionTypes<Device,
|
||||
VisitTopology,
|
||||
IncidentTopology>::ExecObjectType;
|
||||
|
||||
return ExecObjType(connectivity.Shapes.PrepareForInput(Device{}),
|
||||
connectivity.Connectivity.PrepareForInput(Device{}),
|
||||
connectivity.Offsets.PrepareForInput(Device{}));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
template <typename ShapeStorageTag,
|
||||
typename NumIndicesStorageTag,
|
||||
typename ConnectivityStorageTag,
|
||||
typename OffsetsStorageTag>
|
||||
template <typename SST, typename CST, typename OST>
|
||||
template <typename VisitTopology, typename IncidentTopology>
|
||||
VTKM_CONT auto CellSetExplicit<ShapeStorageTag,
|
||||
NumIndicesStorageTag,
|
||||
ConnectivityStorageTag,
|
||||
OffsetsStorageTag>::GetShapesArray(VisitTopology,
|
||||
IncidentTopology) const -> const
|
||||
typename ConnectivityChooser<VisitTopology, IncidentTopology>::ShapeArrayType&
|
||||
VTKM_CONT auto CellSetExplicit<SST, CST, OST>
|
||||
::GetShapesArray(VisitTopology, IncidentTopology) const
|
||||
-> const typename ConnectivityChooser<VisitTopology,
|
||||
IncidentTopology>::ShapesArrayType&
|
||||
{
|
||||
this->BuildConnectivity(vtkm::cont::DeviceAdapterTagAny{}, VisitTopology(), IncidentTopology());
|
||||
return this->GetConnectivity(VisitTopology(), IncidentTopology()).Shapes;
|
||||
this->BuildConnectivity(vtkm::cont::DeviceAdapterTagAny{},
|
||||
VisitTopology{},
|
||||
IncidentTopology{});
|
||||
return this->GetConnectivity(VisitTopology{}, IncidentTopology{}).Shapes;
|
||||
}
|
||||
|
||||
template <typename ShapeStorageTag,
|
||||
typename NumIndicesStorageTag,
|
||||
typename ConnectivityStorageTag,
|
||||
typename OffsetsStorageTag>
|
||||
template <typename SST, typename CST, typename OST>
|
||||
template <typename VisitTopology, typename IncidentTopology>
|
||||
VTKM_CONT auto CellSetExplicit<ShapeStorageTag,
|
||||
NumIndicesStorageTag,
|
||||
ConnectivityStorageTag,
|
||||
OffsetsStorageTag>::GetNumIndicesArray(VisitTopology,
|
||||
IncidentTopology) const
|
||||
-> const typename ConnectivityChooser<VisitTopology, IncidentTopology>::NumIndicesArrayType&
|
||||
VTKM_CONT
|
||||
auto CellSetExplicit<SST, CST, OST>
|
||||
::GetConnectivityArray(VisitTopology, IncidentTopology) const
|
||||
-> const typename ConnectivityChooser<VisitTopology,
|
||||
IncidentTopology>::ConnectivityArrayType&
|
||||
{
|
||||
this->BuildConnectivity(vtkm::cont::DeviceAdapterTagAny{}, VisitTopology(), IncidentTopology());
|
||||
return this->GetConnectivity(VisitTopology(), IncidentTopology()).NumIndices;
|
||||
this->BuildConnectivity(vtkm::cont::DeviceAdapterTagAny{},
|
||||
VisitTopology{},
|
||||
IncidentTopology{});
|
||||
return this->GetConnectivity(VisitTopology{},
|
||||
IncidentTopology{}).Connectivity;
|
||||
}
|
||||
|
||||
template <typename ShapeStorageTag,
|
||||
typename NumIndicesStorageTag,
|
||||
typename ConnectivityStorageTag,
|
||||
typename OffsetsStorageTag>
|
||||
template <typename SST, typename CST, typename OST>
|
||||
template <typename VisitTopology, typename IncidentTopology>
|
||||
VTKM_CONT auto CellSetExplicit<ShapeStorageTag,
|
||||
NumIndicesStorageTag,
|
||||
ConnectivityStorageTag,
|
||||
OffsetsStorageTag>::GetConnectivityArray(VisitTopology,
|
||||
IncidentTopology) const
|
||||
-> const typename ConnectivityChooser<VisitTopology, IncidentTopology>::ConnectivityArrayType&
|
||||
VTKM_CONT
|
||||
auto CellSetExplicit<SST, CST, OST>
|
||||
::GetOffsetsArray(VisitTopology, IncidentTopology) const
|
||||
-> const typename ConnectivityChooser<VisitTopology,
|
||||
IncidentTopology>::OffsetsArrayType&
|
||||
{
|
||||
this->BuildConnectivity(vtkm::cont::DeviceAdapterTagAny{}, VisitTopology(), IncidentTopology());
|
||||
return this->GetConnectivity(VisitTopology(), IncidentTopology()).Connectivity;
|
||||
this->BuildConnectivity(vtkm::cont::DeviceAdapterTagAny{},
|
||||
VisitTopology{},
|
||||
IncidentTopology{});
|
||||
return this->GetConnectivity(VisitTopology{},
|
||||
IncidentTopology{}).Offsets;
|
||||
}
|
||||
|
||||
template <typename ShapeStorageTag,
|
||||
typename NumIndicesStorageTag,
|
||||
typename ConnectivityStorageTag,
|
||||
typename OffsetsStorageTag>
|
||||
template <typename SST, typename CST, typename OST>
|
||||
template <typename VisitTopology, typename IncidentTopology>
|
||||
VTKM_CONT auto CellSetExplicit<ShapeStorageTag,
|
||||
NumIndicesStorageTag,
|
||||
ConnectivityStorageTag,
|
||||
OffsetsStorageTag>::GetIndexOffsetArray(VisitTopology,
|
||||
IncidentTopology) const
|
||||
-> const typename ConnectivityChooser<VisitTopology, IncidentTopology>::IndexOffsetArrayType&
|
||||
VTKM_CONT
|
||||
auto CellSetExplicit<SST, CST, OST>
|
||||
::GetNumIndicesArray(VisitTopology visited, IncidentTopology incident) const
|
||||
-> typename ConnectivityChooser<VisitTopology,
|
||||
IncidentTopology>::NumIndicesArrayType
|
||||
{
|
||||
this->BuildConnectivity(vtkm::cont::DeviceAdapterTagAny{}, VisitTopology(), IncidentTopology());
|
||||
return this->GetConnectivity(VisitTopology(), IncidentTopology()).IndexOffsets;
|
||||
auto offsets = this->GetOffsetsArray(visited, incident);
|
||||
const vtkm::Id numVals = offsets.GetNumberOfValues() - 1;
|
||||
return vtkm::cont::make_ArrayHandleDecorator(numVals,
|
||||
detail::NumIndicesDecorator{},
|
||||
std::move(offsets));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
template <typename ShapeStorageTag,
|
||||
typename NumIndicesStorageTag,
|
||||
typename ConnectivityStorageTag,
|
||||
typename OffsetsStorageTag>
|
||||
std::shared_ptr<CellSet> CellSetExplicit<ShapeStorageTag,
|
||||
NumIndicesStorageTag,
|
||||
ConnectivityStorageTag,
|
||||
OffsetsStorageTag>::NewInstance() const
|
||||
template <typename SST, typename CST, typename OST>
|
||||
VTKM_CONT
|
||||
std::shared_ptr<CellSet> CellSetExplicit<SST, CST, OST>::NewInstance() const
|
||||
{
|
||||
return std::make_shared<CellSetExplicit>();
|
||||
}
|
||||
|
||||
template <typename ShapeStorageTag,
|
||||
typename NumIndicesStorageTag,
|
||||
typename ConnectivityStorageTag,
|
||||
typename OffsetsStorageTag>
|
||||
void CellSetExplicit<ShapeStorageTag,
|
||||
NumIndicesStorageTag,
|
||||
ConnectivityStorageTag,
|
||||
OffsetsStorageTag>::DeepCopy(const CellSet* src)
|
||||
template <typename SST, typename CST, typename OST>
|
||||
VTKM_CONT
|
||||
void CellSetExplicit<SST, CST, OST>::DeepCopy(const CellSet* src)
|
||||
{
|
||||
const auto* other = dynamic_cast<const CellSetExplicit*>(src);
|
||||
if (!other)
|
||||
@ -527,14 +462,18 @@ void CellSetExplicit<ShapeStorageTag,
|
||||
throw vtkm::cont::ErrorBadType("CellSetExplicit::DeepCopy types don't match");
|
||||
}
|
||||
|
||||
// TODO: implement actual deep-copy of the arrays
|
||||
auto ct = vtkm::TopologyElementTagCell{};
|
||||
auto pt = vtkm::TopologyElementTagPoint{};
|
||||
this->Fill(other->GetNumberOfPoints(),
|
||||
other->GetShapesArray(ct, pt),
|
||||
other->GetNumIndicesArray(ct, pt),
|
||||
other->GetConnectivityArray(ct, pt),
|
||||
other->GetIndexOffsetArray(ct, pt));
|
||||
ShapesArrayType shapes;
|
||||
ConnectivityArrayType conn;
|
||||
OffsetsArrayType offsets;
|
||||
|
||||
const auto ct = vtkm::TopologyElementTagCell{};
|
||||
const auto pt = vtkm::TopologyElementTagPoint{};
|
||||
|
||||
vtkm::cont::ArrayCopy(other->GetShapesArray(ct, pt), shapes);
|
||||
vtkm::cont::ArrayCopy(other->GetConnectivityArray(ct, pt), conn);
|
||||
vtkm::cont::ArrayCopy(other->GetOffsetsArray(ct, pt), offsets);
|
||||
|
||||
this->Fill(other->GetNumberOfPoints(), shapes, conn, offsets);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@ -542,33 +481,14 @@ void CellSetExplicit<ShapeStorageTag,
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <typename VisitCellsWithPointsConnectivity>
|
||||
struct BuildVisitCellsWithPointsConnectivityFunctor
|
||||
template <typename CellPointIdsT, typename PointCellIdsT>
|
||||
struct BuildPointCellIdsFunctor
|
||||
{
|
||||
explicit BuildVisitCellsWithPointsConnectivityFunctor(VisitCellsWithPointsConnectivity& obj)
|
||||
: VisitCellsWithPoints(&obj)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Device>
|
||||
bool operator()(Device) const
|
||||
{
|
||||
this->VisitCellsWithPoints->BuildIndexOffsets(Device());
|
||||
return true;
|
||||
}
|
||||
|
||||
VisitCellsWithPointsConnectivity* VisitCellsWithPoints;
|
||||
};
|
||||
|
||||
template <typename VisitCellsWithPointsConnectivity, typename VisitPointsWithCellsConnectivity>
|
||||
struct BuildVisitPointsWithCellsConnectivityFunctor
|
||||
{
|
||||
BuildVisitPointsWithCellsConnectivityFunctor(
|
||||
VisitCellsWithPointsConnectivity& visitCellsWithPoints,
|
||||
VisitPointsWithCellsConnectivity& visitPointsWithCells,
|
||||
vtkm::Id numberOfPoints)
|
||||
: VisitCellsWithPoints(&visitCellsWithPoints)
|
||||
, VisitPointsWithCells(&visitPointsWithCells)
|
||||
BuildPointCellIdsFunctor(CellPointIdsT &cellPointIds,
|
||||
PointCellIdsT &pointCellIds,
|
||||
vtkm::Id numberOfPoints)
|
||||
: CellPointIds(cellPointIds)
|
||||
, PointCellIds(pointCellIds)
|
||||
, NumberOfPoints(numberOfPoints)
|
||||
{
|
||||
}
|
||||
@ -576,81 +496,57 @@ struct BuildVisitPointsWithCellsConnectivityFunctor
|
||||
template <typename Device>
|
||||
bool operator()(Device) const
|
||||
{
|
||||
this->VisitCellsWithPoints->BuildIndexOffsets(Device());
|
||||
internal::ComputeVisitPointsWithCellsConnectivity(
|
||||
*this->VisitPointsWithCells, *this->VisitCellsWithPoints, this->NumberOfPoints, Device());
|
||||
this->VisitPointsWithCells->BuildIndexOffsets(Device());
|
||||
internal::ComputeRConnTable(this->PointCellIds,
|
||||
this->CellPointIds,
|
||||
this->NumberOfPoints,
|
||||
Device{});
|
||||
return true;
|
||||
}
|
||||
|
||||
VisitCellsWithPointsConnectivity* VisitCellsWithPoints;
|
||||
VisitPointsWithCellsConnectivity* VisitPointsWithCells;
|
||||
CellPointIdsT &CellPointIds;
|
||||
PointCellIdsT &PointCellIds;
|
||||
vtkm::Id NumberOfPoints;
|
||||
};
|
||||
|
||||
} // detail
|
||||
|
||||
template <typename ShapeStorageTag,
|
||||
typename NumIndicesStorageTag,
|
||||
typename ConnectivityStorageTag,
|
||||
typename OffsetsStorageTag>
|
||||
VTKM_CONT void
|
||||
CellSetExplicit<ShapeStorageTag, NumIndicesStorageTag, ConnectivityStorageTag, OffsetsStorageTag>::
|
||||
BuildConnectivity(vtkm::cont::DeviceAdapterId device,
|
||||
template <typename SST, typename CST, typename OST>
|
||||
VTKM_CONT
|
||||
void CellSetExplicit<SST, CST, OST>
|
||||
::BuildConnectivity(vtkm::cont::DeviceAdapterId,
|
||||
vtkm::TopologyElementTagCell,
|
||||
vtkm::TopologyElementTagPoint) const
|
||||
{
|
||||
using VisitCellsWithPointsConnectivity =
|
||||
typename ConnectivityChooser<vtkm::TopologyElementTagCell,
|
||||
vtkm::TopologyElementTagPoint>::ConnectivityType;
|
||||
|
||||
VTKM_ASSERT(this->Data->VisitCellsWithPoints.ElementsValid);
|
||||
if (!this->Data->VisitCellsWithPoints.IndexOffsetsValid)
|
||||
{
|
||||
auto self = const_cast<Thisclass*>(this);
|
||||
auto functor =
|
||||
detail::BuildVisitCellsWithPointsConnectivityFunctor<VisitCellsWithPointsConnectivity>(
|
||||
self->Data->VisitCellsWithPoints);
|
||||
if (!vtkm::cont::TryExecuteOnDevice(device, functor))
|
||||
{
|
||||
throw vtkm::cont::ErrorExecution("Failed to run BuildConnectivity.");
|
||||
}
|
||||
}
|
||||
VTKM_ASSERT(this->Data->CellPointIds.ElementsValid);
|
||||
// no-op
|
||||
}
|
||||
|
||||
template <typename ShapeStorageTag,
|
||||
typename NumIndicesStorageTag,
|
||||
typename ConnectivityStorageTag,
|
||||
typename OffsetsStorageTag>
|
||||
VTKM_CONT void
|
||||
CellSetExplicit<ShapeStorageTag, NumIndicesStorageTag, ConnectivityStorageTag, OffsetsStorageTag>::
|
||||
BuildConnectivity(vtkm::cont::DeviceAdapterId device,
|
||||
template <typename SST, typename CST, typename OST>
|
||||
VTKM_CONT
|
||||
void CellSetExplicit<SST, CST, OST>
|
||||
::BuildConnectivity(vtkm::cont::DeviceAdapterId device,
|
||||
vtkm::TopologyElementTagPoint,
|
||||
vtkm::TopologyElementTagCell) const
|
||||
{
|
||||
using VisitCellsWithPointsConnectivity =
|
||||
typename ConnectivityChooser<vtkm::TopologyElementTagCell,
|
||||
vtkm::TopologyElementTagPoint>::ConnectivityType;
|
||||
using VisitPointsWithCellsConnectivity =
|
||||
typename ConnectivityChooser<vtkm::TopologyElementTagPoint,
|
||||
vtkm::TopologyElementTagCell>::ConnectivityType;
|
||||
|
||||
if (!this->Data->VisitPointsWithCells.ElementsValid ||
|
||||
!this->Data->VisitPointsWithCells.IndexOffsetsValid)
|
||||
if (!this->Data->PointCellIds.ElementsValid)
|
||||
{
|
||||
auto self = const_cast<Thisclass*>(this);
|
||||
auto functor =
|
||||
detail::BuildVisitPointsWithCellsConnectivityFunctor<VisitCellsWithPointsConnectivity,
|
||||
VisitPointsWithCellsConnectivity>(
|
||||
self->Data->VisitCellsWithPoints,
|
||||
self->Data->VisitPointsWithCells,
|
||||
this->Data->NumberOfPoints);
|
||||
using Func = detail::BuildPointCellIdsFunctor<CellPointIdsType, PointCellIdsType>;
|
||||
|
||||
auto functor = Func(self->Data->CellPointIds,
|
||||
self->Data->PointCellIds,
|
||||
self->Data->NumberOfPoints);
|
||||
|
||||
if (!vtkm::cont::TryExecuteOnDevice(device, functor))
|
||||
{
|
||||
throw vtkm::cont::ErrorExecution("Failed to run BuildConnectivity.");
|
||||
throw vtkm::cont::ErrorExecution("Failed to run CellSetExplicit reverse "
|
||||
"connectivity builder.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // vtkm::cont
|
||||
|
||||
// clang-format on
|
||||
|
||||
#endif
|
||||
|
@ -15,7 +15,6 @@ namespace
|
||||
struct ComputeReverseMapping : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
using ControlSignature = void(FieldIn cellIndex, WholeArrayOut cellIds);
|
||||
using ExecutionSignature = void(_1, _2);
|
||||
|
||||
VTKM_SUPPRESS_EXEC_WARNINGS
|
||||
template <typename PortalType>
|
||||
|
@ -42,15 +42,12 @@ struct VTKM_ALWAYS_EXPORT CellSetListTagStructured3D
|
||||
};
|
||||
|
||||
|
||||
template <typename ShapeStorageTag = VTKM_DEFAULT_SHAPE_STORAGE_TAG,
|
||||
typename NumIndicesStorageTag = VTKM_DEFAULT_NUM_INDICES_STORAGE_TAG,
|
||||
template <typename ShapesStorageTag = VTKM_DEFAULT_SHAPES_STORAGE_TAG,
|
||||
typename ConnectivityStorageTag = VTKM_DEFAULT_CONNECTIVITY_STORAGE_TAG,
|
||||
typename OffsetsStorageTag = VTKM_DEFAULT_OFFSETS_STORAGE_TAG>
|
||||
struct VTKM_ALWAYS_EXPORT CellSetListTagExplicit
|
||||
: vtkm::ListTagBase<vtkm::cont::CellSetExplicit<ShapeStorageTag,
|
||||
NumIndicesStorageTag,
|
||||
ConnectivityStorageTag,
|
||||
OffsetsStorageTag>>
|
||||
: vtkm::ListTagBase<
|
||||
vtkm::cont::CellSetExplicit<ShapesStorageTag, ConnectivityStorageTag, OffsetsStorageTag>>
|
||||
{
|
||||
};
|
||||
|
||||
|
@ -12,13 +12,15 @@
|
||||
|
||||
#include <vtkm/CellShape.h>
|
||||
#include <vtkm/CellTraits.h>
|
||||
#include <vtkm/cont/ArrayCopy.h>
|
||||
#include <vtkm/cont/ArrayHandleCast.h>
|
||||
#include <vtkm/cont/ArrayHandleGroupVecVariable.h>
|
||||
#include <vtkm/cont/ArrayHandlePermutation.h>
|
||||
#include <vtkm/cont/CellSet.h>
|
||||
#include <vtkm/cont/CellSetExplicit.h>
|
||||
#include <vtkm/cont/Invoker.h>
|
||||
#include <vtkm/cont/internal/ConnectivityExplicitInternals.h>
|
||||
#include <vtkm/internal/ConnectivityStructuredInternals.h>
|
||||
#include <vtkm/worklet/DispatcherMapTopology.h>
|
||||
#include <vtkm/worklet/WorkletMapTopology.h>
|
||||
|
||||
#include <vtkm/exec/ConnectivityPermuted.h>
|
||||
@ -35,7 +37,12 @@ namespace cont
|
||||
namespace internal
|
||||
{
|
||||
|
||||
class CellSetPermutationVisitCellsWithPointsHelpers
|
||||
// To generate the reverse connectivity table with the
|
||||
// ReverseConnectivityBuilder, we need a compact connectivity array that
|
||||
// contains only the cell definitions from the permuted dataset, and an offsets
|
||||
// array. These helpers are used to generate these arrays so that they can be
|
||||
// converted in the reverse conn table.
|
||||
class RConnTableHelpers
|
||||
{
|
||||
public:
|
||||
struct WriteNumIndices : public vtkm::worklet::WorkletVisitCellsWithPoints
|
||||
@ -70,102 +77,137 @@ public:
|
||||
|
||||
public:
|
||||
template <typename CellSetPermutationType, typename Device>
|
||||
static vtkm::cont::ArrayHandle<vtkm::IdComponent> GetNumIndicesArray(
|
||||
static VTKM_CONT vtkm::cont::ArrayHandle<vtkm::IdComponent> GetNumIndicesArray(
|
||||
const CellSetPermutationType& cs,
|
||||
Device)
|
||||
{
|
||||
vtkm::cont::ArrayHandle<vtkm::IdComponent> numIndices;
|
||||
|
||||
vtkm::worklet::DispatcherMapTopology<WriteNumIndices> dispatcher;
|
||||
dispatcher.SetDevice(Device());
|
||||
dispatcher.Invoke(cs, numIndices);
|
||||
|
||||
vtkm::cont::Invoker{ Device{} }(WriteNumIndices{}, cs, numIndices);
|
||||
return numIndices;
|
||||
}
|
||||
|
||||
template <typename NumIndicesStorageType, typename Device>
|
||||
static vtkm::cont::ArrayHandle<vtkm::Id> GetIndexOffsetsArray(
|
||||
static VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Id> GetOffsetsArray(
|
||||
const vtkm::cont::ArrayHandle<vtkm::IdComponent, NumIndicesStorageType>& numIndices,
|
||||
vtkm::Id& connectivityLength,
|
||||
vtkm::Id& connectivityLength /* outparam */,
|
||||
Device)
|
||||
{
|
||||
return vtkm::cont::ConvertNumComponentsToOffsets(numIndices, connectivityLength);
|
||||
return vtkm::cont::ConvertNumIndicesToOffsets(numIndices, connectivityLength);
|
||||
}
|
||||
|
||||
template <typename CellSetPermutationType, typename IndexOffsetsStorageType, typename Device>
|
||||
template <typename CellSetPermutationType, typename OffsetsStorageType, typename Device>
|
||||
static vtkm::cont::ArrayHandle<vtkm::Id> GetConnectivityArray(
|
||||
const CellSetPermutationType& cs,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id, IndexOffsetsStorageType>& indexOffsets,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id, OffsetsStorageType>& offsets,
|
||||
vtkm::Id connectivityLength,
|
||||
Device)
|
||||
{
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> connectivity;
|
||||
connectivity.Allocate(connectivityLength);
|
||||
|
||||
vtkm::worklet::DispatcherMapTopology<WriteConnectivity> dispatcher;
|
||||
dispatcher.SetDevice(Device());
|
||||
dispatcher.Invoke(cs, vtkm::cont::make_ArrayHandleGroupVecVariable(connectivity, indexOffsets));
|
||||
|
||||
const auto offsetsTrim =
|
||||
vtkm::cont::make_ArrayHandleView(offsets, 0, offsets.GetNumberOfValues() - 1);
|
||||
auto connWrap = vtkm::cont::make_ArrayHandleGroupVecVariable(connectivity, offsetsTrim);
|
||||
vtkm::cont::Invoker{ Device{} }(WriteConnectivity{}, cs, connWrap);
|
||||
return connectivity;
|
||||
}
|
||||
};
|
||||
|
||||
// This holds the temporary input arrays for the ReverseConnectivityBuilder
|
||||
// algorithm.
|
||||
template <typename ConnectivityStorageTag = VTKM_DEFAULT_STORAGE_TAG,
|
||||
typename OffsetsStorageTag = VTKM_DEFAULT_STORAGE_TAG,
|
||||
typename NumIndicesStorageTag = VTKM_DEFAULT_STORAGE_TAG>
|
||||
struct RConnBuilderInputData
|
||||
{
|
||||
using ConnectivityArrayType = vtkm::cont::ArrayHandle<vtkm::Id, ConnectivityStorageTag>;
|
||||
using OffsetsArrayType = vtkm::cont::ArrayHandle<vtkm::Id, OffsetsStorageTag>;
|
||||
using NumIndicesArrayType = vtkm::cont::ArrayHandle<vtkm::IdComponent, NumIndicesStorageTag>;
|
||||
|
||||
ConnectivityArrayType Connectivity;
|
||||
OffsetsArrayType Offsets; // Includes the past-the-end offset.
|
||||
NumIndicesArrayType NumIndices;
|
||||
};
|
||||
|
||||
// default for CellSetPermutations of any cell type
|
||||
template <typename CellSetPermutationType>
|
||||
class CellSetPermutationVisitCellsWithPoints
|
||||
class RConnBuilderInput
|
||||
{
|
||||
public:
|
||||
using ConnectivityArrays = vtkm::cont::internal::ConnectivityExplicitInternals<>;
|
||||
using ConnectivityArrays = vtkm::cont::internal::RConnBuilderInputData<>;
|
||||
|
||||
template <typename Device>
|
||||
static ConnectivityArrays Get(const CellSetPermutationType& cellset, Device)
|
||||
{
|
||||
using Helper = RConnTableHelpers;
|
||||
ConnectivityArrays conn;
|
||||
vtkm::Id connectivityLength = 0;
|
||||
|
||||
conn.NumIndices =
|
||||
CellSetPermutationVisitCellsWithPointsHelpers::GetNumIndicesArray(cellset, Device{});
|
||||
conn.IndexOffsets = CellSetPermutationVisitCellsWithPointsHelpers::GetIndexOffsetsArray(
|
||||
conn.NumIndices, connectivityLength, Device{});
|
||||
conn.Connectivity = CellSetPermutationVisitCellsWithPointsHelpers::GetConnectivityArray(
|
||||
cellset, conn.IndexOffsets, connectivityLength, Device{});
|
||||
conn.NumIndices = Helper::GetNumIndicesArray(cellset, Device{});
|
||||
conn.Offsets = Helper::GetOffsetsArray(conn.NumIndices, connectivityLength, Device{});
|
||||
conn.Connectivity =
|
||||
Helper::GetConnectivityArray(cellset, conn.Offsets, connectivityLength, Device{});
|
||||
|
||||
return conn;
|
||||
}
|
||||
};
|
||||
|
||||
// Specialization for CellSetExplicit/CellSetSingleType
|
||||
template <typename S1, typename S2, typename S3, typename S4, typename PermutationArrayHandleType>
|
||||
class CellSetPermutationVisitCellsWithPoints<
|
||||
CellSetPermutation<CellSetExplicit<S1, S2, S3, S4>, PermutationArrayHandleType>>
|
||||
template <typename InShapesST,
|
||||
typename InConnST,
|
||||
typename InOffsetsST,
|
||||
typename PermutationArrayHandleType>
|
||||
class RConnBuilderInput<CellSetPermutation<CellSetExplicit<InShapesST, InConnST, InOffsetsST>,
|
||||
PermutationArrayHandleType>>
|
||||
{
|
||||
private:
|
||||
using CellSetPermutationType =
|
||||
CellSetPermutation<CellSetExplicit<S1, S2, S3, S4>, PermutationArrayHandleType>;
|
||||
using BaseCellSetType = CellSetExplicit<InShapesST, InConnST, InOffsetsST>;
|
||||
using CellSetPermutationType = CellSetPermutation<BaseCellSetType, PermutationArrayHandleType>;
|
||||
|
||||
using InShapesArrayType = typename BaseCellSetType::ShapesArrayType;
|
||||
using InNumIndicesArrayType = typename BaseCellSetType::NumIndicesArrayType;
|
||||
|
||||
using ShapesStorageTag = StorageTagPermutation<PermutationArrayHandleType, InShapesArrayType>;
|
||||
using ConnectivityStorageTag = vtkm::cont::ArrayHandle<vtkm::Id>::StorageTag;
|
||||
using OffsetsStorageTag = vtkm::cont::ArrayHandle<vtkm::Id>::StorageTag;
|
||||
using NumIndicesStorageTag =
|
||||
StorageTagPermutation<PermutationArrayHandleType, InNumIndicesArrayType>;
|
||||
|
||||
using NumIndicesArrayType =
|
||||
vtkm::cont::ArrayHandlePermutation<PermutationArrayHandleType,
|
||||
vtkm::cont::ArrayHandle<vtkm::IdComponent, S2>>;
|
||||
|
||||
public:
|
||||
using ConnectivityArrays = vtkm::cont::internal::ConnectivityExplicitInternals<
|
||||
VTKM_DEFAULT_STORAGE_TAG, // shapes array is not used
|
||||
typename NumIndicesArrayType::StorageTag>;
|
||||
using ConnectivityArrays = vtkm::cont::internal::RConnBuilderInputData<ConnectivityStorageTag,
|
||||
OffsetsStorageTag,
|
||||
NumIndicesStorageTag>;
|
||||
|
||||
template <typename Device>
|
||||
static ConnectivityArrays Get(const CellSetPermutationType& cellset, Device)
|
||||
{
|
||||
ConnectivityArrays conn;
|
||||
vtkm::Id connectivityLength = 0;
|
||||
using Helper = RConnTableHelpers;
|
||||
|
||||
conn.NumIndices =
|
||||
NumIndicesArrayType(cellset.GetValidCellIds(),
|
||||
cellset.GetFullCellSet().GetNumIndicesArray(
|
||||
vtkm::TopologyElementTagCell(), vtkm::TopologyElementTagPoint()));
|
||||
conn.IndexOffsets = CellSetPermutationVisitCellsWithPointsHelpers::GetIndexOffsetsArray(
|
||||
conn.NumIndices, connectivityLength, Device{});
|
||||
conn.Connectivity = CellSetPermutationVisitCellsWithPointsHelpers::GetConnectivityArray(
|
||||
cellset, conn.IndexOffsets, connectivityLength, Device{});
|
||||
static constexpr vtkm::TopologyElementTagCell cell{};
|
||||
static constexpr vtkm::TopologyElementTagPoint point{};
|
||||
|
||||
auto fullCellSet = cellset.GetFullCellSet();
|
||||
|
||||
vtkm::Id connectivityLength = 0;
|
||||
ConnectivityArrays conn;
|
||||
|
||||
fullCellSet.GetOffsetsArray(cell, point);
|
||||
|
||||
// We can use the implicitly generated NumIndices array to save a bit of
|
||||
// memory:
|
||||
conn.NumIndices = vtkm::cont::make_ArrayHandlePermutation(
|
||||
cellset.GetValidCellIds(), fullCellSet.GetNumIndicesArray(cell, point));
|
||||
|
||||
// Need to generate the offsets from scratch so that they're ordered for the
|
||||
// lower-bounds binary searches in ReverseConnectivityBuilder.
|
||||
conn.Offsets = Helper::GetOffsetsArray(conn.NumIndices, connectivityLength, Device{});
|
||||
|
||||
// Need to create a copy of this containing *only* the permuted cell defs,
|
||||
// in order, since the ReverseConnectivityBuilder will process every entry
|
||||
// in the connectivity array and we don't want the removed cells to be
|
||||
// included.
|
||||
conn.Connectivity =
|
||||
Helper::GetConnectivityArray(cellset, conn.Offsets, connectivityLength, Device{});
|
||||
|
||||
return conn;
|
||||
}
|
||||
@ -173,7 +215,7 @@ public:
|
||||
|
||||
// Specialization for CellSetStructured
|
||||
template <vtkm::IdComponent DIMENSION, typename PermutationArrayHandleType>
|
||||
class CellSetPermutationVisitCellsWithPoints<
|
||||
class RConnBuilderInput<
|
||||
CellSetPermutation<CellSetStructured<DIMENSION>, PermutationArrayHandleType>>
|
||||
{
|
||||
private:
|
||||
@ -181,11 +223,10 @@ private:
|
||||
CellSetPermutation<CellSetStructured<DIMENSION>, PermutationArrayHandleType>;
|
||||
|
||||
public:
|
||||
using ConnectivityArrays = vtkm::cont::internal::ConnectivityExplicitInternals<
|
||||
VTKM_DEFAULT_STORAGE_TAG, // shapes array is not used
|
||||
typename vtkm::cont::ArrayHandleConstant<vtkm::IdComponent>::StorageTag,
|
||||
using ConnectivityArrays = vtkm::cont::internal::RConnBuilderInputData<
|
||||
VTKM_DEFAULT_STORAGE_TAG,
|
||||
typename vtkm::cont::ArrayHandleCounting<vtkm::Id>::StorageTag>;
|
||||
typename vtkm::cont::ArrayHandleCounting<vtkm::Id>::StorageTag,
|
||||
typename vtkm::cont::ArrayHandleConstant<vtkm::IdComponent>::StorageTag>;
|
||||
|
||||
template <typename Device>
|
||||
static ConnectivityArrays Get(const CellSetPermutationType& cellset, Device)
|
||||
@ -197,9 +238,9 @@ public:
|
||||
|
||||
ConnectivityArrays conn;
|
||||
conn.NumIndices = make_ArrayHandleConstant(numPointsInCell, numberOfCells);
|
||||
conn.IndexOffsets = ArrayHandleCounting<vtkm::Id>(0, numPointsInCell, numberOfCells);
|
||||
conn.Connectivity = CellSetPermutationVisitCellsWithPointsHelpers::GetConnectivityArray(
|
||||
cellset, conn.IndexOffsets, connectivityLength, Device{});
|
||||
conn.Offsets = ArrayHandleCounting<vtkm::Id>(0, numPointsInCell, numberOfCells + 1);
|
||||
conn.Connectivity =
|
||||
RConnTableHelpers::GetConnectivityArray(cellset, conn.Offsets, connectivityLength, Device{});
|
||||
|
||||
return conn;
|
||||
}
|
||||
@ -312,11 +353,11 @@ public:
|
||||
const auto* other = dynamic_cast<const CellSetPermutation*>(src);
|
||||
if (!other)
|
||||
{
|
||||
throw vtkm::cont::ErrorBadType("CellSetPermutaion::DeepCopy types don't match");
|
||||
throw vtkm::cont::ErrorBadType("CellSetPermutation::DeepCopy types don't match");
|
||||
}
|
||||
|
||||
this->FullCellSet.DeepCopy(&(other->GetFullCellSet()));
|
||||
this->ValidCellIds = other->GetValidCellIds();
|
||||
vtkm::cont::ArrayCopy(other->GetValidCellIds(), this->ValidCellIds);
|
||||
}
|
||||
|
||||
//This is the way you can fill the memory from another system without copying
|
||||
@ -361,17 +402,16 @@ public:
|
||||
{
|
||||
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
||||
|
||||
using ConnectiviyPortalType =
|
||||
using ConnectivityPortalType =
|
||||
typename vtkm::cont::ArrayHandle<vtkm::Id>::template ExecutionTypes<Device>::PortalConst;
|
||||
using NumIndicesPortalType = typename vtkm::cont::ArrayHandle<
|
||||
vtkm::IdComponent>::template ExecutionTypes<Device>::PortalConst;
|
||||
using IndexOffsetPortalType =
|
||||
using OffsetPortalType =
|
||||
typename vtkm::cont::ArrayHandle<vtkm::Id>::template ExecutionTypes<Device>::PortalConst;
|
||||
|
||||
using ExecObjectType =
|
||||
vtkm::exec::ConnectivityPermutedVisitPointsWithCells<ConnectiviyPortalType,
|
||||
NumIndicesPortalType,
|
||||
IndexOffsetPortalType>;
|
||||
vtkm::exec::ConnectivityPermutedVisitPointsWithCells<ConnectivityPortalType,
|
||||
OffsetPortalType>;
|
||||
};
|
||||
|
||||
template <typename Device>
|
||||
@ -397,19 +437,16 @@ public:
|
||||
{
|
||||
if (!this->VisitPointsWithCells.ElementsValid)
|
||||
{
|
||||
auto pointToCell =
|
||||
internal::CellSetPermutationVisitCellsWithPoints<CellSetPermutation>::Get(*this, device);
|
||||
internal::ComputeVisitPointsWithCellsConnectivity(
|
||||
this->VisitPointsWithCells, pointToCell, this->GetNumberOfPoints(), device);
|
||||
this->VisitPointsWithCells.BuildIndexOffsets(device);
|
||||
auto connTable = internal::RConnBuilderInput<CellSetPermutation>::Get(*this, device);
|
||||
internal::ComputeRConnTable(
|
||||
this->VisitPointsWithCells, connTable, this->GetNumberOfPoints(), device);
|
||||
}
|
||||
|
||||
using ConnectivityType = typename ExecutionTypes<Device,
|
||||
vtkm::TopologyElementTagPoint,
|
||||
vtkm::TopologyElementTagCell>::ExecObjectType;
|
||||
return ConnectivityType(this->VisitPointsWithCells.Connectivity.PrepareForInput(device),
|
||||
this->VisitPointsWithCells.NumIndices.PrepareForInput(device),
|
||||
this->VisitPointsWithCells.IndexOffsets.PrepareForInput(device));
|
||||
this->VisitPointsWithCells.Offsets.PrepareForInput(device));
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
|
@ -30,19 +30,16 @@ namespace cont
|
||||
template <typename ConnectivityStorageTag = VTKM_DEFAULT_CONNECTIVITY_STORAGE_TAG>
|
||||
class VTKM_ALWAYS_EXPORT CellSetSingleType
|
||||
: public vtkm::cont::CellSetExplicit<
|
||||
typename vtkm::cont::ArrayHandleConstant<vtkm::UInt8>::StorageTag, //ShapeStorageTag
|
||||
typename vtkm::cont::ArrayHandleConstant<
|
||||
vtkm::IdComponent>::StorageTag, //NumIndicesStorageTag
|
||||
typename vtkm::cont::ArrayHandleConstant<vtkm::UInt8>::StorageTag, //ShapesStorageTag
|
||||
ConnectivityStorageTag,
|
||||
typename vtkm::cont::ArrayHandleCounting<vtkm::Id>::StorageTag //IndexOffsetStorageTag
|
||||
typename vtkm::cont::ArrayHandleCounting<vtkm::Id>::StorageTag //OffsetsStorageTag
|
||||
>
|
||||
{
|
||||
using Thisclass = vtkm::cont::CellSetSingleType<ConnectivityStorageTag>;
|
||||
using Superclass = vtkm::cont::CellSetExplicit<
|
||||
typename vtkm::cont::ArrayHandleConstant<vtkm::UInt8>::StorageTag,
|
||||
typename vtkm::cont::ArrayHandleConstant<vtkm::IdComponent>::StorageTag,
|
||||
ConnectivityStorageTag,
|
||||
typename vtkm::cont::ArrayHandleCounting<vtkm::Id>::StorageTag>;
|
||||
using Superclass =
|
||||
vtkm::cont::CellSetExplicit<typename vtkm::cont::ArrayHandleConstant<vtkm::UInt8>::StorageTag,
|
||||
ConnectivityStorageTag,
|
||||
typename vtkm::cont::ArrayHandleCounting<vtkm::Id>::StorageTag>;
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
@ -98,7 +95,7 @@ public:
|
||||
{
|
||||
this->CellShapeAsId = vtkm::CELL_SHAPE_EMPTY;
|
||||
|
||||
this->Data->VisitCellsWithPoints.Connectivity.Allocate(connectivityMaxLen);
|
||||
this->Data->CellPointIds.Connectivity.Allocate(connectivityMaxLen);
|
||||
|
||||
this->Data->NumberOfCellsAdded = 0;
|
||||
this->Data->ConnectivityAdded = 0;
|
||||
@ -119,10 +116,10 @@ public:
|
||||
}
|
||||
|
||||
if (this->Data->ConnectivityAdded + numVertices >
|
||||
this->Data->VisitCellsWithPoints.Connectivity.GetNumberOfValues())
|
||||
this->Data->CellPointIds.Connectivity.GetNumberOfValues())
|
||||
{
|
||||
throw vtkm::cont::ErrorBadValue(
|
||||
"Connectivity increased passed estimated maximum connectivity.");
|
||||
"Connectivity increased past estimated maximum connectivity.");
|
||||
}
|
||||
|
||||
if (this->CellShapeAsId == vtkm::CELL_SHAPE_EMPTY)
|
||||
@ -147,10 +144,10 @@ public:
|
||||
"Inconsistent number of points in cells for CellSetSingleType.");
|
||||
}
|
||||
}
|
||||
auto conn = this->Data->CellPointIds.Connectivity.GetPortalControl();
|
||||
for (vtkm::IdComponent iVert = 0; iVert < numVertices; ++iVert)
|
||||
{
|
||||
this->Data->VisitCellsWithPoints.Connectivity.GetPortalControl().Set(
|
||||
this->Data->ConnectivityAdded + iVert, Traits::GetComponent(ids, iVert));
|
||||
conn.Set(this->Data->ConnectivityAdded + iVert, Traits::GetComponent(ids, iVert));
|
||||
}
|
||||
this->Data->NumberOfCellsAdded++;
|
||||
this->Data->ConnectivityAdded += numVertices;
|
||||
@ -161,19 +158,16 @@ public:
|
||||
void CompleteAddingCells(vtkm::Id numPoints)
|
||||
{
|
||||
this->Data->NumberOfPoints = numPoints;
|
||||
this->VisitCellsWithPoints.Connectivity.Shrink(this->ConnectivityAdded);
|
||||
this->CellPointIds.Connectivity.Shrink(this->ConnectivityAdded);
|
||||
|
||||
vtkm::Id numCells = this->NumberOfCellsAdded;
|
||||
|
||||
this->VisitCellsWithPoints.Shapes =
|
||||
this->CellPointIds.Shapes =
|
||||
vtkm::cont::make_ArrayHandleConstant(this->GetCellShape(0), numCells);
|
||||
this->VisitCellsWithPoints.NumIndices =
|
||||
vtkm::cont::make_ArrayHandleConstant(this->NumberOfPointsPerCell, numCells);
|
||||
this->VisitCellsWithPoints.IndexOffsets = vtkm::cont::make_ArrayHandleCounting(
|
||||
this->CellPointIds.IndexOffsets = vtkm::cont::make_ArrayHandleCounting(
|
||||
vtkm::Id(0), static_cast<vtkm::Id>(this->NumberOfPointsPerCell), numCells);
|
||||
|
||||
this->VisitCellsWithPoints.ElementsValid = true;
|
||||
this->VisitCellsWithPoints.IndexOffsetsValid = true;
|
||||
this->CellPointIds.ElementsValid = true;
|
||||
|
||||
if (this->ExpectedNumberOfCellsAdded != this->GetNumberOfCells())
|
||||
{
|
||||
@ -195,18 +189,18 @@ public:
|
||||
this->Data->NumberOfPoints = numPoints;
|
||||
this->CellShapeAsId = shapeId;
|
||||
this->CheckNumberOfPointsPerCell(numberOfPointsPerCell);
|
||||
|
||||
const vtkm::Id numCells = connectivity.GetNumberOfValues() / numberOfPointsPerCell;
|
||||
VTKM_ASSERT((connectivity.GetNumberOfValues() % numberOfPointsPerCell) == 0);
|
||||
this->Data->VisitCellsWithPoints.Shapes =
|
||||
vtkm::cont::make_ArrayHandleConstant(shapeId, numCells);
|
||||
this->Data->VisitCellsWithPoints.NumIndices =
|
||||
vtkm::cont::make_ArrayHandleConstant(numberOfPointsPerCell, numCells);
|
||||
this->Data->VisitCellsWithPoints.IndexOffsets = vtkm::cont::make_ArrayHandleCounting(
|
||||
vtkm::Id(0), static_cast<vtkm::Id>(numberOfPointsPerCell), numCells);
|
||||
this->Data->VisitCellsWithPoints.Connectivity = connectivity;
|
||||
|
||||
this->Data->VisitCellsWithPoints.ElementsValid = true;
|
||||
this->Data->VisitCellsWithPoints.IndexOffsetsValid = true;
|
||||
this->Data->CellPointIds.Shapes = vtkm::cont::make_ArrayHandleConstant(shapeId, numCells);
|
||||
|
||||
this->Data->CellPointIds.Offsets = vtkm::cont::make_ArrayHandleCounting(
|
||||
vtkm::Id(0), static_cast<vtkm::Id>(numberOfPointsPerCell), numCells + 1);
|
||||
|
||||
this->Data->CellPointIds.Connectivity = connectivity;
|
||||
|
||||
this->Data->CellPointIds.ElementsValid = true;
|
||||
|
||||
this->ResetConnectivity(TopologyElementTagPoint{}, TopologyElementTagCell{});
|
||||
}
|
||||
@ -242,11 +236,11 @@ public:
|
||||
|
||||
virtual void PrintSummary(std::ostream& out) const override
|
||||
{
|
||||
out << " CellSetSingleType ShapeType " << this->CellShapeAsId << std::endl;
|
||||
out << " VisitCellsWithPoints: " << std::endl;
|
||||
this->Data->VisitCellsWithPoints.PrintSummary(out);
|
||||
out << " VisitPointsWithCells: " << std::endl;
|
||||
this->Data->VisitPointsWithCells.PrintSummary(out);
|
||||
out << " CellSetSingleType: Type=" << this->CellShapeAsId << std::endl;
|
||||
out << " CellPointIds:" << std::endl;
|
||||
this->Data->CellPointIds.PrintSummary(out);
|
||||
out << " PointCellIds:" << std::endl;
|
||||
this->Data->PointCellIds.PrintSummary(out);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -10,6 +10,8 @@
|
||||
#ifndef vtk_m_cont_DataSetBuilderExplicit_h
|
||||
#define vtk_m_cont_DataSetBuilderExplicit_h
|
||||
|
||||
#include <vtkm/cont/Algorithm.h>
|
||||
#include <vtkm/cont/ArrayHandleCast.h>
|
||||
#include <vtkm/cont/ArrayHandleCompositeVector.h>
|
||||
#include <vtkm/cont/ArrayPortalToIterators.h>
|
||||
#include <vtkm/cont/CoordinateSystem.h>
|
||||
@ -21,17 +23,9 @@ namespace cont
|
||||
{
|
||||
|
||||
//Coordinates builder??
|
||||
//Need a singlecellset handler.
|
||||
|
||||
class VTKM_CONT_EXPORT DataSetBuilderExplicit
|
||||
{
|
||||
template <typename T>
|
||||
VTKM_CONT static void CopyInto(const std::vector<T>& input, vtkm::cont::ArrayHandle<T>& output)
|
||||
{
|
||||
output.Allocate(static_cast<vtkm::Id>(input.size()));
|
||||
std::copy(input.begin(), input.end(), ArrayPortalToIteratorBegin(output.GetPortalControl()));
|
||||
}
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
DataSetBuilderExplicit() {}
|
||||
@ -84,8 +78,10 @@ public:
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id>& connectivity,
|
||||
const std::string& coordsNm = "coords")
|
||||
{
|
||||
auto offsets = vtkm::cont::ConvertNumIndicesToOffsets(numIndices);
|
||||
|
||||
return DataSetBuilderExplicit::BuildDataSet(
|
||||
xVals, yVals, zVals, shapes, numIndices, connectivity, coordsNm);
|
||||
xVals, yVals, zVals, shapes, offsets, connectivity, coordsNm);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -103,7 +99,8 @@ public:
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id>& connectivity,
|
||||
const std::string& coordsNm = "coords")
|
||||
{
|
||||
return DataSetBuilderExplicit::BuildDataSet(coords, shapes, numIndices, connectivity, coordsNm);
|
||||
auto offsets = vtkm::cont::ConvertNumIndicesToOffsets(numIndices);
|
||||
return DataSetBuilderExplicit::BuildDataSet(coords, shapes, offsets, connectivity, coordsNm);
|
||||
}
|
||||
|
||||
template <typename T, typename CellShapeTag>
|
||||
@ -127,20 +124,19 @@ public:
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
static vtkm::cont::DataSet BuildDataSet(
|
||||
const vtkm::cont::ArrayHandle<T>& X,
|
||||
const vtkm::cont::ArrayHandle<T>& Y,
|
||||
const vtkm::cont::ArrayHandle<T>& Z,
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8>& shapes,
|
||||
const vtkm::cont::ArrayHandle<vtkm::IdComponent>& numIndices,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id>& connectivity,
|
||||
const std::string& coordsNm);
|
||||
static vtkm::cont::DataSet BuildDataSet(const vtkm::cont::ArrayHandle<T>& X,
|
||||
const vtkm::cont::ArrayHandle<T>& Y,
|
||||
const vtkm::cont::ArrayHandle<T>& Z,
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8>& shapes,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id>& offsets,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id>& connectivity,
|
||||
const std::string& coordsNm);
|
||||
|
||||
template <typename T>
|
||||
VTKM_CONT static vtkm::cont::DataSet BuildDataSet(
|
||||
const vtkm::cont::ArrayHandle<vtkm::Vec<T, 3>>& coords,
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8>& shapes,
|
||||
const vtkm::cont::ArrayHandle<vtkm::IdComponent>& numIndices,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id>& offsets,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id>& connectivity,
|
||||
const std::string& coordsNm);
|
||||
|
||||
@ -165,19 +161,18 @@ inline VTKM_CONT vtkm::cont::DataSet DataSetBuilderExplicit::Create(
|
||||
{
|
||||
VTKM_ASSERT(xVals.size() == yVals.size() && yVals.size() == zVals.size() && xVals.size() > 0);
|
||||
|
||||
vtkm::cont::ArrayHandle<T> Xc, Yc, Zc;
|
||||
DataSetBuilderExplicit::CopyInto(xVals, Xc);
|
||||
DataSetBuilderExplicit::CopyInto(yVals, Yc);
|
||||
DataSetBuilderExplicit::CopyInto(zVals, Zc);
|
||||
auto xArray = vtkm::cont::make_ArrayHandle(xVals, vtkm::CopyFlag::On);
|
||||
auto yArray = vtkm::cont::make_ArrayHandle(yVals, vtkm::CopyFlag::On);
|
||||
auto zArray = vtkm::cont::make_ArrayHandle(zVals, vtkm::CopyFlag::On);
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::UInt8> Sc;
|
||||
vtkm::cont::ArrayHandle<vtkm::IdComponent> Nc;
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> Cc;
|
||||
DataSetBuilderExplicit::CopyInto(shapes, Sc);
|
||||
DataSetBuilderExplicit::CopyInto(numIndices, Nc);
|
||||
DataSetBuilderExplicit::CopyInto(connectivity, Cc);
|
||||
auto shapesArray = vtkm::cont::make_ArrayHandle(shapes, vtkm::CopyFlag::On);
|
||||
auto connArray = vtkm::cont::make_ArrayHandle(connectivity, vtkm::CopyFlag::On);
|
||||
|
||||
return DataSetBuilderExplicit::BuildDataSet(Xc, Yc, Zc, Sc, Nc, Cc, coordsNm);
|
||||
auto offsetsArray = vtkm::cont::ConvertNumIndicesToOffsets(
|
||||
vtkm::cont::make_ArrayHandle(numIndices, vtkm::CopyFlag::Off));
|
||||
|
||||
return DataSetBuilderExplicit::BuildDataSet(
|
||||
xArray, yArray, zArray, shapesArray, offsetsArray, connArray, coordsNm);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -186,13 +181,13 @@ inline VTKM_CONT vtkm::cont::DataSet DataSetBuilderExplicit::BuildDataSet(
|
||||
const vtkm::cont::ArrayHandle<T>& Y,
|
||||
const vtkm::cont::ArrayHandle<T>& Z,
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8>& shapes,
|
||||
const vtkm::cont::ArrayHandle<vtkm::IdComponent>& numIndices,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id>& offsets,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id>& connectivity,
|
||||
const std::string& coordsNm)
|
||||
{
|
||||
VTKM_ASSERT(X.GetNumberOfValues() == Y.GetNumberOfValues() &&
|
||||
Y.GetNumberOfValues() == Z.GetNumberOfValues() && X.GetNumberOfValues() > 0 &&
|
||||
shapes.GetNumberOfValues() == numIndices.GetNumberOfValues());
|
||||
shapes.GetNumberOfValues() + 1 == offsets.GetNumberOfValues());
|
||||
|
||||
vtkm::cont::DataSet dataSet;
|
||||
dataSet.AddCoordinateSystem(
|
||||
@ -200,7 +195,7 @@ inline VTKM_CONT vtkm::cont::DataSet DataSetBuilderExplicit::BuildDataSet(
|
||||
vtkm::Id nPts = X.GetNumberOfValues();
|
||||
vtkm::cont::CellSetExplicit<> cellSet;
|
||||
|
||||
cellSet.Fill(nPts, shapes, numIndices, connectivity);
|
||||
cellSet.Fill(nPts, shapes, connectivity, offsets);
|
||||
dataSet.SetCellSet(cellSet);
|
||||
|
||||
return dataSet;
|
||||
@ -214,24 +209,22 @@ inline VTKM_CONT vtkm::cont::DataSet DataSetBuilderExplicit::Create(
|
||||
const std::vector<vtkm::Id>& connectivity,
|
||||
const std::string& coordsNm)
|
||||
{
|
||||
vtkm::cont::ArrayHandle<Vec<T, 3>> coordsArray;
|
||||
DataSetBuilderExplicit::CopyInto(coords, coordsArray);
|
||||
auto coordsArray = vtkm::cont::make_ArrayHandle(coords, vtkm::CopyFlag::On);
|
||||
auto shapesArray = vtkm::cont::make_ArrayHandle(shapes, vtkm::CopyFlag::On);
|
||||
auto connArray = vtkm::cont::make_ArrayHandle(connectivity, vtkm::CopyFlag::On);
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::UInt8> Sc;
|
||||
vtkm::cont::ArrayHandle<vtkm::IdComponent> Nc;
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> Cc;
|
||||
DataSetBuilderExplicit::CopyInto(shapes, Sc);
|
||||
DataSetBuilderExplicit::CopyInto(numIndices, Nc);
|
||||
DataSetBuilderExplicit::CopyInto(connectivity, Cc);
|
||||
auto offsetsArray = vtkm::cont::ConvertNumIndicesToOffsets(
|
||||
vtkm::cont::make_ArrayHandle(numIndices, vtkm::CopyFlag::Off));
|
||||
|
||||
return DataSetBuilderExplicit::Create(coordsArray, Sc, Nc, Cc, coordsNm);
|
||||
return DataSetBuilderExplicit::BuildDataSet(
|
||||
coordsArray, shapesArray, offsetsArray, connArray, coordsNm);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline VTKM_CONT vtkm::cont::DataSet DataSetBuilderExplicit::BuildDataSet(
|
||||
const vtkm::cont::ArrayHandle<vtkm::Vec<T, 3>>& coords,
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8>& shapes,
|
||||
const vtkm::cont::ArrayHandle<vtkm::IdComponent>& numIndices,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id>& offsets,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id>& connectivity,
|
||||
const std::string& coordsNm)
|
||||
{
|
||||
@ -241,7 +234,7 @@ inline VTKM_CONT vtkm::cont::DataSet DataSetBuilderExplicit::BuildDataSet(
|
||||
vtkm::Id nPts = static_cast<vtkm::Id>(coords.GetNumberOfValues());
|
||||
vtkm::cont::CellSetExplicit<> cellSet;
|
||||
|
||||
cellSet.Fill(nPts, shapes, numIndices, connectivity);
|
||||
cellSet.Fill(nPts, shapes, connectivity, offsets);
|
||||
dataSet.SetCellSet(cellSet);
|
||||
|
||||
return dataSet;
|
||||
@ -255,13 +248,11 @@ inline VTKM_CONT vtkm::cont::DataSet DataSetBuilderExplicit::Create(
|
||||
const std::vector<vtkm::Id>& connectivity,
|
||||
const std::string& coordsNm)
|
||||
{
|
||||
vtkm::cont::ArrayHandle<Vec<T, 3>> coordsArray;
|
||||
DataSetBuilderExplicit::CopyInto(coords, coordsArray);
|
||||
auto coordsArray = vtkm::cont::make_ArrayHandle(coords, vtkm::CopyFlag::On);
|
||||
auto connArray = vtkm::cont::make_ArrayHandle(connectivity, vtkm::CopyFlag::On);
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> Cc;
|
||||
DataSetBuilderExplicit::CopyInto(connectivity, Cc);
|
||||
|
||||
return DataSetBuilderExplicit::Create(coordsArray, tag, numberOfPointsPerCell, Cc, coordsNm);
|
||||
return DataSetBuilderExplicit::Create(
|
||||
coordsArray, tag, numberOfPointsPerCell, connArray, coordsNm);
|
||||
}
|
||||
|
||||
template <typename T, typename CellShapeTag>
|
||||
|
@ -134,7 +134,7 @@ struct DeviceAdapterAlgorithm
|
||||
template <typename WordType>
|
||||
VTKM_CONT static void Fill(vtkm::cont::BitField& bits, WordType word, vtkm::Id numBits);
|
||||
template <typename WordType>
|
||||
VTKM_CONT static void Fill(vtkm::cont::BitField& bits, WordType word, bool value);
|
||||
VTKM_CONT static void Fill(vtkm::cont::BitField& bits, WordType word);
|
||||
/// @}
|
||||
|
||||
/// Fill @a array with @a value. If @a numValues is specified, the array will
|
||||
@ -253,16 +253,6 @@ struct DeviceAdapterAlgorithm
|
||||
VTKM_CONT static T ScanInclusive(const vtkm::cont::ArrayHandle<T, CIn>& input,
|
||||
vtkm::cont::ArrayHandle<T, COut>& output);
|
||||
|
||||
/// \brief Streaming version of scan exclusive
|
||||
///
|
||||
/// Computes a scan one block at a time.
|
||||
///
|
||||
/// \return The total sum.
|
||||
///
|
||||
template <typename T, class CIn, class COut>
|
||||
VTKM_CONT static T StreamingScanExclusive(const vtkm::Id numBlocks,
|
||||
const vtkm::cont::ArrayHandle<T, CIn>& input,
|
||||
vtkm::cont::ArrayHandle<T, COut>& output);
|
||||
|
||||
/// \brief Compute an inclusive prefix sum operation on the input ArrayHandle.
|
||||
///
|
||||
@ -378,6 +368,17 @@ struct DeviceAdapterAlgorithm
|
||||
const vtkm::cont::ArrayHandle<U, VIn>& values,
|
||||
vtkm::cont::ArrayHandle<U, VOut>& output);
|
||||
|
||||
/// \brief Streaming version of scan exclusive
|
||||
///
|
||||
/// Computes a scan one block at a time.
|
||||
///
|
||||
/// \return The total sum.
|
||||
///
|
||||
template <typename T, class CIn, class COut>
|
||||
VTKM_CONT static T StreamingScanExclusive(const vtkm::Id numBlocks,
|
||||
const vtkm::cont::ArrayHandle<T, CIn>& input,
|
||||
vtkm::cont::ArrayHandle<T, COut>& output);
|
||||
|
||||
/// \brief Compute an extended prefix sum operation on the input ArrayHandle.
|
||||
///
|
||||
/// Computes an extended prefix sum operation on the \c input ArrayHandle,
|
||||
|
@ -22,6 +22,13 @@ namespace vtkm
|
||||
namespace cont
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <typename T>
|
||||
using scatter_or_mask = std::integral_constant<bool,
|
||||
vtkm::worklet::internal::is_mask<T>::value ||
|
||||
vtkm::worklet::internal::is_scatter<T>::value>;
|
||||
}
|
||||
|
||||
/// \brief Allows launching any worklet without a dispatcher.
|
||||
///
|
||||
@ -53,40 +60,59 @@ struct Invoker
|
||||
}
|
||||
|
||||
/// Launch the worklet that is provided as the first parameter.
|
||||
/// Optional second parameter is the scatter type associated with the worklet.
|
||||
/// Optional second parameter is either the scatter or mask type associated with the worklet.
|
||||
/// Any additional parameters are the ControlSignature arguments for the worklet.
|
||||
///
|
||||
template <
|
||||
typename Worklet,
|
||||
typename T,
|
||||
typename... Args,
|
||||
typename std::enable_if<std::is_base_of<worklet::internal::ScatterBase,
|
||||
worklet::internal::detail::remove_cvref<T>>::value,
|
||||
int>::type* = nullptr>
|
||||
inline void operator()(Worklet&& worklet, T&& scatter, Args&&... args) const
|
||||
template <typename Worklet,
|
||||
typename T,
|
||||
typename... Args,
|
||||
typename std::enable_if<detail::scatter_or_mask<T>::value, int>::type* = nullptr>
|
||||
inline void operator()(Worklet&& worklet, T&& scatterOrMask, Args&&... args) const
|
||||
{
|
||||
using WorkletType = worklet::internal::detail::remove_cvref<Worklet>;
|
||||
using WorkletType = worklet::internal::remove_cvref<Worklet>;
|
||||
using DispatcherType = typename WorkletType::template Dispatcher<WorkletType>;
|
||||
|
||||
DispatcherType dispatcher(worklet, scatter);
|
||||
DispatcherType dispatcher(worklet, scatterOrMask);
|
||||
dispatcher.SetDevice(this->DeviceId);
|
||||
dispatcher.Invoke(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
/// Launch the worklet that is provided as the first parameter.
|
||||
/// Optional second parameter is the scatter type associated with the worklet.
|
||||
/// Optional second parameter is either the scatter or mask type associated with the worklet.
|
||||
/// Optional third parameter is either the scatter or mask type associated with the worklet.
|
||||
/// Any additional parameters are the ControlSignature arguments for the worklet.
|
||||
///
|
||||
template <
|
||||
typename Worklet,
|
||||
typename T,
|
||||
typename U,
|
||||
typename... Args,
|
||||
typename std::enable_if<!std::is_base_of<worklet::internal::ScatterBase,
|
||||
worklet::internal::detail::remove_cvref<T>>::value,
|
||||
typename std::enable_if<detail::scatter_or_mask<T>::value && detail::scatter_or_mask<U>::value,
|
||||
int>::type* = nullptr>
|
||||
inline void operator()(Worklet&& worklet,
|
||||
T&& scatterOrMaskA,
|
||||
U&& scatterOrMaskB,
|
||||
Args&&... args) const
|
||||
{
|
||||
using WorkletType = worklet::internal::remove_cvref<Worklet>;
|
||||
using DispatcherType = typename WorkletType::template Dispatcher<WorkletType>;
|
||||
|
||||
DispatcherType dispatcher(worklet, scatterOrMaskA, scatterOrMaskB);
|
||||
dispatcher.SetDevice(this->DeviceId);
|
||||
dispatcher.Invoke(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
/// Launch the worklet that is provided as the first parameter.
|
||||
/// Optional second parameter is either the scatter or mask type associated with the worklet.
|
||||
/// Any additional parameters are the ControlSignature arguments for the worklet.
|
||||
///
|
||||
template <typename Worklet,
|
||||
typename T,
|
||||
typename... Args,
|
||||
typename std::enable_if<!detail::scatter_or_mask<T>::value, int>::type* = nullptr>
|
||||
inline void operator()(Worklet&& worklet, T&& t, Args&&... args) const
|
||||
{
|
||||
using WorkletType = worklet::internal::detail::remove_cvref<Worklet>;
|
||||
using WorkletType = worklet::internal::remove_cvref<Worklet>;
|
||||
using DispatcherType = typename WorkletType::template Dispatcher<WorkletType>;
|
||||
|
||||
DispatcherType dispatcher(worklet);
|
||||
|
@ -111,6 +111,7 @@ void InitLogging(int& argc, char* argv[])
|
||||
SetLogLevelName(vtkm::cont::LogLevel::Error, "ERR");
|
||||
SetLogLevelName(vtkm::cont::LogLevel::Warn, "WARN");
|
||||
SetLogLevelName(vtkm::cont::LogLevel::Info, "Info");
|
||||
SetLogLevelName(vtkm::cont::LogLevel::DevicesEnabled, "Dev");
|
||||
SetLogLevelName(vtkm::cont::LogLevel::Perf, "Perf");
|
||||
SetLogLevelName(vtkm::cont::LogLevel::MemCont, "MemC");
|
||||
SetLogLevelName(vtkm::cont::LogLevel::MemExec, "MemE");
|
||||
|
@ -322,6 +322,9 @@ enum class LogLevel
|
||||
/// The range 1-255 are reserved to application use.
|
||||
UserLast = 255,
|
||||
|
||||
/// Information about which devices are enabled/disabled
|
||||
DevicesEnabled,
|
||||
|
||||
/// General timing data and algorithm flow information, such as filter
|
||||
/// execution, worklet dispatches, and device algorithm calls.
|
||||
Perf,
|
||||
@ -482,9 +485,9 @@ static inline VTKM_CONT std::string TypeToString()
|
||||
return TypeToString(typeid(T));
|
||||
}
|
||||
template <typename T>
|
||||
static inline VTKM_CONT std::string TypeToString(const T& t)
|
||||
static inline VTKM_CONT std::string TypeToString(const T&)
|
||||
{
|
||||
return TypeToString(typeid(t));
|
||||
return TypeToString(typeid(T));
|
||||
}
|
||||
/**@}*/
|
||||
}
|
||||
|
@ -86,8 +86,6 @@ void RuntimeDeviceTracker::SetDeviceState(vtkm::cont::DeviceAdapterId deviceId,
|
||||
{
|
||||
this->CheckDevice(deviceId);
|
||||
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Info,
|
||||
"Setting device '" << deviceId.GetName() << "' to " << state);
|
||||
this->Internals->RuntimeAllowed[deviceId.GetValue()] = state;
|
||||
}
|
||||
|
||||
@ -102,6 +100,7 @@ VTKM_CONT void RuntimeDeviceTracker::ResetDevice(vtkm::cont::DeviceAdapterId dev
|
||||
{
|
||||
vtkm::cont::RuntimeDeviceInformation runtimeDevice;
|
||||
this->SetDeviceState(deviceId, runtimeDevice.Exists(deviceId));
|
||||
this->LogEnabledDevices();
|
||||
}
|
||||
}
|
||||
|
||||
@ -122,10 +121,9 @@ void RuntimeDeviceTracker::Reset()
|
||||
{
|
||||
const bool state = runtimeDevice.Exists(device);
|
||||
this->Internals->RuntimeAllowed[device.GetValue()] = state;
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Info,
|
||||
"Reset device '" << device.GetName() << "' to " << state);
|
||||
}
|
||||
}
|
||||
this->LogEnabledDevices();
|
||||
}
|
||||
|
||||
VTKM_CONT void RuntimeDeviceTracker::DisableDevice(vtkm::cont::DeviceAdapterId deviceId)
|
||||
@ -138,6 +136,7 @@ VTKM_CONT void RuntimeDeviceTracker::DisableDevice(vtkm::cont::DeviceAdapterId d
|
||||
{
|
||||
this->SetDeviceState(deviceId, false);
|
||||
}
|
||||
this->LogEnabledDevices();
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
@ -160,12 +159,10 @@ void RuntimeDeviceTracker::ForceDevice(DeviceAdapterId deviceId)
|
||||
throw vtkm::cont::ErrorBadValue(message.str());
|
||||
}
|
||||
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Info,
|
||||
"Forcing execution to occur on device '" << deviceId.GetName() << "'");
|
||||
|
||||
std::fill_n(this->Internals->RuntimeAllowed, VTKM_MAX_DEVICE_ADAPTER_ID, false);
|
||||
|
||||
this->Internals->RuntimeAllowed[deviceId.GetValue()] = runtimeExists;
|
||||
this->LogEnabledDevices();
|
||||
}
|
||||
}
|
||||
|
||||
@ -180,12 +177,35 @@ void RuntimeDeviceTracker::PrintSummary(std::ostream& out) const
|
||||
}
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
void RuntimeDeviceTracker::LogEnabledDevices() const
|
||||
{
|
||||
std::stringstream message;
|
||||
message << "Enabled devices:";
|
||||
bool atLeastOneDeviceEnabled = false;
|
||||
for (vtkm::Int8 deviceIndex = 1; deviceIndex < VTKM_MAX_DEVICE_ADAPTER_ID; ++deviceIndex)
|
||||
{
|
||||
vtkm::cont::DeviceAdapterId device = vtkm::cont::make_DeviceAdapterId(deviceIndex);
|
||||
if (this->CanRunOn(device))
|
||||
{
|
||||
message << " " << device.GetName();
|
||||
atLeastOneDeviceEnabled = true;
|
||||
}
|
||||
}
|
||||
if (!atLeastOneDeviceEnabled)
|
||||
{
|
||||
message << " NONE!";
|
||||
}
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::DevicesEnabled, message.str());
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
ScopedRuntimeDeviceTracker::ScopedRuntimeDeviceTracker(vtkm::cont::DeviceAdapterId device,
|
||||
RuntimeDeviceTrackerMode mode)
|
||||
: RuntimeDeviceTracker(GetRuntimeDeviceTracker().Internals, false)
|
||||
, SavedState(new detail::RuntimeDeviceTrackerInternals())
|
||||
{
|
||||
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);
|
||||
|
||||
@ -211,6 +231,7 @@ ScopedRuntimeDeviceTracker::ScopedRuntimeDeviceTracker(
|
||||
: RuntimeDeviceTracker(tracker.Internals, false)
|
||||
, SavedState(new detail::RuntimeDeviceTrackerInternals())
|
||||
{
|
||||
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)
|
||||
@ -233,6 +254,7 @@ ScopedRuntimeDeviceTracker::ScopedRuntimeDeviceTracker(
|
||||
: RuntimeDeviceTracker(tracker.Internals, false)
|
||||
, SavedState(new detail::RuntimeDeviceTrackerInternals())
|
||||
{
|
||||
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);
|
||||
}
|
||||
@ -240,8 +262,10 @@ ScopedRuntimeDeviceTracker::ScopedRuntimeDeviceTracker(
|
||||
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->LogEnabledDevices();
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
|
@ -131,6 +131,9 @@ private:
|
||||
|
||||
VTKM_CONT
|
||||
void SetDeviceState(vtkm::cont::DeviceAdapterId deviceId, bool state);
|
||||
|
||||
VTKM_CONT
|
||||
void LogEnabledDevices() const;
|
||||
};
|
||||
|
||||
|
||||
|
@ -22,7 +22,6 @@ set(headers
|
||||
ConnectivityExplicitInternals.h
|
||||
DeviceAdapterAlgorithmGeneral.h
|
||||
DeviceAdapterListHelpers.h
|
||||
DynamicTransform.h
|
||||
FunctorsGeneral.h
|
||||
IteratorFromArrayPortal.h
|
||||
KXSort.h
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
#include <vtkm/CellShape.h>
|
||||
#include <vtkm/cont/Algorithm.h>
|
||||
#include <vtkm/cont/ArrayGetValues.h>
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
#include <vtkm/cont/ArrayHandleCast.h>
|
||||
#include <vtkm/cont/ArrayHandleConstant.h>
|
||||
@ -26,67 +27,24 @@ namespace cont
|
||||
namespace internal
|
||||
{
|
||||
|
||||
template <typename NumIndicesArrayType, typename IndexOffsetArrayType>
|
||||
void buildIndexOffsets(const NumIndicesArrayType& numIndices,
|
||||
IndexOffsetArrayType& offsets,
|
||||
vtkm::cont::DeviceAdapterId device,
|
||||
std::true_type)
|
||||
{
|
||||
//We first need to make sure that NumIndices and IndexOffsetArrayType
|
||||
//have the same type so we can call scane exclusive
|
||||
using CastedNumIndicesType = vtkm::cont::ArrayHandleCast<vtkm::Id, NumIndicesArrayType>;
|
||||
|
||||
// Although technically we are making changes to this object, the changes
|
||||
// are logically consistent with the previous state, so we consider it
|
||||
// valid under const.
|
||||
vtkm::cont::Algorithm::ScanExclusive(device, CastedNumIndicesType(numIndices), offsets);
|
||||
}
|
||||
|
||||
template <typename NumIndicesArrayType, typename IndexOffsetArrayType>
|
||||
void buildIndexOffsets(const NumIndicesArrayType&,
|
||||
IndexOffsetArrayType&,
|
||||
vtkm::cont::DeviceAdapterId,
|
||||
std::false_type)
|
||||
{
|
||||
//this is a no-op as the storage for the offsets is an implicit handle
|
||||
//and should already be built. This signature exists so that
|
||||
//the compiler doesn't try to generate un-used code that will
|
||||
//try and run Algorithm::ScanExclusive on an implicit array which will
|
||||
//cause a compile time failure.
|
||||
}
|
||||
|
||||
template <typename ArrayHandleIndices, typename ArrayHandleOffsets>
|
||||
void buildIndexOffsets(const ArrayHandleIndices& numIndices,
|
||||
ArrayHandleOffsets offsets,
|
||||
vtkm::cont::DeviceAdapterId deviceId)
|
||||
{
|
||||
using IsWritable = vtkm::cont::internal::IsWritableArrayHandle<ArrayHandleOffsets>;
|
||||
buildIndexOffsets(numIndices, offsets, deviceId, typename IsWritable::type());
|
||||
}
|
||||
|
||||
template <typename ShapeStorageTag = VTKM_DEFAULT_STORAGE_TAG,
|
||||
typename NumIndicesStorageTag = VTKM_DEFAULT_STORAGE_TAG,
|
||||
template <typename ShapesStorageTag = VTKM_DEFAULT_STORAGE_TAG,
|
||||
typename ConnectivityStorageTag = VTKM_DEFAULT_STORAGE_TAG,
|
||||
typename IndexOffsetStorageTag = VTKM_DEFAULT_STORAGE_TAG>
|
||||
typename OffsetsStorageTag = VTKM_DEFAULT_STORAGE_TAG>
|
||||
struct ConnectivityExplicitInternals
|
||||
{
|
||||
using ShapeArrayType = vtkm::cont::ArrayHandle<vtkm::UInt8, ShapeStorageTag>;
|
||||
using NumIndicesArrayType = vtkm::cont::ArrayHandle<vtkm::IdComponent, NumIndicesStorageTag>;
|
||||
using ShapesArrayType = vtkm::cont::ArrayHandle<vtkm::UInt8, ShapesStorageTag>;
|
||||
using ConnectivityArrayType = vtkm::cont::ArrayHandle<vtkm::Id, ConnectivityStorageTag>;
|
||||
using IndexOffsetArrayType = vtkm::cont::ArrayHandle<vtkm::Id, IndexOffsetStorageTag>;
|
||||
using OffsetsArrayType = vtkm::cont::ArrayHandle<vtkm::Id, OffsetsStorageTag>;
|
||||
|
||||
ShapeArrayType Shapes;
|
||||
NumIndicesArrayType NumIndices;
|
||||
ShapesArrayType Shapes;
|
||||
ConnectivityArrayType Connectivity;
|
||||
mutable IndexOffsetArrayType IndexOffsets;
|
||||
OffsetsArrayType Offsets;
|
||||
|
||||
bool ElementsValid;
|
||||
mutable bool IndexOffsetsValid;
|
||||
|
||||
VTKM_CONT
|
||||
ConnectivityExplicitInternals()
|
||||
: ElementsValid(false)
|
||||
, IndexOffsetsValid(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -102,26 +60,8 @@ struct ConnectivityExplicitInternals
|
||||
void ReleaseResourcesExecution()
|
||||
{
|
||||
this->Shapes.ReleaseResourcesExecution();
|
||||
this->NumIndices.ReleaseResourcesExecution();
|
||||
this->Connectivity.ReleaseResourcesExecution();
|
||||
this->IndexOffsets.ReleaseResourcesExecution();
|
||||
}
|
||||
|
||||
|
||||
VTKM_CONT void BuildIndexOffsets(vtkm::cont::DeviceAdapterId deviceId) const
|
||||
{
|
||||
if (deviceId == vtkm::cont::DeviceAdapterTagUndefined())
|
||||
{
|
||||
throw vtkm::cont::ErrorBadValue("Cannot build indices using DeviceAdapterTagUndefined");
|
||||
}
|
||||
|
||||
VTKM_ASSERT(this->ElementsValid);
|
||||
|
||||
if (!this->IndexOffsetsValid)
|
||||
{
|
||||
buildIndexOffsets(this->NumIndices, this->IndexOffsets, deviceId);
|
||||
this->IndexOffsetsValid = true;
|
||||
}
|
||||
this->Offsets.ReleaseResourcesExecution();
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
@ -131,19 +71,10 @@ struct ConnectivityExplicitInternals
|
||||
{
|
||||
out << " Shapes: ";
|
||||
vtkm::cont::printSummary_ArrayHandle(this->Shapes, out);
|
||||
out << " NumIndices: ";
|
||||
vtkm::cont::printSummary_ArrayHandle(this->NumIndices, out);
|
||||
out << " Connectivity: ";
|
||||
vtkm::cont::printSummary_ArrayHandle(this->Connectivity, out);
|
||||
if (this->IndexOffsetsValid)
|
||||
{
|
||||
out << " IndexOffsets: ";
|
||||
vtkm::cont::printSummary_ArrayHandle(this->IndexOffsets, out);
|
||||
}
|
||||
else
|
||||
{
|
||||
out << " IndexOffsets: Not Allocated" << std::endl;
|
||||
}
|
||||
out << " Offsets: ";
|
||||
vtkm::cont::printSummary_ArrayHandle(this->Offsets, out);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -225,95 +156,73 @@ struct ConnIdxToCellIdCalcSingleType
|
||||
vtkm::Id operator()(vtkm::Id inIdx) const { return inIdx / this->CellSize; }
|
||||
};
|
||||
|
||||
template <typename VisitCellsWithPoints, typename VisitPointsWithCells, typename Device>
|
||||
void ComputeVisitPointsWithCellsConnectivity(VisitPointsWithCells& cell2Point,
|
||||
const VisitCellsWithPoints& point2Cell,
|
||||
vtkm::Id numberOfPoints,
|
||||
Device)
|
||||
template <typename ConnTableT, typename RConnTableT, typename Device>
|
||||
void ComputeRConnTable(RConnTableT& rConnTable,
|
||||
const ConnTableT& connTable,
|
||||
vtkm::Id numberOfPoints,
|
||||
Device)
|
||||
{
|
||||
if (cell2Point.ElementsValid)
|
||||
if (rConnTable.ElementsValid)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto& conn = point2Cell.Connectivity;
|
||||
auto& rConn = cell2Point.Connectivity;
|
||||
auto& rNumIndices = cell2Point.NumIndices;
|
||||
auto& rIndexOffsets = cell2Point.IndexOffsets;
|
||||
vtkm::Id rConnSize = conn.GetNumberOfValues();
|
||||
const auto& conn = connTable.Connectivity;
|
||||
auto& rConn = rConnTable.Connectivity;
|
||||
auto& rOffsets = rConnTable.Offsets;
|
||||
const vtkm::Id rConnSize = conn.GetNumberOfValues();
|
||||
|
||||
auto offInPortal = point2Cell.IndexOffsets.PrepareForInput(Device{});
|
||||
const auto offInPortal = connTable.Offsets.PrepareForInput(Device{});
|
||||
|
||||
PassThrough idxCalc{};
|
||||
ConnIdxToCellIdCalc<decltype(offInPortal)> cellIdCalc{ offInPortal };
|
||||
|
||||
vtkm::cont::internal::ReverseConnectivityBuilder builder;
|
||||
builder.Run(conn,
|
||||
rConn,
|
||||
rNumIndices,
|
||||
rIndexOffsets,
|
||||
idxCalc,
|
||||
cellIdCalc,
|
||||
numberOfPoints,
|
||||
rConnSize,
|
||||
Device());
|
||||
builder.Run(conn, rConn, rOffsets, idxCalc, cellIdCalc, numberOfPoints, rConnSize, Device());
|
||||
|
||||
// Set the VisitPointsWithCells information
|
||||
cell2Point.Shapes = vtkm::cont::make_ArrayHandleConstant(
|
||||
rConnTable.Shapes = vtkm::cont::make_ArrayHandleConstant(
|
||||
static_cast<vtkm::UInt8>(CELL_SHAPE_VERTEX), numberOfPoints);
|
||||
cell2Point.ElementsValid = true;
|
||||
cell2Point.IndexOffsetsValid = true;
|
||||
rConnTable.ElementsValid = true;
|
||||
}
|
||||
|
||||
// Specialize for CellSetSingleType:
|
||||
template <typename ShapeStorageTag,
|
||||
typename ConnectivityStorageTag,
|
||||
typename IndexOffsetStorageTag,
|
||||
typename VisitPointsWithCells,
|
||||
typename Device>
|
||||
void ComputeVisitPointsWithCellsConnectivity(
|
||||
VisitPointsWithCells& cell2Point,
|
||||
const ConnectivityExplicitInternals<
|
||||
ShapeStorageTag,
|
||||
vtkm::cont::ArrayHandleConstant<vtkm::IdComponent>::StorageTag, // nIndices
|
||||
ConnectivityStorageTag,
|
||||
IndexOffsetStorageTag>& point2Cell,
|
||||
vtkm::Id numberOfPoints,
|
||||
Device)
|
||||
template <typename RConnTableT, typename ConnectivityStorageTag, typename Device>
|
||||
void ComputeRConnTable(RConnTableT& rConnTable,
|
||||
const ConnectivityExplicitInternals< // SingleType specialization types:
|
||||
typename vtkm::cont::ArrayHandleConstant<vtkm::UInt8>::StorageTag,
|
||||
ConnectivityStorageTag,
|
||||
typename vtkm::cont::ArrayHandleCounting<vtkm::Id>::StorageTag>& connTable,
|
||||
vtkm::Id numberOfPoints,
|
||||
Device)
|
||||
{
|
||||
if (cell2Point.ElementsValid)
|
||||
if (rConnTable.ElementsValid)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto& conn = point2Cell.Connectivity;
|
||||
auto& rConn = cell2Point.Connectivity;
|
||||
auto& rNumIndices = cell2Point.NumIndices;
|
||||
auto& rIndexOffsets = cell2Point.IndexOffsets;
|
||||
vtkm::Id rConnSize = conn.GetNumberOfValues();
|
||||
const auto& conn = connTable.Connectivity;
|
||||
auto& rConn = rConnTable.Connectivity;
|
||||
auto& rOffsets = rConnTable.Offsets;
|
||||
const vtkm::Id rConnSize = conn.GetNumberOfValues();
|
||||
|
||||
auto sizesInPortal = point2Cell.NumIndices.GetPortalConstControl();
|
||||
vtkm::IdComponent cellSize = sizesInPortal.GetNumberOfValues() > 0 ? sizesInPortal.Get(0) : 0;
|
||||
const vtkm::IdComponent cellSize = [&]() -> vtkm::IdComponent {
|
||||
if (connTable.Offsets.GetNumberOfValues() >= 2)
|
||||
{
|
||||
const auto firstTwo = vtkm::cont::ArrayGetValues({ 0, 1 }, connTable.Offsets);
|
||||
return static_cast<vtkm::IdComponent>(firstTwo[1] - firstTwo[0]);
|
||||
}
|
||||
return 0;
|
||||
}();
|
||||
|
||||
PassThrough idxCalc{};
|
||||
ConnIdxToCellIdCalcSingleType cellIdCalc{ cellSize };
|
||||
|
||||
vtkm::cont::internal::ReverseConnectivityBuilder builder;
|
||||
builder.Run(conn,
|
||||
rConn,
|
||||
rNumIndices,
|
||||
rIndexOffsets,
|
||||
idxCalc,
|
||||
cellIdCalc,
|
||||
numberOfPoints,
|
||||
rConnSize,
|
||||
Device());
|
||||
builder.Run(conn, rConn, rOffsets, idxCalc, cellIdCalc, numberOfPoints, rConnSize, Device());
|
||||
|
||||
// Set the VisitPointsWithCells information
|
||||
cell2Point.Shapes = vtkm::cont::make_ArrayHandleConstant(
|
||||
rConnTable.Shapes = vtkm::cont::make_ArrayHandleConstant(
|
||||
static_cast<vtkm::UInt8>(CELL_SHAPE_VERTEX), numberOfPoints);
|
||||
cell2Point.ElementsValid = true;
|
||||
cell2Point.IndexOffsetsValid = true;
|
||||
rConnTable.ElementsValid = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,62 +0,0 @@
|
||||
//============================================================================
|
||||
// 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.
|
||||
//============================================================================
|
||||
#ifndef vtk_m_cont_internal_DynamicTransform_h
|
||||
#define vtk_m_cont_internal_DynamicTransform_h
|
||||
|
||||
#include <vtkm/cont/CastAndCall.h>
|
||||
#include <vtkm/internal/IndexTag.h>
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
namespace internal
|
||||
{
|
||||
/// This functor can be used as the transform in the \c DynamicTransformCont
|
||||
/// method of \c FunctionInterface. It will allow dynamic objects like
|
||||
/// \c DynamicArray to be cast to their concrete types for templated operation.
|
||||
///
|
||||
struct DynamicTransform
|
||||
{
|
||||
template <typename InputType, typename ContinueFunctor, vtkm::IdComponent Index>
|
||||
VTKM_CONT void operator()(const InputType& input,
|
||||
const ContinueFunctor& continueFunc,
|
||||
vtkm::internal::IndexTag<Index>) const
|
||||
{
|
||||
this->DoTransform(
|
||||
input,
|
||||
continueFunc,
|
||||
typename vtkm::cont::internal::DynamicTransformTraits<InputType>::DynamicTag());
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename InputType, typename ContinueFunctor>
|
||||
VTKM_CONT void DoTransform(const InputType& input,
|
||||
const ContinueFunctor& continueFunc,
|
||||
vtkm::cont::internal::DynamicTransformTagStatic) const
|
||||
{
|
||||
continueFunc(input);
|
||||
}
|
||||
|
||||
template <typename InputType, typename ContinueFunctor>
|
||||
VTKM_CONT void DoTransform(const InputType& dynamicInput,
|
||||
const ContinueFunctor& continueFunc,
|
||||
vtkm::cont::internal::DynamicTransformTagCastAndCall) const
|
||||
{
|
||||
CastAndCall(dynamicInput, continueFunc);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
} // namespace vtkm::cont::internal
|
||||
|
||||
#endif //vtk_m_cont_internal_DynamicTransform_h
|
@ -131,15 +131,13 @@ public:
|
||||
VTKM_CONT
|
||||
template <typename ConnArray,
|
||||
typename RConnArray,
|
||||
typename RNumArray,
|
||||
typename RIndexArray,
|
||||
typename ROffsetsArray,
|
||||
typename RConnToConnIdxCalc,
|
||||
typename ConnIdxToCellIdxCalc,
|
||||
typename Device>
|
||||
inline void Run(const ConnArray& conn,
|
||||
RConnArray& rConn,
|
||||
RNumArray& rNumIndices,
|
||||
RIndexArray& rIndexOffsets,
|
||||
ROffsetsArray& rOffsets,
|
||||
const RConnToConnIdxCalc& rConnToConnCalc,
|
||||
const ConnIdxToCellIdxCalc& cellIdCalc,
|
||||
vtkm::Id numberOfPoints,
|
||||
@ -152,12 +150,13 @@ public:
|
||||
auto zeros = vtkm::cont::make_ArrayHandleConstant(vtkm::IdComponent{ 0 }, numberOfPoints);
|
||||
|
||||
// Compute RConn offsets by atomically building a histogram and doing an
|
||||
// exclusive scan.
|
||||
// extended scan.
|
||||
//
|
||||
// Example:
|
||||
// (in) Conn: | 3 0 1 2 | 3 0 1 3 | 3 0 3 4 | 3 3 4 5 |
|
||||
// (out) RNumIndices: 3 2 1 3 2 1
|
||||
// (out) RIdxOffsets: 0 3 5 6 9 11
|
||||
// (out) RIdxOffsets: 0 3 5 6 9 11 12
|
||||
vtkm::cont::ArrayHandle<vtkm::IdComponent> rNumIndices;
|
||||
{ // allocate and zero the numIndices array:
|
||||
Algo::Copy(zeros, rNumIndices);
|
||||
}
|
||||
@ -165,17 +164,15 @@ public:
|
||||
{ // Build histogram:
|
||||
vtkm::cont::AtomicArray<vtkm::IdComponent> atomicCounter{ rNumIndices };
|
||||
auto ac = atomicCounter.PrepareForExecution(Device());
|
||||
rcb::BuildHistogram<decltype(ac), decltype(connPortal), RConnToConnIdxCalc> histoGen{
|
||||
ac, connPortal, rConnToConnCalc
|
||||
};
|
||||
using BuildHisto =
|
||||
rcb::BuildHistogram<decltype(ac), decltype(connPortal), RConnToConnIdxCalc>;
|
||||
BuildHisto histoGen{ ac, connPortal, rConnToConnCalc };
|
||||
|
||||
Algo::Schedule(histoGen, rConnSize);
|
||||
}
|
||||
|
||||
{ // Compute offsets:
|
||||
auto rNumIndicesAsId =
|
||||
vtkm::cont::make_ArrayHandleCast<typename RIndexArray::ValueType>(rNumIndices);
|
||||
Algo::ScanExclusive(rNumIndicesAsId, rIndexOffsets);
|
||||
Algo::ScanExtended(vtkm::cont::make_ArrayHandleCast<vtkm::Id>(rNumIndices), rOffsets);
|
||||
}
|
||||
|
||||
{ // Reset the numIndices array to 0's:
|
||||
@ -198,16 +195,16 @@ public:
|
||||
{
|
||||
vtkm::cont::AtomicArray<vtkm::IdComponent> atomicCounter{ rNumIndices };
|
||||
auto ac = atomicCounter.PrepareForExecution(Device());
|
||||
auto rOffsetPortal = rIndexOffsets.PrepareForInput(Device());
|
||||
auto rOffsetPortal = rOffsets.PrepareForInput(Device());
|
||||
auto rConnPortal = rConn.PrepareForOutput(rConnSize, Device());
|
||||
|
||||
rcb::GenerateRConn<decltype(ac),
|
||||
decltype(connPortal),
|
||||
decltype(rOffsetPortal),
|
||||
decltype(rConnPortal),
|
||||
RConnToConnIdxCalc,
|
||||
ConnIdxToCellIdxCalc>
|
||||
rConnGen{ ac, connPortal, rOffsetPortal, rConnPortal, rConnToConnCalc, cellIdCalc };
|
||||
using GenRConnT = rcb::GenerateRConn<decltype(ac),
|
||||
decltype(connPortal),
|
||||
decltype(rOffsetPortal),
|
||||
decltype(rConnPortal),
|
||||
RConnToConnIdxCalc,
|
||||
ConnIdxToCellIdxCalc>;
|
||||
GenRConnT rConnGen{ ac, connPortal, rOffsetPortal, rConnPortal, rConnToConnCalc, cellIdCalc };
|
||||
|
||||
Algo::Schedule(rConnGen, rConnSize);
|
||||
}
|
||||
|
@ -12,7 +12,6 @@
|
||||
set(unit_tests
|
||||
UnitTestArrayManagerExecutionShareWithControl.cxx
|
||||
UnitTestArrayPortalFromIterators.cxx
|
||||
UnitTestDynamicTransform.cxx
|
||||
UnitTestIteratorFromArrayPortal.cxx
|
||||
)
|
||||
vtkm_unit_tests(SOURCES ${unit_tests} DEFINES VTKM_NO_ERROR_ON_MIXED_CUDA_CXX_TAG)
|
||||
|
@ -1,196 +0,0 @@
|
||||
//============================================================================
|
||||
// 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.
|
||||
//============================================================================
|
||||
#include <vtkm/cont/internal/DynamicTransform.h>
|
||||
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
#include <vtkm/cont/DynamicCellSet.h>
|
||||
#include <vtkm/cont/VariantArrayHandle.h>
|
||||
|
||||
#include <vtkm/internal/FunctionInterface.h>
|
||||
|
||||
#include <vtkm/cont/testing/Testing.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
|
||||
// VariantArrayHandle requires its value type to have a defined VecTraits
|
||||
// class. One of the tests is to use an "unusual" array of std::string
|
||||
// (which is pretty pointless but might tease out some assumptions).
|
||||
// Make an implementation here. Because I am lazy, this is only a partial
|
||||
// implementation.
|
||||
template <>
|
||||
struct VecTraits<std::string>
|
||||
{
|
||||
using IsSizeStatic = vtkm::VecTraitsTagSizeStatic;
|
||||
static constexpr vtkm::IdComponent NUM_COMPONENTS = 1;
|
||||
using HasMultipleComponents = vtkm::VecTraitsTagSingleComponent;
|
||||
};
|
||||
|
||||
} // namespace vtkm
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
static int g_FunctionCalls;
|
||||
|
||||
#define TRY_TRANSFORM(expr) \
|
||||
g_FunctionCalls = 0; \
|
||||
expr; \
|
||||
VTKM_TEST_ASSERT(g_FunctionCalls == 1, "Functor not called correctly.")
|
||||
|
||||
struct TypeListTagString : vtkm::ListTagBase<std::string>
|
||||
{
|
||||
};
|
||||
|
||||
struct ScalarFunctor
|
||||
{
|
||||
void operator()(vtkm::FloatDefault) const
|
||||
{
|
||||
std::cout << " In Scalar functor." << std::endl;
|
||||
g_FunctionCalls++;
|
||||
}
|
||||
};
|
||||
|
||||
struct ArrayHandleScalarFunctor
|
||||
{
|
||||
template <typename ArrayType>
|
||||
void operator()(const ArrayType&) const
|
||||
{
|
||||
VTKM_TEST_FAIL("Called wrong form of functor operator.");
|
||||
}
|
||||
void operator()(const vtkm::cont::ArrayHandleVirtual<vtkm::FloatDefault>&) const
|
||||
{
|
||||
std::cout << " In ArrayHandleVirtual<Scalar> functor." << std::endl;
|
||||
g_FunctionCalls++;
|
||||
}
|
||||
void operator()(const vtkm::cont::ArrayHandle<vtkm::FloatDefault>&) const
|
||||
{
|
||||
std::cout << " In ArrayHandle<Scalar> functor." << std::endl;
|
||||
g_FunctionCalls++;
|
||||
}
|
||||
};
|
||||
|
||||
struct ArrayHandleStringFunctor
|
||||
{
|
||||
void operator()(const vtkm::cont::ArrayHandleVirtual<std::string>&) const
|
||||
{
|
||||
std::cout << " In ArrayHandleVirtual<string> functor." << std::endl;
|
||||
g_FunctionCalls++;
|
||||
}
|
||||
};
|
||||
|
||||
struct CellSetStructuredFunctor
|
||||
{
|
||||
template <typename T>
|
||||
void operator()(const T&) const
|
||||
{
|
||||
VTKM_TEST_FAIL("Called wrong form of functor operator.");
|
||||
}
|
||||
void operator()(const vtkm::cont::CellSetStructured<3>&) const
|
||||
{
|
||||
std::cout << " In CellSetStructured<3> functor." << std::endl;
|
||||
g_FunctionCalls++;
|
||||
}
|
||||
};
|
||||
|
||||
struct FunctionInterfaceFunctor
|
||||
{
|
||||
template <typename Signature>
|
||||
void operator()(const vtkm::internal::FunctionInterface<Signature>&) const
|
||||
{
|
||||
VTKM_TEST_FAIL("Called wrong form of functor operator.");
|
||||
}
|
||||
void operator()(
|
||||
const vtkm::internal::FunctionInterface<void(vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
|
||||
vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
|
||||
vtkm::cont::ArrayHandle<std::string>,
|
||||
vtkm::cont::CellSetStructured<3>)>&) const
|
||||
{
|
||||
std::cout << " In FunctionInterface<...> functor." << std::endl;
|
||||
g_FunctionCalls++;
|
||||
}
|
||||
|
||||
void operator()(
|
||||
const vtkm::internal::FunctionInterface<void(vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
|
||||
vtkm::cont::ArrayHandleVirtual<vtkm::FloatDefault>,
|
||||
vtkm::cont::ArrayHandleVirtual<std::string>,
|
||||
vtkm::cont::CellSetStructured<3>)>&) const
|
||||
{
|
||||
std::cout << " In FunctionInterface<...> functor." << std::endl;
|
||||
g_FunctionCalls++;
|
||||
}
|
||||
};
|
||||
|
||||
void TestBasicTransform()
|
||||
{
|
||||
std::cout << "Testing basic transform." << std::endl;
|
||||
|
||||
vtkm::cont::internal::DynamicTransform transform;
|
||||
vtkm::internal::IndexTag<1> indexTag;
|
||||
|
||||
std::cout << " Trying with simple scalar." << std::endl;
|
||||
TRY_TRANSFORM(transform(vtkm::FloatDefault(5), ScalarFunctor(), indexTag));
|
||||
|
||||
std::cout << " Trying with basic scalar array." << std::endl;
|
||||
vtkm::cont::ArrayHandle<vtkm::FloatDefault> concreteArray;
|
||||
TRY_TRANSFORM(transform(concreteArray, ArrayHandleScalarFunctor(), indexTag));
|
||||
|
||||
std::cout << " Trying scalar dynamic array." << std::endl;
|
||||
vtkm::cont::VariantArrayHandle dynamicArray = concreteArray;
|
||||
TRY_TRANSFORM(transform(dynamicArray, ArrayHandleScalarFunctor(), indexTag));
|
||||
|
||||
std::cout << " Trying with unusual (string) dynamic array." << std::endl;
|
||||
dynamicArray = vtkm::cont::ArrayHandle<std::string>();
|
||||
TRY_TRANSFORM(
|
||||
transform(dynamicArray.ResetTypes(TypeListTagString()), ArrayHandleStringFunctor(), indexTag));
|
||||
|
||||
std::cout << " Trying with structured cell set." << std::endl;
|
||||
vtkm::cont::CellSetStructured<3> concreteCellSet;
|
||||
TRY_TRANSFORM(transform(concreteCellSet, CellSetStructuredFunctor(), indexTag));
|
||||
|
||||
std::cout << " Trying with dynamic cell set." << std::endl;
|
||||
vtkm::cont::DynamicCellSet dynamicCellSet = concreteCellSet;
|
||||
TRY_TRANSFORM(transform(dynamicCellSet, CellSetStructuredFunctor(), indexTag));
|
||||
}
|
||||
|
||||
void TestFunctionTransform()
|
||||
{
|
||||
std::cout << "Testing transforms in FunctionInterface." << std::endl;
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::FloatDefault> scalarArray;
|
||||
vtkm::cont::ArrayHandle<std::string> stringArray;
|
||||
vtkm::cont::CellSetStructured<3> structuredCellSet;
|
||||
|
||||
std::cout << " Trying basic functor call w/o transform (make sure it works)." << std::endl;
|
||||
TRY_TRANSFORM(FunctionInterfaceFunctor()(vtkm::internal::make_FunctionInterface<void>(
|
||||
scalarArray, scalarArray, stringArray, structuredCellSet)));
|
||||
|
||||
std::cout << " Trying dynamic cast" << std::endl;
|
||||
TRY_TRANSFORM(
|
||||
vtkm::internal::make_FunctionInterface<void>(
|
||||
scalarArray,
|
||||
vtkm::cont::VariantArrayHandle(scalarArray),
|
||||
vtkm::cont::VariantArrayHandle(stringArray).ResetTypes(TypeListTagString()),
|
||||
vtkm::cont::DynamicCellSet(structuredCellSet))
|
||||
.DynamicTransformCont(vtkm::cont::internal::DynamicTransform(), FunctionInterfaceFunctor()));
|
||||
}
|
||||
|
||||
void TestDynamicTransform()
|
||||
{
|
||||
TestBasicTransform();
|
||||
TestFunctionTransform();
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
int UnitTestDynamicTransform(int argc, char* argv[])
|
||||
{
|
||||
return vtkm::cont::testing::Testing::Run(TestDynamicTransform, argc, argv);
|
||||
}
|
@ -42,10 +42,10 @@
|
||||
// tl;dr, put all const variables accessed from openmp blocks in a
|
||||
// VTKM_OPENMP_SHARED_CONST(var1, var2, ...) macro. This will do The Right Thing
|
||||
// on all gcc.
|
||||
#if defined(__GNUC__) && __GNUC__ >= 9
|
||||
#define VTKM_OPENMP_SHARED_CONST(...) shared(__VA_ARGS__)
|
||||
#else
|
||||
#if defined(VTKM_GCC) && (__GNUC__ < 9)
|
||||
#define VTKM_OPENMP_SHARED_CONST(...)
|
||||
#else
|
||||
#define VTKM_OPENMP_SHARED_CONST(...) shared(__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
// When defined, supported type / operator combinations will use the OpenMP
|
||||
|
@ -38,7 +38,7 @@ public:
|
||||
template <class Func>
|
||||
static VTKM_CONT int Run(Func function, int& argc, char* argv[])
|
||||
{
|
||||
vtkm::cont::Initialize(argc, argv);
|
||||
vtkm::cont::Initialize(argc, argv, vtkm::cont::InitializeOptions::Strict);
|
||||
|
||||
try
|
||||
{
|
||||
@ -71,7 +71,8 @@ public:
|
||||
template <class Func>
|
||||
static VTKM_CONT int RunOnDevice(Func function, int argc, char* argv[])
|
||||
{
|
||||
auto opts = vtkm::cont::InitializeOptions::RequireDevice;
|
||||
auto opts =
|
||||
vtkm::cont::InitializeOptions::RequireDevice | vtkm::cont::InitializeOptions::Strict;
|
||||
auto config = vtkm::cont::Initialize(argc, argv, opts);
|
||||
|
||||
try
|
||||
@ -229,11 +230,10 @@ namespace detail
|
||||
|
||||
struct TestEqualCellSet
|
||||
{
|
||||
template <typename ShapeST, typename CountST, typename ConnectivityST, typename OffsetST>
|
||||
void operator()(
|
||||
const vtkm::cont::CellSetExplicit<ShapeST, CountST, ConnectivityST, OffsetST>& cs1,
|
||||
const vtkm::cont::CellSetExplicit<ShapeST, CountST, ConnectivityST, OffsetST>& cs2,
|
||||
TestEqualResult& result) const
|
||||
template <typename ShapeST, typename ConnectivityST, typename OffsetST>
|
||||
void operator()(const vtkm::cont::CellSetExplicit<ShapeST, ConnectivityST, OffsetST>& cs1,
|
||||
const vtkm::cont::CellSetExplicit<ShapeST, ConnectivityST, OffsetST>& cs2,
|
||||
TestEqualResult& result) const
|
||||
{
|
||||
vtkm::TopologyElementTagCell visitTopo{};
|
||||
vtkm::TopologyElementTagPoint incidentTopo{};
|
||||
@ -266,8 +266,8 @@ struct TestEqualCellSet
|
||||
result.PushMessage("connectivity arrays don't match");
|
||||
return;
|
||||
}
|
||||
result = test_equal_ArrayHandles(cs1.GetIndexOffsetArray(visitTopo, incidentTopo),
|
||||
cs2.GetIndexOffsetArray(visitTopo, incidentTopo));
|
||||
result = test_equal_ArrayHandles(cs1.GetOffsetsArray(visitTopo, incidentTopo),
|
||||
cs2.GetOffsetsArray(visitTopo, incidentTopo));
|
||||
if (!result)
|
||||
{
|
||||
result.PushMessage("offsets arrays don't match");
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user