mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-08 13:23:51 +00:00
Merge branch 'master' of https://gitlab.kitware.com/vtk/vtk-m into code_sprint_locator_fixes
This commit is contained in:
commit
c062f2e26c
42
CMake/VTKmCompilerDynamicAnalysisFlags.cmake
Normal file
42
CMake/VTKmCompilerDynamicAnalysisFlags.cmake
Normal file
@ -0,0 +1,42 @@
|
||||
##============================================================================
|
||||
## 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.
|
||||
##
|
||||
## Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
## Copyright 2014 UT-Battelle, LLC.
|
||||
## Copyright 2014 Los Alamos National Security.
|
||||
##
|
||||
## Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
## the U.S. Government retains certain rights in this software.
|
||||
##
|
||||
## Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
|
||||
## Laboratory (LANL), the U.S. Government retains certain rights in
|
||||
## this software.
|
||||
##============================================================================
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# check if this is a sanitizer build. If so, set up the environment.
|
||||
|
||||
function(vtkm_check_sanitizer_build)
|
||||
string (FIND "${CTEST_MEMORYCHECK_TYPE}" "Sanitizer" SANITIZER_BUILD)
|
||||
if (${SANITIZER_BUILD} GREATER -1)
|
||||
# This is a sanitizer build.
|
||||
# Configure the sanitizer blacklist file
|
||||
set (SANITIZER_BLACKLIST "${VTKm_BINARY_DIR}/sanitizer_blacklist.txt")
|
||||
configure_file (
|
||||
"${VTKm_SOURCE_DIR}/Utilities/DynamicAnalysis/sanitizer_blacklist.txt.in"
|
||||
${SANITIZER_BLACKLIST}
|
||||
@ONLY
|
||||
)
|
||||
|
||||
# Add the compiler flags for blacklist
|
||||
set (FSANITIZE_BLACKLIST "\"-fsanitize-blacklist=${SANITIZER_BLACKLIST}\"")
|
||||
foreach (entity C CXX SHARED_LINKER EXE_LINKER MODULE_LINKER)
|
||||
set (CMAKE_${entity}_FLAGS "${CMAKE_${entity}_FLAGS} ${FSANITIZE_BLACKLIST}")
|
||||
endforeach ()
|
||||
endif ()
|
||||
endfunction()
|
@ -51,8 +51,9 @@ add_library(vtkm_compiler_flags INTERFACE)
|
||||
# When building libraries/tests that are part of the VTK-m repository
|
||||
# inherit the properties from vtkm_developer_flags and vtkm_vectorization_flags.
|
||||
# The flags are intended only for VTK-m itself and are not needed by consumers.
|
||||
# We will export vtkm_vectorization_flags in general so consumer can enable
|
||||
# vectorization if they so desire
|
||||
# We will export vtkm_developer_flags, and vtkm_vectorization_flags in general
|
||||
# so consumer can either enable vectorization or use VTK-m's build flags if
|
||||
# they so desire
|
||||
if (VTKm_ENABLE_DEVELOPER_FLAGS)
|
||||
target_link_libraries(vtkm_compiler_flags
|
||||
INTERFACE $<BUILD_INTERFACE:vtkm_developer_flags>)
|
||||
@ -92,26 +93,29 @@ add_library(vtkm_developer_flags INTERFACE)
|
||||
# about failures to vectorize.
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND
|
||||
CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 3.4)
|
||||
target_compile_options(vtkm_developer_flags INTERFACE $<BUILD_INTERFACE:$<$<COMPILE_LANGUAGE:CXX>:-Wno-pass-failed>>)
|
||||
target_compile_options(vtkm_developer_flags INTERFACE $<$<COMPILE_LANGUAGE:CXX>:-Wno-pass-failed>)
|
||||
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" AND
|
||||
CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 6.99)
|
||||
target_compile_options(vtkm_developer_flags INTERFACE $<BUILD_INTERFACE:$<$<COMPILE_LANGUAGE:CXX>:-Wno-pass-failed>>)
|
||||
target_compile_options(vtkm_developer_flags INTERFACE $<$<COMPILE_LANGUAGE:CXX>:-Wno-pass-failed>)
|
||||
endif()
|
||||
|
||||
if(VTKM_COMPILER_IS_MSVC)
|
||||
target_compile_definitions(vtkm_developer_flags INTERFACE "_SCL_SECURE_NO_WARNINGS"
|
||||
"_CRT_SECURE_NO_WARNINGS")
|
||||
|
||||
#CMake COMPILE_LANGUAGE doesn't work with MSVC, ans since we want these flags
|
||||
#only for C++ compilation we have to resort to setting CMAKE_CXX_FLAGS :(
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4702 /wd4505")
|
||||
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -Xcompiler=\"/wd4702 /wd4505\" -Xcudafe=\"--diag_suppress=1394 --diag_suppress=766 --display_error_number\"")
|
||||
#Setup MSVC warnings with CUDA and CXX
|
||||
target_compile_options(vtkm_developer_flags INTERFACE $<$<COMPILE_LANGUAGE:CXX>:-wd4702 -wd4505>)
|
||||
if(TARGET vtkm::cuda)
|
||||
target_compile_options(vtkm_developer_flags INTERFACE $<$<COMPILE_LANGUAGE:CUDA>:-Xcompiler=-wd4702,-wd4505 -Xcudafe=--display_error_number,--diag_suppress=1394,--diag_suppress=766>)
|
||||
endif()
|
||||
|
||||
if(MSVC_VERSION LESS 1900)
|
||||
# In VS2013 the C4127 warning has a bug in the implementation and
|
||||
# generates false positive warnings for lots of template code
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -wd4127")
|
||||
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -Xcompiler=\"/wd4127\"")
|
||||
target_compile_options(vtkm_developer_flags INTERFACE $<$<COMPILE_LANGUAGE:CXX>:-wd4127>)
|
||||
if(TARGET vtkm::cuda)
|
||||
target_compile_options(vtkm_developer_flags INTERFACE $<$<COMPILE_LANGUAGE:CUDA>:-Xcompiler=-wd4127>)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
elseif(VTKM_COMPILER_IS_ICC)
|
||||
@ -137,13 +141,9 @@ elseif(VTKM_COMPILER_IS_GNU OR VTKM_COMPILER_IS_CLANG)
|
||||
(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.99) )
|
||||
list(APPEND cxx_flags -Wno-strict-overflow)
|
||||
endif()
|
||||
target_compile_options(vtkm_developer_flags
|
||||
INTERFACE $<BUILD_INTERFACE:$<$<COMPILE_LANGUAGE:CXX>:${cxx_flags}>>
|
||||
)
|
||||
target_compile_options(vtkm_developer_flags INTERFACE $<$<COMPILE_LANGUAGE:CXX>:${cxx_flags}>)
|
||||
if(TARGET vtkm::cuda)
|
||||
target_compile_options(vtkm_developer_flags
|
||||
INTERFACE $<BUILD_INTERFACE:$<$<COMPILE_LANGUAGE:CUDA>:${cuda_flags}>>
|
||||
)
|
||||
target_compile_options(vtkm_developer_flags INTERFACE $<$<COMPILE_LANGUAGE:CUDA>:${cuda_flags}>)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
@ -72,6 +72,16 @@ if(VTKm_ENABLE_TBB AND NOT TARGET vtkm::tbb)
|
||||
IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
|
||||
IMPORTED_LOCATION_RELEASE "${real_path}"
|
||||
)
|
||||
elseif(EXISTS "${TBB_LIBRARY}")
|
||||
#When VTK-m is mixed with OSPray we could use the OSPray FindTBB file
|
||||
#which doesn't define TBB_LIBRARY_RELEASE but instead defined only
|
||||
#TBB_LIBRARY
|
||||
vtkm_extract_real_library("${TBB_LIBRARY}" real_path)
|
||||
set_property(TARGET vtkm::tbb APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
|
||||
set_target_properties(vtkm::tbb PROPERTIES
|
||||
IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
|
||||
IMPORTED_LOCATION_RELEASE "${real_path}"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(EXISTS "${TBB_LIBRARY_DEBUG}")
|
||||
@ -188,18 +198,21 @@ if(VTKm_ENABLE_CUDA AND NOT TARGET vtkm::cuda)
|
||||
# - Uses: --generate-code=arch=compute_60,code=sm_60
|
||||
# 6 - volta
|
||||
# - Uses: --generate-code=arch=compute_70,code=sm_70
|
||||
# 7 - all
|
||||
# 7 - turing
|
||||
# - Uses: --generate-code=arch=compute_75code=sm_75
|
||||
# 8 - all
|
||||
# - Uses: --generate-code=arch=compute_30,code=sm_30
|
||||
# - Uses: --generate-code=arch=compute_35,code=sm_35
|
||||
# - Uses: --generate-code=arch=compute_50,code=sm_50
|
||||
# - Uses: --generate-code=arch=compute_60,code=sm_60
|
||||
# - Uses: --generate-code=arch=compute_70,code=sm_70
|
||||
# - Uses: --generate-code=arch=compute_75,code=sm_75
|
||||
# 8 - none
|
||||
#
|
||||
|
||||
#specify the property
|
||||
set(VTKm_CUDA_Architecture "native" CACHE STRING "Which GPU Architecture(s) to compile for")
|
||||
set_property(CACHE VTKm_CUDA_Architecture PROPERTY STRINGS native fermi kepler maxwell pascal volta all none)
|
||||
set_property(CACHE VTKm_CUDA_Architecture PROPERTY STRINGS native fermi kepler maxwell pascal volta turing all none)
|
||||
|
||||
#detect what the property is set too
|
||||
if(VTKm_CUDA_Architecture STREQUAL "native")
|
||||
@ -253,12 +266,15 @@ if(VTKm_ENABLE_CUDA AND NOT TARGET vtkm::cuda)
|
||||
set(arch_flags --generate-code=arch=compute_60,code=sm_60)
|
||||
elseif(VTKm_CUDA_Architecture STREQUAL "volta")
|
||||
set(arch_flags --generate-code=arch=compute_70,code=sm_70)
|
||||
elseif(VTKm_CUDA_Architecture STREQUAL "turing")
|
||||
set(arch_flags --generate-code=arch=compute_75,code=sm_75)
|
||||
elseif(VTKm_CUDA_Architecture STREQUAL "all")
|
||||
set(arch_flags --generate-code=arch=compute_30,code=sm_30
|
||||
--generate-code=arch=compute_35,code=sm_35
|
||||
--generate-code=arch=compute_50,code=sm_50
|
||||
--generate-code=arch=compute_60,code=sm_60
|
||||
--generate-code=arch=compute_70,code=sm_70)
|
||||
--generate-code=arch=compute_70,code=sm_70
|
||||
--generate-code=arch=compute_75,code=sm_75)
|
||||
endif()
|
||||
|
||||
string(REPLACE ";" " " arch_flags "${arch_flags}")
|
||||
|
@ -95,6 +95,13 @@ endfunction()
|
||||
function(vtkm_add_header_build_test name dir_prefix use_cuda)
|
||||
set(hfiles ${ARGN})
|
||||
|
||||
#only attempt to add a test build executable if we have any headers to
|
||||
#test. this might not happen when everything depends on thrust.
|
||||
list(LENGTH hfiles num_srcs)
|
||||
if (${num_srcs} EQUAL 0)
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(ext "cxx")
|
||||
if(use_cuda)
|
||||
set(ext "cu")
|
||||
@ -104,10 +111,9 @@ function(vtkm_add_header_build_test name dir_prefix use_cuda)
|
||||
foreach (header ${hfiles})
|
||||
get_source_file_property(cant_be_tested ${header} VTKm_CANT_BE_HEADER_TESTED)
|
||||
if( NOT cant_be_tested )
|
||||
get_filename_component(headername ${header} NAME_WE)
|
||||
get_filename_component(headerextension ${header} EXT)
|
||||
string(SUBSTRING ${headerextension} 1 -1 headerextension)
|
||||
set(src ${CMAKE_CURRENT_BINARY_DIR}/TB_${headername}_${headerextension}.${ext})
|
||||
string(REPLACE "/" "_" headername "${header}")
|
||||
string(REPLACE "." "_" headername "${headername}")
|
||||
set(src ${CMAKE_CURRENT_BINARY_DIR}/TB_${headername}.${ext})
|
||||
|
||||
#By using file generate we will not trigger CMake execution when
|
||||
#a header gets touched
|
||||
@ -118,9 +124,10 @@ function(vtkm_add_header_build_test name dir_prefix use_cuda)
|
||||
//This is used by headers that include thrust to properly define a proper
|
||||
//device backend / system
|
||||
#define VTKM_TEST_HEADER_BUILD
|
||||
#include <${dir_prefix}/${headername}.${headerextension}>
|
||||
#include <${dir_prefix}/${header}>
|
||||
int ${headername}_${headerextension}_testbuild_symbol;"
|
||||
)
|
||||
|
||||
list(APPEND srcs ${src})
|
||||
endif()
|
||||
endforeach()
|
||||
@ -129,13 +136,6 @@ int ${headername}_${headerextension}_testbuild_symbol;"
|
||||
PROPERTIES HEADER_FILE_ONLY TRUE
|
||||
)
|
||||
|
||||
#only attempt to add a test build executable if we have any headers to
|
||||
#test. this might not happen when everything depends on thrust.
|
||||
list(LENGTH srcs num_srcs)
|
||||
if (${num_srcs} EQUAL 0)
|
||||
return()
|
||||
endif()
|
||||
|
||||
if(TARGET TestBuild_${name})
|
||||
#If the target already exists just add more sources to it
|
||||
target_sources(TestBuild_${name} PRIVATE ${srcs})
|
||||
@ -206,6 +206,7 @@ function(vtkm_generate_export_header lib_name)
|
||||
|
||||
endfunction(vtkm_generate_export_header)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
function(vtkm_install_headers dir_prefix)
|
||||
if(NOT VTKm_INSTALL_ONLY_LIBRARIES)
|
||||
set(hfiles ${ARGN})
|
||||
@ -345,6 +346,7 @@ endfunction(vtkm_library)
|
||||
# LIBRARIES <dependent_library_list>
|
||||
# TEST_ARGS <argument_list>
|
||||
# MPI
|
||||
# ALL_BACKENDS
|
||||
# <options>
|
||||
# )
|
||||
#
|
||||
@ -362,6 +364,8 @@ endfunction(vtkm_library)
|
||||
#
|
||||
# [MPI] : when specified, the tests should be run in parallel if
|
||||
# MPI is enabled.
|
||||
# [ALL_BACKENDS] : when specified, the tests would test against all enabled
|
||||
# backends. BACKEND argument would be ignored.
|
||||
#
|
||||
function(vtkm_unit_tests)
|
||||
if (NOT VTKm_ENABLE_TESTING)
|
||||
@ -369,7 +373,7 @@ function(vtkm_unit_tests)
|
||||
endif()
|
||||
|
||||
set(options)
|
||||
set(global_options ${options} MPI)
|
||||
set(global_options ${options} MPI ALL_BACKENDS)
|
||||
set(oneValueArgs BACKEND NAME)
|
||||
set(multiValueArgs SOURCES LIBRARIES TEST_ARGS)
|
||||
cmake_parse_arguments(VTKm_UT
|
||||
@ -378,17 +382,33 @@ function(vtkm_unit_tests)
|
||||
)
|
||||
vtkm_parse_test_options(VTKm_UT_SOURCES "${options}" ${VTKm_UT_SOURCES})
|
||||
|
||||
set(test_prog )
|
||||
set(test_prog)
|
||||
set(backend ${VTKm_UT_BACKEND})
|
||||
|
||||
set(enable_all_backends ${VTKm_UT_ALL_BACKENDS})
|
||||
set(all_backends SERIAL)
|
||||
if (VTKm_ENABLE_CUDA)
|
||||
list(APPEND all_backends CUDA)
|
||||
endif()
|
||||
if (VTKm_ENABLE_TBB)
|
||||
list(APPEND all_backends TBB)
|
||||
endif()
|
||||
if (VTKm_ENABLE_OPENMP)
|
||||
list(APPEND all_backends OPENMP)
|
||||
endif()
|
||||
|
||||
if(VTKm_UT_NAME)
|
||||
set(test_prog "${VTKm_UT_NAME}")
|
||||
else()
|
||||
vtkm_get_kit_name(kit)
|
||||
set(test_prog "UnitTests_${kit}")
|
||||
endif()
|
||||
|
||||
if(backend)
|
||||
set(test_prog "${test_prog}_${backend}")
|
||||
set(all_backends ${backend})
|
||||
elseif(NOT enable_all_backends)
|
||||
set (all_backends "NO_BACKEND")
|
||||
endif()
|
||||
|
||||
if(VTKm_UT_MPI)
|
||||
@ -403,7 +423,8 @@ function(vtkm_unit_tests)
|
||||
#the creation of the test source list needs to occur before the labeling as
|
||||
#cuda. This is so that we get the correctly named entry points generated
|
||||
create_test_sourcelist(test_sources ${test_prog}.cxx ${VTKm_UT_SOURCES} ${extraArgs})
|
||||
if(backend STREQUAL "CUDA")
|
||||
#if all backends are enabled, we can use cuda compiler to handle all possible backends.
|
||||
if(backend STREQUAL "CUDA" OR (enable_all_backends AND VTKm_ENABLE_CUDA))
|
||||
vtkm_compile_as_cuda(cu_srcs ${VTKm_UT_SOURCES})
|
||||
set(VTKm_UT_SOURCES ${cu_srcs})
|
||||
endif()
|
||||
@ -414,43 +435,50 @@ function(vtkm_unit_tests)
|
||||
set_property(TARGET ${test_prog} PROPERTY RUNTIME_OUTPUT_DIRECTORY ${VTKm_EXECUTABLE_OUTPUT_PATH})
|
||||
|
||||
target_link_libraries(${test_prog} PRIVATE vtkm_cont ${VTKm_UT_LIBRARIES})
|
||||
if(backend)
|
||||
target_compile_definitions(${test_prog} PRIVATE "VTKM_DEVICE_ADAPTER=VTKM_DEVICE_ADAPTER_${backend}")
|
||||
endif()
|
||||
|
||||
#determine the timeout for all the tests based on the backend. CUDA tests
|
||||
#generally require more time because of kernel generation.
|
||||
set(timeout 180)
|
||||
set(run_serial False)
|
||||
if(backend STREQUAL "CUDA")
|
||||
set(timeout 1500)
|
||||
elseif(backend STREQUAL "OPENMP")
|
||||
#We need to have all OpenMP tests run serially as they
|
||||
#will uses all the system cores, and we will cause a N*N thread
|
||||
#explosion which causes the tests to run slower than when run
|
||||
#serially
|
||||
set(run_serial True)
|
||||
endif()
|
||||
|
||||
|
||||
foreach (test ${VTKm_UT_SOURCES})
|
||||
get_filename_component(tname ${test} NAME_WE)
|
||||
if(VTKm_UT_MPI AND VTKm_ENABLE_MPI)
|
||||
add_test(NAME ${tname}${backend}
|
||||
COMMAND ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} 3 ${MPIEXEC_PREFLAGS}
|
||||
$<TARGET_FILE:${test_prog}> ${tname} ${VTKm_UT_TEST_ARGS}
|
||||
${MPIEXEC_POSTFLAGS}
|
||||
)
|
||||
else()
|
||||
add_test(NAME ${tname}${backend}
|
||||
COMMAND ${test_prog} ${tname} ${VTKm_UT_TEST_ARGS}
|
||||
)
|
||||
foreach(current_backend ${all_backends})
|
||||
set (device_command_line_argument --device=${current_backend})
|
||||
if (current_backend STREQUAL "NO_BACKEND")
|
||||
set (current_backend "")
|
||||
set(device_command_line_argument "")
|
||||
endif()
|
||||
set_tests_properties("${tname}${backend}" PROPERTIES
|
||||
TIMEOUT ${timeout}
|
||||
RUN_SERIAL ${run_serial}
|
||||
)
|
||||
endforeach (test)
|
||||
foreach (test ${VTKm_UT_SOURCES})
|
||||
get_filename_component(tname ${test} NAME_WE)
|
||||
if(VTKm_UT_MPI AND VTKm_ENABLE_MPI)
|
||||
add_test(NAME ${tname}${current_backend}
|
||||
COMMAND ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} 3 ${MPIEXEC_PREFLAGS}
|
||||
$<TARGET_FILE:${test_prog}> ${tname} ${device_command_line_argument} ${VTKm_UT_TEST_ARGS}
|
||||
${MPIEXEC_POSTFLAGS}
|
||||
)
|
||||
else()
|
||||
add_test(NAME ${tname}${current_backend}
|
||||
COMMAND ${test_prog} ${tname} ${device_command_line_argument} ${VTKm_UT_TEST_ARGS}
|
||||
)
|
||||
endif()
|
||||
|
||||
#determine the timeout for all the tests based on the backend. CUDA tests
|
||||
#generally require more time because of kernel generation.
|
||||
if (current_backend STREQUAL "CUDA")
|
||||
set(timeout 1500)
|
||||
else()
|
||||
set(timeout 180)
|
||||
endif()
|
||||
if(current_backend STREQUAL "OPENMP")
|
||||
#We need to have all OpenMP tests run serially as they
|
||||
#will uses all the system cores, and we will cause a N*N thread
|
||||
#explosion which causes the tests to run slower than when run
|
||||
#serially
|
||||
set(run_serial True)
|
||||
else()
|
||||
set(run_serial False)
|
||||
endif()
|
||||
|
||||
set_tests_properties("${tname}${current_backend}" PROPERTIES
|
||||
TIMEOUT ${timeout}
|
||||
RUN_SERIAL ${run_serial}
|
||||
)
|
||||
endforeach (test)
|
||||
endforeach(current_backend)
|
||||
|
||||
endfunction(vtkm_unit_tests)
|
||||
|
||||
|
@ -97,6 +97,7 @@ vtkm_option(VTKm_ENABLE_OPENMP "Enable OpenMP support" OFF)
|
||||
vtkm_option(VTKm_ENABLE_RENDERING "Enable rendering library" ON)
|
||||
vtkm_option(VTKm_ENABLE_TESTING "Enable VTKm Testing" ON)
|
||||
vtkm_option(VTKm_ENABLE_BENCHMARKS "Enable VTKm Benchmarking" OFF)
|
||||
vtkm_option(VTKm_ENABLE_LOGGING "Enable VTKm Logging" OFF)
|
||||
vtkm_option(VTKm_ENABLE_MPI "Enable MPI support" OFF)
|
||||
|
||||
vtkm_option(VTKm_ENABLE_DOCUMENTATION "Build Doxygen documentation" OFF)
|
||||
@ -199,6 +200,11 @@ if (VTKm_ENABLE_TESTING)
|
||||
# Find Pyexpander in case somebody wants to update the auto generated
|
||||
# faux variadic template code
|
||||
find_package(Pyexpander QUIET)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Setup compiler flags for dynamic analysis if needed
|
||||
include(VTKmCompilerDynamicAnalysisFlags)
|
||||
vtkm_check_sanitizer_build()
|
||||
endif (VTKm_ENABLE_TESTING)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
@ -288,7 +294,7 @@ if(NOT VTKm_INSTALL_ONLY_LIBRARIES)
|
||||
|
||||
# Create and install exports for external projects
|
||||
export(EXPORT ${VTKm_EXPORT_NAME}
|
||||
FILE ${VTKm_BINARY_DIR}/${VTKm_INSTALL_CONFIG_DIR}/VTKmTargets.cmake
|
||||
FILE ${VTKm_BUILD_CMAKE_BASE_DIR}/${VTKm_INSTALL_CONFIG_DIR}/VTKmTargets.cmake
|
||||
)
|
||||
install(EXPORT ${VTKm_EXPORT_NAME}
|
||||
DESTINATION ${VTKm_INSTALL_CONFIG_DIR}
|
||||
|
20
README.md
20
README.md
@ -71,6 +71,7 @@ Optional dependencies are:
|
||||
|
||||
+ CUDA Device Adapter
|
||||
+ [Cuda Toolkit 7.5+](https://developer.nvidia.com/cuda-toolkit)
|
||||
+ Note CUDA >= 10.0 is required on Windows
|
||||
+ TBB Device Adapter
|
||||
+ [TBB](https://www.threadingbuildingblocks.org/)
|
||||
+ OpenMP Device Adapter
|
||||
@ -95,19 +96,20 @@ Optional dependencies are:
|
||||
+ EGL Driver
|
||||
|
||||
VTK-m has been tested on the following configurations:
|
||||
+ On Linux
|
||||
+ GCC 4.8.5, 5.4.0, 6.4.0, Clang 3.8.0
|
||||
+ CMake 3.9.2, 3.9.3, 3.10.3
|
||||
+ CUDA 8.0.61, 9.1.85
|
||||
+ On Linux
|
||||
+ GCC 4.8.5, 5.4.0, 6.4.0, 7.3.0 Clang 3.8.0, Intel 17.0.4
|
||||
+ CMake 3.9.3, 3.10.3
|
||||
+ CUDA 8.0.61, 9.1.85, 10.0.130
|
||||
+ TBB 4.4 U2, 2017 U7
|
||||
+ On Windows
|
||||
+ Visual Studio 2015, 2017
|
||||
+ CMake 3.3, 3.11.1
|
||||
+ CUDA 9.1.85
|
||||
+ CUDA 10.0.130
|
||||
+ TBB 2017 U3, 2018 U2
|
||||
+ On MacOS
|
||||
+ AppleClang 6.0
|
||||
+ TBB 2017 U6
|
||||
+ AppleClang 9.1
|
||||
+ CMake 3.12.0
|
||||
+ TBB 2018
|
||||
|
||||
|
||||
## Building ##
|
||||
@ -133,7 +135,7 @@ Users Guide].
|
||||
## Example##
|
||||
|
||||
The VTK-m source distribution includes a number of examples. The goal of the
|
||||
VTK-m examples is to illustrate specific VTK-m concepts in a consistent and
|
||||
VTK-m examples is to illustrate specific VTK-m concepts in a consistent and
|
||||
simple format. However, these examples only cover a small part of the
|
||||
capabilities of VTK-m.
|
||||
|
||||
@ -204,7 +206,7 @@ See [LICENSE.txt](LICENSE.txt) for details.
|
||||
[VTK-m download page]: http://m.vtk.org/index.php/VTK-m_Releases
|
||||
[VTK-m git repository]: https://gitlab.kitware.com/vtk/vtk-m/
|
||||
[VTK-m Issue Tracker]: https://gitlab.kitware.com/vtk/vtk-m/issues
|
||||
[VTK-m Overview]: http://m.vtk.org/images/2/29/VTKmVis2016.pptx
|
||||
[VTK-m Overview]: http://m.vtk.org/images/2/29/VTKmVis2016.pptx
|
||||
[VTK-m Users Guide]: http://m.vtk.org/images/c/c8/VTKmUsersGuide.pdf
|
||||
[VTK-m users email list]: http://vtk.org/mailman/listinfo/vtkm
|
||||
[VTK-m Wiki]: http://m.vtk.org/
|
||||
|
1
Utilities/DynamicAnalysis/lsan.supp
Normal file
1
Utilities/DynamicAnalysis/lsan.supp
Normal file
@ -0,0 +1 @@
|
||||
leak:libX11*
|
2
Utilities/DynamicAnalysis/sanitizer_blacklist.txt.in
Normal file
2
Utilities/DynamicAnalysis/sanitizer_blacklist.txt.in
Normal file
@ -0,0 +1,2 @@
|
||||
# Blacklist third party libraries from invoking sanitizer errors
|
||||
src:@VTKm_SOURCE_DIR@/vtkm/thirdparty/*
|
@ -698,7 +698,7 @@ private:
|
||||
template <typename Value>
|
||||
struct BenchStableSortIndices
|
||||
{
|
||||
using SSI = vtkm::worklet::StableSortIndices<DeviceAdapterTag>;
|
||||
using SSI = vtkm::worklet::StableSortIndices;
|
||||
using ValueArrayHandle = vtkm::cont::ArrayHandle<Value, StorageTag>;
|
||||
|
||||
ValueArrayHandle ValueHandle;
|
||||
@ -743,7 +743,7 @@ private:
|
||||
template <typename Value>
|
||||
struct BenchStableSortIndicesUnique
|
||||
{
|
||||
using SSI = vtkm::worklet::StableSortIndices<DeviceAdapterTag>;
|
||||
using SSI = vtkm::worklet::StableSortIndices;
|
||||
using IndexArrayHandle = typename SSI::IndexArrayType;
|
||||
using ValueArrayHandle = vtkm::cont::ArrayHandle<Value, StorageTag>;
|
||||
|
||||
@ -915,6 +915,7 @@ public:
|
||||
static VTKM_CONT int Run()
|
||||
{
|
||||
std::cout << DIVIDER << "\nRunning DeviceAdapter benchmarks\n";
|
||||
vtkm::cont::GetGlobalRuntimeDeviceTracker().ForceDevice(DeviceAdapterTag());
|
||||
|
||||
// Run fixed bytes / size tests:
|
||||
for (int sizeType = 0; sizeType < 2; ++sizeType)
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <vtkm/cont/CellSetStructured.h>
|
||||
#include <vtkm/cont/DataSet.h>
|
||||
#include <vtkm/cont/ErrorInternal.h>
|
||||
#include <vtkm/cont/Logging.h>
|
||||
#include <vtkm/cont/RuntimeDeviceTracker.h>
|
||||
#include <vtkm/cont/StorageBasic.h>
|
||||
#include <vtkm/cont/Timer.h>
|
||||
@ -1282,6 +1283,8 @@ int BenchmarkBody(int argc, char* argv[])
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
vtkm::cont::InitLogging(argc, argv);
|
||||
|
||||
int retval = 1;
|
||||
try
|
||||
{
|
||||
|
@ -28,12 +28,15 @@
|
||||
#include <vtkm/cont/testing/MakeTestDataSet.h>
|
||||
|
||||
#include <vtkm/rendering/Camera.h>
|
||||
#include <vtkm/rendering/internal/RunTriangulator.h>
|
||||
#include <vtkm/rendering/raytracing/Ray.h>
|
||||
#include <vtkm/rendering/raytracing/RayTracer.h>
|
||||
#include <vtkm/rendering/raytracing/SphereIntersector.h>
|
||||
#include <vtkm/rendering/raytracing/TriangleExtractor.h>
|
||||
|
||||
#include <vtkm/exec/FunctorBase.h>
|
||||
|
||||
#include <vtkm/cont/ColorTable.hxx>
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@ -66,18 +69,24 @@ struct BenchRayTracing
|
||||
camera.ResetToBounds(bounds);
|
||||
|
||||
vtkm::cont::DynamicCellSet cellset = Data.GetCellSet();
|
||||
vtkm::rendering::internal::RunTriangulator(cellset, Indices, NumberOfTriangles);
|
||||
|
||||
vtkm::rendering::raytracing::TriangleExtractor triExtractor;
|
||||
triExtractor.ExtractCells(cellset);
|
||||
vtkm::rendering::raytracing::TriangleIntersector* triIntersector =
|
||||
new vtkm::rendering::raytracing::TriangleIntersector();
|
||||
triIntersector->SetData(Coords, triExtractor.GetTriangles());
|
||||
Tracer.AddShapeIntersector(triIntersector);
|
||||
|
||||
vtkm::rendering::CanvasRayTracer canvas(1920, 1080);
|
||||
RayCamera.SetParameters(camera, canvas);
|
||||
RayCamera.CreateRays(Rays, Coords);
|
||||
RayCamera.CreateRays(Rays, Coords.GetBounds());
|
||||
|
||||
Rays.Buffers.at(0).InitConst(0.f);
|
||||
|
||||
vtkm::cont::Field field = Data.GetField("pointvar");
|
||||
vtkm::Range range = field.GetRange().GetPortalConstControl().Get(0);
|
||||
|
||||
Tracer.SetData(Coords.GetData(), Indices, field, NumberOfTriangles, range, bounds);
|
||||
Tracer.SetField(field, range);
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 4>> temp;
|
||||
vtkm::cont::ColorTable table("cool to warm");
|
||||
@ -107,7 +116,7 @@ struct BenchRayTracing
|
||||
{
|
||||
vtkm::cont::Timer<VTKM_DEFAULT_DEVICE_ADAPTER_TAG> timer;
|
||||
|
||||
RayCamera.CreateRays(Rays, Coords);
|
||||
RayCamera.CreateRays(Rays, Coords.GetBounds());
|
||||
Tracer.Render(Rays);
|
||||
|
||||
return timer.GetElapsedTime();
|
||||
|
@ -326,7 +326,7 @@ public:
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::cout << "\n"
|
||||
<< "An exception occuring during a benchmark:\n\t" << e.what() << "\n"
|
||||
<< "An exception occurring during a benchmark:\n\t" << e.what() << "\n"
|
||||
<< "Attempting to continue with remaining benchmarks...\n\n";
|
||||
}
|
||||
}
|
||||
|
7
docs/changelog/0-sample-topic.md
Normal file
7
docs/changelog/0-sample-topic.md
Normal file
@ -0,0 +1,7 @@
|
||||
# 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.
|
||||
|
1509
docs/changelog/1.3/release-notes.md
Normal file
1509
docs/changelog/1.3/release-notes.md
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,5 +0,0 @@
|
||||
# Add float version operations for vtkm::Math Pi()
|
||||
|
||||
Now PI related functions are evalulated at compile time as constexpr functions.
|
||||
It also removes the old static_cast<T>vtkm::Pi() usages with
|
||||
template ones and fix several conversion warnings.
|
@ -1,5 +0,0 @@
|
||||
# Add a release resources API to CellSet and its derived classes
|
||||
|
||||
We now offer the ability to unload execution memory from CellSet and its derived
|
||||
classes(CellSetExplicit, CellSetPermutation and CellSetStructured) using the ReleaseResourcesExecution.
|
||||
|
@ -1,31 +0,0 @@
|
||||
# TryExecuteOnDevice allows for runtime selection of which device to execute on
|
||||
|
||||
VTK-m now offers `vtkm::cont::TryExecuteOnDevice` to allow for the user to select
|
||||
which device to execute a function on at runtime. The original `vtkm::cont::TryExecute`
|
||||
used the first valid device, which meant users had to modify the runtime state
|
||||
through the `RuntimeTracker` which was verbose and unwieldy.
|
||||
|
||||
Here is an example of how you can execute a function on the device that an array handle was last executed
|
||||
on:
|
||||
```cpp
|
||||
|
||||
struct ArrayCopyFunctor
|
||||
{
|
||||
template <typename Device, typename InArray, typename OutArray>
|
||||
VTKM_CONT bool operator()(Device, const InArray& src, OutArray& dest)
|
||||
{
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::Copy(src, dest);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, typename InStorage, typename OutStorage>
|
||||
void SmartCopy(const vtkm::cont::ArrayHandle<T, InStorage>& src, vtkm::cont::ArrayHandle<T, OutStorage>& dest)
|
||||
{
|
||||
bool success = vtkm::cont::TryExecuteOnDevice(devId, ArrayCopyFunctor(), src, dest);
|
||||
if (!success)
|
||||
{
|
||||
vtkm::cont::TryExecute(ArrayCopyFunctor(), src, dest);
|
||||
}
|
||||
}
|
||||
```
|
@ -1,26 +0,0 @@
|
||||
# vtkm::cont::Algorithm now can be told which device to use at runtime
|
||||
|
||||
The `vtkm::cont::Algorithm` has been extended to support the user specifying
|
||||
which device to use at runtime previously Algorithm would only use the first
|
||||
enabled device, requiring users to modify the `vtkm::cont::GlobalRuntimeDeviceTracker`
|
||||
if they wanted a specific device used.
|
||||
|
||||
To select a specific device with vtkm::cont::Algorithm pass the `vtkm::cont::DeviceAdapterId`
|
||||
as the first parameter.
|
||||
|
||||
```cpp
|
||||
vtkm::cont::ArrayHandle<double> values;
|
||||
|
||||
|
||||
//call with no tag, will run on first enabled device
|
||||
auto result = vtkm::cont::Algorithm::Reduce(values, 0.0);
|
||||
|
||||
//call with an explicit device tag, will only run on serial
|
||||
vtkm::cont::DeviceAdapterTagSerial serial;
|
||||
result = vtkm::cont::Algorithm::Reduce(serial, values, 0.0);
|
||||
|
||||
//call with an runtime device tag, will only run on serial
|
||||
vtkm::cont::DeviceAdapterId device = serial;
|
||||
result = vtkm::cont::Algorithm::Reduce(device, values, 0.0);
|
||||
|
||||
```
|
@ -1,10 +0,0 @@
|
||||
# Add a common API for CoordinateSystem to unload execution resources
|
||||
|
||||
We now offer the ability to unload execution memory from ArrayHandleVirtualCoordinate
|
||||
and CoordinateSystem using the ReleaseResourcesExecution method.
|
||||
|
||||
Field now has a ReleaseResourcesExecution.
|
||||
|
||||
This commit also fixes a bug that ArrayTransfer of ArrayHandleVirtualCoordinate
|
||||
does not release execution resources properly.
|
||||
|
@ -1,4 +0,0 @@
|
||||
#Allow histogram filter to take custom types
|
||||
|
||||
By passing TypeList and StorageList type into FieldRangeGlobalCompute,
|
||||
upstream users(VTK) can pass custom types into the histogram filter.
|
@ -1,6 +0,0 @@
|
||||
Allow disabling/enabling of CUDA managed memory through a environment variable
|
||||
|
||||
By setting the environment variable "VTKM_MANAGEDMEMO_DISABLED" to be 1,
|
||||
users are able to disable CUDA managed memory even though the hardware is capable
|
||||
of doing so.
|
||||
|
@ -1,16 +0,0 @@
|
||||
# VTK-m ArrayHandle can now take ownership of a user allocated memory location
|
||||
|
||||
Previously memory that was allocated outside of VTK-m was impossible to transfer to
|
||||
VTK-m as we didn't know how to free it. By extending the ArrayHandle constructors
|
||||
to support a Storage object that is being moved, we can clearly express that
|
||||
the ArrayHandle now owns memory it didn't allocate.
|
||||
|
||||
Here is an example of how this is done:
|
||||
```cpp
|
||||
T* buffer = new T[100];
|
||||
auto user_free_function = [](void* ptr) { delete[] static_cast<T*>(ptr); };
|
||||
|
||||
vtkm::cont::internal::Storage<T, vtkm::cont::StorageTagBasic>
|
||||
storage(buffer, 100, user_free_function);
|
||||
vtkm::cont::ArrayHandle<T> arrayHandle(std::move(storage));
|
||||
```
|
@ -1,23 +0,0 @@
|
||||
# Add `ArrayHandleView` fancy array
|
||||
|
||||
Added a new class named `ArrayHandleView` that allows you to get a subset
|
||||
of an array. You use the `ArrayHandleView` by giving it a target array, a
|
||||
starting index, and a length. Here is a simple example of usage:
|
||||
|
||||
``` cpp
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> sourceArray;
|
||||
|
||||
vtkm::cont::ArrayCopy(vtkm::cont::ArrayHandleIndex(10), sourceArray);
|
||||
// sourceArray has [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
|
||||
vtkm::cont::ArrayHandleView<vtkm::cont::ArrayHandle<vtkm::Id>>
|
||||
viewArray(sourceArray, 3, 5);
|
||||
// viewArray has [3, 4, 5, 6, 7]
|
||||
```
|
||||
|
||||
There is also a convenience `make_ArraHandleView` function to create view
|
||||
arrays. The following makes the same view array as before.
|
||||
|
||||
``` cpp
|
||||
auto viewArray = vtkm::cont::make_ArrayHandleView(sourceArray, 3, 5);
|
||||
```
|
@ -1,20 +0,0 @@
|
||||
# `ArrayHandleCompositeVector` simplified and made writable.
|
||||
|
||||
`ArrayHandleCompositeVector` is now easier to use, as its type has a more
|
||||
straightforward definition: `ArrayHandleCompositeVector<Array1, Array2, ...>`.
|
||||
Previously, a helper metaprogramming struct was needed to determine the type
|
||||
of the array handle.
|
||||
|
||||
In addition, the new implementation supports both reading and writing, whereas
|
||||
the original version was read-only.
|
||||
|
||||
Another notable change is that the `ArrayHandleCompositeVector` no longer
|
||||
supports component extraction from the source arrays. While the previous version
|
||||
could take a source array with a `vtkm::Vec` `ValueType` and use only a single
|
||||
component in the output, the new version requires that all input arrays have
|
||||
the same `ValueType`, which becomes the `ComponentType` of the output
|
||||
`vtkm::Vec`.
|
||||
|
||||
When component extraction is needed, the classes `ArrayHandleSwizzle` and
|
||||
`ArrayHandleExtractComponent` have been introduced to allow the previous
|
||||
usecases to continue working efficiently.
|
@ -1,7 +0,0 @@
|
||||
# `ArrayHandleExtractComponent` target component is now set at runtime.
|
||||
|
||||
Rather than embedding the extracted component in a template parameter, the
|
||||
extract operation is now defined at runtime.
|
||||
|
||||
This is easier to use and keeps compile times / sizes / memory requirements
|
||||
down.
|
@ -1,8 +0,0 @@
|
||||
# `ArrayHandleSwizzle` component maps are now set at runtime.
|
||||
|
||||
Rather than embedding the component map in the template parameters, the swizzle
|
||||
operation is now defined at runtime using a `vtkm::Vec<vtkm::IdComponent, N>`
|
||||
that maps the input components to the output components.
|
||||
|
||||
This is easier to use and keeps compile times / sizes / memory requirements
|
||||
down.
|
@ -1,61 +0,0 @@
|
||||
# Build System Redesign and new minimum CMake
|
||||
|
||||
VTK-m CMake buildsystem was redesigned to be more declarative for consumers.
|
||||
This was done by moving away from the previous component design and instead
|
||||
to explicit targets. Additionally VTK-m now uses the native CUDA support
|
||||
introduced in CMake 3.8 and has the following minimum CMake versions:
|
||||
- Visual Studio Generator requires CMake 3.11+
|
||||
- CUDA support requires CMake 3.9+
|
||||
- Otherwise CMake 3.3+ is supported
|
||||
|
||||
When VTK-m is found find_package it defines the following targets:
|
||||
- `vtkm_cont`
|
||||
- contains all common core functionality
|
||||
- always exists
|
||||
|
||||
- `vtkm_rendering`
|
||||
- contains all the rendering code
|
||||
- exists only when rendering is enabled
|
||||
- rendering also provides a `vtkm_find_gl` function
|
||||
- allows you to find the GL (EGL,MESA,Hardware), GLUT, and GLEW
|
||||
versions that VTK-m was built with.
|
||||
|
||||
VTK-m also provides targets that represent what device adapters it
|
||||
was built to support. The pattern for these targets are `vtkm::<device>`.
|
||||
Currently we don't provide a target for the serial device.
|
||||
|
||||
- `vtkm::tbb`
|
||||
- Target that contains tbb related link information
|
||||
implicitly linked to by `vtkm_cont` if tbb was enabled
|
||||
|
||||
- `vtkm::cuda`
|
||||
- Target that contains cuda related link information
|
||||
implicitly linked to by `vtkm_cont` if cuda was enabled
|
||||
|
||||
VTK-m can be built with specific CPU architecture vectorization/optimization flags.
|
||||
Consumers of the project can find these flags by looking at the `vtkm_vectorization_flags`
|
||||
target.
|
||||
|
||||
So a project that wants to build an executable that uses vtk-m would look like:
|
||||
|
||||
```cmake
|
||||
|
||||
cmake_minimum_required(VERSION 3.3 FATAL_ERROR)
|
||||
project(HellowWorld CXX)
|
||||
|
||||
#Find the VTK-m package.
|
||||
#Will automatically enable the CUDA language if needed ( and bump CMake minimum )
|
||||
|
||||
find_package(VTKm REQUIRED)
|
||||
|
||||
add_executable(HelloWorld HelloWorld.cxx)
|
||||
target_link_libraries(HelloWorld PRIVATE vtkm_cont)
|
||||
|
||||
if(TARGET vtkm::cuda)
|
||||
set_source_files_properties(HelloWorld.cxx PROPERTIES LANGUAGE CUDA)
|
||||
endif()
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
@ -1,54 +0,0 @@
|
||||
# Cell measure functions, worklet, and filter
|
||||
|
||||
VTK-m now provides free functions, a worklet, and a filter for computing
|
||||
the integral measure of a cell (i.e., its arc length, area, or volume).
|
||||
|
||||
The free functions are located in `vtkm/exec/CellMeasure.h` and share the
|
||||
same signature:
|
||||
|
||||
```c++
|
||||
template<typename OutType, typename PointVecType>
|
||||
OutType CellMeasure(
|
||||
const vtkm::IdComponent& numPts,
|
||||
const PointCoordVecType& pts,
|
||||
CellShapeTag,
|
||||
const vtkm::exec::FunctorBase& worklet);
|
||||
```
|
||||
|
||||
The number of points argument is provided for cell-types such as lines,
|
||||
which allow an arbitrary number of points per cell.
|
||||
See the worklet for examples of their use.
|
||||
|
||||
The worklet is named `vtkm::worklet::CellMeasure` and takes a template
|
||||
parameter that is a tag list of measures to include.
|
||||
Cells that are not selected by the tag list return a measure of 0.
|
||||
Some convenient tag lists are predefined for you:
|
||||
|
||||
+ `vtkm::ArcLength` will only compute the measure of cells with a 1-dimensional parameter-space.
|
||||
+ `vtkm::Area` will only compute the measure of cells with a 2-dimensional parameter-space.
|
||||
+ `vtkm::Volume` will only compute the measure of cells with a 3-dimensional parameter-space.
|
||||
+ `vtkm::AllMeasures` will compute all of the above.
|
||||
|
||||
The filter version, named `vtkm::filter::CellMeasures` – plural since
|
||||
it produces a cell-centered array of measures — takes the same template
|
||||
parameter and tag lists as the worklet.
|
||||
By default, the output array of measure values is named "measure" but
|
||||
the filter accepts other names via the `SetCellMeasureName()` method.
|
||||
|
||||
The only cell type that is not supported is the polygon;
|
||||
you must triangulate polygons before running this filter.
|
||||
See the unit tests for examples of how to use the worklet and filter.
|
||||
|
||||
The cell measures are all signed: negative measures indicate that the cell is inverted.
|
||||
Simplicial cells (points, lines, triangles, tetrahedra) cannot not be inverted
|
||||
by definition and thus always return values above or equal to 0.0.
|
||||
Negative values indicate either the order in which vertices appear in its connectivity
|
||||
array is improper or the relative locations of the vertices in world coordinates
|
||||
result in a cell with a negative Jacobian somewhere in its interior.
|
||||
Finally, note that cell measures may return invalid (NaN) or infinite (Inf, -Inf)
|
||||
values if the cell is poorly defined, e.g., has coincident vertices
|
||||
or a parametric dimension larger than the space spanned by its world-coordinate
|
||||
vertices.
|
||||
|
||||
The verdict mesh quality library was used as the source of the methods
|
||||
for approximating the cell measures.
|
@ -1,21 +0,0 @@
|
||||
# CellSetExplicit now caches CellToPoint table when used with Invoke.
|
||||
|
||||
Issue #268 highlighted an issue where the expensive CellToPoint table
|
||||
update was not properly cached when a CellSetExplicit was used with a
|
||||
filter. This has been corrected by ensuring that the metadata
|
||||
associated with the table survives shallow copying of the CellSet.
|
||||
|
||||
New methods are also added to check whether the CellToPoint table
|
||||
exists, and also to reset it if needed (e.g. for benchmarking):
|
||||
|
||||
```
|
||||
vtkm::cont::CellSetExplicit<> cellSet = ...;
|
||||
// Check if the CellToPoint table has already been computed:
|
||||
if (cellSet.HasConnectivity(vtkm::TopologyElementTagCell{},
|
||||
vtkm::TopologyElementTagPoint{}))
|
||||
{
|
||||
// Reset it:
|
||||
cellSet.ResetConnectivity(vtkm::TopologyElementTagCell{},
|
||||
vtkm::TopologyElementTagPoint{});
|
||||
}
|
||||
```
|
@ -1,27 +0,0 @@
|
||||
# User defined execution objects now usable with runtime selection of device adapter
|
||||
|
||||
- Changed how Execution objects are created and passed from the cont environment to the execution environment. See chapter 13.9 on worklets in the user manual for details.
|
||||
|
||||
- Instead we will now fill out a class and call prepareForExecution() and create the execution object for the execution environment from this function. This way we do not have to template the class that extends `vtkm::cont::ExecutionObjectBase` on the device.
|
||||
|
||||
Example of new execution object:
|
||||
```cpp
|
||||
template <typename Device>
|
||||
struct ExecutionObject
|
||||
{
|
||||
vtkm::Int32 Number;
|
||||
};
|
||||
|
||||
struct TestExecutionObject : public vtkm::cont::ExecutionObjectBase
|
||||
{
|
||||
vtkm::Int32 Number;
|
||||
|
||||
template <typename Device>
|
||||
VTKM_CONT ExecutionObject<Device> PrepareForExecution(Device) const
|
||||
{
|
||||
ExecutionObject<Device> object;
|
||||
object.Number = this->Number;
|
||||
return object;
|
||||
}
|
||||
};
|
||||
```
|
@ -1,4 +0,0 @@
|
||||
# Use the strong typed enums for vtkm::cont::Field
|
||||
|
||||
By doing so, the compiler would not convert these enums into `int`s
|
||||
which can cause some unexpected behavior.
|
@ -1,8 +0,0 @@
|
||||
# Add new option to VTKm_CUDA_Architecture
|
||||
|
||||
A new VTKm_CUDA_Architecture option called 'none' has been added. This will
|
||||
disable all VTK-m generated cuda architecture flags, allowing the user to
|
||||
specify their own custom flags.
|
||||
|
||||
Useful when VTK-m is used as a library in another project and the project wants
|
||||
to use its own architecture flags.
|
@ -1,15 +0,0 @@
|
||||
# Worklets are now asynchronous in Cuda
|
||||
|
||||
Worklets are now fully asynchronous in the cuda backend. This means that
|
||||
worklet errors are reported asynchonously. Existing errors are checked for
|
||||
before invocation of a new worklet and at explicit synchronization points like
|
||||
`DeviceAdapterAlgorithm<>::Synchronize()`.
|
||||
|
||||
An important effect of this change is that functions that are synchronization
|
||||
points, like `ArrayHandle::GetPortalControl()` and
|
||||
`ArrayHandle::GetPortalConstControl()`, may now throw exception for errors from
|
||||
previously executed worklets.
|
||||
|
||||
Worklet invocations, synchronization and error reporting happen independtly
|
||||
on different threads. Therefore, synchronization on one thread does not affect
|
||||
any other threads.
|
@ -1,8 +0,0 @@
|
||||
# Add support for deferred freeing of cuda memory
|
||||
|
||||
A new function, `void CudaAllocator::FreeDeferred(void* ptr, std::size_t numBytes)` has
|
||||
been added that can be used to defer the freeing of cuda memory to a later point.
|
||||
This is useful because `cudaFree` causes a global sync across all cuda streams. This function
|
||||
internally maintains a pool of to-be-freed pointers that are freed together when a
|
||||
size threshold is reached. This way a number of global syncs are collected together at
|
||||
one point.
|
@ -1,49 +0,0 @@
|
||||
# VTK-m Worklets now execute on Cuda using grid stride loops
|
||||
|
||||
Previously VTK-m Worklets used what is referred to as a monolithic kernel
|
||||
pattern for worklet execution. This assumes a single large grid of threads
|
||||
to process an entire array in a single pass. This resulted in launches that
|
||||
looked like:
|
||||
|
||||
```cpp
|
||||
template<typename F>
|
||||
void TaskSingular(F f, vtkm::Id end)
|
||||
{
|
||||
const vtkm::Id index = static_cast<vtkm::Id>(blockDim.x * blockIdx.x + threadIdx.x);
|
||||
if (index < end)
|
||||
{
|
||||
f(index);
|
||||
}
|
||||
}
|
||||
|
||||
Schedule1DIndexKernel<TaskSingular><<<totalBlocks, 128, 0, cudaStreamPerThread>>>(
|
||||
functor, numInstances);
|
||||
```
|
||||
|
||||
This was problematic as it had the drawbacks of:
|
||||
- Not being able to reuse any infrastructure between kernel executions.
|
||||
- Harder to tune performance based on the current hardware.
|
||||
|
||||
The solution was to move to a grid stride loop strategy with a block size
|
||||
based off the number of SM's on the executing GPU. The result is something
|
||||
that looks like:
|
||||
|
||||
```cpp
|
||||
template<typename F>
|
||||
void TaskStrided(F f, vtkm::Id end)
|
||||
{
|
||||
const vtkm::Id start = blockIdx.x * blockDim.x + threadIdx.x;
|
||||
const vtkm::Id inc = blockDim.x * gridDim.x;
|
||||
for (vtkm::Id index = start; index < end; index += inc)
|
||||
{
|
||||
f(index);
|
||||
}
|
||||
}
|
||||
Schedule1DIndexKernel<TaskStrided><<<32*numSMs, 128, 0, cudaStreamPerThread>>>(
|
||||
functor, numInstances);
|
||||
```
|
||||
|
||||
With a loop stride equal to grid size we maintain the optimal memory
|
||||
coalescing patterns as we had with the monolithic version. These changes
|
||||
also allow VTK-m to optimize TaskStrided so that it can reuse infrastructure
|
||||
between iterations.
|
@ -1,41 +0,0 @@
|
||||
#DeviceAdapterId has becomes a real constexpr type and not an alias to vtkm::UInt8
|
||||
|
||||
As part of the ability to support `vtkm::cont::TryExecuteOnDevice` VTK-m has made the
|
||||
DeviceAdapterId a real constexpr type instead of a vtkm::UInt8.
|
||||
|
||||
The benefits of a real type are as follows:
|
||||
|
||||
- Easier to add functionality like range verification, which previously had
|
||||
to be located in each user of `DeviceAdapterId`
|
||||
|
||||
- In ability to have ambiguous arguments. Previously it wasn't perfectly clear
|
||||
what a method parameter of `vtkm::UInt8` represented. Was it actually the
|
||||
DeviceAdapterId or something else?
|
||||
|
||||
- Ability to add subclasses that represent things such as Undefined, Error, or Any.
|
||||
|
||||
|
||||
The implementation of DeviceAdapterId is:
|
||||
```cpp
|
||||
struct DeviceAdapterId
|
||||
{
|
||||
constexpr explicit DeviceAdapterId(vtkm::Int8 id)
|
||||
: Value(id)
|
||||
{
|
||||
}
|
||||
|
||||
constexpr bool operator==(DeviceAdapterId other) const { return this->Value == other.Value; }
|
||||
constexpr bool operator!=(DeviceAdapterId other) const { return this->Value != other.Value; }
|
||||
constexpr bool operator<(DeviceAdapterId other) const { return this->Value < other.Value; }
|
||||
|
||||
constexpr bool IsValueValid() const
|
||||
{
|
||||
return this->Value > 0 && this->Value < VTKM_MAX_DEVICE_ADAPTER_ID;
|
||||
}
|
||||
|
||||
constexpr vtkm::Int8 GetValue() const { return this->Value; }
|
||||
|
||||
private:
|
||||
vtkm::Int8 Value;
|
||||
};
|
||||
```
|
@ -1,45 +0,0 @@
|
||||
# DeviceAdapterTags are usable for runtime device selection
|
||||
|
||||
VTK-m DeviceAdapterTags now are both a compile time representation of which device to use, and
|
||||
also the runtime representation of that device. Previously the runtime representation was handled
|
||||
by `vtkm::cont::DeviceAdapterId`. This was done by making `DeviceAdapterTag`'s' a constexpr type that
|
||||
inherits from the constexpr `vtkm::cont::DeviceAdapterId` type.
|
||||
|
||||
At at ten thousand foot level this change means that in general instead of using `vtkm::cont::DeviceAdapterTraits<DeviceTag>`
|
||||
you can simply use `DeviceTag`, or an instance of if `DeviceTag runtimeDeviceId;`.
|
||||
|
||||
Previously if you wanted to get the runtime representation of a device you would do the following:
|
||||
```cpp
|
||||
template<typename DeviceTag>
|
||||
vtkm::cont::DeviceAdapterId getDeviceId()
|
||||
{
|
||||
using Traits = vtkm::cont::DeviceAdapterTraits<DeviceTag>;
|
||||
return Traits::GetId();
|
||||
}
|
||||
...
|
||||
vtkm::cont::DeviceAdapterId runtimeId = getDeviceId<DeviceTag>();
|
||||
```
|
||||
Now with the updates you could do the following.
|
||||
```cpp
|
||||
vtkm::cont::DeviceAdapterId runtimeId = DeviceTag();
|
||||
```
|
||||
More importantly this conversion is unnecessary as you can pass instances `DeviceAdapterTags` into methods or functions
|
||||
that want `vtkm::cont::DeviceAdapterId` as they are that type!
|
||||
|
||||
|
||||
Previously if you wanted to see if a DeviceAdapter was enabled you would the following:
|
||||
```cpp
|
||||
using Traits = vtkm::cont::DeviceAdapterTraits<DeviceTag>;
|
||||
constexpr auto isValid = std::integral_constant<bool, Traits::Valid>();
|
||||
```
|
||||
Now you would do:
|
||||
```cpp
|
||||
constexpr auto isValid = std::integral_constant<bool, DeviceTag::IsEnabled>();
|
||||
```
|
||||
|
||||
So why did VTK-m make these changes?
|
||||
|
||||
That is a good question, and the answer for that is two fold. The VTK-m project is working better support for ArraysHandles that leverage runtime polymorphism (aka virtuals), and the ability to construct `vtkm::worklet::Dispatchers` without specifying
|
||||
the explicit device they should run on. Both of these designs push more of the VTK-m logic to operate at runtime rather than compile time. This changes are designed to allow for consistent object usage between runtime and compile time instead of having
|
||||
to convert between compile time and runtime types.
|
||||
|
@ -1,15 +0,0 @@
|
||||
# Make DispatcherBase invoke using a TryExecute
|
||||
|
||||
Rather than force all dispatchers to be templated on a device adapter,
|
||||
instead use a TryExecute internally within the invoke to select a device
|
||||
adapter.
|
||||
|
||||
Because this removes the need to declare a device when invoking a worklet,
|
||||
this commit also removes the need to declare a device in several other
|
||||
areas of the code.
|
||||
|
||||
This changes touches quite a bit a code. The first pass of the change
|
||||
usually does the minimum amount of work, which is to change the
|
||||
compile-time specification of the device to a run-time call to `SetDevice`
|
||||
on the dispatcher. Although functionally equivalent, it might mean calling
|
||||
`TryExecute` within itself.
|
@ -1,19 +0,0 @@
|
||||
# VTK-m now supports dispatcher parameters being pointers
|
||||
|
||||
Previously it was only possible to pass values to a dispatcher when
|
||||
you wanted to invoke a VTK-m worklet. This caused problems when it came
|
||||
to designing new types that used inheritance as the types couldn't be
|
||||
past as the base type to the dispatcher. To fix this issue we now
|
||||
support invoking worklets with pointers as seen below.
|
||||
|
||||
```cpp
|
||||
vtkm::cont::ArrayHandle<T> input;
|
||||
//fill input
|
||||
|
||||
vtkm::cont::ArrayHandle<T> output;
|
||||
vtkm::worklet::DispatcherMapField<WorkletType> dispatcher;
|
||||
|
||||
dispatcher(&input, output);
|
||||
dispatcher(input, &output);
|
||||
dispatcher(&input, &output);
|
||||
```
|
@ -1,6 +0,0 @@
|
||||
# Dot product function name changed.
|
||||
|
||||
The free function `vtkm::dot()` has been renamed to `vtkm::Dot()`
|
||||
to be consistent with other vtk-m function names.
|
||||
Aliases are provided for backwards compatibility but will
|
||||
be removed in the next release.
|
@ -1,11 +0,0 @@
|
||||
# Add a new cmake option: VTKm_ENABLE_DEVELOPER_FLAGS
|
||||
|
||||
The new cmake option VTKm_ENABLE_DEVELOPER_FLAGS can be used to enable/disable
|
||||
warnings in VTK-m. It is useful to disable VTK-m's warning flags when VTK-m is
|
||||
directly embedded by a project as sub project (add_subdirectory), and the
|
||||
warnings are too strict for the project. This does not apply when using an
|
||||
installed version of VTK-m.
|
||||
|
||||
For example, this flag is disabled in VTK.
|
||||
|
||||
This flag is enabled by default.
|
@ -1,24 +0,0 @@
|
||||
# Support ExecArg behavior in `vtkm::cont::Algorithm` methods
|
||||
|
||||
`vtkm::cont::Algorithm` is a wrapper around `DeviceAdapterAlgorithm` that
|
||||
internally uses `TryExecute`s to select an appropriate device. The
|
||||
intention is that you can run parallel algorithms (outside of worklets)
|
||||
without having to specify a particular device.
|
||||
|
||||
Most of the arguments given to device adapter algorithms are actually
|
||||
control-side arguments that get converted to execution objects internally
|
||||
(usually a `vtkm::cont::ArrayHandle`). However, some of the algorithms,
|
||||
take an argument that is passed directly to the execution environment, such
|
||||
as the predicate argument of `Sort`. If the argument is a plain-old-data
|
||||
(POD) type, which is common enough, then you can just pass the object
|
||||
straight through. However, if the object has any special elements that have
|
||||
to be transferred to the execution environment, such as internal arrays,
|
||||
passing this to the `vtkm::cont::Algorithm` functions becomes problematic.
|
||||
|
||||
To cover this use case, all the `vtkm::cont::Algorithm` functions now
|
||||
support automatically transferring objects that support the `ExecObject`
|
||||
worklet convention. If any argument to any of the `vtkm::cont::Algorithm`
|
||||
functions inherits from `vtkm::cont::ExecutionObjectBase`, then the
|
||||
`PrepareForExecution` method is called with the device the algorithm is
|
||||
running on, which allows these device-specific objects to be used without
|
||||
the hassle of creating a `TryExecute`.
|
@ -1,75 +0,0 @@
|
||||
# New geometry classes and header.
|
||||
|
||||
There are now some additional structures available both
|
||||
the control and execution environments for representing
|
||||
geometric entities (mostly of dimensions 2 and 3).
|
||||
These new structures are now in `vtkm/Geometry.h` and
|
||||
demonstrated/tested in `vtkm/testing/TestingGeometry.h`:
|
||||
|
||||
+ `Ray<CoordType, Dimension, IsTwoSided>`.
|
||||
Instances of this struct represent a semi-infinite line
|
||||
segment in a 2-D plane or in a 3-D space, depending on the
|
||||
integer dimension specified as a template parameter.
|
||||
Its state is the point at the start of the ray (`Origin`)
|
||||
plus the ray's `Direction`, a unit-length vector.
|
||||
If the third template parameter (IsTwoSided) is true, then
|
||||
the ray serves as an infinite line. Otherwise, the ray will
|
||||
only report intersections in its positive halfspace.
|
||||
+ `LineSegment<CoordType, Dimension>`.
|
||||
Instances of this struct represent a finite line segment
|
||||
in a 2-D plane or in a 3-D space, depending on the integer
|
||||
dimension specified as a template parameter.
|
||||
Its state is the coordinates of its `Endpoints`.
|
||||
+ `Plane<CoordType>`.
|
||||
Instances of this struct represent a plane in 3-D.
|
||||
Its state is the coordinates of a base point (`Origin`) and
|
||||
a unit-length normal vector (`Normal`).
|
||||
+ `Sphere<CoordType, Dimension>`.
|
||||
Instances of this struct represent a *d*-dimensional sphere.
|
||||
Its state is the coordinates of its center plus a radius.
|
||||
It is also aliased with a `using` statment to `Circle<CoordType>`
|
||||
for the specific case of 2-D.
|
||||
|
||||
These structures provide useful queries and generally
|
||||
interact with one another.
|
||||
For instance, it is possible to intersect lines and planes
|
||||
and compute distances.
|
||||
|
||||
For ease of use, there are also several `using` statements
|
||||
that alias these geometric structures to names that specialize
|
||||
them for a particular dimension or other template parameter.
|
||||
As an example, `Ray<CoordType, Dimension, true>` is aliased
|
||||
to `Line<CoordType, Dimension>` and `Ray<CoordType, 3, true>`
|
||||
is aliased to `Line3<CoordType>` and `Ray<FloatDefault, 3, true>`
|
||||
is aliased to `Line3d`.
|
||||
|
||||
## Design patterns
|
||||
|
||||
If you plan to add a new geometric entity type,
|
||||
please adopt these conventions:
|
||||
|
||||
+ Each geometric entity may be default-constructed.
|
||||
The default constructor will initialize the state to some
|
||||
valid unit-length entity, usually with some part of
|
||||
its state at the origin of the coordinate system.
|
||||
+ Entities may always be constructed by passing in values
|
||||
for their internal state.
|
||||
Alternate construction methods are declared as free functions
|
||||
such as `make_CircleFrom3Points()`
|
||||
+ Use template metaprogramming to make methods available
|
||||
only when the template dimension gives them semantic meaning.
|
||||
For example, a 2-D line segment's perpendicular bisector
|
||||
is another line segment, but a 3-D line segment's perpendicular
|
||||
line segment is a plane.
|
||||
Note how this is accomplished and apply this pattern to
|
||||
new geometric entities or new methods on existing entities.
|
||||
+ Some entities may have invalid state.
|
||||
If this is possible, the entity will have an `IsValid()` method.
|
||||
For example, a sphere may be invalid because the user or some
|
||||
construction technique specified a zero or negative radius.
|
||||
+ When signed distance is semantically meaningful, provide it
|
||||
in favor of or in addition to unsigned distance.
|
||||
+ Accept a tolerance parameter when appropriate,
|
||||
but provide a sensible default value.
|
||||
You may want to perform exact arithmetic versions of tests,
|
||||
but please provide fast, tolerance-based versions as well.
|
@ -1,9 +0,0 @@
|
||||
# Add a new cmake option: VTKm_INSTALL_ONLY_LIBRARIES
|
||||
|
||||
The new cmake option VTKm_INSTALL_ONLY_LIBRARIES when enabled will cause
|
||||
VTK-m to only install libraries. This is useful for projects that are
|
||||
producing an application and don't want to ship headers or CMake infrastructure.
|
||||
|
||||
For example, this flag is enabled by ParaView for releases.
|
||||
|
||||
This flag is disabled by default.
|
@ -1,20 +0,0 @@
|
||||
# Filter to support Lagrangian analysis capabilities.
|
||||
|
||||
Lagrangian analysis operates in two phases - phase one involes the extraction of flow field information. Phase two involves calculating new particle trajectories using the saved information.
|
||||
|
||||
The lagrangian filter can be used to extract flow field information given a time-varying vector fields. The extracted information is in the form of particle trajectories.
|
||||
|
||||
The filter operates by first being set up with some information regarding step size, the interval at which information should be saved (write frequency), the number of seeds to be placed in the domain (specified as a reduction factor along each axis of the original dimensions).
|
||||
The step size should be equivalent to the time between vector field data input.
|
||||
The write frequency corresponds to the number of cycles between saves.
|
||||
|
||||
Filter execution is called for each cycle of the simulation data. Each filter execution call requires a velocity field to advect particles forward.
|
||||
|
||||
The extracted particle trajectories - referred to as basis flows exist in the domain for the specified interval (write frequency). Particles are then reset along a uniform grid and new particle trajectories are calculated.
|
||||
|
||||
An example of using the Lagrangian filter is at vtk-m/examples/lagrangian
|
||||
The basis flows are saved into a folder named output which needs to be created in the directory in which the program is being executed.
|
||||
|
||||
The basis flows can be interpolated using barycentric coordinate interpolation or a form of linear interpolation to calculate new particle trajectories post hoc.
|
||||
|
||||
An example of using basis flows generated by the Lagrangian filter is at vtk-m/examples/posthocinterpolation. The folder contains a script which specifies parameters which need to be provided to use the example.
|
11
docs/changelog/merge-worklet-testing-executables.md
Normal file
11
docs/changelog/merge-worklet-testing-executables.md
Normal file
@ -0,0 +1,11 @@
|
||||
Merge worklet testing executables into a device dependent shared library
|
||||
|
||||
VTK-m has been updated to replace old per device worklet testing executables with a device
|
||||
dependent shared library so that it's able to accept a device adapter
|
||||
at runtime.
|
||||
Meanwhile, it updates the testing infrastructure APIs. vtkm::cont::testing::Run
|
||||
function would call ForceDevice when needed and if users need the device
|
||||
adapter info at runtime, RunOnDevice function would pass the adapter into the functor.
|
||||
|
||||
Optional Parser is bumped from 1.3 to 1.7.
|
||||
|
@ -1,5 +0,0 @@
|
||||
# OpenMP Device Adapter
|
||||
|
||||
A device adapter that leverages OpenMP 4.0 for threading is now available. The
|
||||
new adapter is enabled using the CMake option `VTKm_ENABLE_OPENMP` and its
|
||||
performance is comparable to the TBB device adapter.
|
@ -1,11 +0,0 @@
|
||||
# Time-varying "oscillator" source-filter and example
|
||||
|
||||
The oscillator is a simple analytical source of time-varying data.
|
||||
It provides a function value at each point of a uniform grid that
|
||||
is computed as a sum of Gaussian kernels — each with a specified
|
||||
position, amplitude, frequency, and phase.
|
||||
|
||||
The example (in `examples/oscillator`) generates volumetric Cinema
|
||||
datasets that can be viewed in a web browser with [ArcticViewer][].
|
||||
|
||||
[ArcticViewer]: https://kitware.github.io/arctic-viewer/
|
@ -1,5 +0,0 @@
|
||||
Replace std::random_shuffle with std::shuffle
|
||||
|
||||
std::random_shuffle is deprecated in C++14 because it's using std::rand
|
||||
which uses a non uniform distribution and the underlying algorithm is
|
||||
unspecified. Using std::shuffle can provide a reliable result in a 64 bit version.
|
@ -1,73 +0,0 @@
|
||||
# Scatter class moved to dispatcher
|
||||
|
||||
Scatter classes are special objects that are associated with a worklet to
|
||||
adjust the standard 1:1 mapping of input to output in the worklet execution
|
||||
to some other mapping with multiple outputs to a single input or skipping
|
||||
over input values. A classic use case is the Marching Cubes algorithm where
|
||||
cube cases will have different numbers of output. A scatter object allows
|
||||
you to specify for each output polygon which source cube it comes from.
|
||||
|
||||
Scatter objects have been in VTK-m for some time now (since before the 1.0
|
||||
release). The way they used to work is that the worklet completely managed
|
||||
the scatter object. It would declare the `ScatterType`, keep a copy as part
|
||||
of its state, and provide a `GetScatter` method so that the dispatcher
|
||||
could use it for scheduling.
|
||||
|
||||
The problem with this approach is that it put control-environment-specific
|
||||
state into the worklet. The scatter object would be pushed into the
|
||||
execution environment (like a CUDA device) like the rest of the worklet
|
||||
where it could not be used. It also meant that worklets that defined their
|
||||
own scatter had to declare a bunch more code to manage the scatter.
|
||||
|
||||
This behavior has been changed so that the dispatcher object manages the
|
||||
scatter object. The worklet still declares the type of scatter by declaring
|
||||
a `ScatterType` (defaulting to `ScatterUniform` for 1:1 mapping),
|
||||
but its responsibility ends there. When the dispatcher is constructed, it
|
||||
must be given a scatter object that matches the `ScatterType` of the
|
||||
associated worklet. (If `ScatterType` has a default constructor, then one
|
||||
can be created automatically.) A worklet may declare a static `MakeScatter`
|
||||
method for convenience, but this is not necessary.
|
||||
|
||||
As an example, a worklet may declare a custom scatter like this.
|
||||
|
||||
``` cpp
|
||||
class Generate : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
typedef void ControlSignature(FieldIn<Vec3> inPoints,
|
||||
FieldOut<Vec3> outPoints);
|
||||
typedef void ExecutionSignature(_1, _2);
|
||||
using InputDomain = _1;
|
||||
|
||||
using ScatterType = vtkm::worklet::ScatterCounting;
|
||||
|
||||
template<typename CountArrayType, typename DeviceAdapterTag>
|
||||
VTKM_CONT
|
||||
static ScatterType MakeScatter(const CountArrayType &countArray,
|
||||
DeviceAdapterTag)
|
||||
{
|
||||
VTKM_IS_ARRAY_HANDLE(CountArrayType);
|
||||
return ScatterType(countArray, DeviceAdapterTag());
|
||||
}
|
||||
```
|
||||
|
||||
Note that the `ScatterCounting` needs to be created with the appropriate
|
||||
indexing arrays to make the scatter behave as the worklet expects, so the
|
||||
worklet provides a helpful `MakeScatter` method to make it more clear how
|
||||
to construct the scatter.
|
||||
|
||||
This worklet can be invoked as follows.
|
||||
|
||||
``` cpp
|
||||
auto generateScatter =
|
||||
ClipPoints::Generate::MakeScatter(countArray, DeviceAdapterTag());
|
||||
vtkm::worklet::DispatcherMapField<ClipPoints::Generate, DeviceAdapterTag>
|
||||
dispatcherGenerate(generateScatter);
|
||||
dispatcherGenerate.Invoke(pointArray, clippedPointsArray);
|
||||
```
|
||||
|
||||
Because the `ScatterCounting` class does not have a default constructor,
|
||||
you would get a compiler error if you failed to provide one to the
|
||||
dispatcher's constructor. The compiler error will probably not be too
|
||||
helpful the the user, but there is a detailed comment in the dispatcher's
|
||||
code where the compiler error will occur describing what the issue is.
|
@ -1,5 +0,0 @@
|
||||
# CellDerivativeFor3DCell has a better version for Vec of Vec fields.
|
||||
|
||||
Previously we would compute a 3x3 matrix where each element was a Vec. Using
|
||||
the jacobain of a single component is sufficient instead of computing it for
|
||||
each component. This approach saves anywhere from 2 to 3 times the memory space.
|
@ -1,54 +0,0 @@
|
||||
#Interfaces for VTK-m spatial search strucutres added
|
||||
|
||||
The objective for this feature was to add a commom interface for the VTK-m
|
||||
spatial search strucutes for ease of use for the users.
|
||||
VTK-m now distinguishes locators into two types, cell locators and point
|
||||
locators. Cell locators can be used to query a containing cell for a point,
|
||||
and point locators can be used to search for other points that are close to the
|
||||
given point.
|
||||
|
||||
All cell locators are now required to inherit from the interface
|
||||
`vtkm::cont::CellLocator`, and all point locatos are required to inherit from
|
||||
the interface `vtkm::cont::PointLocator`
|
||||
|
||||
These interfaces describe the necessary features that are required from either
|
||||
a cell locator, or a point locator and provided an easy way to use them in the
|
||||
execution environment.
|
||||
|
||||
By deriving new search structures from these locator interfaces, it makes it
|
||||
easier for users to build the underlying strucutres as well, abstracting away
|
||||
complicated details. After providing all the required data from a
|
||||
`vtkm::cont::DataSet` object, the user only need to call the `Update` method
|
||||
on the object of `vtkm::cont::CellLocator`, or `vtkm::cont::PointLocator`.
|
||||
|
||||
For example, building the cell locator which used a Bounding Interval Hiererchy
|
||||
tree as a search structure, provided in the class
|
||||
`vtkm::cont::BoundingIntervalHierarchy` which inherits from
|
||||
`vtkm::cont::CellLocator`, only requires few steps.
|
||||
|
||||
```c++
|
||||
// Build a bounding interval hierarchy with 5 splitting planes,
|
||||
// and a maximum of 10 cells in the leaf node.
|
||||
vtkm::cont::BoundingIntervalHierarchy locator(5, 10);
|
||||
// Provide the cell set required by the search structure.
|
||||
locator.SetCellSet(cellSet);
|
||||
// Provide the coordinate system required by the search structure.
|
||||
locator.SetCoordinates(coords);
|
||||
// Cell the Update methods to finish building the underlying tree.
|
||||
locator.Update();
|
||||
```
|
||||
Similarly, users can easily build available point locators as well.
|
||||
|
||||
When using an object of `vtkm::cont::CellLocator`, or `vtkm::cont::PointLocator`
|
||||
in the execution environment, they need to be passed to the worklet as an
|
||||
`ExecObject` argument. In the execution environment, users will receive a
|
||||
pointer to an object of type `vtkm::exec::CellLocator`, or
|
||||
`vtkm::exec::PointLocator` respectively. `vtkm::exec::CellLocator` provides a
|
||||
method `FindCell` to use in the execution environment to query the containing
|
||||
cell of a point. `vtkm::exec::PointLocator` provides a method
|
||||
`FindNearestNeighbor` to query for the nearest point.
|
||||
|
||||
As of now, VTK-m provides only one implementation for each of the given
|
||||
interfaces. `vtkm::cont::BoundingIntervalHierarchy` which is an implementation
|
||||
of `vtkm::cont::CellLocator`, and `vtkm::cont::PointLocatorUniformGrid`, which
|
||||
is an implementation of `vtkm::cont::PointLocator`.
|
@ -1,24 +0,0 @@
|
||||
# VTK-m StorageBasic now can provide or be provided a delete function
|
||||
|
||||
Memory that was allocated outside of VTK-m was impossible to transfer to
|
||||
VTK-m as we didn't know how to free it. This is now resolved by allowing the
|
||||
user to specify a free function to be called on release.
|
||||
|
||||
Memory that was allocated by VTK-m and Stolen by the user needed the
|
||||
proper free function. When running on CUDA on hardware that supports
|
||||
concurrent managed access the free function of the storage could
|
||||
be cudaFree.
|
||||
|
||||
To properly steal memory from VTK-m you do the following:
|
||||
```cpp
|
||||
vtkm::cont::ArrayHandle<T> arrayHandle;
|
||||
//fill arrayHandle
|
||||
|
||||
//you must get the free function before calling steal array
|
||||
auto free_function = arrayHandle.GetDeleteFunction();
|
||||
T* ptr = arrayHandle.StealArray();
|
||||
//use ptr
|
||||
|
||||
|
||||
free_function(ptr);
|
||||
```
|
@ -1,7 +0,0 @@
|
||||
# Add a CUDA-safe `vtkm::Swap` method.
|
||||
|
||||
Added a swap implementation that is safe to call from all backends.
|
||||
|
||||
It is not legal to call std functions from CUDA code, and the new
|
||||
`vtkm::Swap` implements a naive swap when compiled under NVCC while
|
||||
falling back to a std/ADL swap otherwise.
|
@ -1,4 +0,0 @@
|
||||
# Use std::call_once to construct singeltons
|
||||
|
||||
By using call_once from C++11, we can simplify the logic in code where we are querying same value variables from multiple threads.
|
||||
|
@ -1,5 +0,0 @@
|
||||
# Use thread_local in GetGlobalRuntimeDeviceTracker function if possible
|
||||
|
||||
It will reduce the cost of getting the thread runtime device tracker,
|
||||
and will have a better runtime overhead if user constructs a lot of
|
||||
short lived threads that use VTK-m.
|
@ -1,115 +0,0 @@
|
||||
# Support constexpr and variadic constructor for Vec
|
||||
|
||||
Add variadic constructors to the `vtkm::Vec` classes. The main advantage of this addition
|
||||
is that it makes it much easier to initialize `Vec`s of arbitrary length.
|
||||
|
||||
Meanwhile, `Vec` classes constructed with values listed in their parameters up to size 4
|
||||
are constructed as constant expressions at compile time to reduce runtime overhead.
|
||||
Sizes greater than 4 are not yet supported to be constructed at compile time via initializer lists
|
||||
since in C++11 constexpr does not allow for loops. Only on Windows platform with a compiler older
|
||||
than Visual Studio 2017 version 15.0, users are allowed to use initializer lists to construct a
|
||||
vec with size > 4.
|
||||
|
||||
`vtkm::make_Vec` would always construct `Vec` at compile time if possible.
|
||||
|
||||
``` cpp
|
||||
vtkm::Vec<vtkm::Float64, 3> vec1{1.1, 2.2, 3.3}; // New better initializer since
|
||||
// it does not allow type narrowing
|
||||
|
||||
vtkm::Vec<vtkm::Float64, 3> vec2 = {1.1, 2.2, 3.3}; // Nice syntax also supported by
|
||||
// initializer lists.
|
||||
|
||||
vtkm::Vec<vtkm::Float64, 3> vec3 = vtkm::make_Vec(1.1, 2.2, 3.3); // Old style that still works.
|
||||
|
||||
vtkm::Vec<vtkm::Float64, 3> vec3(1.1, 2.2, 3.3); // Old style that still works but
|
||||
// should be deprecated. Reason listed below.
|
||||
```
|
||||
|
||||
Nested initializer lists work to initialize `Vec` of `Vec`s. If the size is no more than 4,
|
||||
it's always constructed at compile time if possible.
|
||||
|
||||
``` cpp
|
||||
vtkm::Vec<vtkm::Vec<vtkm::Float64, 2>, 3> vec{ {1.1, 2.2}, {3.3, 4.4}, {5.5, 6.6} };
|
||||
//Constructed at compile time
|
||||
```
|
||||
|
||||
One drawback about the `std::initializer_list` implementation is that it constructs larger
|
||||
`Vec`(size>4) of scalars or `vec`s at run time.
|
||||
|
||||
``` cpp
|
||||
vtkm::Vec<vtkm::Float64, 5> vec1{1.1, 2.2, 3.3, 4.4, 5.5}; // Constructed at run time.
|
||||
|
||||
vtkm::Vec<vtkm::Vec<vtkm::Float64, 2>, 5> vec2{{1.1, 1.1},{2.2, 2.2},{3.3, 3.3},
|
||||
{4.4, 4.4}, {5.5, 5.5}}; // Constructed at run time.
|
||||
```
|
||||
|
||||
Parenthesis constructor would report an error if the size is larger than 4 when being used
|
||||
to construct a `Vec` of `Vec`s. If it's being used to construct a `Vec` of scalars then it's
|
||||
fine.
|
||||
|
||||
```cpp
|
||||
vtkm::Vec<vtkm::Vec<vtkm::Float64, 2>, 5> vec2({1.1, 1.1},{2.2, 2.2},{3.3, 3.3},
|
||||
{4.4, 4.4}, {5.5, 5.5}); // ERROR! This type of
|
||||
// constructor not implemented!
|
||||
|
||||
vtkm::Vec<vtkm::Float64, 5> vec1(1.1, 2.2, 3.3, 4.4, 5.5); // Constructed at compile time.
|
||||
```
|
||||
|
||||
If a `vtkm::Vec` is initialized with a list of size one, then that one value is
|
||||
replicated for all components.
|
||||
|
||||
``` cpp
|
||||
vtkm::Vec<vtkm::Float64, 3> vec{1.1}; // vec gets [ 1.1, 1.1, 1.1 ]
|
||||
```
|
||||
|
||||
This "scalar" initialization also works for `Vec` of `Vec`s.
|
||||
|
||||
``` cpp
|
||||
vtkm::Vec<vtkm::Vec<vtkm::Float64, 2>, 3> vec1{ { 1.1, 2.2 } };
|
||||
// vec1 is [[1.1, 2.2], [1.1, 2.2], [1.1, 2.2]]
|
||||
|
||||
vtkm::Vec<vtkm::Vec<vtkm::Float64, 2>, 3> vec2{ { 3.3}, { 4.4 }, { 5.5 } };
|
||||
// vec2 is [[3.3, 3.3], [4.4, 4.4], [5.5, 5.5]]
|
||||
```
|
||||
|
||||
`vtkm::make_Vec` is also updated to support an arbitrary number initial values which are
|
||||
constructed at compile time.
|
||||
|
||||
``` cpp
|
||||
// Creates a vtkm::Vec<vtkm::Float64, 5>
|
||||
auto vec = vtkm::make_Vec(1.1, 2.2, 3.3, 4.4, 5.5);
|
||||
```
|
||||
|
||||
This is super convenient when dealing with variadic function arguments.
|
||||
|
||||
``` cpp
|
||||
template <typename... Ts>
|
||||
void ExampleVariadicFunction(const Ts&... params)
|
||||
{
|
||||
auto vec = vtkm::make_Vec(params...);
|
||||
```
|
||||
|
||||
Of course, this assumes that the type of all the parameters is the same. If not, you
|
||||
could run into compiler trouble.
|
||||
|
||||
`vtkm::make_Vec` does not accept an `std::initializer_list`,
|
||||
|
||||
``` cpp
|
||||
// Creates a vtkm::Vec<vtkm::Float64, 3>
|
||||
auto vec1 = vtkm::make_Vec<3>({1.1, 2.2, 3.3}); // ERROR
|
||||
|
||||
// Creates exactly the same thing but compiles
|
||||
auto vec1 = vtkm::make_Vec<3>(1.1, 2.2, 3.3);
|
||||
```
|
||||
|
||||
A limitation of the initializer list constructor is that the compiler has no way to
|
||||
check the length of the list or force it to a particular length. Thus it is entirely
|
||||
possible to construct a `Vec` with the wrong number of arguments. Or, more to the
|
||||
point, the compiler will let you do it, but there is an assert in the constructor to
|
||||
correct for that. (Of course, asserts are not compiled in release builds.)
|
||||
|
||||
``` cpp
|
||||
// This will compile, but it's results are undefined when it is run.
|
||||
// In debug builds, it will fail an assert.
|
||||
vtkm::Vec<vtkm::Float64, 3> vec{1.1, 1.2};
|
||||
```
|
@ -1,18 +0,0 @@
|
||||
# VTK-m Vec< Vec<T> > can't be constructed from Vec<U>
|
||||
|
||||
|
||||
When you have a Vec<Vec<float,3>> it was possible to incorrectly initialize
|
||||
it with the contents of a Vec<double,3>. An example of this is:
|
||||
```cpp
|
||||
using Vec3d = vtkm::Vec<double, 3>;
|
||||
using Vec3f = vtkm::Vec<float, 3>;
|
||||
using Vec3x3f = vtkm::Vec<Vec3f, 3>;
|
||||
|
||||
Vec3d x(0.0, 1.0, 2.0);
|
||||
Vec3x3f b(x); // becomes [[0,0,0],[1,1,1],[2,2,2]]
|
||||
Vec3x3f c(x, x, x); // becomes [[0,1,2],[0,1,2],[0,1,2]]
|
||||
Vec3x3f d(Vec3f(0.0f,1.0f,2.0f)) //becomes [[0,0,0],[1,1,1],[2,2,2]]
|
||||
```
|
||||
|
||||
So the solution we have chosen is to disallow the construction of objects such
|
||||
as b. This still allows the free implicit cast to go from double to float.
|
@ -1,21 +0,0 @@
|
||||
# VTK-m VirtualObjectHandle can transfer to a device using runtime `DeviceAdapterId` value
|
||||
|
||||
Previously `VirtualObjectHandle` required the caller to know a compile time device adapter tag to
|
||||
transfer data. This was problematic since in parts of VTK-m you would only have the runtime
|
||||
`vtkm::cont::DeviceAdapterId` value of the desired device. To than transfer the
|
||||
`VirtualObjectHandle` you would have to call `FindDeviceAdapterTagAndCall`. All this extra
|
||||
work was unneeded as `VirtualObjectHandle` internally was immediately converting from
|
||||
a compile time type to a runtime value.
|
||||
|
||||
|
||||
Here is an example of how you can now transfer a `VirtualObjectHandle` to a device using
|
||||
a runtime value:
|
||||
```cpp
|
||||
|
||||
template<typename BaseType>
|
||||
const BaseType* moveToDevice(VirtualObjectHandle<BaseType>& handle,
|
||||
vtkm::cont::vtkm::cont::DeviceAdapterId deviceId)
|
||||
{
|
||||
return handle.PrepareForExecution(deviceId);
|
||||
}
|
||||
```
|
@ -1,4 +0,0 @@
|
||||
# Visual Studio generator now requires CMake 3.11
|
||||
|
||||
We require CMake 3.11 for the Visual Studio generators as the
|
||||
$<COMPILE_LANGUAGE:> generator expression is not supported on older versions.
|
@ -1,7 +0,0 @@
|
||||
# Add a warp vector worklet and filter
|
||||
|
||||
This commit adds a worklet that modifies point coordinates by moving points
|
||||
along point normals by the scalar amount. It's a simpified version of the
|
||||
vtkWarpScalar in VTK. Additionally the filter doesn't modify the point coordinates,
|
||||
but creates a new point coordinates that have been warped.
|
||||
Useful for showing flow profiles or mechanical deformation.
|
@ -1,7 +0,0 @@
|
||||
Add a warpScalar worklet and filter
|
||||
|
||||
This commit adds a worklet as well as a filter that modify point coordinates by moving points
|
||||
along point normals by the scalar amount times the scalar factor.
|
||||
It's a simpified version of the vtkWarpScalar class in VTK. Additionally the filter doesn't
|
||||
modify the point coordinates, but creates a new point coordinates that have been warped.
|
||||
|
@ -1,5 +0,0 @@
|
||||
# Add a `WaveletGenerator` worklet (e.g. vtkRTAnalyticSource)
|
||||
|
||||
Add a VTK-m implementation of VTK's `vtkRTAnalyticSource`, or "Wavelet" source
|
||||
as it is known in ParaView. This is a customizable dataset with properties
|
||||
that make it useful for testing and benchmarking various algorithms.
|
@ -25,6 +25,7 @@ set(CMAKE_PREFIX_PATH ${VTKm_BINARY_DIR}/${VTKm_INSTALL_CONFIG_DIR})
|
||||
|
||||
add_subdirectory(clipping)
|
||||
add_subdirectory(contour_tree)
|
||||
add_subdirectory(contour_tree_augmented)
|
||||
add_subdirectory(cosmotools)
|
||||
add_subdirectory(demo)
|
||||
add_subdirectory(dynamic_dispatcher)
|
||||
|
@ -19,7 +19,6 @@
|
||||
//============================================================================
|
||||
#include <vtkm/cont/ArrayHandleCast.h>
|
||||
#include <vtkm/cont/DataSet.h>
|
||||
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
|
||||
#include <vtkm/cont/Timer.h>
|
||||
#include <vtkm/io/reader/VTKDataSetReader.h>
|
||||
#include <vtkm/io/writer/VTKDataSetWriter.h>
|
||||
@ -37,7 +36,6 @@ using FloatVec3 = vtkm::Vec<vtkm::Float32, 3>;
|
||||
namespace
|
||||
{
|
||||
|
||||
template <typename DeviceTag>
|
||||
struct FieldMapper
|
||||
{
|
||||
vtkm::cont::DynamicArrayHandle& Output;
|
||||
@ -58,11 +56,11 @@ struct FieldMapper
|
||||
{
|
||||
if (this->IsCellField)
|
||||
{
|
||||
this->Output = this->Worklet.ProcessCellField(input, DeviceTag());
|
||||
this->Output = this->Worklet.ProcessCellField(input);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->Output = this->Worklet.ProcessPointField(input, DeviceTag());
|
||||
this->Output = this->Worklet.ProcessPointField(input);
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -79,10 +77,6 @@ int main(int argc, char* argv[])
|
||||
return 1;
|
||||
}
|
||||
|
||||
using DeviceAdapter = VTKM_DEFAULT_DEVICE_ADAPTER_TAG;
|
||||
std::cout << "Device Adapter Name: " << vtkm::cont::DeviceAdapterTraits<DeviceAdapter>::GetName()
|
||||
<< std::endl;
|
||||
|
||||
vtkm::io::reader::VTKDataSetReader reader(argv[1]);
|
||||
vtkm::cont::DataSet input = reader.ReadDataSet();
|
||||
|
||||
@ -91,15 +85,14 @@ int main(int argc, char* argv[])
|
||||
vtkm::Float32 clipValue = std::stof(argv[argc - 2]);
|
||||
vtkm::worklet::Clip clip;
|
||||
|
||||
vtkm::cont::Timer<DeviceAdapter> total;
|
||||
vtkm::cont::Timer<DeviceAdapter> timer;
|
||||
vtkm::cont::Timer<> total;
|
||||
vtkm::cont::Timer<> timer;
|
||||
bool invertClip = false;
|
||||
vtkm::cont::CellSetExplicit<> outputCellSet =
|
||||
clip.Run(input.GetCellSet(0),
|
||||
scalarField.GetData().ResetTypeList(vtkm::TypeListTagScalarAll()),
|
||||
clipValue,
|
||||
invertClip,
|
||||
DeviceAdapter());
|
||||
invertClip);
|
||||
vtkm::Float64 clipTime = timer.GetElapsedTime();
|
||||
|
||||
vtkm::cont::DataSet output;
|
||||
@ -108,7 +101,7 @@ int main(int argc, char* argv[])
|
||||
|
||||
auto inCoords = input.GetCoordinateSystem(0).GetData();
|
||||
timer.Reset();
|
||||
auto outCoords = clip.ProcessCellField(inCoords, DeviceAdapter());
|
||||
auto outCoords = clip.ProcessCellField(inCoords);
|
||||
vtkm::Float64 processCoordinatesTime = timer.GetElapsedTime();
|
||||
output.AddCoordinateSystem(vtkm::cont::CoordinateSystem("coordinates", outCoords));
|
||||
|
||||
@ -132,7 +125,7 @@ int main(int argc, char* argv[])
|
||||
}
|
||||
|
||||
vtkm::cont::DynamicArrayHandle outField;
|
||||
FieldMapper<DeviceAdapter> fieldMapper(outField, clip, isCellField);
|
||||
FieldMapper fieldMapper(outField, clip, isCellField);
|
||||
inField.GetData().CastAndCall(fieldMapper);
|
||||
output.AddField(vtkm::cont::Field(inField.GetName(), inField.GetAssociation(), outField));
|
||||
}
|
||||
|
125
examples/contour_tree_augmented/CMakeLists.txt
Normal file
125
examples/contour_tree_augmented/CMakeLists.txt
Normal file
@ -0,0 +1,125 @@
|
||||
##=============================================================================
|
||||
##
|
||||
## 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.
|
||||
##
|
||||
## Copyright 2018 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
## Copyright 2018 UT-Battelle, LLC.
|
||||
## Copyright 2018 Los Alamos National Security.
|
||||
##
|
||||
## Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
## the U.S. Government retains certain rights in this software.
|
||||
## Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
|
||||
## Laboratory (LANL), the U.S. Government retains certain rights in
|
||||
## this software.
|
||||
##
|
||||
##=============================================================================
|
||||
##============================================================================
|
||||
## Copyright (c) 2018, The Regents of the University of California, through
|
||||
## Lawrence Berkeley National Laboratory (subject to receipt of any required approvals
|
||||
## from the U.S. Dept. of Energy). All rights reserved.
|
||||
##
|
||||
## Redistribution and use in source and binary forms, with or without modification,
|
||||
## are permitted provided that the following conditions are met:
|
||||
##
|
||||
## (1) Redistributions of source code must retain the above copyright notice, this
|
||||
## list of conditions and the following disclaimer.
|
||||
##
|
||||
## (2) Redistributions in binary form must reproduce the above copyright notice,
|
||||
## this list of conditions and the following disclaimer in the documentation
|
||||
## and/or other materials provided with the distribution.
|
||||
##
|
||||
## (3) Neither the name of the University of California, Lawrence Berkeley National
|
||||
## Laboratory, U.S. Dept. of Energy nor the names of its contributors may be
|
||||
## used to endorse or promote products derived from this software without
|
||||
## specific prior written permission.
|
||||
##
|
||||
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
## ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
## WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
## IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
## INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
## BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
## LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
## OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
## OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
##
|
||||
##=============================================================================
|
||||
##
|
||||
## This code is an extension of the algorithm presented in the paper:
|
||||
## Parallel Peak Pruning for Scalable SMP Contour Tree Computation.
|
||||
## Hamish Carr, Gunther Weber, Christopher Sewell, and James Ahrens.
|
||||
## Proceedings of the IEEE Symposium on Large Data Analysis and Visualization
|
||||
## (LDAV), October 2016, Baltimore, Maryland.
|
||||
##
|
||||
## The PPP2 algorithm and software were jointly developed by
|
||||
## Hamish Carr (University of Leeds), Gunther H. Weber (LBNL), and
|
||||
## Oliver Ruebel (LBNL)
|
||||
##==============================================================================
|
||||
|
||||
#Find the VTK-m package
|
||||
find_package(VTKm REQUIRED QUIET)
|
||||
|
||||
# MAKE DEBUG BUILD
|
||||
# set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g3 -g -fsanitize=address")
|
||||
|
||||
# MAKE OPTIMIZED BUILD
|
||||
# set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O3")
|
||||
|
||||
####################################
|
||||
# Serial builds
|
||||
####################################
|
||||
# Serial 2D / 3D / MC
|
||||
add_executable(ContourTree_PPP2_SERIAL ContourTreeApp.cxx)
|
||||
target_link_libraries(ContourTree_PPP2_SERIAL vtkm_cont)
|
||||
target_compile_definitions(ContourTree_PPP2_SERIAL PRIVATE
|
||||
"VTKM_DEVICE_ADAPTER=VTKM_DEVICE_ADAPTER_SERIAL")
|
||||
|
||||
|
||||
####################################
|
||||
# Serial debug builds
|
||||
####################################
|
||||
|
||||
# Debug Serial 2D / 3D / MC
|
||||
add_executable(ContourTree_PPP2_SERIAL_DEBUG ContourTreeApp.cxx)
|
||||
target_link_libraries(ContourTree_PPP2_SERIAL_DEBUG vtkm_cont)
|
||||
target_compile_definitions(ContourTree_PPP2_SERIAL_DEBUG PRIVATE
|
||||
"VTKM_DEVICE_ADAPTER=VTKM_DEVICE_ADAPTER_SERIAL" "DEBUG_PRINT")
|
||||
|
||||
|
||||
if(TARGET vtkm::tbb)
|
||||
# TBB 2D/3D/MC
|
||||
add_executable(ContourTree_PPP2_TBB ContourTreeApp.cxx)
|
||||
target_link_libraries(ContourTree_PPP2_TBB vtkm_cont)
|
||||
target_compile_definitions(ContourTree_PPP2_TBB PRIVATE
|
||||
"VTKM_DEVICE_ADAPTER=VTKM_DEVICE_ADAPTER_TBB" "ENABLE_SET_NUM_THREADS")
|
||||
|
||||
# TBB 2D/3D/MC DEBUG
|
||||
add_executable(ContourTree_PPP2_TBB_DEBUG ContourTreeApp.cxx)
|
||||
target_link_libraries(ContourTree_PPP2_TBB_DEBUG vtkm_cont)
|
||||
target_compile_definitions(ContourTree_PPP2_TBB_DEBUG PRIVATE
|
||||
"VTKM_DEVICE_ADAPTER=VTKM_DEVICE_ADAPTER_TBB" "ENABLE_SET_NUM_THREADS" "DEBUG_PRINT")
|
||||
|
||||
endif()
|
||||
|
||||
if(TARGET vtkm::cuda)
|
||||
# CUDA 2D/3D/MC
|
||||
vtkm_compile_as_cuda(cudaSource ContourTreeApp.cxx)
|
||||
add_executable(ContourTree_PPP2_CUDA ${cudaSource})
|
||||
target_link_libraries(ContourTree_PPP2_CUDA vtkm_cont)
|
||||
target_compile_definitions(ContourTree_PPP2_CUDA PRIVATE
|
||||
"VTKM_DEVICE_ADAPTER=VTKM_DEVICE_ADAPTER_CUDA")
|
||||
|
||||
# CUDA 2D/3D/MC
|
||||
# vtkm_compile_as_cuda(cudaSource ContourTreeApp.cxx)
|
||||
add_executable(ContourTree_PPP2_CUDA_DEBUG ${cudaSource})
|
||||
target_link_libraries(ContourTree_PPP2_CUDA_DEBUG vtkm_cont)
|
||||
target_compile_definitions(ContourTree_PPP2_CUDA_DEBUG PRIVATE
|
||||
"VTKM_DEVICE_ADAPTER=VTKM_DEVICE_ADAPTER_CUDA" "DEBUG_PRINT")
|
||||
endif()
|
435
examples/contour_tree_augmented/ContourTreeApp.cxx
Normal file
435
examples/contour_tree_augmented/ContourTreeApp.cxx
Normal file
@ -0,0 +1,435 @@
|
||||
//============================================================================
|
||||
// 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.
|
||||
//
|
||||
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2014 UT-Battelle, LLC.
|
||||
// Copyright 2014 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// the U.S. Government retains certain rights in this software.
|
||||
//
|
||||
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
|
||||
// Laboratory (LANL), the U.S. Government retains certain rights in
|
||||
// this software.
|
||||
//============================================================================
|
||||
// Copyright (c) 2018, The Regents of the University of California, through
|
||||
// Lawrence Berkeley National Laboratory (subject to receipt of any required approvals
|
||||
// from the U.S. Dept. of Energy). All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// (1) Redistributions of source code must retain the above copyright notice, this
|
||||
// list of conditions and the following disclaimer.
|
||||
//
|
||||
// (2) Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// (3) Neither the name of the University of California, Lawrence Berkeley National
|
||||
// Laboratory, U.S. Dept. of Energy nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without
|
||||
// specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//=============================================================================
|
||||
//
|
||||
// This code is an extension of the algorithm presented in the paper:
|
||||
// Parallel Peak Pruning for Scalable SMP Contour Tree Computation.
|
||||
// Hamish Carr, Gunther Weber, Christopher Sewell, and James Ahrens.
|
||||
// Proceedings of the IEEE Symposium on Large Data Analysis and Visualization
|
||||
// (LDAV), October 2016, Baltimore, Maryland.
|
||||
//
|
||||
// The PPP2 algorithm and software were jointly developed by
|
||||
// Hamish Carr (University of Leeds), Gunther H. Weber (LBNL), and
|
||||
// Oliver Ruebel (LBNL)
|
||||
//==============================================================================
|
||||
|
||||
#define DEBUG_TIMING
|
||||
|
||||
#ifdef ENABLE_SET_NUM_THREADS
|
||||
#include "tbb/task_scheduler_init.h"
|
||||
#endif
|
||||
|
||||
#include <vtkm/Types.h>
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
#include <vtkm/cont/DataSet.h>
|
||||
#include <vtkm/cont/DataSetBuilderUniform.h>
|
||||
#include <vtkm/cont/DataSetFieldAdd.h>
|
||||
#include <vtkm/cont/Timer.h>
|
||||
#include <vtkm/filter/ContourTreeUniformAugmented.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/PrintVectors.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/ProcessContourTree.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/Types.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace cppp2_ns = vtkm::worklet::contourtree_augmented;
|
||||
|
||||
// Simple helper class for parsing the command line options
|
||||
class ParseCL
|
||||
{
|
||||
public:
|
||||
ParseCL() {}
|
||||
|
||||
void parse(std::vector<std::string>::size_type argc, char** argv)
|
||||
{
|
||||
mCLOptions.resize(std::vector<std::string>::size_type(argc));
|
||||
for (std::vector<std::string>::size_type i = 1; i < argc; ++i)
|
||||
{
|
||||
this->mCLOptions[i] = std::string(argv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
vtkm::Id findOption(const std::string& option) const
|
||||
{
|
||||
auto it =
|
||||
std::find_if(this->mCLOptions.begin(),
|
||||
this->mCLOptions.end(),
|
||||
[option](const std::string& val) -> bool { return val.find(option) == 0; });
|
||||
if (it == this->mCLOptions.end())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return static_cast<vtkm::Id>(it - this->mCLOptions.begin());
|
||||
}
|
||||
}
|
||||
|
||||
bool hasOption(const std::string& option) const { return this->findOption(option) >= 0; }
|
||||
|
||||
std::string getOption(const std::string& option) const
|
||||
{
|
||||
vtkm::Id index = this->findOption(option);
|
||||
if (index >= 0)
|
||||
{
|
||||
std::string val = this->mCLOptions[std::vector<std::string>::size_type(index)];
|
||||
auto valPos = val.find("=");
|
||||
if (valPos)
|
||||
{
|
||||
return val.substr(valPos + 1);
|
||||
}
|
||||
}
|
||||
return std::string("");
|
||||
}
|
||||
|
||||
const std::vector<std::string>& getOptions() const { return this->mCLOptions; }
|
||||
|
||||
private:
|
||||
std::vector<std::string> mCLOptions;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Compute and render an isosurface for a uniform grid example
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
// TODO: Change timing to use logging in vtkm/cont/Logging.h
|
||||
vtkm::cont::Timer<> totalTime;
|
||||
vtkm::Float64 prevTime = 0;
|
||||
vtkm::Float64 currTime = 0;
|
||||
std::cout << "ContourTreePPP2Mesh <options> <fileName>" << std::endl;
|
||||
|
||||
////////////////////////////////////////////
|
||||
// Parse the command line options
|
||||
////////////////////////////////////////////
|
||||
ParseCL parser;
|
||||
parser.parse(std::vector<std::string>::size_type(argc), argv);
|
||||
std::string filename = parser.getOptions().back();
|
||||
bool computeRegularStructure = true;
|
||||
bool useMarchingCubes = false;
|
||||
bool computeBranchDecomposition = true;
|
||||
bool printContourTree = false;
|
||||
if (parser.hasOption("--augmentTree"))
|
||||
computeRegularStructure = std::stoi(parser.getOption("--augmentTree"));
|
||||
if (parser.hasOption("--mc"))
|
||||
useMarchingCubes = true;
|
||||
if (parser.hasOption("--printCT"))
|
||||
printContourTree = true;
|
||||
if (parser.hasOption("--branchDecomp"))
|
||||
computeBranchDecomposition = std::stoi(parser.getOption("--branchDecomp"));
|
||||
#ifdef ENABLE_SET_NUM_THREADS
|
||||
int numThreads = tbb::task_scheduler_init::default_num_threads();
|
||||
if (parser.hasOption("--numThreads"))
|
||||
numThreads = std::stoi(parser.getOption("--numThreads"));
|
||||
tbb::task_scheduler_init schedulerInit(numThreads);
|
||||
#endif
|
||||
|
||||
if (argc < 2 || parser.hasOption("--help") || parser.hasOption("-h"))
|
||||
{
|
||||
std::cout << "Parameter is <fileName>" << std::endl;
|
||||
std::cout << "File is expected to be ASCII with either: " << std::endl;
|
||||
std::cout << " - xdim ydim integers for 2D or" << std::endl;
|
||||
std::cout << " - xdim ydim zdim integers for 3D" << std::endl;
|
||||
std::cout << "followed by vector data last dimension varying fastest" << std::endl;
|
||||
|
||||
std::cout << std::endl;
|
||||
std::cout << "Options: (Bool options are give via int, i.e. =0 for False and =1 for True)"
|
||||
<< std::endl;
|
||||
std::cout << "--mc Use marching cubes interpolation for contour tree calculation. "
|
||||
"(Default=False)"
|
||||
<< std::endl;
|
||||
std::cout << "--augmentTree Compute the augmented contour tree. (Default=True)"
|
||||
<< std::endl;
|
||||
std::cout << "--branchDecomp Compute the volume branch decomposition for the contour tree. "
|
||||
"Requires --augmentTree (Default=True)"
|
||||
<< std::endl;
|
||||
std::cout << "--printCT Print the contour tree. (Default=False)" << std::endl;
|
||||
#ifdef ENABLE_SET_NUM_THREADS
|
||||
std::cout << "--numThreads Specify the number of threads to use. Available only with TBB."
|
||||
<< std::endl;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::cout << "Settings:" << std::endl;
|
||||
std::cout << " filename=" << filename << std::endl;
|
||||
std::cout << " mc=" << useMarchingCubes << std::endl;
|
||||
std::cout << " augmentTree=" << computeRegularStructure << std::endl;
|
||||
std::cout << " branchDecomp=" << computeBranchDecomposition << std::endl;
|
||||
#ifdef ENABLE_SET_NUM_THREADS
|
||||
std::cout << " numThreads=" << numThreads << std::endl;
|
||||
#endif
|
||||
std::cout << std::endl;
|
||||
|
||||
|
||||
currTime = totalTime.GetElapsedTime();
|
||||
vtkm::Float64 startUpTime = currTime - prevTime;
|
||||
prevTime = currTime;
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// Read the input data
|
||||
///////////////////////////////////////////////
|
||||
std::ifstream inFile(filename);
|
||||
if (inFile.bad())
|
||||
return 0;
|
||||
|
||||
// Read the dimensions of the mesh, i.e,. number of elementes in x, y, and z
|
||||
std::vector<vtkm::Id> dims;
|
||||
std::string line;
|
||||
getline(inFile, line);
|
||||
std::istringstream linestream(line);
|
||||
vtkm::Id dimVertices;
|
||||
while (linestream >> dimVertices)
|
||||
{
|
||||
dims.push_back(dimVertices);
|
||||
}
|
||||
|
||||
// Compute the number of vertices, i.e., xdim * ydim * zdim
|
||||
auto nDims = dims.size();
|
||||
std::vector<vtkm::Float32>::size_type nVertices = std::vector<vtkm::Float32>::size_type(
|
||||
std::accumulate(dims.begin(), dims.end(), vtkm::Id(1), std::multiplies<vtkm::Id>()));
|
||||
|
||||
// Print the mesh metadata
|
||||
std::cout << "Number of dimensions: " << nDims << std::endl;
|
||||
std::cout << "Number of mesh vertices: " << nVertices << std::endl;
|
||||
|
||||
// Check the the number of dimensiosn is either 2D or 3D
|
||||
if (nDims < 2 || nDims > 3)
|
||||
{
|
||||
std::cout << "The input mesh is " << nDims << "D. Input data must be either 2D or 3D."
|
||||
<< std::endl;
|
||||
return 0;
|
||||
}
|
||||
if (useMarchingCubes && nDims != 3)
|
||||
{
|
||||
std::cout << "The input mesh is " << nDims
|
||||
<< "D. Contour tree using marching cubes only supported for 3D data." << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// read data
|
||||
std::vector<vtkm::Float32> values(nVertices);
|
||||
for (std::vector<vtkm::Float32>::size_type vertex = 0; vertex < nVertices; vertex++)
|
||||
{
|
||||
inFile >> values[vertex];
|
||||
}
|
||||
|
||||
// finish reading the data
|
||||
inFile.close();
|
||||
|
||||
currTime = totalTime.GetElapsedTime();
|
||||
vtkm::Float64 dataReadTime = currTime - prevTime;
|
||||
prevTime = currTime;
|
||||
// build the input dataset
|
||||
vtkm::cont::DataSetBuilderUniform dsb;
|
||||
vtkm::cont::DataSet inDataSet;
|
||||
// 2D data
|
||||
if (nDims == 2)
|
||||
{
|
||||
vtkm::Id2 vdims;
|
||||
vdims[0] = dims[0];
|
||||
vdims[1] = dims[1];
|
||||
inDataSet = dsb.Create(vdims);
|
||||
}
|
||||
// 3D data
|
||||
else
|
||||
{
|
||||
vtkm::Id3 vdims;
|
||||
vdims[0] = dims[0];
|
||||
vdims[1] = dims[1];
|
||||
vdims[2] = dims[2];
|
||||
inDataSet = dsb.Create(vdims);
|
||||
}
|
||||
vtkm::cont::DataSetFieldAdd dsf;
|
||||
dsf.AddPointField(inDataSet, "values", values);
|
||||
|
||||
currTime = totalTime.GetElapsedTime();
|
||||
vtkm::Float64 buildDatasetTime = currTime - prevTime;
|
||||
prevTime = currTime;
|
||||
|
||||
// Output data set is pairs of saddle and peak vertex IDs
|
||||
vtkm::cont::DataSet result;
|
||||
|
||||
// Convert the mesh of values into contour tree, pairs of vertex ids
|
||||
vtkm::filter::ContourTreePPP2 filter(useMarchingCubes, computeRegularStructure);
|
||||
filter.SetActiveField("values");
|
||||
result = filter.Execute(inDataSet); //, std::string("values"));
|
||||
|
||||
currTime = totalTime.GetElapsedTime();
|
||||
vtkm::Float64 computeContourTreeTime = currTime - prevTime;
|
||||
prevTime = currTime;
|
||||
|
||||
#ifdef DEBUG_TIMING
|
||||
std::cout << "-------------------------------------------------------------" << std::endl;
|
||||
std::cout << "-------------------Contour Tree Timings----------------------" << std::endl;
|
||||
// Get the timings from the contour tree computation
|
||||
const std::vector<std::pair<std::string, vtkm::Float64>>& contourTreeTimings =
|
||||
filter.GetTimings();
|
||||
for (std::vector<std::pair<std::string, vtkm::Float64>>::size_type i = 0;
|
||||
i < contourTreeTimings.size();
|
||||
i++)
|
||||
std::cout << std::setw(42) << std::left << contourTreeTimings[i].first << ": "
|
||||
<< contourTreeTimings[i].second << " seconds" << std::endl;
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////
|
||||
// Compute the branch decomposition
|
||||
////////////////////////////////////////////
|
||||
if (computeBranchDecomposition)
|
||||
{
|
||||
// TODO: Change timing to use logging in vtkm/cont/Logging.h
|
||||
vtkm::cont::Timer<> branchDecompTimer;
|
||||
// compute the volume for each hyperarc and superarc
|
||||
cppp2_ns::IdArrayType superarcIntrinsicWeight;
|
||||
cppp2_ns::IdArrayType superarcDependentWeight;
|
||||
cppp2_ns::IdArrayType supernodeTransferWeight;
|
||||
cppp2_ns::IdArrayType hyperarcDependentWeight;
|
||||
|
||||
cppp2_ns::ProcessContourTree::ComputeVolumeWeights(filter.GetContourTree(),
|
||||
filter.GetNumIterations(),
|
||||
superarcIntrinsicWeight, // (output)
|
||||
superarcDependentWeight, // (output)
|
||||
supernodeTransferWeight, // (output)
|
||||
hyperarcDependentWeight); // (output)
|
||||
std::cout << std::setw(42) << std::left << "Compute Volume Weights"
|
||||
<< ": " << branchDecompTimer.GetElapsedTime() << " seconds" << std::endl;
|
||||
branchDecompTimer.Reset();
|
||||
|
||||
// compute the branch decomposition by volume
|
||||
cppp2_ns::IdArrayType whichBranch;
|
||||
cppp2_ns::IdArrayType branchMinimum;
|
||||
cppp2_ns::IdArrayType branchMaximum;
|
||||
cppp2_ns::IdArrayType branchSaddle;
|
||||
cppp2_ns::IdArrayType branchParent;
|
||||
|
||||
cppp2_ns::ProcessContourTree::ComputeVolumeBranchDecomposition(filter.GetContourTree(),
|
||||
superarcDependentWeight,
|
||||
superarcIntrinsicWeight,
|
||||
whichBranch, // (output)
|
||||
branchMinimum, // (output)
|
||||
branchMaximum, // (output)
|
||||
branchSaddle, // (output)
|
||||
branchParent); // (output)
|
||||
std::cout << std::setw(42) << std::left << "Compute Volume Branch Decomposition"
|
||||
<< ": " << branchDecompTimer.GetElapsedTime() << " seconds" << std::endl;
|
||||
}
|
||||
currTime = totalTime.GetElapsedTime();
|
||||
vtkm::Float64 computeBranchDecompTime = currTime - prevTime;
|
||||
prevTime = currTime;
|
||||
|
||||
//vtkm::cont::Field resultField = result.GetField();
|
||||
//vtkm::cont::ArrayHandle<vtkm::Pair<vtkm::Id, vtkm::Id> > saddlePeak;
|
||||
//resultField.GetData().CopyTo(saddlePeak);
|
||||
|
||||
// dump out contour tree for comparison
|
||||
if (printContourTree)
|
||||
{
|
||||
std::cout << "Contour Tree" << std::endl;
|
||||
std::cout << "============" << std::endl;
|
||||
cppp2_ns::EdgePairArray saddlePeak;
|
||||
cppp2_ns::ProcessContourTree::CollectSortedSuperarcs(
|
||||
filter.GetContourTree(), filter.GetSortOrder(), saddlePeak);
|
||||
cppp2_ns::printEdgePairArray(saddlePeak);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_TIMING
|
||||
std::cout << "-------------------------------------------------------------" << std::endl;
|
||||
std::cout << "--------------------------Totals-----------------------------" << std::endl;
|
||||
std::cout << std::setw(42) << std::left << "Start-up"
|
||||
<< ": " << startUpTime << " seconds" << std::endl;
|
||||
std::cout << std::setw(42) << std::left << "Data Read"
|
||||
<< ": " << dataReadTime << " seconds" << std::endl;
|
||||
std::cout << std::setw(42) << std::left << "Build VTKM Dataset"
|
||||
<< ": " << buildDatasetTime << " seconds" << std::endl;
|
||||
std::cout << std::setw(42) << std::left << "Compute Contour Tree"
|
||||
<< ": " << computeContourTreeTime << " seconds" << std::endl;
|
||||
if (computeBranchDecomposition)
|
||||
{
|
||||
std::cout << std::setw(42) << std::left << "Compute Branch Decomposition"
|
||||
<< ": " << computeBranchDecompTime << " seconds" << std::endl;
|
||||
}
|
||||
currTime = totalTime.GetElapsedTime();
|
||||
//vtkm::Float64 miscTime = currTime - startUpTime - dataReadTime - buildDatasetTime - computeContourTreeTime;
|
||||
//if (computeBranchDecomposition) miscTime -= computeBranchDecompTime;
|
||||
//std::cout<<std::setw(42)<<std::left<<"Misc. Times"<<": "<<miscTime<<" seconds"<<std::endl;
|
||||
std::cout << std::setw(42) << std::left << "Total Time"
|
||||
<< ": " << currTime << " seconds" << std::endl;
|
||||
|
||||
std::cout << "-------------------------------------------------------------" << std::endl;
|
||||
std::cout << "----------------Contour Tree Array Sizes---------------------" << std::endl;
|
||||
const vtkm::worklet::contourtree_augmented::ContourTree& ct = filter.GetContourTree();
|
||||
std::cout << std::setw(42) << std::left << "#Nodes"
|
||||
<< ": " << ct.nodes.GetNumberOfValues() << std::endl;
|
||||
std::cout << std::setw(42) << std::left << "#Arcs"
|
||||
<< ": " << ct.arcs.GetNumberOfValues() << std::endl;
|
||||
std::cout << std::setw(42) << std::left << "#Superparents"
|
||||
<< ": " << ct.superparents.GetNumberOfValues() << std::endl;
|
||||
std::cout << std::setw(42) << std::left << "#Superarcs"
|
||||
<< ": " << ct.superarcs.GetNumberOfValues() << std::endl;
|
||||
std::cout << std::setw(42) << std::left << "#Supernodes"
|
||||
<< ": " << ct.supernodes.GetNumberOfValues() << std::endl;
|
||||
std::cout << std::setw(42) << std::left << "#Hyperparents"
|
||||
<< ": " << ct.hyperparents.GetNumberOfValues() << std::endl;
|
||||
std::cout << std::setw(42) << std::left << "#WhenTransferred"
|
||||
<< ": " << ct.whenTransferred.GetNumberOfValues() << std::endl;
|
||||
std::cout << std::setw(42) << std::left << "#Hypernodes"
|
||||
<< ": " << ct.hypernodes.GetNumberOfValues() << std::endl;
|
||||
std::cout << std::setw(42) << std::left << "#Hyperarcs"
|
||||
<< ": " << ct.hyperarcs.GetNumberOfValues() << std::endl;
|
||||
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
@ -25,24 +25,16 @@ project(CosmoTools CXX)
|
||||
#Find the VTK-m package
|
||||
find_package(VTKm REQUIRED QUIET)
|
||||
|
||||
add_executable(CosmoCenterFinder_SERIAL CosmoCenterFinder.cxx)
|
||||
add_executable(CosmoHaloFinder_SERIAL CosmoHaloFinder.cxx)
|
||||
|
||||
target_link_libraries(CosmoCenterFinder_SERIAL PRIVATE vtkm_cont)
|
||||
target_link_libraries(CosmoHaloFinder_SERIAL PRIVATE vtkm_cont)
|
||||
|
||||
if(TARGET vtkm::cuda)
|
||||
add_executable(CosmoCenterFinder_CUDA CosmoCenterFinder.cu)
|
||||
add_executable(CosmoHaloFinder_CUDA CosmoHaloFinder.cu)
|
||||
vtkm_compile_as_cuda(cu_srcs CosmoCenterFinder.cxx)
|
||||
add_executable(CosmoCenterFinder ${cu_srcs})
|
||||
|
||||
target_link_libraries(CosmoCenterFinder_CUDA PRIVATE vtkm_cont)
|
||||
target_link_libraries(CosmoHaloFinder_CUDA PRIVATE vtkm_cont)
|
||||
vtkm_compile_as_cuda(cu_srcs CosmoHaloFinder.cxx)
|
||||
add_executable(CosmoHaloFinder ${cu_srcs})
|
||||
else()
|
||||
add_executable(CosmoCenterFinder CosmoCenterFinder.cxx)
|
||||
add_executable(CosmoHaloFinder CosmoHaloFinder.cxx)
|
||||
endif()
|
||||
|
||||
if(TARGET vtkm::tbb)
|
||||
add_executable(CosmoCenterFinder_TBB CosmoCenterFinderTBB.cxx)
|
||||
add_executable(CosmoHaloFinder_TBB CosmoHaloFinderTBB.cxx)
|
||||
|
||||
target_link_libraries(CosmoCenterFinder_TBB PRIVATE vtkm_cont)
|
||||
target_link_libraries(CosmoHaloFinder_TBB PRIVATE vtkm_cont)
|
||||
endif()
|
||||
target_link_libraries(CosmoCenterFinder PRIVATE vtkm_cont)
|
||||
target_link_libraries(CosmoHaloFinder PRIVATE vtkm_cont)
|
||||
|
@ -19,8 +19,7 @@
|
||||
//============================================================================
|
||||
#include <vtkm/cont/ArrayHandleCast.h>
|
||||
#include <vtkm/cont/DataSet.h>
|
||||
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
|
||||
#include <vtkm/cont/Timer.h>
|
||||
#include <vtkm/cont/Logging.h>
|
||||
#include <vtkm/io/reader/VTKDataSetReader.h>
|
||||
#include <vtkm/io/writer/VTKDataSetWriter.h>
|
||||
|
||||
@ -32,7 +31,7 @@
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
using DeviceAdapter = VTKM_DEFAULT_DEVICE_ADAPTER_TAG;
|
||||
static const vtkm::cont::LogLevel CosmoLogLevel = vtkm::cont::LogLevel(1);
|
||||
|
||||
void TestCosmoCenterFinder(const char* fileName)
|
||||
{
|
||||
@ -72,29 +71,27 @@ void TestCosmoCenterFinder(const char* fileName)
|
||||
vtkm::Pair<vtkm::Id, vtkm::Float32> nxnResult;
|
||||
vtkm::Pair<vtkm::Id, vtkm::Float32> mxnResult;
|
||||
|
||||
vtkm::cont::Timer<DeviceAdapter> total;
|
||||
vtkm::cont::Timer<DeviceAdapter> timer;
|
||||
|
||||
// Create the worklet and run it
|
||||
vtkm::Float32 particleMass = 1.08413e+09f;
|
||||
|
||||
const vtkm::Float32 particleMass = 1.08413e+09f;
|
||||
vtkm::worklet::CosmoTools cosmoTools;
|
||||
cosmoTools.RunMBPCenterFinderNxN(
|
||||
xLocArray, yLocArray, zLocArray, nParticles, particleMass, nxnResult, DeviceAdapter());
|
||||
vtkm::Float64 nxnTime = timer.GetElapsedTime();
|
||||
|
||||
std::cout << "**** NxN MPB = " << nxnResult.first << " potential = " << nxnResult.second
|
||||
<< std::endl;
|
||||
std::cout << "**** Time for NxN: " << nxnTime << std::endl;
|
||||
{
|
||||
VTKM_LOG_SCOPE(CosmoLogLevel, "Executing NxN");
|
||||
|
||||
timer.Reset();
|
||||
cosmoTools.RunMBPCenterFinderMxN(
|
||||
xLocArray, yLocArray, zLocArray, nParticles, particleMass, mxnResult, DeviceAdapter());
|
||||
vtkm::Float64 estTime = timer.GetElapsedTime();
|
||||
cosmoTools.RunMBPCenterFinderNxN(
|
||||
xLocArray, yLocArray, zLocArray, nParticles, particleMass, nxnResult);
|
||||
|
||||
std::cout << "**** MxN MPB = " << mxnResult.first << " potential = " << mxnResult.second
|
||||
<< std::endl;
|
||||
std::cout << "**** Time for MxN: " << estTime << std::endl;
|
||||
VTKM_LOG_S(CosmoLogLevel,
|
||||
"NxN MPB = " << nxnResult.first << " potential = " << nxnResult.second);
|
||||
}
|
||||
|
||||
{
|
||||
VTKM_LOG_SCOPE(CosmoLogLevel, "Executing MxN");
|
||||
cosmoTools.RunMBPCenterFinderMxN(
|
||||
xLocArray, yLocArray, zLocArray, nParticles, particleMass, mxnResult);
|
||||
|
||||
VTKM_LOG_S(CosmoLogLevel,
|
||||
"MxN MPB = " << mxnResult.first << " potential = " << mxnResult.second);
|
||||
}
|
||||
|
||||
if (nxnResult.first == mxnResult.first)
|
||||
std::cout << "FOUND CORRECT PARTICLE " << mxnResult.first << " with potential "
|
||||
@ -123,12 +120,20 @@ void TestCosmoCenterFinder(const char* fileName)
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
vtkm::cont::SetLogLevelName(CosmoLogLevel, "Cosmo");
|
||||
vtkm::cont::SetStderrLogLevel(CosmoLogLevel);
|
||||
vtkm::cont::InitLogging(argc, argv);
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
std::cout << "Usage: " << std::endl << "$ " << argv[0] << " <input_file>" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifndef VTKM_ENABLE_LOGGING
|
||||
std::cout << "Warning: turn on VTKm_ENABLE_LOGGING CMake option to turn on timing." << std::endl;
|
||||
#endif
|
||||
|
||||
TestCosmoCenterFinder(argv[1]);
|
||||
|
||||
return 0;
|
||||
|
@ -1,23 +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.
|
||||
//
|
||||
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2014 UT-Battelle, LLC.
|
||||
// Copyright 2014 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// the U.S. Government retains certain rights in this software.
|
||||
//
|
||||
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
|
||||
// Laboratory (LANL), the U.S. Government retains certain rights in
|
||||
// this software.
|
||||
//============================================================================
|
||||
|
||||
#define VTKM_DEVICE_ADAPTER VTKM_DEVICE_ADAPTER_CUDA
|
||||
|
||||
#include "CosmoHaloFinder.cxx"
|
@ -19,8 +19,7 @@
|
||||
//============================================================================
|
||||
#include <vtkm/cont/ArrayHandleCast.h>
|
||||
#include <vtkm/cont/DataSet.h>
|
||||
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
|
||||
#include <vtkm/cont/Timer.h>
|
||||
#include <vtkm/cont/Logging.h>
|
||||
#include <vtkm/io/reader/VTKDataSetReader.h>
|
||||
#include <vtkm/io/writer/VTKDataSetWriter.h>
|
||||
|
||||
@ -32,7 +31,7 @@
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
using DeviceAdapter = VTKM_DEFAULT_DEVICE_ADAPTER_TAG;
|
||||
static const vtkm::cont::LogLevel CosmoLogLevel = vtkm::cont::LogLevel(1);
|
||||
|
||||
void TestCosmoHaloFinder(const char* fileName)
|
||||
{
|
||||
@ -73,28 +72,26 @@ void TestCosmoHaloFinder(const char* fileName)
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> resultMBP;
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32> resultPot;
|
||||
|
||||
vtkm::cont::Timer<DeviceAdapter> total;
|
||||
vtkm::cont::Timer<DeviceAdapter> timer;
|
||||
|
||||
// Create the worklet and run it
|
||||
vtkm::Id minHaloSize = 20;
|
||||
vtkm::Float32 linkingLength = 0.2f;
|
||||
vtkm::Float32 particleMass = 1.08413e+09f;
|
||||
|
||||
vtkm::worklet::CosmoTools cosmoTools;
|
||||
cosmoTools.RunHaloFinder(xLocArray,
|
||||
yLocArray,
|
||||
zLocArray,
|
||||
nParticles,
|
||||
particleMass,
|
||||
minHaloSize,
|
||||
linkingLength,
|
||||
resultHaloId,
|
||||
resultMBP,
|
||||
resultPot,
|
||||
DeviceAdapter());
|
||||
vtkm::Float64 haloTime = timer.GetElapsedTime();
|
||||
std::cout << "**** Time for HaloFinder: " << haloTime << std::endl;
|
||||
{
|
||||
VTKM_LOG_SCOPE(CosmoLogLevel, "Executing HaloFinder");
|
||||
|
||||
vtkm::worklet::CosmoTools cosmoTools;
|
||||
cosmoTools.RunHaloFinder(xLocArray,
|
||||
yLocArray,
|
||||
zLocArray,
|
||||
nParticles,
|
||||
particleMass,
|
||||
minHaloSize,
|
||||
linkingLength,
|
||||
resultHaloId,
|
||||
resultMBP,
|
||||
resultPot);
|
||||
}
|
||||
|
||||
xLocArray.ReleaseResources();
|
||||
yLocArray.ReleaseResources();
|
||||
@ -117,12 +114,20 @@ void TestCosmoHaloFinder(const char* fileName)
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
vtkm::cont::SetLogLevelName(CosmoLogLevel, "Cosmo");
|
||||
vtkm::cont::SetStderrLogLevel(CosmoLogLevel);
|
||||
vtkm::cont::InitLogging(argc, argv);
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
std::cout << "Usage: " << std::endl << "$ " << argv[0] << " <input_file>" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifndef VTKM_ENABLE_LOGGING
|
||||
std::cout << "Warning: turn on VTKm_ENABLE_LOGGING CMake option to turn on timing." << std::endl;
|
||||
#endif
|
||||
|
||||
TestCosmoHaloFinder(argv[1]);
|
||||
|
||||
return 0;
|
||||
|
@ -1,23 +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.
|
||||
//
|
||||
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2014 UT-Battelle, LLC.
|
||||
// Copyright 2014 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// the U.S. Government retains certain rights in this software.
|
||||
//
|
||||
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
|
||||
// Laboratory (LANL), the U.S. Government retains certain rights in
|
||||
// this software.
|
||||
//============================================================================
|
||||
|
||||
#define VTKM_DEVICE_ADAPTER VTKM_DEVICE_ADAPTER_TBB
|
||||
|
||||
#include "CosmoHaloFinder.cxx"
|
@ -122,23 +122,12 @@ struct UpdateLifeState : public vtkm::worklet::WorkletPointNeighborhood3x3x3
|
||||
|
||||
class GameOfLife : public vtkm::filter::FilterDataSet<GameOfLife>
|
||||
{
|
||||
bool PrintedDeviceMsg = false;
|
||||
|
||||
public:
|
||||
template <typename Policy, typename Device>
|
||||
template <typename Policy>
|
||||
VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input,
|
||||
vtkm::filter::PolicyBase<Policy> policy,
|
||||
Device)
|
||||
vtkm::filter::PolicyBase<Policy> policy)
|
||||
|
||||
{
|
||||
if (!this->PrintedDeviceMsg)
|
||||
{
|
||||
using DeviceAdapterTraits = vtkm::cont::DeviceAdapterTraits<Device>;
|
||||
std::cout << "Running GameOfLife filter on device adapter: " << DeviceAdapterTraits::GetName()
|
||||
<< std::endl;
|
||||
this->PrintedDeviceMsg = true;
|
||||
}
|
||||
|
||||
using DispatcherType = vtkm::worklet::DispatcherPointNeighborhood<UpdateLifeState>;
|
||||
|
||||
|
||||
@ -154,7 +143,6 @@ public:
|
||||
|
||||
//Update the game state
|
||||
DispatcherType dispatcher;
|
||||
dispatcher.SetDevice(Device());
|
||||
dispatcher.Invoke(vtkm::filter::ApplyPolicy(cells, policy), prevstate, state, colors);
|
||||
|
||||
//save the results
|
||||
@ -171,12 +159,11 @@ public:
|
||||
return output;
|
||||
}
|
||||
|
||||
template <typename T, typename StorageType, typename DerivedPolicy, typename DeviceAdapter>
|
||||
template <typename T, typename StorageType, typename DerivedPolicy>
|
||||
VTKM_CONT bool DoMapField(vtkm::cont::DataSet&,
|
||||
const vtkm::cont::ArrayHandle<T, StorageType>&,
|
||||
const vtkm::filter::FieldMetadata&,
|
||||
const vtkm::filter::PolicyBase<DerivedPolicy>&,
|
||||
DeviceAdapter)
|
||||
vtkm::filter::PolicyBase<DerivedPolicy>)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
#include <thread>
|
||||
|
||||
using RuntimeTaskQueue = TaskQueue<std::function<void(const vtkm::cont::RuntimeDeviceTracker&)>>;
|
||||
using RuntimeTaskQueue = TaskQueue<std::function<void()>>;
|
||||
|
||||
/// \brief Construct a MultiDeviceGradient for a given multiblock dataset
|
||||
///
|
||||
|
@ -45,10 +45,10 @@ void process_block_tbb(RuntimeTaskQueue& queue)
|
||||
{
|
||||
//Step 1. Set the device adapter to this thread to TBB.
|
||||
//This makes sure that any vtkm::filters used by our
|
||||
//task operate only on TBB
|
||||
//task operate only on TBB. The "global" thread tracker
|
||||
//is actually thread-local, so we can use that.
|
||||
//
|
||||
vtkm::cont::RuntimeDeviceTracker tracker;
|
||||
tracker.ForceDevice(vtkm::cont::DeviceAdapterTagTBB{});
|
||||
vtkm::cont::GetGlobalRuntimeDeviceTracker().ForceDevice(vtkm::cont::DeviceAdapterTagTBB{});
|
||||
|
||||
while (queue.hasTasks())
|
||||
{
|
||||
@ -60,7 +60,7 @@ void process_block_tbb(RuntimeTaskQueue& queue)
|
||||
//when the queue is empty and we are shutting down
|
||||
if (task != nullptr)
|
||||
{
|
||||
task(tracker);
|
||||
task();
|
||||
}
|
||||
|
||||
//Step 4. Notify the queue that we finished processing this task
|
||||
@ -73,13 +73,10 @@ void process_block_cuda(RuntimeTaskQueue& queue, int gpuId)
|
||||
{
|
||||
//Step 1. Set the device adapter to this thread to cuda.
|
||||
//This makes sure that any vtkm::filters used by our
|
||||
//task operate only on cuda
|
||||
//task operate only on cuda. The "global" thread tracker
|
||||
//is actually thread-local, so we can use that.
|
||||
//
|
||||
vtkm::cont::RuntimeDeviceTracker tracker;
|
||||
#if defined(VTKM_ENABLE_CUDA)
|
||||
auto error = cudaSetDevice(gpuId);
|
||||
tracker.ForceDevice(vtkm::cont::DeviceAdapterTagCuda{});
|
||||
#endif
|
||||
vtkm::cont::GetGlobalRuntimeDeviceTracker().ForceDevice(vtkm::cont::DeviceAdapterTagCuda{});
|
||||
(void)gpuId;
|
||||
|
||||
while (queue.hasTasks())
|
||||
@ -87,12 +84,12 @@ void process_block_cuda(RuntimeTaskQueue& queue, int gpuId)
|
||||
//Step 2. Get the task to run on cuda
|
||||
auto task = queue.pop();
|
||||
|
||||
//Step 3. Run the task on TBB. We check the validity
|
||||
//Step 3. Run the task on cuda. We check the validity
|
||||
//of the task since we could be given an empty task
|
||||
//when the queue is empty and we are shutting down
|
||||
if (task != nullptr)
|
||||
{
|
||||
task(tracker);
|
||||
task();
|
||||
}
|
||||
|
||||
//Step 4. Notify the queue that we finished processing this task
|
||||
@ -190,11 +187,8 @@ inline VTKM_CONT vtkm::cont::MultiBlock MultiDeviceGradient::PrepareForExecution
|
||||
{
|
||||
vtkm::cont::DataSet input = *block;
|
||||
this->Queue.push( //build a lambda that is the work to do
|
||||
[=](const vtkm::cont::RuntimeDeviceTracker& tracker) {
|
||||
//make a per thread copy of the filter
|
||||
//and give it the device tracker
|
||||
[=]() {
|
||||
vtkm::filter::Gradient perThreadGrad = gradient;
|
||||
perThreadGrad.SetRuntimeDeviceTracker(tracker);
|
||||
|
||||
vtkm::cont::DataSet result = perThreadGrad.Execute(input, policy);
|
||||
outPtr->ReplaceBlock(0, result);
|
||||
@ -212,11 +206,8 @@ inline VTKM_CONT vtkm::cont::MultiBlock MultiDeviceGradient::PrepareForExecution
|
||||
//will allows us to have multiple works execute in a non
|
||||
//blocking manner
|
||||
this->Queue.push( //build a lambda that is the work to do
|
||||
[=](const vtkm::cont::RuntimeDeviceTracker& tracker) {
|
||||
//make a per thread copy of the filter
|
||||
//and give it the device tracker
|
||||
[=]() {
|
||||
vtkm::filter::Gradient perThreadGrad = gradient;
|
||||
perThreadGrad.SetRuntimeDeviceTracker(tracker);
|
||||
|
||||
vtkm::cont::DataSet result = perThreadGrad.Execute(input, policy);
|
||||
outPtr->ReplaceBlock(index, result);
|
||||
|
@ -18,10 +18,6 @@
|
||||
// this software.
|
||||
//============================================================================
|
||||
|
||||
#ifndef VTKM_DEVICE_ADAPTER
|
||||
#define VTKM_DEVICE_ADAPTER VTKM_DEVICE_ADAPTER_SERIAL
|
||||
#endif
|
||||
|
||||
#include <vtkm/cont/DataSet.h>
|
||||
#include <vtkm/worklet/ParticleAdvection.h>
|
||||
#include <vtkm/worklet/particleadvection/GridEvaluators.h>
|
||||
@ -66,20 +62,14 @@ void RunTest(const std::string& fname,
|
||||
vtkm::Id advectType,
|
||||
vtkm::Id seeding)
|
||||
{
|
||||
using DeviceAdapter = VTKM_DEFAULT_DEVICE_ADAPTER_TAG;
|
||||
|
||||
using FieldType = vtkm::Float32;
|
||||
using FieldHandle = vtkm::cont::ArrayHandle<vtkm::Vec<FieldType, 3>>;
|
||||
using FieldPortalConstType =
|
||||
typename FieldHandle::template ExecutionTypes<DeviceAdapter>::PortalConst;
|
||||
|
||||
vtkm::io::reader::BOVDataSetReader rdr(fname);
|
||||
vtkm::cont::DataSet ds = rdr.ReadDataSet();
|
||||
|
||||
using RGEvalType = vtkm::worklet::particleadvection::UniformGridEvaluate<FieldPortalConstType,
|
||||
FieldType,
|
||||
DeviceAdapter>;
|
||||
using RK4RGType = vtkm::worklet::particleadvection::RK4Integrator<RGEvalType, FieldType>;
|
||||
using RGEvalType = vtkm::worklet::particleadvection::UniformGridEvaluate<FieldHandle>;
|
||||
using RK4RGType = vtkm::worklet::particleadvection::RK4Integrator<RGEvalType>;
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<FieldType, 3>> fieldArray;
|
||||
ds.GetField(0).GetData().CopyTo(fieldArray);
|
||||
@ -167,12 +157,12 @@ void RunTest(const std::string& fname,
|
||||
if (advectType == 0)
|
||||
{
|
||||
vtkm::worklet::ParticleAdvection particleAdvection;
|
||||
particleAdvection.Run(rk4, seedArray, numSteps, DeviceAdapter());
|
||||
particleAdvection.Run(rk4, seedArray, numSteps);
|
||||
}
|
||||
else
|
||||
{
|
||||
vtkm::worklet::Streamline streamline;
|
||||
streamline.Run(rk4, seedArray, numSteps, DeviceAdapter());
|
||||
streamline.Run(rk4, seedArray, numSteps);
|
||||
}
|
||||
|
||||
auto t1 = std::chrono::high_resolution_clock::now() - t0;
|
||||
|
@ -22,7 +22,7 @@
|
||||
#include <vtkm/cont/Algorithm.h>
|
||||
#include <vtkm/cont/AssignerMultiBlock.h>
|
||||
#include <vtkm/cont/BoundsGlobalCompute.h>
|
||||
#include <vtkm/cont/diy/Serialization.h>
|
||||
#include <vtkm/cont/Serialization.h>
|
||||
#include <vtkm/filter/ExtractPoints.h>
|
||||
#include <vtkm/filter/Filter.h>
|
||||
|
||||
@ -73,6 +73,66 @@ class Redistributor
|
||||
return extractor.Execute(input, this->Policy);
|
||||
}
|
||||
|
||||
class ConcatenateFields
|
||||
{
|
||||
public:
|
||||
explicit ConcatenateFields(vtkm::Id totalSize) : TotalSize(totalSize), CurrentIdx(0) {}
|
||||
|
||||
void Append(const vtkm::cont::Field& field)
|
||||
{
|
||||
VTKM_ASSERT(this->CurrentIdx + field.GetData().GetNumberOfValues() <= this->TotalSize);
|
||||
|
||||
if (this->Field.GetData().GetNumberOfValues() == 0)
|
||||
{
|
||||
this->Field = field;
|
||||
field.GetData().CastAndCall(Allocator{}, this->Field, this->TotalSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
VTKM_ASSERT(this->Field.GetName() == field.GetName() &&
|
||||
this->Field.GetAssociation() == field.GetAssociation());
|
||||
}
|
||||
|
||||
field.GetData().CastAndCall(Appender{}, this->Field, this->CurrentIdx);
|
||||
this->CurrentIdx += field.GetData().GetNumberOfValues();
|
||||
}
|
||||
|
||||
const vtkm::cont::Field& GetResult() const
|
||||
{
|
||||
return this->Field;
|
||||
}
|
||||
|
||||
private:
|
||||
struct Allocator
|
||||
{
|
||||
template <typename T, typename S>
|
||||
void operator()(const vtkm::cont::ArrayHandle<T, S>&,
|
||||
vtkm::cont::Field& field,
|
||||
vtkm::Id totalSize) const
|
||||
{
|
||||
vtkm::cont::ArrayHandle<T> init;
|
||||
init.Allocate(totalSize);
|
||||
field.SetData(init);
|
||||
}
|
||||
};
|
||||
|
||||
struct Appender
|
||||
{
|
||||
template <typename T, typename S>
|
||||
void operator()(const vtkm::cont::ArrayHandle<T, S>& data,
|
||||
vtkm::cont::Field& field,
|
||||
vtkm::Id currentIdx) const
|
||||
{
|
||||
vtkm::cont::ArrayHandle<T> farray =
|
||||
field.GetData().template Cast<vtkm::cont::ArrayHandle<T>>();
|
||||
vtkm::cont::Algorithm::CopySubRange(data, 0, data.GetNumberOfValues(), farray, currentIdx);
|
||||
}
|
||||
};
|
||||
|
||||
vtkm::Id TotalSize;
|
||||
vtkm::Id CurrentIdx;
|
||||
vtkm::cont::Field Field;
|
||||
};
|
||||
|
||||
public:
|
||||
Redistributor(const diy::RegularDecomposer<diy::ContinuousBounds>& decomposer,
|
||||
@ -95,11 +155,7 @@ public:
|
||||
this->Decomposer.fill_bounds(bds, target.gid);
|
||||
|
||||
auto extractedDS = this->Extract(*block, bds);
|
||||
const auto inputAH = extractedDS.GetCoordinateSystem(0).GetData();
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::FloatDefault, 3>> outputAH;
|
||||
outputAH.Allocate(inputAH.GetNumberOfValues());
|
||||
vtkm::cont::Algorithm::Copy(inputAH, outputAH);
|
||||
rp.enqueue(target, outputAH);
|
||||
rp.enqueue(target, vtkm::filter::MakeSerializableDataSet(extractedDS, DerivedPolicy{}));
|
||||
}
|
||||
// clear our dataset.
|
||||
*block = vtkm::cont::DataSet();
|
||||
@ -108,36 +164,43 @@ public:
|
||||
else
|
||||
{
|
||||
vtkm::Id numValues = 0;
|
||||
std::vector<vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::FloatDefault, 3>>> received_arrays;
|
||||
std::vector<vtkm::cont::DataSet> receives;
|
||||
for (int cc = 0; cc < rp.in_link().size(); ++cc)
|
||||
{
|
||||
auto target = rp.in_link().target(cc);
|
||||
if (rp.incoming(target.gid).size() > 0)
|
||||
{
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::FloatDefault, 3>> incomingAH;
|
||||
rp.dequeue(target.gid, incomingAH);
|
||||
received_arrays.push_back(incomingAH);
|
||||
numValues += incomingAH.GetNumberOfValues();
|
||||
auto sds = vtkm::filter::MakeSerializableDataSet(DerivedPolicy{});
|
||||
rp.dequeue(target.gid, sds);
|
||||
receives.push_back(sds.DataSet);
|
||||
numValues += receives.back().GetCoordinateSystem(0).GetData().GetNumberOfValues();
|
||||
}
|
||||
}
|
||||
|
||||
*block = vtkm::cont::DataSet();
|
||||
if (received_arrays.size() == 1)
|
||||
if (receives.size() == 1)
|
||||
{
|
||||
auto coords = vtkm::cont::CoordinateSystem("coords", received_arrays[0]);
|
||||
block->AddCoordinateSystem(coords);
|
||||
*block = receives[0];
|
||||
}
|
||||
else if (received_arrays.size() > 1)
|
||||
else if (receives.size() > 1)
|
||||
{
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::FloatDefault, 3>> coordsAH;
|
||||
coordsAH.Allocate(numValues);
|
||||
vtkm::Id offset = 0;
|
||||
for (const vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::FloatDefault, 3>>& receivedAH : received_arrays)
|
||||
ConcatenateFields concatCoords(numValues);
|
||||
for (const auto& ds: receives)
|
||||
{
|
||||
vtkm::cont::Algorithm::CopySubRange(receivedAH, 0, receivedAH.GetNumberOfValues(), coordsAH, offset);
|
||||
offset += receivedAH.GetNumberOfValues();
|
||||
concatCoords.Append(ds.GetCoordinateSystem(0));
|
||||
}
|
||||
block->AddCoordinateSystem(vtkm::cont::CoordinateSystem(
|
||||
concatCoords.GetResult().GetName(), concatCoords.GetResult().GetData()));
|
||||
|
||||
for (vtkm::IdComponent i = 0; i < receives[0].GetNumberOfFields(); ++i)
|
||||
{
|
||||
ConcatenateFields concatField(numValues);
|
||||
for (const auto& ds: receives)
|
||||
{
|
||||
concatField.Append(ds.GetField(i));
|
||||
}
|
||||
block->AddField(concatField.GetResult());
|
||||
}
|
||||
block->AddCoordinateSystem(vtkm::cont::CoordinateSystem("coords", coordsAH));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,10 +18,6 @@
|
||||
// this software.
|
||||
//============================================================================
|
||||
|
||||
#ifndef VTKM_DEVICE_ADAPTER
|
||||
#define VTKM_DEVICE_ADAPTER VTKM_DEVICE_ADAPTER_SERIAL
|
||||
#endif
|
||||
|
||||
#include <vtkm/cont/DataSet.h>
|
||||
#include <vtkm/worklet/ParticleAdvection.h>
|
||||
#include <vtkm/worklet/particleadvection/Integrators.h>
|
||||
@ -49,11 +45,8 @@ int renderAndWriteDataSet(const vtkm::cont::DataSet& dataset)
|
||||
|
||||
void RunTest(vtkm::Id numSteps, vtkm::Float32 stepSize, vtkm::Id advectType)
|
||||
{
|
||||
using DeviceAdapter = VTKM_DEFAULT_DEVICE_ADAPTER_TAG;
|
||||
using FieldType = vtkm::Float32;
|
||||
using FieldHandle = vtkm::cont::ArrayHandle<vtkm::Vec<FieldType, 3>>;
|
||||
using FieldPortalConstType =
|
||||
typename FieldHandle::template ExecutionTypes<DeviceAdapter>::PortalConst;
|
||||
|
||||
// These lines read two datasets, which are BOVs.
|
||||
// Currently VTKm does not support providing time series datasets
|
||||
@ -73,11 +66,8 @@ void RunTest(vtkm::Id numSteps, vtkm::Float32 stepSize, vtkm::Id advectType)
|
||||
|
||||
// The only change in this example and the vanilla particle advection example is
|
||||
// this example makes use of the TemporalGridEvaluator.
|
||||
using GridEvaluator =
|
||||
vtkm::worklet::particleadvection::TemporalGridEvaluator<FieldPortalConstType,
|
||||
FieldType,
|
||||
DeviceAdapter>;
|
||||
using Integrator = vtkm::worklet::particleadvection::EulerIntegrator<GridEvaluator, FieldType>;
|
||||
using GridEvaluator = vtkm::worklet::particleadvection::TemporalGridEvaluator<FieldHandle>;
|
||||
using Integrator = vtkm::worklet::particleadvection::EulerIntegrator<GridEvaluator>;
|
||||
|
||||
GridEvaluator eval(ds1.GetCoordinateSystem(),
|
||||
ds1.GetCellSet(0),
|
||||
@ -109,13 +99,12 @@ void RunTest(vtkm::Id numSteps, vtkm::Float32 stepSize, vtkm::Id advectType)
|
||||
if (advectType == 0)
|
||||
{
|
||||
vtkm::worklet::ParticleAdvection particleAdvection;
|
||||
particleAdvection.Run(integrator, seedArray, numSteps, DeviceAdapter());
|
||||
particleAdvection.Run(integrator, seedArray, numSteps);
|
||||
}
|
||||
else
|
||||
{
|
||||
vtkm::worklet::Streamline streamline;
|
||||
vtkm::worklet::StreamlineResult<FieldType> res =
|
||||
streamline.Run(integrator, seedArray, numSteps, DeviceAdapter());
|
||||
vtkm::worklet::StreamlineResult res = streamline.Run(integrator, seedArray, numSteps);
|
||||
vtkm::cont::DataSet outData;
|
||||
vtkm::cont::CoordinateSystem outputCoords("coordinates", res.positions);
|
||||
outData.AddCellSet(res.polyLines);
|
||||
|
@ -1 +1 @@
|
||||
1.2.0
|
||||
1.3.0
|
||||
|
70
vtkm/Bitset.h
Normal file
70
vtkm/Bitset.h
Normal file
@ -0,0 +1,70 @@
|
||||
//============================================================================
|
||||
// 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.
|
||||
//
|
||||
// Copyright 2016 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2016 UT-Battelle, LLC.
|
||||
// Copyright 2016 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// the U.S. Government retains certain rights in this software.
|
||||
//
|
||||
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
|
||||
// Laboratory (LANL), the U.S. Government retains certain rights in
|
||||
// this software.
|
||||
//============================================================================
|
||||
|
||||
#ifndef vtk_m_Bitset_h
|
||||
#define vtk_m_Bitset_h
|
||||
|
||||
#include <assert.h>
|
||||
#include <limits>
|
||||
#include <vtkm/Types.h>
|
||||
#include <vtkm/internal/ExportMacros.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
|
||||
/// \brief A bitmap to serve different needs.
|
||||
/// Ex. Editing particular bits in a byte(s), checkint if particular bit values
|
||||
/// are present or not. Once Cuda supports std::bitset, we should use the
|
||||
/// standard one if possible
|
||||
template <typename MaskType>
|
||||
struct Bitset
|
||||
{
|
||||
VTKM_EXEC_CONT Bitset()
|
||||
: Mask(0)
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT void set(vtkm::Id bitIndex)
|
||||
{
|
||||
this->Mask = this->Mask | (static_cast<MaskType>(1) << bitIndex);
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT void reset(vtkm::Id bitIndex)
|
||||
{
|
||||
this->Mask = this->Mask & ~(static_cast<MaskType>(1) << bitIndex);
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT void toggle(vtkm::Id bitIndex)
|
||||
{
|
||||
this->Mask = this->Mask ^ (static_cast<MaskType>(0) << bitIndex);
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT bool test(vtkm::Id bitIndex)
|
||||
{
|
||||
return ((this->Mask & (static_cast<MaskType>(1) << bitIndex)) != 0);
|
||||
}
|
||||
|
||||
private:
|
||||
MaskType Mask;
|
||||
};
|
||||
|
||||
} // namespace vtkm
|
||||
|
||||
#endif //vtk_m_Bitset_h
|
@ -31,11 +31,13 @@ set(headers
|
||||
BaseComponent.h
|
||||
BinaryPredicates.h
|
||||
BinaryOperators.h
|
||||
Bitset.h
|
||||
Bounds.h
|
||||
CellShape.h
|
||||
CellTraits.h
|
||||
Flags.h
|
||||
Geometry.h
|
||||
GhostCell.h
|
||||
Hash.h
|
||||
ImplicitFunction.h
|
||||
ListTag.h
|
||||
@ -80,6 +82,9 @@ vtkm_declare_headers(
|
||||
#first add all the components vtkm that are shared between control and exec
|
||||
add_subdirectory(thirdparty/diy)
|
||||
add_subdirectory(thirdparty/taotuple)
|
||||
if(VTKm_ENABLE_LOGGING)
|
||||
add_subdirectory(thirdparty/loguru)
|
||||
endif()
|
||||
add_subdirectory(testing)
|
||||
add_subdirectory(internal)
|
||||
|
||||
|
@ -17,7 +17,23 @@
|
||||
// Laboratory (LANL), the U.S. Government retains certain rights in
|
||||
// this software.
|
||||
//============================================================================
|
||||
#ifndef vtk_m_Ghost_Cell_h
|
||||
#define vtk_m_Ghost_Cell_h
|
||||
|
||||
#define VTKM_DEVICE_ADAPTER VTKM_DEVICE_ADAPTER_TBB
|
||||
namespace vtkm
|
||||
{
|
||||
|
||||
#include "CosmoCenterFinder.cxx"
|
||||
enum struct CellClassification
|
||||
{
|
||||
NORMAL = 0, //Valid cell
|
||||
DUPLICATE = 1 << 0, //Ghost cell
|
||||
INVALID = 1 << 1, //Cell is invalid
|
||||
UNUSED0 = 1 << 2,
|
||||
UNUSED1 = 1 << 3,
|
||||
UNUSED3 = 1 << 4,
|
||||
UNUSED4 = 1 << 5,
|
||||
UNUSED5 = 1 << 6,
|
||||
};
|
||||
}
|
||||
|
||||
#endif // vtk_m_Ghost_Cell_h
|
@ -77,7 +77,7 @@ VTKM_EXEC_CONT inline vtkm::HashType HashFNV1a64(const InVecType& inVec)
|
||||
|
||||
// If you get a compile error saying that there is no implementation of the class HashChooser,
|
||||
// then you have tried to make a hash from an invalid type (like a float).
|
||||
template <typename NumericTag, vtkm::Id DataSize>
|
||||
template <typename NumericTag, std::size_t DataSize>
|
||||
struct HashChooser;
|
||||
|
||||
template <>
|
||||
|
@ -32,46 +32,46 @@ namespace vtkm
|
||||
|
||||
/// A list containing the type vtkm::Id.
|
||||
///
|
||||
struct TypeListTagId : vtkm::ListTagBase<vtkm::Id>
|
||||
struct VTKM_ALWAYS_EXPORT TypeListTagId : vtkm::ListTagBase<vtkm::Id>
|
||||
{
|
||||
};
|
||||
|
||||
/// A list containing the type vtkm::Id2.
|
||||
///
|
||||
struct TypeListTagId2 : vtkm::ListTagBase<vtkm::Id2>
|
||||
struct VTKM_ALWAYS_EXPORT TypeListTagId2 : vtkm::ListTagBase<vtkm::Id2>
|
||||
{
|
||||
};
|
||||
|
||||
/// A list containing the type vtkm::Id3.
|
||||
///
|
||||
struct TypeListTagId3 : vtkm::ListTagBase<vtkm::Id3>
|
||||
struct VTKM_ALWAYS_EXPORT TypeListTagId3 : vtkm::ListTagBase<vtkm::Id3>
|
||||
{
|
||||
};
|
||||
|
||||
/// A list containing the type vtkm::IdComponent
|
||||
///
|
||||
struct TypeListTagIdComponent : vtkm::ListTagBase<vtkm::IdComponent>
|
||||
struct VTKM_ALWAYS_EXPORT TypeListTagIdComponent : vtkm::ListTagBase<vtkm::IdComponent>
|
||||
{
|
||||
};
|
||||
|
||||
/// A list containing types used to index arrays. Contains vtkm::Id, vtkm::Id2,
|
||||
/// and vtkm::Id3.
|
||||
///
|
||||
struct TypeListTagIndex : vtkm::ListTagBase<vtkm::Id, vtkm::Id2, vtkm::Id3>
|
||||
struct VTKM_ALWAYS_EXPORT TypeListTagIndex : vtkm::ListTagBase<vtkm::Id, vtkm::Id2, vtkm::Id3>
|
||||
{
|
||||
};
|
||||
|
||||
/// A list containing types used for scalar fields. Specifically, contains
|
||||
/// floating point numbers of different widths (i.e. vtkm::Float32 and
|
||||
/// vtkm::Float64).
|
||||
struct TypeListTagFieldScalar : vtkm::ListTagBase<vtkm::Float32, vtkm::Float64>
|
||||
struct VTKM_ALWAYS_EXPORT TypeListTagFieldScalar : vtkm::ListTagBase<vtkm::Float32, vtkm::Float64>
|
||||
{
|
||||
};
|
||||
|
||||
/// A list containing types for values for fields with two dimensional
|
||||
/// vectors.
|
||||
///
|
||||
struct TypeListTagFieldVec2
|
||||
struct VTKM_ALWAYS_EXPORT TypeListTagFieldVec2
|
||||
: vtkm::ListTagBase<vtkm::Vec<vtkm::Float32, 2>, vtkm::Vec<vtkm::Float64, 2>>
|
||||
{
|
||||
};
|
||||
@ -79,7 +79,7 @@ struct TypeListTagFieldVec2
|
||||
/// A list containing types for values for fields with three dimensional
|
||||
/// vectors.
|
||||
///
|
||||
struct TypeListTagFieldVec3
|
||||
struct VTKM_ALWAYS_EXPORT TypeListTagFieldVec3
|
||||
: vtkm::ListTagBase<vtkm::Vec<vtkm::Float32, 3>, vtkm::Vec<vtkm::Float64, 3>>
|
||||
{
|
||||
};
|
||||
@ -87,7 +87,7 @@ struct TypeListTagFieldVec3
|
||||
/// A list containing types for values for fields with four dimensional
|
||||
/// vectors.
|
||||
///
|
||||
struct TypeListTagFieldVec4
|
||||
struct VTKM_ALWAYS_EXPORT TypeListTagFieldVec4
|
||||
: vtkm::ListTagBase<vtkm::Vec<vtkm::Float32, 4>, vtkm::Vec<vtkm::Float64, 4>>
|
||||
{
|
||||
};
|
||||
@ -96,12 +96,13 @@ struct TypeListTagFieldVec4
|
||||
/// floating point vectors of size 2, 3, and 4 with floating point components.
|
||||
/// Scalars are not included.
|
||||
///
|
||||
struct TypeListTagFloatVec : vtkm::ListTagBase<vtkm::Vec<vtkm::Float32, 2>,
|
||||
vtkm::Vec<vtkm::Float64, 2>,
|
||||
vtkm::Vec<vtkm::Float32, 3>,
|
||||
vtkm::Vec<vtkm::Float64, 3>,
|
||||
vtkm::Vec<vtkm::Float32, 4>,
|
||||
vtkm::Vec<vtkm::Float64, 4>>
|
||||
struct VTKM_ALWAYS_EXPORT TypeListTagFloatVec
|
||||
: vtkm::ListTagBase<vtkm::Vec<vtkm::Float32, 2>,
|
||||
vtkm::Vec<vtkm::Float64, 2>,
|
||||
vtkm::Vec<vtkm::Float32, 3>,
|
||||
vtkm::Vec<vtkm::Float64, 3>,
|
||||
vtkm::Vec<vtkm::Float32, 4>,
|
||||
vtkm::Vec<vtkm::Float64, 4>>
|
||||
{
|
||||
};
|
||||
|
||||
@ -109,30 +110,32 @@ struct TypeListTagFloatVec : vtkm::ListTagBase<vtkm::Vec<vtkm::Float32, 2>,
|
||||
/// floating point scalars and vectors of size 2, 3, and 4 with floating point
|
||||
/// components.
|
||||
///
|
||||
struct TypeListTagField : vtkm::ListTagBase<vtkm::Float32,
|
||||
vtkm::Float64,
|
||||
vtkm::Vec<vtkm::Float32, 2>,
|
||||
vtkm::Vec<vtkm::Float64, 2>,
|
||||
vtkm::Vec<vtkm::Float32, 3>,
|
||||
vtkm::Vec<vtkm::Float64, 3>,
|
||||
vtkm::Vec<vtkm::Float32, 4>,
|
||||
vtkm::Vec<vtkm::Float64, 4>>
|
||||
struct VTKM_ALWAYS_EXPORT TypeListTagField
|
||||
: vtkm::ListTagBase<vtkm::Float32,
|
||||
vtkm::Float64,
|
||||
vtkm::Vec<vtkm::Float32, 2>,
|
||||
vtkm::Vec<vtkm::Float64, 2>,
|
||||
vtkm::Vec<vtkm::Float32, 3>,
|
||||
vtkm::Vec<vtkm::Float64, 3>,
|
||||
vtkm::Vec<vtkm::Float32, 4>,
|
||||
vtkm::Vec<vtkm::Float64, 4>>
|
||||
{
|
||||
};
|
||||
|
||||
/// A list of all scalars defined in vtkm/Types.h. A scalar is a type that
|
||||
/// holds a single number.
|
||||
///
|
||||
struct TypeListTagScalarAll : vtkm::ListTagBase<vtkm::Int8,
|
||||
vtkm::UInt8,
|
||||
vtkm::Int16,
|
||||
vtkm::UInt16,
|
||||
vtkm::Int32,
|
||||
vtkm::UInt32,
|
||||
vtkm::Int64,
|
||||
vtkm::UInt64,
|
||||
vtkm::Float32,
|
||||
vtkm::Float64>
|
||||
struct VTKM_ALWAYS_EXPORT TypeListTagScalarAll
|
||||
: vtkm::ListTagBase<vtkm::Int8,
|
||||
vtkm::UInt8,
|
||||
vtkm::Int16,
|
||||
vtkm::UInt16,
|
||||
vtkm::Int32,
|
||||
vtkm::UInt32,
|
||||
vtkm::Int64,
|
||||
vtkm::UInt64,
|
||||
vtkm::Float32,
|
||||
vtkm::Float64>
|
||||
{
|
||||
};
|
||||
|
||||
@ -140,21 +143,22 @@ struct TypeListTagScalarAll : vtkm::ListTagBase<vtkm::Int8,
|
||||
/// vectors of size 2, 3, or 4 containing either unsigned bytes, signed
|
||||
/// integers of 32 or 64 bits, or floating point values of 32 or 64 bits.
|
||||
///
|
||||
struct TypeListTagVecCommon : vtkm::ListTagBase<vtkm::Vec<vtkm::UInt8, 2>,
|
||||
vtkm::Vec<vtkm::Int32, 2>,
|
||||
vtkm::Vec<vtkm::Int64, 2>,
|
||||
vtkm::Vec<vtkm::Float32, 2>,
|
||||
vtkm::Vec<vtkm::Float64, 2>,
|
||||
vtkm::Vec<vtkm::UInt8, 3>,
|
||||
vtkm::Vec<vtkm::Int32, 3>,
|
||||
vtkm::Vec<vtkm::Int64, 3>,
|
||||
vtkm::Vec<vtkm::Float32, 3>,
|
||||
vtkm::Vec<vtkm::Float64, 3>,
|
||||
vtkm::Vec<vtkm::UInt8, 4>,
|
||||
vtkm::Vec<vtkm::Int32, 4>,
|
||||
vtkm::Vec<vtkm::Int64, 4>,
|
||||
vtkm::Vec<vtkm::Float32, 4>,
|
||||
vtkm::Vec<vtkm::Float64, 4>>
|
||||
struct VTKM_ALWAYS_EXPORT TypeListTagVecCommon
|
||||
: vtkm::ListTagBase<vtkm::Vec<vtkm::UInt8, 2>,
|
||||
vtkm::Vec<vtkm::Int32, 2>,
|
||||
vtkm::Vec<vtkm::Int64, 2>,
|
||||
vtkm::Vec<vtkm::Float32, 2>,
|
||||
vtkm::Vec<vtkm::Float64, 2>,
|
||||
vtkm::Vec<vtkm::UInt8, 3>,
|
||||
vtkm::Vec<vtkm::Int32, 3>,
|
||||
vtkm::Vec<vtkm::Int64, 3>,
|
||||
vtkm::Vec<vtkm::Float32, 3>,
|
||||
vtkm::Vec<vtkm::Float64, 3>,
|
||||
vtkm::Vec<vtkm::UInt8, 4>,
|
||||
vtkm::Vec<vtkm::Int32, 4>,
|
||||
vtkm::Vec<vtkm::Int64, 4>,
|
||||
vtkm::Vec<vtkm::Float32, 4>,
|
||||
vtkm::Vec<vtkm::Float64, 4>>
|
||||
{
|
||||
};
|
||||
|
||||
@ -165,21 +169,22 @@ namespace internal
|
||||
/// use in general, but is used when joined with \c TypeListTagVecCommon
|
||||
/// to get a list of all vectors up to size 4.
|
||||
///
|
||||
struct TypeListTagVecUncommon : vtkm::ListTagBase<vtkm::Vec<vtkm::Int8, 2>,
|
||||
vtkm::Vec<vtkm::Int16, 2>,
|
||||
vtkm::Vec<vtkm::UInt16, 2>,
|
||||
vtkm::Vec<vtkm::UInt32, 2>,
|
||||
vtkm::Vec<vtkm::UInt64, 2>,
|
||||
vtkm::Vec<vtkm::Int8, 3>,
|
||||
vtkm::Vec<vtkm::Int16, 3>,
|
||||
vtkm::Vec<vtkm::UInt16, 3>,
|
||||
vtkm::Vec<vtkm::UInt32, 3>,
|
||||
vtkm::Vec<vtkm::UInt64, 3>,
|
||||
vtkm::Vec<vtkm::Int8, 4>,
|
||||
vtkm::Vec<vtkm::Int16, 4>,
|
||||
vtkm::Vec<vtkm::UInt16, 4>,
|
||||
vtkm::Vec<vtkm::UInt32, 4>,
|
||||
vtkm::Vec<vtkm::UInt64, 4>>
|
||||
struct VTKM_ALWAYS_EXPORT TypeListTagVecUncommon
|
||||
: vtkm::ListTagBase<vtkm::Vec<vtkm::Int8, 2>,
|
||||
vtkm::Vec<vtkm::Int16, 2>,
|
||||
vtkm::Vec<vtkm::UInt16, 2>,
|
||||
vtkm::Vec<vtkm::UInt32, 2>,
|
||||
vtkm::Vec<vtkm::UInt64, 2>,
|
||||
vtkm::Vec<vtkm::Int8, 3>,
|
||||
vtkm::Vec<vtkm::Int16, 3>,
|
||||
vtkm::Vec<vtkm::UInt16, 3>,
|
||||
vtkm::Vec<vtkm::UInt32, 3>,
|
||||
vtkm::Vec<vtkm::UInt64, 3>,
|
||||
vtkm::Vec<vtkm::Int8, 4>,
|
||||
vtkm::Vec<vtkm::Int16, 4>,
|
||||
vtkm::Vec<vtkm::UInt16, 4>,
|
||||
vtkm::Vec<vtkm::UInt32, 4>,
|
||||
vtkm::Vec<vtkm::UInt64, 4>>
|
||||
{
|
||||
};
|
||||
|
||||
@ -188,7 +193,7 @@ struct TypeListTagVecUncommon : vtkm::ListTagBase<vtkm::Vec<vtkm::Int8, 2>,
|
||||
/// A list of all vector classes with standard types as components and
|
||||
/// lengths between 2 and 4.
|
||||
///
|
||||
struct TypeListTagVecAll
|
||||
struct VTKM_ALWAYS_EXPORT TypeListTagVecAll
|
||||
: vtkm::ListTagJoin<vtkm::TypeListTagVecCommon, vtkm::internal::TypeListTagVecUncommon>
|
||||
{
|
||||
};
|
||||
@ -197,19 +202,21 @@ struct TypeListTagVecAll
|
||||
/// possible VTK-m types like arbitrarily typed and sized Vecs (only up to
|
||||
/// length 4) or math types like matrices.
|
||||
///
|
||||
struct TypeListTagAll : vtkm::ListTagJoin<vtkm::TypeListTagScalarAll, vtkm::TypeListTagVecAll>
|
||||
struct VTKM_ALWAYS_EXPORT TypeListTagAll
|
||||
: vtkm::ListTagJoin<vtkm::TypeListTagScalarAll, vtkm::TypeListTagVecAll>
|
||||
{
|
||||
};
|
||||
|
||||
/// A list of the most commonly used types across multiple domains. Includes
|
||||
/// integers, floating points, and 3 dimensional vectors of floating points.
|
||||
///
|
||||
struct TypeListTagCommon : vtkm::ListTagBase<vtkm::Int32,
|
||||
vtkm::Int64,
|
||||
vtkm::Float32,
|
||||
vtkm::Float64,
|
||||
vtkm::Vec<vtkm::Float32, 3>,
|
||||
vtkm::Vec<vtkm::Float64, 3>>
|
||||
struct VTKM_ALWAYS_EXPORT TypeListTagCommon
|
||||
: vtkm::ListTagBase<vtkm::Int32,
|
||||
vtkm::Int64,
|
||||
vtkm::Float32,
|
||||
vtkm::Float64,
|
||||
vtkm::Vec<vtkm::Float32, 3>,
|
||||
vtkm::Vec<vtkm::Float64, 3>>
|
||||
{
|
||||
};
|
||||
|
||||
@ -217,7 +224,7 @@ struct TypeListTagCommon : vtkm::ListTagBase<vtkm::Int32,
|
||||
// true. Although TypeListTagAll is necessarily finite, the point is to
|
||||
// be all inclusive. Besides, this should speed up the compilation when
|
||||
// checking a list that should contain everything.
|
||||
template <typename Type>
|
||||
template<typename Type>
|
||||
struct ListContains<vtkm::TypeListTagAll, Type>
|
||||
{
|
||||
static constexpr bool value = true;
|
||||
|
@ -38,24 +38,25 @@ template <typename Device, typename T>
|
||||
inline auto DoPrepareArgForExec(T&& object, std::true_type)
|
||||
-> decltype(std::declval<T>().PrepareForExecution(Device()))
|
||||
{
|
||||
VTKM_IS_EXECUTION_OBJECT(T);
|
||||
return object.PrepareForExecution(Device{});
|
||||
}
|
||||
|
||||
template <typename Device, typename T>
|
||||
inline T&& DoPrepareArgForExec(T&& object, std::false_type)
|
||||
{
|
||||
static_assert(!vtkm::cont::internal::IsExecutionObjectBase<T>::value,
|
||||
"Internal error: failed to detect execution object.");
|
||||
return std::forward<T>(object);
|
||||
}
|
||||
|
||||
template <typename Device, typename T>
|
||||
auto PrepareArgForExec(T&& object) -> decltype(DoPrepareArgForExec<Device>(
|
||||
std::forward<T>(object),
|
||||
typename std::is_base_of<vtkm::cont::ExecutionObjectBase, typename std::decay<T>::type>::type{}))
|
||||
auto PrepareArgForExec(T&& object)
|
||||
-> decltype(DoPrepareArgForExec<Device>(std::forward<T>(object),
|
||||
vtkm::cont::internal::IsExecutionObjectBase<T>{}))
|
||||
{
|
||||
return DoPrepareArgForExec<Device>(
|
||||
std::forward<T>(object),
|
||||
typename std::is_base_of<vtkm::cont::ExecutionObjectBase,
|
||||
typename std::decay<T>::type>::type{});
|
||||
return DoPrepareArgForExec<Device>(std::forward<T>(object),
|
||||
vtkm::cont::internal::IsExecutionObjectBase<T>{});
|
||||
}
|
||||
|
||||
struct CopyFunctor
|
||||
@ -87,6 +88,11 @@ struct CopySubRangeFunctor
|
||||
{
|
||||
bool valid;
|
||||
|
||||
CopySubRangeFunctor()
|
||||
: valid(false)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Device, typename... Args>
|
||||
VTKM_CONT bool operator()(Device, Args&&... args)
|
||||
{
|
||||
@ -181,6 +187,54 @@ struct StreamingScanExclusiveFunctor
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::StreamingScanExclusive(numBlocks, input, output);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Device, class CIn, class COut, class BinaryFunctor>
|
||||
VTKM_CONT bool operator()(Device,
|
||||
const vtkm::Id numBlocks,
|
||||
const vtkm::cont::ArrayHandle<T, CIn>& input,
|
||||
vtkm::cont::ArrayHandle<T, COut>& output,
|
||||
BinaryFunctor binary_functor,
|
||||
const T& initialValue)
|
||||
{
|
||||
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
||||
result = vtkm::cont::DeviceAdapterAlgorithm<Device>::StreamingScanExclusive(
|
||||
numBlocks, input, output, binary_functor, initialValue);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename U>
|
||||
struct StreamingReduceFunctor
|
||||
{
|
||||
U result;
|
||||
StreamingReduceFunctor()
|
||||
: result(U(0))
|
||||
{
|
||||
}
|
||||
template <typename Device, typename T, class CIn>
|
||||
VTKM_CONT bool operator()(Device,
|
||||
const vtkm::Id numBlocks,
|
||||
const vtkm::cont::ArrayHandle<T, CIn>& input,
|
||||
U initialValue)
|
||||
{
|
||||
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
||||
result =
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::StreamingReduce(numBlocks, input, initialValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Device, typename T, class CIn, class BinaryFunctor>
|
||||
VTKM_CONT bool operator()(Device,
|
||||
const vtkm::Id numBlocks,
|
||||
const vtkm::cont::ArrayHandle<T, CIn>& input,
|
||||
U InitialValue,
|
||||
BinaryFunctor binaryFunctor)
|
||||
{
|
||||
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
||||
result = vtkm::cont::DeviceAdapterAlgorithm<Device>::StreamingReduce(
|
||||
numBlocks, input, InitialValue, binaryFunctor);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
struct ScanInclusiveByKeyFunctor
|
||||
@ -201,8 +255,9 @@ template <typename T>
|
||||
struct ScanExclusiveFunctor
|
||||
{
|
||||
T result;
|
||||
|
||||
ScanExclusiveFunctor()
|
||||
: result(T(0))
|
||||
: result(T())
|
||||
{
|
||||
}
|
||||
|
||||
@ -552,6 +607,7 @@ struct Algorithm
|
||||
vtkm::cont::TryExecuteOnDevice(devId, functor, numBlocks, input, output);
|
||||
return functor.result;
|
||||
}
|
||||
|
||||
template <typename T, class CIn, class COut>
|
||||
VTKM_CONT static T StreamingScanExclusive(const vtkm::Id numBlocks,
|
||||
const vtkm::cont::ArrayHandle<T, CIn>& input,
|
||||
@ -560,6 +616,46 @@ struct Algorithm
|
||||
return StreamingScanExclusive(vtkm::cont::DeviceAdapterTagAny(), numBlocks, input, output);
|
||||
}
|
||||
|
||||
template <typename T, class CIn, class COut, class BinaryFunctor>
|
||||
VTKM_CONT static T StreamingScanExclusive(const vtkm::Id numBlocks,
|
||||
const vtkm::cont::ArrayHandle<T, CIn>& input,
|
||||
vtkm::cont::ArrayHandle<T, COut>& output,
|
||||
BinaryFunctor binary_functor,
|
||||
const T& initialValue)
|
||||
{
|
||||
detail::StreamingScanExclusiveFunctor<T> functor;
|
||||
vtkm::cont::TryExecuteOnDevice(vtkm::cont::DeviceAdapterTagAny(),
|
||||
functor,
|
||||
numBlocks,
|
||||
input,
|
||||
output,
|
||||
binary_functor,
|
||||
initialValue);
|
||||
return functor.result;
|
||||
}
|
||||
|
||||
template <typename T, typename U, class CIn>
|
||||
VTKM_CONT static U StreamingReduce(const vtkm::Id numBlocks,
|
||||
const vtkm::cont::ArrayHandle<T, CIn>& input,
|
||||
U initialValue)
|
||||
{
|
||||
detail::StreamingReduceFunctor<U> functor;
|
||||
vtkm::cont::TryExecuteOnDevice(
|
||||
vtkm::cont::DeviceAdapterTagAny(), functor, numBlocks, input, initialValue);
|
||||
return functor.result;
|
||||
}
|
||||
|
||||
template <typename T, typename U, class CIn, class BinaryFunctor>
|
||||
VTKM_CONT static U StreamingReduce(const vtkm::Id numBlocks,
|
||||
const vtkm::cont::ArrayHandle<T, CIn>& input,
|
||||
U initialValue,
|
||||
BinaryFunctor binaryFunctor)
|
||||
{
|
||||
detail::StreamingReduceFunctor<U> functor;
|
||||
vtkm::cont::TryExecuteOnDevice(
|
||||
vtkm::cont::DeviceAdapterTagAny(), functor, numBlocks, input, initialValue, binaryFunctor);
|
||||
return functor.result;
|
||||
}
|
||||
|
||||
template <typename T, class CIn, class COut, class BinaryFunctor>
|
||||
VTKM_CONT static T ScanInclusive(vtkm::cont::DeviceAdapterId devId,
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include <vtkm/cont/ArrayPortalToIterators.h>
|
||||
#include <vtkm/cont/ErrorBadValue.h>
|
||||
#include <vtkm/cont/ErrorInternal.h>
|
||||
#include <vtkm/cont/Serialization.h>
|
||||
#include <vtkm/cont/Storage.h>
|
||||
#include <vtkm/cont/StorageBasic.h>
|
||||
|
||||
@ -293,7 +294,7 @@ public:
|
||||
/// with CUDA), then the automatically generated move constructor could be
|
||||
/// created for all devices, and it would not be valid for all devices.
|
||||
///
|
||||
ArrayHandle(vtkm::cont::ArrayHandle<ValueType, StorageTag>&& src);
|
||||
ArrayHandle(vtkm::cont::ArrayHandle<ValueType, StorageTag>&& src) noexcept;
|
||||
|
||||
/// Special constructor for subclass specializations that need to set the
|
||||
/// initial state of the control array. When this constructor is used, it
|
||||
@ -306,7 +307,7 @@ public:
|
||||
/// initial state of the control array. When this constructor is used, it
|
||||
/// is assumed that the control array is valid.
|
||||
///
|
||||
ArrayHandle(StorageType&& storage);
|
||||
ArrayHandle(StorageType&& storage) noexcept;
|
||||
|
||||
/// Destructs an empty ArrayHandle.
|
||||
///
|
||||
@ -327,7 +328,7 @@ public:
|
||||
///
|
||||
VTKM_CONT
|
||||
vtkm::cont::ArrayHandle<ValueType, StorageTag>& operator=(
|
||||
vtkm::cont::ArrayHandle<ValueType, StorageTag>&& src);
|
||||
vtkm::cont::ArrayHandle<ValueType, StorageTag>&& src) noexcept;
|
||||
|
||||
/// Like a pointer, two \c ArrayHandles are considered equal if they point
|
||||
/// to the same location in memory.
|
||||
@ -674,6 +675,50 @@ VTKM_NEVER_EXPORT VTKM_CONT inline void printSummary_ArrayHandle(
|
||||
}
|
||||
} //namespace vtkm::cont
|
||||
|
||||
//=============================================================================
|
||||
// Specializations of serialization related classes
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
struct TypeString<ArrayHandle<T>>
|
||||
{
|
||||
static VTKM_CONT const std::string& Get()
|
||||
{
|
||||
static std::string name = "AH<" + TypeString<T>::Get() + ">";
|
||||
return name;
|
||||
}
|
||||
};
|
||||
|
||||
namespace internal
|
||||
{
|
||||
|
||||
template <typename T, typename S>
|
||||
void VTKM_CONT ArrayHandleDefaultSerialization(diy::BinaryBuffer& bb,
|
||||
const vtkm::cont::ArrayHandle<T, S>& obj);
|
||||
|
||||
} // internal
|
||||
}
|
||||
} // vtkm::cont
|
||||
|
||||
namespace diy
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
struct Serialization<vtkm::cont::ArrayHandle<T>>
|
||||
{
|
||||
static VTKM_CONT void save(BinaryBuffer& bb, const vtkm::cont::ArrayHandle<T>& obj)
|
||||
{
|
||||
vtkm::cont::internal::ArrayHandleDefaultSerialization(bb, obj);
|
||||
}
|
||||
|
||||
static VTKM_CONT void load(BinaryBuffer& bb, vtkm::cont::ArrayHandle<T>& obj);
|
||||
};
|
||||
|
||||
} // diy
|
||||
|
||||
#include <vtkm/cont/ArrayHandle.hxx>
|
||||
#include <vtkm/cont/internal/ArrayHandleBasicImpl.h>
|
||||
#include <vtkm/cont/internal/ArrayExportMacros.h>
|
||||
|
@ -38,7 +38,7 @@ ArrayHandle<T, S>::ArrayHandle(const ArrayHandle<T, S>& src)
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
ArrayHandle<T, S>::ArrayHandle(ArrayHandle<T, S>&& src)
|
||||
ArrayHandle<T, S>::ArrayHandle(ArrayHandle<T, S>&& src) noexcept
|
||||
: Internals(std::move(src.Internals))
|
||||
{
|
||||
}
|
||||
@ -53,7 +53,7 @@ ArrayHandle<T, S>::ArrayHandle(const typename ArrayHandle<T, S>::StorageType& st
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
ArrayHandle<T, S>::ArrayHandle(typename ArrayHandle<T, S>::StorageType&& storage)
|
||||
ArrayHandle<T, S>::ArrayHandle(typename ArrayHandle<T, S>::StorageType&& storage) noexcept
|
||||
: Internals(new InternalStruct)
|
||||
{
|
||||
this->Internals->ControlArray = std::move(storage);
|
||||
@ -74,7 +74,7 @@ ArrayHandle<T, S>& ArrayHandle<T, S>::operator=(const ArrayHandle<T, S>& src)
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
ArrayHandle<T, S>& ArrayHandle<T, S>::operator=(ArrayHandle<T, S>&& src)
|
||||
ArrayHandle<T, S>& ArrayHandle<T, S>::operator=(ArrayHandle<T, S>&& src) noexcept
|
||||
{
|
||||
this->Internals = std::move(src.Internals);
|
||||
return *this;
|
||||
@ -345,4 +345,49 @@ void ArrayHandle<T, S>::SyncControlArray() const
|
||||
}
|
||||
}
|
||||
}
|
||||
} // vtkm::cont
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
namespace internal
|
||||
{
|
||||
|
||||
template <typename T, typename S>
|
||||
inline void VTKM_CONT ArrayHandleDefaultSerialization(diy::BinaryBuffer& bb,
|
||||
const vtkm::cont::ArrayHandle<T, S>& obj)
|
||||
{
|
||||
vtkm::Id count = obj.GetNumberOfValues();
|
||||
diy::save(bb, count);
|
||||
|
||||
auto portal = obj.GetPortalConstControl();
|
||||
for (vtkm::Id i = 0; i < count; ++i)
|
||||
{
|
||||
diy::save(bb, portal.Get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // vtkm::cont::internal
|
||||
|
||||
namespace diy
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
VTKM_CONT void Serialization<vtkm::cont::ArrayHandle<T>>::load(BinaryBuffer& bb,
|
||||
vtkm::cont::ArrayHandle<T>& obj)
|
||||
{
|
||||
vtkm::Id count = 0;
|
||||
diy::load(bb, count);
|
||||
|
||||
obj.Allocate(count);
|
||||
auto portal = obj.GetPortalControl();
|
||||
for (vtkm::Id i = 0; i < count; ++i)
|
||||
{
|
||||
T val{};
|
||||
diy::load(bb, val);
|
||||
portal.Set(i, val);
|
||||
}
|
||||
}
|
||||
} // diy
|
||||
|
@ -181,15 +181,16 @@ struct ArrayHandleCartesianProductTraits
|
||||
using Superclass = vtkm::cont::ArrayHandle<ValueType, Tag>;
|
||||
};
|
||||
|
||||
template <typename T, typename FirstHandleType, typename SecondHandleType, typename ThirdHandleType>
|
||||
class Storage<T, StorageTagCartesianProduct<FirstHandleType, SecondHandleType, ThirdHandleType>>
|
||||
template <typename FirstHandleType, typename SecondHandleType, typename ThirdHandleType>
|
||||
class Storage<vtkm::Vec<typename FirstHandleType::ValueType, 3>,
|
||||
StorageTagCartesianProduct<FirstHandleType, SecondHandleType, ThirdHandleType>>
|
||||
{
|
||||
VTKM_IS_ARRAY_HANDLE(FirstHandleType);
|
||||
VTKM_IS_ARRAY_HANDLE(SecondHandleType);
|
||||
VTKM_IS_ARRAY_HANDLE(ThirdHandleType);
|
||||
|
||||
public:
|
||||
using ValueType = T;
|
||||
using ValueType = vtkm::Vec<typename FirstHandleType::ValueType, 3>;
|
||||
|
||||
using PortalType =
|
||||
vtkm::exec::internal::ArrayPortalCartesianProduct<ValueType,
|
||||
@ -277,21 +278,22 @@ private:
|
||||
ThirdHandleType ThirdArray;
|
||||
};
|
||||
|
||||
template <typename T,
|
||||
typename FirstHandleType,
|
||||
template <typename FirstHandleType,
|
||||
typename SecondHandleType,
|
||||
typename ThirdHandleType,
|
||||
typename Device>
|
||||
class ArrayTransfer<T,
|
||||
class ArrayTransfer<vtkm::Vec<typename FirstHandleType::ValueType, 3>,
|
||||
StorageTagCartesianProduct<FirstHandleType, SecondHandleType, ThirdHandleType>,
|
||||
Device>
|
||||
{
|
||||
public:
|
||||
using ValueType = vtkm::Vec<typename FirstHandleType::ValueType, 3>;
|
||||
|
||||
private:
|
||||
using StorageTag = StorageTagCartesianProduct<FirstHandleType, SecondHandleType, ThirdHandleType>;
|
||||
using StorageType = vtkm::cont::internal::Storage<T, StorageTag>;
|
||||
using StorageType = vtkm::cont::internal::Storage<ValueType, StorageTag>;
|
||||
|
||||
public:
|
||||
using ValueType = T;
|
||||
|
||||
using PortalControl = typename StorageType::PortalType;
|
||||
using PortalConstControl = typename StorageType::PortalConstType;
|
||||
|
||||
@ -428,4 +430,74 @@ VTKM_CONT
|
||||
}
|
||||
} // namespace vtkm::cont
|
||||
|
||||
//=============================================================================
|
||||
// Specializations of serialization related classes
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
|
||||
template <typename AH1, typename AH2, typename AH3>
|
||||
struct TypeString<vtkm::cont::ArrayHandleCartesianProduct<AH1, AH2, AH3>>
|
||||
{
|
||||
static VTKM_CONT const std::string& Get()
|
||||
{
|
||||
static std::string name = "AH_CartesianProduct<" + TypeString<AH1>::Get() + "," +
|
||||
TypeString<AH2>::Get() + "," + TypeString<AH3>::Get() + ">";
|
||||
return name;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename AH1, typename AH2, typename AH3>
|
||||
struct TypeString<
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<typename AH1::ValueType, 3>,
|
||||
vtkm::cont::internal::StorageTagCartesianProduct<AH1, AH2, AH3>>>
|
||||
: TypeString<vtkm::cont::ArrayHandleCartesianProduct<AH1, AH2, AH3>>
|
||||
{
|
||||
};
|
||||
}
|
||||
} // vtkm::cont
|
||||
|
||||
namespace diy
|
||||
{
|
||||
|
||||
template <typename AH1, typename AH2, typename AH3>
|
||||
struct Serialization<vtkm::cont::ArrayHandleCartesianProduct<AH1, AH2, AH3>>
|
||||
{
|
||||
private:
|
||||
using Type = typename vtkm::cont::ArrayHandleCartesianProduct<AH1, AH2, AH3>;
|
||||
using BaseType = vtkm::cont::ArrayHandle<typename Type::ValueType, typename Type::StorageTag>;
|
||||
|
||||
public:
|
||||
static VTKM_CONT void save(BinaryBuffer& bb, const BaseType& obj)
|
||||
{
|
||||
auto storage = obj.GetStorage();
|
||||
diy::save(bb, storage.GetFirstArray());
|
||||
diy::save(bb, storage.GetSecondArray());
|
||||
diy::save(bb, storage.GetThirdArray());
|
||||
}
|
||||
|
||||
static VTKM_CONT void load(BinaryBuffer& bb, BaseType& obj)
|
||||
{
|
||||
AH1 array1;
|
||||
AH2 array2;
|
||||
AH3 array3;
|
||||
|
||||
diy::load(bb, array1);
|
||||
diy::load(bb, array2);
|
||||
diy::load(bb, array3);
|
||||
|
||||
obj = vtkm::cont::make_ArrayHandleCartesianProduct(array1, array2, array3);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename AH1, typename AH2, typename AH3>
|
||||
struct Serialization<
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<typename AH1::ValueType, 3>,
|
||||
vtkm::cont::internal::StorageTagCartesianProduct<AH1, AH2, AH3>>>
|
||||
: Serialization<vtkm::cont::ArrayHandleCartesianProduct<AH1, AH2, AH3>>
|
||||
{
|
||||
};
|
||||
} // diy
|
||||
|
||||
#endif //vtk_m_cont_ArrayHandleCartesianProduct_h
|
||||
|
@ -103,4 +103,56 @@ VTKM_CONT
|
||||
}
|
||||
} // namespace vtkm::cont
|
||||
|
||||
//=============================================================================
|
||||
// Specializations of serialization related classes
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
|
||||
template <typename T1, typename T2>
|
||||
struct TypeString<vtkm::cont::internal::Cast<T1, T2>>
|
||||
{
|
||||
static VTKM_CONT const std::string& Get()
|
||||
{
|
||||
static std::string name =
|
||||
"AH_Cast_Functor<" + TypeString<T1>::Get() + "," + TypeString<T2>::Get() + ">";
|
||||
return name;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename AH>
|
||||
struct TypeString<vtkm::cont::ArrayHandleCast<T, AH>>
|
||||
: TypeString<
|
||||
vtkm::cont::ArrayHandleTransform<AH,
|
||||
vtkm::cont::internal::Cast<typename AH::ValueType, T>,
|
||||
vtkm::cont::internal::Cast<T, typename AH::ValueType>>>
|
||||
{
|
||||
};
|
||||
}
|
||||
} // namespace vtkm::cont
|
||||
|
||||
namespace diy
|
||||
{
|
||||
|
||||
template <typename T1, typename T2>
|
||||
struct Serialization<vtkm::cont::internal::Cast<T1, T2>>
|
||||
{
|
||||
static VTKM_CONT void save(BinaryBuffer&, const vtkm::cont::internal::Cast<T1, T2>&) {}
|
||||
|
||||
static VTKM_CONT void load(BinaryBuffer&, vtkm::cont::internal::Cast<T1, T2>&) {}
|
||||
};
|
||||
|
||||
template <typename T, typename AH>
|
||||
struct Serialization<vtkm::cont::ArrayHandleCast<T, AH>>
|
||||
: Serialization<
|
||||
vtkm::cont::ArrayHandleTransform<AH,
|
||||
vtkm::cont::internal::Cast<typename AH::ValueType, T>,
|
||||
vtkm::cont::internal::Cast<T, typename AH::ValueType>>>
|
||||
{
|
||||
};
|
||||
|
||||
} // diy
|
||||
|
||||
#endif // vtk_m_cont_ArrayHandleCast_h
|
||||
|
@ -723,4 +723,121 @@ VTKM_CONT ArrayHandleCompositeVector<ArrayTs...> make_ArrayHandleCompositeVector
|
||||
}
|
||||
} // namespace vtkm::cont
|
||||
|
||||
//=============================================================================
|
||||
// Specializations of serialization related classes
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
|
||||
template <typename... AHs>
|
||||
struct TypeString<vtkm::cont::ArrayHandleCompositeVector<AHs...>>
|
||||
{
|
||||
static VTKM_CONT const std::string& Get()
|
||||
{
|
||||
static std::string name =
|
||||
"AH_CompositeVector<" + internal::GetVariadicTypeString(AHs{}...) + ">";
|
||||
return name;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename... AHs>
|
||||
struct TypeString<vtkm::cont::ArrayHandle<
|
||||
typename vtkm::cont::internal::compvec::GetValueType<vtkmstd::tuple<AHs...>>::ValueType,
|
||||
vtkm::cont::internal::StorageTagCompositeVector<vtkmstd::tuple<AHs...>>>>
|
||||
: TypeString<vtkm::cont::ArrayHandleCompositeVector<AHs...>>
|
||||
{
|
||||
};
|
||||
}
|
||||
} // vtkm::cont
|
||||
|
||||
namespace diy
|
||||
{
|
||||
|
||||
namespace internal
|
||||
{
|
||||
|
||||
template <typename Functor, typename TupleType, typename... Args>
|
||||
inline void TupleForEachImpl(TupleType&& t,
|
||||
std::integral_constant<size_t, 0>,
|
||||
Functor&& f,
|
||||
Args&&... args)
|
||||
{
|
||||
f(vtkmstd::get<0>(t), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename Functor, typename TupleType, size_t Index, typename... Args>
|
||||
inline void TupleForEachImpl(TupleType&& t,
|
||||
std::integral_constant<size_t, Index>,
|
||||
Functor&& f,
|
||||
Args&&... args)
|
||||
{
|
||||
TupleForEachImpl(std::forward<TupleType>(t),
|
||||
std::integral_constant<size_t, Index - 1>{},
|
||||
std::forward<Functor>(f),
|
||||
std::forward<Args>(args)...);
|
||||
f(vtkmstd::get<Index>(t), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename Functor, typename TupleType, typename... Args>
|
||||
inline void TupleForEach(TupleType&& t, Functor&& f, Args&&... args)
|
||||
{
|
||||
constexpr auto size = vtkmstd::tuple_size<typename std::decay<TupleType>::type>::value;
|
||||
|
||||
TupleForEachImpl(std::forward<TupleType>(t),
|
||||
std::integral_constant<size_t, size - 1>{},
|
||||
std::forward<Functor>(f),
|
||||
std::forward<Args>(args)...);
|
||||
}
|
||||
} // internal
|
||||
|
||||
template <typename... AHs>
|
||||
struct Serialization<vtkm::cont::ArrayHandleCompositeVector<AHs...>>
|
||||
{
|
||||
private:
|
||||
using Type = typename vtkm::cont::ArrayHandleCompositeVector<AHs...>;
|
||||
using BaseType = vtkm::cont::ArrayHandle<typename Type::ValueType, typename Type::StorageTag>;
|
||||
|
||||
struct SaveFunctor
|
||||
{
|
||||
template <typename AH>
|
||||
void operator()(const AH& ah, BinaryBuffer& bb) const
|
||||
{
|
||||
diy::save(bb, ah);
|
||||
}
|
||||
};
|
||||
|
||||
struct LoadFunctor
|
||||
{
|
||||
template <typename AH>
|
||||
void operator()(AH& ah, BinaryBuffer& bb) const
|
||||
{
|
||||
diy::load(bb, ah);
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
static VTKM_CONT void save(BinaryBuffer& bb, const BaseType& obj)
|
||||
{
|
||||
internal::TupleForEach(obj.GetStorage().GetArrayTuple(), SaveFunctor{}, bb);
|
||||
}
|
||||
|
||||
static VTKM_CONT void load(BinaryBuffer& bb, BaseType& obj)
|
||||
{
|
||||
vtkmstd::tuple<AHs...> arrayTuple;
|
||||
internal::TupleForEach(arrayTuple, LoadFunctor{}, bb);
|
||||
obj = BaseType(typename BaseType::StorageType(arrayTuple));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename... AHs>
|
||||
struct Serialization<vtkm::cont::ArrayHandle<
|
||||
typename vtkm::cont::internal::compvec::GetValueType<vtkmstd::tuple<AHs...>>::ValueType,
|
||||
vtkm::cont::internal::StorageTagCompositeVector<vtkmstd::tuple<AHs...>>>>
|
||||
: Serialization<vtkm::cont::ArrayHandleCompositeVector<AHs...>>
|
||||
{
|
||||
};
|
||||
} // diy
|
||||
|
||||
#endif //vtk_m_ArrayHandleCompositeVector_h
|
||||
|
@ -324,4 +324,69 @@ VTKM_CONT ArrayHandleConcatenate<ArrayHandleType1, ArrayHandleType2> make_ArrayH
|
||||
}
|
||||
} // namespace vtkm::cont
|
||||
|
||||
//=============================================================================
|
||||
// Specializations of serialization related classes
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
|
||||
template <typename AH1, typename AH2>
|
||||
struct TypeString<vtkm::cont::ArrayHandleConcatenate<AH1, AH2>>
|
||||
{
|
||||
static VTKM_CONT const std::string& Get()
|
||||
{
|
||||
static std::string name =
|
||||
"AH_Concatenate<" + TypeString<AH1>::Get() + "," + TypeString<AH2>::Get() + ">";
|
||||
return name;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename AH1, typename AH2>
|
||||
struct TypeString<
|
||||
vtkm::cont::ArrayHandle<typename AH1::ValueType, vtkm::cont::StorageTagConcatenate<AH1, AH2>>>
|
||||
: TypeString<vtkm::cont::ArrayHandleConcatenate<AH1, AH2>>
|
||||
{
|
||||
};
|
||||
}
|
||||
} // vtkm::cont
|
||||
|
||||
namespace diy
|
||||
{
|
||||
|
||||
template <typename AH1, typename AH2>
|
||||
struct Serialization<vtkm::cont::ArrayHandleConcatenate<AH1, AH2>>
|
||||
{
|
||||
private:
|
||||
using Type = vtkm::cont::ArrayHandleConcatenate<AH1, AH2>;
|
||||
using BaseType = vtkm::cont::ArrayHandle<typename Type::ValueType, typename Type::StorageTag>;
|
||||
|
||||
public:
|
||||
static VTKM_CONT void save(BinaryBuffer& bb, const BaseType& obj)
|
||||
{
|
||||
auto storage = obj.GetStorage();
|
||||
diy::save(bb, storage.GetArray1());
|
||||
diy::save(bb, storage.GetArray2());
|
||||
}
|
||||
|
||||
static VTKM_CONT void load(BinaryBuffer& bb, BaseType& obj)
|
||||
{
|
||||
AH1 array1;
|
||||
AH2 array2;
|
||||
|
||||
diy::load(bb, array1);
|
||||
diy::load(bb, array2);
|
||||
|
||||
obj = vtkm::cont::make_ArrayHandleConcatenate(array1, array2);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename AH1, typename AH2>
|
||||
struct Serialization<
|
||||
vtkm::cont::ArrayHandle<typename AH1::ValueType, vtkm::cont::StorageTagConcatenate<AH1, AH2>>>
|
||||
: Serialization<vtkm::cont::ArrayHandleConcatenate<AH1, AH2>>
|
||||
{
|
||||
};
|
||||
} // diy
|
||||
|
||||
#endif //vtk_m_cont_ArrayHandleConcatenate_h
|
||||
|
@ -85,4 +85,40 @@ vtkm::cont::ArrayHandleConstant<T> make_ArrayHandleConstant(T value, vtkm::Id nu
|
||||
}
|
||||
} // vtkm::cont
|
||||
|
||||
//=============================================================================
|
||||
// Specializations of serialization related classes
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
struct TypeString<vtkm::cont::detail::ConstantFunctor<T>>
|
||||
{
|
||||
static VTKM_CONT const std::string& Get()
|
||||
{
|
||||
static std::string name = "AH_ConstantFunctor<" + TypeString<T>::Get() + ">";
|
||||
return name;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct TypeString<vtkm::cont::ArrayHandleConstant<T>>
|
||||
: TypeString<vtkm::cont::ArrayHandleImplicit<vtkm::cont::detail::ConstantFunctor<T>>>
|
||||
{
|
||||
};
|
||||
}
|
||||
} // vtkm::cont
|
||||
|
||||
namespace diy
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
struct Serialization<vtkm::cont::ArrayHandleConstant<T>>
|
||||
: Serialization<vtkm::cont::ArrayHandleImplicit<vtkm::cont::detail::ConstantFunctor<T>>>
|
||||
{
|
||||
};
|
||||
|
||||
} // diy
|
||||
|
||||
#endif //vtk_m_cont_ArrayHandleConstant_h
|
||||
|
@ -76,6 +76,12 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
ValueType GetStart() const { return this->Start; }
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
ValueType GetStep() const { return this->Step; }
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
vtkm::Id GetNumberOfValues() const { return this->NumberOfValues; }
|
||||
|
||||
@ -142,4 +148,70 @@ make_ArrayHandleCounting(CountingValueType start, CountingValueType step, vtkm::
|
||||
}
|
||||
} // namespace vtkm::cont
|
||||
|
||||
//=============================================================================
|
||||
// Specializations of serialization related classes
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
struct TypeString<vtkm::cont::ArrayHandleCounting<T>>
|
||||
{
|
||||
static VTKM_CONT const std::string& Get()
|
||||
{
|
||||
static std::string name = "AH_Counting<" + TypeString<T>::Get() + ">";
|
||||
return name;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct TypeString<
|
||||
vtkm::cont::ArrayHandle<T, typename vtkm::cont::ArrayHandleCounting<T>::StorageTag>>
|
||||
: TypeString<vtkm::cont::ArrayHandleCounting<T>>
|
||||
{
|
||||
};
|
||||
}
|
||||
} // vtkm::cont
|
||||
|
||||
namespace diy
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
struct Serialization<vtkm::cont::ArrayHandleCounting<T>>
|
||||
{
|
||||
private:
|
||||
using Type = vtkm::cont::ArrayHandleCounting<T>;
|
||||
using BaseType = vtkm::cont::ArrayHandle<typename Type::ValueType, typename Type::StorageTag>;
|
||||
|
||||
public:
|
||||
static VTKM_CONT void save(BinaryBuffer& bb, const BaseType& obj)
|
||||
{
|
||||
auto portal = obj.GetPortalConstControl();
|
||||
diy::save(bb, portal.GetStart());
|
||||
diy::save(bb, portal.GetStep());
|
||||
diy::save(bb, portal.GetNumberOfValues());
|
||||
}
|
||||
|
||||
static VTKM_CONT void load(BinaryBuffer& bb, BaseType& obj)
|
||||
{
|
||||
T start{}, step{};
|
||||
vtkm::Id count = 0;
|
||||
|
||||
diy::load(bb, start);
|
||||
diy::load(bb, step);
|
||||
diy::load(bb, count);
|
||||
|
||||
obj = vtkm::cont::make_ArrayHandleCounting(start, step, count);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct Serialization<
|
||||
vtkm::cont::ArrayHandle<T, typename vtkm::cont::ArrayHandleCounting<T>::StorageTag>>
|
||||
: Serialization<vtkm::cont::ArrayHandleCounting<T>>
|
||||
{
|
||||
};
|
||||
} // diy
|
||||
|
||||
#endif //vtk_m_cont_ArrayHandleCounting_h
|
||||
|
@ -310,4 +310,69 @@ VTKM_CONT ArrayHandleExtractComponent<ArrayHandleType> make_ArrayHandleExtractCo
|
||||
}
|
||||
} // namespace vtkm::cont
|
||||
|
||||
//=============================================================================
|
||||
// Specializations of serialization related classes
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
|
||||
template <typename AH>
|
||||
struct TypeString<vtkm::cont::ArrayHandleExtractComponent<AH>>
|
||||
{
|
||||
static VTKM_CONT const std::string& Get()
|
||||
{
|
||||
static std::string name = "AH_ExtractComponent<" + TypeString<AH>::Get() + ">";
|
||||
return name;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename AH>
|
||||
struct TypeString<
|
||||
vtkm::cont::ArrayHandle<typename vtkm::VecTraits<typename AH::ValueType>::ComponentType,
|
||||
vtkm::cont::StorageTagExtractComponent<AH>>>
|
||||
: TypeString<vtkm::cont::ArrayHandleExtractComponent<AH>>
|
||||
{
|
||||
};
|
||||
}
|
||||
} // vtkm::cont
|
||||
|
||||
namespace diy
|
||||
{
|
||||
|
||||
template <typename AH>
|
||||
struct Serialization<vtkm::cont::ArrayHandleExtractComponent<AH>>
|
||||
{
|
||||
private:
|
||||
using Type = vtkm::cont::ArrayHandleExtractComponent<AH>;
|
||||
using BaseType = vtkm::cont::ArrayHandle<typename Type::ValueType, typename Type::StorageTag>;
|
||||
|
||||
public:
|
||||
static VTKM_CONT void save(BinaryBuffer& bb, const BaseType& obj)
|
||||
{
|
||||
auto storage = obj.GetStorage();
|
||||
diy::save(bb, storage.GetComponent());
|
||||
diy::save(bb, storage.GetArray());
|
||||
}
|
||||
|
||||
static VTKM_CONT void load(BinaryBuffer& bb, BaseType& obj)
|
||||
{
|
||||
vtkm::IdComponent component = 0;
|
||||
AH array;
|
||||
diy::load(bb, component);
|
||||
diy::load(bb, array);
|
||||
|
||||
obj = vtkm::cont::make_ArrayHandleExtractComponent(array, component);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename AH>
|
||||
struct Serialization<
|
||||
vtkm::cont::ArrayHandle<typename vtkm::VecTraits<typename AH::ValueType>::ComponentType,
|
||||
vtkm::cont::StorageTagExtractComponent<AH>>>
|
||||
: Serialization<vtkm::cont::ArrayHandleExtractComponent<AH>>
|
||||
{
|
||||
};
|
||||
} // diy
|
||||
|
||||
#endif // vtk_m_cont_ArrayHandleExtractComponent_h
|
||||
|
@ -366,4 +366,66 @@ VTKM_CONT vtkm::cont::ArrayHandleGroupVec<ArrayHandleType, NUM_COMPONENTS> make_
|
||||
}
|
||||
} // namespace vtkm::cont
|
||||
|
||||
//=============================================================================
|
||||
// Specializations of serialization related classes
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
|
||||
template <typename AH, vtkm::IdComponent NUM_COMPS>
|
||||
struct TypeString<vtkm::cont::ArrayHandleGroupVec<AH, NUM_COMPS>>
|
||||
{
|
||||
static VTKM_CONT const std::string& Get()
|
||||
{
|
||||
static std::string name =
|
||||
"AH_GroupVec<" + TypeString<AH>::Get() + "," + std::to_string(NUM_COMPS) + ">";
|
||||
return name;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename AH, vtkm::IdComponent NUM_COMPS>
|
||||
struct TypeString<vtkm::cont::ArrayHandle<vtkm::Vec<typename AH::ValueType, NUM_COMPS>,
|
||||
vtkm::cont::internal::StorageTagGroupVec<AH, NUM_COMPS>>>
|
||||
: TypeString<vtkm::cont::ArrayHandleGroupVec<AH, NUM_COMPS>>
|
||||
{
|
||||
};
|
||||
}
|
||||
} // vtkm::cont
|
||||
|
||||
namespace diy
|
||||
{
|
||||
|
||||
template <typename AH, vtkm::IdComponent NUM_COMPS>
|
||||
struct Serialization<vtkm::cont::ArrayHandleGroupVec<AH, NUM_COMPS>>
|
||||
{
|
||||
private:
|
||||
using Type = vtkm::cont::ArrayHandleGroupVec<AH, NUM_COMPS>;
|
||||
using BaseType = vtkm::cont::ArrayHandle<typename Type::ValueType, typename Type::StorageTag>;
|
||||
|
||||
public:
|
||||
static VTKM_CONT void save(BinaryBuffer& bb, const BaseType& obj)
|
||||
{
|
||||
diy::save(bb, obj.GetStorage().GetSourceArray());
|
||||
}
|
||||
|
||||
static VTKM_CONT void load(BinaryBuffer& bb, BaseType& obj)
|
||||
{
|
||||
AH array;
|
||||
diy::load(bb, array);
|
||||
|
||||
obj = vtkm::cont::make_ArrayHandleGroupVec<NUM_COMPS>(array);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename AH, vtkm::IdComponent NUM_COMPS>
|
||||
struct Serialization<
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<typename AH::ValueType, NUM_COMPS>,
|
||||
vtkm::cont::internal::StorageTagGroupVec<AH, NUM_COMPS>>>
|
||||
: Serialization<vtkm::cont::ArrayHandleGroupVec<AH, NUM_COMPS>>
|
||||
{
|
||||
};
|
||||
|
||||
} // diy
|
||||
|
||||
#endif //vtk_m_cont_ArrayHandleGroupVec_h
|
||||
|
@ -613,4 +613,70 @@ VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Id> ConvertNumComponentsToOffsets(
|
||||
}
|
||||
} // namespace vtkm::cont
|
||||
|
||||
//=============================================================================
|
||||
// Specializations of serialization related classes
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
|
||||
template <typename SAH, typename OAH>
|
||||
struct TypeString<vtkm::cont::ArrayHandleGroupVecVariable<SAH, OAH>>
|
||||
{
|
||||
static VTKM_CONT const std::string& Get()
|
||||
{
|
||||
static std::string name =
|
||||
"AH_GroupVecVariable<" + TypeString<SAH>::Get() + "," + TypeString<OAH>::Get() + ">";
|
||||
return name;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename SAH, typename OAH>
|
||||
struct TypeString<
|
||||
vtkm::cont::ArrayHandle<vtkm::VecFromPortal<typename SAH::PortalControl>,
|
||||
vtkm::cont::internal::StorageTagGroupVecVariable<SAH, OAH>>>
|
||||
: TypeString<vtkm::cont::ArrayHandleGroupVecVariable<SAH, OAH>>
|
||||
{
|
||||
};
|
||||
}
|
||||
} // vtkm::cont
|
||||
|
||||
namespace diy
|
||||
{
|
||||
|
||||
template <typename SAH, typename OAH>
|
||||
struct Serialization<vtkm::cont::ArrayHandleGroupVecVariable<SAH, OAH>>
|
||||
{
|
||||
private:
|
||||
using Type = vtkm::cont::ArrayHandleGroupVecVariable<SAH, OAH>;
|
||||
using BaseType = vtkm::cont::ArrayHandle<typename Type::ValueType, typename Type::StorageTag>;
|
||||
|
||||
public:
|
||||
static VTKM_CONT void save(BinaryBuffer& bb, const BaseType& obj)
|
||||
{
|
||||
diy::save(bb, obj.GetStorage().GetSourceArray());
|
||||
diy::save(bb, obj.GetStorage().GetOffsetsArray());
|
||||
}
|
||||
|
||||
static VTKM_CONT void load(BinaryBuffer& bb, BaseType& obj)
|
||||
{
|
||||
SAH src;
|
||||
OAH off;
|
||||
|
||||
diy::load(bb, src);
|
||||
diy::load(bb, off);
|
||||
|
||||
obj = vtkm::cont::make_ArrayHandleGroupVecVariable(src, off);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename SAH, typename OAH>
|
||||
struct Serialization<
|
||||
vtkm::cont::ArrayHandle<vtkm::VecFromPortal<typename SAH::PortalControl>,
|
||||
vtkm::cont::internal::StorageTagGroupVecVariable<SAH, OAH>>>
|
||||
: Serialization<vtkm::cont::ArrayHandleGroupVecVariable<SAH, OAH>>
|
||||
{
|
||||
};
|
||||
} // diy
|
||||
|
||||
#endif //vtk_m_cont_ArrayHandleGroupVecVariable_h
|
||||
|
@ -76,6 +76,9 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
const FunctorType& GetFunctor() const { return this->Functor; }
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
vtkm::Id GetNumberOfValues() const { return this->NumberOfValues; }
|
||||
|
||||
@ -142,4 +145,70 @@ VTKM_CONT vtkm::cont::ArrayHandleImplicit<FunctorType> make_ArrayHandleImplicit(
|
||||
}
|
||||
} // namespace vtkm::cont
|
||||
|
||||
//=============================================================================
|
||||
// Specializations of serialization related classes
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
|
||||
template <typename Functor>
|
||||
struct TypeString<vtkm::cont::ArrayHandleImplicit<Functor>>
|
||||
{
|
||||
static VTKM_CONT const std::string& Get()
|
||||
{
|
||||
static std::string name = "AH_Implicit<" + TypeString<Functor>::Get() + ">";
|
||||
return name;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Functor>
|
||||
struct TypeString<vtkm::cont::ArrayHandle<
|
||||
typename vtkm::cont::detail::ArrayHandleImplicitTraits<Functor>::ValueType,
|
||||
vtkm::cont::StorageTagImplicit<vtkm::cont::detail::ArrayPortalImplicit<Functor>>>>
|
||||
: TypeString<vtkm::cont::ArrayHandleImplicit<Functor>>
|
||||
{
|
||||
};
|
||||
}
|
||||
} // vtkm::cont
|
||||
|
||||
namespace diy
|
||||
{
|
||||
|
||||
template <typename Functor>
|
||||
struct Serialization<vtkm::cont::ArrayHandleImplicit<Functor>>
|
||||
{
|
||||
private:
|
||||
using Type = vtkm::cont::ArrayHandleImplicit<Functor>;
|
||||
using BaseType = vtkm::cont::ArrayHandle<typename Type::ValueType, typename Type::StorageTag>;
|
||||
|
||||
public:
|
||||
static VTKM_CONT void save(BinaryBuffer& bb, const BaseType& obj)
|
||||
{
|
||||
diy::save(bb, obj.GetNumberOfValues());
|
||||
diy::save(bb, obj.GetPortalConstControl().GetFunctor());
|
||||
}
|
||||
|
||||
static VTKM_CONT void load(BinaryBuffer& bb, BaseType& obj)
|
||||
{
|
||||
vtkm::Id count = 0;
|
||||
diy::load(bb, count);
|
||||
|
||||
Functor functor;
|
||||
diy::load(bb, functor);
|
||||
|
||||
obj = vtkm::cont::make_ArrayHandleImplicit(functor, count);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Functor>
|
||||
struct Serialization<vtkm::cont::ArrayHandle<
|
||||
typename vtkm::cont::detail::ArrayHandleImplicitTraits<Functor>::ValueType,
|
||||
vtkm::cont::StorageTagImplicit<vtkm::cont::detail::ArrayPortalImplicit<Functor>>>>
|
||||
: Serialization<vtkm::cont::ArrayHandleImplicit<Functor>>
|
||||
{
|
||||
};
|
||||
|
||||
} // diy
|
||||
|
||||
#endif //vtk_m_cont_ArrayHandleImplicit_h
|
||||
|
@ -61,4 +61,45 @@ public:
|
||||
}
|
||||
} // namespace vtkm::cont
|
||||
|
||||
//=============================================================================
|
||||
// Specializations of serialization related classes
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
|
||||
template <>
|
||||
struct TypeString<vtkm::cont::detail::IndexFunctor>
|
||||
{
|
||||
static VTKM_CONT const std::string Get() { return "AH_IndexFunctor"; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct TypeString<vtkm::cont::ArrayHandleIndex>
|
||||
: TypeString<vtkm::cont::ArrayHandleImplicit<vtkm::cont::detail::IndexFunctor>>
|
||||
{
|
||||
};
|
||||
}
|
||||
} // vtkm::cont
|
||||
|
||||
namespace diy
|
||||
{
|
||||
|
||||
template <>
|
||||
struct Serialization<vtkm::cont::detail::IndexFunctor>
|
||||
{
|
||||
static VTKM_CONT void save(BinaryBuffer&, const vtkm::cont::detail::IndexFunctor&) {}
|
||||
|
||||
static VTKM_CONT void load(BinaryBuffer&, vtkm::cont::detail::IndexFunctor&) {}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Serialization<vtkm::cont::ArrayHandleIndex>
|
||||
: Serialization<vtkm::cont::ArrayHandleImplicit<vtkm::cont::detail::IndexFunctor>>
|
||||
{
|
||||
};
|
||||
|
||||
} // diy
|
||||
|
||||
#endif //vtk_m_cont_ArrayHandleIndex_h
|
||||
|
@ -372,4 +372,72 @@ make_ArrayHandlePermutation(IndexArrayHandleType indexArray, ValueArrayHandleTyp
|
||||
}
|
||||
} // namespace vtkm::cont
|
||||
|
||||
//=============================================================================
|
||||
// Specializations of serialization related classes
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
|
||||
template <typename IdxAH, typename ValAH>
|
||||
struct TypeString<vtkm::cont::ArrayHandlePermutation<IdxAH, ValAH>>
|
||||
{
|
||||
static VTKM_CONT const std::string& Get()
|
||||
{
|
||||
static std::string name =
|
||||
"AH_Permutation<" + TypeString<IdxAH>::Get() + "," + TypeString<ValAH>::Get() + ">";
|
||||
return name;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename IdxAH, typename ValAH>
|
||||
struct TypeString<
|
||||
vtkm::cont::ArrayHandle<typename ValAH::ValueType,
|
||||
vtkm::cont::internal::StorageTagPermutation<IdxAH, ValAH>>>
|
||||
: TypeString<vtkm::cont::ArrayHandlePermutation<IdxAH, ValAH>>
|
||||
{
|
||||
};
|
||||
}
|
||||
} // vtkm::cont
|
||||
|
||||
namespace diy
|
||||
{
|
||||
|
||||
template <typename IdxAH, typename ValAH>
|
||||
struct Serialization<vtkm::cont::ArrayHandlePermutation<IdxAH, ValAH>>
|
||||
{
|
||||
private:
|
||||
using Type = vtkm::cont::ArrayHandlePermutation<IdxAH, ValAH>;
|
||||
using BaseType = vtkm::cont::ArrayHandle<typename Type::ValueType, typename Type::StorageTag>;
|
||||
|
||||
public:
|
||||
static VTKM_CONT void save(BinaryBuffer& bb, const BaseType& obj)
|
||||
{
|
||||
auto storage = obj.GetStorage();
|
||||
diy::save(bb, storage.GetIndexArray());
|
||||
diy::save(bb, storage.GetValueArray());
|
||||
}
|
||||
|
||||
static VTKM_CONT void load(BinaryBuffer& bb, BaseType& obj)
|
||||
{
|
||||
IdxAH indices;
|
||||
ValAH values;
|
||||
|
||||
diy::load(bb, indices);
|
||||
diy::load(bb, values);
|
||||
|
||||
obj = vtkm::cont::make_ArrayHandlePermutation(indices, values);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename IdxAH, typename ValAH>
|
||||
struct Serialization<
|
||||
vtkm::cont::ArrayHandle<typename ValAH::ValueType,
|
||||
vtkm::cont::internal::StorageTagPermutation<IdxAH, ValAH>>>
|
||||
: Serialization<vtkm::cont::ArrayHandlePermutation<IdxAH, ValAH>>
|
||||
{
|
||||
};
|
||||
|
||||
} // diy
|
||||
|
||||
#endif //vtk_m_cont_ArrayHandlePermutation_h
|
||||
|
@ -243,4 +243,63 @@ VTKM_CONT ArrayHandleReverse<HandleType> make_ArrayHandleReverse(const HandleTyp
|
||||
}
|
||||
} // namespace vtkm::cont
|
||||
|
||||
//=============================================================================
|
||||
// Specializations of serialization related classes
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
|
||||
template <typename AH>
|
||||
struct TypeString<vtkm::cont::ArrayHandleReverse<AH>>
|
||||
{
|
||||
static VTKM_CONT const std::string& Get()
|
||||
{
|
||||
static std::string name = "AH_Reverse<" + TypeString<AH>::Get() + ">";
|
||||
return name;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename AH>
|
||||
struct TypeString<
|
||||
vtkm::cont::ArrayHandle<typename AH::ValueType, vtkm::cont::StorageTagReverse<AH>>>
|
||||
: TypeString<vtkm::cont::ArrayHandleReverse<AH>>
|
||||
{
|
||||
};
|
||||
}
|
||||
} // vtkm::cont
|
||||
|
||||
namespace diy
|
||||
{
|
||||
|
||||
template <typename AH>
|
||||
struct Serialization<vtkm::cont::ArrayHandleReverse<AH>>
|
||||
{
|
||||
private:
|
||||
using Type = vtkm::cont::ArrayHandleReverse<AH>;
|
||||
using BaseType = vtkm::cont::ArrayHandle<typename Type::ValueType, typename Type::StorageTag>;
|
||||
|
||||
public:
|
||||
static VTKM_CONT void save(BinaryBuffer& bb, const BaseType& obj)
|
||||
{
|
||||
diy::save(bb, obj.GetStorage().GetArray());
|
||||
}
|
||||
|
||||
static VTKM_CONT void load(BinaryBuffer& bb, BaseType& obj)
|
||||
{
|
||||
AH array;
|
||||
diy::load(bb, array);
|
||||
obj = vtkm::cont::make_ArrayHandleReverse(array);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename AH>
|
||||
struct Serialization<
|
||||
vtkm::cont::ArrayHandle<typename AH::ValueType, vtkm::cont::StorageTagReverse<AH>>>
|
||||
: Serialization<vtkm::cont::ArrayHandleReverse<AH>>
|
||||
{
|
||||
};
|
||||
|
||||
} // diy
|
||||
|
||||
#endif // vtk_m_cont_ArrayHandleReverse_h
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user