Deprecate old filter base classes and supporting classes

This commit is contained in:
Kenneth Moreland 2022-09-26 10:23:26 -06:00
parent b6d54eb612
commit de2f2b59ba
30 changed files with 795 additions and 753 deletions

@ -29,7 +29,6 @@
#include <vtkm/cont/internal/OptionParser.h>
#include <vtkm/filter/FieldSelection.h>
#include <vtkm/filter/PolicyBase.h>
#include <vtkm/filter/contour/Contour.h>
#include <vtkm/filter/entity_extraction/ExternalFaces.h>
#include <vtkm/filter/entity_extraction/Threshold.h>

@ -0,0 +1,9 @@
# Old Filter Base Classes are Deprecated
In recent versions of VTK-m, a new structure for filter classes was
introduced. All of the existing filters have been moved over to this new
structure, and the old filter class structure has been deprecated.
This is in preparation for changed in VTK-m 2.0, where the old filter
classes will be removed and the new filter classes will have the `New` in
their name removed (so that they become simply `Filter` and `FilterField`).

@ -19,13 +19,14 @@
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ArrayHandleCounting.h>
#include <vtkm/cont/CellSetStructured.h>
#include <vtkm/cont/DataSetBuilderUniform.h>
#include <vtkm/cont/Initialize.h>
#include <vtkm/cont/Timer.h>
#include <vtkm/interop/TransferToOpenGL.h>
#include <vtkm/filter/FilterDataSet.h>
#include <vtkm/filter/NewFilterField.h>
#include <vtkm/worklet/WorkletPointNeighborhood.h>
#include <vtkm/cont/Invoker.h>
@ -48,11 +49,6 @@
#include "LoadShaders.h"
struct GameOfLifePolicy : public vtkm::filter::PolicyBase<GameOfLifePolicy>
{
using FieldTypeList = vtkm::List<vtkm::UInt8, vtkm::Vec4ui_8>;
};
struct UpdateLifeState : public vtkm::worklet::WorkletPointNeighborhood
{
using CountingHandle = vtkm::cont::ArrayHandleCounting<vtkm::Id>;
@ -99,44 +95,33 @@ struct UpdateLifeState : public vtkm::worklet::WorkletPointNeighborhood
};
class GameOfLife : public vtkm::filter::FilterDataSet<GameOfLife>
class GameOfLife : public vtkm::filter::NewFilterField
{
public:
template <typename Policy>
VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input,
vtkm::filter::PolicyBase<Policy> policy)
VTKM_CONT GameOfLife() { this->SetActiveField("state", vtkm::cont::Field::Association::Points); }
VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input) override
{
vtkm::cont::ArrayHandle<vtkm::UInt8> state;
vtkm::cont::ArrayHandle<vtkm::UInt8> prevstate;
vtkm::cont::ArrayHandle<vtkm::Vec4ui_8> colors;
//get the coordinate system we are using for the 2D area
const vtkm::cont::UnknownCellSet cells = input.GetCellSet();
vtkm::cont::CellSetStructured<2> cells;
input.GetCellSet().AsCellSet(cells);
//get the previous state of the game
input.GetField("state", vtkm::cont::Field::Association::Points).GetData().CopyTo(prevstate);
this->GetFieldFromDataSet(input).GetData().AsArrayHandle(prevstate);
//Update the game state
this->Invoke(
UpdateLifeState{}, vtkm::filter::ApplyPolicyCellSet(cells, policy), prevstate, state, colors);
this->Invoke(UpdateLifeState{}, cells, prevstate, state, colors);
//save the results
vtkm::cont::DataSet output;
output.CopyStructure(input);
vtkm::cont::DataSet output =
this->CreateResultFieldPoint(input, this->GetActiveFieldName(), state);
output.AddField(vtkm::cont::make_FieldPoint("colors", colors));
output.AddField(vtkm::cont::make_FieldPoint("state", state));
return output;
}
template <typename DerivedPolicy>
VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet&,
const vtkm::cont::Field&,
vtkm::filter::PolicyBase<DerivedPolicy>)
{
return false;
}
};
struct UploadData
@ -346,7 +331,7 @@ int main(int argc, char** argv)
glutDisplayFunc([]() {
const vtkm::Float32 c = static_cast<vtkm::Float32>(gTimer.GetElapsedTime());
vtkm::cont::DataSet oData = gFilter->Execute(*gData, GameOfLifePolicy());
vtkm::cont::DataSet oData = gFilter->Execute(*gData);
gRenderer->render(oData);
glutSwapBuffers();

@ -10,8 +10,7 @@
#include <vtkm/worklet/WorkletMapField.h>
#include <vtkm/filter/CreateResult.h>
#include <vtkm/filter/FilterField.h>
#include <vtkm/filter/NewFilterField.h>
#include <vtkm/io/VTKDataSetReader.h>
#include <vtkm/io/VTKDataSetWriter.h>
@ -23,58 +22,56 @@
#include <cstdlib>
#include <iostream>
namespace vtkm
{
namespace worklet
namespace hello_worklet_example
{
struct HelloWorklet : public vtkm::worklet::WorkletMapField
{
using ControlSignature = void(FieldIn inVector, FieldOut outMagnitude);
VTKM_EXEC void operator()(const vtkm::Vec3f& inVector, vtkm::FloatDefault& outMagnitude) const
template <typename T>
VTKM_EXEC void operator()(const vtkm::Vec<T, 3>& inVector, T& outMagnitude) const
{
outMagnitude = vtkm::Magnitude(inVector);
}
};
}
} // namespace vtkm::worklet
} // namespace hello_worklet_example
namespace vtkm
{
namespace filter
{
class HelloField : public vtkm::filter::FilterField<HelloField>
class HelloField : public vtkm::filter::NewFilterField
{
public:
// Specify that this filter operates on 3-vectors
using SupportedTypes = vtkm::TypeListFieldVec3;
template <typename FieldType, typename Policy>
VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& inDataSet,
const FieldType& inField,
const vtkm::filter::FieldMetadata& fieldMetadata,
vtkm::filter::PolicyBase<Policy>)
VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& inDataSet)
{
VTKM_IS_ARRAY_HANDLE(FieldType);
// Input field
vtkm::cont::Field inField = this->GetFieldFromDataSet(inDataSet);
//construct our output
vtkm::cont::ArrayHandle<vtkm::FloatDefault> outField;
// Holder for output
vtkm::cont::UnknownArrayHandle outArray;
//construct our invoker to launch worklets
vtkm::worklet::HelloWorklet mag;
this->Invoke(mag, inField, outField); //launch mag worklets
hello_worklet_example::HelloWorklet mag;
auto resolveType = [&](const auto& inputArray) {
// use std::decay to remove const ref from the decltype of concrete.
using T = typename std::decay_t<decltype(inputArray)>::ValueType::ComponentType;
vtkm::cont::ArrayHandle<T> result;
this->Invoke(mag, inputArray, result);
outArray = result;
};
//construct output field information
if (this->GetOutputFieldName().empty())
this->CastAndCallVecField<3>(inField, resolveType);
std::string outFieldName = this->GetOutputFieldName();
if (outFieldName.empty())
{
this->SetOutputFieldName(fieldMetadata.GetName() + "_magnitude");
outFieldName = inField.GetName() + "_magnitude";
}
//return the result, which is the input data with the computed field added to it
return vtkm::filter::CreateResult(
inDataSet, outField, this->GetOutputFieldName(), fieldMetadata);
return this->CreateResultField(inDataSet, outFieldName, inField.GetAssociation(), outArray);
}
};
}

@ -13,9 +13,9 @@ project(Histogram CXX)
#Find the VTK-m package
find_package(VTKm REQUIRED QUIET)
if (VTKm_ENABLE_MPI)
add_executable(Histogram Histogram.cxx HistogramMPI.h HistogramMPI.hxx)
add_executable(Histogram Histogram.cxx HistogramMPI.h HistogramMPI.cxx)
target_link_libraries(Histogram PRIVATE vtkm_filter MPI::MPI_CXX)
vtkm_add_target_information(Histogram
DROP_UNUSED_SYMBOLS MODIFY_CUDA_FLAGS
DEVICE_SOURCES Histogram.cxx)
DEVICE_SOURCES HistogramMPI.cxx)
endif()

@ -64,9 +64,8 @@ int main(int argc, char* argv[])
// tell VTK-m the communicator to use.
vtkm::cont::EnvironmentTracker::SetCommunicator(world);
int rank, size;
MPI_Comm_rank(vtkmdiy::mpi::mpi_cast(world.handle()), &rank);
MPI_Comm_size(vtkmdiy::mpi::mpi_cast(world.handle()), &size);
int rank = world.rank();
int size = world.size();
if (argc != 2)
{

@ -8,6 +8,8 @@
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#include "HistogramMPI.h"
#include <vtkm/filter/density_estimate/worklet/FieldHistogram.h>
#include <vtkm/cont/Algorithm.h>
@ -102,53 +104,69 @@ public:
} // namespace detail
//-----------------------------------------------------------------------------
inline VTKM_CONT HistogramMPI::HistogramMPI()
: NumberOfBins(10)
, BinDelta(0)
, ComputedRange()
, Range()
VTKM_CONT vtkm::cont::DataSet HistogramMPI::DoExecute(const vtkm::cont::DataSet& input)
{
this->SetOutputFieldName("histogram");
}
const auto& fieldArray = this->GetFieldFromDataSet(input).GetData();
//-----------------------------------------------------------------------------
template <typename T, typename StorageType, typename DerivedPolicy>
inline VTKM_CONT vtkm::cont::DataSet HistogramMPI::DoExecute(
const vtkm::cont::DataSet&,
const vtkm::cont::ArrayHandle<T, StorageType>& field,
const vtkm::filter::FieldMetadata&,
const vtkm::filter::PolicyBase<DerivedPolicy>&)
{
vtkm::cont::ArrayHandle<vtkm::Id> binArray;
T delta;
vtkm::worklet::FieldHistogram worklet;
if (this->ComputedRange.IsNonEmpty())
if (!this->InExecutePartitions)
{
worklet.Run(field,
// Handle initialization that would be done in PreExecute if the data set had partitions.
if (this->Range.IsNonEmpty())
{
this->ComputedRange = this->Range;
}
else
{
auto handle = vtkm::cont::FieldRangeGlobalCompute(
input, this->GetActiveFieldName(), this->GetActiveFieldAssociation());
if (handle.GetNumberOfValues() != 1)
{
throw vtkm::cont::ErrorFilterExecution("expecting scalar field.");
}
this->ComputedRange = handle.ReadPortal().Get(0);
}
}
vtkm::cont::ArrayHandle<vtkm::Id> binArray;
auto resolveType = [&](const auto& concrete) {
using T = typename std::decay_t<decltype(concrete)>::ValueType;
T delta;
vtkm::worklet::FieldHistogram worklet;
worklet.Run(concrete,
this->NumberOfBins,
static_cast<T>(this->ComputedRange.Min),
static_cast<T>(this->ComputedRange.Max),
delta,
binArray);
}
else
{
worklet.Run(field, this->NumberOfBins, this->ComputedRange, delta, binArray);
}
this->BinDelta = static_cast<vtkm::Float64>(delta);
this->BinDelta = static_cast<vtkm::Float64>(delta);
};
fieldArray
.CastAndCallForTypesWithFloatFallback<vtkm::TypeListFieldScalar, VTKM_DEFAULT_STORAGE_LIST>(
resolveType);
vtkm::cont::DataSet output;
vtkm::cont::Field rfield(
this->GetOutputFieldName(), vtkm::cont::Field::Association::WholeMesh, binArray);
output.AddField(rfield);
output.AddField(
{ this->GetOutputFieldName(), vtkm::cont::Field::Association::WholeDataSet, binArray });
// The output is a "summary" of the input, no need to map fields
return output;
}
VTKM_CONT vtkm::cont::PartitionedDataSet HistogramMPI::DoExecutePartitions(
const vtkm::cont::PartitionedDataSet& input)
{
this->PreExecute(input);
auto result = this->NewFilter::DoExecutePartitions(input);
this->PostExecute(input, result);
return result;
}
//-----------------------------------------------------------------------------
template <typename DerivedPolicy>
inline VTKM_CONT void HistogramMPI::PreExecute(const vtkm::cont::PartitionedDataSet& input,
const vtkm::filter::PolicyBase<DerivedPolicy>&)
inline VTKM_CONT void HistogramMPI::PreExecute(const vtkm::cont::PartitionedDataSet& input)
{
if (this->Range.IsNonEmpty())
{
@ -167,10 +185,8 @@ inline VTKM_CONT void HistogramMPI::PreExecute(const vtkm::cont::PartitionedData
}
//-----------------------------------------------------------------------------
template <typename DerivedPolicy>
inline VTKM_CONT void HistogramMPI::PostExecute(const vtkm::cont::PartitionedDataSet&,
vtkm::cont::PartitionedDataSet& result,
const vtkm::filter::PolicyBase<DerivedPolicy>&)
vtkm::cont::PartitionedDataSet& result)
{
// iterate and compute HistogramMPI for each local block.
detail::DistributedHistogram helper(result.GetNumberOfPartitions());
@ -182,7 +198,7 @@ inline VTKM_CONT void HistogramMPI::PostExecute(const vtkm::cont::PartitionedDat
vtkm::cont::DataSet output;
vtkm::cont::Field rfield(this->GetOutputFieldName(),
vtkm::cont::Field::Association::WholeMesh,
vtkm::cont::Field::Association::WholeDataSet,
helper.ReduceAll(this->NumberOfBins));
output.AddField(rfield);

@ -10,7 +10,7 @@
#ifndef vtk_m_examples_histogram_HistogramMPI_h
#define vtk_m_examples_histogram_HistogramMPI_h
#include <vtkm/filter/FilterField.h>
#include <vtkm/filter/NewFilterField.h>
namespace example
{
@ -19,7 +19,7 @@ namespace example
///
/// Construct a HistogramMPI with a default of 10 bins.
///
class HistogramMPI : public vtkm::filter::FilterField<HistogramMPI>
class HistogramMPI : public vtkm::filter::NewFilterField
{
public:
//currently the HistogramMPI filter only works on scalar data.
@ -29,7 +29,7 @@ public:
//Construct a HistogramMPI with a default of 10 bins
VTKM_CONT
HistogramMPI();
HistogramMPI() { this->SetOutputFieldName("histogram"); }
VTKM_CONT
void SetNumberOfBins(vtkm::Id count) { this->NumberOfBins = count; }
@ -58,34 +58,27 @@ public:
VTKM_CONT
vtkm::Range GetComputedRange() const { return this->ComputedRange; }
template <typename T, typename StorageType, typename DerivedPolicy>
VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input,
const vtkm::cont::ArrayHandle<T, StorageType>& field,
const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy);
protected:
VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input) override;
VTKM_CONT vtkm::cont::PartitionedDataSet DoExecutePartitions(
const vtkm::cont::PartitionedDataSet& input) override;
///@{
/// 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::PartitionedDataSet& input,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy);
template <typename DerivedPolicy>
VTKM_CONT void PreExecute(const vtkm::cont::PartitionedDataSet& input);
VTKM_CONT void PostExecute(const vtkm::cont::PartitionedDataSet& input,
vtkm::cont::PartitionedDataSet& output,
const vtkm::filter::PolicyBase<DerivedPolicy>&);
vtkm::cont::PartitionedDataSet& output);
///@}
private:
vtkm::Id NumberOfBins;
vtkm::Float64 BinDelta;
vtkm::Id NumberOfBins = 10;
vtkm::Float64 BinDelta = 0;
vtkm::Range ComputedRange;
vtkm::Range Range;
bool InExecutePartitions = false;
};
} // namespace example
#include "HistogramMPI.hxx"
#endif // vtk_m_filter_Histogram_h

@ -8,11 +8,251 @@
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#define vtk_m_examples_multibackend_MultiDeviceGradient_cxx
#include "MultiDeviceGradient.h"
#include "MultiDeviceGradient.hxx"
template vtkm::cont::PartitionedDataSet MultiDeviceGradient::PrepareForExecution<
vtkm::filter::PolicyDefault>(const vtkm::cont::PartitionedDataSet&,
const vtkm::filter::PolicyBase<vtkm::filter::PolicyDefault>&);
#include <vtkm/cont/Logging.h>
#include <vtkm/cont/RuntimeDeviceInformation.h>
#include <vtkm/cont/RuntimeDeviceTracker.h>
#include <vtkm/cont/cuda/DeviceAdapterCuda.h>
#include <vtkm/cont/openmp/DeviceAdapterOpenMP.h>
#include <vtkm/cont/tbb/DeviceAdapterTBB.h>
#include <vtkm/filter/vector_analysis/Gradient.h>
namespace
{
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
//task operate only on TBB. The "global" thread tracker
//is actually thread-local, so we can use that.
//
vtkm::cont::GetRuntimeDeviceTracker().ForceDevice(vtkm::cont::DeviceAdapterTagTBB{});
while (queue.hasTasks())
{
//Step 2. Get the task to run on TBB
auto task = queue.pop();
//Step 3. Run the task on TBB. We check the validity
//of the task since we could be given an empty task
//when the queue is empty and we are shutting down
if (task != nullptr)
{
task();
}
//Step 4. Notify the queue that we finished processing this task
queue.completedTask();
std::cout << "finished a partition on tbb (" << std::this_thread::get_id() << ")" << std::endl;
}
}
void process_partition_openMP(RuntimeTaskQueue& queue)
{
//Step 1. Set the device adapter to this thread to openMP.
//This makes sure that any vtkm::filters used by our
//task operate only on openMP. The "global" thread tracker
//is actually thread-local, so we can use that.
//
vtkm::cont::GetRuntimeDeviceTracker().ForceDevice(vtkm::cont::DeviceAdapterTagOpenMP{});
while (queue.hasTasks())
{
//Step 2. Get the task to run on openMP
auto task = queue.pop();
//Step 3. Run the task on openMP. We check the validity
//of the task since we could be given an empty task
//when the queue is empty and we are shutting down
if (task != nullptr)
{
task();
}
//Step 4. Notify the queue that we finished processing this task
queue.completedTask();
std::cout << "finished a partition on openMP (" << std::this_thread::get_id() << ")"
<< std::endl;
}
}
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
//task operate only on cuda. The "global" thread tracker
//is actually thread-local, so we can use that.
//
vtkm::cont::GetRuntimeDeviceTracker().ForceDevice(vtkm::cont::DeviceAdapterTagCuda{});
(void)gpuId;
while (queue.hasTasks())
{
//Step 2. Get the task to run on cuda
auto task = queue.pop();
//Step 3. Run the task on cuda. We check the validity
//of the task since we could be given an empty task
//when the queue is empty and we are shutting down
if (task != nullptr)
{
task();
}
//Step 4. Notify the queue that we finished processing this task
queue.completedTask();
std::cout << "finished a partition on cuda (" << std::this_thread::get_id() << ")" << std::endl;
}
}
} //namespace
//-----------------------------------------------------------------------------
VTKM_CONT MultiDeviceGradient::MultiDeviceGradient()
: ComputePointGradient(false)
, Queue()
, Workers()
{
//Step 1. Determine the number of workers we want
auto& tracker = vtkm::cont::GetRuntimeDeviceTracker();
const bool runOnCuda = tracker.CanRunOn(vtkm::cont::DeviceAdapterTagCuda{});
const bool runOnOpenMP = tracker.CanRunOn(vtkm::cont::DeviceAdapterTagOpenMP{});
const bool runOnTbb = tracker.CanRunOn(vtkm::cont::DeviceAdapterTagTBB{});
//Note currently the virtual implementation has some issues
//In a multi-threaded environment only cuda can be used or
//all SMP backends ( Serial, TBB, OpenMP ).
//Once this issue is resolved we can enable CUDA + TBB in
//this example
//Step 2. Launch workers that will use cuda (if enabled).
//The threads share a queue object so we need to explicitly pass it
//by reference (the std::ref call)
if (runOnCuda)
{
std::cout << "adding cuda workers" << std::endl;
try
{
vtkm::Id gpu_count = 0;
vtkm::cont::RuntimeDeviceInformation{}
.GetRuntimeConfiguration(vtkm::cont::DeviceAdapterTagCuda{})
.GetMaxDevices(gpu_count);
for (int i = 0; i < gpu_count; ++i)
{
//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_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));
}
}
catch (const vtkm::cont::ErrorBadDevice& err)
{
VTKM_LOG_S(vtkm::cont::LogLevel::Error,
"Error getting CudaDeviceCount: " << err.GetMessage());
}
}
//Step 3. Launch a worker that will use openMP (if enabled).
//The threads share a queue object so we need to explicitly pass it
//by reference (the std::ref call)
else if (runOnOpenMP)
{
std::cout << "adding a openMP worker" << std::endl;
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
//by reference (the std::ref call)
else if (runOnTbb)
{
std::cout << "adding a tbb worker" << std::endl;
this->Workers.emplace_back(std::bind(process_partition_tbb, std::ref(this->Queue)));
}
}
//-----------------------------------------------------------------------------
VTKM_CONT MultiDeviceGradient::~MultiDeviceGradient()
{
this->Queue.shutdown();
//shutdown all workers
for (auto&& thread : this->Workers)
{
thread.join();
}
}
//-----------------------------------------------------------------------------
VTKM_CONT vtkm::cont::PartitionedDataSet MultiDeviceGradient::DoExecutePartitions(
const vtkm::cont::PartitionedDataSet& pds)
{
//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 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 partition
vtkm::filter::vector_analysis::Gradient gradient;
gradient.SetComputePointGradient(this->GetComputePointGradient());
gradient.SetActiveField(this->GetActiveFieldName());
//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 partition = pds.cbegin();
{
vtkm::cont::DataSet input = *partition;
this->Queue.push( //build a lambda that is the work to do
[=]() {
vtkm::filter::vector_analysis::Gradient perThreadGrad = gradient;
vtkm::cont::DataSet result = perThreadGrad.Execute(input);
outPtr->ReplacePartition(0, result);
});
this->Queue.waitForAllTasksToComplete();
partition++;
}
vtkm::Id index = 1;
for (; partition != pds.cend(); ++partition)
{
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
this->Queue.push( //build a lambda that is the work to do
[=]() {
vtkm::filter::vector_analysis::Gradient perThreadGrad = gradient;
vtkm::cont::DataSet result = perThreadGrad.Execute(input);
outPtr->ReplacePartition(index, result);
});
index++;
}
// Step 5. Wait on all workers to finish
this->Queue.waitForAllTasksToComplete();
return output;
}
VTKM_CONT vtkm::cont::DataSet MultiDeviceGradient::DoExecute(const vtkm::cont::DataSet& inData)
{
vtkm::cont::PartitionedDataSet outData = this->Execute(vtkm::cont::PartitionedDataSet(inData));
VTKM_ASSERT(outData.GetNumberOfPartitions() == 1);
return outData.GetPartition(0);
}

@ -10,7 +10,7 @@
#ifndef vtk_m_examples_multibackend_MultiDeviceGradient_h
#define vtk_m_examples_multibackend_MultiDeviceGradient_h
#include <vtkm/filter/FilterField.h>
#include <vtkm/filter/NewFilterField.h>
#include "TaskQueue.h"
@ -22,11 +22,9 @@ using RuntimeTaskQueue = TaskQueue<std::function<void()>>;
///
/// The Policy used with MultiDeviceGradient must include the TBB and CUDA
/// backends.
class MultiDeviceGradient : public vtkm::filter::FilterField<MultiDeviceGradient>
class MultiDeviceGradient : public vtkm::filter::NewFilterField
{
public:
using SupportedTypes = vtkm::List<vtkm::Float32, vtkm::Float64, vtkm::Vec3f_32, vtkm::Vec3f_64>;
//Construct a MultiDeviceGradient and worker pool
VTKM_CONT
MultiDeviceGradient();
@ -43,10 +41,12 @@ public:
/// Will submit each block to a work queue that the threads will
/// pull work from
template <typename DerivedPolicy>
VTKM_CONT vtkm::cont::PartitionedDataSet PrepareForExecution(
const vtkm::cont::PartitionedDataSet&,
const vtkm::filter::PolicyBase<DerivedPolicy>&);
VTKM_CONT vtkm::cont::PartitionedDataSet DoExecutePartitions(
const vtkm::cont::PartitionedDataSet& inData) override;
// All filters must override this method. Our implementation will just wrap this in
// a partitioned data set.
VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& inData) override;
private:
bool ComputePointGradient;
@ -54,10 +54,4 @@ private:
std::vector<std::thread> Workers;
};
#ifndef vtk_m_examples_multibackend_MultiDeviceGradient_cxx
extern template vtkm::cont::PartitionedDataSet MultiDeviceGradient::PrepareForExecution<
vtkm::filter::PolicyDefault>(const vtkm::cont::PartitionedDataSet&,
const vtkm::filter::PolicyBase<vtkm::filter::PolicyDefault>&);
#endif
#endif

@ -1,251 +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/Logging.h>
#include <vtkm/cont/RuntimeDeviceInformation.h>
#include <vtkm/cont/RuntimeDeviceTracker.h>
#include <vtkm/cont/cuda/DeviceAdapterCuda.h>
#include <vtkm/cont/openmp/DeviceAdapterOpenMP.h>
#include <vtkm/cont/tbb/DeviceAdapterTBB.h>
#include <vtkm/filter/vector_analysis/Gradient.h>
namespace
{
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
//task operate only on TBB. The "global" thread tracker
//is actually thread-local, so we can use that.
//
vtkm::cont::GetRuntimeDeviceTracker().ForceDevice(vtkm::cont::DeviceAdapterTagTBB{});
while (queue.hasTasks())
{
//Step 2. Get the task to run on TBB
auto task = queue.pop();
//Step 3. Run the task on TBB. We check the validity
//of the task since we could be given an empty task
//when the queue is empty and we are shutting down
if (task != nullptr)
{
task();
}
//Step 4. Notify the queue that we finished processing this task
queue.completedTask();
std::cout << "finished a partition on tbb (" << std::this_thread::get_id() << ")" << std::endl;
}
}
void process_partition_openMP(RuntimeTaskQueue& queue)
{
//Step 1. Set the device adapter to this thread to openMP.
//This makes sure that any vtkm::filters used by our
//task operate only on openMP. The "global" thread tracker
//is actually thread-local, so we can use that.
//
vtkm::cont::GetRuntimeDeviceTracker().ForceDevice(vtkm::cont::DeviceAdapterTagOpenMP{});
while (queue.hasTasks())
{
//Step 2. Get the task to run on openMP
auto task = queue.pop();
//Step 3. Run the task on openMP. We check the validity
//of the task since we could be given an empty task
//when the queue is empty and we are shutting down
if (task != nullptr)
{
task();
}
//Step 4. Notify the queue that we finished processing this task
queue.completedTask();
std::cout << "finished a partition on openMP (" << std::this_thread::get_id() << ")"
<< std::endl;
}
}
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
//task operate only on cuda. The "global" thread tracker
//is actually thread-local, so we can use that.
//
vtkm::cont::GetRuntimeDeviceTracker().ForceDevice(vtkm::cont::DeviceAdapterTagCuda{});
(void)gpuId;
while (queue.hasTasks())
{
//Step 2. Get the task to run on cuda
auto task = queue.pop();
//Step 3. Run the task on cuda. We check the validity
//of the task since we could be given an empty task
//when the queue is empty and we are shutting down
if (task != nullptr)
{
task();
}
//Step 4. Notify the queue that we finished processing this task
queue.completedTask();
std::cout << "finished a partition on cuda (" << std::this_thread::get_id() << ")" << std::endl;
}
}
} //namespace
//-----------------------------------------------------------------------------
VTKM_CONT MultiDeviceGradient::MultiDeviceGradient()
: ComputePointGradient(false)
, Queue()
, Workers()
{
//Step 1. Determine the number of workers we want
auto& tracker = vtkm::cont::GetRuntimeDeviceTracker();
const bool runOnCuda = tracker.CanRunOn(vtkm::cont::DeviceAdapterTagCuda{});
const bool runOnOpenMP = tracker.CanRunOn(vtkm::cont::DeviceAdapterTagOpenMP{});
const bool runOnTbb = tracker.CanRunOn(vtkm::cont::DeviceAdapterTagTBB{});
//Note currently the virtual implementation has some issues
//In a multi-threaded environment only cuda can be used or
//all SMP backends ( Serial, TBB, OpenMP ).
//Once this issue is resolved we can enable CUDA + TBB in
//this example
//Step 2. Launch workers that will use cuda (if enabled).
//The threads share a queue object so we need to explicitly pass it
//by reference (the std::ref call)
if (runOnCuda)
{
std::cout << "adding cuda workers" << std::endl;
try
{
vtkm::Id gpu_count = 0;
vtkm::cont::RuntimeDeviceInformation{}
.GetRuntimeConfiguration(vtkm::cont::DeviceAdapterTagCuda{})
.GetMaxDevices(gpu_count);
for (int i = 0; i < gpu_count; ++i)
{
//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_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));
}
}
catch (const vtkm::cont::ErrorBadDevice& err)
{
VTKM_LOG_S(vtkm::cont::LogLevel::Error,
"Error getting CudaDeviceCount: " << err.GetMessage());
}
}
//Step 3. Launch a worker that will use openMP (if enabled).
//The threads share a queue object so we need to explicitly pass it
//by reference (the std::ref call)
else if (runOnOpenMP)
{
std::cout << "adding a openMP worker" << std::endl;
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
//by reference (the std::ref call)
else if (runOnTbb)
{
std::cout << "adding a tbb worker" << std::endl;
this->Workers.emplace_back(std::bind(process_partition_tbb, std::ref(this->Queue)));
}
}
//-----------------------------------------------------------------------------
VTKM_CONT MultiDeviceGradient::~MultiDeviceGradient()
{
this->Queue.shutdown();
//shutdown all workers
for (auto&& thread : this->Workers)
{
thread.join();
}
}
//-----------------------------------------------------------------------------
template <typename DerivedPolicy>
inline VTKM_CONT vtkm::cont::PartitionedDataSet MultiDeviceGradient::PrepareForExecution(
const vtkm::cont::PartitionedDataSet& pds,
const vtkm::filter::PolicyBase<DerivedPolicy>&)
{
//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 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 partition
vtkm::filter::vector_analysis::Gradient gradient;
gradient.SetComputePointGradient(this->GetComputePointGradient());
gradient.SetActiveField(this->GetActiveFieldName());
//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 partition = pds.cbegin();
{
vtkm::cont::DataSet input = *partition;
this->Queue.push( //build a lambda that is the work to do
[=]() {
vtkm::filter::vector_analysis::Gradient perThreadGrad = gradient;
vtkm::cont::DataSet result = perThreadGrad.Execute(input);
outPtr->ReplacePartition(0, result);
});
this->Queue.waitForAllTasksToComplete();
partition++;
}
vtkm::Id index = 1;
for (; partition != pds.cend(); ++partition)
{
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
this->Queue.push( //build a lambda that is the work to do
[=]() {
vtkm::filter::vector_analysis::Gradient perThreadGrad = gradient;
vtkm::cont::DataSet result = perThreadGrad.Execute(input);
outPtr->ReplacePartition(index, result);
});
index++;
}
// Step 5. Wait on all workers to finish
this->Queue.waitForAllTasksToComplete();
return output;
}

@ -12,7 +12,7 @@ project(RedistributePoints CXX)
#Find the VTK-m package
find_package(VTKm REQUIRED QUIET)
add_executable(RedistributePoints RedistributePoints.cxx RedistributePoints.h)
add_executable(RedistributePoints RedistributePoints.cxx RedistributePoints.h main.cxx)
target_link_libraries(RedistributePoints PRIVATE vtkm_filter vtkm_io)
vtkm_add_target_information(RedistributePoints
DROP_UNUSED_SYMBOLS MODIFY_CUDA_FLAGS

@ -8,53 +8,228 @@
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#include <vtkm/cont/DataSet.h>
#include <vtkm/cont/EnvironmentTracker.h>
#include <vtkm/cont/Initialize.h>
#include "RedistributePoints.h"
#include <vtkm/io/VTKDataSetReader.h>
#include <vtkm/io/VTKDataSetWriter.h>
#include <vtkm/ImplicitFunction.h>
#include <vtkm/cont/Algorithm.h>
#include <vtkm/cont/AssignerPartitionedDataSet.h>
#include <vtkm/cont/BoundsGlobalCompute.h>
#include <vtkm/cont/EnvironmentTracker.h>
#include <vtkm/cont/Serialization.h>
#include <vtkm/filter/entity_extraction/ExtractPoints.h>
#include <vtkm/thirdparty/diy/diy.h>
#include "RedistributePoints.h"
#include <sstream>
using std::cout;
using std::endl;
int main(int argc, char* argv[])
namespace example
{
// Process vtk-m general args
auto opts = vtkm::cont::InitializeOptions::DefaultAnyDevice;
auto config = vtkm::cont::Initialize(argc, argv, opts);
vtkmdiy::mpi::environment env(argc, argv);
vtkmdiy::mpi::communicator comm;
vtkm::cont::EnvironmentTracker::SetCommunicator(comm);
namespace internal
{
if (argc != 3)
{
cout << "Usage: " << endl
<< "$ " << argv[0] << " [options] <input-vtk-file> <output-file-prefix>" << endl;
cout << config.Usage << endl;
return EXIT_FAILURE;
}
vtkm::cont::DataSet input;
if (comm.rank() == 0)
{
vtkm::io::VTKDataSetReader reader(argv[1]);
input = reader.ReadDataSet();
}
example::RedistributePoints redistributor;
auto output = redistributor.Execute(input);
std::ostringstream str;
str << argv[2] << "-" << comm.rank() << ".vtk";
vtkm::io::VTKDataSetWriter writer(str.str());
writer.WriteDataSet(output);
return EXIT_SUCCESS;
static vtkmdiy::ContinuousBounds convert(const vtkm::Bounds& bds)
{
vtkmdiy::ContinuousBounds result(3);
result.min[0] = static_cast<float>(bds.X.Min);
result.min[1] = static_cast<float>(bds.Y.Min);
result.min[2] = static_cast<float>(bds.Z.Min);
result.max[0] = static_cast<float>(bds.X.Max);
result.max[1] = static_cast<float>(bds.Y.Max);
result.max[2] = static_cast<float>(bds.Z.Max);
return result;
}
template <typename FilterType>
class Redistributor
{
const vtkmdiy::RegularDecomposer<vtkmdiy::ContinuousBounds>& Decomposer;
const FilterType& Filter;
vtkm::cont::DataSet Extract(const vtkm::cont::DataSet& input,
const vtkmdiy::ContinuousBounds& bds) const
{
// extract points
vtkm::Box box(bds.min[0], bds.max[0], bds.min[1], bds.max[1], bds.min[2], bds.max[2]);
vtkm::filter::entity_extraction::ExtractPoints extractor;
extractor.SetCompactPoints(true);
extractor.SetImplicitFunction(box);
return extractor.Execute(input);
}
class ConcatenateFields
{
public:
explicit ConcatenateFields(vtkm::Id totalSize)
: TotalSize(totalSize)
, CurrentIdx(0)
{
}
void Append(const vtkm::cont::Field& field)
{
VTKM_ASSERT(this->CurrentIdx + field.GetNumberOfValues() <= this->TotalSize);
if (this->Field.GetNumberOfValues() == 0)
{
// Copy metadata
this->Field = field;
// Reset array
this->Field.SetData(field.GetData().NewInstanceBasic());
// Preallocate array
this->Field.GetData().Allocate(this->TotalSize);
}
else
{
VTKM_ASSERT(this->Field.GetName() == field.GetName() &&
this->Field.GetAssociation() == field.GetAssociation());
}
field.GetData().CastAndCallForTypes<VTKM_DEFAULT_TYPE_LIST, VTKM_DEFAULT_STORAGE_LIST>(
Appender{}, this->Field, this->CurrentIdx);
this->CurrentIdx += field.GetNumberOfValues();
}
const vtkm::cont::Field& GetResult() const { return this->Field; }
private:
struct Appender
{
template <typename T, typename S>
void operator()(const vtkm::cont::ArrayHandle<T, S>& data,
vtkm::cont::Field& field,
vtkm::Id currentIdx) const
{
vtkm::cont::ArrayHandle<T> farray =
field.GetData().template AsArrayHandle<vtkm::cont::ArrayHandle<T>>();
vtkm::cont::Algorithm::CopySubRange(data, 0, data.GetNumberOfValues(), farray, currentIdx);
}
};
vtkm::Id TotalSize;
vtkm::Id CurrentIdx;
vtkm::cont::Field Field;
};
public:
Redistributor(const vtkmdiy::RegularDecomposer<vtkmdiy::ContinuousBounds>& decomposer,
const FilterType& filter)
: Decomposer(decomposer)
, Filter(filter)
{
}
void operator()(vtkm::cont::DataSet* block, const vtkmdiy::ReduceProxy& rp) const
{
if (rp.in_link().size() == 0)
{
if (block->GetNumberOfCoordinateSystems() > 0)
{
for (int cc = 0; cc < rp.out_link().size(); ++cc)
{
auto target = rp.out_link().target(cc);
// let's get the bounding box for the target block.
vtkmdiy::ContinuousBounds bds(3);
this->Decomposer.fill_bounds(bds, target.gid);
auto extractedDS = this->Extract(*block, bds);
// TODO: Need a better way to serialize DataSet. See issue #725.
rp.enqueue(target, vtkm::cont::SerializableDataSet<>(extractedDS));
}
// clear our dataset.
*block = vtkm::cont::DataSet();
}
}
else
{
vtkm::Id numValues = 0;
std::vector<vtkm::cont::DataSet> receives;
for (int cc = 0; cc < rp.in_link().size(); ++cc)
{
auto target = rp.in_link().target(cc);
if (rp.incoming(target.gid).size() > 0)
{
// TODO: Need a better way to serialize DataSet. See issue #725.
vtkm::cont::SerializableDataSet<> sds;
rp.dequeue(target.gid, sds);
receives.push_back(sds.DataSet);
numValues += receives.back().GetCoordinateSystem(0).GetNumberOfPoints();
}
}
*block = vtkm::cont::DataSet();
if (receives.size() == 1)
{
*block = receives[0];
}
else if (receives.size() > 1)
{
ConcatenateFields concatCoords(numValues);
for (const auto& ds : receives)
{
concatCoords.Append(ds.GetCoordinateSystem(0));
}
block->AddCoordinateSystem(vtkm::cont::CoordinateSystem(
concatCoords.GetResult().GetName(), concatCoords.GetResult().GetData()));
for (vtkm::IdComponent i = 0; i < receives[0].GetNumberOfFields(); ++i)
{
ConcatenateFields concatField(numValues);
for (const auto& ds : receives)
{
concatField.Append(ds.GetField(i));
}
block->AddField(concatField.GetResult());
}
}
}
}
};
} // namespace example::internal
VTKM_CONT vtkm::cont::PartitionedDataSet RedistributePoints::DoExecutePartitions(
const vtkm::cont::PartitionedDataSet& input)
{
auto comm = vtkm::cont::EnvironmentTracker::GetCommunicator();
// let's first get the global bounds of the domain
vtkm::Bounds gbounds = vtkm::cont::BoundsGlobalCompute(input);
vtkm::cont::AssignerPartitionedDataSet assigner(input.GetNumberOfPartitions());
vtkmdiy::RegularDecomposer<vtkmdiy::ContinuousBounds> decomposer(
/*dim*/ 3, internal::convert(gbounds), assigner.nblocks());
vtkmdiy::Master master(
comm,
/*threads*/ 1,
/*limit*/ -1,
[]() -> void* { return new vtkm::cont::DataSet(); },
[](void* ptr) { delete static_cast<vtkm::cont::DataSet*>(ptr); });
decomposer.decompose(comm.rank(), assigner, master);
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.GetPartition(lid);
});
internal::Redistributor<RedistributePoints> redistributor(decomposer, *this);
vtkmdiy::all_to_all(master, assigner, redistributor, /*k=*/2);
vtkm::cont::PartitionedDataSet result;
master.foreach ([&result](vtkm::cont::DataSet* ds, const vtkmdiy::Master::ProxyWithLink&) {
result.AppendPartition(*ds);
});
return result;
}
vtkm::cont::DataSet RedistributePoints::DoExecute(const vtkm::cont::DataSet&)
{
throw vtkm::cont::ErrorBadType("RedistributePoints requires PartitionedDataSet.");
}
} // namespace example

@ -7,238 +7,28 @@
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#ifndef example_RedistributePoints_h
#define example_RedistributePoints_h
#include <vtkm/ImplicitFunction.h>
#include <vtkm/cont/Algorithm.h>
#include <vtkm/cont/AssignerPartitionedDataSet.h>
#include <vtkm/cont/BoundsGlobalCompute.h>
#include <vtkm/cont/EnvironmentTracker.h>
#include <vtkm/cont/Serialization.h>
#include <vtkm/filter/Filter.h>
#include <vtkm/filter/entity_extraction/ExtractPoints.h>
#include <vtkm/thirdparty/diy/diy.h>
#include <vtkm/filter/NewFilter.h>
namespace example
{
namespace internal
{
static vtkmdiy::ContinuousBounds convert(const vtkm::Bounds& bds)
{
vtkmdiy::ContinuousBounds result(3);
result.min[0] = static_cast<float>(bds.X.Min);
result.min[1] = static_cast<float>(bds.Y.Min);
result.min[2] = static_cast<float>(bds.Z.Min);
result.max[0] = static_cast<float>(bds.X.Max);
result.max[1] = static_cast<float>(bds.Y.Max);
result.max[2] = static_cast<float>(bds.Z.Max);
return result;
}
template <typename FilterType>
class Redistributor
{
const vtkmdiy::RegularDecomposer<vtkmdiy::ContinuousBounds>& Decomposer;
const FilterType& Filter;
vtkm::cont::DataSet Extract(const vtkm::cont::DataSet& input,
const vtkmdiy::ContinuousBounds& bds) const
{
// extract points
vtkm::Box box(bds.min[0], bds.max[0], bds.min[1], bds.max[1], bds.min[2], bds.max[2]);
vtkm::filter::entity_extraction::ExtractPoints extractor;
extractor.SetCompactPoints(true);
extractor.SetImplicitFunction(box);
return extractor.Execute(input);
}
class ConcatenateFields
{
public:
explicit ConcatenateFields(vtkm::Id totalSize)
: TotalSize(totalSize)
, CurrentIdx(0)
{
}
void Append(const vtkm::cont::Field& field)
{
VTKM_ASSERT(this->CurrentIdx + field.GetNumberOfValues() <= this->TotalSize);
if (this->Field.GetNumberOfValues() == 0)
{
// Copy metadata
this->Field = field;
// Reset array
this->Field.SetData(field.GetData().NewInstanceBasic());
// Preallocate array
this->Field.GetData().Allocate(this->TotalSize);
}
else
{
VTKM_ASSERT(this->Field.GetName() == field.GetName() &&
this->Field.GetAssociation() == field.GetAssociation());
}
field.GetData().CastAndCallForTypes<VTKM_DEFAULT_TYPE_LIST, VTKM_DEFAULT_STORAGE_LIST>(
Appender{}, this->Field, this->CurrentIdx);
this->CurrentIdx += field.GetNumberOfValues();
}
const vtkm::cont::Field& GetResult() const { return this->Field; }
private:
struct Appender
{
template <typename T, typename S>
void operator()(const vtkm::cont::ArrayHandle<T, S>& data,
vtkm::cont::Field& field,
vtkm::Id currentIdx) const
{
vtkm::cont::ArrayHandle<T> farray =
field.GetData().template AsArrayHandle<vtkm::cont::ArrayHandle<T>>();
vtkm::cont::Algorithm::CopySubRange(data, 0, data.GetNumberOfValues(), farray, currentIdx);
}
};
vtkm::Id TotalSize;
vtkm::Id CurrentIdx;
vtkm::cont::Field Field;
};
public:
Redistributor(const vtkmdiy::RegularDecomposer<vtkmdiy::ContinuousBounds>& decomposer,
const FilterType& filter)
: Decomposer(decomposer)
, Filter(filter)
{
}
void operator()(vtkm::cont::DataSet* block, const vtkmdiy::ReduceProxy& rp) const
{
if (rp.in_link().size() == 0)
{
if (block->GetNumberOfCoordinateSystems() > 0)
{
for (int cc = 0; cc < rp.out_link().size(); ++cc)
{
auto target = rp.out_link().target(cc);
// let's get the bounding box for the target block.
vtkmdiy::ContinuousBounds bds(3);
this->Decomposer.fill_bounds(bds, target.gid);
auto extractedDS = this->Extract(*block, bds);
rp.enqueue(target, vtkm::filter::MakeSerializableDataSet(extractedDS, this->Filter));
}
// clear our dataset.
*block = vtkm::cont::DataSet();
}
}
else
{
vtkm::Id numValues = 0;
std::vector<vtkm::cont::DataSet> receives;
for (int cc = 0; cc < rp.in_link().size(); ++cc)
{
auto target = rp.in_link().target(cc);
if (rp.incoming(target.gid).size() > 0)
{
auto sds = vtkm::filter::MakeSerializableDataSet(this->Filter);
rp.dequeue(target.gid, sds);
receives.push_back(sds.DataSet);
numValues += receives.back().GetCoordinateSystem(0).GetNumberOfPoints();
}
}
*block = vtkm::cont::DataSet();
if (receives.size() == 1)
{
*block = receives[0];
}
else if (receives.size() > 1)
{
ConcatenateFields concatCoords(numValues);
for (const auto& ds : receives)
{
concatCoords.Append(ds.GetCoordinateSystem(0));
}
block->AddCoordinateSystem(vtkm::cont::CoordinateSystem(
concatCoords.GetResult().GetName(), concatCoords.GetResult().GetData()));
for (vtkm::IdComponent i = 0; i < receives[0].GetNumberOfFields(); ++i)
{
ConcatenateFields concatField(numValues);
for (const auto& ds : receives)
{
concatField.Append(ds.GetField(i));
}
block->AddField(concatField.GetResult());
}
}
}
}
};
} // namespace example::internal
class RedistributePoints : public vtkm::filter::Filter<RedistributePoints>
class RedistributePoints : public vtkm::filter::NewFilter
{
public:
VTKM_CONT
RedistributePoints() {}
VTKM_CONT RedistributePoints() {}
VTKM_CONT
~RedistributePoints() {}
VTKM_CONT ~RedistributePoints() {}
template <typename DerivedPolicy>
VTKM_CONT vtkm::cont::PartitionedDataSet PrepareForExecution(
const vtkm::cont::PartitionedDataSet& input,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy);
protected:
VTKM_CONT vtkm::cont::PartitionedDataSet DoExecutePartitions(
const vtkm::cont::PartitionedDataSet& input) override;
VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input) override;
};
template <typename DerivedPolicy>
inline VTKM_CONT vtkm::cont::PartitionedDataSet RedistributePoints::PrepareForExecution(
const vtkm::cont::PartitionedDataSet& input,
const vtkm::filter::PolicyBase<DerivedPolicy>&)
{
auto comm = vtkm::cont::EnvironmentTracker::GetCommunicator();
// let's first get the global bounds of the domain
vtkm::Bounds gbounds = vtkm::cont::BoundsGlobalCompute(input);
vtkm::cont::AssignerPartitionedDataSet assigner(input.GetNumberOfPartitions());
vtkmdiy::RegularDecomposer<vtkmdiy::ContinuousBounds> decomposer(
/*dim*/ 3, internal::convert(gbounds), assigner.nblocks());
vtkmdiy::Master master(
comm,
/*threads*/ 1,
/*limit*/ -1,
[]() -> void* { return new vtkm::cont::DataSet(); },
[](void* ptr) { delete static_cast<vtkm::cont::DataSet*>(ptr); });
decomposer.decompose(comm.rank(), assigner, master);
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.GetPartition(lid);
});
internal::Redistributor<RedistributePoints> redistributor(decomposer, *this);
vtkmdiy::all_to_all(master, assigner, redistributor, /*k=*/2);
vtkm::cont::PartitionedDataSet result;
master.foreach ([&result](vtkm::cont::DataSet* ds, const vtkmdiy::Master::ProxyWithLink&) {
result.AppendPartition(*ds);
});
return result;
}
} // namespace example
#endif //example_RedistributePoints_h

@ -0,0 +1,60 @@
//============================================================================
// 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/DataSet.h>
#include <vtkm/cont/EnvironmentTracker.h>
#include <vtkm/cont/Initialize.h>
#include <vtkm/io/VTKDataSetReader.h>
#include <vtkm/io/VTKDataSetWriter.h>
#include <vtkm/thirdparty/diy/diy.h>
#include "RedistributePoints.h"
#include <sstream>
using std::cout;
using std::endl;
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);
vtkmdiy::mpi::environment env(argc, argv);
vtkmdiy::mpi::communicator comm;
vtkm::cont::EnvironmentTracker::SetCommunicator(comm);
if (argc != 3)
{
cout << "Usage: " << endl
<< "$ " << argv[0] << " [options] <input-vtk-file> <output-file-prefix>" << endl;
cout << config.Usage << endl;
return EXIT_FAILURE;
}
vtkm::cont::DataSet input;
if (comm.rank() == 0)
{
vtkm::io::VTKDataSetReader reader(argv[1]);
input = reader.ReadDataSet();
}
example::RedistributePoints redistributor;
auto output = redistributor.Execute(input);
std::ostringstream str;
str << argv[2] << "-" << comm.rank() << ".vtk";
vtkm::io::VTKDataSetWriter writer(str.str());
writer.WriteDataSet(output);
return EXIT_SUCCESS;
}

@ -20,9 +20,9 @@
#include <vtkm/io/VTKDataSetReader.h>
#include <vtkm/io/VTKDataSetWriter.h>
#include <vtkm/filter/FilterDataSet.h>
#include <vtkm/filter/MapFieldMergeAverage.h>
#include <vtkm/filter/MapFieldPermutation.h>
#include <vtkm/filter/NewFilter.h>
#include <vtkm/filter/contour/Contour.h>
#include <vtkm/worklet/WorkletMapTopology.h>

@ -22,6 +22,7 @@ set(deprecated_headers
ContourTreeUniformAugmented.h
ContourTreeUniformDistributed.h
CoordinateSystemTransform.h
CreateResult.h
CrossProduct.h
DotProduct.h
Entropy.h
@ -30,6 +31,17 @@ set(deprecated_headers
ExtractPoints.h
ExtractStructured.h
FieldToColors.h
FieldMetadata.h
FilterCell.h
FilterDataSet.h
FilterDataSet.hxx
FilterDataSetWithField.h
FilterDataSetWithField.hxx
FilterField.h
FilterField.hxx
Filter.h
Filter.hxx
FilterTraits.h
GenerateIds.h
GhostCellClassify.h
GhostCellRemove.h
@ -55,6 +67,8 @@ set(deprecated_headers
PointAverage.h
PointElevation.h
PointTransform.h
PolicyBase.h
PolicyDefault.h
Probe.h
Slice.h
SplitSharpEdges.h
@ -80,30 +94,6 @@ set(deprecated_headers
vtkm_declare_headers(${deprecated_headers})
set(common_headers
CreateResult.h
FieldMetadata.h
FilterCell.h
FilterDataSet.h
FilterDataSetWithField.h
FilterField.h
Filter.h
FilterTraits.h
PolicyBase.h
PolicyDefault.h
)
vtkm_declare_headers(${common_headers})
set(common_header_template_sources
FilterDataSet.hxx
FilterDataSetWithField.hxx
FilterField.hxx
Filter.hxx
)
vtkm_declare_headers(${common_header_template_sources})
set(core_headers
FieldSelection.h
NewFilter.h

@ -31,6 +31,7 @@ namespace filter
/// Use this if you have built a \c Field object. An output
/// \c DataSet will be created by adding the field to the input.
VTKM_DEPRECATED(1.9, "Use CreateResultField method in NewFilterField.")
inline VTKM_CONT vtkm::cont::DataSet CreateResult(const vtkm::cont::DataSet& inDataSet,
const vtkm::cont::Field& field)
{
@ -45,11 +46,12 @@ inline VTKM_CONT vtkm::cont::DataSet CreateResult(const vtkm::cont::DataSet& inD
/// Use this function if you have an ArrayHandle that holds the data for
/// the field. You also need to specify a name for the field.
template <typename T, typename Storage>
inline VTKM_CONT vtkm::cont::DataSet CreateResult(
const vtkm::cont::DataSet& inDataSet,
const vtkm::cont::ArrayHandle<T, Storage>& fieldArray,
const std::string& fieldName,
const vtkm::filter::FieldMetadata& metaData)
VTKM_DEPRECATED(1.9, "Use CreateResultField method in NewFilterField.")
inline VTKM_CONT vtkm::cont::DataSet
CreateResult(const vtkm::cont::DataSet& inDataSet,
const vtkm::cont::ArrayHandle<T, Storage>& fieldArray,
const std::string& fieldName,
const vtkm::filter::FieldMetadata& metaData)
{
VTKM_ASSERT(!fieldName.empty());
@ -64,6 +66,7 @@ inline VTKM_CONT vtkm::cont::DataSet CreateResult(
/// Use this function if you have a UnknownArrayHandle that holds the data
/// for the field.
VTKM_DEPRECATED(1.9, "Use CreateResultField method in NewFilterField.")
inline VTKM_CONT vtkm::cont::DataSet CreateResult(const vtkm::cont::DataSet& inDataSet,
const vtkm::cont::UnknownArrayHandle& fieldArray,
const std::string& fieldName,
@ -83,10 +86,11 @@ inline VTKM_CONT vtkm::cont::DataSet CreateResult(const vtkm::cont::DataSet& inD
/// Use this function if you want to explicit construct a Cell field and have a ArrayHandle
/// that holds the data for the field.
template <typename T, typename Storage>
inline VTKM_CONT vtkm::cont::DataSet CreateResultFieldCell(
const vtkm::cont::DataSet& inDataSet,
const vtkm::cont::ArrayHandle<T, Storage>& fieldArray,
const std::string& fieldName)
VTKM_DEPRECATED(1.9, "Use CreateResultFieldCell method in NewFilterField.")
inline VTKM_CONT vtkm::cont::DataSet
CreateResultFieldCell(const vtkm::cont::DataSet& inDataSet,
const vtkm::cont::ArrayHandle<T, Storage>& fieldArray,
const std::string& fieldName)
{
VTKM_ASSERT(!fieldName.empty());
@ -101,6 +105,7 @@ inline VTKM_CONT vtkm::cont::DataSet CreateResultFieldCell(
/// Use this function if you want to explicit construct a Cell field and have a UnknownArrayHandle
/// that holds the data for the field.
VTKM_DEPRECATED(1.9, "Use CreateResultFieldCell method in NewFilterField.")
inline VTKM_CONT vtkm::cont::DataSet CreateResultFieldCell(
const vtkm::cont::DataSet& inDataSet,
const vtkm::cont::UnknownArrayHandle& fieldArray,
@ -120,10 +125,11 @@ inline VTKM_CONT vtkm::cont::DataSet CreateResultFieldCell(
/// Use this function if you want to explicit construct a Point field and have a ArrayHandle
/// that holds the data for the field.
template <typename T, typename Storage>
inline VTKM_CONT vtkm::cont::DataSet CreateResultFieldPoint(
const vtkm::cont::DataSet& inDataSet,
const vtkm::cont::ArrayHandle<T, Storage>& fieldArray,
const std::string& fieldName)
VTKM_DEPRECATED(1.9, "Use CreateResultFieldPoint method in NewFilterField.")
inline VTKM_CONT vtkm::cont::DataSet
CreateResultFieldPoint(const vtkm::cont::DataSet& inDataSet,
const vtkm::cont::ArrayHandle<T, Storage>& fieldArray,
const std::string& fieldName)
{
VTKM_ASSERT(!fieldName.empty());
@ -138,6 +144,7 @@ inline VTKM_CONT vtkm::cont::DataSet CreateResultFieldPoint(
/// Use this function if you want to explicit construct a Point field and have a UnknownArrayHandle
/// that holds the data for the field.
VTKM_DEPRECATED(1.9, "Use CreateResultFieldCell method in NewFilterField.")
inline VTKM_CONT vtkm::cont::DataSet CreateResultFieldPoint(
const vtkm::cont::DataSet& inDataSet,
const vtkm::cont::UnknownArrayHandle& fieldArray,

@ -19,7 +19,7 @@ namespace vtkm
namespace filter
{
class FieldMetadata
class VTKM_DEPRECATED(1.9) FieldMetadata
{
public:
VTKM_CONT

@ -10,6 +10,8 @@
#ifndef vtk_m_filter_Filter_h
#define vtk_m_filter_Filter_h
#include <vtkm/Deprecated.h>
#include <vtkm/cont/CoordinateSystem.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/cont/ErrorExecution.h>
@ -171,7 +173,7 @@ namespace filter
/// partition.
///
template <typename Derived>
class Filter
class VTKM_DEPRECATED(1.9, "Use vtkm::filter::NewFilter.") Filter
{
public:
VTKM_CONT

@ -18,9 +18,11 @@ namespace vtkm
namespace filter
{
VTKM_DEPRECATED_SUPPRESS_BEGIN
template <class Derived>
using FilterCell VTKM_DEPRECATED(1.6, "Use FilterField instead of FilterCell.") =
vtkm::filter::FilterField<Derived>;
VTKM_DEPRECATED_SUPPRESS_END
}
}
#endif // vtk_m_filter_CellFilter_h

@ -24,8 +24,10 @@ namespace vtkm
namespace filter
{
VTKM_DEPRECATED_SUPPRESS_BEGIN
template <class Derived>
class FilterDataSet : public vtkm::filter::Filter<Derived>
class VTKM_DEPRECATED(1.9, "Use vtkm::filter::NewFilter.") FilterDataSet
: public vtkm::filter::Filter<Derived>
{
public:
VTKM_CONT
@ -67,6 +69,7 @@ private:
friend class vtkm::filter::Filter<Derived>;
};
VTKM_DEPRECATED_SUPPRESS_END
}
} // namespace vtkm::filter

@ -24,8 +24,10 @@ namespace vtkm
namespace filter
{
VTKM_DEPRECATED_SUPPRESS_BEGIN
template <class Derived>
class FilterDataSetWithField : public vtkm::filter::Filter<Derived>
class VTKM_DEPRECATED(1.9, "Use vtkm::filter::NewFilterField.") FilterDataSetWithField
: public vtkm::filter::Filter<Derived>
{
public:
VTKM_CONT
@ -109,6 +111,7 @@ private:
friend class vtkm::filter::Filter<Derived>;
};
VTKM_DEPRECATED_SUPPRESS_END
}
} // namespace vtkm::filter

@ -24,8 +24,10 @@ namespace vtkm
namespace filter
{
VTKM_DEPRECATED_SUPPRESS_BEGIN
template <class Derived>
class FilterField : public vtkm::filter::Filter<Derived>
class VTKM_DEPRECATED(1.9, "Use vtkm::filter::NewFilterField.") FilterField
: public vtkm::filter::Filter<Derived>
{
public:
VTKM_CONT
@ -112,6 +114,7 @@ private:
friend class vtkm::filter::Filter<Derived>;
};
VTKM_DEPRECATED_SUPPRESS_END
}
} // namespace vtkm::filter

@ -11,6 +11,7 @@
#ifndef vtk_m_filter_FilterTraits_h
#define vtk_m_filter_FilterTraits_h
#include <vtkm/Deprecated.h>
#include <vtkm/List.h>
namespace vtkm
@ -23,21 +24,21 @@ class Filter;
template <typename Filter>
struct FilterTraits
struct VTKM_DEPRECATED(1.9) FilterTraits
{
using InputFieldTypeList = typename Filter::SupportedTypes;
using AdditionalFieldStorage = typename Filter::AdditionalFieldStorage;
};
template <typename DerivedPolicy, typename ListOfTypes>
struct DeduceFilterFieldTypes
struct VTKM_DEPRECATED(1.9) DeduceFilterFieldTypes
{
using PList = typename DerivedPolicy::FieldTypeList;
using TypeList = vtkm::ListIntersect<ListOfTypes, PList>;
};
template <typename DerivedPolicy, typename ListOfStorage>
struct DeduceFilterFieldStorage
struct VTKM_DEPRECATED(1.9) DeduceFilterFieldStorage
{
using PList = typename DerivedPolicy::StorageList;
using StorageList = vtkm::ListAppend<ListOfStorage, PList>;

@ -10,7 +10,6 @@
#include <vtkm/cont/Logging.h>
#include <vtkm/filter/MapFieldMergeAverage.h>
#include <vtkm/filter/PolicyDefault.h>
#include <vtkm/worklet/AverageByKey.h>
namespace

@ -11,6 +11,7 @@
#ifndef vtk_m_filter_PolicyBase_h
#define vtk_m_filter_PolicyBase_h
#include <vtkm/Deprecated.h>
#include <vtkm/List.h>
#include <vtkm/cont/CellSetList.h>
@ -31,7 +32,7 @@ namespace filter
{
template <typename Derived>
struct PolicyBase
struct VTKM_DEPRECATED(1.9) PolicyBase
{
using FieldTypeList = vtkm::ListUniversal;
using StorageList = VTKM_DEFAULT_STORAGE_LIST;
@ -215,13 +216,15 @@ using ArrayHandleMultiplexerForStorageList = vtkm::cont::ArrayHandleMultiplexerF
/// passed to the `DoMapField` method of filters.
///
template <typename DerivedPolicy>
VTKM_DEPRECATED(1.9)
VTKM_CONT vtkm::cont::UncertainArrayHandle<
typename std::conditional<
std::is_same<typename DerivedPolicy::FieldTypeList, vtkm::ListUniversal>::value,
VTKM_DEFAULT_TYPE_LIST,
typename DerivedPolicy::FieldTypeList>::type,
typename DerivedPolicy::StorageList>
ApplyPolicyFieldNotActive(const vtkm::cont::Field& field, vtkm::filter::PolicyBase<DerivedPolicy>)
typename DerivedPolicy::StorageList> ApplyPolicyFieldNotActive(const vtkm::cont::Field& field,
vtkm::filter::PolicyBase<
DerivedPolicy>)
{
// Policies are on their way out, but until they are we want to respect them. In the mean
// time, respect the policy if it is defined.
@ -239,13 +242,14 @@ ApplyPolicyFieldNotActive(const vtkm::cont::Field& field, vtkm::filter::PolicyBa
/// (more likely) there is a type you are going to cast it to anyway.
///
template <typename T, typename DerivedPolicy, typename FilterType>
VTKM_DEPRECATED(1.9)
VTKM_CONT internal::ArrayHandleMultiplexerForStorageList<
T,
vtkm::ListAppend<typename vtkm::filter::FilterTraits<FilterType>::AdditionalFieldStorage,
typename DerivedPolicy::StorageList>>
ApplyPolicyFieldOfType(const vtkm::cont::Field& field,
vtkm::filter::PolicyBase<DerivedPolicy>,
const FilterType&)
typename DerivedPolicy::
StorageList>> ApplyPolicyFieldOfType(const vtkm::cont::Field& field,
vtkm::filter::PolicyBase<DerivedPolicy>,
const FilterType&)
{
using ArrayHandleMultiplexerType = internal::ArrayHandleMultiplexerForStorageList<
T,
@ -261,16 +265,17 @@ ApplyPolicyFieldOfType(const vtkm::cont::Field& field,
/// the active field of this filter.
///
template <typename DerivedPolicy, typename FilterType>
VTKM_DEPRECATED(1.9)
VTKM_CONT vtkm::cont::UncertainArrayHandle<
typename vtkm::filter::DeduceFilterFieldTypes<
DerivedPolicy,
typename vtkm::filter::FilterTraits<FilterType>::InputFieldTypeList>::TypeList,
typename vtkm::filter::DeduceFilterFieldStorage<
DerivedPolicy,
typename vtkm::filter::FilterTraits<FilterType>::AdditionalFieldStorage>::StorageList>
ApplyPolicyFieldActive(const vtkm::cont::Field& field,
vtkm::filter::PolicyBase<DerivedPolicy>,
vtkm::filter::FilterTraits<FilterType>)
typename vtkm::filter::FilterTraits<FilterType>::AdditionalFieldStorage>::
StorageList> ApplyPolicyFieldActive(const vtkm::cont::Field& field,
vtkm::filter::PolicyBase<DerivedPolicy>,
vtkm::filter::FilterTraits<FilterType>)
{
using FilterTypes = typename vtkm::filter::FilterTraits<FilterType>::InputFieldTypeList;
using TypeList =
@ -287,11 +292,13 @@ ApplyPolicyFieldActive(const vtkm::cont::Field& field,
/// Adjusts the types of `CellSet`s to support those types specified in a policy.
///
template <typename DerivedPolicy, typename DerivedFilter>
VTKM_CONT vtkm::cont::UncertainCellSet<vtkm::ListAppend<typename DerivedFilter::SupportedCellSets,
typename DerivedPolicy::AllCellSetList>>
ApplyPolicyCellSet(const vtkm::cont::UnknownCellSet& cellset,
vtkm::filter::PolicyBase<DerivedPolicy>,
const vtkm::filter::Filter<DerivedFilter>&)
VTKM_DEPRECATED(1.9)
VTKM_CONT vtkm::cont::UncertainCellSet<
vtkm::ListAppend<typename DerivedFilter::SupportedCellSets,
typename DerivedPolicy::
AllCellSetList>> ApplyPolicyCellSet(const vtkm::cont::UnknownCellSet& cellset,
vtkm::filter::PolicyBase<DerivedPolicy>,
const vtkm::filter::Filter<DerivedFilter>&)
{
using CellSetList = vtkm::ListAppend<typename DerivedFilter::SupportedCellSets,
typename DerivedPolicy::AllCellSetList>;
@ -315,12 +322,13 @@ VTKM_CONT vtkm::cont::UncertainCellSet<typename DerivedPolicy::AllCellSetList> A
/// specified in a policy.
///
template <typename DerivedPolicy, typename DerivedFilter>
VTKM_CONT
vtkm::cont::UncertainCellSet<vtkm::ListAppend<typename DerivedFilter::SupportedStructuredCellSets,
typename DerivedPolicy::StructuredCellSetList>>
ApplyPolicyCellSetStructured(const vtkm::cont::UnknownCellSet& cellset,
vtkm::filter::PolicyBase<DerivedPolicy>,
const vtkm::filter::Filter<DerivedFilter>&)
VTKM_DEPRECATED(1.9)
VTKM_CONT vtkm::cont::UncertainCellSet<vtkm::ListAppend<
typename DerivedFilter::SupportedStructuredCellSets,
typename DerivedPolicy::
StructuredCellSetList>> ApplyPolicyCellSetStructured(const vtkm::cont::UnknownCellSet& cellset,
vtkm::filter::PolicyBase<DerivedPolicy>,
const vtkm::filter::Filter<DerivedFilter>&)
{
using CellSetList = vtkm::ListAppend<typename DerivedFilter::SupportedStructuredCellSets,
typename DerivedPolicy::StructuredCellSetList>;
@ -345,12 +353,16 @@ VTKM_CONT vtkm::cont::
/// specified in a policy.
///
template <typename DerivedPolicy, typename DerivedFilter>
VTKM_CONT vtkm::cont::UncertainCellSet<
vtkm::ListAppend<typename DerivedFilter::SupportedUnstructuredCellSets,
typename DerivedPolicy::UnstructuredCellSetList>>
ApplyPolicyCellSetUnstructured(const vtkm::cont::UnknownCellSet& cellset,
vtkm::filter::PolicyBase<DerivedPolicy>,
const vtkm::filter::Filter<DerivedFilter>&)
VTKM_DEPRECATED(1.9)
VTKM_CONT vtkm::cont::UncertainCellSet<vtkm::ListAppend<
typename DerivedFilter::SupportedUnstructuredCellSets,
typename DerivedPolicy::
UnstructuredCellSetList>> ApplyPolicyCellSetUnstructured(const vtkm::cont::UnknownCellSet&
cellset,
vtkm::filter::PolicyBase<
DerivedPolicy>,
const vtkm::filter::Filter<
DerivedFilter>&)
{
using CellSetList = vtkm::ListAppend<typename DerivedFilter::SupportedUnstructuredCellSets,
typename DerivedPolicy::UnstructuredCellSetList>;
@ -400,21 +412,27 @@ VTKM_CONT vtkm::cont::SerializableDataSet<
return {};
}
// TODO: Make DataSet serializable (issue #725).
template <typename DerivedPolicy, typename DerivedFilter>
VTKM_CONT
vtkm::cont::SerializableDataSet<typename DerivedPolicy::FieldTypeList,
vtkm::ListAppend<typename DerivedFilter::SupportedCellSets,
typename DerivedPolicy::AllCellSetList>>
MakeSerializableDataSet(vtkm::filter::PolicyBase<DerivedPolicy>,
const vtkm::filter::Filter<DerivedFilter>&)
VTKM_DEPRECATED(1.9)
VTKM_CONT vtkm::cont::SerializableDataSet<
typename DerivedPolicy::FieldTypeList,
vtkm::ListAppend<
typename DerivedFilter::SupportedCellSets,
typename DerivedPolicy::AllCellSetList>> MakeSerializableDataSet(vtkm::filter::
PolicyBase<DerivedPolicy>,
const vtkm::filter::Filter<
DerivedFilter>&)
{
return {};
}
template <typename DerivedFilter>
VTKM_CONT
vtkm::cont::SerializableDataSet<VTKM_DEFAULT_TYPE_LIST, typename DerivedFilter::SupportedCellSets>
MakeSerializableDataSet(const vtkm::filter::Filter<DerivedFilter>&)
VTKM_DEPRECATED(1.9)
VTKM_CONT vtkm::cont::SerializableDataSet<
VTKM_DEFAULT_TYPE_LIST,
typename DerivedFilter::SupportedCellSets> MakeSerializableDataSet(const vtkm::filter::
Filter<DerivedFilter>&)
{
return {};
}
@ -433,13 +451,15 @@ VTKM_CONT vtkm::cont::SerializableDataSet<
}
template <typename DerivedPolicy, typename DerivedFilter>
VTKM_CONT
vtkm::cont::SerializableDataSet<typename DerivedPolicy::FieldTypeList,
vtkm::ListAppend<typename DerivedFilter::SupportedCellSets,
typename DerivedPolicy::AllCellSetList>>
MakeSerializableDataSet(const vtkm::cont::DataSet& dataset,
vtkm::filter::PolicyBase<DerivedPolicy>,
const vtkm::filter::Filter<DerivedFilter>&)
VTKM_DEPRECATED(1.9)
VTKM_CONT vtkm::cont::SerializableDataSet<
typename DerivedPolicy::FieldTypeList,
vtkm::ListAppend<
typename DerivedFilter::SupportedCellSets,
typename DerivedPolicy::
AllCellSetList>> MakeSerializableDataSet(const vtkm::cont::DataSet& dataset,
vtkm::filter::PolicyBase<DerivedPolicy>,
const vtkm::filter::Filter<DerivedFilter>&)
{
return vtkm::cont::SerializableDataSet<typename DerivedPolicy::FieldTypeList,
vtkm::ListAppend<typename DerivedFilter::SupportedCellSets,
@ -449,10 +469,13 @@ VTKM_CONT
}
template <typename DerivedFilter>
VTKM_CONT
vtkm::cont::SerializableDataSet<VTKM_DEFAULT_TYPE_LIST, typename DerivedFilter::SupportedCellSets>
MakeSerializableDataSet(const vtkm::cont::DataSet& dataset,
const vtkm::filter::Filter<DerivedFilter>&)
VTKM_DEPRECATED(1.9)
VTKM_CONT vtkm::cont::SerializableDataSet<
VTKM_DEFAULT_TYPE_LIST,
typename DerivedFilter::SupportedCellSets> MakeSerializableDataSet(const vtkm::cont::DataSet&
dataset,
const vtkm::filter::Filter<
DerivedFilter>&)
{
return vtkm::cont::SerializableDataSet<VTKM_DEFAULT_TYPE_LIST,
typename DerivedFilter::SupportedCellSets>{ dataset };

@ -18,7 +18,7 @@ namespace vtkm
namespace filter
{
struct PolicyDefault : vtkm::filter::PolicyBase<PolicyDefault>
struct VTKM_DEPRECATED(1.9) PolicyDefault : vtkm::filter::PolicyBase<PolicyDefault>
{
// Inherit defaults from PolicyBase
};

@ -1,3 +1,4 @@
##============================================================================
## Copyright (c) Kitware, Inc.
## All rights reserved.
@ -8,9 +9,9 @@
## PURPOSE. See the above copyright notice for more information.
##============================================================================
set(headers
set(deprecated_headers
ResolveFieldTypeAndExecute.h
ResolveFieldTypeAndMap.h
)
vtkm_declare_headers(${headers})
vtkm_declare_headers(${deprecated_headers})

@ -11,6 +11,7 @@
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/filter/FieldMetadata.h>
VTKM_DEPRECATED_SUPPRESS_BEGIN
namespace
{
@ -77,3 +78,4 @@ int UnitTestFieldMetadata(int argc, char* argv[])
{
return vtkm::cont::testing::Testing::Run(TestFieldMetadata, argc, argv);
}
VTKM_DEPRECATED_SUPPRESS_END