mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-16 17:22:55 +00:00
Merge branch 'master' into tangle_source
This commit is contained in:
commit
05b6792500
4
.gitattributes
vendored
4
.gitattributes
vendored
@ -6,8 +6,8 @@
|
||||
*.hxx our-c-style
|
||||
*.cu our-c-style
|
||||
|
||||
data/* filter=lfs diff=lfs merge=lfs -text
|
||||
/**/data/* filter=lfs diff=lfs merge=lfs -text
|
||||
data/** filter=lfs diff=lfs merge=lfs -text
|
||||
/**/data/** filter=lfs diff=lfs merge=lfs -text
|
||||
|
||||
*.cmake whitespace=tab-in-indent
|
||||
*.md whitespace=tab-in-indent conflict-marker-size=79 -whitespace
|
||||
|
@ -87,10 +87,20 @@ endif()
|
||||
|
||||
# Load the library exports, but only if not compiling VTK-m itself
|
||||
set_and_check(VTKm_CONFIG_DIR "@PACKAGE_VTKm_INSTALL_CONFIG_DIR@")
|
||||
set(VTKM_FROM_INSTALL_DIR FALSE)
|
||||
if(NOT "${CMAKE_BINARY_DIR}" STREQUAL "@VTKm_BINARY_DIR@")
|
||||
set(VTKM_FROM_INSTALL_DIR TRUE)
|
||||
include(${VTKm_CONFIG_DIR}/VTKmTargets.cmake)
|
||||
endif()
|
||||
|
||||
# Once we can require CMake 3.15 for all cuda builds we can
|
||||
# replace this with setting `cuda_architecture_flags` as part of the
|
||||
# EXPORT_PROPERTIES of the vtkm_cuda target
|
||||
if(VTKm_ENABLE_CUDA AND VTKM_FROM_INSTALL_DIR)
|
||||
set_target_properties(vtkm::cuda PROPERTIES cuda_architecture_flags "@VTKm_CUDA_Architecture_Flags@")
|
||||
set_target_properties(vtkm::cuda PROPERTIES requires_static_builds TRUE)
|
||||
endif()
|
||||
|
||||
# VTKm requires some CMake Find modules not included with CMake, so
|
||||
# include the CMake modules distributed with VTKm.
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${VTKm_CMAKE_MODULE_PATH})
|
||||
|
@ -121,14 +121,18 @@ if(VTKm_ENABLE_CUDA)
|
||||
set_target_properties(vtkm_cuda PROPERTIES EXPORT_NAME vtkm::cuda)
|
||||
|
||||
install(TARGETS vtkm_cuda EXPORT ${VTKm_EXPORT_NAME})
|
||||
# Reserve `INTERFACE_REQUIRES_STATIC_BUILDS` to potential work around issues
|
||||
# Reserve `requires_static_builds` to potential work around issues
|
||||
# where VTK-m doesn't work when building shared as virtual functions fail
|
||||
# inside device code. We don't want to force BUILD_SHARED_LIBS to a specific
|
||||
# value as that could impact other projects that embed VTK-m. Instead what
|
||||
# we do is make sure that libraries built by vtkm_library() are static
|
||||
# if they use CUDA
|
||||
#
|
||||
# This needs to be lower-case for the property to be properly exported
|
||||
# CMake 3.15 we can add `requires_static_builds` to the EXPORT_PROPERTIES
|
||||
# target property to have this automatically exported for us
|
||||
set_target_properties(vtkm_cuda PROPERTIES
|
||||
INTERFACE_REQUIRES_STATIC_BUILDS TRUE
|
||||
requires_static_builds TRUE
|
||||
)
|
||||
|
||||
|
||||
@ -247,7 +251,11 @@ if(VTKm_ENABLE_CUDA)
|
||||
string(REPLACE ";" " " arch_flags "${arch_flags}")
|
||||
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} ${arch_flags}")
|
||||
|
||||
set_target_properties(vtkm_cuda PROPERTIES INTERFACE_CUDA_Architecture_Flags "${arch_flags}")
|
||||
# This needs to be lower-case for the property to be properly exported
|
||||
# CMake 3.15 we can add `cuda_architecture_flags` to the EXPORT_PROPERTIES
|
||||
# target property to have this automatically exported for us
|
||||
set_target_properties(vtkm_cuda PROPERTIES cuda_architecture_flags "${arch_flags}")
|
||||
set(VTKm_CUDA_Architecture_Flags "${arch_flags}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
@ -130,7 +130,7 @@ function(vtkm_get_cuda_flags settings_var)
|
||||
if(TARGET vtkm::cuda)
|
||||
get_property(arch_flags
|
||||
TARGET vtkm::cuda
|
||||
PROPERTY INTERFACE_CUDA_Architecture_Flags)
|
||||
PROPERTY cuda_architecture_flags)
|
||||
set(${settings_var} "${${settings_var}} ${arch_flags}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
@ -166,7 +166,8 @@ endfunction()
|
||||
# need to be marked as going to a special compiler for certain device adapters
|
||||
# such as CUDA.
|
||||
#
|
||||
# EXTENDS_VTKM: Some programming models have restrictions on how types can be extended.
|
||||
# EXTENDS_VTKM: Some programming models have restrictions on how types can be used,
|
||||
# passed across library boundaries, and derived from.
|
||||
# For example CUDA doesn't allow device side calls across dynamic library boundaries,
|
||||
# and requires all polymorphic classes to be reachable at dynamic library/executable
|
||||
# link time.
|
||||
@ -177,10 +178,13 @@ endfunction()
|
||||
# Executable: do nothing, zero restrictions
|
||||
# Static library: do nothing, zero restrictions
|
||||
# Dynamic library:
|
||||
# -> Wanting to extend VTK-m and provide these types to consumers. This
|
||||
# is supported when CUDA isn't enabled. Otherwise we need to ERROR!
|
||||
# -> Wanting to use VTK-m as implementation detail, doesn't expose VTK-m
|
||||
# types to consumers. This is supported no matter if CUDA is enabled.
|
||||
# -> Wanting to extend VTK-m and provide these types to consumers.
|
||||
# This is only supported when CUDA isn't enabled. Otherwise we need to ERROR!
|
||||
# -> Wanting to pass known VTK-m types across library boundaries for others
|
||||
# to use in filters/worklets.
|
||||
# This is only supported when CUDA isn't enabled. Otherwise we need to ERROR!
|
||||
#
|
||||
# For most consumers they can ignore the `EXTENDS_VTKM` property as the default
|
||||
# will be correct.
|
||||
@ -203,9 +207,9 @@ function(vtkm_add_target_information uses_vtkm_target)
|
||||
# dynamic library boundaries.
|
||||
if(TARGET vtkm::cuda)
|
||||
get_target_property(lib_type ${uses_vtkm_target} TYPE)
|
||||
get_target_property(requires_static vtkm::cuda INTERFACE_REQUIRES_STATIC_BUILDS)
|
||||
get_target_property(requires_static vtkm::cuda requires_static_builds)
|
||||
|
||||
if(requires_static AND ${lib_type} STREQUAL "SHARED_LIBRARY")
|
||||
if(requires_static AND ${lib_type} STREQUAL "SHARED_LIBRARY" AND VTKm_TI_EXTENDS_VTKM)
|
||||
#We provide different error messages based on if we are building VTK-m
|
||||
#or being called by a consumer of VTK-m. We use PROJECT_NAME so that we
|
||||
#produce the correct error message when VTK-m is a subdirectory include
|
||||
@ -277,6 +281,7 @@ function(vtkm_library)
|
||||
${VTKm_LIB_DEVICE_SOURCES}
|
||||
)
|
||||
vtkm_add_target_information(${lib_name}
|
||||
EXTENDS_VTKM
|
||||
DEVICE_SOURCES ${VTKm_LIB_DEVICE_SOURCES}
|
||||
)
|
||||
if(NOT VTKm_USE_DEFAULT_SYMBOL_VISIBILITY)
|
||||
|
@ -56,7 +56,7 @@ function(vtkm_unit_tests)
|
||||
set(test_prog)
|
||||
|
||||
|
||||
set(per_device_command_line_arguments "")
|
||||
set(per_device_command_line_arguments "NONE")
|
||||
set(per_device_suffix "")
|
||||
set(per_device_timeout 180)
|
||||
set(per_device_serial FALSE)
|
||||
@ -65,7 +65,6 @@ function(vtkm_unit_tests)
|
||||
if(enable_all_backends)
|
||||
set(per_device_command_line_arguments --device=serial)
|
||||
set(per_device_suffix "SERIAL")
|
||||
|
||||
if (VTKm_ENABLE_CUDA)
|
||||
list(APPEND per_device_command_line_arguments --device=cuda)
|
||||
list(APPEND per_device_suffix "CUDA")
|
||||
@ -131,8 +130,14 @@ function(vtkm_unit_tests)
|
||||
|
||||
target_link_libraries(${test_prog} PRIVATE vtkm_cont ${VTKm_UT_LIBRARIES})
|
||||
|
||||
foreach(index RANGE per_device_command_line_arguments)
|
||||
if(per_device_command_line_arguments STREQUAL "")
|
||||
list(LENGTH per_device_command_line_arguments number_of_devices)
|
||||
foreach(index RANGE ${number_of_devices})
|
||||
if(index EQUAL number_of_devices)
|
||||
#RANGE is inclusive on both sides, and we want it to be
|
||||
#exclusive on the end ( e.g. for(i=0; i < n; ++i))
|
||||
break()
|
||||
endif()
|
||||
if(per_device_command_line_arguments STREQUAL "NONE")
|
||||
set(device_command_line_argument ${per_device_command_line_arguments})
|
||||
set(upper_backend ${per_device_suffix})
|
||||
set(timeout ${per_device_timeout})
|
||||
|
@ -317,7 +317,7 @@ public:
|
||||
vtkm::Id idx = i % this->ArraySize;
|
||||
ValueType val = static_cast<ValueType>(i);
|
||||
// Get the old val with a no-op
|
||||
ValueType oldVal = this->Portal.Add(idx, static_cast<ValueType>(0));
|
||||
ValueType oldVal = this->Portal.Get(idx);
|
||||
ValueType assumed = static_cast<ValueType>(0);
|
||||
do
|
||||
{
|
||||
@ -445,7 +445,7 @@ public:
|
||||
vtkm::Id idx = (i / this->Stride + this->Stride * (i % this->Stride)) % this->ArraySize;
|
||||
ValueType val = static_cast<ValueType>(i);
|
||||
// Get the old val with a no-op
|
||||
ValueType oldVal = this->Portal.Add(idx, static_cast<ValueType>(0));
|
||||
ValueType oldVal = this->Portal.Get(idx);
|
||||
ValueType assumed = static_cast<ValueType>(0);
|
||||
do
|
||||
{
|
||||
|
3
data/magField.vtk
Normal file
3
data/magField.vtk
Normal file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:b947d66dbae99a1ebb392b200a9ea0d380cfccb7fcb3a3739615d0dde558d2f1
|
||||
size 238166
|
3
data/temporal_datasets/DoubleGyre_0.vtk
Normal file
3
data/temporal_datasets/DoubleGyre_0.vtk
Normal file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:6969444d4082055c2334a834f025cf8490bd6d43bb2965b3e0859740e0b73767
|
||||
size 7670
|
3
data/temporal_datasets/DoubleGyre_5.vtk
Normal file
3
data/temporal_datasets/DoubleGyre_5.vtk
Normal file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:b7a6f69e78910d828523fa3c05b787f1d6d89ec6049d2279758b3b032177fda5
|
||||
size 7703
|
47
docs/changelog/apply-policy-with-single-type.md
Normal file
47
docs/changelog/apply-policy-with-single-type.md
Normal file
@ -0,0 +1,47 @@
|
||||
# Add ability to get an array from a Field for a particular type
|
||||
|
||||
Previously, whenever you got an array from a `Field` object from a call to
|
||||
an `ApplyPolicy`, you would get back a `VariantArrayHandle` that allows you
|
||||
to cast to multiple types. To use that, you then have to cast it to
|
||||
multiple different types and multiple different storage.
|
||||
|
||||
Often, this is what you want. If you are operating on a field, then you
|
||||
want to cast to the native type. But there are also cases where you know a
|
||||
specific type you want. For example, if you are operating on two fields, it
|
||||
makes sense to find the exact type for the first field and then cast the
|
||||
second field to that type if necessary rather than pointlessly unroll
|
||||
templates for the cross of every possible combination. Also, we are not
|
||||
unrolling for different storage types or attempting to create a virtual
|
||||
array. Instead, we are using an `ArrayHandleMultiplexer` so that you only
|
||||
have to compile for this array once.
|
||||
|
||||
This is done through a new version of `ApplyPolicy`. This version takes a
|
||||
type of the array as its first template argument, which must be specified.
|
||||
|
||||
This requires having a list of potential storage to try. It will use that
|
||||
to construct an `ArrayHandleMultiplexer` containing all potential types.
|
||||
This list of storages comes from the policy. A `StorageList` item was added
|
||||
to the policy. It is also sometimes necessary for a filter to provide its
|
||||
own special storage types. Thus, an `AdditionalFieldStorage` type was added
|
||||
to `Filter` which is set to a `ListTag` of storage types that should be
|
||||
added to those specified by the policy.
|
||||
|
||||
Types are automatically converted. So if you ask for a `vtkm::Float64` and
|
||||
field contains a `vtkm::Float32`, it will the array wrapped in an
|
||||
`ArrayHandleCast` to give the expected type.
|
||||
|
||||
Here is an example where you are doing an operation on a field and
|
||||
coordinate system. The superclass finds the correct type of the field. Your
|
||||
result is just going to follow the type of the field.
|
||||
|
||||
``` cpp
|
||||
template <typename T, typename StorageType, typename DerivedPolicy>
|
||||
inline VTKM_CONT vtkm::cont::DataSet MyFilter::DoExecute(
|
||||
const vtkm::cont::DataSet& inDataSet,
|
||||
const vtkm::cont::ArrayHandle<T, StorageType>& field,
|
||||
const vtkm::filter::FieldMetadata& fieldMetadata,
|
||||
vtkm::filter::PolicyBase<DerivedPolicy> policy)
|
||||
{
|
||||
vtkm::cont::CoordinateSystem coords = inDataSet.GetCoordianteSystem();
|
||||
auto coordsArray = vtkm::filter::ApplyPolicy<T>(coords, policy, *this);
|
||||
```
|
8
docs/changelog/cellsets-dont-have-names.md
Normal file
8
docs/changelog/cellsets-dont-have-names.md
Normal file
@ -0,0 +1,8 @@
|
||||
# CellSets now don't have a name
|
||||
|
||||
The requirement that `vtkm::cont::CellSets` have a name was so
|
||||
cell based `vtkm::cont::Field`'s could be associated with the
|
||||
correct CellSet in a `vtkm::cont::DataSet`.
|
||||
|
||||
Now that `DataSet`'s don't support multiple CellSets, we can remove
|
||||
the `CellSet` name member variable.
|
@ -1,6 +1,6 @@
|
||||
# DataSet queries for CellSet and Coordinate System Indices don't throw
|
||||
# DataSet queries for CoordinateSystem Indices don't throw
|
||||
|
||||
Asking for the index of a `vtkm::cont::CellSet` or `vtkm::cont::CoordinateSystem` by
|
||||
Asking for the index of a `vtkm::cont::CoordinateSystem` by
|
||||
name now returns a `-1` when no matching item has been found instead of throwing
|
||||
an exception.
|
||||
|
||||
|
29
docs/changelog/dataset-only-single-cellset.md
Normal file
29
docs/changelog/dataset-only-single-cellset.md
Normal file
@ -0,0 +1,29 @@
|
||||
# DataSet only has a single vtkm::cont::CellSet
|
||||
|
||||
Multiple `vtkm::cont::CellSets` on a datasets increased the
|
||||
complexity of using VTK-m correctly without any significant
|
||||
benefits.
|
||||
|
||||
It had the effect that `vtkm::cont::Fields` that representing
|
||||
cell fields needed to be associated with a given cellset. This
|
||||
has to be a loose coupling to allow for filters to generate
|
||||
new output cellsets. At the same time it introduced errors when
|
||||
that output had a different name.
|
||||
|
||||
It raised questions about how should filters propagate cell fields.
|
||||
Should a filter drop all cell fields not associated with the active
|
||||
CellSet, or is that too aggressive given the fact that maybe the
|
||||
algorithm just mistakenly named the field, or the IO routine added
|
||||
a field with the wrong cellset name.
|
||||
|
||||
It increased the complexity of filters, as the developer needed to
|
||||
determine if the algorithm should support execution on a single `CellSet` or
|
||||
execution over all `CellSets`.
|
||||
|
||||
Given these issues it was deemed that removing multiple `CellSets` was
|
||||
the correct way forward. People using multiple `CellSets` will need to
|
||||
move over to `vtkm::cont::MultiBlock` which supports shared points and
|
||||
fields between multiple blocks.
|
||||
|
||||
|
||||
|
5
docs/changelog/field-no-cellset-name-required.md
Normal file
5
docs/changelog/field-no-cellset-name-required.md
Normal file
@ -0,0 +1,5 @@
|
||||
# Fields now don't require the associated CellSet name
|
||||
|
||||
Now that `vtkm::cont::DataSet` can only have a single `vtkm::cont::CellSet`
|
||||
the requirement that cell based `vtkm::cont::Field`s need a CellSet name
|
||||
has been lifted.
|
@ -1,6 +0,0 @@
|
||||
# FilterField now tries to be smart when selecting active cellset
|
||||
|
||||
Now when a calls a `vtkm::filter::FilterField` algorithm without an explicit
|
||||
active CellSet, if the field is cell based we set the active `vtkm::cont::CellSet`
|
||||
to be the one associated with that field. If that `vtkm::cont::CellSet` doesn't
|
||||
exist we default back to using the first CellSet in the input `vtkm::cont::DataSet`.
|
4
docs/changelog/filters-no-active-cellset.md
Normal file
4
docs/changelog/filters-no-active-cellset.md
Normal file
@ -0,0 +1,4 @@
|
||||
# vtkm::cont::Filter now don't have an active cell set
|
||||
|
||||
`vtkm::filter::FilterField` has removed the concept of `ActiveCellSetIndex`. This
|
||||
has been done as `vtkm::cont::DataSet` now only contains a single `vtkm::cont::CellSet`.
|
19
docs/changelog/fix-polygon-gradient.md
Normal file
19
docs/changelog/fix-polygon-gradient.md
Normal file
@ -0,0 +1,19 @@
|
||||
# Fix cell derivatives for polygon cell shape
|
||||
|
||||
For polygon cell shapes (that are not triangles or quadrilaterals),
|
||||
interpolations are done by finding the center point and creating a triangle
|
||||
fan around that point. Previously, the gradient was computed in the same
|
||||
way as interpolation: identifying the correct triangle and computing the
|
||||
gradient for that triangle.
|
||||
|
||||
The problem with that approach is that makes the gradient discontinuous at
|
||||
the boundaries of this implicit triangle fan. To make things worse, this
|
||||
discontinuity happens right at each vertex where gradient calculations
|
||||
happen frequently. This means that when you ask for the gradient at the
|
||||
vertex, you might get wildly different answers based on floating point
|
||||
imprecision.
|
||||
|
||||
Get around this problem by creating a small triangle around the point in
|
||||
question, interpolating values to that triangle, and use that for the
|
||||
gradient. This makes for a smoother gradient transition around these
|
||||
internal boundaries.
|
16
docs/changelog/multiblock_renamed_partitioneddataset.md
Normal file
16
docs/changelog/multiblock_renamed_partitioneddataset.md
Normal file
@ -0,0 +1,16 @@
|
||||
# `MultiBlock` renamed to `PartitionedDataSet`
|
||||
|
||||
The `MultiBlock` class has been renamed to `PartitionedDataSet`, and its API
|
||||
has been refactored to refer to "partitions", rather than "blocks".
|
||||
Additionally, the `AddBlocks` method has been changed to `AppendPartitions` to
|
||||
more accurately reflect the operation performed. The associated
|
||||
`AssignerMultiBlock` class has also been renamed to
|
||||
`AssignerPartitionedDataSet`.
|
||||
|
||||
This change is motivated towards unifying VTK-m's data model with VTK. VTK has
|
||||
started to move away from `vtkMultiBlockDataSet`, which is a hierarchical tree
|
||||
of nested datasets, to `vtkPartitionedDataSet`, which is always a flat vector
|
||||
of datasets used to assist geometry distribution in multi-process environments.
|
||||
This simplifies traversal during processing and clarifies the intent of the
|
||||
container: The component datasets are partitions for distribution, not
|
||||
organizational groupings (e.g. materials).
|
10
docs/changelog/remove-array-portal-shrink.md
Normal file
10
docs/changelog/remove-array-portal-shrink.md
Normal file
@ -0,0 +1,10 @@
|
||||
# Remove ArrayPortalShrink, behavior subsumed by ArrayHandleView
|
||||
|
||||
ArrayPortalShrink originaly allowed a user to pass in a delegate array portal
|
||||
and then shrink the reported array size without actually modifying the
|
||||
underlying allocation. An iterator was also provided that would
|
||||
correctly iterate over the shrunken size of the stored array.
|
||||
|
||||
Instead of directly shrinking the original array, it is prefered
|
||||
to create an ArrayHandleView from an ArrayHandle and then specify the
|
||||
number of values to use in the ArrayHandleView constructor.
|
29
docs/changelog/scan-extended.md
Normal file
29
docs/changelog/scan-extended.md
Normal file
@ -0,0 +1,29 @@
|
||||
# A `ScanExtended` device algorithm has been added.
|
||||
|
||||
This new scan algorithm produces an array that contains both an inclusive scan
|
||||
and an exclusive scan in the same array:
|
||||
|
||||
```
|
||||
#include <vtkm/cont/Algorithm.h>
|
||||
#include <vtkm/cont/ArrayGetValue.h>
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
#include <vtkm/cont/ArrayHandleView.h>
|
||||
|
||||
vtkm::cont::ArrayHandle<T> inputData = ...;
|
||||
const vtkm::Id size = inputData.GetNumberOfValues();
|
||||
|
||||
vtkm::cont::ArrayHandle<T> extendedScan;
|
||||
vtkm::cont::Algorithm::ScanExtended(inputData, extendedScan);
|
||||
|
||||
// The exclusive scan is the first `inputSize` values starting at index 0:
|
||||
auto exclusiveScan = vtkm::cont::make_ArrayHandleView(extendedScan, 0, size);
|
||||
|
||||
// The inclusive scan is the first `inputSize` values starting at index 1:
|
||||
auto inclusiveScan = vtkm::cont::make_ArrayHandleView(extendedScan, 1, size);
|
||||
|
||||
// The total sum of the input data is the last value in the extended scan.
|
||||
const T totalSum = vtkm::cont::ArrayGetValue(size, extendedScan);
|
||||
```
|
||||
|
||||
This can also be thought of as an exclusive scan that appends the total sum,
|
||||
rather than returning it.
|
39
docs/changelog/vec-traits-base-components.md
Normal file
39
docs/changelog/vec-traits-base-components.md
Normal file
@ -0,0 +1,39 @@
|
||||
# Recursive base component queries to VecTraits
|
||||
|
||||
This change adds a recursive `BaseComponentType` to `VecTraits` that
|
||||
recursively finds the base (non-`Vec`) type of a `Vec`. This is useful when
|
||||
dealing with potentially nested `Vec`s (e.g. `Vec<Vec<T, M>, N>`) and you
|
||||
want to know the precision of the math being defined.
|
||||
|
||||
``` cpp
|
||||
using NestedVec = vtkm::Vec<vtkm::Vec<vtkm::Float32, 3>, 8>;
|
||||
|
||||
// ComponentType becomes vtkm::Vec<vtkm::Float32, 3>
|
||||
using ComponentType = typename vtkm::VecTraits<NestedVec>::ComponentType;
|
||||
|
||||
// BaseComponentType becomes vtkm::Float32
|
||||
using BaseComponentType = typename vtkm::VecTraits<NestedVec>::BaseComponentType;
|
||||
```
|
||||
|
||||
Also added the ability to `VecTraits` to change the component type of a
|
||||
vector. The template `RepalceComponentType` resolves to a `Vec` of the same
|
||||
type with the component replaced with a new type. The template
|
||||
`ReplaceBaseComponentType` traverses down a nested type and replaces the
|
||||
base type.
|
||||
|
||||
``` cpp
|
||||
using NestedVec = vtkm::Vec<vtkm::Vec<vtkm::Float32, 3>, 8>;
|
||||
|
||||
// NewVec1 becomes vtkm::Vec<vtkm::Float64, 8>
|
||||
using NewVec1 =
|
||||
typename vtkm::VecTraits<NestedVec>::template ReplaceComponentType<vtkm::Float64>;
|
||||
|
||||
// NewVec2 becomes vtkm::Vec<vtkm::Vec<vtkm::Float64, 3>, 8>
|
||||
using NewVec1 =
|
||||
typename vtkm::VecTraits<NestedVec>::template ReplaceBaseComponentType<vtkm::Float64>;
|
||||
```
|
||||
|
||||
This functionality replaces the functionality in `vtkm::BaseComponent`. Unfortunately,
|
||||
`vtkm::BaseComponent` did not have the ability to replace the base component and
|
||||
there was no straightforward way to implement that outside of `VecTraits`.
|
||||
|
@ -40,10 +40,11 @@ void TestCosmoHaloFinder(const char* fileName)
|
||||
// Read in number of particles and locations
|
||||
int nParticles;
|
||||
inFile >> nParticles;
|
||||
std::size_t size = static_cast<std::size_t>(nParticles);
|
||||
|
||||
float* xLocation = new float[nParticles];
|
||||
float* yLocation = new float[nParticles];
|
||||
float* zLocation = new float[nParticles];
|
||||
float* xLocation = new float[size];
|
||||
float* yLocation = new float[size];
|
||||
float* zLocation = new float[size];
|
||||
std::cout << "Running Halo Finder on " << nParticles << std::endl;
|
||||
|
||||
for (vtkm::Id p = 0; p < nParticles; p++)
|
||||
|
@ -115,26 +115,21 @@ public:
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec4ui_8> colors;
|
||||
|
||||
//get the coordinate system we are using for the 2D area
|
||||
const vtkm::cont::DynamicCellSet& cells = input.GetCellSet(this->GetActiveCellSetIndex());
|
||||
const vtkm::cont::DynamicCellSet& cells = input.GetCellSet();
|
||||
|
||||
//get the previous state of the game
|
||||
input.GetField("state", vtkm::cont::Field::Association::POINTS).GetData().CopyTo(prevstate);
|
||||
|
||||
//Update the game state
|
||||
this->Invoke(
|
||||
UpdateLifeState{}, vtkm::filter::ApplyPolicy(cells, policy), prevstate, state, colors);
|
||||
UpdateLifeState{}, vtkm::filter::ApplyPolicyCellSet(cells, policy), prevstate, state, colors);
|
||||
|
||||
//save the results
|
||||
vtkm::cont::DataSet output;
|
||||
output.AddCellSet(input.GetCellSet(this->GetActiveCellSetIndex()));
|
||||
output.AddCoordinateSystem(input.GetCoordinateSystem(this->GetActiveCoordinateSystemIndex()));
|
||||
|
||||
vtkm::cont::Field colorField("colors", vtkm::cont::Field::Association::POINTS, colors);
|
||||
output.AddField(colorField);
|
||||
|
||||
vtkm::cont::Field stateField("state", vtkm::cont::Field::Association::POINTS, state);
|
||||
output.AddField(stateField);
|
||||
output.CopyStructure(input);
|
||||
|
||||
output.AddField(vtkm::cont::make_FieldPoint("colors", colors));
|
||||
output.AddField(vtkm::cont::make_FieldPoint("state", state));
|
||||
return output;
|
||||
}
|
||||
|
||||
@ -206,7 +201,7 @@ struct RenderGameOfLife
|
||||
void render(vtkm::cont::DataSet& data)
|
||||
{
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
vtkm::Int32 arraySize = (vtkm::Int32)data.GetCoordinateSystem().GetNumberOfPoints();
|
||||
vtkm::Int32 arraySize = (vtkm::Int32)data.GetNumberOfPoints();
|
||||
|
||||
UploadData task(&this->ColorState,
|
||||
data.GetField("colors", vtkm::cont::Field::Association::POINTS));
|
||||
|
@ -80,18 +80,18 @@ int main(int argc, char* argv[])
|
||||
const vtkm::Id num_bins = static_cast<vtkm::Id>(std::atoi(argv[1]));
|
||||
const vtkm::Id numVals = 1024;
|
||||
|
||||
vtkm::cont::MultiBlock mb;
|
||||
vtkm::cont::PartitionedDataSet pds;
|
||||
vtkm::cont::DataSet ds;
|
||||
vtkm::cont::DataSetFieldAdd::AddPointField(ds, "pointvar", CreateArray(-1024, 1024, numVals));
|
||||
mb.AddBlock(ds);
|
||||
pds.AppendPartition(ds);
|
||||
|
||||
example::HistogramMPI histogram;
|
||||
histogram.SetActiveField("pointvar");
|
||||
histogram.SetNumberOfBins(std::max<vtkm::Id>(1, num_bins));
|
||||
vtkm::cont::MultiBlock result = histogram.Execute(mb);
|
||||
vtkm::cont::PartitionedDataSet result = histogram.Execute(pds);
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> bins;
|
||||
result.GetBlock(0).GetField("histogram").GetData().CopyTo(bins);
|
||||
result.GetPartition(0).GetField("histogram").GetData().CopyTo(bins);
|
||||
auto binPortal = bins.GetPortalConstControl();
|
||||
if (rank == 0)
|
||||
{
|
||||
|
@ -65,16 +65,16 @@ public:
|
||||
const vtkm::filter::PolicyBase<DerivedPolicy>& policy);
|
||||
|
||||
//@{
|
||||
/// when operating on vtkm::cont::MultiBlock, we
|
||||
/// when operating on vtkm::cont::PartitionedDataSet, we
|
||||
/// want to do processing across ranks as well. Just adding pre/post handles
|
||||
/// for the same does the trick.
|
||||
template <typename DerivedPolicy>
|
||||
VTKM_CONT void PreExecute(const vtkm::cont::MultiBlock& input,
|
||||
VTKM_CONT void PreExecute(const vtkm::cont::PartitionedDataSet& input,
|
||||
const vtkm::filter::PolicyBase<DerivedPolicy>& policy);
|
||||
|
||||
template <typename DerivedPolicy>
|
||||
VTKM_CONT void PostExecute(const vtkm::cont::MultiBlock& input,
|
||||
vtkm::cont::MultiBlock& output,
|
||||
VTKM_CONT void PostExecute(const vtkm::cont::PartitionedDataSet& input,
|
||||
vtkm::cont::PartitionedDataSet& output,
|
||||
const vtkm::filter::PolicyBase<DerivedPolicy>&);
|
||||
//@}
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
#include <vtkm/cont/Algorithm.h>
|
||||
#include <vtkm/cont/ArrayPortalToIterators.h>
|
||||
#include <vtkm/cont/AssignerMultiBlock.h>
|
||||
#include <vtkm/cont/AssignerPartitionedDataSet.h>
|
||||
#include <vtkm/cont/EnvironmentTracker.h>
|
||||
#include <vtkm/cont/ErrorFilterExecution.h>
|
||||
#include <vtkm/cont/FieldRangeGlobalCompute.h>
|
||||
@ -143,7 +143,7 @@ inline VTKM_CONT vtkm::cont::DataSet HistogramMPI::DoExecute(
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename DerivedPolicy>
|
||||
inline VTKM_CONT void HistogramMPI::PreExecute(const vtkm::cont::MultiBlock& input,
|
||||
inline VTKM_CONT void HistogramMPI::PreExecute(const vtkm::cont::PartitionedDataSet& input,
|
||||
const vtkm::filter::PolicyBase<DerivedPolicy>&)
|
||||
{
|
||||
if (this->Range.IsNonEmpty())
|
||||
@ -164,15 +164,15 @@ inline VTKM_CONT void HistogramMPI::PreExecute(const vtkm::cont::MultiBlock& inp
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename DerivedPolicy>
|
||||
inline VTKM_CONT void HistogramMPI::PostExecute(const vtkm::cont::MultiBlock&,
|
||||
vtkm::cont::MultiBlock& result,
|
||||
inline VTKM_CONT void HistogramMPI::PostExecute(const vtkm::cont::PartitionedDataSet&,
|
||||
vtkm::cont::PartitionedDataSet& result,
|
||||
const vtkm::filter::PolicyBase<DerivedPolicy>&)
|
||||
{
|
||||
// iterate and compute HistogramMPI for each local block.
|
||||
detail::DistributedHistogram helper(result.GetNumberOfBlocks());
|
||||
for (vtkm::Id cc = 0; cc < result.GetNumberOfBlocks(); ++cc)
|
||||
detail::DistributedHistogram helper(result.GetNumberOfPartitions());
|
||||
for (vtkm::Id cc = 0; cc < result.GetNumberOfPartitions(); ++cc)
|
||||
{
|
||||
auto& ablock = result.GetBlock(cc);
|
||||
auto& ablock = result.GetPartition(cc);
|
||||
helper.SetLocalHistogram(cc, ablock.GetField(this->GetOutputFieldName()));
|
||||
}
|
||||
|
||||
@ -182,6 +182,6 @@ inline VTKM_CONT void HistogramMPI::PostExecute(const vtkm::cont::MultiBlock&,
|
||||
helper.ReduceAll(this->NumberOfBins));
|
||||
output.AddField(rfield);
|
||||
|
||||
result = vtkm::cont::MultiBlock(output);
|
||||
result = vtkm::cont::PartitionedDataSet(output);
|
||||
}
|
||||
} // namespace example
|
||||
|
@ -16,4 +16,4 @@ add_executable(Lagrangian lagrangian.cxx ABCfield.h)
|
||||
target_link_libraries(Lagrangian PRIVATE vtkm_filter)
|
||||
vtkm_add_target_information(Lagrangian
|
||||
MODIFY_CUDA_FLAGS
|
||||
DEVICE_SOURCES Lagrangian.cxx)
|
||||
DEVICE_SOURCES lagrangian.cxx)
|
||||
|
@ -32,6 +32,6 @@ if(TARGET vtkm::tbb)
|
||||
target_compile_definitions(MeshQuality PRIVATE BUILDING_TBB_VERSION)
|
||||
endif()
|
||||
|
||||
if(TARGET vtkm::cuda)
|
||||
set_source_files_properties(MeshQuality.cxx PROPERTIES LANGUAGE "CUDA")
|
||||
endif()
|
||||
vtkm_add_target_information(MeshQuality
|
||||
MODIFY_CUDA_FLAGS
|
||||
DEVICE_SOURCES MeshQuality.cxx)
|
||||
|
@ -194,7 +194,7 @@ inline vtkm::cont::DataSet Make3DExplicitDataSet()
|
||||
conn.push_back(7);
|
||||
conn.push_back(2);
|
||||
|
||||
dataSet = dsb.Create(coords, shapes, numindices, conn, "coordinates", "cells");
|
||||
dataSet = dsb.Create(coords, shapes, numindices, conn, "coordinates");
|
||||
|
||||
return dataSet;
|
||||
}
|
||||
|
@ -20,17 +20,14 @@ set(headers
|
||||
TaskQueue.h
|
||||
)
|
||||
|
||||
set(device_srcs
|
||||
MultiDeviceGradient.cxx
|
||||
)
|
||||
|
||||
set(srcs
|
||||
IOGenerator.cxx
|
||||
MultiBackend.cxx
|
||||
MultiDeviceGradient.cxx
|
||||
IOGenerator.cxx
|
||||
)
|
||||
|
||||
add_executable(MultiBackend ${device_srcs} ${srcs} ${headers})
|
||||
add_executable(MultiBackend ${srcs} ${headers})
|
||||
target_link_libraries(MultiBackend PRIVATE vtkm_filter Threads::Threads)
|
||||
vtkm_add_target_information(MultiBackend
|
||||
MODIFY_CUDA_FLAGS
|
||||
DEVICE_SOURCES ${device_srcs})
|
||||
DEVICE_SOURCES ${srcs})
|
||||
|
@ -51,46 +51,47 @@ vtkm::cont::DataSet make_test3DImageData(vtkm::Id3 dims)
|
||||
}
|
||||
|
||||
//=================================================================
|
||||
void io_generator(TaskQueue<vtkm::cont::MultiBlock>& queue, std::size_t numberOfTasks)
|
||||
void io_generator(TaskQueue<vtkm::cont::PartitionedDataSet>& queue, std::size_t numberOfTasks)
|
||||
{
|
||||
//Step 1. We want to build an initial set of blocks
|
||||
//Step 1. We want to build an initial set of partitions
|
||||
//that vary in size. This way we can generate uneven
|
||||
//work to show off the vtk-m filter work distribution
|
||||
vtkm::Id3 small(128, 128, 128);
|
||||
vtkm::Id3 medium(256, 256, 128);
|
||||
vtkm::Id3 large(512, 256, 128);
|
||||
|
||||
std::vector<vtkm::Id3> block_sizes;
|
||||
block_sizes.push_back(small);
|
||||
block_sizes.push_back(medium);
|
||||
block_sizes.push_back(large);
|
||||
std::vector<vtkm::Id3> partition_sizes;
|
||||
partition_sizes.push_back(small);
|
||||
partition_sizes.push_back(medium);
|
||||
partition_sizes.push_back(large);
|
||||
|
||||
|
||||
std::mt19937 rng;
|
||||
//uniform_int_distribution is a closed interval [] so both the min and max
|
||||
//can be chosen values
|
||||
std::uniform_int_distribution<vtkm::Id> blockNumGen(6, 32);
|
||||
std::uniform_int_distribution<std::size_t> blockPicker(0, block_sizes.size() - 1);
|
||||
std::uniform_int_distribution<vtkm::Id> partitionNumGen(6, 32);
|
||||
std::uniform_int_distribution<std::size_t> partitionPicker(0, partition_sizes.size() - 1);
|
||||
for (std::size_t i = 0; i < numberOfTasks; ++i)
|
||||
{
|
||||
//Step 2. Construct a random number of blocks
|
||||
const vtkm::Id numberOfBlocks = blockNumGen(rng);
|
||||
//Step 2. Construct a random number of partitions
|
||||
const vtkm::Id numberOfPartitions = partitionNumGen(rng);
|
||||
|
||||
//Step 3. Randomly pick the blocks in the dataset
|
||||
vtkm::cont::MultiBlock mb(numberOfBlocks);
|
||||
for (vtkm::Id b = 0; b < numberOfBlocks; ++b)
|
||||
//Step 3. Randomly pick the partitions in the dataset
|
||||
vtkm::cont::PartitionedDataSet pds(numberOfPartitions);
|
||||
for (vtkm::Id p = 0; p < numberOfPartitions; ++p)
|
||||
{
|
||||
const auto& dims = block_sizes[blockPicker(rng)];
|
||||
auto block = make_test3DImageData(dims);
|
||||
mb.AddBlock(block);
|
||||
const auto& dims = partition_sizes[partitionPicker(rng)];
|
||||
auto partition = make_test3DImageData(dims);
|
||||
pds.AppendPartition(partition);
|
||||
}
|
||||
|
||||
std::cout << "adding multi-block with " << mb.GetNumberOfBlocks() << " blocks" << std::endl;
|
||||
std::cout << "adding partitioned dataset with " << pds.GetNumberOfPartitions() << " partitions"
|
||||
<< std::endl;
|
||||
|
||||
//Step 4. Add the multi-block to the queue. We explicitly
|
||||
//Step 4. Add the partitioned dataset to the queue. We explicitly
|
||||
//use std::move to signal that this thread can't use the
|
||||
//mb object after this call
|
||||
queue.push(std::move(mb));
|
||||
//pds object after this call
|
||||
queue.push(std::move(pds));
|
||||
|
||||
//Step 5. Go to sleep for a period of time to replicate
|
||||
//data stream in
|
||||
|
@ -12,9 +12,9 @@
|
||||
|
||||
#include "TaskQueue.h"
|
||||
#include <vtkm/cont/DataSet.h>
|
||||
#include <vtkm/cont/MultiBlock.h>
|
||||
#include <vtkm/cont/PartitionedDataSet.h>
|
||||
|
||||
vtkm::cont::DataSet make_test3DImageData(int xdim, int ydim, int zdim);
|
||||
void io_generator(TaskQueue<vtkm::cont::MultiBlock>& queue, std::size_t numberOfTasks);
|
||||
void io_generator(TaskQueue<vtkm::cont::PartitionedDataSet>& queue, std::size_t numberOfTasks);
|
||||
|
||||
#endif
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include <thread>
|
||||
|
||||
#include <vtkm/cont/Initialize.h>
|
||||
#include <vtkm/cont/MultiBlock.h>
|
||||
#include <vtkm/cont/PartitionedDataSet.h>
|
||||
|
||||
#include "IOGenerator.h"
|
||||
#include "MultiDeviceGradient.h"
|
||||
@ -22,9 +22,9 @@
|
||||
//
|
||||
//At a high level we have 2 primary threads, an IO thread and a Worker thread
|
||||
//The IO thread will generate all data using the vtk-m serial device, and
|
||||
//will post this data to a worker queue as a vtk-m multiblock.
|
||||
//The Worker thread will pull down these vtk-m multiblock data and run a
|
||||
//vtk-m filter on the multiblock.
|
||||
//will post this data to a worker queue as a vtk-m partitioned dataset.
|
||||
//The Worker thread will pull down these vtk-m data and run a
|
||||
//vtk-m filter on the partitions.
|
||||
//The vtk-m filter it runs will itself have a worker pool which it will
|
||||
//distribute work too. The number of workers is based on what device adapters
|
||||
//are enabled but uses the following logic:
|
||||
@ -38,7 +38,7 @@
|
||||
//and single GPU we should expect that we will have 2 primary 'main loop'
|
||||
//threads, and 5 threads for heavy 'task' work.
|
||||
|
||||
void multiblock_processing(TaskQueue<vtkm::cont::MultiBlock>& queue);
|
||||
void partition_processing(TaskQueue<vtkm::cont::PartitionedDataSet>& queue);
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
auto opts =
|
||||
@ -48,9 +48,9 @@ int main(int argc, char** argv)
|
||||
//Step 1. Construct the two primary 'main loops'. The threads
|
||||
//share a queue object so we need to explicitly pass it
|
||||
//by reference (the std::ref call)
|
||||
TaskQueue<vtkm::cont::MultiBlock> queue;
|
||||
TaskQueue<vtkm::cont::PartitionedDataSet> queue;
|
||||
std::thread io(io_generator, std::ref(queue), 6);
|
||||
std::thread worker(multiblock_processing, std::ref(queue));
|
||||
std::thread worker(partition_processing, std::ref(queue));
|
||||
|
||||
//Step N. Wait for the work to finish
|
||||
io.join();
|
||||
@ -59,7 +59,7 @@ int main(int argc, char** argv)
|
||||
}
|
||||
|
||||
//=================================================================
|
||||
void multiblock_processing(TaskQueue<vtkm::cont::MultiBlock>& queue)
|
||||
void partition_processing(TaskQueue<vtkm::cont::PartitionedDataSet>& queue)
|
||||
{
|
||||
//Step 1. Construct the gradient filter outside the work loop
|
||||
//so that we can reuse the thread pool it constructs
|
||||
@ -67,42 +67,37 @@ void multiblock_processing(TaskQueue<vtkm::cont::MultiBlock>& queue)
|
||||
gradient.SetComputePointGradient(true);
|
||||
while (queue.hasTasks())
|
||||
{
|
||||
//Step 2. grab the next multi-block skipping any that are empty
|
||||
//Step 2. grab the next partition skipping any that are empty
|
||||
//as empty ones can be returned when the queue is about
|
||||
//to say it has no work
|
||||
vtkm::cont::MultiBlock mb = queue.pop();
|
||||
if (mb.GetNumberOfBlocks() == 0)
|
||||
vtkm::cont::PartitionedDataSet pds = queue.pop();
|
||||
if (pds.GetNumberOfPartitions() == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//Step 3. Get the first field name from the multi-block
|
||||
std::string fieldName = mb.GetBlock(0).GetField(0).GetName();
|
||||
//Step 3. Get the first field name from the partition
|
||||
std::string fieldName = pds.GetPartition(0).GetField(0).GetName();
|
||||
|
||||
//Step 4. Run a multi device gradient
|
||||
gradient.SetActiveField(fieldName);
|
||||
vtkm::cont::MultiBlock result = gradient.Execute(mb);
|
||||
std::cout << "finished processing a multi-block" << std::endl;
|
||||
vtkm::cont::PartitionedDataSet result = gradient.Execute(pds);
|
||||
std::cout << "finished processing a partitioned dataset" << std::endl;
|
||||
|
||||
//Step 5. Verify each block has a "Gradients" field
|
||||
for (auto&& block : result)
|
||||
//Step 5. Verify each partition has a "Gradients" field
|
||||
for (auto&& partition : result)
|
||||
{
|
||||
// std::cout << std::endl << std::endl << std::endl;
|
||||
// std::cout << "block: " << std::endl;
|
||||
// block.PrintSummary(std::cout);
|
||||
try
|
||||
{
|
||||
const auto& field = block.GetField("Gradients", vtkm::cont::Field::Association::POINTS);
|
||||
(void)field;
|
||||
}
|
||||
catch (const vtkm::cont::ErrorBadValue& error)
|
||||
// std::cout << "partition: " << std::endl;
|
||||
// partition.PrintSummary(std::cout);
|
||||
if (!partition.HasField("Gradients", vtkm::cont::Field::Association::POINTS))
|
||||
{
|
||||
std::cerr << "Gradient filter failed!" << std::endl;
|
||||
std::cerr << error.GetMessage() << std::endl;
|
||||
std::cerr << "Missing Gradient field on output partition." << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "multiblock_processing finished" << std::endl;
|
||||
std::cout << "partition_processing finished" << std::endl;
|
||||
}
|
||||
|
@ -13,6 +13,6 @@
|
||||
#include "MultiDeviceGradient.h"
|
||||
#include "MultiDeviceGradient.hxx"
|
||||
|
||||
template vtkm::cont::MultiBlock MultiDeviceGradient::PrepareForExecution<
|
||||
vtkm::filter::PolicyDefault>(const vtkm::cont::MultiBlock&,
|
||||
template vtkm::cont::PartitionedDataSet MultiDeviceGradient::PrepareForExecution<
|
||||
vtkm::filter::PolicyDefault>(const vtkm::cont::PartitionedDataSet&,
|
||||
const vtkm::filter::PolicyBase<vtkm::filter::PolicyDefault>&);
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
using RuntimeTaskQueue = TaskQueue<std::function<void()>>;
|
||||
|
||||
/// \brief Construct a MultiDeviceGradient for a given multiblock dataset
|
||||
/// \brief Construct a MultiDeviceGradient for a given partitioned dataset
|
||||
///
|
||||
/// The Policy used with MultiDeviceGradient must include the TBB and CUDA
|
||||
/// backends.
|
||||
@ -45,8 +45,8 @@ public:
|
||||
/// Will submit each block to a work queue that the threads will
|
||||
/// pull work from
|
||||
template <typename DerivedPolicy>
|
||||
VTKM_CONT vtkm::cont::MultiBlock PrepareForExecution(
|
||||
const vtkm::cont::MultiBlock&,
|
||||
VTKM_CONT vtkm::cont::PartitionedDataSet PrepareForExecution(
|
||||
const vtkm::cont::PartitionedDataSet&,
|
||||
const vtkm::filter::PolicyBase<DerivedPolicy>&);
|
||||
|
||||
private:
|
||||
@ -56,8 +56,8 @@ private:
|
||||
};
|
||||
|
||||
#ifndef vtk_m_examples_multibackend_MultiDeviceGradient_cxx
|
||||
extern template vtkm::cont::MultiBlock MultiDeviceGradient::PrepareForExecution<
|
||||
vtkm::filter::PolicyDefault>(const vtkm::cont::MultiBlock&,
|
||||
extern template vtkm::cont::PartitionedDataSet MultiDeviceGradient::PrepareForExecution<
|
||||
vtkm::filter::PolicyDefault>(const vtkm::cont::PartitionedDataSet&,
|
||||
const vtkm::filter::PolicyBase<vtkm::filter::PolicyDefault>&);
|
||||
#endif
|
||||
|
||||
|
@ -32,7 +32,7 @@ int determine_cuda_gpu_count()
|
||||
return count;
|
||||
}
|
||||
|
||||
void process_block_tbb(RuntimeTaskQueue& queue)
|
||||
void process_partition_tbb(RuntimeTaskQueue& queue)
|
||||
{
|
||||
//Step 1. Set the device adapter to this thread to TBB.
|
||||
//This makes sure that any vtkm::filters used by our
|
||||
@ -56,11 +56,11 @@ void process_block_tbb(RuntimeTaskQueue& queue)
|
||||
|
||||
//Step 4. Notify the queue that we finished processing this task
|
||||
queue.completedTask();
|
||||
std::cout << "finished a block on tbb (" << std::this_thread::get_id() << ")" << std::endl;
|
||||
std::cout << "finished a partition on tbb (" << std::this_thread::get_id() << ")" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void process_block_openMP(RuntimeTaskQueue& queue)
|
||||
void process_partition_openMP(RuntimeTaskQueue& queue)
|
||||
{
|
||||
//Step 1. Set the device adapter to this thread to TBB.
|
||||
//This makes sure that any vtkm::filters used by our
|
||||
@ -84,11 +84,11 @@ void process_block_openMP(RuntimeTaskQueue& queue)
|
||||
|
||||
//Step 4. Notify the queue that we finished processing this task
|
||||
queue.completedTask();
|
||||
std::cout << "finished a block on tbb (" << std::this_thread::get_id() << ")" << std::endl;
|
||||
std::cout << "finished a partition on tbb (" << std::this_thread::get_id() << ")" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void process_block_cuda(RuntimeTaskQueue& queue, int gpuId)
|
||||
void process_partition_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
|
||||
@ -113,7 +113,7 @@ void process_block_cuda(RuntimeTaskQueue& queue, int gpuId)
|
||||
|
||||
//Step 4. Notify the queue that we finished processing this task
|
||||
queue.completedTask();
|
||||
std::cout << "finished a block on cuda (" << std::this_thread::get_id() << ")" << std::endl;
|
||||
std::cout << "finished a partition on cuda (" << std::this_thread::get_id() << ")" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
@ -149,10 +149,10 @@ VTKM_CONT MultiDeviceGradient::MultiDeviceGradient()
|
||||
//The number of workers per GPU is purely arbitrary currently,
|
||||
//but in general we want multiple of them so we can overlap compute
|
||||
//and transfer
|
||||
this->Workers.emplace_back(std::bind(process_block_cuda, std::ref(this->Queue), i));
|
||||
this->Workers.emplace_back(std::bind(process_block_cuda, std::ref(this->Queue), i));
|
||||
this->Workers.emplace_back(std::bind(process_block_cuda, std::ref(this->Queue), i));
|
||||
this->Workers.emplace_back(std::bind(process_block_cuda, std::ref(this->Queue), i));
|
||||
this->Workers.emplace_back(std::bind(process_partition_cuda, std::ref(this->Queue), i));
|
||||
this->Workers.emplace_back(std::bind(process_partition_cuda, std::ref(this->Queue), i));
|
||||
this->Workers.emplace_back(std::bind(process_partition_cuda, std::ref(this->Queue), i));
|
||||
this->Workers.emplace_back(std::bind(process_partition_cuda, std::ref(this->Queue), i));
|
||||
}
|
||||
}
|
||||
//Step 3. Launch a worker that will use openMP (if enabled).
|
||||
@ -161,7 +161,7 @@ VTKM_CONT MultiDeviceGradient::MultiDeviceGradient()
|
||||
else if (runOnOpenMP)
|
||||
{
|
||||
std::cout << "adding a openMP worker" << std::endl;
|
||||
this->Workers.emplace_back(std::bind(process_block_openMP, std::ref(this->Queue)));
|
||||
this->Workers.emplace_back(std::bind(process_partition_openMP, std::ref(this->Queue)));
|
||||
}
|
||||
//Step 4. Launch a worker that will use tbb (if enabled).
|
||||
//The threads share a queue object so we need to explicitly pass it
|
||||
@ -169,7 +169,7 @@ VTKM_CONT MultiDeviceGradient::MultiDeviceGradient()
|
||||
else if (runOnTbb)
|
||||
{
|
||||
std::cout << "adding a tbb worker" << std::endl;
|
||||
this->Workers.emplace_back(std::bind(process_block_tbb, std::ref(this->Queue)));
|
||||
this->Workers.emplace_back(std::bind(process_partition_tbb, std::ref(this->Queue)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -187,49 +187,50 @@ VTKM_CONT MultiDeviceGradient::~MultiDeviceGradient()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename DerivedPolicy>
|
||||
inline VTKM_CONT vtkm::cont::MultiBlock MultiDeviceGradient::PrepareForExecution(
|
||||
const vtkm::cont::MultiBlock& mb,
|
||||
inline VTKM_CONT vtkm::cont::PartitionedDataSet MultiDeviceGradient::PrepareForExecution(
|
||||
const vtkm::cont::PartitionedDataSet& pds,
|
||||
const vtkm::filter::PolicyBase<DerivedPolicy>& policy)
|
||||
{
|
||||
//Step 1. Say that we have no more to submit for this multi block
|
||||
//Step 1. Say that we have no more to submit for this PartitionedDataSet
|
||||
//This is needed to happen for each execute as we want to support
|
||||
//the same filter being used for multiple inputs
|
||||
this->Queue.reset();
|
||||
|
||||
//Step 2. Construct the multi-block we are going to fill. The size signature
|
||||
//to MultiBlock just reserves size
|
||||
vtkm::cont::MultiBlock output;
|
||||
output.AddBlocks(std::vector<vtkm::cont::DataSet>(static_cast<size_t>(mb.GetNumberOfBlocks())));
|
||||
vtkm::cont::MultiBlock* outPtr = &output;
|
||||
//Step 2. Construct the PartitionedDataSet we are going to fill. The size
|
||||
//signature to PartitionedDataSet just reserves size
|
||||
vtkm::cont::PartitionedDataSet output;
|
||||
output.AppendPartitions(
|
||||
std::vector<vtkm::cont::DataSet>(static_cast<size_t>(pds.GetNumberOfPartitions())));
|
||||
vtkm::cont::PartitionedDataSet* outPtr = &output;
|
||||
|
||||
|
||||
//Step 3. Construct the filter we want to run on each block
|
||||
//Step 3. Construct the filter we want to run on each partition
|
||||
vtkm::filter::Gradient gradient;
|
||||
gradient.SetComputePointGradient(this->GetComputePointGradient());
|
||||
gradient.SetActiveField(this->GetActiveFieldName());
|
||||
|
||||
//Step 3b. Post 1 block up as work and block intil it is
|
||||
//Step 3b. Post 1 partition up as work and block until it is
|
||||
//complete. This is needed as currently constructing the virtual
|
||||
//Point Coordinates is not thread safe.
|
||||
auto block = mb.cbegin();
|
||||
auto partition = pds.cbegin();
|
||||
{
|
||||
vtkm::cont::DataSet input = *block;
|
||||
vtkm::cont::DataSet input = *partition;
|
||||
this->Queue.push( //build a lambda that is the work to do
|
||||
[=]() {
|
||||
vtkm::filter::Gradient perThreadGrad = gradient;
|
||||
|
||||
vtkm::cont::DataSet result = perThreadGrad.Execute(input, policy);
|
||||
outPtr->ReplaceBlock(0, result);
|
||||
outPtr->ReplacePartition(0, result);
|
||||
});
|
||||
this->Queue.waitForAllTasksToComplete();
|
||||
block++;
|
||||
partition++;
|
||||
}
|
||||
|
||||
vtkm::Id index = 1;
|
||||
for (; block != mb.cend(); ++block)
|
||||
for (; partition != pds.cend(); ++partition)
|
||||
{
|
||||
vtkm::cont::DataSet input = *block;
|
||||
//Step 4. For each input block construct a lambda
|
||||
vtkm::cont::DataSet input = *partition;
|
||||
//Step 4. For each input partition construct a lambda
|
||||
//and add it to the queue for workers to take. This
|
||||
//will allows us to have multiple works execute in a non
|
||||
//blocking manner
|
||||
@ -238,7 +239,7 @@ inline VTKM_CONT vtkm::cont::MultiBlock MultiDeviceGradient::PrepareForExecution
|
||||
vtkm::filter::Gradient perThreadGrad = gradient;
|
||||
|
||||
vtkm::cont::DataSet result = perThreadGrad.Execute(input, policy);
|
||||
outPtr->ReplaceBlock(index, result);
|
||||
outPtr->ReplacePartition(index, result);
|
||||
});
|
||||
index++;
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
#ifndef vtk_m_examples_multibackend_TaskQueue_h
|
||||
#define vtk_m_examples_multibackend_TaskQueue_h
|
||||
|
||||
#include <vtkm/cont/MultiBlock.h>
|
||||
#include <vtkm/cont/PartitionedDataSet.h>
|
||||
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
|
@ -9,297 +9,76 @@
|
||||
//============================================================================
|
||||
|
||||
#include <vtkm/cont/DataSet.h>
|
||||
#include <vtkm/cont/Initialize.h>
|
||||
#include <vtkm/cont/Timer.h>
|
||||
#include <vtkm/filter/Streamline.h>
|
||||
#include <vtkm/io/reader/VTKDataSetReader.h>
|
||||
#include <vtkm/io/writer/VTKDataSetWriter.h>
|
||||
|
||||
#include <vtkm/worklet/ParticleAdvection.h>
|
||||
#include <vtkm/worklet/particleadvection/GridEvaluators.h>
|
||||
#include <vtkm/worklet/particleadvection/Integrators.h>
|
||||
#include <vtkm/worklet/particleadvection/ParticleAdvectionWorklets.h>
|
||||
#include <vtkm/worklet/particleadvection/Particles.h>
|
||||
|
||||
#include <vtkm/io/reader/BOVDataSetReader.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <vector>
|
||||
|
||||
#ifdef BUILDING_TBB_VERSION
|
||||
#include <tbb/task_scheduler_init.h>
|
||||
#endif
|
||||
|
||||
const vtkm::Id SPARSE = 0;
|
||||
const vtkm::Id DENSE = 1;
|
||||
const vtkm::Id MEDIUM = 2;
|
||||
|
||||
template <typename T>
|
||||
static vtkm::Range subRange(vtkm::Range& range, T a, T b)
|
||||
{
|
||||
vtkm::Float32 arg1, arg2, len;
|
||||
arg1 = static_cast<vtkm::Float32>(a);
|
||||
arg2 = static_cast<vtkm::Float32>(b);
|
||||
len = static_cast<vtkm::Float32>(range.Length());
|
||||
return vtkm::Range(range.Min + arg1 * len, range.Min + arg2 * len);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void ignore(T&&)
|
||||
{
|
||||
}
|
||||
|
||||
void RunTest(const std::string& fname,
|
||||
vtkm::Id numSeeds,
|
||||
vtkm::Id numSteps,
|
||||
vtkm::Float32 stepSize,
|
||||
vtkm::Id numThreads,
|
||||
vtkm::Id advectType,
|
||||
vtkm::Id seeding)
|
||||
{
|
||||
using FieldType = vtkm::Float32;
|
||||
using FieldHandle = vtkm::cont::ArrayHandle<vtkm::Vec<FieldType, 3>>;
|
||||
|
||||
vtkm::io::reader::BOVDataSetReader rdr(fname);
|
||||
vtkm::cont::DataSet ds = rdr.ReadDataSet();
|
||||
|
||||
using RGEvalType = vtkm::worklet::particleadvection::GridEvaluator<FieldHandle>;
|
||||
using RK4RGType = vtkm::worklet::particleadvection::RK4Integrator<RGEvalType>;
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<FieldType, 3>> fieldArray;
|
||||
ds.GetField(0).GetData().CopyTo(fieldArray);
|
||||
|
||||
RGEvalType eval(ds.GetCoordinateSystem(), ds.GetCellSet(0), fieldArray);
|
||||
RK4RGType rk4(eval, stepSize);
|
||||
|
||||
std::vector<vtkm::Vec<FieldType, 3>> seeds;
|
||||
srand(314);
|
||||
|
||||
vtkm::Bounds bounds = ds.GetCoordinateSystem().GetBounds();
|
||||
if (seeding == SPARSE)
|
||||
bounds = ds.GetCoordinateSystem().GetBounds();
|
||||
else if (seeding == DENSE)
|
||||
{
|
||||
if (fname.find("astro") != std::string::npos)
|
||||
{
|
||||
bounds.X = subRange(bounds.X, .1, .15);
|
||||
bounds.Y = subRange(bounds.Y, .1, .15);
|
||||
bounds.Z = subRange(bounds.Z, .1, .15);
|
||||
}
|
||||
else if (fname.find("fusion") != std::string::npos)
|
||||
{
|
||||
bounds.X = subRange(bounds.X, .8, .85);
|
||||
bounds.Y = subRange(bounds.Y, .55, .60);
|
||||
bounds.Z = subRange(bounds.Z, .55, .60);
|
||||
}
|
||||
else if (fname.find("fishtank") != std::string::npos)
|
||||
{
|
||||
bounds.X = subRange(bounds.X, .1, .15);
|
||||
bounds.Y = subRange(bounds.Y, .1, .15);
|
||||
bounds.Z = subRange(bounds.Z, .55, .60);
|
||||
}
|
||||
}
|
||||
else if (seeding == MEDIUM)
|
||||
{
|
||||
if (fname.find("astro") != std::string::npos)
|
||||
{
|
||||
bounds.X = subRange(bounds.X, .4, .6);
|
||||
bounds.Y = subRange(bounds.Y, .4, .6);
|
||||
bounds.Z = subRange(bounds.Z, .4, .6);
|
||||
}
|
||||
else if (fname.find("fusion") != std::string::npos)
|
||||
{
|
||||
bounds.X = subRange(bounds.X, .01, .99);
|
||||
bounds.Y = subRange(bounds.Y, .01, .99);
|
||||
bounds.Z = subRange(bounds.Z, .45, .55);
|
||||
}
|
||||
else if (fname.find("fishtank") != std::string::npos)
|
||||
{
|
||||
bounds.X = subRange(bounds.X, .4, .6);
|
||||
bounds.Y = subRange(bounds.Y, .4, .6);
|
||||
bounds.Z = subRange(bounds.Z, .4, .6);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < numSeeds; i++)
|
||||
{
|
||||
vtkm::Vec<FieldType, 3> p;
|
||||
vtkm::Float32 rx = (vtkm::Float32)rand() / (vtkm::Float32)RAND_MAX;
|
||||
vtkm::Float32 ry = (vtkm::Float32)rand() / (vtkm::Float32)RAND_MAX;
|
||||
vtkm::Float32 rz = (vtkm::Float32)rand() / (vtkm::Float32)RAND_MAX;
|
||||
p[0] = static_cast<FieldType>(bounds.X.Min + rx * bounds.X.Length());
|
||||
p[1] = static_cast<FieldType>(bounds.Y.Min + ry * bounds.Y.Length());
|
||||
p[2] = static_cast<FieldType>(bounds.Z.Min + rz * bounds.Z.Length());
|
||||
seeds.push_back(p);
|
||||
}
|
||||
|
||||
#ifdef BUILDING_TBB_VERSION
|
||||
int nT = tbb::task_scheduler_init::default_num_threads();
|
||||
if (numThreads != -1)
|
||||
nT = (int)numThreads;
|
||||
//make sure the task_scheduler_init object is in scope when running sth w/ TBB
|
||||
tbb::task_scheduler_init init(nT);
|
||||
#else
|
||||
ignore(numThreads);
|
||||
#endif
|
||||
|
||||
//time only the actual run
|
||||
auto t0 = std::chrono::high_resolution_clock::now();
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<FieldType, 3>> seedArray;
|
||||
seedArray = vtkm::cont::make_ArrayHandle(seeds);
|
||||
|
||||
if (advectType == 0)
|
||||
{
|
||||
vtkm::worklet::ParticleAdvection particleAdvection;
|
||||
particleAdvection.Run(rk4, seedArray, numSteps);
|
||||
}
|
||||
else
|
||||
{
|
||||
vtkm::worklet::Streamline streamline;
|
||||
streamline.Run(rk4, seedArray, numSteps);
|
||||
}
|
||||
|
||||
auto t1 = std::chrono::high_resolution_clock::now() - t0;
|
||||
auto runtime = std::chrono::duration_cast<std::chrono::milliseconds>(t1).count();
|
||||
std::cerr << "Runtime = " << runtime << " ms " << std::endl;
|
||||
}
|
||||
|
||||
bool ParseArgs(int argc,
|
||||
char** argv,
|
||||
const vtkm::cont::InitializeResult& config,
|
||||
vtkm::Id& numSeeds,
|
||||
vtkm::Id& numSteps,
|
||||
vtkm::Float32& stepSize,
|
||||
vtkm::Id& advectType,
|
||||
vtkm::Id& stepsPerRound,
|
||||
vtkm::Id& particlesPerRound,
|
||||
vtkm::Id& numThreads,
|
||||
std::string& dataFile,
|
||||
std::string& pgmType,
|
||||
bool& dumpOutput,
|
||||
vtkm::Id& seeding)
|
||||
{
|
||||
numSeeds = 100;
|
||||
numSteps = 100;
|
||||
stepSize = 0.1f;
|
||||
advectType = 0;
|
||||
stepsPerRound = -1;
|
||||
particlesPerRound = -1;
|
||||
numThreads = -1;
|
||||
dataFile = "";
|
||||
pgmType = config.Device.GetName();
|
||||
dumpOutput = false;
|
||||
seeding = SPARSE;
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
std::cerr << "Usage " << argv[0] << std::endl;
|
||||
std::cerr << " -seeds #seeds" << std::endl;
|
||||
std::cerr << " -steps maxSteps" << std::endl;
|
||||
std::cerr << " -h stepSize" << std::endl;
|
||||
std::cerr << " -particle : particle push" << std::endl;
|
||||
std::cerr << " -streamline steps_per_round (-1 = 0 rounds): particle history" << std::endl;
|
||||
std::cerr << " -t #numThreads" << std::endl;
|
||||
std::cerr << " -file dataFile" << std::endl;
|
||||
std::cerr << " -dump : dump output points" << std::endl << std::endl;
|
||||
std::cerr << "General VTK-m Options" << std::endl;
|
||||
std::cerr << config.Usage << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 1; i < argc; i++)
|
||||
{
|
||||
std::string arg = argv[i];
|
||||
if (arg == "-seeds")
|
||||
numSeeds = static_cast<vtkm::Id>(atoi(argv[++i]));
|
||||
else if (arg == "-steps")
|
||||
numSteps = static_cast<vtkm::Id>(atoi(argv[++i]));
|
||||
else if (arg == "-h")
|
||||
stepSize = static_cast<vtkm::Float32>(atof(argv[++i]));
|
||||
else if (arg == "-particle")
|
||||
advectType = 0;
|
||||
else if (arg == "-streamline")
|
||||
{
|
||||
advectType = 1;
|
||||
}
|
||||
else if (arg == "-streamlineS")
|
||||
{
|
||||
advectType = 1;
|
||||
stepsPerRound = static_cast<vtkm::Id>(atoi(argv[++i]));
|
||||
}
|
||||
else if (arg == "-streamlineP")
|
||||
{
|
||||
advectType = 1;
|
||||
particlesPerRound = static_cast<vtkm::Id>(atoi(argv[++i]));
|
||||
}
|
||||
else if (arg == "-streamlineSP")
|
||||
{
|
||||
advectType = 1;
|
||||
stepsPerRound = static_cast<vtkm::Id>(atoi(argv[++i]));
|
||||
particlesPerRound = static_cast<vtkm::Id>(atoi(argv[++i]));
|
||||
}
|
||||
else if (arg == "-file")
|
||||
dataFile = argv[++i];
|
||||
else if (arg == "-t")
|
||||
numThreads = static_cast<vtkm::Id>(atoi(argv[++i]));
|
||||
else if (arg == "-dump")
|
||||
dumpOutput = true;
|
||||
else if (arg == "-sparse")
|
||||
seeding = SPARSE;
|
||||
else if (arg == "-dense")
|
||||
seeding = DENSE;
|
||||
else if (arg == "-medium")
|
||||
seeding = MEDIUM;
|
||||
else
|
||||
std::cerr << "Unexpected argument: " << arg << std::endl;
|
||||
}
|
||||
|
||||
if (dataFile.size() == 0)
|
||||
{
|
||||
std::cerr << "Error: no data file specified" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
//Congratulations user, we have a valid run:
|
||||
std::cerr << pgmType << ": " << numSeeds << " " << numSteps << " " << stepSize << " ";
|
||||
if (advectType == 0)
|
||||
std::cerr << "PP ";
|
||||
else
|
||||
std::cerr << "SL ";
|
||||
std::cerr << numThreads << " ";
|
||||
std::cerr << dataFile << std::endl;
|
||||
return true;
|
||||
}
|
||||
// Example computing streamlines.
|
||||
// An example vector field is available in the vtk-m data directory: magField.vtk
|
||||
// Example usage:
|
||||
// this will advect 200 particles 50 steps using a step size of 0.01
|
||||
//
|
||||
// Particle_Advection <path-to-data-dir>/magField.vtk vec 200 50 0.01 output.vtk
|
||||
//
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
// Process vtk-m general args
|
||||
auto opts = vtkm::cont::InitializeOptions::DefaultAnyDevice;
|
||||
auto config = vtkm::cont::Initialize(argc, argv, opts);
|
||||
|
||||
vtkm::Id numSeeds = 100, numSteps = 100, advectType = 0, numThreads = -1, stepsPerRound = -1,
|
||||
particlesPerRound = -1;
|
||||
vtkm::Float32 stepSize = 0.1f;
|
||||
std::string dataFile, pgmType;
|
||||
vtkm::Id seeding = SPARSE;
|
||||
bool dumpOutput = false;
|
||||
|
||||
if (!ParseArgs(argc,
|
||||
argv,
|
||||
config,
|
||||
numSeeds,
|
||||
numSteps,
|
||||
stepSize,
|
||||
advectType,
|
||||
stepsPerRound,
|
||||
particlesPerRound,
|
||||
numThreads,
|
||||
dataFile,
|
||||
pgmType,
|
||||
dumpOutput,
|
||||
seeding))
|
||||
if (argc != 7)
|
||||
{
|
||||
std::cerr << "Usage: " << argv[0] << " dataFile varName numSeeds numSteps stepSize outputFile"
|
||||
<< std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
RunTest(dataFile, numSeeds, numSteps, stepSize, numThreads, advectType, seeding);
|
||||
std::string dataFile = argv[1];
|
||||
std::string varName = argv[2];
|
||||
vtkm::Id numSeeds = std::stoi(argv[3]);
|
||||
vtkm::Id numSteps = std::stoi(argv[4]);
|
||||
vtkm::FloatDefault stepSize = std::stof(argv[5]);
|
||||
std::string outputFile = argv[6];
|
||||
|
||||
vtkm::cont::DataSet ds;
|
||||
|
||||
if (dataFile.find(".vtk") != std::string::npos)
|
||||
{
|
||||
vtkm::io::reader::VTKDataSetReader rdr(dataFile);
|
||||
ds = rdr.ReadDataSet();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Unsupported data file: " << dataFile << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
//create seeds randomly placed withing the bounding box of the data.
|
||||
vtkm::Bounds bounds = ds.GetCoordinateSystem().GetBounds();
|
||||
std::vector<vtkm::Vec3f> seeds;
|
||||
|
||||
for (int i = 0; i < numSeeds; i++)
|
||||
{
|
||||
vtkm::Vec3f p;
|
||||
vtkm::FloatDefault rx = (vtkm::FloatDefault)rand() / (vtkm::FloatDefault)RAND_MAX;
|
||||
vtkm::FloatDefault ry = (vtkm::FloatDefault)rand() / (vtkm::FloatDefault)RAND_MAX;
|
||||
vtkm::FloatDefault rz = (vtkm::FloatDefault)rand() / (vtkm::FloatDefault)RAND_MAX;
|
||||
p[0] = static_cast<vtkm::FloatDefault>(bounds.X.Min + rx * bounds.X.Length());
|
||||
p[1] = static_cast<vtkm::FloatDefault>(bounds.Y.Min + ry * bounds.Y.Length());
|
||||
p[2] = static_cast<vtkm::FloatDefault>(bounds.Z.Min + rz * bounds.Z.Length());
|
||||
seeds.push_back(p);
|
||||
}
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec3f> seedArray = vtkm::cont::make_ArrayHandle(seeds);
|
||||
|
||||
//compute streamlines
|
||||
vtkm::filter::Streamline streamline;
|
||||
|
||||
streamline.SetStepSize(stepSize);
|
||||
streamline.SetNumberOfSteps(numSteps);
|
||||
streamline.SetSeeds(seedArray);
|
||||
|
||||
streamline.SetActiveField(varName);
|
||||
auto output = streamline.Execute(ds);
|
||||
|
||||
vtkm::io::writer::VTKDataSetWriter wrt(outputFile);
|
||||
wrt.WriteDataSet(output);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -67,11 +67,11 @@ void TubeThatSpiral(vtkm::FloatDefault radius, vtkm::Id numLineSegments, vtkm::I
|
||||
// This generates a new pointset, and new cell set.
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec3f> tubePoints;
|
||||
vtkm::cont::CellSetSingleType<> tubeCells;
|
||||
tubeWorklet.Run(ds.GetCoordinateSystem(0), ds.GetCellSet(0), tubePoints, tubeCells);
|
||||
tubeWorklet.Run(ds.GetCoordinateSystem(), ds.GetCellSet(), tubePoints, tubeCells);
|
||||
|
||||
vtkm::cont::DataSet tubeDataset;
|
||||
tubeDataset.AddCoordinateSystem(vtkm::cont::CoordinateSystem("coords", tubePoints));
|
||||
tubeDataset.AddCellSet(tubeCells);
|
||||
tubeDataset.SetCellSet(tubeCells);
|
||||
|
||||
vtkm::Bounds coordsBounds = tubeDataset.GetCoordinateSystem().GetBounds();
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
#include <vtkm/ImplicitFunction.h>
|
||||
#include <vtkm/cont/Algorithm.h>
|
||||
#include <vtkm/cont/AssignerMultiBlock.h>
|
||||
#include <vtkm/cont/AssignerPartitionedDataSet.h>
|
||||
#include <vtkm/cont/BoundsGlobalCompute.h>
|
||||
#include <vtkm/cont/EnvironmentTracker.h>
|
||||
#include <vtkm/cont/Serialization.h>
|
||||
@ -204,14 +204,14 @@ public:
|
||||
~RedistributePoints() {}
|
||||
|
||||
template <typename DerivedPolicy>
|
||||
VTKM_CONT vtkm::cont::MultiBlock PrepareForExecution(
|
||||
const vtkm::cont::MultiBlock& input,
|
||||
VTKM_CONT vtkm::cont::PartitionedDataSet PrepareForExecution(
|
||||
const vtkm::cont::PartitionedDataSet& input,
|
||||
const vtkm::filter::PolicyBase<DerivedPolicy>& policy);
|
||||
};
|
||||
|
||||
template <typename DerivedPolicy>
|
||||
inline VTKM_CONT vtkm::cont::MultiBlock RedistributePoints::PrepareForExecution(
|
||||
const vtkm::cont::MultiBlock& input,
|
||||
inline VTKM_CONT vtkm::cont::PartitionedDataSet RedistributePoints::PrepareForExecution(
|
||||
const vtkm::cont::PartitionedDataSet& input,
|
||||
const vtkm::filter::PolicyBase<DerivedPolicy>& policy)
|
||||
{
|
||||
auto comm = vtkm::cont::EnvironmentTracker::GetCommunicator();
|
||||
@ -219,7 +219,7 @@ inline VTKM_CONT vtkm::cont::MultiBlock RedistributePoints::PrepareForExecution(
|
||||
// let's first get the global bounds of the domain
|
||||
vtkm::Bounds gbounds = vtkm::cont::BoundsGlobalCompute(input);
|
||||
|
||||
vtkm::cont::AssignerMultiBlock assigner(input.GetNumberOfBlocks());
|
||||
vtkm::cont::AssignerPartitionedDataSet assigner(input.GetNumberOfPartitions());
|
||||
vtkmdiy::RegularDecomposer<vtkmdiy::ContinuousBounds> decomposer(
|
||||
/*dim*/ 3, internal::convert(gbounds), assigner.nblocks());
|
||||
|
||||
@ -230,19 +230,19 @@ inline VTKM_CONT vtkm::cont::MultiBlock RedistributePoints::PrepareForExecution(
|
||||
[](void* ptr) { delete static_cast<vtkm::cont::DataSet*>(ptr); });
|
||||
decomposer.decompose(comm.rank(), assigner, master);
|
||||
|
||||
assert(static_cast<vtkm::Id>(master.size()) == input.GetNumberOfBlocks());
|
||||
assert(static_cast<vtkm::Id>(master.size()) == input.GetNumberOfPartitions());
|
||||
// let's populate local blocks
|
||||
master.foreach ([&input](vtkm::cont::DataSet* ds, const vtkmdiy::Master::ProxyWithLink& proxy) {
|
||||
auto lid = proxy.master()->lid(proxy.gid());
|
||||
*ds = input.GetBlock(lid);
|
||||
*ds = input.GetPartition(lid);
|
||||
});
|
||||
|
||||
internal::Redistributor<DerivedPolicy> redistributor(decomposer, policy);
|
||||
vtkmdiy::all_to_all(master, assigner, redistributor, /*k=*/2);
|
||||
|
||||
vtkm::cont::MultiBlock result;
|
||||
vtkm::cont::PartitionedDataSet result;
|
||||
master.foreach ([&result](vtkm::cont::DataSet* ds, const vtkmdiy::Master::ProxyWithLink&) {
|
||||
result.AddBlock(*ds);
|
||||
result.AppendPartition(*ds);
|
||||
});
|
||||
|
||||
return result;
|
||||
|
@ -8,127 +8,95 @@
|
||||
// PURPOSE. See the above copyright notice for more information.
|
||||
//============================================================================
|
||||
|
||||
#include <vtkm/cont/DataSet.h>
|
||||
#include <vtkm/cont/Initialize.h>
|
||||
|
||||
#include <vtkm/worklet/ParticleAdvection.h>
|
||||
#include <vtkm/worklet/particleadvection/Integrators.h>
|
||||
#include <vtkm/worklet/particleadvection/ParticleAdvectionWorklets.h>
|
||||
#include <vtkm/worklet/particleadvection/TemporalGridEvaluators.h>
|
||||
|
||||
#include <vtkm/cont/Timer.h>
|
||||
#include <vtkm/io/reader/BOVDataSetReader.h>
|
||||
#include <vtkm/io/writer/VTKDataSetWriter.h>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
// The way to verify if the code produces correct streamlines
|
||||
// is to do a visual test by using VisIt/ParaView to visualize
|
||||
// the file written by this method.
|
||||
int renderAndWriteDataSet(const vtkm::cont::DataSet& dataset)
|
||||
{
|
||||
std::cout << "Trying to render the dataset" << std::endl;
|
||||
vtkm::io::writer::VTKDataSetWriter writer("pathlines.vtk");
|
||||
writer.WriteDataSet(dataset);
|
||||
return 0;
|
||||
}
|
||||
#include <vtkm/cont/DataSet.h>
|
||||
#include <vtkm/cont/Initialize.h>
|
||||
#include <vtkm/cont/Timer.h>
|
||||
|
||||
#include <vtkm/filter/Pathline.h>
|
||||
|
||||
void RunTest(vtkm::Id numSteps, vtkm::Float32 stepSize, vtkm::Id advectType)
|
||||
{
|
||||
using FieldType = vtkm::Float32;
|
||||
using FieldHandle = vtkm::cont::ArrayHandle<vtkm::Vec<FieldType, 3>>;
|
||||
|
||||
// These lines read two datasets, which are BOVs.
|
||||
// Currently VTKm does not support providing time series datasets
|
||||
// In the hackiest way possible this pathlines example run using
|
||||
// two time slices. The way to provide more datasets will be explored
|
||||
// as VTKm evolves.
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<FieldType, 3>> fieldArray1;
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<FieldType, 3>> fieldArray2;
|
||||
|
||||
vtkm::io::reader::BOVDataSetReader reader1("slice1.bov");
|
||||
vtkm::cont::DataSet ds1 = reader1.ReadDataSet();
|
||||
ds1.GetField(0).GetData().CopyTo(fieldArray1);
|
||||
|
||||
vtkm::io::reader::BOVDataSetReader reader2("slice2.bov");
|
||||
vtkm::cont::DataSet ds2 = reader2.ReadDataSet();
|
||||
ds2.GetField(0).GetData().CopyTo(fieldArray2);
|
||||
|
||||
// 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<FieldHandle>;
|
||||
using Integrator = vtkm::worklet::particleadvection::EulerIntegrator<GridEvaluator>;
|
||||
|
||||
GridEvaluator eval(ds1.GetCoordinateSystem(),
|
||||
ds1.GetCellSet(0),
|
||||
fieldArray1,
|
||||
0,
|
||||
ds2.GetCoordinateSystem(),
|
||||
ds2.GetCellSet(0),
|
||||
fieldArray2,
|
||||
10.0);
|
||||
|
||||
Integrator integrator(eval, stepSize);
|
||||
|
||||
// This example does not work on scale, works on basic 11 particles
|
||||
// so the results are more tractible
|
||||
std::vector<vtkm::Vec<FieldType, 3>> seeds;
|
||||
FieldType x = 0, y = 5, z = 0;
|
||||
for (int i = 0; i <= 11; i++)
|
||||
{
|
||||
vtkm::Vec<FieldType, 3> point;
|
||||
point[0] = x;
|
||||
point[1] = y;
|
||||
point[2] = z++;
|
||||
seeds.push_back(point);
|
||||
}
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<FieldType, 3>> seedArray;
|
||||
seedArray = vtkm::cont::make_ArrayHandle(seeds);
|
||||
|
||||
if (advectType == 0)
|
||||
{
|
||||
vtkm::worklet::ParticleAdvection particleAdvection;
|
||||
particleAdvection.Run(integrator, seedArray, numSteps);
|
||||
}
|
||||
else
|
||||
{
|
||||
vtkm::worklet::Streamline streamline;
|
||||
vtkm::worklet::StreamlineResult res = streamline.Run(integrator, seedArray, numSteps);
|
||||
vtkm::cont::DataSet outData;
|
||||
vtkm::cont::CoordinateSystem outputCoords("coordinates", res.positions);
|
||||
outData.AddCellSet(res.polyLines);
|
||||
outData.AddCoordinateSystem(outputCoords);
|
||||
renderAndWriteDataSet(outData);
|
||||
}
|
||||
}
|
||||
#include <vtkm/io/reader/VTKDataSetReader.h>
|
||||
#include <vtkm/io/writer/VTKDataSetWriter.h>
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
auto opts = vtkm::cont::InitializeOptions::DefaultAnyDevice;
|
||||
auto config = vtkm::cont::Initialize(argc, argv, opts);
|
||||
|
||||
std::cout << "TemporalAdvection Example" << std::endl;
|
||||
std::cout << "Parameters are [options] numSteps stepSize advectionType" << std::endl << std::endl;
|
||||
std::cout << "advectionType Particles=0 Streamlines=1" << std::endl;
|
||||
// Sample data to use this example can be found in the data directory of the
|
||||
// VTK-m repo in the location temporal_datasets.
|
||||
// These example with these datasets can be used for this example as :
|
||||
// ./Temporal_Advection DoubleGyre_0.vtk 0.0 DoubleGyre_5.vtk 5.0
|
||||
// velocity 500 0.025 pathlines.vtk
|
||||
std::cout
|
||||
<< "Parameters : [options] slice1 time1 slice2 time2 field num_steps step_size output\n"
|
||||
<< "slice1 : Time slice 1, sample data in vtk-m/data/temporal_datasets/Double_Gyre0.vtk\n"
|
||||
<< "time1 : simulation time for slice 1, for sample data use 0.0\n"
|
||||
<< "slice2 : Time slice 2, sample data in vtk-m/data/temporal_datasets/Double_Gyre5.vtk\n"
|
||||
<< "time2 : simulation time for slice 2, for sample data use 5.0\n"
|
||||
<< "field : active velocity field in the data set, for sample data use 'velocity'\n"
|
||||
<< "num_steps : maximum number of steps for advection, for sample data use 500\n"
|
||||
<< "step_size : the size of a single step during advection, for sample data use 0.025\n"
|
||||
<< "output : the name of the output file" << std::endl;
|
||||
|
||||
vtkm::Id numSteps;
|
||||
vtkm::Float32 stepSize;
|
||||
vtkm::Id advectionType;
|
||||
|
||||
if (argc < 4)
|
||||
if (argc < 8)
|
||||
{
|
||||
std::cout << "Wrong number of parameters provided" << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
numSteps = atoi(argv[1]);
|
||||
stepSize = static_cast<vtkm::Float32>(atof(argv[2]));
|
||||
advectionType = atoi(argv[3]);
|
||||
std::string fieldName, datasetName1, datasetName2, outputName;
|
||||
vtkm::FloatDefault time1, time2;
|
||||
|
||||
RunTest(numSteps, stepSize, advectionType);
|
||||
vtkm::Id numSteps;
|
||||
vtkm::Float32 stepSize;
|
||||
|
||||
datasetName1 = std::string(argv[1]);
|
||||
time1 = static_cast<vtkm::FloatDefault>(atof(argv[2]));
|
||||
datasetName2 = std::string(argv[3]);
|
||||
time2 = static_cast<vtkm::FloatDefault>(atof(argv[4]));
|
||||
fieldName = std::string(argv[5]);
|
||||
numSteps = atoi(argv[6]);
|
||||
stepSize = static_cast<vtkm::Float32>(atof(argv[7]));
|
||||
outputName = std::string(argv[8]);
|
||||
|
||||
vtkm::io::reader::VTKDataSetReader reader1(datasetName1);
|
||||
vtkm::cont::DataSet ds1 = reader1.ReadDataSet();
|
||||
|
||||
vtkm::io::reader::VTKDataSetReader reader2(datasetName2);
|
||||
vtkm::cont::DataSet ds2 = reader2.ReadDataSet();
|
||||
|
||||
// Use the coordinate system as seeds for performing advection
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec3f> seeds;
|
||||
vtkm::cont::ArrayCopy(ds1.GetCoordinateSystem().GetData(), seeds);
|
||||
|
||||
// Instantiate the filter by providing necessary parameters.
|
||||
// Necessary parameters are :
|
||||
vtkm::filter::Pathline pathlineFilter;
|
||||
pathlineFilter.SetActiveField(fieldName);
|
||||
// 1. The current and next time slice. The current time slice is passed
|
||||
// through the parameter to the Execute method.
|
||||
pathlineFilter.SetNextDataSet(ds2);
|
||||
// 2. The current and next times, these times will be used to interpolate
|
||||
// the velocities for particle positions in space and time.
|
||||
pathlineFilter.SetCurrentTime(time1);
|
||||
pathlineFilter.SetNextTime(time2);
|
||||
// 3. Maximum number of steps the particle is allowed to take until termination.
|
||||
pathlineFilter.SetNumberOfSteps(numSteps);
|
||||
// 4. Length for each step.
|
||||
pathlineFilter.SetStepSize(stepSize);
|
||||
// 5. Seeds for advection.
|
||||
pathlineFilter.SetSeeds(seeds);
|
||||
|
||||
vtkm::cont::DataSet output = pathlineFilter.Execute(ds1);
|
||||
|
||||
// The way to verify if the code produces correct streamlines
|
||||
// is to do a visual test by using VisIt/ParaView to visualize
|
||||
// the file written by this method.
|
||||
vtkm::io::writer::VTKDataSetWriter writer(outputName);
|
||||
writer.WriteDataSet(output);
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,64 +0,0 @@
|
||||
//============================================================================
|
||||
// Copyright (c) Kitware, Inc.
|
||||
// All rights reserved.
|
||||
// See LICENSE.txt for details.
|
||||
//
|
||||
// This software is distributed WITHOUT ANY WARRANTY; without even
|
||||
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the above copyright notice for more information.
|
||||
//============================================================================
|
||||
#ifndef vtk_m_BaseComponent_h
|
||||
#define vtk_m_BaseComponent_h
|
||||
|
||||
#include <vtkm/Matrix.h>
|
||||
#include <vtkm/TypeTraits.h>
|
||||
#include <vtkm/VecTraits.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <typename VecType, typename DimensionalityTag>
|
||||
struct BaseComponentImpl;
|
||||
|
||||
template <typename VecType>
|
||||
struct BaseComponentImpl<VecType, vtkm::TypeTraitsVectorTag>
|
||||
{
|
||||
private:
|
||||
using ComponentType = typename vtkm::VecTraits<VecType>::ComponentType;
|
||||
|
||||
public:
|
||||
using Type =
|
||||
typename BaseComponentImpl<ComponentType,
|
||||
typename vtkm::TypeTraits<ComponentType>::DimensionalityTag>::Type;
|
||||
};
|
||||
|
||||
template <typename VecType>
|
||||
struct BaseComponentImpl<VecType, vtkm::TypeTraitsMatrixTag>
|
||||
: BaseComponentImpl<VecType, vtkm::TypeTraitsVectorTag>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename ScalarType>
|
||||
struct BaseComponentImpl<ScalarType, vtkm::TypeTraitsScalarTag>
|
||||
{
|
||||
using Type = ScalarType;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// Finds the base component type of a Vec. If you have a Vec of Vecs, it will
|
||||
// descend all Vecs until you get to the scalar type.
|
||||
template <typename VecType>
|
||||
struct BaseComponent
|
||||
{
|
||||
using Type =
|
||||
typename detail::BaseComponentImpl<VecType,
|
||||
typename vtkm::TypeTraits<VecType>::DimensionalityTag>::Type;
|
||||
};
|
||||
|
||||
} // namespace vtkm
|
||||
|
||||
#endif //vtk_m_BaseComponent_h
|
@ -18,7 +18,6 @@ vtkm_install_headers(
|
||||
|
||||
set(headers
|
||||
Assert.h
|
||||
BaseComponent.h
|
||||
BinaryPredicates.h
|
||||
BinaryOperators.h
|
||||
Bitset.h
|
||||
|
@ -103,13 +103,10 @@ struct ListTagEmpty : detail::ListRoot
|
||||
|
||||
/// A tag that is a construction of two other tags joined together. This struct
|
||||
/// can be subclassed and still behave like a list tag.
|
||||
template <typename ListTag1, typename ListTag2>
|
||||
template <typename... ListTags>
|
||||
struct ListTagJoin : detail::ListRoot
|
||||
{
|
||||
VTKM_IS_LIST_TAG(ListTag1);
|
||||
VTKM_IS_LIST_TAG(ListTag2);
|
||||
using list = typename detail::ListJoin<internal::ListTagAsBrigandList<ListTag1>,
|
||||
internal::ListTagAsBrigandList<ListTag2>>::type;
|
||||
using list = typename detail::ListJoin<internal::ListTagAsBrigandList<ListTags>...>::type;
|
||||
};
|
||||
|
||||
|
||||
|
@ -541,6 +541,7 @@ private:
|
||||
|
||||
public:
|
||||
using ComponentType = T;
|
||||
using BaseComponentType = typename vtkm::VecTraits<T>::BaseComponentType;
|
||||
static constexpr vtkm::IdComponent NUM_COMPONENTS = NumRow * NumCol;
|
||||
using HasMultipleComponents = vtkm::VecTraitsTagMultipleComponents;
|
||||
using IsSizeStatic = vtkm::VecTraitsTagSizeStatic;
|
||||
@ -567,6 +568,15 @@ public:
|
||||
{
|
||||
GetComponent(matrix, component) = value;
|
||||
}
|
||||
|
||||
template <typename NewComponentType>
|
||||
using ReplaceComponentType = vtkm::Matrix<NewComponentType, NumRow, NumCol>;
|
||||
|
||||
template <typename NewComponentType>
|
||||
using ReplaceBaseComponentType =
|
||||
vtkm::Matrix<typename vtkm::VecTraits<T>::template ReplaceBaseComponentType<NewComponentType>,
|
||||
NumRow,
|
||||
NumCol>;
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -147,6 +147,7 @@ struct VecTraits<vtkm::VecAxisAlignedPointCoordinates<NumDimensions>>
|
||||
using VecType = vtkm::VecAxisAlignedPointCoordinates<NumDimensions>;
|
||||
|
||||
using ComponentType = vtkm::Vec3f;
|
||||
using BaseComponentType = vtkm::FloatDefault;
|
||||
using HasMultipleComponents = vtkm::VecTraitsTagMultipleComponents;
|
||||
using IsSizeStatic = vtkm::VecTraitsTagSizeStatic;
|
||||
|
||||
@ -161,6 +162,13 @@ struct VecTraits<vtkm::VecAxisAlignedPointCoordinates<NumDimensions>>
|
||||
return vector[componentIndex];
|
||||
}
|
||||
|
||||
// These are a bit of a hack since VecAxisAlignedPointCoordinates only supports one component
|
||||
// type. Using these might not work as expected.
|
||||
template <typename NewComponentType>
|
||||
using ReplaceComponentType = vtkm::Vec<NewComponentType, NUM_COMPONENTS>;
|
||||
template <typename NewComponentType>
|
||||
using ReplaceBaseComponenttype = vtkm::Vec<vtkm::Vec<NewComponentType, 3>, NUM_COMPONENTS>;
|
||||
|
||||
template <vtkm::IdComponent destSize>
|
||||
VTKM_EXEC_CONT static void CopyInto(const VecType& src, vtkm::Vec<ComponentType, destSize>& dest)
|
||||
{
|
||||
|
@ -99,6 +99,7 @@ struct VecTraits<vtkm::VecFromPortal<PortalType>>
|
||||
using VecType = vtkm::VecFromPortal<PortalType>;
|
||||
|
||||
using ComponentType = typename VecType::ComponentType;
|
||||
using BaseComponentType = typename vtkm::VecTraits<ComponentType>::BaseComponentType;
|
||||
using HasMultipleComponents = vtkm::VecTraitsTagMultipleComponents;
|
||||
using IsSizeStatic = vtkm::VecTraitsTagSizeVariable;
|
||||
|
||||
|
@ -136,6 +136,7 @@ struct VecTraits<vtkm::VecFromPortalPermute<IndexVecType, PortalType>>
|
||||
using VecType = vtkm::VecFromPortalPermute<IndexVecType, PortalType>;
|
||||
|
||||
using ComponentType = typename VecType::ComponentType;
|
||||
using BaseComponentType = typename vtkm::VecTraits<ComponentType>::BaseComponentType;
|
||||
using HasMultipleComponents = vtkm::VecTraitsTagMultipleComponents;
|
||||
using IsSizeStatic = vtkm::VecTraitsTagSizeVariable;
|
||||
|
||||
|
133
vtkm/VecTraits.h
133
vtkm/VecTraits.h
@ -66,10 +66,19 @@ template <class VecType>
|
||||
struct VTKM_NEVER_EXPORT VecTraits
|
||||
{
|
||||
#ifdef VTKM_DOXYGEN_ONLY
|
||||
/// Type of the components in the vector.
|
||||
/// \brief Type of the components in the vector.
|
||||
///
|
||||
/// If the type is really a scalar, then the component type is the same as the scalar type.
|
||||
///
|
||||
using ComponentType = typename VecType::ComponentType;
|
||||
|
||||
/// \brief Base component type in the vector.
|
||||
///
|
||||
/// Similar to ComponentType except that for nested vectors (e.g. Vec<Vec<T, M>, N>), it
|
||||
/// returns the base scalar type at the end of the composition (T in this example).
|
||||
///
|
||||
using BaseComponentType = typename vtkm::VecTraits<ComponentType>::BaseComponentType;
|
||||
|
||||
/// \brief Number of components in the vector.
|
||||
///
|
||||
/// This is only defined for vectors of a static size.
|
||||
@ -111,6 +120,27 @@ struct VTKM_NEVER_EXPORT VecTraits
|
||||
vtkm::IdComponent component,
|
||||
ComponentType value);
|
||||
|
||||
/// \brief Get a vector of the same type but with a different component.
|
||||
///
|
||||
/// This type resolves to another vector with a different component type. For example,
|
||||
/// vtkm::VecTraits<vtkm::Vec<T, N>>::ReplaceComponentType<T2> is vtkm::Vec<T2, N>.
|
||||
/// This replacement is not recursive. So VecTraits<Vec<Vec<T, M>, N>::ReplaceComponentType<T2>
|
||||
/// is vtkm::Vec<T2, N>.
|
||||
///
|
||||
template <typename NewComponentType>
|
||||
using ReplaceComponentType = VecTemplate<NewComponentType, N>;
|
||||
|
||||
/// \brief Get a vector of the same type but with a different base component.
|
||||
///
|
||||
/// This type resolves to another vector with a different base component type. The replacement
|
||||
/// is recursive for nested types. For example,
|
||||
/// VecTraits<Vec<Vec<T, M>, N>::ReplaceComponentType<T2> is Vec<Vec<T2, M>, N>.
|
||||
///
|
||||
template <typename NewComponentType>
|
||||
using ReplaceBaseComponentType = VecTemplate<
|
||||
typename VecTraits<ComponentType>::template ReplaceBaseComponentType<NewComponentType>,
|
||||
N>;
|
||||
|
||||
/// Copies the components in the given vector into a given Vec object.
|
||||
///
|
||||
template <vktm::IdComponent destSize>
|
||||
@ -158,10 +188,19 @@ struct VTKM_NEVER_EXPORT VecTraits<vtkm::Vec<T, Size>>
|
||||
{
|
||||
using VecType = vtkm::Vec<T, Size>;
|
||||
|
||||
/// Type of the components in the vector.
|
||||
/// \brief Type of the components in the vector.
|
||||
///
|
||||
/// If the type is really a scalar, then the component type is the same as the scalar type.
|
||||
///
|
||||
using ComponentType = typename VecType::ComponentType;
|
||||
|
||||
/// \brief Base component type in the vector.
|
||||
///
|
||||
/// Similar to ComponentType except that for nested vectors (e.g. Vec<Vec<T, M>, N>), it
|
||||
/// returns the base scalar type at the end of the composition (T in this example).
|
||||
///
|
||||
using BaseComponentType = typename vtkm::VecTraits<ComponentType>::BaseComponentType;
|
||||
|
||||
/// Number of components in the vector.
|
||||
///
|
||||
static constexpr vtkm::IdComponent NUM_COMPONENTS = VecType::NUM_COMPONENTS;
|
||||
@ -208,6 +247,27 @@ struct VTKM_NEVER_EXPORT VecTraits<vtkm::Vec<T, Size>>
|
||||
vector[component] = value;
|
||||
}
|
||||
|
||||
/// \brief Get a vector of the same type but with a different component.
|
||||
///
|
||||
/// This type resolves to another vector with a different component type. For example,
|
||||
/// vtkm::VecTraits<vtkm::Vec<T, N>>::ReplaceComponentType<T2> is vtkm::Vec<T2, N>.
|
||||
/// This replacement is not recursive. So VecTraits<Vec<Vec<T, M>, N>::ReplaceComponentType<T2>
|
||||
/// is vtkm::Vec<T2, N>.
|
||||
///
|
||||
template <typename NewComponentType>
|
||||
using ReplaceComponentType = vtkm::Vec<NewComponentType, Size>;
|
||||
|
||||
/// \brief Get a vector of the same type but with a different base component.
|
||||
///
|
||||
/// This type resolves to another vector with a different base component type. The replacement
|
||||
/// is recursive for nested types. For example,
|
||||
/// VecTraits<Vec<Vec<T, M>, N>::ReplaceComponentType<T2> is Vec<Vec<T2, M>, N>.
|
||||
///
|
||||
template <typename NewComponentType>
|
||||
using ReplaceBaseComponentType = vtkm::Vec<
|
||||
typename vtkm::VecTraits<ComponentType>::template ReplaceBaseComponentType<NewComponentType>,
|
||||
Size>;
|
||||
|
||||
/// Converts whatever type this vector is into the standard VTKm Tuple.
|
||||
///
|
||||
template <vtkm::IdComponent destSize>
|
||||
@ -222,10 +282,19 @@ struct VTKM_NEVER_EXPORT VecTraits<vtkm::VecC<T>>
|
||||
{
|
||||
using VecType = vtkm::VecC<T>;
|
||||
|
||||
/// Type of the components in the vector.
|
||||
/// \brief Type of the components in the vector.
|
||||
///
|
||||
/// If the type is really a scalar, then the component type is the same as the scalar type.
|
||||
///
|
||||
using ComponentType = typename VecType::ComponentType;
|
||||
|
||||
/// \brief Base component type in the vector.
|
||||
///
|
||||
/// Similar to ComponentType except that for nested vectors (e.g. Vec<Vec<T, M>, N>), it
|
||||
/// returns the base scalar type at the end of the composition (T in this example).
|
||||
///
|
||||
using BaseComponentType = typename vtkm::VecTraits<ComponentType>::BaseComponentType;
|
||||
|
||||
/// Number of components in the given vector.
|
||||
///
|
||||
VTKM_EXEC_CONT
|
||||
@ -273,6 +342,26 @@ struct VTKM_NEVER_EXPORT VecTraits<vtkm::VecC<T>>
|
||||
vector[component] = value;
|
||||
}
|
||||
|
||||
/// \brief Get a vector of the same type but with a different component.
|
||||
///
|
||||
/// This type resolves to another vector with a different component type. For example,
|
||||
/// vtkm::VecTraits<vtkm::Vec<T, N>>::ReplaceComponentType<T2> is vtkm::Vec<T2, N>.
|
||||
/// This replacement is not recursive. So VecTraits<Vec<Vec<T, M>, N>::ReplaceComponentType<T2>
|
||||
/// is vtkm::Vec<T2, N>.
|
||||
///
|
||||
template <typename NewComponentType>
|
||||
using ReplaceComponentType = vtkm::VecC<NewComponentType>;
|
||||
|
||||
/// \brief Get a vector of the same type but with a different base component.
|
||||
///
|
||||
/// This type resolves to another vector with a different base component type. The replacement
|
||||
/// is recursive for nested types. For example,
|
||||
/// VecTraits<Vec<Vec<T, M>, N>::ReplaceComponentType<T2> is Vec<Vec<T2, M>, N>.
|
||||
///
|
||||
template <typename NewComponentType>
|
||||
using ReplaceBaseComponentType = vtkm::VecC<
|
||||
typename vtkm::VecTraits<ComponentType>::template ReplaceBaseComponentType<NewComponentType>>;
|
||||
|
||||
/// Converts whatever type this vector is into the standard VTKm Tuple.
|
||||
///
|
||||
template <vtkm::IdComponent destSize>
|
||||
@ -287,10 +376,19 @@ struct VTKM_NEVER_EXPORT VecTraits<vtkm::VecCConst<T>>
|
||||
{
|
||||
using VecType = vtkm::VecCConst<T>;
|
||||
|
||||
/// Type of the components in the vector.
|
||||
/// \brief Type of the components in the vector.
|
||||
///
|
||||
/// If the type is really a scalar, then the component type is the same as the scalar type.
|
||||
///
|
||||
using ComponentType = typename VecType::ComponentType;
|
||||
|
||||
/// \brief Base component type in the vector.
|
||||
///
|
||||
/// Similar to ComponentType except that for nested vectors (e.g. Vec<Vec<T, M>, N>), it
|
||||
/// returns the base scalar type at the end of the composition (T in this example).
|
||||
///
|
||||
using BaseComponentType = typename vtkm::VecTraits<ComponentType>::BaseComponentType;
|
||||
|
||||
/// Number of components in the given vector.
|
||||
///
|
||||
VTKM_EXEC_CONT
|
||||
@ -333,6 +431,26 @@ struct VTKM_NEVER_EXPORT VecTraits<vtkm::VecCConst<T>>
|
||||
vector[component] = value;
|
||||
}
|
||||
|
||||
/// \brief Get a vector of the same type but with a different component.
|
||||
///
|
||||
/// This type resolves to another vector with a different component type. For example,
|
||||
/// vtkm::VecTraits<vtkm::Vec<T, N>>::ReplaceComponentType<T2> is vtkm::Vec<T2, N>.
|
||||
/// This replacement is not recursive. So VecTraits<Vec<Vec<T, M>, N>::ReplaceComponentType<T2>
|
||||
/// is vtkm::Vec<T2, N>.
|
||||
///
|
||||
template <typename NewComponentType>
|
||||
using ReplaceComponentType = vtkm::VecCConst<NewComponentType>;
|
||||
|
||||
/// \brief Get a vector of the same type but with a different base component.
|
||||
///
|
||||
/// This type resolves to another vector with a different base component type. The replacement
|
||||
/// is recursive for nested types. For example,
|
||||
/// VecTraits<Vec<Vec<T, M>, N>::ReplaceComponentType<T2> is Vec<Vec<T2, M>, N>.
|
||||
///
|
||||
template <typename NewComponentType>
|
||||
using ReplaceBaseComponentType = vtkm::VecCConst<
|
||||
typename vtkm::VecTraits<ComponentType>::template ReplaceBaseComponentType<NewComponentType>>;
|
||||
|
||||
/// Converts whatever type this vector is into the standard VTKm Tuple.
|
||||
///
|
||||
template <vtkm::IdComponent destSize>
|
||||
@ -350,6 +468,7 @@ template <typename ScalarType>
|
||||
struct VTKM_NEVER_EXPORT VecTraitsBasic
|
||||
{
|
||||
using ComponentType = ScalarType;
|
||||
using BaseComponentType = ScalarType;
|
||||
static constexpr vtkm::IdComponent NUM_COMPONENTS = 1;
|
||||
using HasMultipleComponents = vtkm::VecTraitsTagSingleComponent;
|
||||
using IsSizeStatic = vtkm::VecTraitsTagSizeStatic;
|
||||
@ -372,6 +491,12 @@ struct VTKM_NEVER_EXPORT VecTraitsBasic
|
||||
vector = value;
|
||||
}
|
||||
|
||||
template <typename NewComponentType>
|
||||
using ReplaceComponentType = NewComponentType;
|
||||
|
||||
template <typename NewComponentType>
|
||||
using ReplaceBaseComponentType = NewComponentType;
|
||||
|
||||
template <vtkm::IdComponent destSize>
|
||||
VTKM_EXEC_CONT static void CopyInto(const ScalarType& src, vtkm::Vec<ScalarType, destSize>& dest)
|
||||
{
|
||||
|
@ -103,6 +103,7 @@ struct VecTraits<vtkm::VecVariable<T, MaxSize>>
|
||||
using VecType = vtkm::VecVariable<T, MaxSize>;
|
||||
|
||||
using ComponentType = typename VecType::ComponentType;
|
||||
using BaseComponentType = typename vtkm::VecTraits<ComponentType>::BaseComponentType;
|
||||
using HasMultipleComponents = vtkm::VecTraitsTagMultipleComponents;
|
||||
using IsSizeStatic = vtkm::VecTraitsTagSizeVariable;
|
||||
|
||||
@ -131,6 +132,14 @@ struct VecTraits<vtkm::VecVariable<T, MaxSize>>
|
||||
vector[componentIndex] = value;
|
||||
}
|
||||
|
||||
template <typename NewComponentType>
|
||||
using ReplaceComponentType = vtkm::VecVariable<NewComponentType, MaxSize>;
|
||||
|
||||
template <typename NewComponentType>
|
||||
using ReplaceBaseComponentType = vtkm::VecVariable<
|
||||
typename vtkm::VecTraits<ComponentType>::template ReplaceBaseComponentType<NewComponentType>,
|
||||
MaxSize>;
|
||||
|
||||
template <vtkm::IdComponent destSize>
|
||||
VTKM_EXEC_CONT static void CopyInto(const VecType& src, vtkm::Vec<ComponentType, destSize>& dest)
|
||||
{
|
||||
|
@ -317,6 +317,19 @@ struct ScanExclusiveByKeyFunctor
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct ScanExtendedFunctor
|
||||
{
|
||||
template <typename Device, typename... Args>
|
||||
VTKM_CONT bool operator()(Device, Args&&... args)
|
||||
{
|
||||
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::ScanExtended(
|
||||
PrepareArgForExec<Device>(std::forward<Args>(args))...);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
struct ScheduleFunctor
|
||||
{
|
||||
template <typename Device, typename... Args>
|
||||
@ -976,6 +989,42 @@ struct Algorithm
|
||||
}
|
||||
|
||||
|
||||
template <typename T, class CIn, class COut>
|
||||
VTKM_CONT static void ScanExtended(vtkm::cont::DeviceAdapterId devId,
|
||||
const vtkm::cont::ArrayHandle<T, CIn>& input,
|
||||
vtkm::cont::ArrayHandle<T, COut>& output)
|
||||
{
|
||||
detail::ScanExtendedFunctor<T> functor;
|
||||
vtkm::cont::TryExecuteOnDevice(devId, functor, input, output);
|
||||
}
|
||||
template <typename T, class CIn, class COut>
|
||||
VTKM_CONT static void ScanExtended(const vtkm::cont::ArrayHandle<T, CIn>& input,
|
||||
vtkm::cont::ArrayHandle<T, COut>& output)
|
||||
{
|
||||
ScanExtended(vtkm::cont::DeviceAdapterTagAny(), input, output);
|
||||
}
|
||||
|
||||
|
||||
template <typename T, class CIn, class COut, class BinaryFunctor>
|
||||
VTKM_CONT static void ScanExtended(vtkm::cont::DeviceAdapterId devId,
|
||||
const vtkm::cont::ArrayHandle<T, CIn>& input,
|
||||
vtkm::cont::ArrayHandle<T, COut>& output,
|
||||
BinaryFunctor binaryFunctor,
|
||||
const T& initialValue)
|
||||
{
|
||||
detail::ScanExtendedFunctor<T> functor;
|
||||
vtkm::cont::TryExecuteOnDevice(devId, functor, input, output, binaryFunctor, initialValue);
|
||||
}
|
||||
template <typename T, class CIn, class COut, class BinaryFunctor>
|
||||
VTKM_CONT static void ScanExtended(const vtkm::cont::ArrayHandle<T, CIn>& input,
|
||||
vtkm::cont::ArrayHandle<T, COut>& output,
|
||||
BinaryFunctor binaryFunctor,
|
||||
const T& initialValue)
|
||||
{
|
||||
ScanExtended(vtkm::cont::DeviceAdapterTagAny(), input, output, binaryFunctor, initialValue);
|
||||
}
|
||||
|
||||
|
||||
template <class Functor>
|
||||
VTKM_CONT static void Schedule(vtkm::cont::DeviceAdapterId devId,
|
||||
Functor functor,
|
||||
|
@ -23,23 +23,16 @@ namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
/// \brief Does a deep copy from one array to another array.
|
||||
///
|
||||
/// Given a source \c ArrayHandle and a destination \c ArrayHandle, this function allocates the
|
||||
/// destination \c ArrayHandle to the correct size and deeply copies all the values from the source
|
||||
/// to the destination.
|
||||
///
|
||||
/// This method will attempt to copy the data using the device that the input
|
||||
/// data is already valid on. If the input data is only valid in the control
|
||||
/// environment, the runtime device tracker is used to try to find another
|
||||
/// device.
|
||||
///
|
||||
template <typename InValueType, typename InStorage, typename OutValueType, typename OutStorage>
|
||||
VTKM_CONT inline void ArrayCopy(const vtkm::cont::ArrayHandle<InValueType, InStorage>& source,
|
||||
vtkm::cont::ArrayHandle<OutValueType, OutStorage>& destination)
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// normal element-wise copy:
|
||||
template <typename InArrayType, typename OutArrayType>
|
||||
void ArrayCopyImpl(const InArrayType& in, OutArrayType& out, std::false_type /* Copy storage */)
|
||||
{
|
||||
// Find the device that already has a copy of the data:
|
||||
vtkm::cont::DeviceAdapterId devId = source.GetDeviceAdapterId();
|
||||
vtkm::cont::DeviceAdapterId devId = in.GetDeviceAdapterId();
|
||||
|
||||
// If the data is not on any device, let the runtime tracker pick an available
|
||||
// parallel copy algorithm.
|
||||
@ -48,14 +41,14 @@ VTKM_CONT inline void ArrayCopy(const vtkm::cont::ArrayHandle<InValueType, InSto
|
||||
devId = vtkm::cont::make_DeviceAdapterId(VTKM_DEVICE_ADAPTER_ANY);
|
||||
}
|
||||
|
||||
bool success = vtkm::cont::Algorithm::Copy(devId, source, destination);
|
||||
bool success = vtkm::cont::Algorithm::Copy(devId, in, out);
|
||||
|
||||
if (!success && devId.GetValue() != VTKM_DEVICE_ADAPTER_ANY)
|
||||
{ // Retry on any device if the first attempt failed.
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Error,
|
||||
"Failed to run ArrayCopy on device '" << devId.GetName()
|
||||
<< "'. Retrying on any device.");
|
||||
success = vtkm::cont::Algorithm::Copy(vtkm::cont::DeviceAdapterTagAny{}, source, destination);
|
||||
success = vtkm::cont::Algorithm::Copy(vtkm::cont::DeviceAdapterTagAny{}, in, out);
|
||||
}
|
||||
|
||||
if (!success)
|
||||
@ -63,6 +56,60 @@ VTKM_CONT inline void ArrayCopy(const vtkm::cont::ArrayHandle<InValueType, InSto
|
||||
throw vtkm::cont::ErrorExecution("Failed to run ArrayCopy on any device.");
|
||||
}
|
||||
}
|
||||
|
||||
// Copy storage for implicit arrays, must be of same type:
|
||||
template <typename ArrayType>
|
||||
void ArrayCopyImpl(const ArrayType& in, ArrayType& out, std::true_type /* Copy storage */)
|
||||
{
|
||||
// This is only called if in/out are the same type and the handle is not
|
||||
// writable. This allows read-only implicit array handles to be copied.
|
||||
auto newStorage = in.GetStorage();
|
||||
out = ArrayType(newStorage);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/// \brief Does a deep copy from one array to another array.
|
||||
///
|
||||
/// Given a source \c ArrayHandle and a destination \c ArrayHandle, this
|
||||
/// function allocates the destination \c ArrayHandle to the correct size and
|
||||
/// deeply copies all the values from the source to the destination.
|
||||
///
|
||||
/// This method will attempt to copy the data using the device that the input
|
||||
/// data is already valid on. If the input data is only valid in the control
|
||||
/// environment, the runtime device tracker is used to try to find another
|
||||
/// device.
|
||||
///
|
||||
/// This should work on some non-writable array handles as well, as long as
|
||||
/// both \a source and \a destination are the same type.
|
||||
///
|
||||
template <typename InValueType, typename InStorage, typename OutValueType, typename OutStorage>
|
||||
VTKM_CONT void ArrayCopy(const vtkm::cont::ArrayHandle<InValueType, InStorage>& source,
|
||||
vtkm::cont::ArrayHandle<OutValueType, OutStorage>& destination)
|
||||
{
|
||||
using InArrayType = vtkm::cont::ArrayHandle<InValueType, InStorage>;
|
||||
using OutArrayType = vtkm::cont::ArrayHandle<OutValueType, OutStorage>;
|
||||
using SameTypes = std::is_same<InArrayType, OutArrayType>;
|
||||
using IsWritable = vtkm::cont::internal::IsWritableArrayHandle<OutArrayType>;
|
||||
|
||||
// There are three cases handled here:
|
||||
// 1. Output is writable:
|
||||
// -> Do element-wise copy (normal copy behavior)
|
||||
// 2. Output is not writable and arrays are same type:
|
||||
// -> just copy storage (special case for implicit array cloning)
|
||||
// 3. Output is not writable and arrays are different types:
|
||||
// -> fail (cannot copy)
|
||||
|
||||
// Give a nice error message for case 3:
|
||||
VTKM_STATIC_ASSERT_MSG(IsWritable::value || SameTypes::value,
|
||||
"Cannot copy to a read-only array with a different "
|
||||
"type than the source.");
|
||||
|
||||
using JustCopyStorage = std::integral_constant<bool, SameTypes::value && !IsWritable::value>;
|
||||
|
||||
// Static dispatch cases 1 & 2
|
||||
detail::ArrayCopyImpl(source, destination, JustCopyStorage{});
|
||||
}
|
||||
}
|
||||
} // namespace vtkm::cont
|
||||
|
||||
|
@ -74,15 +74,11 @@ struct IsInValidArrayHandle
|
||||
{
|
||||
};
|
||||
|
||||
/// Checks to see if the ArrayHandle allows
|
||||
/// writing, as some ArrayHandles (Implicit) don't support writing.
|
||||
/// This check is compatible with the C++11 type_traits.
|
||||
/// It contains a typedef named type that is either
|
||||
/// std::true_type or std::false_type.
|
||||
/// Both of these have a typedef named value with the respective boolean value.
|
||||
///
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <typename ArrayHandle>
|
||||
struct IsWritableArrayHandle
|
||||
struct IsWritableArrayHandleImpl
|
||||
{
|
||||
private:
|
||||
template <typename U,
|
||||
@ -98,6 +94,17 @@ public:
|
||||
using type = decltype(hasSet<PortalType>(0));
|
||||
static constexpr bool value = type::value;
|
||||
};
|
||||
}
|
||||
|
||||
/// Checks to see if the ArrayHandle allows
|
||||
/// writing, as some ArrayHandles (Implicit) don't support writing.
|
||||
/// This check is compatible with the C++11 type_traits.
|
||||
/// It contains a typedef named type that is either
|
||||
/// std::true_type or std::false_type.
|
||||
/// Both of these have a typedef named value with the respective boolean value.
|
||||
///
|
||||
template <typename ArrayHandle>
|
||||
using IsWritableArrayHandle = typename detail::IsWritableArrayHandleImpl<ArrayHandle>::type;
|
||||
|
||||
/// Checks to see if the given object is an array handle. This check is
|
||||
/// compatible with C++11 type_traits. It a typedef named \c type that is
|
||||
|
@ -14,8 +14,8 @@
|
||||
|
||||
#include <vtkm/cont/Logging.h>
|
||||
|
||||
#include <vtkm/BaseComponent.h>
|
||||
#include <vtkm/Range.h>
|
||||
#include <vtkm/VecTraits.h>
|
||||
|
||||
#include <limits>
|
||||
|
||||
@ -70,8 +70,8 @@ private:
|
||||
{
|
||||
#ifdef VTKM_ENABLE_LOGGING
|
||||
using DstValueType = T;
|
||||
using SrcComp = typename vtkm::BaseComponent<SrcValueType>::Type;
|
||||
using DstComp = typename vtkm::BaseComponent<DstValueType>::Type;
|
||||
using SrcComp = typename vtkm::VecTraits<SrcValueType>::BaseComponentType;
|
||||
using DstComp = typename vtkm::VecTraits<DstValueType>::BaseComponentType;
|
||||
using SrcLimits = std::numeric_limits<SrcComp>;
|
||||
using DstLimits = std::numeric_limits<DstComp>;
|
||||
|
||||
|
@ -41,6 +41,7 @@ struct ArrayPortalMultiplexerGetNumberOfValuesFunctor
|
||||
|
||||
struct ArrayPortalMultiplexerGetFunctor
|
||||
{
|
||||
VTKM_SUPPRESS_EXEC_WARNINGS
|
||||
template <typename PortalType>
|
||||
VTKM_EXEC_CONT typename PortalType::ValueType operator()(const PortalType& portal,
|
||||
vtkm::Id index) const noexcept
|
||||
@ -51,6 +52,7 @@ struct ArrayPortalMultiplexerGetFunctor
|
||||
|
||||
struct ArrayPortalMultiplexerSetFunctor
|
||||
{
|
||||
VTKM_SUPPRESS_EXEC_WARNINGS
|
||||
template <typename PortalType>
|
||||
VTKM_EXEC_CONT void operator()(const PortalType& portal,
|
||||
vtkm::Id index,
|
||||
@ -211,6 +213,20 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_CONT bool IsValid() const { return this->ArrayHandleVariant.IsValid(); }
|
||||
|
||||
template <typename S>
|
||||
VTKM_CONT void SetArray(vtkm::cont::ArrayHandle<ValueType, S>&& rhs)
|
||||
{
|
||||
this->ArrayHandleVariant = std::move(rhs);
|
||||
}
|
||||
|
||||
template <typename S>
|
||||
VTKM_CONT void SetArray(const vtkm::cont::ArrayHandle<ValueType, S>& src)
|
||||
{
|
||||
this->ArrayHandleVariant = src;
|
||||
}
|
||||
|
||||
private:
|
||||
struct GetPortalFunctor
|
||||
{
|
||||
@ -243,22 +259,56 @@ public:
|
||||
|
||||
VTKM_CONT vtkm::Id GetNumberOfValues() const
|
||||
{
|
||||
return this->ArrayHandleVariant.CastAndCall(detail::MultiplexerGetNumberOfValuesFunctor{});
|
||||
if (this->IsValid())
|
||||
{
|
||||
return this->ArrayHandleVariant.CastAndCall(detail::MultiplexerGetNumberOfValuesFunctor{});
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
VTKM_CONT void Allocate(vtkm::Id numberOfValues)
|
||||
{
|
||||
this->ArrayHandleVariant.CastAndCall(detail::MultiplexerAllocateFunctor{}, numberOfValues);
|
||||
if (this->IsValid())
|
||||
{
|
||||
this->ArrayHandleVariant.CastAndCall(detail::MultiplexerAllocateFunctor{}, numberOfValues);
|
||||
}
|
||||
else if (numberOfValues > 0)
|
||||
{
|
||||
throw vtkm::cont::ErrorBadValue(
|
||||
"Attempted to allocate an ArrayHandleMultiplexer with no underlying array.");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Special case, OK to perform "0" allocation on invalid array.
|
||||
}
|
||||
}
|
||||
|
||||
VTKM_CONT void Shrink(vtkm::Id numberOfValues)
|
||||
{
|
||||
this->ArrayHandleVariant.CastAndCall(detail::MultiplexerShrinkFunctor{}, numberOfValues);
|
||||
if (this->IsValid())
|
||||
{
|
||||
this->ArrayHandleVariant.CastAndCall(detail::MultiplexerShrinkFunctor{}, numberOfValues);
|
||||
}
|
||||
else if (numberOfValues > 0)
|
||||
{
|
||||
throw vtkm::cont::ErrorBadValue(
|
||||
"Attempted to allocate an ArrayHandleMultiplexer with no underlying array.");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Special case, OK to perform "0" allocation on invalid array.
|
||||
}
|
||||
}
|
||||
|
||||
VTKM_CONT void ReleaseResources()
|
||||
{
|
||||
this->ArrayHandleVariant.CastAndCall(detail::MultiplexerReleaseResourcesFunctor{});
|
||||
if (this->IsValid())
|
||||
{
|
||||
this->ArrayHandleVariant.CastAndCall(detail::MultiplexerReleaseResourcesFunctor{});
|
||||
}
|
||||
}
|
||||
|
||||
VTKM_CONT ArrayHandleVariantType& GetArrayHandleVariant() { return this->ArrayHandleVariant; }
|
||||
@ -462,8 +512,31 @@ public:
|
||||
: Superclass(StorageType(std::move(rhs)))
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_CONT bool IsValid() const { return this->GetStorage().IsValid(); }
|
||||
|
||||
template <typename S>
|
||||
VTKM_CONT void SetArray(vtkm::cont::ArrayHandle<ValueType, S>&& rhs)
|
||||
{
|
||||
this->GetStorage().SetArray(std::move(rhs));
|
||||
}
|
||||
|
||||
template <typename S>
|
||||
VTKM_CONT void SetArray(const vtkm::cont::ArrayHandle<ValueType, S>& src)
|
||||
{
|
||||
this->GetStorage().SetArray(src);
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Converts a \c vtkm::ListTag to an \c ArrayHandleMultiplexer
|
||||
///
|
||||
/// The argument of this template must be a vtkm::ListTag and furthermore all the types in
|
||||
/// the list tag must be some type of \c ArrayHandle. The templated type gets aliased to
|
||||
/// an \c ArrayHandleMultiplexer that can store any of these ArrayHandle types.
|
||||
///
|
||||
template <typename ListTag>
|
||||
using ArrayHandleMultiplexerFromListTag = vtkm::ListTagApply<ListTag, ArrayHandleMultiplexer>;
|
||||
|
||||
} // namespace cont
|
||||
|
||||
} // namespace vtkm
|
||||
|
@ -1,80 +0,0 @@
|
||||
//============================================================================
|
||||
// Copyright (c) Kitware, Inc.
|
||||
// All rights reserved.
|
||||
// See LICENSE.txt for details.
|
||||
//
|
||||
// This software is distributed WITHOUT ANY WARRANTY; without even
|
||||
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the above copyright notice for more information.
|
||||
//============================================================================
|
||||
#include <vtkm/cont/AssignerMultiBlock.h>
|
||||
|
||||
#include <vtkm/cont/EnvironmentTracker.h>
|
||||
#include <vtkm/cont/MultiBlock.h>
|
||||
|
||||
|
||||
#include <vtkm/thirdparty/diy/diy.h>
|
||||
|
||||
#include <algorithm> // std::lower_bound
|
||||
#include <numeric> // std::iota
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
|
||||
VTKM_CONT
|
||||
AssignerMultiBlock::AssignerMultiBlock(const vtkm::cont::MultiBlock& mb)
|
||||
: AssignerMultiBlock(mb.GetNumberOfBlocks())
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
AssignerMultiBlock::AssignerMultiBlock(vtkm::Id num_blocks)
|
||||
: vtkmdiy::StaticAssigner(vtkm::cont::EnvironmentTracker::GetCommunicator().size(), 1)
|
||||
, IScanBlockCounts()
|
||||
{
|
||||
auto comm = vtkm::cont::EnvironmentTracker::GetCommunicator();
|
||||
if (comm.size() > 1)
|
||||
{
|
||||
vtkm::Id iscan;
|
||||
vtkmdiy::mpi::scan(comm, num_blocks, iscan, std::plus<vtkm::Id>());
|
||||
vtkmdiy::mpi::all_gather(comm, iscan, this->IScanBlockCounts);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->IScanBlockCounts.push_back(num_blocks);
|
||||
}
|
||||
|
||||
this->set_nblocks(static_cast<int>(this->IScanBlockCounts.back()));
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
void AssignerMultiBlock::local_gids(int my_rank, std::vector<int>& gids) const
|
||||
{
|
||||
const size_t s_rank = static_cast<size_t>(my_rank);
|
||||
if (my_rank == 0)
|
||||
{
|
||||
assert(this->IScanBlockCounts.size() > 0);
|
||||
gids.resize(static_cast<size_t>(this->IScanBlockCounts[s_rank]));
|
||||
std::iota(gids.begin(), gids.end(), 0);
|
||||
}
|
||||
else if (my_rank > 0 && s_rank < this->IScanBlockCounts.size())
|
||||
{
|
||||
gids.resize(
|
||||
static_cast<size_t>(this->IScanBlockCounts[s_rank] - this->IScanBlockCounts[s_rank - 1]));
|
||||
std::iota(gids.begin(), gids.end(), static_cast<int>(this->IScanBlockCounts[s_rank - 1]));
|
||||
}
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
int AssignerMultiBlock::rank(int gid) const
|
||||
{
|
||||
return static_cast<int>(
|
||||
std::lower_bound(this->IScanBlockCounts.begin(), this->IScanBlockCounts.end(), gid + 1) -
|
||||
this->IScanBlockCounts.begin());
|
||||
}
|
||||
|
||||
|
||||
} // vtkm::cont
|
||||
} // vtkm
|
81
vtkm/cont/AssignerPartitionedDataSet.cxx
Normal file
81
vtkm/cont/AssignerPartitionedDataSet.cxx
Normal file
@ -0,0 +1,81 @@
|
||||
//============================================================================
|
||||
// Copyright (c) Kitware, Inc.
|
||||
// All rights reserved.
|
||||
// See LICENSE.txt for details.
|
||||
//
|
||||
// This software is distributed WITHOUT ANY WARRANTY; without even
|
||||
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the above copyright notice for more information.
|
||||
//============================================================================
|
||||
#include <vtkm/cont/AssignerPartitionedDataSet.h>
|
||||
|
||||
#include <vtkm/cont/EnvironmentTracker.h>
|
||||
#include <vtkm/cont/PartitionedDataSet.h>
|
||||
|
||||
|
||||
#include <vtkm/thirdparty/diy/diy.h>
|
||||
|
||||
#include <algorithm> // std::lower_bound
|
||||
#include <numeric> // std::iota
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
|
||||
VTKM_CONT
|
||||
AssignerPartitionedDataSet::AssignerPartitionedDataSet(const vtkm::cont::PartitionedDataSet& pds)
|
||||
: AssignerPartitionedDataSet(pds.GetNumberOfPartitions())
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
AssignerPartitionedDataSet::AssignerPartitionedDataSet(vtkm::Id num_partitions)
|
||||
: vtkmdiy::StaticAssigner(vtkm::cont::EnvironmentTracker::GetCommunicator().size(), 1)
|
||||
, IScanPartitionCounts()
|
||||
{
|
||||
auto comm = vtkm::cont::EnvironmentTracker::GetCommunicator();
|
||||
if (comm.size() > 1)
|
||||
{
|
||||
vtkm::Id iscan;
|
||||
vtkmdiy::mpi::scan(comm, num_partitions, iscan, std::plus<vtkm::Id>());
|
||||
vtkmdiy::mpi::all_gather(comm, iscan, this->IScanPartitionCounts);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->IScanPartitionCounts.push_back(num_partitions);
|
||||
}
|
||||
|
||||
this->set_nblocks(static_cast<int>(this->IScanPartitionCounts.back()));
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
void AssignerPartitionedDataSet::local_gids(int my_rank, std::vector<int>& gids) const
|
||||
{
|
||||
const size_t s_rank = static_cast<size_t>(my_rank);
|
||||
if (my_rank == 0)
|
||||
{
|
||||
assert(this->IScanPartitionCounts.size() > 0);
|
||||
gids.resize(static_cast<size_t>(this->IScanPartitionCounts[s_rank]));
|
||||
std::iota(gids.begin(), gids.end(), 0);
|
||||
}
|
||||
else if (my_rank > 0 && s_rank < this->IScanPartitionCounts.size())
|
||||
{
|
||||
gids.resize(static_cast<size_t>(this->IScanPartitionCounts[s_rank] -
|
||||
this->IScanPartitionCounts[s_rank - 1]));
|
||||
std::iota(gids.begin(), gids.end(), static_cast<int>(this->IScanPartitionCounts[s_rank - 1]));
|
||||
}
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
int AssignerPartitionedDataSet::rank(int gid) const
|
||||
{
|
||||
return static_cast<int>(std::lower_bound(this->IScanPartitionCounts.begin(),
|
||||
this->IScanPartitionCounts.end(),
|
||||
gid + 1) -
|
||||
this->IScanPartitionCounts.begin());
|
||||
}
|
||||
|
||||
|
||||
} // vtkm::cont
|
||||
} // vtkm
|
@ -7,8 +7,8 @@
|
||||
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the above copyright notice for more information.
|
||||
//============================================================================
|
||||
#ifndef vtk_m_cont_AssignerMultiBlock_h
|
||||
#define vtk_m_cont_AssignerMultiBlock_h
|
||||
#ifndef vtk_m_cont_AssignerPartitionedDataSet_h
|
||||
#define vtk_m_cont_AssignerPartitionedDataSet_h
|
||||
|
||||
#include <vtkm/cont/vtkm_cont_export.h>
|
||||
|
||||
@ -31,31 +31,32 @@ namespace vtkm
|
||||
namespace cont
|
||||
{
|
||||
|
||||
class MultiBlock;
|
||||
class PartitionedDataSet;
|
||||
|
||||
/// \brief Assigner for `MultiBlock` blocks.
|
||||
/// \brief Assigner for PartitionedDataSet partitions.
|
||||
///
|
||||
/// `AssignerMultiBlock` is a `vtkmdiy::StaticAssigner` implementation that uses
|
||||
/// `MultiBlock`'s block distribution to build global-id/rank associations
|
||||
/// needed for several `diy` operations.
|
||||
/// It uses a contiguous assignment strategy to map blocks to global ids i.e.
|
||||
/// blocks on rank 0 come first, then rank 1, etc. Any rank may have 0 blocks.
|
||||
/// `AssignerPartitionedDataSet` is a `vtkmdiy::StaticAssigner` implementation
|
||||
/// that uses `PartitionedDataSet`'s partition distribution to build
|
||||
/// global-id/rank associations needed for several `diy` operations.
|
||||
/// It uses a contiguous assignment strategy to map partitions to global ids,
|
||||
/// i.e. partitions on rank 0 come first, then rank 1, etc. Any rank may have 0
|
||||
/// partitions.
|
||||
///
|
||||
/// AssignerMultiBlock uses collectives in the constructor hence it is
|
||||
/// AssignerPartitionedDataSet uses collectives in the constructor hence it is
|
||||
/// essential it gets created on all ranks irrespective of whether the rank has
|
||||
/// any blocks.
|
||||
/// any partitions.
|
||||
///
|
||||
class VTKM_CONT_EXPORT AssignerMultiBlock : public vtkmdiy::StaticAssigner
|
||||
class VTKM_CONT_EXPORT AssignerPartitionedDataSet : public vtkmdiy::StaticAssigner
|
||||
{
|
||||
public:
|
||||
/// Initialize the assigner using a multiblock dataset.
|
||||
/// Initialize the assigner using a partitioned dataset.
|
||||
/// This may initialize collective operations to populate the assigner with
|
||||
/// information about blocks on all ranks.
|
||||
/// information about partitions on all ranks.
|
||||
VTKM_CONT
|
||||
AssignerMultiBlock(const vtkm::cont::MultiBlock& mb);
|
||||
AssignerPartitionedDataSet(const vtkm::cont::PartitionedDataSet& pds);
|
||||
|
||||
VTKM_CONT
|
||||
AssignerMultiBlock(vtkm::Id num_blocks);
|
||||
AssignerPartitionedDataSet(vtkm::Id num_partitions);
|
||||
|
||||
///@{
|
||||
/// vtkmdiy::Assigner API implementation.
|
||||
@ -66,7 +67,7 @@ public:
|
||||
int rank(int gid) const override;
|
||||
//@}
|
||||
private:
|
||||
std::vector<vtkm::Id> IScanBlockCounts;
|
||||
std::vector<vtkm::Id> IScanPartitionCounts;
|
||||
};
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@
|
||||
#define vtk_m_cont_AtomicArray_h
|
||||
|
||||
#include <vtkm/ListTag.h>
|
||||
#include <vtkm/StaticAssert.h>
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
#include <vtkm/cont/DeviceAdapter.h>
|
||||
#include <vtkm/cont/ExecutionObjectBase.h>
|
||||
@ -23,7 +24,8 @@ namespace cont
|
||||
|
||||
/// \brief A type list containing types that can be used with an AtomicArray.
|
||||
///
|
||||
struct AtomicArrayTypeListTag : vtkm::ListTagBase<vtkm::Int32, vtkm::Int64>
|
||||
struct AtomicArrayTypeListTag
|
||||
: vtkm::ListTagBase<vtkm::UInt32, vtkm::Int32, vtkm::UInt64, vtkm::Int64>
|
||||
{
|
||||
};
|
||||
|
||||
@ -37,14 +39,19 @@ struct AtomicArrayTypeListTag : vtkm::ListTagBase<vtkm::Int32, vtkm::Int64>
|
||||
/// vtkm::cont::ArrayHandle that is used as the underlying storage for the
|
||||
/// AtomicArray
|
||||
///
|
||||
/// Supported Operations: add / compare and swap (CAS)
|
||||
/// Supported Operations: get / add / compare and swap (CAS). See
|
||||
/// AtomicArrayExecutionObject for details.
|
||||
///
|
||||
/// Supported Types: 32 / 64 bit signed integers
|
||||
/// Supported Types: 32 / 64 bit signed/unsigned integers.
|
||||
///
|
||||
///
|
||||
template <typename T>
|
||||
class AtomicArray : public vtkm::cont::ExecutionObjectBase
|
||||
{
|
||||
static constexpr bool ValueTypeIsValid = vtkm::ListContains<AtomicArrayTypeListTag, T>::value;
|
||||
VTKM_STATIC_ASSERT_MSG(ValueTypeIsValid, "AtomicArray used with unsupported ValueType.");
|
||||
|
||||
|
||||
public:
|
||||
using ValueType = T;
|
||||
|
||||
@ -54,8 +61,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
template <typename StorageType>
|
||||
VTKM_CONT AtomicArray(vtkm::cont::ArrayHandle<T, StorageType> handle)
|
||||
VTKM_CONT AtomicArray(vtkm::cont::ArrayHandle<T> handle)
|
||||
: Handle(handle)
|
||||
{
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
#include <vtkm/cont/CoordinateSystem.h>
|
||||
#include <vtkm/cont/DataSet.h>
|
||||
#include <vtkm/cont/MultiBlock.h>
|
||||
#include <vtkm/cont/PartitionedDataSet.h>
|
||||
|
||||
#include <numeric> // for std::accumulate
|
||||
|
||||
@ -31,14 +31,15 @@ vtkm::Bounds BoundsCompute(const vtkm::cont::DataSet& dataset, vtkm::Id coordina
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
VTKM_CONT
|
||||
vtkm::Bounds BoundsCompute(const vtkm::cont::MultiBlock& multiblock,
|
||||
vtkm::Bounds BoundsCompute(const vtkm::cont::PartitionedDataSet& pds,
|
||||
vtkm::Id coordinate_system_index)
|
||||
{
|
||||
return std::accumulate(multiblock.begin(),
|
||||
multiblock.end(),
|
||||
return std::accumulate(pds.begin(),
|
||||
pds.end(),
|
||||
vtkm::Bounds(),
|
||||
[=](const vtkm::Bounds& val, const vtkm::cont::DataSet& block) {
|
||||
return val + vtkm::cont::BoundsCompute(block, coordinate_system_index);
|
||||
[=](const vtkm::Bounds& val, const vtkm::cont::DataSet& partition) {
|
||||
return val +
|
||||
vtkm::cont::BoundsCompute(partition, coordinate_system_index);
|
||||
});
|
||||
}
|
||||
|
||||
@ -59,13 +60,13 @@ vtkm::Bounds BoundsCompute(const vtkm::cont::DataSet& dataset, const std::string
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
VTKM_CONT
|
||||
vtkm::Bounds BoundsCompute(const vtkm::cont::MultiBlock& multiblock, const std::string& name)
|
||||
vtkm::Bounds BoundsCompute(const vtkm::cont::PartitionedDataSet& pds, const std::string& name)
|
||||
{
|
||||
return std::accumulate(multiblock.begin(),
|
||||
multiblock.end(),
|
||||
return std::accumulate(pds.begin(),
|
||||
pds.end(),
|
||||
vtkm::Bounds(),
|
||||
[=](const vtkm::Bounds& val, const vtkm::cont::DataSet& block) {
|
||||
return val + vtkm::cont::BoundsCompute(block, name);
|
||||
[=](const vtkm::Bounds& val, const vtkm::cont::DataSet& partition) {
|
||||
return val + vtkm::cont::BoundsCompute(partition, name);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -19,19 +19,19 @@ namespace cont
|
||||
{
|
||||
|
||||
class DataSet;
|
||||
class MultiBlock;
|
||||
class PartitionedDataSet;
|
||||
|
||||
//@{
|
||||
/// \brief Functions to compute bounds for a dataset or multiblock
|
||||
/// \brief Functions to compute bounds for a single dataSset or partition dataset
|
||||
///
|
||||
/// These are utility functions that compute bounds for the dataset or
|
||||
/// multiblock. When VTK-m is operating in an distributed environment, these
|
||||
/// are bounds on the local process. To get global bounds across all ranks,
|
||||
/// use `vtkm::cont::BoundsGlobalCompute` instead.
|
||||
/// These are utility functions that compute bounds for a single dataset or
|
||||
/// partitioned dataset. When VTK-m is operating in an distributed environment,
|
||||
/// these are bounds on the local process. To get global bounds across all
|
||||
/// ranks, use `vtkm::cont::BoundsGlobalCompute` instead.
|
||||
///
|
||||
/// Note that if the provided CoordinateSystem does not exists, empty bounds
|
||||
/// are returned. Likewise, for MultiBlock, blocks without the chosen CoordinateSystem
|
||||
/// are skipped.
|
||||
/// are returned. Likewise, for PartitionedDataSet, partitions without the
|
||||
/// chosen CoordinateSystem are skipped.
|
||||
VTKM_CONT_EXPORT
|
||||
VTKM_CONT
|
||||
vtkm::Bounds BoundsCompute(const vtkm::cont::DataSet& dataset,
|
||||
@ -39,7 +39,7 @@ vtkm::Bounds BoundsCompute(const vtkm::cont::DataSet& dataset,
|
||||
|
||||
VTKM_CONT_EXPORT
|
||||
VTKM_CONT
|
||||
vtkm::Bounds BoundsCompute(const vtkm::cont::MultiBlock& multiblock,
|
||||
vtkm::Bounds BoundsCompute(const vtkm::cont::PartitionedDataSet& pds,
|
||||
vtkm::Id coordinate_system_index = 0);
|
||||
|
||||
VTKM_CONT_EXPORT
|
||||
@ -49,7 +49,7 @@ vtkm::Bounds BoundsCompute(const vtkm::cont::DataSet& dataset,
|
||||
|
||||
VTKM_CONT_EXPORT
|
||||
VTKM_CONT
|
||||
vtkm::Bounds BoundsCompute(const vtkm::cont::MultiBlock& multiblock,
|
||||
vtkm::Bounds BoundsCompute(const vtkm::cont::PartitionedDataSet& pds,
|
||||
const std::string& coordinate_system_name);
|
||||
//@}
|
||||
}
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include <vtkm/cont/CoordinateSystem.h>
|
||||
#include <vtkm/cont/DataSet.h>
|
||||
#include <vtkm/cont/FieldRangeGlobalCompute.h>
|
||||
#include <vtkm/cont/MultiBlock.h>
|
||||
#include <vtkm/cont/PartitionedDataSet.h>
|
||||
|
||||
#include <numeric> // for std::accumulate
|
||||
|
||||
@ -50,10 +50,10 @@ vtkm::Bounds BoundsGlobalCompute(const vtkm::cont::DataSet& dataset,
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
VTKM_CONT
|
||||
vtkm::Bounds BoundsGlobalCompute(const vtkm::cont::MultiBlock& multiblock,
|
||||
vtkm::Bounds BoundsGlobalCompute(const vtkm::cont::PartitionedDataSet& pds,
|
||||
vtkm::Id coordinate_system_index)
|
||||
{
|
||||
return detail::MergeBoundsGlobal(vtkm::cont::BoundsCompute(multiblock, coordinate_system_index));
|
||||
return detail::MergeBoundsGlobal(vtkm::cont::BoundsCompute(pds, coordinate_system_index));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -65,9 +65,9 @@ vtkm::Bounds BoundsGlobalCompute(const vtkm::cont::DataSet& dataset, const std::
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
VTKM_CONT
|
||||
vtkm::Bounds BoundsGlobalCompute(const vtkm::cont::MultiBlock& multiblock, const std::string& name)
|
||||
vtkm::Bounds BoundsGlobalCompute(const vtkm::cont::PartitionedDataSet& pds, const std::string& name)
|
||||
{
|
||||
return detail::MergeBoundsGlobal(vtkm::cont::BoundsCompute(multiblock, name));
|
||||
return detail::MergeBoundsGlobal(vtkm::cont::BoundsCompute(pds, name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,19 +19,20 @@ namespace cont
|
||||
{
|
||||
|
||||
class DataSet;
|
||||
class MultiBlock;
|
||||
class PartitionedDataSet;
|
||||
|
||||
//@{
|
||||
/// \brief Functions to compute bounds for a dataset or multiblock globally
|
||||
/// \brief Functions to compute bounds for a single dataset or partitioned
|
||||
/// dataset globally
|
||||
///
|
||||
/// These are utility functions that compute bounds for the dataset or
|
||||
/// multiblock globally i.e. across all ranks when operating in a distributed
|
||||
/// environment. When VTK-m not operating in an distributed environment, these
|
||||
/// behave same as `vtkm::cont::BoundsCompute`.
|
||||
/// These are utility functions that compute bounds for a single dataset or
|
||||
/// partitioned dataset globally i.e. across all ranks when operating in a
|
||||
/// distributed environment. When VTK-m not operating in an distributed
|
||||
/// environment, these behave same as `vtkm::cont::BoundsCompute`.
|
||||
///
|
||||
/// Note that if the provided CoordinateSystem does not exists, empty bounds
|
||||
/// are returned. Likewise, for MultiBlock, blocks without the chosen CoordinateSystem
|
||||
/// are skipped.
|
||||
/// are returned. Likewise, for PartitionedDataSet, partitions without the
|
||||
/// chosen CoordinateSystem are skipped.
|
||||
VTKM_CONT_EXPORT
|
||||
VTKM_CONT
|
||||
vtkm::Bounds BoundsGlobalCompute(const vtkm::cont::DataSet& dataset,
|
||||
@ -39,7 +40,7 @@ vtkm::Bounds BoundsGlobalCompute(const vtkm::cont::DataSet& dataset,
|
||||
|
||||
VTKM_CONT_EXPORT
|
||||
VTKM_CONT
|
||||
vtkm::Bounds BoundsGlobalCompute(const vtkm::cont::MultiBlock& multiblock,
|
||||
vtkm::Bounds BoundsGlobalCompute(const vtkm::cont::PartitionedDataSet& pds,
|
||||
vtkm::Id coordinate_system_index = 0);
|
||||
|
||||
VTKM_CONT_EXPORT
|
||||
@ -49,7 +50,7 @@ vtkm::Bounds BoundsGlobalCompute(const vtkm::cont::DataSet& dataset,
|
||||
|
||||
VTKM_CONT_EXPORT
|
||||
VTKM_CONT
|
||||
vtkm::Bounds BoundsGlobalCompute(const vtkm::cont::MultiBlock& multiblock,
|
||||
vtkm::Bounds BoundsGlobalCompute(const vtkm::cont::PartitionedDataSet& pds,
|
||||
const std::string& coordinate_system_name);
|
||||
//@}
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ set(headers
|
||||
ArrayPortal.h
|
||||
ArrayPortalToIterators.h
|
||||
ArrayRangeCompute.h
|
||||
AssignerMultiBlock.h
|
||||
AssignerPartitionedDataSet.h
|
||||
AtomicArray.h
|
||||
BitField.h
|
||||
BoundsCompute.h
|
||||
@ -93,7 +93,7 @@ set(headers
|
||||
Initialize.h
|
||||
Invoker.h
|
||||
Logging.h
|
||||
MultiBlock.h
|
||||
PartitionedDataSet.h
|
||||
PointLocator.h
|
||||
PointLocatorUniformGrid.h
|
||||
RuntimeDeviceInformation.h
|
||||
@ -152,7 +152,7 @@ set(sources
|
||||
set(device_sources
|
||||
ArrayHandleVirtual.cxx
|
||||
ArrayRangeCompute.cxx
|
||||
AssignerMultiBlock.cxx
|
||||
AssignerPartitionedDataSet.cxx
|
||||
BoundsCompute.cxx
|
||||
BoundsGlobalCompute.cxx
|
||||
CellLocator.cxx
|
||||
@ -175,7 +175,7 @@ set(sources
|
||||
Field.cxx
|
||||
FieldRangeCompute.cxx
|
||||
FieldRangeGlobalCompute.cxx
|
||||
MultiBlock.cxx
|
||||
PartitionedDataSet.cxx
|
||||
PointLocator.cxx
|
||||
PointLocatorUniformGrid.cxx
|
||||
RuntimeDeviceInformation.cxx
|
||||
|
@ -33,6 +33,7 @@ template <typename T, typename S, typename U, typename V>
|
||||
class CellSetExplicit;
|
||||
template <typename T, typename S>
|
||||
class CellSetPermutation;
|
||||
class CellSetExtrude;
|
||||
|
||||
/// A Generic interface to CastAndCall. The default implementation simply calls
|
||||
/// DynamicObject's CastAndCall, but specializations of this function exist for
|
||||
@ -106,6 +107,15 @@ void CastAndCall(const vtkm::cont::CellSetPermutation<PermutationType, CellSetTy
|
||||
f(cellset, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
/// A specialization of CastAndCall for basic CellSetExtrude types,
|
||||
/// Since the type is already known no deduction is needed.
|
||||
/// This specialization is used to simplify numerous worklet algorithms
|
||||
template <typename Functor, typename... Args>
|
||||
void CastAndCall(const vtkm::cont::CellSetExtrude& cellset, Functor&& f, Args&&... args)
|
||||
{
|
||||
f(cellset, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
/// CastAndCall if the condition is true.
|
||||
template <typename... Args>
|
||||
void ConditionalCastAndCall(std::true_type, Args&&... args)
|
||||
|
@ -27,29 +27,8 @@ namespace cont
|
||||
class VTKM_CONT_EXPORT CellSet
|
||||
{
|
||||
public:
|
||||
VTKM_CONT
|
||||
CellSet(const std::string& name)
|
||||
: Name(name)
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
CellSet(const vtkm::cont::CellSet& src)
|
||||
: Name(src.Name)
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
CellSet& operator=(const vtkm::cont::CellSet& src)
|
||||
{
|
||||
this->Name = src.Name;
|
||||
return *this;
|
||||
}
|
||||
|
||||
virtual ~CellSet();
|
||||
|
||||
std::string GetName() const { return this->Name; }
|
||||
|
||||
virtual vtkm::Id GetNumberOfCells() const = 0;
|
||||
|
||||
virtual vtkm::Id GetNumberOfFaces() const = 0;
|
||||
@ -68,9 +47,6 @@ public:
|
||||
virtual void PrintSummary(std::ostream&) const = 0;
|
||||
|
||||
virtual void ReleaseResourcesExecution() = 0;
|
||||
|
||||
protected:
|
||||
std::string Name;
|
||||
};
|
||||
|
||||
namespace internal
|
||||
|
@ -98,7 +98,7 @@ public:
|
||||
typename VisitCellsWithPointsConnectivityType::ConnectivityArrayType;
|
||||
using IndexOffsetArrayType = typename VisitCellsWithPointsConnectivityType::IndexOffsetArrayType;
|
||||
|
||||
VTKM_CONT CellSetExplicit(const std::string& name = std::string());
|
||||
VTKM_CONT CellSetExplicit();
|
||||
VTKM_CONT CellSetExplicit(const Thisclass& src);
|
||||
VTKM_CONT CellSetExplicit(Thisclass&& src) noexcept;
|
||||
|
||||
@ -377,7 +377,6 @@ private:
|
||||
public:
|
||||
static VTKM_CONT void save(BinaryBuffer& bb, const Type& cs)
|
||||
{
|
||||
vtkmdiy::save(bb, cs.GetName());
|
||||
vtkmdiy::save(bb, cs.GetNumberOfPoints());
|
||||
vtkmdiy::save(
|
||||
bb, cs.GetShapesArray(vtkm::TopologyElementTagCell{}, vtkm::TopologyElementTagPoint{}));
|
||||
@ -391,8 +390,6 @@ public:
|
||||
|
||||
static VTKM_CONT void load(BinaryBuffer& bb, Type& cs)
|
||||
{
|
||||
std::string name;
|
||||
vtkmdiy::load(bb, name);
|
||||
vtkm::Id numberOfPoints = 0;
|
||||
vtkmdiy::load(bb, numberOfPoints);
|
||||
vtkm::cont::ArrayHandle<vtkm::UInt8, ShapeST> shapes;
|
||||
@ -404,7 +401,7 @@ public:
|
||||
vtkm::cont::ArrayHandle<vtkm::Id, OffsetST> offsets;
|
||||
vtkmdiy::load(bb, offsets);
|
||||
|
||||
cs = Type(name);
|
||||
cs = Type{};
|
||||
cs.Fill(numberOfPoints, shapes, counts, connectivity, offsets);
|
||||
}
|
||||
};
|
||||
|
@ -25,8 +25,8 @@ template <typename ShapeStorageTag,
|
||||
VTKM_CONT CellSetExplicit<ShapeStorageTag,
|
||||
NumIndicesStorageTag,
|
||||
ConnectivityStorageTag,
|
||||
OffsetsStorageTag>::CellSetExplicit(const std::string& name)
|
||||
: CellSet(name)
|
||||
OffsetsStorageTag>::CellSetExplicit()
|
||||
: CellSet()
|
||||
, Data(std::make_shared<Internals>())
|
||||
{
|
||||
}
|
||||
@ -103,7 +103,7 @@ void CellSetExplicit<ShapeStorageTag,
|
||||
ConnectivityStorageTag,
|
||||
OffsetsStorageTag>::PrintSummary(std::ostream& out) const
|
||||
{
|
||||
out << " ExplicitCellSet: " << this->Name << std::endl;
|
||||
out << " ExplicitCellSet: " << std::endl;
|
||||
out << " VisitCellsWithPoints: " << std::endl;
|
||||
this->Data->VisitCellsWithPoints.PrintSummary(out);
|
||||
out << " VisitPointsWithCells: " << std::endl;
|
||||
|
@ -19,8 +19,8 @@ namespace vtkm
|
||||
namespace cont
|
||||
{
|
||||
|
||||
CellSetExtrude::CellSetExtrude(const std::string& name)
|
||||
: vtkm::cont::CellSet(name)
|
||||
CellSetExtrude::CellSetExtrude()
|
||||
: vtkm::cont::CellSet()
|
||||
, IsPeriodic(false)
|
||||
, NumberOfPointsPerPlane(0)
|
||||
, NumberOfCellsPerPlane(0)
|
||||
@ -33,9 +33,8 @@ CellSetExtrude::CellSetExtrude(const vtkm::cont::ArrayHandle<vtkm::Int32>& conn,
|
||||
vtkm::Int32 numberOfPointsPerPlane,
|
||||
vtkm::Int32 numberOfPlanes,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Int32>& nextNode,
|
||||
bool periodic,
|
||||
const std::string& name)
|
||||
: vtkm::cont::CellSet(name)
|
||||
bool periodic)
|
||||
: vtkm::cont::CellSet()
|
||||
, IsPeriodic(periodic)
|
||||
, NumberOfPointsPerPlane(numberOfPointsPerPlane)
|
||||
, NumberOfCellsPerPlane(
|
||||
@ -47,6 +46,81 @@ CellSetExtrude::CellSetExtrude(const vtkm::cont::ArrayHandle<vtkm::Int32>& conn,
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
CellSetExtrude::CellSetExtrude(const CellSetExtrude& src)
|
||||
: CellSet(src)
|
||||
, IsPeriodic(src.IsPeriodic)
|
||||
, NumberOfPointsPerPlane(src.NumberOfPointsPerPlane)
|
||||
, NumberOfCellsPerPlane(src.NumberOfCellsPerPlane)
|
||||
, NumberOfPlanes(src.NumberOfPlanes)
|
||||
, Connectivity(src.Connectivity)
|
||||
, NextNode(src.NextNode)
|
||||
, ReverseConnectivityBuilt(src.ReverseConnectivityBuilt)
|
||||
, RConnectivity(src.RConnectivity)
|
||||
, ROffsets(src.ROffsets)
|
||||
, RCounts(src.RCounts)
|
||||
, PrevNode(src.PrevNode)
|
||||
{
|
||||
}
|
||||
|
||||
CellSetExtrude::CellSetExtrude(CellSetExtrude&& src) noexcept
|
||||
: CellSet(std::forward<CellSet>(src)),
|
||||
IsPeriodic(src.IsPeriodic),
|
||||
NumberOfPointsPerPlane(src.NumberOfPointsPerPlane),
|
||||
NumberOfCellsPerPlane(src.NumberOfCellsPerPlane),
|
||||
NumberOfPlanes(src.NumberOfPlanes),
|
||||
Connectivity(std::move(src.Connectivity)),
|
||||
NextNode(std::move(src.NextNode)),
|
||||
ReverseConnectivityBuilt(src.ReverseConnectivityBuilt),
|
||||
RConnectivity(std::move(src.RConnectivity)),
|
||||
ROffsets(std::move(src.ROffsets)),
|
||||
RCounts(std::move(src.RCounts)),
|
||||
PrevNode(std::move(src.PrevNode))
|
||||
{
|
||||
}
|
||||
|
||||
CellSetExtrude& CellSetExtrude::operator=(const CellSetExtrude& src)
|
||||
{
|
||||
this->CellSet::operator=(src);
|
||||
|
||||
this->IsPeriodic = src.IsPeriodic;
|
||||
this->NumberOfPointsPerPlane = src.NumberOfPointsPerPlane;
|
||||
this->NumberOfCellsPerPlane = src.NumberOfCellsPerPlane;
|
||||
this->NumberOfPlanes = src.NumberOfPlanes;
|
||||
this->Connectivity = src.Connectivity;
|
||||
this->NextNode = src.NextNode;
|
||||
this->ReverseConnectivityBuilt = src.ReverseConnectivityBuilt;
|
||||
this->RConnectivity = src.RConnectivity;
|
||||
this->ROffsets = src.ROffsets;
|
||||
this->RCounts = src.RCounts;
|
||||
this->PrevNode = src.PrevNode;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
CellSetExtrude& CellSetExtrude::operator=(CellSetExtrude&& src) noexcept
|
||||
{
|
||||
this->CellSet::operator=(std::forward<CellSet>(src));
|
||||
|
||||
this->IsPeriodic = src.IsPeriodic;
|
||||
this->NumberOfPointsPerPlane = src.NumberOfPointsPerPlane;
|
||||
this->NumberOfCellsPerPlane = src.NumberOfCellsPerPlane;
|
||||
this->NumberOfPlanes = src.NumberOfPlanes;
|
||||
this->Connectivity = std::move(src.Connectivity);
|
||||
this->NextNode = std::move(src.NextNode);
|
||||
this->ReverseConnectivityBuilt = src.ReverseConnectivityBuilt;
|
||||
this->RConnectivity = std::move(src.RConnectivity);
|
||||
this->ROffsets = std::move(src.ROffsets);
|
||||
this->RCounts = std::move(src.RCounts);
|
||||
this->PrevNode = std::move(src.PrevNode);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
CellSetExtrude::~CellSetExtrude()
|
||||
{
|
||||
}
|
||||
|
||||
vtkm::Int32 CellSetExtrude::GetNumberOfPlanes() const
|
||||
{
|
||||
return this->NumberOfPlanes;
|
||||
@ -167,7 +241,7 @@ vtkm::Id2 CellSetExtrude::GetSchedulingRange(vtkm::TopologyElementTagPoint) cons
|
||||
|
||||
void CellSetExtrude::PrintSummary(std::ostream& out) const
|
||||
{
|
||||
out << " vtkmCellSetSingleType: " << this->Name << std::endl;
|
||||
out << " vtkmCellSetSingleType: " << std::endl;
|
||||
out << " NumberOfCellsPerPlane: " << this->NumberOfCellsPerPlane << std::endl;
|
||||
out << " NumberOfPointsPerPlane: " << this->NumberOfPointsPerPlane << std::endl;
|
||||
out << " NumberOfPlanes: " << this->NumberOfPlanes << std::endl;
|
||||
|
@ -29,14 +29,21 @@ namespace cont
|
||||
class VTKM_CONT_EXPORT CellSetExtrude : public CellSet
|
||||
{
|
||||
public:
|
||||
VTKM_CONT CellSetExtrude(const std::string& name = "extrude");
|
||||
VTKM_CONT CellSetExtrude();
|
||||
|
||||
VTKM_CONT CellSetExtrude(const vtkm::cont::ArrayHandle<vtkm::Int32>& conn,
|
||||
vtkm::Int32 numberOfPointsPerPlane,
|
||||
vtkm::Int32 numberOfPlanes,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Int32>& nextNode,
|
||||
bool periodic,
|
||||
const std::string& name = "extrude");
|
||||
bool periodic);
|
||||
|
||||
VTKM_CONT CellSetExtrude(const CellSetExtrude& src);
|
||||
VTKM_CONT CellSetExtrude(CellSetExtrude&& src) noexcept;
|
||||
|
||||
VTKM_CONT CellSetExtrude& operator=(const CellSetExtrude& src);
|
||||
VTKM_CONT CellSetExtrude& operator=(CellSetExtrude&& src) noexcept;
|
||||
|
||||
virtual ~CellSetExtrude();
|
||||
|
||||
vtkm::Int32 GetNumberOfPlanes() const;
|
||||
|
||||
@ -126,11 +133,10 @@ template <typename T>
|
||||
CellSetExtrude make_CellSetExtrude(const vtkm::cont::ArrayHandle<vtkm::Int32>& conn,
|
||||
const vtkm::cont::ArrayHandleExtrudeCoords<T>& coords,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Int32>& nextNode,
|
||||
bool periodic = true,
|
||||
const std::string name = "extrude")
|
||||
bool periodic = true)
|
||||
{
|
||||
return CellSetExtrude{
|
||||
conn, coords.GetNumberOfPointsPerPlane(), coords.GetNumberOfPlanes(), nextNode, periodic, name
|
||||
conn, coords.GetNumberOfPointsPerPlane(), coords.GetNumberOfPlanes(), nextNode, periodic
|
||||
};
|
||||
}
|
||||
|
||||
@ -138,15 +144,13 @@ template <typename T>
|
||||
CellSetExtrude make_CellSetExtrude(const std::vector<vtkm::Int32>& conn,
|
||||
const vtkm::cont::ArrayHandleExtrudeCoords<T>& coords,
|
||||
const std::vector<vtkm::Int32>& nextNode,
|
||||
bool periodic = true,
|
||||
const std::string name = "extrude")
|
||||
bool periodic = true)
|
||||
{
|
||||
return CellSetExtrude{ vtkm::cont::make_ArrayHandle(conn),
|
||||
static_cast<vtkm::Int32>(coords.GetNumberOfPointsPerPlane()),
|
||||
coords.GetNumberOfPlanes(),
|
||||
vtkm::cont::make_ArrayHandle(nextNode),
|
||||
periodic,
|
||||
name };
|
||||
periodic };
|
||||
}
|
||||
}
|
||||
} // vtkm::cont
|
||||
@ -183,7 +187,6 @@ private:
|
||||
public:
|
||||
static VTKM_CONT void save(BinaryBuffer& bb, const Type& cs)
|
||||
{
|
||||
vtkmdiy::save(bb, cs.GetName());
|
||||
vtkmdiy::save(bb, cs.GetNumberOfPointsPerPlane());
|
||||
vtkmdiy::save(bb, cs.GetNumberOfPlanes());
|
||||
vtkmdiy::save(bb, cs.GetIsPeriodic());
|
||||
@ -193,21 +196,19 @@ public:
|
||||
|
||||
static VTKM_CONT void load(BinaryBuffer& bb, Type& cs)
|
||||
{
|
||||
std::string name;
|
||||
vtkm::Int32 numberOfPointsPerPlane;
|
||||
vtkm::Int32 numberOfPlanes;
|
||||
bool isPeriodic;
|
||||
vtkm::cont::ArrayHandle<vtkm::Int32> conn;
|
||||
vtkm::cont::ArrayHandle<vtkm::Int32> nextNode;
|
||||
|
||||
vtkmdiy::load(bb, name);
|
||||
vtkmdiy::load(bb, numberOfPointsPerPlane);
|
||||
vtkmdiy::load(bb, numberOfPlanes);
|
||||
vtkmdiy::load(bb, isPeriodic);
|
||||
vtkmdiy::load(bb, conn);
|
||||
vtkmdiy::load(bb, nextNode);
|
||||
|
||||
cs = Type{ conn, numberOfPointsPerPlane, numberOfPlanes, nextNode, isPeriodic, name };
|
||||
cs = Type{ conn, numberOfPointsPerPlane, numberOfPlanes, nextNode, isPeriodic };
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -243,17 +243,16 @@ public:
|
||||
|
||||
VTKM_CONT
|
||||
CellSetPermutation(const PermutationArrayHandleType& validCellIds,
|
||||
const OriginalCellSetType& cellset,
|
||||
const std::string& name = std::string())
|
||||
: CellSet(name)
|
||||
const OriginalCellSetType& cellset)
|
||||
: CellSet()
|
||||
, ValidCellIds(validCellIds)
|
||||
, FullCellSet(cellset)
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
CellSetPermutation(const std::string& name = std::string())
|
||||
: CellSet(name)
|
||||
CellSetPermutation()
|
||||
: CellSet()
|
||||
, ValidCellIds()
|
||||
, FullCellSet()
|
||||
{
|
||||
@ -446,17 +445,15 @@ private:
|
||||
public:
|
||||
VTKM_CONT
|
||||
CellSetPermutation(const PermutationArrayHandleType2& validCellIds,
|
||||
const CellSetPermutation<CellSetType, PermutationArrayHandleType1>& cellset,
|
||||
const std::string& name = std::string())
|
||||
const CellSetPermutation<CellSetType, PermutationArrayHandleType1>& cellset)
|
||||
: Superclass(vtkm::cont::make_ArrayHandlePermutation(validCellIds, cellset.GetValidCellIds()),
|
||||
cellset.GetFullCellSet(),
|
||||
name)
|
||||
cellset.GetFullCellSet())
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
CellSetPermutation(const std::string& name = std::string())
|
||||
: Superclass(name)
|
||||
CellSetPermutation()
|
||||
: Superclass()
|
||||
{
|
||||
}
|
||||
|
||||
@ -471,19 +468,6 @@ public:
|
||||
std::shared_ptr<CellSet> NewInstance() const { return std::make_shared<CellSetPermutation>(); }
|
||||
};
|
||||
|
||||
template <typename OriginalCellSet, typename PermutationArrayHandleType>
|
||||
vtkm::cont::CellSetPermutation<OriginalCellSet, PermutationArrayHandleType> make_CellSetPermutation(
|
||||
const PermutationArrayHandleType& cellIndexMap,
|
||||
const OriginalCellSet& cellSet,
|
||||
const std::string& name)
|
||||
{
|
||||
VTKM_IS_CELL_SET(OriginalCellSet);
|
||||
VTKM_IS_ARRAY_HANDLE(PermutationArrayHandleType);
|
||||
|
||||
return vtkm::cont::CellSetPermutation<OriginalCellSet, PermutationArrayHandleType>(
|
||||
cellIndexMap, cellSet, name);
|
||||
}
|
||||
|
||||
template <typename OriginalCellSet, typename PermutationArrayHandleType>
|
||||
vtkm::cont::CellSetPermutation<OriginalCellSet, PermutationArrayHandleType> make_CellSetPermutation(
|
||||
const PermutationArrayHandleType& cellIndexMap,
|
||||
@ -492,7 +476,8 @@ vtkm::cont::CellSetPermutation<OriginalCellSet, PermutationArrayHandleType> make
|
||||
VTKM_IS_CELL_SET(OriginalCellSet);
|
||||
VTKM_IS_ARRAY_HANDLE(PermutationArrayHandleType);
|
||||
|
||||
return vtkm::cont::make_CellSetPermutation(cellIndexMap, cellSet, cellSet.GetName());
|
||||
return vtkm::cont::CellSetPermutation<OriginalCellSet, PermutationArrayHandleType>(cellIndexMap,
|
||||
cellSet);
|
||||
}
|
||||
}
|
||||
} // namespace vtkm::cont
|
||||
@ -529,21 +514,18 @@ private:
|
||||
public:
|
||||
static VTKM_CONT void save(BinaryBuffer& bb, const Type& cs)
|
||||
{
|
||||
vtkmdiy::save(bb, cs.GetName());
|
||||
vtkmdiy::save(bb, cs.GetFullCellSet());
|
||||
vtkmdiy::save(bb, cs.GetValidCellIds());
|
||||
}
|
||||
|
||||
static VTKM_CONT void load(BinaryBuffer& bb, Type& cs)
|
||||
{
|
||||
std::string name;
|
||||
vtkmdiy::load(bb, name);
|
||||
CSType fullCS;
|
||||
vtkmdiy::load(bb, fullCS);
|
||||
AHValidCellIds validCellIds;
|
||||
vtkmdiy::load(bb, validCellIds);
|
||||
|
||||
cs = make_CellSetPermutation(validCellIds, fullCS, name);
|
||||
cs = make_CellSetPermutation(validCellIds, fullCS);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -46,8 +46,8 @@ class VTKM_ALWAYS_EXPORT CellSetSingleType
|
||||
|
||||
public:
|
||||
VTKM_CONT
|
||||
CellSetSingleType(const std::string& name = std::string())
|
||||
: Superclass(name)
|
||||
CellSetSingleType()
|
||||
: Superclass()
|
||||
, ExpectedNumberOfCellsAdded(-1)
|
||||
, CellShapeAsId(CellShapeTagEmpty::Id)
|
||||
, NumberOfPointsPerCell(0)
|
||||
@ -63,6 +63,15 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
CellSetSingleType(Thisclass&& src) noexcept : Superclass(std::forward<Superclass>(src)),
|
||||
ExpectedNumberOfCellsAdded(-1),
|
||||
CellShapeAsId(src.CellShapeAsId),
|
||||
NumberOfPointsPerCell(src.NumberOfPointsPerCell)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
VTKM_CONT
|
||||
Thisclass& operator=(const Thisclass& src)
|
||||
{
|
||||
@ -72,6 +81,15 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
Thisclass& operator=(Thisclass&& src) noexcept
|
||||
{
|
||||
this->Superclass::operator=(std::forward<Superclass>(src));
|
||||
this->CellShapeAsId = src.CellShapeAsId;
|
||||
this->NumberOfPointsPerCell = src.NumberOfPointsPerCell;
|
||||
return *this;
|
||||
}
|
||||
|
||||
virtual ~CellSetSingleType() {}
|
||||
|
||||
/// First method to add cells -- one at a time.
|
||||
@ -224,7 +242,7 @@ public:
|
||||
|
||||
virtual void PrintSummary(std::ostream& out) const override
|
||||
{
|
||||
out << " CellSetSingleType: " << this->Name << " Type " << this->CellShapeAsId << std::endl;
|
||||
out << " CellSetSingleType ShapeType " << this->CellShapeAsId << std::endl;
|
||||
out << " VisitCellsWithPoints: " << std::endl;
|
||||
this->Data->VisitCellsWithPoints.PrintSummary(out);
|
||||
out << " VisitPointsWithCells: " << std::endl;
|
||||
@ -304,7 +322,6 @@ private:
|
||||
public:
|
||||
static VTKM_CONT void save(BinaryBuffer& bb, const Type& cs)
|
||||
{
|
||||
vtkmdiy::save(bb, cs.GetName());
|
||||
vtkmdiy::save(bb, cs.GetNumberOfPoints());
|
||||
vtkmdiy::save(bb, cs.GetCellShape(0));
|
||||
vtkmdiy::save(bb, cs.GetNumberOfPointsInCell(0));
|
||||
@ -314,8 +331,6 @@ public:
|
||||
|
||||
static VTKM_CONT void load(BinaryBuffer& bb, Type& cs)
|
||||
{
|
||||
std::string name;
|
||||
vtkmdiy::load(bb, name);
|
||||
vtkm::Id numberOfPoints = 0;
|
||||
vtkmdiy::load(bb, numberOfPoints);
|
||||
vtkm::UInt8 shape;
|
||||
@ -325,7 +340,7 @@ public:
|
||||
vtkm::cont::ArrayHandle<vtkm::Id, ConnectivityST> connectivity;
|
||||
vtkmdiy::load(bb, connectivity);
|
||||
|
||||
cs = Type(name);
|
||||
cs = Type{};
|
||||
cs.Fill(numberOfPoints, shape, count, connectivity);
|
||||
}
|
||||
};
|
||||
|
@ -35,18 +35,6 @@ public:
|
||||
|
||||
using SchedulingRangeType = typename InternalsType::SchedulingRangeType;
|
||||
|
||||
CellSetStructured(const std::string& name = std::string())
|
||||
: CellSet(name)
|
||||
, Structure()
|
||||
{
|
||||
}
|
||||
|
||||
CellSetStructured(const Thisclass& src);
|
||||
CellSetStructured(Thisclass&& src) noexcept;
|
||||
|
||||
Thisclass& operator=(const Thisclass& src);
|
||||
Thisclass& operator=(Thisclass&& src) noexcept;
|
||||
|
||||
vtkm::Id GetNumberOfCells() const override { return this->Structure.GetNumberOfCells(); }
|
||||
|
||||
vtkm::Id GetNumberOfPoints() const override { return this->Structure.GetNumberOfPoints(); }
|
||||
@ -174,20 +162,17 @@ private:
|
||||
public:
|
||||
static VTKM_CONT void save(BinaryBuffer& bb, const Type& cs)
|
||||
{
|
||||
vtkmdiy::save(bb, cs.GetName());
|
||||
vtkmdiy::save(bb, cs.GetPointDimensions());
|
||||
vtkmdiy::save(bb, cs.GetGlobalPointIndexStart());
|
||||
}
|
||||
|
||||
static VTKM_CONT void load(BinaryBuffer& bb, Type& cs)
|
||||
{
|
||||
std::string name;
|
||||
vtkmdiy::load(bb, name);
|
||||
typename Type::SchedulingRangeType dims, start;
|
||||
vtkmdiy::load(bb, dims);
|
||||
vtkmdiy::load(bb, start);
|
||||
|
||||
cs = Type(name);
|
||||
cs = Type{};
|
||||
cs.SetPointDimensions(dims);
|
||||
cs.SetGlobalPointIndexStart(start);
|
||||
}
|
||||
|
@ -15,38 +15,6 @@ namespace vtkm
|
||||
namespace cont
|
||||
{
|
||||
|
||||
template <vtkm::IdComponent DIMENSION>
|
||||
CellSetStructured<DIMENSION>::CellSetStructured(const CellSetStructured<DIMENSION>& src)
|
||||
: CellSet(src)
|
||||
, Structure(src.Structure)
|
||||
{
|
||||
}
|
||||
|
||||
template <vtkm::IdComponent DIMENSION>
|
||||
CellSetStructured<DIMENSION>::CellSetStructured(CellSetStructured<DIMENSION>&& src) noexcept
|
||||
: CellSet(std::forward<CellSet>(src)),
|
||||
Structure(std::move(src.Structure))
|
||||
{
|
||||
}
|
||||
|
||||
template <vtkm::IdComponent DIMENSION>
|
||||
CellSetStructured<DIMENSION>& CellSetStructured<DIMENSION>::operator=(
|
||||
const CellSetStructured<DIMENSION>& src)
|
||||
{
|
||||
this->CellSet::operator=(src);
|
||||
this->Structure = src.Structure;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <vtkm::IdComponent DIMENSION>
|
||||
CellSetStructured<DIMENSION>& CellSetStructured<DIMENSION>::operator=(
|
||||
CellSetStructured<DIMENSION>&& src) noexcept
|
||||
{
|
||||
this->CellSet::operator=(std::forward<CellSet>(src));
|
||||
this->Structure = std::move(src.Structure);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <vtkm::IdComponent DIMENSION>
|
||||
template <typename TopologyElement>
|
||||
typename CellSetStructured<DIMENSION>::SchedulingRangeType
|
||||
@ -73,7 +41,7 @@ typename CellSetStructured<DIMENSION>::template ExecutionTypes<DeviceAdapter,
|
||||
template <vtkm::IdComponent DIMENSION>
|
||||
void CellSetStructured<DIMENSION>::PrintSummary(std::ostream& out) const
|
||||
{
|
||||
out << " StructuredCellSet: " << this->GetName() << std::endl;
|
||||
out << " StructuredCellSet: " << std::endl;
|
||||
this->Structure.PrintSummary(out);
|
||||
}
|
||||
}
|
||||
|
@ -18,13 +18,27 @@ void DataSet::Clear()
|
||||
{
|
||||
this->CoordSystems.clear();
|
||||
this->Fields.clear();
|
||||
this->CellSets.clear();
|
||||
this->CellSet = this->CellSet.NewInstance();
|
||||
}
|
||||
|
||||
vtkm::Id DataSet::GetNumberOfCells() const
|
||||
{
|
||||
return this->CellSet.GetNumberOfCells();
|
||||
}
|
||||
|
||||
vtkm::Id DataSet::GetNumberOfPoints() const
|
||||
{
|
||||
if (this->CoordSystems.empty())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return this->CoordSystems[0].GetNumberOfPoints();
|
||||
}
|
||||
|
||||
void DataSet::CopyStructure(const vtkm::cont::DataSet& source)
|
||||
{
|
||||
this->CoordSystems = source.CoordSystems;
|
||||
this->CellSets = source.CellSets;
|
||||
this->CellSet = source.CellSet;
|
||||
}
|
||||
|
||||
const vtkm::cont::Field& DataSet::GetField(vtkm::Id index) const
|
||||
@ -33,6 +47,12 @@ const vtkm::cont::Field& DataSet::GetField(vtkm::Id index) const
|
||||
return this->Fields[static_cast<std::size_t>(index)];
|
||||
}
|
||||
|
||||
vtkm::cont::Field& DataSet::GetField(vtkm::Id index)
|
||||
{
|
||||
VTKM_ASSERT((index >= 0) && (index < this->GetNumberOfFields()));
|
||||
return this->Fields[static_cast<std::size_t>(index)];
|
||||
}
|
||||
|
||||
vtkm::Id DataSet::GetFieldIndex(const std::string& name, vtkm::cont::Field::Association assoc) const
|
||||
{
|
||||
bool found;
|
||||
@ -53,6 +73,12 @@ const vtkm::cont::CoordinateSystem& DataSet::GetCoordinateSystem(vtkm::Id index)
|
||||
return this->CoordSystems[static_cast<std::size_t>(index)];
|
||||
}
|
||||
|
||||
vtkm::cont::CoordinateSystem& DataSet::GetCoordinateSystem(vtkm::Id index)
|
||||
{
|
||||
VTKM_ASSERT((index >= 0) && (index < this->GetNumberOfCoordinateSystems()));
|
||||
return this->CoordSystems[static_cast<std::size_t>(index)];
|
||||
}
|
||||
|
||||
vtkm::Id DataSet::GetCoordinateSystemIndex(const std::string& name) const
|
||||
{
|
||||
vtkm::Id index = -1;
|
||||
@ -83,39 +109,20 @@ const vtkm::cont::CoordinateSystem& DataSet::GetCoordinateSystem(const std::stri
|
||||
return this->GetCoordinateSystem(index);
|
||||
}
|
||||
|
||||
const vtkm::cont::DynamicCellSet& DataSet::GetCellSet(vtkm::Id index) const
|
||||
vtkm::cont::CoordinateSystem& DataSet::GetCoordinateSystem(const std::string& name)
|
||||
{
|
||||
VTKM_ASSERT((index >= 0) && (index < this->GetNumberOfCellSets()));
|
||||
return this->CellSets[static_cast<std::size_t>(index)];
|
||||
}
|
||||
|
||||
vtkm::Id DataSet::GetCellSetIndex(const std::string& name) const
|
||||
{
|
||||
vtkm::Id index = -1;
|
||||
for (auto i = this->CellSets.begin(); i != this->CellSets.end(); ++i)
|
||||
{
|
||||
if (i->GetName() == name)
|
||||
{
|
||||
index = static_cast<vtkm::Id>(std::distance(this->CellSets.begin(), i));
|
||||
break;
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
const vtkm::cont::DynamicCellSet& DataSet::GetCellSet(const std::string& name) const
|
||||
{
|
||||
vtkm::Id index = this->GetCellSetIndex(name);
|
||||
vtkm::Id index = this->GetCoordinateSystemIndex(name);
|
||||
if (index < 0)
|
||||
{
|
||||
std::string error_message("No cell set with the name " + name + " valid names are: \n");
|
||||
for (const auto& cs : this->CellSets)
|
||||
std::string error_message("No coordinate system with the name " + name +
|
||||
" valid names are: \n");
|
||||
for (const auto& cs : this->CoordSystems)
|
||||
{
|
||||
error_message += cs.GetName() + "\n";
|
||||
}
|
||||
throw vtkm::cont::ErrorBadValue(error_message);
|
||||
}
|
||||
return this->GetCellSet(index);
|
||||
return this->GetCoordinateSystem(index);
|
||||
}
|
||||
|
||||
void DataSet::PrintSummary(std::ostream& out) const
|
||||
@ -127,17 +134,16 @@ void DataSet::PrintSummary(std::ostream& out) const
|
||||
this->CoordSystems[index].PrintSummary(out);
|
||||
}
|
||||
|
||||
out << " CellSets[" << this->GetNumberOfCellSets() << "]\n";
|
||||
for (vtkm::Id index = 0; index < this->GetNumberOfCellSets(); index++)
|
||||
{
|
||||
this->GetCellSet(index).PrintSummary(out);
|
||||
}
|
||||
out << " CellSet \n";
|
||||
this->GetCellSet().PrintSummary(out);
|
||||
|
||||
out << " Fields[" << this->GetNumberOfFields() << "]\n";
|
||||
for (vtkm::Id index = 0; index < this->GetNumberOfFields(); index++)
|
||||
{
|
||||
this->GetField(index).PrintSummary(out);
|
||||
}
|
||||
|
||||
out.flush();
|
||||
}
|
||||
|
||||
vtkm::Id DataSet::FindFieldIndex(const std::string& name,
|
||||
|
@ -30,11 +30,23 @@ class VTKM_CONT_EXPORT DataSet
|
||||
public:
|
||||
VTKM_CONT void Clear();
|
||||
|
||||
/// Get the number of cells contained in this DataSet
|
||||
VTKM_CONT vtkm::Id GetNumberOfCells() const;
|
||||
|
||||
/// Get the number of points contained in this DataSet
|
||||
///
|
||||
/// Note: All coordinate systems for a DataSet are expected
|
||||
/// to have the same number of points.
|
||||
VTKM_CONT vtkm::Id GetNumberOfPoints() const;
|
||||
|
||||
VTKM_CONT void AddField(const Field& field) { this->Fields.push_back(field); }
|
||||
|
||||
VTKM_CONT
|
||||
const vtkm::cont::Field& GetField(vtkm::Id index) const;
|
||||
|
||||
VTKM_CONT
|
||||
vtkm::cont::Field& GetField(vtkm::Id index);
|
||||
|
||||
VTKM_CONT
|
||||
bool HasField(const std::string& name,
|
||||
vtkm::cont::Field::Association assoc = vtkm::cont::Field::Association::ANY) const
|
||||
@ -70,6 +82,7 @@ public:
|
||||
|
||||
/// Returns the first field that matches the provided name and association
|
||||
/// Will throw an exception if no match is found
|
||||
//@{
|
||||
VTKM_CONT
|
||||
const vtkm::cont::Field& GetField(
|
||||
const std::string& name,
|
||||
@ -78,22 +91,47 @@ public:
|
||||
return this->GetField(this->GetFieldIndex(name, assoc));
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
vtkm::cont::Field& GetField(
|
||||
const std::string& name,
|
||||
vtkm::cont::Field::Association assoc = vtkm::cont::Field::Association::ANY)
|
||||
{
|
||||
return this->GetField(this->GetFieldIndex(name, assoc));
|
||||
}
|
||||
//@}
|
||||
|
||||
/// Returns the first cell field that matches the provided name.
|
||||
/// Will throw an exception if no match is found
|
||||
//@{
|
||||
VTKM_CONT
|
||||
const vtkm::cont::Field& GetCellField(const std::string& name) const
|
||||
{
|
||||
return this->GetField(name, vtkm::cont::Field::Association::CELL_SET);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
vtkm::cont::Field& GetCellField(const std::string& name)
|
||||
{
|
||||
return this->GetField(name, vtkm::cont::Field::Association::CELL_SET);
|
||||
}
|
||||
//@}
|
||||
|
||||
/// Returns the first point field that matches the provided name.
|
||||
/// Will throw an exception if no match is found
|
||||
//@{
|
||||
VTKM_CONT
|
||||
const vtkm::cont::Field& GetPointField(const std::string& name) const
|
||||
{
|
||||
return this->GetField(name, vtkm::cont::Field::Association::POINTS);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
vtkm::cont::Field& GetPointField(const std::string& name)
|
||||
{
|
||||
return this->GetField(name, vtkm::cont::Field::Association::POINTS);
|
||||
}
|
||||
//@}
|
||||
|
||||
VTKM_CONT
|
||||
void AddCoordinateSystem(const vtkm::cont::CoordinateSystem& cs)
|
||||
{
|
||||
@ -109,6 +147,9 @@ public:
|
||||
VTKM_CONT
|
||||
const vtkm::cont::CoordinateSystem& GetCoordinateSystem(vtkm::Id index = 0) const;
|
||||
|
||||
VTKM_CONT
|
||||
vtkm::cont::CoordinateSystem& GetCoordinateSystem(vtkm::Id index = 0);
|
||||
|
||||
/// Returns the index for the first CoordinateSystem whose
|
||||
/// name matches the provided string.
|
||||
/// Will return -1 if no match is found
|
||||
@ -117,44 +158,29 @@ public:
|
||||
|
||||
/// Returns the first CoordinateSystem that matches the provided name.
|
||||
/// Will throw an exception if no match is found
|
||||
//@{
|
||||
VTKM_CONT
|
||||
const vtkm::cont::CoordinateSystem& GetCoordinateSystem(const std::string& name) const;
|
||||
|
||||
VTKM_CONT
|
||||
void AddCellSet(const vtkm::cont::DynamicCellSet& cellSet) { this->CellSets.push_back(cellSet); }
|
||||
vtkm::cont::CoordinateSystem& GetCoordinateSystem(const std::string& name);
|
||||
//@}
|
||||
|
||||
VTKM_CONT
|
||||
void SetCellSet(const vtkm::cont::DynamicCellSet& cellSet) { this->CellSet = cellSet; }
|
||||
|
||||
template <typename CellSetType>
|
||||
VTKM_CONT void AddCellSet(const CellSetType& cellSet)
|
||||
VTKM_CONT void SetCellSet(const CellSetType& cellSet)
|
||||
{
|
||||
VTKM_IS_CELL_SET(CellSetType);
|
||||
this->CellSets.push_back(vtkm::cont::DynamicCellSet(cellSet));
|
||||
this->CellSet = vtkm::cont::DynamicCellSet(cellSet);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
bool HasCellSet(const std::string& name) const { return this->GetCellSetIndex(name) >= 0; }
|
||||
const vtkm::cont::DynamicCellSet& GetCellSet() const { return this->CellSet; }
|
||||
|
||||
VTKM_CONT
|
||||
const vtkm::cont::DynamicCellSet& GetCellSet(vtkm::Id index = 0) const;
|
||||
|
||||
|
||||
/// Returns the index for the first cell set whose
|
||||
/// name matches the provided string.
|
||||
/// Will return -1 if no match is found
|
||||
VTKM_CONT
|
||||
vtkm::Id GetCellSetIndex(const std::string& name) const;
|
||||
|
||||
|
||||
/// Returns the first DynamicCellSet that matches the provided name.
|
||||
/// Will throw an exception if no match is found
|
||||
VTKM_CONT
|
||||
const vtkm::cont::DynamicCellSet& GetCellSet(const std::string& name) const;
|
||||
|
||||
|
||||
VTKM_CONT
|
||||
vtkm::IdComponent GetNumberOfCellSets() const
|
||||
{
|
||||
return static_cast<vtkm::IdComponent>(this->CellSets.size());
|
||||
}
|
||||
vtkm::cont::DynamicCellSet& GetCellSet() { return this->CellSet; }
|
||||
|
||||
VTKM_CONT
|
||||
vtkm::IdComponent GetNumberOfFields() const
|
||||
@ -168,7 +194,7 @@ public:
|
||||
return static_cast<vtkm::IdComponent>(this->CoordSystems.size());
|
||||
}
|
||||
|
||||
/// Copies the structure i.e. coordinates systems and cellsets from the source
|
||||
/// Copies the structure i.e. coordinates systems and cellset from the source
|
||||
/// dataset. The fields are left unchanged.
|
||||
VTKM_CONT
|
||||
void CopyStructure(const vtkm::cont::DataSet& source);
|
||||
@ -179,7 +205,7 @@ public:
|
||||
private:
|
||||
std::vector<vtkm::cont::CoordinateSystem> CoordSystems;
|
||||
std::vector<vtkm::cont::Field> Fields;
|
||||
std::vector<vtkm::cont::DynamicCellSet> CellSets;
|
||||
vtkm::cont::DynamicCellSet CellSet;
|
||||
|
||||
VTKM_CONT
|
||||
vtkm::Id FindFieldIndex(const std::string& name,
|
||||
@ -234,12 +260,7 @@ public:
|
||||
vtkmdiy::save(bb, dataset.GetCoordinateSystem(i));
|
||||
}
|
||||
|
||||
vtkm::IdComponent numberOfCellSets = dataset.GetNumberOfCellSets();
|
||||
vtkmdiy::save(bb, numberOfCellSets);
|
||||
for (vtkm::IdComponent i = 0; i < numberOfCellSets; ++i)
|
||||
{
|
||||
vtkmdiy::save(bb, dataset.GetCellSet(i).ResetCellSetList(CellSetTypesList{}));
|
||||
}
|
||||
vtkmdiy::save(bb, dataset.GetCellSet().ResetCellSetList(CellSetTypesList{}));
|
||||
|
||||
vtkm::IdComponent numberOfFields = dataset.GetNumberOfFields();
|
||||
vtkmdiy::save(bb, numberOfFields);
|
||||
@ -263,14 +284,9 @@ public:
|
||||
dataset.AddCoordinateSystem(coords);
|
||||
}
|
||||
|
||||
vtkm::IdComponent numberOfCellSets = 0;
|
||||
vtkmdiy::load(bb, numberOfCellSets);
|
||||
for (vtkm::IdComponent i = 0; i < numberOfCellSets; ++i)
|
||||
{
|
||||
vtkm::cont::DynamicCellSetBase<CellSetTypesList> cells;
|
||||
vtkmdiy::load(bb, cells);
|
||||
dataset.AddCellSet(vtkm::cont::DynamicCellSet(cells));
|
||||
}
|
||||
vtkm::cont::DynamicCellSetBase<CellSetTypesList> cells;
|
||||
vtkmdiy::load(bb, cells);
|
||||
dataset.SetCellSet(vtkm::cont::DynamicCellSet(cells));
|
||||
|
||||
vtkm::IdComponent numberOfFields = 0;
|
||||
vtkmdiy::load(bb, numberOfFields);
|
||||
|
@ -22,11 +22,9 @@ DataSetBuilderExplicitIterative::DataSetBuilderExplicitIterative()
|
||||
|
||||
|
||||
VTKM_CONT
|
||||
void DataSetBuilderExplicitIterative::Begin(const std::string& coordName,
|
||||
const std::string& cellName)
|
||||
void DataSetBuilderExplicitIterative::Begin(const std::string& coordName)
|
||||
{
|
||||
this->coordNm = coordName;
|
||||
this->cellNm = cellName;
|
||||
this->points.resize(0);
|
||||
this->shapes.resize(0);
|
||||
this->numIdx.resize(0);
|
||||
@ -38,11 +36,11 @@ VTKM_CONT
|
||||
vtkm::cont::DataSet DataSetBuilderExplicitIterative::Create()
|
||||
{
|
||||
DataSetBuilderExplicit dsb;
|
||||
return dsb.Create(points, shapes, numIdx, connectivity, coordNm, cellNm);
|
||||
return dsb.Create(points, shapes, numIdx, connectivity, coordNm);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
vtkm::Id DataSetBuilderExplicitIterative::AddPoint(const vtkm::Vec3f_32& pt)
|
||||
vtkm::Id DataSetBuilderExplicitIterative::AddPoint(const vtkm::Vec3f& pt)
|
||||
{
|
||||
points.push_back(pt);
|
||||
vtkm::Id id = static_cast<vtkm::Id>(points.size());
|
||||
@ -51,9 +49,9 @@ vtkm::Id DataSetBuilderExplicitIterative::AddPoint(const vtkm::Vec3f_32& pt)
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
vtkm::Id DataSetBuilderExplicitIterative::AddPoint(const vtkm::Float32& x,
|
||||
const vtkm::Float32& y,
|
||||
const vtkm::Float32& z)
|
||||
vtkm::Id DataSetBuilderExplicitIterative::AddPoint(const vtkm::FloatDefault& x,
|
||||
const vtkm::FloatDefault& y,
|
||||
const vtkm::FloatDefault& z)
|
||||
{
|
||||
points.push_back(vtkm::make_Vec(x, y, z));
|
||||
vtkm::Id id = static_cast<vtkm::Id>(points.size());
|
||||
|
@ -45,12 +45,11 @@ public:
|
||||
const std::vector<vtkm::UInt8>& shapes,
|
||||
const std::vector<vtkm::IdComponent>& numIndices,
|
||||
const std::vector<vtkm::Id>& connectivity,
|
||||
const std::string& coordsNm = "coords",
|
||||
const std::string& cellNm = "cells")
|
||||
const std::string& coordsNm = "coords")
|
||||
{
|
||||
std::vector<T> yVals(xVals.size(), 0), zVals(xVals.size(), 0);
|
||||
return DataSetBuilderExplicit::Create(
|
||||
xVals, yVals, zVals, shapes, numIndices, connectivity, coordsNm, cellNm);
|
||||
xVals, yVals, zVals, shapes, numIndices, connectivity, coordsNm);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -59,12 +58,11 @@ public:
|
||||
const std::vector<vtkm::UInt8>& shapes,
|
||||
const std::vector<vtkm::IdComponent>& numIndices,
|
||||
const std::vector<vtkm::Id>& connectivity,
|
||||
const std::string& coordsNm = "coords",
|
||||
const std::string& cellNm = "cells")
|
||||
const std::string& coordsNm = "coords")
|
||||
{
|
||||
std::vector<T> zVals(xVals.size(), 0);
|
||||
return DataSetBuilderExplicit::Create(
|
||||
xVals, yVals, zVals, shapes, numIndices, connectivity, coordsNm, cellNm);
|
||||
xVals, yVals, zVals, shapes, numIndices, connectivity, coordsNm);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -74,8 +72,7 @@ public:
|
||||
const std::vector<vtkm::UInt8>& shapes,
|
||||
const std::vector<vtkm::IdComponent>& numIndices,
|
||||
const std::vector<vtkm::Id>& connectivity,
|
||||
const std::string& coordsNm = "coords",
|
||||
const std::string& cellNm = "cells");
|
||||
const std::string& coordsNm = "coords");
|
||||
|
||||
template <typename T>
|
||||
VTKM_CONT static vtkm::cont::DataSet Create(
|
||||
@ -85,11 +82,10 @@ public:
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8>& shapes,
|
||||
const vtkm::cont::ArrayHandle<vtkm::IdComponent>& numIndices,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id>& connectivity,
|
||||
const std::string& coordsNm = "coords",
|
||||
const std::string& cellNm = "cells")
|
||||
const std::string& coordsNm = "coords")
|
||||
{
|
||||
return DataSetBuilderExplicit::BuildDataSet(
|
||||
xVals, yVals, zVals, shapes, numIndices, connectivity, coordsNm, cellNm);
|
||||
xVals, yVals, zVals, shapes, numIndices, connectivity, coordsNm);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -97,8 +93,7 @@ public:
|
||||
const std::vector<vtkm::UInt8>& shapes,
|
||||
const std::vector<vtkm::IdComponent>& numIndices,
|
||||
const std::vector<vtkm::Id>& connectivity,
|
||||
const std::string& coordsNm = "coords",
|
||||
const std::string& cellNm = "cells");
|
||||
const std::string& coordsNm = "coords");
|
||||
|
||||
template <typename T>
|
||||
VTKM_CONT static vtkm::cont::DataSet Create(
|
||||
@ -106,11 +101,9 @@ public:
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8>& shapes,
|
||||
const vtkm::cont::ArrayHandle<vtkm::IdComponent>& numIndices,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id>& connectivity,
|
||||
const std::string& coordsNm = "coords",
|
||||
const std::string& cellNm = "cells")
|
||||
const std::string& coordsNm = "coords")
|
||||
{
|
||||
return DataSetBuilderExplicit::BuildDataSet(
|
||||
coords, shapes, numIndices, connectivity, coordsNm, cellNm);
|
||||
return DataSetBuilderExplicit::BuildDataSet(coords, shapes, numIndices, connectivity, coordsNm);
|
||||
}
|
||||
|
||||
template <typename T, typename CellShapeTag>
|
||||
@ -118,8 +111,7 @@ public:
|
||||
CellShapeTag tag,
|
||||
vtkm::IdComponent numberOfPointsPerCell,
|
||||
const std::vector<vtkm::Id>& connectivity,
|
||||
const std::string& coordsNm = "coords",
|
||||
const std::string& cellNm = "cells");
|
||||
const std::string& coordsNm = "coords");
|
||||
|
||||
template <typename T, typename CellShapeTag>
|
||||
VTKM_CONT static vtkm::cont::DataSet Create(
|
||||
@ -127,11 +119,10 @@ public:
|
||||
CellShapeTag tag,
|
||||
vtkm::IdComponent numberOfPointsPerCell,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id>& connectivity,
|
||||
const std::string& coordsNm = "coords",
|
||||
const std::string& cellNm = "cells")
|
||||
const std::string& coordsNm = "coords")
|
||||
{
|
||||
return DataSetBuilderExplicit::BuildDataSet(
|
||||
coords, tag, numberOfPointsPerCell, connectivity, coordsNm, cellNm);
|
||||
coords, tag, numberOfPointsPerCell, connectivity, coordsNm);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -143,8 +134,7 @@ private:
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8>& shapes,
|
||||
const vtkm::cont::ArrayHandle<vtkm::IdComponent>& numIndices,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id>& connectivity,
|
||||
const std::string& coordsNm,
|
||||
const std::string& cellNm);
|
||||
const std::string& coordsNm);
|
||||
|
||||
template <typename T>
|
||||
VTKM_CONT static vtkm::cont::DataSet BuildDataSet(
|
||||
@ -152,8 +142,7 @@ private:
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8>& shapes,
|
||||
const vtkm::cont::ArrayHandle<vtkm::IdComponent>& numIndices,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id>& connectivity,
|
||||
const std::string& coordsNm,
|
||||
const std::string& cellNm);
|
||||
const std::string& coordsNm);
|
||||
|
||||
template <typename T, typename CellShapeTag>
|
||||
VTKM_CONT static vtkm::cont::DataSet BuildDataSet(
|
||||
@ -161,8 +150,7 @@ private:
|
||||
CellShapeTag tag,
|
||||
vtkm::IdComponent numberOfPointsPerCell,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id>& connectivity,
|
||||
const std::string& coordsNm,
|
||||
const std::string& cellNm);
|
||||
const std::string& coordsNm);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
@ -173,8 +161,7 @@ inline VTKM_CONT vtkm::cont::DataSet DataSetBuilderExplicit::Create(
|
||||
const std::vector<vtkm::UInt8>& shapes,
|
||||
const std::vector<vtkm::IdComponent>& numIndices,
|
||||
const std::vector<vtkm::Id>& connectivity,
|
||||
const std::string& coordsNm,
|
||||
const std::string& cellNm)
|
||||
const std::string& coordsNm)
|
||||
{
|
||||
VTKM_ASSERT(xVals.size() == yVals.size() && yVals.size() == zVals.size() && xVals.size() > 0);
|
||||
|
||||
@ -190,7 +177,7 @@ inline VTKM_CONT vtkm::cont::DataSet DataSetBuilderExplicit::Create(
|
||||
DataSetBuilderExplicit::CopyInto(numIndices, Nc);
|
||||
DataSetBuilderExplicit::CopyInto(connectivity, Cc);
|
||||
|
||||
return DataSetBuilderExplicit::BuildDataSet(Xc, Yc, Zc, Sc, Nc, Cc, coordsNm, cellNm);
|
||||
return DataSetBuilderExplicit::BuildDataSet(Xc, Yc, Zc, Sc, Nc, Cc, coordsNm);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -201,8 +188,7 @@ inline VTKM_CONT vtkm::cont::DataSet DataSetBuilderExplicit::BuildDataSet(
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8>& shapes,
|
||||
const vtkm::cont::ArrayHandle<vtkm::IdComponent>& numIndices,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id>& connectivity,
|
||||
const std::string& coordsNm,
|
||||
const std::string& cellNm)
|
||||
const std::string& coordsNm)
|
||||
{
|
||||
VTKM_ASSERT(X.GetNumberOfValues() == Y.GetNumberOfValues() &&
|
||||
Y.GetNumberOfValues() == Z.GetNumberOfValues() && X.GetNumberOfValues() > 0 &&
|
||||
@ -212,10 +198,10 @@ inline VTKM_CONT vtkm::cont::DataSet DataSetBuilderExplicit::BuildDataSet(
|
||||
dataSet.AddCoordinateSystem(
|
||||
vtkm::cont::CoordinateSystem(coordsNm, make_ArrayHandleCompositeVector(X, Y, Z)));
|
||||
vtkm::Id nPts = X.GetNumberOfValues();
|
||||
vtkm::cont::CellSetExplicit<> cellSet(cellNm);
|
||||
vtkm::cont::CellSetExplicit<> cellSet;
|
||||
|
||||
cellSet.Fill(nPts, shapes, numIndices, connectivity);
|
||||
dataSet.AddCellSet(cellSet);
|
||||
dataSet.SetCellSet(cellSet);
|
||||
|
||||
return dataSet;
|
||||
}
|
||||
@ -226,8 +212,7 @@ inline VTKM_CONT vtkm::cont::DataSet DataSetBuilderExplicit::Create(
|
||||
const std::vector<vtkm::UInt8>& shapes,
|
||||
const std::vector<vtkm::IdComponent>& numIndices,
|
||||
const std::vector<vtkm::Id>& connectivity,
|
||||
const std::string& coordsNm,
|
||||
const std::string& cellNm)
|
||||
const std::string& coordsNm)
|
||||
{
|
||||
vtkm::cont::ArrayHandle<Vec<T, 3>> coordsArray;
|
||||
DataSetBuilderExplicit::CopyInto(coords, coordsArray);
|
||||
@ -239,7 +224,7 @@ inline VTKM_CONT vtkm::cont::DataSet DataSetBuilderExplicit::Create(
|
||||
DataSetBuilderExplicit::CopyInto(numIndices, Nc);
|
||||
DataSetBuilderExplicit::CopyInto(connectivity, Cc);
|
||||
|
||||
return DataSetBuilderExplicit::Create(coordsArray, Sc, Nc, Cc, coordsNm, cellNm);
|
||||
return DataSetBuilderExplicit::Create(coordsArray, Sc, Nc, Cc, coordsNm);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -248,17 +233,16 @@ inline VTKM_CONT vtkm::cont::DataSet DataSetBuilderExplicit::BuildDataSet(
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8>& shapes,
|
||||
const vtkm::cont::ArrayHandle<vtkm::IdComponent>& numIndices,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id>& connectivity,
|
||||
const std::string& coordsNm,
|
||||
const std::string& cellNm)
|
||||
const std::string& coordsNm)
|
||||
{
|
||||
vtkm::cont::DataSet dataSet;
|
||||
|
||||
dataSet.AddCoordinateSystem(vtkm::cont::CoordinateSystem(coordsNm, coords));
|
||||
vtkm::Id nPts = static_cast<vtkm::Id>(coords.GetNumberOfValues());
|
||||
vtkm::cont::CellSetExplicit<> cellSet(cellNm);
|
||||
vtkm::cont::CellSetExplicit<> cellSet;
|
||||
|
||||
cellSet.Fill(nPts, shapes, numIndices, connectivity);
|
||||
dataSet.AddCellSet(cellSet);
|
||||
dataSet.SetCellSet(cellSet);
|
||||
|
||||
return dataSet;
|
||||
}
|
||||
@ -269,8 +253,7 @@ inline VTKM_CONT vtkm::cont::DataSet DataSetBuilderExplicit::Create(
|
||||
CellShapeTag tag,
|
||||
vtkm::IdComponent numberOfPointsPerCell,
|
||||
const std::vector<vtkm::Id>& connectivity,
|
||||
const std::string& coordsNm,
|
||||
const std::string& cellNm)
|
||||
const std::string& coordsNm)
|
||||
{
|
||||
vtkm::cont::ArrayHandle<Vec<T, 3>> coordsArray;
|
||||
DataSetBuilderExplicit::CopyInto(coords, coordsArray);
|
||||
@ -278,8 +261,7 @@ inline VTKM_CONT vtkm::cont::DataSet DataSetBuilderExplicit::Create(
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> Cc;
|
||||
DataSetBuilderExplicit::CopyInto(connectivity, Cc);
|
||||
|
||||
return DataSetBuilderExplicit::Create(
|
||||
coordsArray, tag, numberOfPointsPerCell, Cc, coordsNm, cellNm);
|
||||
return DataSetBuilderExplicit::Create(coordsArray, tag, numberOfPointsPerCell, Cc, coordsNm);
|
||||
}
|
||||
|
||||
template <typename T, typename CellShapeTag>
|
||||
@ -288,17 +270,16 @@ inline VTKM_CONT vtkm::cont::DataSet DataSetBuilderExplicit::BuildDataSet(
|
||||
CellShapeTag tag,
|
||||
vtkm::IdComponent numberOfPointsPerCell,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id>& connectivity,
|
||||
const std::string& coordsNm,
|
||||
const std::string& cellNm)
|
||||
const std::string& coordsNm)
|
||||
{
|
||||
(void)tag; //C4100 false positive workaround
|
||||
vtkm::cont::DataSet dataSet;
|
||||
|
||||
dataSet.AddCoordinateSystem(vtkm::cont::CoordinateSystem(coordsNm, coords));
|
||||
vtkm::cont::CellSetSingleType<> cellSet(cellNm);
|
||||
vtkm::cont::CellSetSingleType<> cellSet;
|
||||
|
||||
cellSet.Fill(coords.GetNumberOfValues(), tag.Id, numberOfPointsPerCell, connectivity);
|
||||
dataSet.AddCellSet(cellSet);
|
||||
dataSet.SetCellSet(cellSet);
|
||||
|
||||
return dataSet;
|
||||
}
|
||||
@ -310,29 +291,32 @@ public:
|
||||
DataSetBuilderExplicitIterative();
|
||||
|
||||
VTKM_CONT
|
||||
void Begin(const std::string& coordName = "coords", const std::string& cellName = "cells");
|
||||
void Begin(const std::string& coordName = "coords");
|
||||
|
||||
//Define points.
|
||||
VTKM_CONT
|
||||
vtkm::cont::DataSet Create();
|
||||
|
||||
VTKM_CONT
|
||||
vtkm::Id AddPoint(const vtkm::Vec3f_32& pt);
|
||||
vtkm::Id AddPoint(const vtkm::Vec3f& pt);
|
||||
|
||||
VTKM_CONT
|
||||
vtkm::Id AddPoint(const vtkm::Float32& x, const vtkm::Float32& y, const vtkm::Float32& z = 0);
|
||||
vtkm::Id AddPoint(const vtkm::FloatDefault& x,
|
||||
const vtkm::FloatDefault& y,
|
||||
const vtkm::FloatDefault& z = 0);
|
||||
|
||||
template <typename T>
|
||||
VTKM_CONT vtkm::Id AddPoint(const T& x, const T& y, const T& z = 0)
|
||||
{
|
||||
return AddPoint(
|
||||
static_cast<vtkm::Float32>(x), static_cast<vtkm::Float32>(y), static_cast<vtkm::Float32>(z));
|
||||
return AddPoint(static_cast<vtkm::FloatDefault>(x),
|
||||
static_cast<vtkm::FloatDefault>(y),
|
||||
static_cast<vtkm::FloatDefault>(z));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
VTKM_CONT vtkm::Id AddPoint(const vtkm::Vec<T, 3>& pt)
|
||||
{
|
||||
return AddPoint(static_cast<vtkm::Vec3f_32>(pt));
|
||||
return AddPoint(static_cast<vtkm::Vec3f>(pt));
|
||||
}
|
||||
|
||||
//Define cells.
|
||||
@ -349,9 +333,9 @@ public:
|
||||
void AddCellPoint(vtkm::Id pointIndex);
|
||||
|
||||
private:
|
||||
std::string coordNm, cellNm;
|
||||
std::string coordNm;
|
||||
|
||||
std::vector<vtkm::Vec3f_32> points;
|
||||
std::vector<vtkm::Vec3f> points;
|
||||
std::vector<vtkm::UInt8> shapes;
|
||||
std::vector<vtkm::IdComponent> numIdx;
|
||||
std::vector<vtkm::Id> connectivity;
|
||||
|
@ -50,46 +50,41 @@ public:
|
||||
//1D grids.
|
||||
template <typename T>
|
||||
VTKM_CONT static vtkm::cont::DataSet Create(const std::vector<T>& xvals,
|
||||
std::string coordNm = "coords",
|
||||
std::string cellNm = "cells")
|
||||
const std::string& coordNm = "coords")
|
||||
{
|
||||
std::vector<T> yvals(1, 0), zvals(1, 0);
|
||||
return DataSetBuilderRectilinear::BuildDataSet(xvals, yvals, zvals, coordNm, cellNm);
|
||||
return DataSetBuilderRectilinear::BuildDataSet(xvals, yvals, zvals, coordNm);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
VTKM_CONT static vtkm::cont::DataSet Create(vtkm::Id nx,
|
||||
T* xvals,
|
||||
std::string coordNm = "coords",
|
||||
std::string cellNm = "cells")
|
||||
const std::string& coordNm = "coords")
|
||||
{
|
||||
T yvals = 0, zvals = 0;
|
||||
return DataSetBuilderRectilinear::BuildDataSet(
|
||||
nx, 1, 1, xvals, &yvals, &zvals, coordNm, cellNm);
|
||||
return DataSetBuilderRectilinear::BuildDataSet(nx, 1, 1, xvals, &yvals, &zvals, coordNm);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
VTKM_CONT static vtkm::cont::DataSet Create(const vtkm::cont::ArrayHandle<T>& xvals,
|
||||
std::string coordNm = "coords",
|
||||
std::string cellNm = "cells")
|
||||
const std::string& coordNm = "coords")
|
||||
{
|
||||
vtkm::cont::ArrayHandle<T> yvals, zvals;
|
||||
yvals.Allocate(1);
|
||||
yvals.GetPortalControl().Set(0, 0.0);
|
||||
zvals.Allocate(1);
|
||||
zvals.GetPortalControl().Set(0, 0.0);
|
||||
return DataSetBuilderRectilinear::BuildDataSet(xvals, yvals, zvals, coordNm, cellNm);
|
||||
return DataSetBuilderRectilinear::BuildDataSet(xvals, yvals, zvals, coordNm);
|
||||
}
|
||||
|
||||
//2D grids.
|
||||
template <typename T>
|
||||
VTKM_CONT static vtkm::cont::DataSet Create(const std::vector<T>& xvals,
|
||||
const std::vector<T>& yvals,
|
||||
std::string coordNm = "coords",
|
||||
std::string cellNm = "cells")
|
||||
const std::string& coordNm = "coords")
|
||||
{
|
||||
std::vector<T> zvals(1, 0);
|
||||
return DataSetBuilderRectilinear::BuildDataSet(xvals, yvals, zvals, coordNm, cellNm);
|
||||
return DataSetBuilderRectilinear::BuildDataSet(xvals, yvals, zvals, coordNm);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -97,24 +92,21 @@ public:
|
||||
vtkm::Id ny,
|
||||
T* xvals,
|
||||
T* yvals,
|
||||
std::string coordNm = "coords",
|
||||
std::string cellNm = "cells")
|
||||
const std::string& coordNm = "coords")
|
||||
{
|
||||
T zvals = 0;
|
||||
return DataSetBuilderRectilinear::BuildDataSet(
|
||||
nx, ny, 1, xvals, yvals, &zvals, coordNm, cellNm);
|
||||
return DataSetBuilderRectilinear::BuildDataSet(nx, ny, 1, xvals, yvals, &zvals, coordNm);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
VTKM_CONT static vtkm::cont::DataSet Create(const vtkm::cont::ArrayHandle<T>& xvals,
|
||||
const vtkm::cont::ArrayHandle<T>& yvals,
|
||||
std::string coordNm = "coords",
|
||||
std::string cellNm = "cells")
|
||||
const std::string& coordNm = "coords")
|
||||
{
|
||||
vtkm::cont::ArrayHandle<T> zvals;
|
||||
zvals.Allocate(1);
|
||||
zvals.GetPortalControl().Set(0, 0.0);
|
||||
return DataSetBuilderRectilinear::BuildDataSet(xvals, yvals, zvals, coordNm, cellNm);
|
||||
return DataSetBuilderRectilinear::BuildDataSet(xvals, yvals, zvals, coordNm);
|
||||
}
|
||||
|
||||
//3D grids.
|
||||
@ -125,31 +117,27 @@ public:
|
||||
T* xvals,
|
||||
T* yvals,
|
||||
T* zvals,
|
||||
std::string coordNm = "coords",
|
||||
std::string cellNm = "cells")
|
||||
const std::string& coordNm = "coords")
|
||||
{
|
||||
return DataSetBuilderRectilinear::BuildDataSet(
|
||||
nx, ny, nz, xvals, yvals, zvals, coordNm, cellNm);
|
||||
return DataSetBuilderRectilinear::BuildDataSet(nx, ny, nz, xvals, yvals, zvals, coordNm);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
VTKM_CONT static vtkm::cont::DataSet Create(const std::vector<T>& xvals,
|
||||
const std::vector<T>& yvals,
|
||||
const std::vector<T>& zvals,
|
||||
std::string coordNm = "coords",
|
||||
std::string cellNm = "cells")
|
||||
const std::string& coordNm = "coords")
|
||||
{
|
||||
return DataSetBuilderRectilinear::BuildDataSet(xvals, yvals, zvals, coordNm, cellNm);
|
||||
return DataSetBuilderRectilinear::BuildDataSet(xvals, yvals, zvals, coordNm);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
VTKM_CONT static vtkm::cont::DataSet Create(const vtkm::cont::ArrayHandle<T>& xvals,
|
||||
const vtkm::cont::ArrayHandle<T>& yvals,
|
||||
const vtkm::cont::ArrayHandle<T>& zvals,
|
||||
std::string coordNm = "coords",
|
||||
std::string cellNm = "cells")
|
||||
const std::string& coordNm = "coords")
|
||||
{
|
||||
return DataSetBuilderRectilinear::BuildDataSet(xvals, yvals, zvals, coordNm, cellNm);
|
||||
return DataSetBuilderRectilinear::BuildDataSet(xvals, yvals, zvals, coordNm);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -157,15 +145,14 @@ private:
|
||||
VTKM_CONT static vtkm::cont::DataSet BuildDataSet(const std::vector<T>& xvals,
|
||||
const std::vector<T>& yvals,
|
||||
const std::vector<T>& zvals,
|
||||
std::string coordNm,
|
||||
std::string cellNm)
|
||||
const std::string& coordNm)
|
||||
{
|
||||
vtkm::cont::ArrayHandle<vtkm::FloatDefault> Xc, Yc, Zc;
|
||||
DataSetBuilderRectilinear::CopyInto(xvals, Xc);
|
||||
DataSetBuilderRectilinear::CopyInto(yvals, Yc);
|
||||
DataSetBuilderRectilinear::CopyInto(zvals, Zc);
|
||||
|
||||
return DataSetBuilderRectilinear::BuildDataSet(Xc, Yc, Zc, coordNm, cellNm);
|
||||
return DataSetBuilderRectilinear::BuildDataSet(Xc, Yc, Zc, coordNm);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -175,23 +162,21 @@ private:
|
||||
const T* xvals,
|
||||
const T* yvals,
|
||||
const T* zvals,
|
||||
std::string coordNm,
|
||||
std::string cellNm)
|
||||
const std::string& coordNm)
|
||||
{
|
||||
vtkm::cont::ArrayHandle<vtkm::FloatDefault> Xc, Yc, Zc;
|
||||
DataSetBuilderRectilinear::CopyInto(xvals, nx, Xc);
|
||||
DataSetBuilderRectilinear::CopyInto(yvals, ny, Yc);
|
||||
DataSetBuilderRectilinear::CopyInto(zvals, nz, Zc);
|
||||
|
||||
return DataSetBuilderRectilinear::BuildDataSet(Xc, Yc, Zc, coordNm, cellNm);
|
||||
return DataSetBuilderRectilinear::BuildDataSet(Xc, Yc, Zc, coordNm);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
VTKM_CONT static vtkm::cont::DataSet BuildDataSet(const vtkm::cont::ArrayHandle<T>& X,
|
||||
const vtkm::cont::ArrayHandle<T>& Y,
|
||||
const vtkm::cont::ArrayHandle<T>& Z,
|
||||
std::string coordNm,
|
||||
std::string cellNm)
|
||||
const std::string& coordNm)
|
||||
{
|
||||
vtkm::cont::DataSet dataSet;
|
||||
|
||||
@ -229,21 +214,21 @@ private:
|
||||
|
||||
if (ndims == 1)
|
||||
{
|
||||
vtkm::cont::CellSetStructured<1> cellSet(cellNm);
|
||||
vtkm::cont::CellSetStructured<1> cellSet;
|
||||
cellSet.SetPointDimensions(dims[0]);
|
||||
dataSet.AddCellSet(cellSet);
|
||||
dataSet.SetCellSet(cellSet);
|
||||
}
|
||||
else if (ndims == 2)
|
||||
{
|
||||
vtkm::cont::CellSetStructured<2> cellSet(cellNm);
|
||||
vtkm::cont::CellSetStructured<2> cellSet;
|
||||
cellSet.SetPointDimensions(vtkm::make_Vec(dims[0], dims[1]));
|
||||
dataSet.AddCellSet(cellSet);
|
||||
dataSet.SetCellSet(cellSet);
|
||||
}
|
||||
else if (ndims == 3)
|
||||
{
|
||||
vtkm::cont::CellSetStructured<3> cellSet(cellNm);
|
||||
vtkm::cont::CellSetStructured<3> cellSet;
|
||||
cellSet.SetPointDimensions(vtkm::make_Vec(dims[0], dims[1], dims[2]));
|
||||
dataSet.AddCellSet(cellSet);
|
||||
dataSet.SetCellSet(cellSet);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -22,39 +22,31 @@ DataSetBuilderUniform::DataSetBuilderUniform()
|
||||
|
||||
VTKM_CONT
|
||||
vtkm::cont::DataSet DataSetBuilderUniform::Create(const vtkm::Id& dimension,
|
||||
std::string coordNm,
|
||||
std::string cellNm)
|
||||
const std::string& coordNm)
|
||||
{
|
||||
return CreateDataSet(vtkm::Id3(dimension, 1, 1), VecType(0), VecType(1), coordNm, cellNm);
|
||||
return CreateDataSet(vtkm::Id3(dimension, 1, 1), VecType(0), VecType(1), coordNm);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
vtkm::cont::DataSet DataSetBuilderUniform::Create(const vtkm::Id2& dimensions,
|
||||
std::string coordNm,
|
||||
std::string cellNm)
|
||||
const std::string& coordNm)
|
||||
{
|
||||
return CreateDataSet(
|
||||
vtkm::Id3(dimensions[0], dimensions[1], 1), VecType(0), VecType(1), coordNm, cellNm);
|
||||
return CreateDataSet(vtkm::Id3(dimensions[0], dimensions[1], 1), VecType(0), VecType(1), coordNm);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
vtkm::cont::DataSet DataSetBuilderUniform::Create(const vtkm::Id3& dimensions,
|
||||
std::string coordNm,
|
||||
std::string cellNm)
|
||||
const std::string& coordNm)
|
||||
{
|
||||
return CreateDataSet(vtkm::Id3(dimensions[0], dimensions[1], dimensions[2]),
|
||||
VecType(0),
|
||||
VecType(1),
|
||||
coordNm,
|
||||
cellNm);
|
||||
return CreateDataSet(
|
||||
vtkm::Id3(dimensions[0], dimensions[1], dimensions[2]), VecType(0), VecType(1), coordNm);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
vtkm::cont::DataSet DataSetBuilderUniform::CreateDataSet(const vtkm::Id3& dimensions,
|
||||
const vtkm::Vec3f& origin,
|
||||
const vtkm::Vec3f& spacing,
|
||||
std::string coordNm,
|
||||
std::string cellNm)
|
||||
const std::string& coordNm)
|
||||
{
|
||||
vtkm::Id dims[3] = { 1, 1, 1 };
|
||||
int ndims = 0;
|
||||
@ -77,21 +69,21 @@ vtkm::cont::DataSet DataSetBuilderUniform::CreateDataSet(const vtkm::Id3& dimens
|
||||
|
||||
if (ndims == 1)
|
||||
{
|
||||
vtkm::cont::CellSetStructured<1> cellSet(cellNm);
|
||||
vtkm::cont::CellSetStructured<1> cellSet;
|
||||
cellSet.SetPointDimensions(dims[0]);
|
||||
dataSet.AddCellSet(cellSet);
|
||||
dataSet.SetCellSet(cellSet);
|
||||
}
|
||||
else if (ndims == 2)
|
||||
{
|
||||
vtkm::cont::CellSetStructured<2> cellSet(cellNm);
|
||||
vtkm::cont::CellSetStructured<2> cellSet;
|
||||
cellSet.SetPointDimensions(vtkm::Id2(dims[0], dims[1]));
|
||||
dataSet.AddCellSet(cellSet);
|
||||
dataSet.SetCellSet(cellSet);
|
||||
}
|
||||
else if (ndims == 3)
|
||||
{
|
||||
vtkm::cont::CellSetStructured<3> cellSet(cellNm);
|
||||
vtkm::cont::CellSetStructured<3> cellSet;
|
||||
cellSet.SetPointDimensions(vtkm::Id3(dims[0], dims[1], dims[2]));
|
||||
dataSet.AddCellSet(cellSet);
|
||||
dataSet.SetCellSet(cellSet);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -31,29 +31,25 @@ public:
|
||||
VTKM_CONT static vtkm::cont::DataSet Create(const vtkm::Id& dimension,
|
||||
const T& origin,
|
||||
const T& spacing,
|
||||
std::string coordNm = "coords",
|
||||
std::string cellNm = "cells")
|
||||
const std::string& coordNm = "coords")
|
||||
{
|
||||
return DataSetBuilderUniform::CreateDataSet(
|
||||
vtkm::Id3(dimension, 1, 1),
|
||||
VecType(static_cast<vtkm::FloatDefault>(origin), 0, 0),
|
||||
VecType(static_cast<vtkm::FloatDefault>(spacing), 1, 1),
|
||||
coordNm,
|
||||
cellNm);
|
||||
coordNm);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
static vtkm::cont::DataSet Create(const vtkm::Id& dimension,
|
||||
std::string coordNm = "coords",
|
||||
std::string cellNm = "cells");
|
||||
const std::string& coordNm = "coords");
|
||||
|
||||
//2D uniform grids.
|
||||
template <typename T>
|
||||
VTKM_CONT static vtkm::cont::DataSet Create(const vtkm::Id2& dimensions,
|
||||
const vtkm::Vec<T, 2>& origin,
|
||||
const vtkm::Vec<T, 2>& spacing,
|
||||
std::string coordNm = "coords",
|
||||
std::string cellNm = "cells")
|
||||
const std::string& coordNm = "coords")
|
||||
{
|
||||
return DataSetBuilderUniform::CreateDataSet(vtkm::Id3(dimensions[0], dimensions[1], 1),
|
||||
VecType(static_cast<vtkm::FloatDefault>(origin[0]),
|
||||
@ -62,22 +58,19 @@ public:
|
||||
VecType(static_cast<vtkm::FloatDefault>(spacing[0]),
|
||||
static_cast<vtkm::FloatDefault>(spacing[1]),
|
||||
1),
|
||||
coordNm,
|
||||
cellNm);
|
||||
coordNm);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
static vtkm::cont::DataSet Create(const vtkm::Id2& dimensions,
|
||||
std::string coordNm = "coords",
|
||||
std::string cellNm = "cells");
|
||||
const std::string& coordNm = "coords");
|
||||
|
||||
//3D uniform grids.
|
||||
template <typename T>
|
||||
VTKM_CONT static vtkm::cont::DataSet Create(const vtkm::Id3& dimensions,
|
||||
const vtkm::Vec<T, 3>& origin,
|
||||
const vtkm::Vec<T, 3>& spacing,
|
||||
std::string coordNm = "coords",
|
||||
std::string cellNm = "cells")
|
||||
const std::string& coordNm = "coords")
|
||||
{
|
||||
return DataSetBuilderUniform::CreateDataSet(
|
||||
vtkm::Id3(dimensions[0], dimensions[1], dimensions[2]),
|
||||
@ -87,22 +80,19 @@ public:
|
||||
VecType(static_cast<vtkm::FloatDefault>(spacing[0]),
|
||||
static_cast<vtkm::FloatDefault>(spacing[1]),
|
||||
static_cast<vtkm::FloatDefault>(spacing[2])),
|
||||
coordNm,
|
||||
cellNm);
|
||||
coordNm);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
static vtkm::cont::DataSet Create(const vtkm::Id3& dimensions,
|
||||
std::string coordNm = "coords",
|
||||
std::string cellNm = "cells");
|
||||
const std::string& coordNm = "coords");
|
||||
|
||||
private:
|
||||
VTKM_CONT
|
||||
static vtkm::cont::DataSet CreateDataSet(const vtkm::Id3& dimensions,
|
||||
const vtkm::Vec3f& origin,
|
||||
const vtkm::Vec3f& spacing,
|
||||
std::string coordNm,
|
||||
std::string cellNm);
|
||||
const std::string& coordNm);
|
||||
};
|
||||
|
||||
} // namespace cont
|
||||
|
@ -64,83 +64,36 @@ public:
|
||||
VTKM_CONT
|
||||
static void AddCellField(vtkm::cont::DataSet& dataSet,
|
||||
const std::string& fieldName,
|
||||
const vtkm::cont::VariantArrayHandle& field,
|
||||
const std::string& cellSetName)
|
||||
const vtkm::cont::VariantArrayHandle& field)
|
||||
{
|
||||
dataSet.AddField(make_FieldCell(fieldName, cellSetName, field));
|
||||
dataSet.AddField(make_FieldCell(fieldName, field));
|
||||
}
|
||||
|
||||
template <typename T, typename Storage>
|
||||
VTKM_CONT static void AddCellField(vtkm::cont::DataSet& dataSet,
|
||||
const std::string& fieldName,
|
||||
const vtkm::cont::ArrayHandle<T, Storage>& field,
|
||||
const std::string& cellSetName)
|
||||
const vtkm::cont::ArrayHandle<T, Storage>& field)
|
||||
{
|
||||
dataSet.AddField(make_FieldCell(fieldName, cellSetName, field));
|
||||
dataSet.AddField(make_FieldCell(fieldName, field));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
VTKM_CONT static void AddCellField(vtkm::cont::DataSet& dataSet,
|
||||
const std::string& fieldName,
|
||||
const std::vector<T>& field,
|
||||
const std::string& cellSetName)
|
||||
const std::vector<T>& field)
|
||||
{
|
||||
dataSet.AddField(
|
||||
make_Field(fieldName, vtkm::cont::Field::Association::CELL_SET, field, vtkm::CopyFlag::On));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
VTKM_CONT static void AddCellField(vtkm::cont::DataSet& dataSet,
|
||||
const std::string& fieldName,
|
||||
const T* field,
|
||||
const vtkm::Id& n)
|
||||
{
|
||||
dataSet.AddField(make_Field(
|
||||
fieldName, vtkm::cont::Field::Association::CELL_SET, cellSetName, field, vtkm::CopyFlag::On));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
VTKM_CONT static void AddCellField(vtkm::cont::DataSet& dataSet,
|
||||
const std::string& fieldName,
|
||||
const T* field,
|
||||
const vtkm::Id& n,
|
||||
const std::string& cellSetName)
|
||||
{
|
||||
dataSet.AddField(make_Field(fieldName,
|
||||
vtkm::cont::Field::Association::CELL_SET,
|
||||
cellSetName,
|
||||
field,
|
||||
n,
|
||||
vtkm::CopyFlag::On));
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
static void AddCellField(vtkm::cont::DataSet& dataSet,
|
||||
const std::string& fieldName,
|
||||
const vtkm::cont::VariantArrayHandle& field,
|
||||
vtkm::Id cellSetIndex = 0)
|
||||
{
|
||||
std::string cellSetName = dataSet.GetCellSet(cellSetIndex).GetName();
|
||||
DataSetFieldAdd::AddCellField(dataSet, fieldName, field, cellSetName);
|
||||
}
|
||||
template <typename T, typename Storage>
|
||||
VTKM_CONT static void AddCellField(vtkm::cont::DataSet& dataSet,
|
||||
const std::string& fieldName,
|
||||
const vtkm::cont::ArrayHandle<T, Storage>& field,
|
||||
vtkm::Id cellSetIndex = 0)
|
||||
{
|
||||
std::string cellSetName = dataSet.GetCellSet(cellSetIndex).GetName();
|
||||
DataSetFieldAdd::AddCellField(dataSet, fieldName, field, cellSetName);
|
||||
}
|
||||
template <typename T>
|
||||
VTKM_CONT static void AddCellField(vtkm::cont::DataSet& dataSet,
|
||||
const std::string& fieldName,
|
||||
const std::vector<T>& field,
|
||||
vtkm::Id cellSetIndex = 0)
|
||||
{
|
||||
std::string cellSetName = dataSet.GetCellSet(cellSetIndex).GetName();
|
||||
DataSetFieldAdd::AddCellField(dataSet, fieldName, field, cellSetName);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
VTKM_CONT static void AddCellField(vtkm::cont::DataSet& dataSet,
|
||||
const std::string& fieldName,
|
||||
const T* field,
|
||||
const vtkm::Id& n,
|
||||
vtkm::Id cellSetIndex = 0)
|
||||
{
|
||||
std::string cellSetName = dataSet.GetCellSet(cellSetIndex).GetName();
|
||||
DataSetFieldAdd::AddCellField(dataSet, fieldName, field, n, cellSetName);
|
||||
fieldName, vtkm::cont::Field::Association::CELL_SET, field, n, vtkm::CopyFlag::On));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -378,6 +378,55 @@ struct DeviceAdapterAlgorithm
|
||||
const vtkm::cont::ArrayHandle<U, VIn>& values,
|
||||
vtkm::cont::ArrayHandle<U, VOut>& output);
|
||||
|
||||
/// \brief Compute an extended prefix sum operation on the input ArrayHandle.
|
||||
///
|
||||
/// Computes an extended prefix sum operation on the \c input ArrayHandle,
|
||||
/// storing the results in the \c output ArrayHandle. This produces an output
|
||||
/// array that contains both an inclusive scan (in elements [1, size)) and an
|
||||
/// exclusive scan (in elements [0, size-1)). By using ArrayHandleView,
|
||||
/// arrays containing both inclusive and exclusive scans can be generated
|
||||
/// from an extended scan with minimal memory usage.
|
||||
///
|
||||
/// This algorithm may also be more efficient than ScanInclusive and
|
||||
/// ScanExclusive on some devices, since it may be able to avoid copying the
|
||||
/// total sum to the control environment to return.
|
||||
///
|
||||
/// ScanExtended is similar to the stl partial sum function, exception that
|
||||
/// ScanExtended doesn't do a serial summation. This means that if you have
|
||||
/// defined a custom plus operator for T it must be associative, or you will
|
||||
/// get inconsistent results.
|
||||
///
|
||||
/// This overload of ScanExtended uses vtkm::Add for the binary functor, and
|
||||
/// uses zero for the initial value of the scan operation.
|
||||
///
|
||||
template <typename T, class CIn, class COut>
|
||||
VTKM_CONT static void ScanExtended(const vtkm::cont::ArrayHandle<T, CIn>& input,
|
||||
vtkm::cont::ArrayHandle<T, COut>& output);
|
||||
|
||||
/// \brief Compute an extended prefix sum operation on the input ArrayHandle.
|
||||
///
|
||||
/// Computes an extended prefix sum operation on the \c input ArrayHandle,
|
||||
/// storing the results in the \c output ArrayHandle. This produces an output
|
||||
/// array that contains both an inclusive scan (in elements [1, size)) and an
|
||||
/// exclusive scan (in elements [0, size-1)). By using ArrayHandleView,
|
||||
/// arrays containing both inclusive and exclusive scans can be generated
|
||||
/// from an extended scan with minimal memory usage.
|
||||
///
|
||||
/// This algorithm may also be more efficient than ScanInclusive and
|
||||
/// ScanExclusive on some devices, since it may be able to avoid copying the
|
||||
/// total sum to the control environment to return.
|
||||
///
|
||||
/// ScanExtended is similar to the stl partial sum function, exception that
|
||||
/// ScanExtended doesn't do a serial summation. This means that if you have
|
||||
/// defined a custom plus operator for T it must be associative, or you will
|
||||
/// get inconsistent results.
|
||||
///
|
||||
template <typename T, class CIn, class COut, class BinaryFunctor>
|
||||
VTKM_CONT static void ScanExtended(const vtkm::cont::ArrayHandle<T, CIn>& input,
|
||||
vtkm::cont::ArrayHandle<T, COut>& output,
|
||||
BinaryFunctor binaryFunctor,
|
||||
const T& initialValue);
|
||||
|
||||
/// \brief Schedule many instances of a function to run on concurrent threads.
|
||||
///
|
||||
/// Calls the \c functor on several threads. This is the function used in the
|
||||
@ -683,15 +732,6 @@ public:
|
||||
#endif
|
||||
};
|
||||
|
||||
/// \brief Class providing a device-specific support for atomic operations.
|
||||
///
|
||||
/// The class provide the actual implementation used by
|
||||
/// vtkm::cont::DeviceAdapterAtomicArrayImplementation.
|
||||
///
|
||||
/// TODO combine this with AtomicInterfaceExecution.
|
||||
template <typename T, typename DeviceTag>
|
||||
class DeviceAdapterAtomicArrayImplementation;
|
||||
|
||||
/// \brief Class providing a device-specific support for atomic operations.
|
||||
///
|
||||
/// AtomicInterfaceControl provides atomic operations for the control
|
||||
|
@ -174,9 +174,6 @@ public:
|
||||
VTKM_CONT
|
||||
const vtkm::cont::CellSet* GetCellSetBase() const { return this->CellSet.get(); }
|
||||
|
||||
VTKM_CONT
|
||||
std::string GetName() const { return this->CellSet ? this->CellSet->GetName() : std::string{}; }
|
||||
|
||||
VTKM_CONT
|
||||
vtkm::Id GetNumberOfCells() const
|
||||
{
|
||||
|
@ -20,36 +20,16 @@ VTKM_CONT
|
||||
Field::Field(std::string name, Association association, const vtkm::cont::VariantArrayHandle& data)
|
||||
: Name(name)
|
||||
, FieldAssociation(association)
|
||||
, AssocCellSetName()
|
||||
, Data(data)
|
||||
, Range()
|
||||
, ModifiedFlag(true)
|
||||
{
|
||||
VTKM_ASSERT(this->FieldAssociation == Association::WHOLE_MESH ||
|
||||
this->FieldAssociation == Association::POINTS);
|
||||
}
|
||||
|
||||
/// constructors for cell set associations
|
||||
VTKM_CONT
|
||||
Field::Field(std::string name,
|
||||
Association association,
|
||||
const std::string& cellSetName,
|
||||
const vtkm::cont::VariantArrayHandle& data)
|
||||
: Name(name)
|
||||
, FieldAssociation(association)
|
||||
, AssocCellSetName(cellSetName)
|
||||
, Data(data)
|
||||
, Range()
|
||||
, ModifiedFlag(true)
|
||||
{
|
||||
VTKM_ASSERT(this->FieldAssociation == Association::CELL_SET);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
Field::Field(const vtkm::cont::Field& src)
|
||||
: Name(src.Name)
|
||||
, FieldAssociation(src.FieldAssociation)
|
||||
, AssocCellSetName(src.AssocCellSetName)
|
||||
, Data(src.Data)
|
||||
, Range(src.Range)
|
||||
, ModifiedFlag(src.ModifiedFlag)
|
||||
@ -59,7 +39,6 @@ Field::Field(const vtkm::cont::Field& src)
|
||||
VTKM_CONT
|
||||
Field::Field(vtkm::cont::Field&& src) noexcept : Name(std::move(src.Name)),
|
||||
FieldAssociation(std::move(src.FieldAssociation)),
|
||||
AssocCellSetName(std::move(src.AssocCellSetName)),
|
||||
Data(std::move(src.Data)),
|
||||
Range(std::move(src.Range)),
|
||||
ModifiedFlag(std::move(src.ModifiedFlag))
|
||||
@ -71,7 +50,6 @@ Field& Field::operator=(const vtkm::cont::Field& src)
|
||||
{
|
||||
this->Name = src.Name;
|
||||
this->FieldAssociation = src.FieldAssociation;
|
||||
this->AssocCellSetName = src.AssocCellSetName;
|
||||
this->Data = src.Data;
|
||||
this->Range = src.Range;
|
||||
this->ModifiedFlag = src.ModifiedFlag;
|
||||
@ -83,7 +61,6 @@ Field& Field::operator=(vtkm::cont::Field&& src) noexcept
|
||||
{
|
||||
this->Name = std::move(src.Name);
|
||||
this->FieldAssociation = std::move(src.FieldAssociation);
|
||||
this->AssocCellSetName = std::move(src.AssocCellSetName);
|
||||
this->Data = std::move(src.Data);
|
||||
this->Range = std::move(src.Range);
|
||||
this->ModifiedFlag = std::move(src.ModifiedFlag);
|
||||
|
@ -58,7 +58,6 @@ public:
|
||||
VTKM_CONT
|
||||
Field() = default;
|
||||
|
||||
/// constructors for points / whole mesh
|
||||
VTKM_CONT
|
||||
Field(std::string name, Association association, const vtkm::cont::VariantArrayHandle& data);
|
||||
|
||||
@ -70,22 +69,6 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
/// constructors for cell set associations
|
||||
VTKM_CONT
|
||||
Field(std::string name,
|
||||
Association association,
|
||||
const std::string& cellSetName,
|
||||
const vtkm::cont::VariantArrayHandle& data);
|
||||
|
||||
template <typename T, typename Storage>
|
||||
VTKM_CONT Field(std::string name,
|
||||
Association association,
|
||||
const std::string& cellSetName,
|
||||
const vtkm::cont::ArrayHandle<T, Storage>& data)
|
||||
: Field(name, association, cellSetName, vtkm::cont::VariantArrayHandle{ data })
|
||||
{
|
||||
}
|
||||
|
||||
Field(const vtkm::cont::Field& src);
|
||||
Field(vtkm::cont::Field&& src) noexcept;
|
||||
|
||||
@ -96,7 +79,6 @@ public:
|
||||
|
||||
VTKM_CONT const std::string& GetName() const { return this->Name; }
|
||||
VTKM_CONT Association GetAssociation() const { return this->FieldAssociation; }
|
||||
VTKM_CONT std::string GetAssocCellSet() const { return this->AssocCellSetName; }
|
||||
const vtkm::cont::VariantArrayHandle& GetData() const;
|
||||
vtkm::cont::VariantArrayHandle& GetData();
|
||||
|
||||
@ -161,8 +143,6 @@ private:
|
||||
std::string Name; ///< name of field
|
||||
|
||||
Association FieldAssociation = Association::ANY;
|
||||
std::string AssocCellSetName; ///< only populate if assoc is cells
|
||||
|
||||
vtkm::cont::VariantArrayHandle Data;
|
||||
mutable vtkm::cont::ArrayHandle<vtkm::Range> Range;
|
||||
mutable bool ModifiedFlag = true;
|
||||
@ -211,50 +191,8 @@ vtkm::cont::Field make_Field(std::string name,
|
||||
return vtkm::cont::Field(name, association, vtkm::cont::make_ArrayHandle(data, copy));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
vtkm::cont::Field make_Field(std::string name,
|
||||
Field::Association association,
|
||||
const std::string& cellSetName,
|
||||
const T* data,
|
||||
vtkm::Id size,
|
||||
vtkm::CopyFlag copy = vtkm::CopyFlag::Off)
|
||||
{
|
||||
return vtkm::cont::Field(
|
||||
name, association, cellSetName, vtkm::cont::make_ArrayHandle(data, size, copy));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
vtkm::cont::Field make_Field(std::string name,
|
||||
Field::Association association,
|
||||
const std::string& cellSetName,
|
||||
const std::vector<T>& data,
|
||||
vtkm::CopyFlag copy = vtkm::CopyFlag::Off)
|
||||
{
|
||||
return vtkm::cont::Field(
|
||||
name, association, cellSetName, vtkm::cont::make_ArrayHandle(data, copy));
|
||||
}
|
||||
|
||||
//@}
|
||||
|
||||
/// Convenience functions to build a point or cell field from vtkm::cont::ArrayHandle
|
||||
/// If \c association is CELL_SET it will
|
||||
template <typename T, typename S>
|
||||
vtkm::cont::Field make_Field(std::string name,
|
||||
Field::Association association,
|
||||
const std::string& cellSetName,
|
||||
const vtkm::cont::ArrayHandle<T, S>& data)
|
||||
{
|
||||
if (association == Field::Association::CELL_SET)
|
||||
{
|
||||
return vtkm::cont::Field(name, association, cellSetName, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
return vtkm::cont::Field(name, association, data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Convenience function to build point fields from vtkm::cont::ArrayHandle
|
||||
template <typename T, typename S>
|
||||
vtkm::cont::Field make_FieldPoint(std::string name, const vtkm::cont::ArrayHandle<T, S>& data)
|
||||
@ -271,20 +209,17 @@ inline vtkm::cont::Field make_FieldPoint(std::string name,
|
||||
|
||||
/// Convenience function to build cell fields from vtkm::cont::ArrayHandle
|
||||
template <typename T, typename S>
|
||||
vtkm::cont::Field make_FieldCell(std::string name,
|
||||
const std::string& cellSetName,
|
||||
const vtkm::cont::ArrayHandle<T, S>& data)
|
||||
vtkm::cont::Field make_FieldCell(std::string name, const vtkm::cont::ArrayHandle<T, S>& data)
|
||||
{
|
||||
return vtkm::cont::Field(name, vtkm::cont::Field::Association::CELL_SET, cellSetName, data);
|
||||
return vtkm::cont::Field(name, vtkm::cont::Field::Association::CELL_SET, data);
|
||||
}
|
||||
|
||||
|
||||
/// Convenience function to build cell fields from vtkm::cont::VariantArrayHandle
|
||||
inline vtkm::cont::Field make_FieldCell(std::string name,
|
||||
const std::string& cellSetName,
|
||||
const vtkm::cont::VariantArrayHandle& data)
|
||||
{
|
||||
return vtkm::cont::Field(name, vtkm::cont::Field::Association::CELL_SET, cellSetName, data);
|
||||
return vtkm::cont::Field(name, vtkm::cont::Field::Association::CELL_SET, data);
|
||||
}
|
||||
|
||||
} // namespace cont
|
||||
@ -343,10 +278,6 @@ public:
|
||||
|
||||
vtkmdiy::save(bb, field.GetName());
|
||||
vtkmdiy::save(bb, static_cast<int>(field.GetAssociation()));
|
||||
if (field.GetAssociation() == vtkm::cont::Field::Association::CELL_SET)
|
||||
{
|
||||
vtkmdiy::save(bb, field.GetAssocCellSet());
|
||||
}
|
||||
vtkmdiy::save(bb, field.GetData().ResetTypes(TypeList{}));
|
||||
}
|
||||
|
||||
@ -361,19 +292,8 @@ public:
|
||||
|
||||
auto assoc = static_cast<vtkm::cont::Field::Association>(assocVal);
|
||||
vtkm::cont::VariantArrayHandleBase<TypeList> data;
|
||||
if (assoc == vtkm::cont::Field::Association::CELL_SET)
|
||||
{
|
||||
std::string assocCellSetName;
|
||||
vtkmdiy::load(bb, assocCellSetName);
|
||||
vtkmdiy::load(bb, data);
|
||||
field =
|
||||
vtkm::cont::Field(name, assoc, assocCellSetName, vtkm::cont::VariantArrayHandle(data));
|
||||
}
|
||||
else
|
||||
{
|
||||
vtkmdiy::load(bb, data);
|
||||
field = vtkm::cont::Field(name, assoc, vtkm::cont::VariantArrayHandle(data));
|
||||
}
|
||||
vtkmdiy::load(bb, data);
|
||||
field = vtkm::cont::Field(name, assoc, vtkm::cont::VariantArrayHandle(data));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -29,12 +29,11 @@ vtkm::cont::ArrayHandle<vtkm::Range> FieldRangeCompute(const vtkm::cont::DataSet
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
VTKM_CONT
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> FieldRangeCompute(const vtkm::cont::MultiBlock& multiblock,
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> FieldRangeCompute(const vtkm::cont::PartitionedDataSet& pds,
|
||||
const std::string& name,
|
||||
vtkm::cont::Field::Association assoc)
|
||||
{
|
||||
return vtkm::cont::detail::FieldRangeComputeImpl(
|
||||
multiblock, name, assoc, VTKM_DEFAULT_TYPE_LIST_TAG());
|
||||
return vtkm::cont::detail::FieldRangeComputeImpl(pds, name, assoc, VTKM_DEFAULT_TYPE_LIST_TAG());
|
||||
}
|
||||
}
|
||||
} // namespace vtkm::cont
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
#include <vtkm/cont/DataSet.h>
|
||||
#include <vtkm/cont/Field.h>
|
||||
#include <vtkm/cont/MultiBlock.h>
|
||||
#include <vtkm/cont/PartitionedDataSet.h>
|
||||
|
||||
#include <vtkm/cont/FieldRangeCompute.hxx>
|
||||
|
||||
@ -20,9 +20,10 @@ namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
/// \brief Compute ranges for fields in a DataSet or MultiBlock.
|
||||
/// \brief Compute ranges for fields in a DataSet or PartitionedDataSet.
|
||||
///
|
||||
/// These methods to compute ranges for fields in a dataset or a multiblock.
|
||||
/// These methods to compute ranges for fields in a single dataset or a
|
||||
/// partitioned dataset.
|
||||
/// When using VTK-m in a hybrid-parallel environment with distributed processing,
|
||||
/// this class uses ranges for locally available data alone. Use FieldRangeGlobalCompute
|
||||
/// to compute ranges globally across all ranks even in distributed mode.
|
||||
@ -51,28 +52,30 @@ VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> FieldRangeCompute(
|
||||
//@}
|
||||
|
||||
//{@
|
||||
/// Returns the range for a field from a multiblock. If the field is not present on any
|
||||
/// of the blocks, an empty ArrayHandle will be returned. If the field is present on some blocks,
|
||||
/// but not all, those blocks without the field are skipped.
|
||||
/// Returns the range for a field from a PartitionedDataSet. If the field is
|
||||
/// not present on any of the partitions, an empty ArrayHandle will be
|
||||
/// returned. If the field is present on some partitions, but not all, those
|
||||
/// partitions without the field are skipped.
|
||||
///
|
||||
/// The returned array handle will have as many values as the maximum number of
|
||||
/// components for the selected field across all partitions.
|
||||
///
|
||||
/// The returned array handle will have as many values as the maximum number of components for
|
||||
/// the selected field across all blocks.
|
||||
VTKM_CONT_EXPORT
|
||||
VTKM_CONT
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> FieldRangeCompute(
|
||||
const vtkm::cont::MultiBlock& multiblock,
|
||||
const vtkm::cont::PartitionedDataSet& pds,
|
||||
const std::string& name,
|
||||
vtkm::cont::Field::Association assoc = vtkm::cont::Field::Association::ANY);
|
||||
|
||||
template <typename TypeList>
|
||||
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> FieldRangeCompute(
|
||||
const vtkm::cont::MultiBlock& multiblock,
|
||||
const vtkm::cont::PartitionedDataSet& pds,
|
||||
const std::string& name,
|
||||
vtkm::cont::Field::Association assoc,
|
||||
TypeList)
|
||||
{
|
||||
VTKM_IS_LIST_TAG(TypeList);
|
||||
return vtkm::cont::detail::FieldRangeComputeImpl(multiblock, name, assoc, TypeList());
|
||||
return vtkm::cont::detail::FieldRangeComputeImpl(pds, name, assoc, TypeList());
|
||||
}
|
||||
|
||||
//@}
|
||||
|
@ -10,6 +10,12 @@
|
||||
#ifndef vtk_m_cont_FieldRangeCompute_hxx
|
||||
#define vtk_m_cont_FieldRangeCompute_hxx
|
||||
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
#include <vtkm/cont/DataSet.h>
|
||||
#include <vtkm/cont/PartitionedDataSet.h>
|
||||
|
||||
#include <vtkm/Range.h>
|
||||
|
||||
#include <numeric> // for std::accumulate
|
||||
|
||||
namespace vtkm
|
||||
@ -42,26 +48,27 @@ VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> FieldRangeComputeImpl(
|
||||
|
||||
template <typename TypeList>
|
||||
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> FieldRangeComputeImpl(
|
||||
const vtkm::cont::MultiBlock& multiblock,
|
||||
const vtkm::cont::PartitionedDataSet& pds,
|
||||
const std::string& name,
|
||||
vtkm::cont::Field::Association assoc,
|
||||
TypeList)
|
||||
{
|
||||
std::vector<vtkm::Range> result_vector = std::accumulate(
|
||||
multiblock.begin(),
|
||||
multiblock.end(),
|
||||
pds.begin(),
|
||||
pds.end(),
|
||||
std::vector<vtkm::Range>(),
|
||||
[&](const std::vector<vtkm::Range>& accumulated_value, const vtkm::cont::DataSet& dataset) {
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> block_range =
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> partition_range =
|
||||
vtkm::cont::detail::FieldRangeComputeImpl(dataset, name, assoc, TypeList());
|
||||
|
||||
std::vector<vtkm::Range> result = accumulated_value;
|
||||
|
||||
// if the current block has more components than we have seen so far,
|
||||
// if the current partition has more components than we have seen so far,
|
||||
// resize the result to fit all components.
|
||||
result.resize(std::max(result.size(), static_cast<size_t>(block_range.GetNumberOfValues())));
|
||||
result.resize(
|
||||
std::max(result.size(), static_cast<size_t>(partition_range.GetNumberOfValues())));
|
||||
|
||||
auto portal = block_range.GetPortalConstControl();
|
||||
auto portal = partition_range.GetPortalConstControl();
|
||||
std::transform(vtkm::cont::ArrayPortalToIteratorBegin(portal),
|
||||
vtkm::cont::ArrayPortalToIteratorEnd(portal),
|
||||
result.begin(),
|
||||
|
@ -33,11 +33,11 @@ vtkm::cont::ArrayHandle<vtkm::Range> FieldRangeGlobalCompute(const vtkm::cont::D
|
||||
//-----------------------------------------------------------------------------
|
||||
VTKM_CONT
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> FieldRangeGlobalCompute(
|
||||
const vtkm::cont::MultiBlock& multiblock,
|
||||
const vtkm::cont::PartitionedDataSet& pds,
|
||||
const std::string& name,
|
||||
vtkm::cont::Field::Association assoc)
|
||||
{
|
||||
return detail::FieldRangeGlobalComputeImpl(multiblock, name, assoc, VTKM_DEFAULT_TYPE_LIST_TAG());
|
||||
return detail::FieldRangeGlobalComputeImpl(pds, name, assoc, VTKM_DEFAULT_TYPE_LIST_TAG());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -20,7 +20,8 @@ namespace cont
|
||||
{
|
||||
/// \brief utility functions to compute global ranges for dataset fields.
|
||||
///
|
||||
/// These functions compute global ranges for fields in a dataset or a multiblock.
|
||||
/// These functions compute global ranges for fields in a single DataSet or a
|
||||
/// PartitionedDataSet.
|
||||
/// In non-distributed environments, this is exactly same as `FieldRangeCompute`. In
|
||||
/// distributed environments, however, the range is computed locally on each rank
|
||||
/// and then a reduce-all collective is performed to reduces the ranges on all ranks.
|
||||
@ -49,28 +50,29 @@ VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> FieldRangeGlobalCompute(
|
||||
//@}
|
||||
|
||||
//{@
|
||||
/// Returns the range for a field from a multiblock. If the field is not present on any
|
||||
/// of the blocks, an empty ArrayHandle will be returned. If the field is present on some blocks,
|
||||
/// but not all, those blocks without the field are skipped.
|
||||
/// Returns the range for a field from a PartitionedDataSet. If the field is
|
||||
/// not present on any of the partitions, an empty ArrayHandle will be
|
||||
/// returned. If the field is present on some partitions, but not all, those
|
||||
/// partitions without the field are skipped.
|
||||
///
|
||||
/// The returned array handle will have as many values as the maximum number of components for
|
||||
/// the selected field across all blocks.
|
||||
/// The returned array handle will have as many values as the maximum number of
|
||||
/// components for the selected field across all partitions.
|
||||
VTKM_CONT_EXPORT
|
||||
VTKM_CONT
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> FieldRangeGlobalCompute(
|
||||
const vtkm::cont::MultiBlock& multiblock,
|
||||
const vtkm::cont::PartitionedDataSet& pds,
|
||||
const std::string& name,
|
||||
vtkm::cont::Field::Association assoc = vtkm::cont::Field::Association::ANY);
|
||||
|
||||
template <typename TypeList>
|
||||
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> FieldRangeGlobalCompute(
|
||||
const vtkm::cont::MultiBlock& multiblock,
|
||||
const vtkm::cont::PartitionedDataSet& pds,
|
||||
const std::string& name,
|
||||
vtkm::cont::Field::Association assoc,
|
||||
TypeList)
|
||||
{
|
||||
VTKM_IS_LIST_TAG(TypeList);
|
||||
return detail::FieldRangeGlobalComputeImpl(multiblock, name, assoc, TypeList());
|
||||
return detail::FieldRangeGlobalComputeImpl(pds, name, assoc, TypeList());
|
||||
}
|
||||
//@}
|
||||
}
|
||||
|
@ -35,12 +35,12 @@ VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> FieldRangeGlobalComputeImpl(
|
||||
|
||||
template <typename TypeList>
|
||||
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> FieldRangeGlobalComputeImpl(
|
||||
const vtkm::cont::MultiBlock& multiblock,
|
||||
const vtkm::cont::PartitionedDataSet& pds,
|
||||
const std::string& name,
|
||||
vtkm::cont::Field::Association assoc,
|
||||
TypeList)
|
||||
{
|
||||
auto lrange = vtkm::cont::FieldRangeCompute(multiblock, name, assoc, TypeList());
|
||||
auto lrange = vtkm::cont::FieldRangeCompute(pds, name, assoc, TypeList());
|
||||
return vtkm::cont::detail::MergeRangesGlobal(lrange);
|
||||
}
|
||||
}
|
||||
|
@ -431,6 +431,7 @@ VTKM_CONT_EXPORT
|
||||
VTKM_CONT
|
||||
std::string GetStackTrace(vtkm::Int32 skip = 0);
|
||||
|
||||
//@{
|
||||
/// Convert a size in bytes to a human readable string (e.g. "64 bytes",
|
||||
/// "1.44 MiB", "128 GiB", etc). @a prec controls the fixed point precision
|
||||
/// of the stringified number.
|
||||
@ -438,12 +439,27 @@ VTKM_CONT_EXPORT
|
||||
VTKM_CONT
|
||||
std::string GetHumanReadableSize(vtkm::UInt64 bytes, int prec = 2);
|
||||
|
||||
template <typename T>
|
||||
VTKM_CONT inline std::string GetHumanReadableSize(T&& bytes, int prec = 2)
|
||||
{
|
||||
return GetHumanReadableSize(static_cast<vtkm::UInt64>(std::forward<T>(bytes)), prec);
|
||||
}
|
||||
//@}
|
||||
|
||||
//@{
|
||||
/// Returns "%1 (%2 bytes)" where %1 is the result from GetHumanReadableSize
|
||||
/// and two is the exact number of bytes.
|
||||
VTKM_CONT_EXPORT
|
||||
VTKM_CONT
|
||||
std::string GetSizeString(vtkm::UInt64 bytes, int prec = 2);
|
||||
|
||||
template <typename T>
|
||||
VTKM_CONT inline std::string GetSizeString(T&& bytes, int prec = 2)
|
||||
{
|
||||
return GetSizeString(static_cast<vtkm::UInt64>(std::forward<T>(bytes)), prec);
|
||||
}
|
||||
//@}
|
||||
|
||||
/**
|
||||
* Use RTTI information to retrieve the name of the type T. If logging is
|
||||
* enabled and the platform supports it, the type name will also be demangled.
|
||||
|
@ -1,143 +0,0 @@
|
||||
//============================================================================
|
||||
// Copyright (c) Kitware, Inc.
|
||||
// All rights reserved.
|
||||
// See LICENSE.txt for details.
|
||||
//
|
||||
// This software is distributed WITHOUT ANY WARRANTY; without even
|
||||
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the above copyright notice for more information.
|
||||
//============================================================================
|
||||
|
||||
#include <vtkm/StaticAssert.h>
|
||||
#include <vtkm/cont/ArrayCopy.h>
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
#include <vtkm/cont/DataSet.h>
|
||||
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
|
||||
#include <vtkm/cont/EnvironmentTracker.h>
|
||||
#include <vtkm/cont/ErrorExecution.h>
|
||||
#include <vtkm/cont/Field.h>
|
||||
#include <vtkm/cont/MultiBlock.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
|
||||
VTKM_CONT
|
||||
MultiBlock::MultiBlock(const vtkm::cont::DataSet& ds)
|
||||
{
|
||||
this->Blocks.insert(this->Blocks.end(), ds);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
MultiBlock::MultiBlock(const vtkm::cont::MultiBlock& src)
|
||||
{
|
||||
this->Blocks = src.GetBlocks();
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
MultiBlock::MultiBlock(const std::vector<vtkm::cont::DataSet>& mblocks)
|
||||
{
|
||||
this->Blocks = mblocks;
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
MultiBlock::MultiBlock(vtkm::Id size)
|
||||
{
|
||||
this->Blocks.reserve(static_cast<std::size_t>(size));
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
MultiBlock::MultiBlock()
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
MultiBlock::~MultiBlock()
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
MultiBlock& MultiBlock::operator=(const vtkm::cont::MultiBlock& src)
|
||||
{
|
||||
this->Blocks = src.GetBlocks();
|
||||
return *this;
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
vtkm::cont::Field MultiBlock::GetField(const std::string& field_name, const int& block_index)
|
||||
{
|
||||
assert(block_index >= 0);
|
||||
assert(static_cast<std::size_t>(block_index) < this->Blocks.size());
|
||||
return this->Blocks[static_cast<std::size_t>(block_index)].GetField(field_name);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
vtkm::Id MultiBlock::GetNumberOfBlocks() const
|
||||
{
|
||||
return static_cast<vtkm::Id>(this->Blocks.size());
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
const vtkm::cont::DataSet& MultiBlock::GetBlock(vtkm::Id blockId) const
|
||||
{
|
||||
return this->Blocks[static_cast<std::size_t>(blockId)];
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
const std::vector<vtkm::cont::DataSet>& MultiBlock::GetBlocks() const
|
||||
{
|
||||
return this->Blocks;
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
void MultiBlock::AddBlock(const vtkm::cont::DataSet& ds)
|
||||
{
|
||||
this->Blocks.insert(this->Blocks.end(), ds);
|
||||
return;
|
||||
}
|
||||
|
||||
void MultiBlock::AddBlocks(const std::vector<vtkm::cont::DataSet>& mblocks)
|
||||
{
|
||||
this->Blocks.insert(this->Blocks.end(), mblocks.begin(), mblocks.end());
|
||||
return;
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
void MultiBlock::InsertBlock(vtkm::Id index, const vtkm::cont::DataSet& ds)
|
||||
{
|
||||
if (index <= static_cast<vtkm::Id>(this->Blocks.size()))
|
||||
this->Blocks.insert(this->Blocks.begin() + index, ds);
|
||||
else
|
||||
{
|
||||
std::string msg = "invalid insert position\n ";
|
||||
throw ErrorExecution(msg);
|
||||
}
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
void MultiBlock::ReplaceBlock(vtkm::Id index, const vtkm::cont::DataSet& ds)
|
||||
{
|
||||
if (index < static_cast<vtkm::Id>(this->Blocks.size()))
|
||||
this->Blocks.at(static_cast<std::size_t>(index)) = ds;
|
||||
else
|
||||
{
|
||||
std::string msg = "invalid replace position\n ";
|
||||
throw ErrorExecution(msg);
|
||||
}
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
void MultiBlock::PrintSummary(std::ostream& stream) const
|
||||
{
|
||||
stream << "block "
|
||||
<< "\n";
|
||||
|
||||
for (size_t block_index = 0; block_index < this->Blocks.size(); ++block_index)
|
||||
{
|
||||
stream << "block " << block_index << "\n";
|
||||
this->Blocks[block_index].PrintSummary(stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace vtkm::cont
|
@ -1,92 +0,0 @@
|
||||
//============================================================================
|
||||
// Copyright (c) Kitware, Inc.
|
||||
// All rights reserved.
|
||||
// See LICENSE.txt for details.
|
||||
//
|
||||
// This software is distributed WITHOUT ANY WARRANTY; without even
|
||||
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the above copyright notice for more information.
|
||||
//============================================================================
|
||||
#ifndef vtk_m_cont_MultiBlock_h
|
||||
#define vtk_m_cont_MultiBlock_h
|
||||
#include <limits>
|
||||
#include <vtkm/StaticAssert.h>
|
||||
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
#include <vtkm/cont/DataSet.h>
|
||||
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
|
||||
#include <vtkm/cont/Field.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
|
||||
class VTKM_CONT_EXPORT MultiBlock
|
||||
{
|
||||
public:
|
||||
/// create a new MultiBlock containng a single DataSet "ds"
|
||||
VTKM_CONT
|
||||
MultiBlock(const vtkm::cont::DataSet& ds);
|
||||
/// create a new MultiBlock with the existing one "src"
|
||||
VTKM_CONT
|
||||
MultiBlock(const vtkm::cont::MultiBlock& src);
|
||||
/// create a new MultiBlock with a DataSet vector "mblocks"
|
||||
VTKM_CONT
|
||||
explicit MultiBlock(const std::vector<vtkm::cont::DataSet>& mblocks);
|
||||
/// create a new MultiBlock with the capacity set to be "size"
|
||||
VTKM_CONT
|
||||
explicit MultiBlock(vtkm::Id size);
|
||||
|
||||
VTKM_CONT
|
||||
MultiBlock();
|
||||
|
||||
VTKM_CONT
|
||||
MultiBlock& operator=(const vtkm::cont::MultiBlock& src);
|
||||
|
||||
VTKM_CONT
|
||||
~MultiBlock();
|
||||
/// get the field "field_name" from block "block_index"
|
||||
VTKM_CONT
|
||||
vtkm::cont::Field GetField(const std::string& field_name, const int& block_index);
|
||||
|
||||
VTKM_CONT
|
||||
vtkm::Id GetNumberOfBlocks() const;
|
||||
|
||||
VTKM_CONT
|
||||
const vtkm::cont::DataSet& GetBlock(vtkm::Id blockId) const;
|
||||
|
||||
VTKM_CONT
|
||||
const std::vector<vtkm::cont::DataSet>& GetBlocks() const;
|
||||
/// add DataSet "ds" to the end of the contained DataSet vector
|
||||
VTKM_CONT
|
||||
void AddBlock(const vtkm::cont::DataSet& ds);
|
||||
/// add DataSet "ds" to position "index" of the contained DataSet vector
|
||||
VTKM_CONT
|
||||
void InsertBlock(vtkm::Id index, const vtkm::cont::DataSet& ds);
|
||||
/// replace the "index" positioned element of the contained DataSet vector with "ds"
|
||||
VTKM_CONT
|
||||
void ReplaceBlock(vtkm::Id index, const vtkm::cont::DataSet& ds);
|
||||
/// append the DataSet vector "mblocks" to the end of the contained one
|
||||
VTKM_CONT
|
||||
void AddBlocks(const std::vector<vtkm::cont::DataSet>& mblocks);
|
||||
|
||||
VTKM_CONT
|
||||
void PrintSummary(std::ostream& stream) const;
|
||||
|
||||
//@{
|
||||
/// API to support range-based for loops on blocks.
|
||||
std::vector<DataSet>::iterator begin() noexcept { return this->Blocks.begin(); }
|
||||
std::vector<DataSet>::iterator end() noexcept { return this->Blocks.end(); }
|
||||
std::vector<DataSet>::const_iterator begin() const noexcept { return this->Blocks.begin(); }
|
||||
std::vector<DataSet>::const_iterator end() const noexcept { return this->Blocks.end(); }
|
||||
std::vector<DataSet>::const_iterator cbegin() const noexcept { return this->Blocks.begin(); }
|
||||
std::vector<DataSet>::const_iterator cend() const noexcept { return this->Blocks.end(); }
|
||||
//@}
|
||||
private:
|
||||
std::vector<vtkm::cont::DataSet> Blocks;
|
||||
};
|
||||
}
|
||||
} // namespace vtkm::cont
|
||||
|
||||
#endif
|
143
vtkm/cont/PartitionedDataSet.cxx
Normal file
143
vtkm/cont/PartitionedDataSet.cxx
Normal file
@ -0,0 +1,143 @@
|
||||
//============================================================================
|
||||
// Copyright (c) Kitware, Inc.
|
||||
// All rights reserved.
|
||||
// See LICENSE.txt for details.
|
||||
//
|
||||
// This software is distributed WITHOUT ANY WARRANTY; without even
|
||||
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the above copyright notice for more information.
|
||||
//============================================================================
|
||||
|
||||
#include <vtkm/StaticAssert.h>
|
||||
#include <vtkm/cont/ArrayCopy.h>
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
#include <vtkm/cont/DataSet.h>
|
||||
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
|
||||
#include <vtkm/cont/EnvironmentTracker.h>
|
||||
#include <vtkm/cont/ErrorBadValue.h>
|
||||
#include <vtkm/cont/Field.h>
|
||||
#include <vtkm/cont/PartitionedDataSet.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
|
||||
VTKM_CONT
|
||||
PartitionedDataSet::PartitionedDataSet(const vtkm::cont::DataSet& ds)
|
||||
{
|
||||
this->Partitions.insert(this->Partitions.end(), ds);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
PartitionedDataSet::PartitionedDataSet(const vtkm::cont::PartitionedDataSet& src)
|
||||
{
|
||||
this->Partitions = src.GetPartitions();
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
PartitionedDataSet::PartitionedDataSet(const std::vector<vtkm::cont::DataSet>& partitions)
|
||||
{
|
||||
this->Partitions = partitions;
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
PartitionedDataSet::PartitionedDataSet(vtkm::Id size)
|
||||
{
|
||||
this->Partitions.reserve(static_cast<std::size_t>(size));
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
PartitionedDataSet::PartitionedDataSet()
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
PartitionedDataSet::~PartitionedDataSet()
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
PartitionedDataSet& PartitionedDataSet::operator=(const vtkm::cont::PartitionedDataSet& src)
|
||||
{
|
||||
this->Partitions = src.GetPartitions();
|
||||
return *this;
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
vtkm::cont::Field PartitionedDataSet::GetField(const std::string& field_name, int partition_index)
|
||||
{
|
||||
assert(partition_index >= 0);
|
||||
assert(static_cast<std::size_t>(partition_index) < this->Partitions.size());
|
||||
return this->Partitions[static_cast<std::size_t>(partition_index)].GetField(field_name);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
vtkm::Id PartitionedDataSet::GetNumberOfPartitions() const
|
||||
{
|
||||
return static_cast<vtkm::Id>(this->Partitions.size());
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
const vtkm::cont::DataSet& PartitionedDataSet::GetPartition(vtkm::Id blockId) const
|
||||
{
|
||||
return this->Partitions[static_cast<std::size_t>(blockId)];
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
const std::vector<vtkm::cont::DataSet>& PartitionedDataSet::GetPartitions() const
|
||||
{
|
||||
return this->Partitions;
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
void PartitionedDataSet::AppendPartition(const vtkm::cont::DataSet& ds)
|
||||
{
|
||||
this->Partitions.insert(this->Partitions.end(), ds);
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
void PartitionedDataSet::AppendPartitions(const std::vector<vtkm::cont::DataSet>& partitions)
|
||||
{
|
||||
this->Partitions.insert(this->Partitions.end(), partitions.begin(), partitions.end());
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
void PartitionedDataSet::InsertPartition(vtkm::Id index, const vtkm::cont::DataSet& ds)
|
||||
{
|
||||
if (index <= static_cast<vtkm::Id>(this->Partitions.size()))
|
||||
{
|
||||
this->Partitions.insert(this->Partitions.begin() + index, ds);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string msg = "invalid insert position\n ";
|
||||
throw ErrorBadValue(msg);
|
||||
}
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
void PartitionedDataSet::ReplacePartition(vtkm::Id index, const vtkm::cont::DataSet& ds)
|
||||
{
|
||||
if (index < static_cast<vtkm::Id>(this->Partitions.size()))
|
||||
this->Partitions.at(static_cast<std::size_t>(index)) = ds;
|
||||
else
|
||||
{
|
||||
std::string msg = "invalid replace position\n ";
|
||||
throw ErrorBadValue(msg);
|
||||
}
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
void PartitionedDataSet::PrintSummary(std::ostream& stream) const
|
||||
{
|
||||
stream << "PartitionedDataSet [" << this->Partitions.size() << " partitions]:\n";
|
||||
|
||||
for (size_t part = 0; part < this->Partitions.size(); ++part)
|
||||
{
|
||||
stream << "Partition " << part << ":\n";
|
||||
this->Partitions[part].PrintSummary(stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace vtkm::cont
|
111
vtkm/cont/PartitionedDataSet.h
Normal file
111
vtkm/cont/PartitionedDataSet.h
Normal file
@ -0,0 +1,111 @@
|
||||
//============================================================================
|
||||
// Copyright (c) Kitware, Inc.
|
||||
// All rights reserved.
|
||||
// See LICENSE.txt for details.
|
||||
//
|
||||
// This software is distributed WITHOUT ANY WARRANTY; without even
|
||||
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the above copyright notice for more information.
|
||||
//============================================================================
|
||||
#ifndef vtk_m_cont_PartitionedDataSet_h
|
||||
#define vtk_m_cont_PartitionedDataSet_h
|
||||
#include <limits>
|
||||
#include <vtkm/StaticAssert.h>
|
||||
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
#include <vtkm/cont/DataSet.h>
|
||||
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
|
||||
#include <vtkm/cont/Field.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
|
||||
class VTKM_CONT_EXPORT PartitionedDataSet
|
||||
{
|
||||
using StorageVec = std::vector<vtkm::cont::DataSet>;
|
||||
|
||||
public:
|
||||
using iterator = typename StorageVec::iterator;
|
||||
using const_iterator = typename StorageVec::const_iterator;
|
||||
using value_type = typename StorageVec::value_type;
|
||||
using reference = typename StorageVec::reference;
|
||||
using const_reference = typename StorageVec::const_reference;
|
||||
|
||||
/// create a new PartitionedDataSet containng a single DataSet @a ds
|
||||
VTKM_CONT
|
||||
PartitionedDataSet(const vtkm::cont::DataSet& ds);
|
||||
/// create a new PartitionedDataSet with the existing one @a src
|
||||
VTKM_CONT
|
||||
PartitionedDataSet(const vtkm::cont::PartitionedDataSet& src);
|
||||
/// create a new PartitionedDataSet with a DataSet vector @a partitions.
|
||||
VTKM_CONT
|
||||
explicit PartitionedDataSet(const std::vector<vtkm::cont::DataSet>& partitions);
|
||||
/// create a new PartitionedDataSet with the capacity set to be @a size
|
||||
VTKM_CONT
|
||||
explicit PartitionedDataSet(vtkm::Id size);
|
||||
|
||||
VTKM_CONT
|
||||
PartitionedDataSet();
|
||||
|
||||
VTKM_CONT
|
||||
PartitionedDataSet& operator=(const vtkm::cont::PartitionedDataSet& src);
|
||||
|
||||
VTKM_CONT
|
||||
~PartitionedDataSet();
|
||||
/// get the field @a field_name from partition @a partition_index
|
||||
VTKM_CONT
|
||||
vtkm::cont::Field GetField(const std::string& field_name, int partition_index);
|
||||
|
||||
VTKM_CONT
|
||||
vtkm::Id GetNumberOfPartitions() const;
|
||||
|
||||
VTKM_CONT
|
||||
const vtkm::cont::DataSet& GetPartition(vtkm::Id partId) const;
|
||||
|
||||
VTKM_CONT
|
||||
const std::vector<vtkm::cont::DataSet>& GetPartitions() const;
|
||||
|
||||
/// add DataSet @a ds to the end of the contained DataSet vector
|
||||
VTKM_CONT
|
||||
void AppendPartition(const vtkm::cont::DataSet& ds);
|
||||
|
||||
/// add DataSet @a ds to position @a index of the contained DataSet vector
|
||||
VTKM_CONT
|
||||
void InsertPartition(vtkm::Id index, const vtkm::cont::DataSet& ds);
|
||||
|
||||
/// replace the @a index positioned element of the contained DataSet vector
|
||||
/// with @a ds
|
||||
VTKM_CONT
|
||||
void ReplacePartition(vtkm::Id index, const vtkm::cont::DataSet& ds);
|
||||
|
||||
/// append the DataSet vector "partitions" to the end of the contained one
|
||||
VTKM_CONT
|
||||
void AppendPartitions(const std::vector<vtkm::cont::DataSet>& partitions);
|
||||
|
||||
VTKM_CONT
|
||||
void PrintSummary(std::ostream& stream) const;
|
||||
|
||||
//@{
|
||||
/// API to support range-based for loops on partitions.
|
||||
VTKM_CONT
|
||||
iterator begin() noexcept { return this->Partitions.begin(); }
|
||||
VTKM_CONT
|
||||
iterator end() noexcept { return this->Partitions.end(); }
|
||||
VTKM_CONT
|
||||
const_iterator begin() const noexcept { return this->Partitions.begin(); }
|
||||
VTKM_CONT
|
||||
const_iterator end() const noexcept { return this->Partitions.end(); }
|
||||
VTKM_CONT
|
||||
const_iterator cbegin() const noexcept { return this->Partitions.cbegin(); }
|
||||
VTKM_CONT
|
||||
const_iterator cend() const noexcept { return this->Partitions.cend(); }
|
||||
//@}
|
||||
private:
|
||||
std::vector<vtkm::cont::DataSet> Partitions;
|
||||
};
|
||||
}
|
||||
} // namespace vtkm::cont
|
||||
|
||||
#endif
|
@ -169,6 +169,17 @@ void RuntimeDeviceTracker::ForceDevice(DeviceAdapterId deviceId)
|
||||
}
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
void RuntimeDeviceTracker::PrintSummary(std::ostream& out) const
|
||||
{
|
||||
for (vtkm::Int8 i = 1; i < VTKM_MAX_DEVICE_ADAPTER_ID; ++i)
|
||||
{
|
||||
auto dev = vtkm::cont::make_DeviceAdapterId(i);
|
||||
out << " - Device " << static_cast<vtkm::Int32>(i) << " (" << dev.GetName()
|
||||
<< "): Enabled=" << this->CanRunOn(dev) << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
ScopedRuntimeDeviceTracker::ScopedRuntimeDeviceTracker(vtkm::cont::DeviceAdapterId device,
|
||||
RuntimeDeviceTrackerMode mode)
|
||||
|
@ -110,6 +110,8 @@ public:
|
||||
///
|
||||
VTKM_CONT void ForceDevice(DeviceAdapterId deviceId);
|
||||
|
||||
VTKM_CONT void PrintSummary(std::ostream& out) const;
|
||||
|
||||
private:
|
||||
friend struct ScopedRuntimeDeviceTracker;
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
#include <vtkm/internal/IndicesExtrude.h>
|
||||
|
||||
#include <vtkm/BaseComponent.h>
|
||||
#include <vtkm/VecTraits.h>
|
||||
|
||||
#include <vtkm/cont/ErrorBadType.h>
|
||||
|
||||
@ -371,7 +371,7 @@ struct VTKM_ALWAYS_EXPORT StorageTagExtrude
|
||||
template <typename T>
|
||||
class Storage<T, internal::StorageTagExtrude>
|
||||
{
|
||||
using BaseT = typename BaseComponent<T>::Type;
|
||||
using BaseT = typename VecTraits<T>::BaseComponentType;
|
||||
using HandleType = vtkm::cont::ArrayHandle<BaseT>;
|
||||
using TPortalType = typename HandleType::PortalConstControl;
|
||||
|
||||
@ -461,7 +461,7 @@ private:
|
||||
template <typename T, typename Device>
|
||||
class VTKM_ALWAYS_EXPORT ArrayTransfer<T, internal::StorageTagExtrude, Device>
|
||||
{
|
||||
using BaseT = typename BaseComponent<T>::Type;
|
||||
using BaseT = typename VecTraits<T>::BaseComponentType;
|
||||
using TPortalType = decltype(vtkm::cont::ArrayHandle<BaseT>{}.PrepareForInput(Device{}));
|
||||
|
||||
public:
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user