Commit 1cc543d2 authored by David Thompson's avatar David Thompson
Browse files

Modernize sensei's VTKm support.

+ Do not require a modern VTKm when analyses (such as VTKmContourAnalysis)
  use the vtkAcceleratorsVtkm library in VTK rather than VTKm directly.
+ Make usage of vtkAcceleratorsVtkm a build option (ENABLE_VTK_ACCELERATORS).
+ Add a direct VTKm analysis adaptor: VTKmVolumeReductionAnalysis, which
  performs a Haar wavelet transform and keeps only the low-frequency
  component in order to reduce image-data down to a manageable size.
+ Require a modern VTKm for direct VTKm analysis adaptors.
  Make direct usage of VTK-m a build option (ENABLE_VTKM).
+ Be explicit about installing header files. Using globbing is discouraged
  as it slows CMake down and can produce counterintuitive results.
+ Add a CinemaHelper class used by the VTKmVolumeReductionAnalysis to
  write out data for post-hoc visualization using cinema/arctic-viewer.
parent af6c26b6
......@@ -33,9 +33,13 @@ set(ENABLE_LIBSIM @ENABLE_LIBSIM@)
set(ENABLE_ADIOS @ENABLE_ADIOS@)
set(ENABLE_CONDUIT @ENABLE_CONDUIT@)
set(ENABLE_VTK_GENERIC_ARRAYS @ENABLE_VTK_GENERIC_ARRAYS@)
set(ENABLE_VTK_ACCELERATORS @ENABLE_VTK_ACCELERATORS@)
set(ENABLE_VTK_MPI @ENABLE_VTK_MPI@)
set(ENABLE_VTK_IO @ENABLE_VTK_IO@)
set(ENABLE_VTKM @ENABLE_VTKM@)
set(ENABLE_VTKM_RENDERING @ENABLE_VTKM_RENDERING@)
if (NOT CMAKE_CXX_FLAGS)
set(CMAKE_CXX_FLAGS "@CMAKE_CXX_FLAGS@"
CACHE STRING "sensei build defaults"
......@@ -63,6 +67,9 @@ include(ArrayIO)
include(timer)
include(diy)
include(grid)
if(ENABLE_VTKM)
include(vtkm)
endif()
if(ENABLE_LIBSIM)
include(libsim)
endif()
......
......@@ -36,9 +36,25 @@ cmake_dependent_option(ENABLE_VTK_MPI
"Enable use of parallel vtk" OFF
"ENABLE_SENSEI" OFF)
cmake_dependent_option(ENABLE_VTK_M
cmake_dependent_option(ENABLE_VTK_ACCELERATORS
"Enable analysis methods that use VTK-m via VTK's Accelerators module" OFF
"ENABLE_SENSEI" OFF)
# Build with vtk-m support
# If ENABLE_VTKM is ON, then linking your library/executable to vtkm_cont
# will add include-directories and preprocessor definitions required by vtk-m.
# The sensei library will transitively link to vtkm_cont.
cmake_dependent_option(ENABLE_VTKM
"Enable analysis methods that use VTK-m" OFF
"ENABLE_VTK_MPI" OFF)
"ENABLE_SENSEI" OFF)
# If ENABLE_VTKM_RENDERING is ON, then linking your library/executable to
# vtkm_rendering will add include-directories and preprocessor definitions
# required by vtk-m.
# The sensei library will transitively link to vtkm_rendering.
cmake_dependent_option(ENABLE_VTKM_RENDERING
"Enable analysis methods that use VTK-m's rendering library" OFF
"ENABLE_VTKM" OFF)
option(ENABLE_PARALLEL3D "Enable Parallel3D miniapp" ON)
......@@ -55,6 +71,9 @@ message(STATUS "ENABLE_CONDUIT=${ENABLE_CONDUIT}")
message(STATUS "ENABLE_LIBSIM=${ENABLE_LIBSIM}")
message(STATUS "ENABLE_VTK_IO=${ENABLE_VTK_IO}")
message(STATUS "ENABLE_VTK_MPI=${ENABLE_VTK_MPI}")
message(STATUS "ENABLE_VTK_ACCELERATORS=${ENABLE_VTK_ACCELERATORS}")
message(STATUS "ENABLE_VTKM=${ENABLE_VTKM}")
message(STATUS "ENABLE_VTKM_RENDERING=${ENABLE_VTKM_RENDERING}")
message(STATUS "ENABLE_PARALLEL3D=${ENABLE_PARALLEL3D}")
message(STATUS "ENABLE_OSCILLATORS=${ENABLE_OSCILLATORS}")
message(STATUS "ENABLE_CONDUITTEST=${ENABLE_CONDUITTEST}")
......@@ -11,16 +11,9 @@ endif()
if (ENABLE_PYTHON)
list(APPEND SENSEI_VTK_COMPONENTS vtkPython vtkWrappingPythonCore)
endif()
if (ENABLE_VTK_M)
if (ENABLE_VTK_ACCELERATORS)
list(APPEND SENSEI_VTK_COMPONENTS vtkAcceleratorsVTKm vtkIOLegacy
vtkFiltersGeometry vtkImagingCore)
# Now find VTK-m so it can be used independently of VTK
# This makes the vtkm_cont library available as well as
# targets vtkm::tbb and vtkm::cuda if they exist (so that
# device support can be conditionally compiled) using
# IF (TARGET vtkm::tbb) ... ENDIF()
find_package(VTKm REQUIRED QUIET)
endif()
if (NOT ENABLE_CATALYST)
......
set(SENSEI_VTKM_COMPONENTS Base)
if (ENABLE_VTKM_RENDERING)
list(APPEND SENSEI_VTKM_COMPONENTS Rendering)
endif()
if (ENABLE_VTKM)
find_package(VTKm QUIET REQUIRED COMPONENTS ${SENSEI_VTKM_COMPONENTS})
endif()
......@@ -12,6 +12,7 @@ include(adios)
include(vtk)
include(libsim)
include(catalyst)
include(vtkm) # Place after vtk, catalyst, others that depend on vtkm
include(conduit)
include(python)
include(version)
......
......@@ -112,7 +112,7 @@ $ make install
| `ENABLE_LIBSIM` | OFF | Enables Libsim data and analysis adaptors. Requires Libsim. Set `VTK_DIR` and `LIBSIM_DIR`. |
| `ENABLE_VTK_IO` | OFF | Enables adaptors to write to VTK XML format. |
| `ENABLE_VTK_MPI` | OFF | Enables MPI parallel VTK filters, such as parallel I/O. |
| `ENABLE_VTK_M` | ON | Enables analyses that use VTKm directly instead of via VTK. |
| `ENABLE_VTKM` | ON | Enables analyses that use VTKm directly instead of via VTK. |
| `ENABLE_PARALLEL3D` | ON | Enables the parallel 3D mini-app. |
| `ENABLE_OSCILLATORS` | ON | Enables the oscillators mini-app. |
| `VTK_DIR` | | Set to the directory containing VTKConfig.cmake. |
......@@ -139,6 +139,9 @@ cmake -DENABLE_SENSEI=ON -DENABLE_LIBSIM=ON -DVTK_DIR=[your path] -DLIBSIM_DIR=[
cmake -DENABLE_SENSEI=ON -DENABLE_CATALYST=ON -DParaView_DIR=[your path] ..
```
Optionally, `-DENABLE_CATALYST_PYTHON=ON` will enable Catalyst Python scripts.
Note that a development version of ParaView is required when building with
both `ENABLE_CATALYST` and `ENABLE_VTKM` are enabled as released versions of
ParaView (5.5.2 and earlier) do not include a modern-enough version of vtk-m.
### Enable writing to Visit ".visit" format or ParaView ".pvd" format
```bash
......@@ -146,6 +149,14 @@ cmake -DENABLE_SENSEI=ON -DENABLE_VTK_IO=ON -DVTK_DIR=[your path] ..
```
Can be used with either `ParaView_DIR` or `VTK_DIR`.
### For use with VTK-m
```bash
cmake -DENABLE_SENSEI=ON -DENABLE_VTKM=ON -DVTK_DIR=[your path] ..
```
Note that a development version of VTK is required when building with
both `ENABLE_SENSEI` and `ENABLE_VTKM` are enabled as released versions of
VTK (8.1.1 and earlier) do not include a modern-enough version of vtk-m.
### Enabling Python bindings
In essence this is as simple as adding `-DENABLE_PYTHON=ON`. However, VTK (or
ParaView when used with Catalyst) needs to be built with Python enabled, and
......@@ -176,9 +187,20 @@ approvals from the U.S. Dept. of Energy).
* [pugixml](https://github.com/zeux/pugixml), Copyright (c) 2006-2016 Arseny Kapoulkine.
The SENSEI framework makes use of (links to) the following software:
* [ADIOS](https://www.olcf.ornl.gov/center-projects/adios/), Copyright (c) 2008 - 2009. UT-BATTELLE, LLC. Copyright (c) 2008 - 2009. Georgia Institute of Technology.
* [ADIOS](https://www.olcf.ornl.gov/center-projects/adios/), Copyright (c) 2008 - 2009.
UT-BATTELLE, LLC. Copyright (c) 2008 - 2009. Georgia Institute of Technology.
* [ParaView/Catalyst](https://gitlab.kitware.com/paraview/paraview), Copyright (c) 2005-2008 Sandia Corporation, Kitware Inc.
Sensei requires ParaView v5.5.1 or later when `ENABLE_CATALYST` is on
and a development version (v5.6.0 or later) when both `ENABLE_CATALYST` and `ENABLE_VTKM` are on.
* [VisIt/libsim](http://visit.llnl.gov), Copyright (c) 2000 - 2016, Lawrence Livermore National Security, LLC.
* [VTK](https://gitlab.kitware.com/vtk/vtk), Copyright (c) 1993-2015 Ken Martin, Will Schroeder, Bill Lorensen.
For full license information regarding included and used software please refer to the file [THIRDPARTY_SOFTWARE_LICENSES](THIRDPARTY_SOFTWARE_LICENSES).
Sensei can use VTK provided separately or the VTK included with
VisIt/libSim (VTK v6.1 when `ENABLE_LIBSIM` is on) or
ParaView/Catalyst (VTK v8.1 when `ENABLE_CATALYST` is on).
If VTK is provided separately and both `ENABLE_VTK` and `ENABLE_VTKM` are on,
Sensei requires a development version (VTK v9.0 or later).
* [VTKm](https://gitlab.kitware.com/vtk/vtkm), Copyright (c) 2014-2018 NTESS, SNL, LANL, UT-Battelle, Kitware, UC Davis.
A development version is currently required as packaging infrastructure has recently changed.
For full license information regarding included and used software please refer
to the file [THIRDPARTY_SOFTWARE_LICENSES](THIRDPARTY_SOFTWARE_LICENSES).
<sensei>
<!--
type="vtkmaar" - we should use Haar wavelets to reduce the dataset size
mesh="mesh" - that this analysis will run on the oscillator's image data
field="data" - the scalar field we wish to reduce
association="points" - that the scalar field is defined on points of the image
reduction="1" - we should perform a single (factor of 8) reduction step
working-directory="/tmp" - where the result files should be stored.
The results include an "index.json" summary and on directory
per timestep of cinema data.
-->
<analysis
enabled="1"
type="vtkmhaar"
mesh="mesh"
field="data"
association="points"
reduction="1"
working-directory="/tmp"
/>
</sensei>
......@@ -3,44 +3,105 @@ if (ENABLE_SENSEI)
# senseiCore
# everything but the Python and configurable analysis adaptors.
set(senseiCore_sources AnalysisAdaptor.cxx Autocorrelation.cxx
DataAdaptor.cxx DataRequirements.cxx Histogram.cxx Error.cxx
ProgrammableDataAdaptor.cxx VTKHistogram.cxx VTKDataAdaptor.cxx
VTKUtils.cxx)
set(senseiCore_headers
AnalysisAdaptor.h
Autocorrelation.h
DataAdaptor.h
DataRequirements.h
Error.h
Histogram.h
ProgrammableDataAdaptor.h
VTKHistogram.h
VTKDataAdaptor.h
VTKUtils.h
)
set(senseiCore_sources
AnalysisAdaptor.cxx
Autocorrelation.cxx
DataAdaptor.cxx
DataRequirements.cxx
Error.cxx
Histogram.cxx
ProgrammableDataAdaptor.cxx
VTKHistogram.cxx
VTKDataAdaptor.cxx
VTKUtils.cxx
)
set(senseiCore_libs mpi pugixml vtk thread ArrayIO timer diy grid)
if(ENABLE_CONDUIT)
list(APPEND senseiCore_headers ConduitDataAdaptor.h)
list(APPEND senseiCore_sources ConduitDataAdaptor.cxx)
list(APPEND senseiCore_libs sconduit)
endif()
if(ENABLE_CATALYST)
list(APPEND senseiCore_sources CatalystAnalysisAdaptor.cxx
CatalystSlice.cxx CatalystUtilities.cxx)
list(APPEND senseiCore_headers
CatalystAnalysisAdaptor.h
CatalystSlice.h
CatalystUtilities.h
)
list(APPEND senseiCore_sources
CatalystAnalysisAdaptor.cxx
CatalystSlice.cxx
CatalystUtilities.cxx
)
endif()
if (ENABLE_VTKM)
list(APPEND senseiCore_headers
VTKmVolumeReductionAnalysis.h
CinemaHelper.h
)
list(APPEND senseiCore_sources
VTKmVolumeReductionAnalysis.cxx
CinemaHelper.cxx
)
list(APPEND senseiCore_libs vtkm_cont)
endif()
if(ENABLE_ADIOS)
list(APPEND senseiCore_sources ADIOSSchema.cxx
ADIOSAnalysisAdaptor.cxx ADIOSDataAdaptor.cxx)
list(APPEND senseiCore_headers
ADIOSSchema.h
ADIOSAnalysisAdaptor.h
ADIOSDataAdaptor.h
)
list(APPEND senseiCore_sources
ADIOSSchema.cxx
ADIOSAnalysisAdaptor.cxx
ADIOSDataAdaptor.cxx
)
list(APPEND senseiCore_libs adios)
endif()
if(ENABLE_VTK_M)
if(ENABLE_VTK_ACCELERATORS)
list(APPEND senseiCore_headers
VTKmContourAnalysis.h
)
list(APPEND senseiCore_sources
VTKmContourAnalysis.cxx
VTKmContourAnalysis.h)
)
endif()
if(ENABLE_LIBSIM)
list(APPEND senseiCore_sources LibsimAnalysisAdaptor.cxx
LibsimImageProperties.cxx)
list(APPEND senseiCore_headers
LibsimAnalysisAdaptor.h
LibsimImageProperties.h
)
list(APPEND senseiCore_sources
LibsimAnalysisAdaptor.cxx
LibsimImageProperties.cxx
)
list(APPEND senseiCore_libs libsim)
endif()
if(ENABLE_VTK_IO)
list(APPEND senseiCore_headers VTKPosthocIO.h)
list(APPEND senseiCore_sources VTKPosthocIO.cxx)
if (ENABLE_VTK_MPI)
list(APPEND senseiCore_headers VTKAmrWriter.h)
list(APPEND senseiCore_sources VTKAmrWriter.cxx)
endif()
endif()
......@@ -60,7 +121,13 @@ if (ENABLE_SENSEI)
install(EXPORT senseiCore DESTINATION lib/cmake
EXPORT_LINK_INTERFACE_LIBRARIES)
install(
FILES ${senseiCore_headers}
DESTINATION include
)
set(sensei_sources ConfigurableAnalysis.cxx)
set(sensei_headers ConfigurableAnalysis.h)
set(sensei_libs senseiCore)
# PythonAnalysis
......@@ -94,8 +161,10 @@ if (ENABLE_SENSEI)
install(EXPORT _PythonAnalysis DESTINATION lib/cmake
EXPORT_LINK_INTERFACE_LIBRARIES)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/PythonAnalysis.py
DESTINATION lib)
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/PythonAnalysis.py
DESTINATION lib
)
set(python_analyses Histogram.py)
foreach(python_analysis ${python_analyses})
......@@ -106,6 +175,7 @@ if (ENABLE_SENSEI)
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/"
DESTINATION lib FILES_MATCHING PATTERN "*.py")
list(APPEND sensei_headers PythonAnalysis.h)
list(APPEND sensei_libs _PythonAnalysis)
endif()
......@@ -120,8 +190,10 @@ if (ENABLE_SENSEI)
target_link_libraries(sensei PUBLIC ${sensei_libs})
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/"
DESTINATION include FILES_MATCHING PATTERN "*.h")
install(
FILES ${sensei_headers}
DESTINATION include
)
install(TARGETS sensei EXPORT sensei
INCLUDES DESTINATION include ARCHIVE DESTINATION lib
......
......@@ -106,9 +106,9 @@ int CatalystAnalysisAdaptor::DescribeData(int timeStep, double time,
{
int assoc = ait.Association();
if (assoc == vtkDataObject::POINT)
inDesc->AddPointField(ait.Array().c_str());
inDesc->AddField(ait.Array().c_str(), vtkDataObject::POINT);
else if (assoc == vtkDataObject::CELL)
inDesc->AddCellField(ait.Array().c_str());
inDesc->AddField(ait.Array().c_str(), vtkDataObject::CELL);
else
SENSEI_WARNING("Unknown association " << assoc)
}
......@@ -151,7 +151,7 @@ int CatalystAnalysisAdaptor::SelectData(DataAdaptor *dataAdaptor,
int assoc = ait.Association();
std::string arrayName = ait.Array();
if (inDesc->IsFieldNeeded(arrayName.c_str()))
if (inDesc->IsFieldNeeded(arrayName.c_str(), assoc))
{
if (dataAdaptor->AddArray(dobj, meshName, assoc, arrayName))
{
......
This diff is collapsed.
#ifndef sensei_CinemaHelper_h
#define sensei_CinemaHelper_h
class vtkSMViewProxy;
class vtkSMRenderViewProxy;
class vtkSMRepresentationProxy;
class vtkActor;
class vtkCamera;
class vtkRenderer;
class vtkRenderWindow;
class vtkIceTCompositePass;
class vtkCameraPass;
class vtkLightingMapPass;
class vtkImageData;
#include <string>
namespace sensei
{
class CinemaHelper
{
public:
CinemaHelper();
~CinemaHelper();
// Metadata handling
void SetImageSize(int width, int height);
void SetWorkingDirectory(const std::string& path);
void SetExportType(const std::string& exportType);
void AddTimeEntry();
void WriteMetadata();
// Camera handling
void SetCameraConfig(const std::string& config);
int GetNumberOfCameraPositions();
void ApplyCameraPosition(vtkSMViewProxy* view, int cameraPositionIndex);
void ApplyCameraPosition(vtkCamera* camera, int cameraPositionIndex);
// Contours handling
int GetNumberOfContours();
double GetContourValue(int idx);
void SetContours(const std::string& values);
// Composite dataset handling
// => FIXME: Assume => intensity + constant coloring
int RegisterLayer(const std::string& name, vtkSMRepresentationProxy* representation, double scalarValue);
int RegisterLayer(const std::string& name, vtkActor* actor, double scalarValue);
void CaptureSortedCompositeData(vtkSMRenderViewProxy* view);
void CaptureSortedCompositeData(vtkRenderWindow* renderWindow, vtkRenderer* renderer, vtkIceTCompositePass* compositePass);
void Render(vtkRenderWindow* renderWindow);
vtkImageData* CaptureWindow(vtkRenderWindow* renderWindow);
// Image handling
void CaptureImage(vtkSMViewProxy* view, const std::string fileName, const std::string writerName, double scale = 1, bool createDirectory = true);
// Generic Methods
void Capture(vtkSMViewProxy* view);
// Volume handling
void WriteVolume(vtkImageData* image);
private:
struct Internals;
Internals *Data;
};
}
#endif
......@@ -12,9 +12,12 @@
#include "VTKAmrWriter.h"
#endif
#endif
#ifdef ENABLE_VTK_M
#ifdef ENABLE_VTK_ACCELERATORS
#include "VTKmContourAnalysis.h"
#endif
#ifdef ENABLE_VTKM
#include "VTKmVolumeReductionAnalysis.h"
#endif
#ifdef ENABLE_ADIOS
#include "ADIOSAnalysisAdaptor.h"
#endif
......@@ -132,6 +135,7 @@ struct ConfigurableAnalysis::InternalsType
// by rank 0
int AddHistogram(pugi::xml_node node);
int AddVTKmContour(pugi::xml_node node);
int AddVTKmVolumeReduction(pugi::xml_node node);
int AddAdios(pugi::xml_node node);
int AddCatalyst(pugi::xml_node node);
int AddLibsim(pugi::xml_node node);
......@@ -202,10 +206,10 @@ int ConfigurableAnalysis::InternalsType::AddHistogram(pugi::xml_node node)
// --------------------------------------------------------------------------
int ConfigurableAnalysis::InternalsType::AddVTKmContour(pugi::xml_node node)
{
#ifndef ENABLE_VTK_M
{
#ifndef ENABLE_VTK_ACCELERATORS
(void)node;
SENSEI_ERROR("VTK-m was requested but is disabled in this build")
SENSEI_ERROR("vtkAcceleratorsVtkm was requested but is disabled in this build")
return -1;
#else
......@@ -234,7 +238,44 @@ int ConfigurableAnalysis::InternalsType::AddVTKmContour(pugi::xml_node node)
return 0;
#endif
}
}
// --------------------------------------------------------------------------
int ConfigurableAnalysis::InternalsType::AddVTKmVolumeReduction(pugi::xml_node node)
{
#ifndef ENABLE_VTKM
(void)node;
SENSEI_ERROR("VTK-m analysis was requested but is disabled in this build")
return -1;
#else
if (
requireAttribute(node, "mesh") ||
requireAttribute(node, "field") ||
requireAttribute(node, "association") ||
requireAttribute(node, "reduction")
)
{
SENSEI_ERROR("Failed to initialize VTKmVolumeReductionAnalysis");
return -1;
}
auto mesh = node.attribute("mesh").as_string();
auto field = node.attribute("field").as_string();
auto assoc = node.attribute("association").as_string();
auto reduction = node.attribute("reduction").as_int();
bool haveWorkDir = !!node.attribute("working-directory");
std::string workDir = haveWorkDir ? node.attribute("working-directory").as_string() : ".";
vtkNew<VTKmVolumeReductionAnalysis> reducer;
reducer->Initialize(mesh, field, assoc, workDir, reduction, this->Comm);
this->Analyses.push_back(reducer.GetPointer());
SENSEI_STATUS("Configured VTKmVolumeReductionAnalysis " << mesh << "/" << field)
return 0;
#endif
}
// --------------------------------------------------------------------------
int ConfigurableAnalysis::InternalsType::AddAdios(pugi::xml_node node)
......@@ -724,6 +765,7 @@ int ConfigurableAnalysis::Initialize(const std::string& filename)
|| ((type == "PosthocIO") && !this->Internals->AddPosthocIO(node))
|| ((type == "VTKAmrWriter") && !this->Internals->AddVTKAmrWriter(node))
|| ((type == "vtkmcontour") && !this->Internals->AddVTKmContour(node))
|| ((type == "vtkmhaar") && !this->Internals->AddVTKmVolumeReduction(node))
|| ((type == "python") && !this->Internals->AddPythonAnalysis(node))))
{
if (rank == 0)
......
#include "VTKmVolumeReductionAnalysis.h"
#include "CinemaHelper.h"
#include "DataAdaptor.h"
#include <Timer.h>
#include <vtkCellData.h>
#include <vtkFloatArray.h>
#include <vtkImageData.h>
#include <vtkMPICommunicator.h>
#include <vtkMPIController.h>
#include <vtkMultiBlockDataSet.h>
#include <vtkNew.h>
#include <vtkObjectFactory.h>
#include <vtkPointData.h>
#include <vtkSmartPointer.h>
#include <algorithm>
#include <vector>
// --- vtkm ---
#include <vtkm/Math.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ArrayHandleCounting.h>
#include <vtkm/cont/DataSetBuilderUniform.h>
#include <vtkm/filter/FilterDataSet.h>
#include <vtkm/worklet/DispatcherPointNeighborhood.h>
#include <vtkm/worklet/ScatterPermutation.h>
#include <vtkm/worklet/WorkletPointNeighborhood.h>
#include <vtkm/cont/TryExecute.h>
#include <vtkm/cont/cuda/DeviceAdapterCuda.h>
#include <vtkm/cont/serial/DeviceAdapterSerial.h>
#include <vtkm/cont/tbb/DeviceAdapterTBB.h>
namespace sensei
{
//-----------------------------------------------------------------------------
// VTK-M
//-----------------------------------------------------------------------------
//This is the list of devices to compile in support for. The order of the
//devices determines the runtime preference.
struct DevicesToTry : vtkm::ListTagBase<vtkm::cont::DeviceAdapterTagCuda,
vtkm::cont::DeviceAdapterTagTBB,
vtkm::cont::DeviceAdapterTagSerial>
{
};
struct ImageReductionPolicy : public vtkm::filter::PolicyBase<ImageReductionPolicy>
{
using DeviceAdapterList = DevicesToTry;
};
struct VoxelMean : public vtkm::worklet::WorkletPointNeighborhood3x3x3
{
using CountingHandle = vtkm::cont::ArrayHandle<vtkm::Id>;
VoxelMean(CountingHandle handle): Scatter(handle)
{
}
typedef void ControlSignature(CellSetIn,
FieldInNeighborhood<> in,
FieldOut<> out);
typedef void ExecutionSignature(_2, _3);
using ScatterType = vtkm::worklet::ScatterPermutation<typename CountingHandle::StorageTag>;
template <typename NeighIn>
VTKM_EXEC void operator()(const NeighIn& in,
vtkm::Float32& out) const
{
out = in.Get(0, 0, 0) + in.Get(1, 0, 0)
+ in.Get(0, 1, 0) + in.Get(1, 1, 0)
+ in.Get(0, 0, 1) + in.Get(1, 0, 1)
+ in.Get(0, 1, 1) + in.Get(1, 1, 1);
out *= 0.125;
}
ScatterType GetScatter() const { return this->Scatter; }
private:
ScatterType Scatter;
};
class ImageReduction : public vtkm::filter::FilterDataSet<ImageReduction>
{
vtkm::Vec<vtkm::Int32, 3> InputDimensions;
vtkm::cont::Field::Association FieldAssoc;
std::string FieldName;
public: