Make locator exec objects not depend on device type

With recent changes to `ArrayHandle`, the type for the associated array
portal is now the same across all devices. This means that almost all
exec objects no longer need to be specialized on the device types. Thus,
clean up the locator exec objects to no longer need to be templated on
device.
This commit is contained in:
Kenneth Moreland 2021-02-09 17:20:57 -07:00
parent 6232670049
commit c62e38bab6
11 changed files with 93 additions and 205 deletions

@ -449,48 +449,26 @@ void CellLocatorBoundingIntervalHierarchy::Build()
namespace
{
struct CellLocatorBIHPrepareForExecutionFunctor
struct BIHCellSetCaster
{
template <typename DeviceAdapter, typename CellSetType>
bool operator()(
DeviceAdapter,
template <typename CellSetType>
void operator()(
const CellSetType& cellset,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token,
vtkm::cont::VirtualObjectHandle<vtkm::exec::CellLocator>& bihExec,
const vtkm::cont::ArrayHandle<vtkm::exec::CellLocatorBoundingIntervalHierarchyNode>& nodes,
const vtkm::cont::ArrayHandle<vtkm::Id>& processedCellIds,
const vtkm::cont::CoordinateSystem::MultiplexerArrayType& coords) const
{
using ExecutionType =
vtkm::exec::CellLocatorBoundingIntervalHierarchyExec<DeviceAdapter, CellSetType>;
using ExecutionType = vtkm::exec::CellLocatorBoundingIntervalHierarchyExec<CellSetType>;
ExecutionType* execObject =
new ExecutionType(nodes, processedCellIds, cellset, coords, DeviceAdapter(), token);
new ExecutionType(nodes, processedCellIds, cellset, coords, device, token);
bihExec.Reset(execObject);
return true;
}
};
struct BIHCellSetCaster
{
template <typename CellSet, typename... Args>
void operator()(CellSet&& cellset,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token,
Args&&... args) const
{
//We need to go though CastAndCall first
const bool success = vtkm::cont::TryExecuteOnDevice(device,
CellLocatorBIHPrepareForExecutionFunctor(),
cellset,
token,
std::forward<Args>(args)...);
if (!success)
{
throwFailedRuntimeDeviceTransfer("BoundingIntervalHierarchy", device);
}
}
};
}
} // anonymous namespace
const vtkm::exec::CellLocator* CellLocatorBoundingIntervalHierarchy::PrepareForExecution(

@ -59,59 +59,33 @@ void CellLocatorRectilinearGrid::Build()
}
}
namespace
{
template <vtkm::IdComponent dimensions>
struct CellLocatorRectilinearGridPrepareForExecutionFunctor
{
template <typename DeviceAdapter, typename... Args>
VTKM_CONT bool operator()(DeviceAdapter,
vtkm::cont::VirtualObjectHandle<vtkm::exec::CellLocator>& execLocator,
vtkm::cont::Token& token,
Args&&... args) const
{
using ExecutionType = vtkm::exec::CellLocatorRectilinearGrid<DeviceAdapter, dimensions>;
ExecutionType* execObject =
new ExecutionType(std::forward<Args>(args)..., DeviceAdapter(), token);
execLocator.Reset(execObject);
return true;
}
};
}
const vtkm::exec::CellLocator* CellLocatorRectilinearGrid::PrepareForExecution(
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token) const
{
bool success = false;
if (this->Is3D)
{
success = vtkm::cont::TryExecuteOnDevice(
device,
CellLocatorRectilinearGridPrepareForExecutionFunctor<3>(),
this->ExecutionObjectHandle,
token,
this->PlaneSize,
this->RowSize,
this->GetCellSet().template Cast<Structured3DType>(),
this->GetCoordinates().GetData().template AsArrayHandle<RectilinearType>());
using ExecutionType = vtkm::exec::CellLocatorRectilinearGrid<3>;
ExecutionType* execObject =
new ExecutionType(this->PlaneSize,
this->RowSize,
this->GetCellSet().Cast<Structured3DType>(),
this->GetCoordinates().GetData().AsArrayHandle<RectilinearType>(),
device,
token);
this->ExecutionObjectHandle.Reset(execObject);
}
else
{
success = vtkm::cont::TryExecuteOnDevice(
device,
CellLocatorRectilinearGridPrepareForExecutionFunctor<2>(),
this->ExecutionObjectHandle,
token,
this->PlaneSize,
this->RowSize,
this->GetCellSet().template Cast<Structured2DType>(),
this->GetCoordinates().GetData().template AsArrayHandle<RectilinearType>());
}
if (!success)
{
throwFailedRuntimeDeviceTransfer("CellLocatorRectilinearGrid", device);
using ExecutionType = vtkm::exec::CellLocatorRectilinearGrid<2>;
ExecutionType* execObject =
new ExecutionType(this->PlaneSize,
this->RowSize,
this->GetCellSet().Cast<Structured2DType>(),
this->GetCoordinates().GetData().AsArrayHandle<RectilinearType>(),
device,
token);
this->ExecutionObjectHandle.Reset(execObject);
}
return this->ExecutionObjectHandle.PrepareForExecution(device, token);
}

@ -457,46 +457,31 @@ VTKM_CONT void CellLocatorTwoLevel::Build()
//----------------------------------------------------------------------------
struct CellLocatorTwoLevel::MakeExecObject
{
template <typename CellSetType, typename DeviceAdapter>
template <typename CellSetType>
VTKM_CONT void operator()(const CellSetType& cellSet,
DeviceAdapter,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token,
const CellLocatorTwoLevel& self) const
{
auto execObject =
new vtkm::exec::CellLocatorTwoLevel<CellSetType, DeviceAdapter>(self.TopLevel,
self.LeafDimensions,
self.LeafStartIndex,
self.CellStartIndex,
self.CellCount,
self.CellIds,
cellSet,
self.GetCoordinates(),
token);
auto execObject = new vtkm::exec::CellLocatorTwoLevel<CellSetType>(self.TopLevel,
self.LeafDimensions,
self.LeafStartIndex,
self.CellStartIndex,
self.CellCount,
self.CellIds,
cellSet,
self.GetCoordinates(),
device,
token);
self.ExecutionObjectHandle.Reset(execObject);
}
};
struct CellLocatorTwoLevel::PrepareForExecutionFunctor
{
template <typename DeviceAdapter>
VTKM_CONT bool operator()(DeviceAdapter,
vtkm::cont::Token& token,
const CellLocatorTwoLevel& self) const
{
self.GetCellSet().CastAndCall(MakeExecObject{}, DeviceAdapter{}, token, self);
return true;
}
};
VTKM_CONT const vtkm::exec::CellLocator* CellLocatorTwoLevel::PrepareForExecution(
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token) const
{
if (!vtkm::cont::TryExecuteOnDevice(device, PrepareForExecutionFunctor(), token, *this))
{
throwFailedRuntimeDeviceTransfer("CellLocatorTwoLevel", device);
}
this->GetCellSet().CastAndCall(MakeExecObject{}, device, token, *this);
return this->ExecutionObjectHandle.PrepareForExecution(device, token);
}

@ -85,7 +85,6 @@ private:
mutable vtkm::cont::VirtualObjectHandle<vtkm::exec::CellLocator> ExecutionObjectHandle;
struct MakeExecObject;
struct PrepareForExecutionFunctor;
};
}
} // vtkm::cont

@ -73,54 +73,23 @@ void CellLocatorUniformGrid::Build()
this->CellDims[2] = this->PointDims[2] - 1;
}
namespace
{
template <vtkm::IdComponent dimensions>
struct CellLocatorUniformGridPrepareForExecutionFunctor
{
template <typename DeviceAdapter, typename... Args>
VTKM_CONT bool operator()(DeviceAdapter,
vtkm::cont::VirtualObjectHandle<vtkm::exec::CellLocator>& execLocator,
Args&&... args) const
{
using ExecutionType = vtkm::exec::CellLocatorUniformGrid<DeviceAdapter, dimensions>;
ExecutionType* execObject = new ExecutionType(std::forward<Args>(args)..., DeviceAdapter());
execLocator.Reset(execObject);
return true;
}
};
}
const vtkm::exec::CellLocator* CellLocatorUniformGrid::PrepareForExecution(
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token) const
{
bool success = true;
if (this->Is3D)
{
success = vtkm::cont::TryExecuteOnDevice(device,
CellLocatorUniformGridPrepareForExecutionFunctor<3>(),
this->ExecutionObjectHandle,
this->CellDims,
this->PointDims,
this->Origin,
this->InvSpacing,
this->MaxPoint);
using ExecutionType = vtkm::exec::CellLocatorUniformGrid<3>;
ExecutionType* execObject = new ExecutionType(
this->CellDims, this->PointDims, this->Origin, this->InvSpacing, this->MaxPoint);
this->ExecutionObjectHandle.Reset(execObject);
}
else
{
success = vtkm::cont::TryExecuteOnDevice(device,
CellLocatorUniformGridPrepareForExecutionFunctor<2>(),
this->ExecutionObjectHandle,
this->CellDims,
this->PointDims,
this->Origin,
this->InvSpacing,
this->MaxPoint);
}
if (!success)
{
throwFailedRuntimeDeviceTransfer("CellLocatorUniformGrid", device);
using ExecutionType = vtkm::exec::CellLocatorUniformGrid<2>;
ExecutionType* execObject = new ExecutionType(
this->CellDims, this->PointDims, this->Origin, this->InvSpacing, this->MaxPoint);
this->ExecutionObjectHandle.Reset(execObject);
}
return this->ExecutionObjectHandle.PrepareForExecution(device, token);
}

@ -98,45 +98,26 @@ void PointLocatorSparseGrid::Build()
vtkm::cont::Algorithm::LowerBounds(cellIds, cell_ids_counting, this->CellLower);
}
struct PointLocatorSparseGrid::PrepareExecutionObjectFunctor
{
template <typename DeviceAdapter>
VTKM_CONT bool operator()(DeviceAdapter,
const vtkm::cont::PointLocatorSparseGrid& self,
ExecutionObjectHandleType& handle,
vtkm::cont::Token& token) const
{
auto rmin = vtkm::make_Vec(static_cast<vtkm::FloatDefault>(self.Range[0].Min),
static_cast<vtkm::FloatDefault>(self.Range[1].Min),
static_cast<vtkm::FloatDefault>(self.Range[2].Min));
auto rmax = vtkm::make_Vec(static_cast<vtkm::FloatDefault>(self.Range[0].Max),
static_cast<vtkm::FloatDefault>(self.Range[1].Max),
static_cast<vtkm::FloatDefault>(self.Range[2].Max));
vtkm::exec::PointLocatorSparseGrid<DeviceAdapter>* h =
new vtkm::exec::PointLocatorSparseGrid<DeviceAdapter>(
rmin,
rmax,
self.Dims,
self.GetCoordinates().GetDataAsMultiplexer().PrepareForInput(DeviceAdapter(), token),
self.PointIds.PrepareForInput(DeviceAdapter(), token),
self.CellLower.PrepareForInput(DeviceAdapter(), token),
self.CellUpper.PrepareForInput(DeviceAdapter(), token));
handle.Reset(h);
return true;
}
};
VTKM_CONT void PointLocatorSparseGrid::PrepareExecutionObject(
ExecutionObjectHandleType& execObjHandle,
vtkm::cont::DeviceAdapterId deviceId,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token) const
{
const bool success = vtkm::cont::TryExecuteOnDevice(
deviceId, PrepareExecutionObjectFunctor(), *this, execObjHandle, token);
if (!success)
{
throwFailedRuntimeDeviceTransfer("PointLocatorSparseGrid", deviceId);
}
auto rmin = vtkm::make_Vec(static_cast<vtkm::FloatDefault>(this->Range[0].Min),
static_cast<vtkm::FloatDefault>(this->Range[1].Min),
static_cast<vtkm::FloatDefault>(this->Range[2].Min));
auto rmax = vtkm::make_Vec(static_cast<vtkm::FloatDefault>(this->Range[0].Max),
static_cast<vtkm::FloatDefault>(this->Range[1].Max),
static_cast<vtkm::FloatDefault>(this->Range[2].Max));
vtkm::exec::PointLocatorSparseGrid* h = new vtkm::exec::PointLocatorSparseGrid(
rmin,
rmax,
this->Dims,
this->GetCoordinates().GetDataAsMultiplexer().PrepareForInput(device, token),
this->PointIds.PrepareForInput(device, token),
this->CellLower.PrepareForInput(device, token),
this->CellUpper.PrepareForInput(device, token));
execObjHandle.Reset(h);
}
}
} // vtkm::cont

@ -61,7 +61,7 @@ struct CellLocatorBoundingIntervalHierarchyNode
}
}; // struct CellLocatorBoundingIntervalHierarchyNode
template <typename DeviceAdapter, typename CellSetType>
template <typename CellSetType>
class VTKM_ALWAYS_EXPORT CellLocatorBoundingIntervalHierarchyExec final
: public vtkm::exec::CellLocator
{
@ -79,12 +79,12 @@ public:
const CellIdArrayHandle& cellIds,
const CellSetType& cellSet,
const vtkm::cont::CoordinateSystem::MultiplexerArrayType& coords,
DeviceAdapter,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
: Nodes(nodes.PrepareForInput(DeviceAdapter(), token))
, CellIds(cellIds.PrepareForInput(DeviceAdapter(), token))
, CellSet(cellSet.PrepareForInput(DeviceAdapter(), VisitType(), IncidentType(), token))
, Coords(coords.PrepareForInput(DeviceAdapter(), token))
: Nodes(nodes.PrepareForInput(device, token))
, CellIds(cellIds.PrepareForInput(device, token))
, CellSet(cellSet.PrepareForInput(device, VisitType(), IncidentType(), token))
, Coords(coords.PrepareForInput(device, token))
{
}

@ -15,6 +15,7 @@
#include <vtkm/Types.h>
#include <vtkm/VecFromPortalPermute.h>
#include <vtkm/cont/ArrayHandleCartesianProduct.h>
#include <vtkm/cont/CellSetStructured.h>
#include <vtkm/exec/CellInside.h>
@ -28,7 +29,7 @@ namespace vtkm
namespace exec
{
template <typename DeviceAdapter, vtkm::IdComponent dimensions>
template <vtkm::IdComponent dimensions>
class VTKM_ALWAYS_EXPORT CellLocatorRectilinearGrid final : public vtkm::exec::CellLocator
{
private:
@ -48,12 +49,12 @@ public:
const vtkm::Id rowSize,
const vtkm::cont::CellSetStructured<dimensions>& cellSet,
const RectilinearType& coords,
DeviceAdapter,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
: PlaneSize(planeSize)
, RowSize(rowSize)
, CellSet(cellSet.PrepareForInput(DeviceAdapter(), VisitType(), IncidentType(), token))
, Coords(coords.PrepareForInput(DeviceAdapter(), token))
, CellSet(cellSet.PrepareForInput(device, VisitType(), IncidentType(), token))
, Coords(coords.PrepareForInput(device, token))
, PointDimensions(cellSet.GetPointDimensions())
{
this->AxisPortals[0] = this->Coords.GetFirstPortal();

@ -13,6 +13,10 @@
#include <vtkm/exec/CellInside.h>
#include <vtkm/exec/ParametricCoordinates.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/CoordinateSystem.h>
#include <vtkm/cont/DeviceAdapterTag.h>
#include <vtkm/Math.h>
#include <vtkm/Types.h>
#include <vtkm/VecFromPortalPermute.h>
@ -79,7 +83,7 @@ namespace exec
{
//--------------------------------------------------------------------
template <typename CellSetType, typename DeviceAdapter>
template <typename CellSetType>
class VTKM_ALWAYS_EXPORT CellLocatorTwoLevel : public vtkm::exec::CellLocator
{
private:
@ -92,11 +96,11 @@ private:
using CoordsPortalType =
typename vtkm::cont::CoordinateSystem::MultiplexerArrayType::ReadPortalType;
using CellSetP2CExecType =
decltype(std::declval<CellSetType>().PrepareForInput(DeviceAdapter{},
vtkm::TopologyElementTagCell{},
vtkm::TopologyElementTagPoint{},
std::declval<vtkm::cont::Token&>()));
using CellSetP2CExecType = decltype(
std::declval<CellSetType>().PrepareForInput(std::declval<vtkm::cont::DeviceAdapterId>(),
vtkm::TopologyElementTagCell{},
vtkm::TopologyElementTagPoint{},
std::declval<vtkm::cont::Token&>()));
// TODO: This function may return false positives for non 3D cells as the
// tests are done on the projection of the point on the cell. Extra checks
@ -133,18 +137,19 @@ public:
const vtkm::cont::ArrayHandle<vtkm::Id>& cellIds,
const CellSetType& cellSet,
const vtkm::cont::CoordinateSystem& coords,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
: TopLevel(topLevelGrid)
, LeafDimensions(leafDimensions.PrepareForInput(DeviceAdapter{}, token))
, LeafStartIndex(leafStartIndex.PrepareForInput(DeviceAdapter{}, token))
, CellStartIndex(cellStartIndex.PrepareForInput(DeviceAdapter{}, token))
, CellCount(cellCount.PrepareForInput(DeviceAdapter{}, token))
, CellIds(cellIds.PrepareForInput(DeviceAdapter{}, token))
, CellSet(cellSet.PrepareForInput(DeviceAdapter{},
, LeafDimensions(leafDimensions.PrepareForInput(device, token))
, LeafStartIndex(leafStartIndex.PrepareForInput(device, token))
, CellStartIndex(cellStartIndex.PrepareForInput(device, token))
, CellCount(cellCount.PrepareForInput(device, token))
, CellIds(cellIds.PrepareForInput(device, token))
, CellSet(cellSet.PrepareForInput(device,
vtkm::TopologyElementTagCell{},
vtkm::TopologyElementTagPoint{},
token))
, Coords(coords.GetDataAsMultiplexer().PrepareForInput(DeviceAdapter{}, token))
, Coords(coords.GetDataAsMultiplexer().PrepareForInput(device, token))
{
}

@ -27,7 +27,7 @@ namespace vtkm
namespace exec
{
template <typename DeviceAdapter, vtkm::IdComponent dimensions>
template <vtkm::IdComponent dimensions>
class VTKM_ALWAYS_EXPORT CellLocatorUniformGrid final : public vtkm::exec::CellLocator
{
private:
@ -41,8 +41,7 @@ public:
const vtkm::Id3 pointDims,
const vtkm::Vec3f origin,
const vtkm::Vec3f invSpacing,
const vtkm::Vec3f maxPoint,
DeviceAdapter)
const vtkm::Vec3f maxPoint)
: CellDims(cellDims)
, PointDims(pointDims)
, Origin(origin)

@ -11,8 +11,6 @@
#define vtk_m_exec_PointLocatorSparseGrid_h
#include <vtkm/cont/CoordinateSystem.h>
#include <vtkm/cont/DeviceAdapter.h>
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
#include <vtkm/worklet/DispatcherMapField.h>
#include <vtkm/worklet/WorkletMapField.h>
@ -26,7 +24,6 @@ namespace vtkm
namespace exec
{
template <typename DeviceAdapter>
class VTKM_ALWAYS_EXPORT PointLocatorSparseGrid : public vtkm::exec::PointLocator
{
public: