Make PointLocatorUniformGrid default constructible

plus some style changes to match VTK-m style.
This commit is contained in:
Sujin Philip 2019-03-15 13:06:23 -04:00
parent 163b694b9d
commit 178da6c0dc
4 changed files with 171 additions and 119 deletions

@ -34,41 +34,51 @@ class PointLocator : public vtkm::cont::ExecutionObjectBase
{
public:
PointLocator()
: dirty(true)
: Modified(true)
{
}
vtkm::cont::CoordinateSystem GetCoordinates() const { return Coords; }
vtkm::cont::CoordinateSystem GetCoordinates() const { return this->Coords; }
void SetCoordinates(const vtkm::cont::CoordinateSystem& coords)
{
Coords = coords;
dirty = true;
this->Coords = coords;
this->SetModified();
}
virtual void Build() = 0;
void Update()
{
if (dirty)
if (this->Modified)
{
Build();
dirty = false;
this->Modified = false;
}
}
template <typename DeviceAdapter>
VTKM_CONT const vtkm::exec::PointLocator* PrepareForExecution(DeviceAdapter device) const
VTKM_CONT const vtkm::exec::PointLocator* PrepareForExecution(
vtkm::cont::DeviceAdapterId device) const
{
return PrepareForExecutionImpl(device).PrepareForExecution(device);
this->PrepareExecutionObject(this->ExecutionObjectHandle, device);
return this->ExecutionObjectHandle.PrepareForExecution(device);
}
using HandleType = vtkm::cont::VirtualObjectHandle<vtkm::exec::PointLocator>;
VTKM_CONT virtual const HandleType PrepareForExecutionImpl(
vtkm::cont::DeviceAdapterId deviceId) const = 0;
protected:
void SetModified() { this->Modified = true; }
bool GetModified() const { return this->Modified; }
virtual void Build() = 0;
using ExecutionObjectHandleType = vtkm::cont::VirtualObjectHandle<vtkm::exec::PointLocator>;
VTKM_CONT virtual void PrepareExecutionObject(ExecutionObjectHandleType& execObjHandle,
vtkm::cont::DeviceAdapterId deviceId) const = 0;
private:
vtkm::cont::CoordinateSystem Coords;
bool Modified;
bool dirty;
mutable ExecutionObjectHandleType ExecutionObjectHandle;
};
}
}

@ -33,123 +33,171 @@ namespace vtkm
{
namespace cont
{
class PointLocatorUniformGrid : public vtkm::cont::PointLocator
namespace internal
{
namespace point_locator_uniform_grid
{
class BinPointsWorklet : public vtkm::worklet::WorkletMapField
{
public:
PointLocatorUniformGrid(const vtkm::Vec<vtkm::FloatDefault, 3>& _min,
const vtkm::Vec<vtkm::FloatDefault, 3>& _max,
const vtkm::Vec<vtkm::Id, 3>& _dims)
: PointLocator()
, Min(_min)
, Max(_max)
, Dims(_dims)
using ControlSignature = void(FieldIn coord, FieldOut label);
using ExecutionSignature = void(_1, _2);
VTKM_CONT
BinPointsWorklet(vtkm::Vec<vtkm::FloatDefault, 3> min,
vtkm::Vec<vtkm::FloatDefault, 3> max,
vtkm::Vec<vtkm::Id, 3> dims)
: Min(min)
, Dims(dims)
, Dxdydz((max - Min) / Dims)
{
}
class BinPointsWorklet : public vtkm::worklet::WorkletMapField
template <typename CoordVecType, typename IdType>
VTKM_EXEC void operator()(const CoordVecType& coord, IdType& label) const
{
public:
using ControlSignature = void(FieldIn coord, FieldOut label);
vtkm::Vec<vtkm::Id, 3> ijk = (coord - Min) / Dxdydz;
label = ijk[0] + ijk[1] * Dims[0] + ijk[2] * Dims[0] * Dims[1];
}
using ExecutionSignature = void(_1, _2);
private:
vtkm::Vec<vtkm::FloatDefault, 3> Min;
vtkm::Vec<vtkm::Id, 3> Dims;
vtkm::Vec<vtkm::FloatDefault, 3> Dxdydz;
};
}
} // internal::point_locator_uniform_grid
VTKM_CONT
BinPointsWorklet(vtkm::Vec<vtkm::FloatDefault, 3> _min,
vtkm::Vec<vtkm::FloatDefault, 3> _max,
vtkm::Vec<vtkm::Id, 3> _dims)
: Min(_min)
, Dims(_dims)
, Dxdydz((_max - Min) / Dims)
class PointLocatorUniformGrid : public vtkm::cont::PointLocator
{
public:
using RangeType = vtkm::Vec<vtkm::Range, 3>;
PointLocatorUniformGrid() = default;
void SetRange(const RangeType& range)
{
if (this->Range != range)
{
this->Range = range;
this->SetModified();
}
}
template <typename CoordVecType, typename IdType>
VTKM_EXEC void operator()(const CoordVecType& coord, IdType& label) const
const RangeType& GetRange() const { return this->Range; }
void SetComputeRangeFromCoordinates()
{
if (!this->IsRangeInvalid())
{
vtkm::Vec<vtkm::Id, 3> ijk = (coord - Min) / Dxdydz;
label = ijk[0] + ijk[1] * Dims[0] + ijk[2] * Dims[0] * Dims[1];
this->Range = { { 0.0, -1.0 } };
this->SetModified();
}
}
private:
vtkm::Vec<vtkm::FloatDefault, 3> Min;
vtkm::Vec<vtkm::Id, 3> Dims;
vtkm::Vec<vtkm::FloatDefault, 3> Dxdydz;
};
void SetNumberOfBins(const vtkm::Id3& bins)
{
if (this->Dims != bins)
{
this->Dims = bins;
this->SetModified();
}
}
const vtkm::Id3& GetNumberOfBins() const { return this->Dims; }
protected:
void Build() override
{
// Save training data points.
vtkm::cont::ArrayCopy(this->GetCoordinates().GetData(), this->coords);
if (this->IsRangeInvalid())
{
this->Range = this->GetCoordinates().GetRange();
}
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));
// generate unique id for each input point
vtkm::cont::ArrayHandleCounting<vtkm::Id> pointCounting(0, 1, this->coords.GetNumberOfValues());
vtkm::cont::ArrayCopy(pointCounting, this->pointIds);
vtkm::cont::ArrayHandleCounting<vtkm::Id> pointCounting(
0, 1, this->GetCoordinates().GetNumberOfValues());
vtkm::cont::ArrayCopy(pointCounting, this->PointIds);
using internal::point_locator_uniform_grid::BinPointsWorklet;
// bin points into cells and give each of them the cell id.
BinPointsWorklet cellIdWorklet(this->Min, this->Max, this->Dims);
vtkm::cont::ArrayHandle<vtkm::Id> cellIds;
BinPointsWorklet cellIdWorklet(rmin, rmax, this->Dims);
vtkm::worklet::DispatcherMapField<BinPointsWorklet> dispatchCellId(cellIdWorklet);
dispatchCellId.Invoke(this->coords, this->cellIds);
dispatchCellId.Invoke(this->GetCoordinates(), cellIds);
// Group points of the same cell together by sorting them according to the cell ids
vtkm::cont::Algorithm::SortByKey(this->cellIds, this->pointIds);
vtkm::cont::Algorithm::SortByKey(cellIds, this->PointIds);
// for each cell, find the lower and upper bound of indices to the sorted point ids.
vtkm::cont::ArrayHandleCounting<vtkm::Id> cell_ids_counting(
0, 1, this->Dims[0] * this->Dims[1] * this->Dims[2]);
vtkm::cont::Algorithm::UpperBounds(this->cellIds, cell_ids_counting, this->cellUpper);
vtkm::cont::Algorithm::LowerBounds(this->cellIds, cell_ids_counting, this->cellLower);
vtkm::cont::Algorithm::UpperBounds(cellIds, cell_ids_counting, this->CellUpper);
vtkm::cont::Algorithm::LowerBounds(cellIds, cell_ids_counting, this->CellLower);
}
using HandleType = vtkm::cont::VirtualObjectHandle<vtkm::exec::PointLocator>;
struct PrepareForExecutionFunctor
struct PrepareExecutionObjectFunctor
{
template <typename DeviceAdapter>
VTKM_CONT bool operator()(DeviceAdapter,
const vtkm::cont::PointLocatorUniformGrid& self,
HandleType& handle) const
ExecutionObjectHandleType& handle) 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::PointLocatorUniformGrid<DeviceAdapter>* h =
new vtkm::exec::PointLocatorUniformGrid<DeviceAdapter>(
self.Min,
self.Max,
rmin,
rmax,
self.Dims,
self.coords.PrepareForInput(DeviceAdapter()),
self.pointIds.PrepareForInput(DeviceAdapter()),
self.cellLower.PrepareForInput(DeviceAdapter()),
self.cellUpper.PrepareForInput(DeviceAdapter()));
self.GetCoordinates().GetData().PrepareForInput(DeviceAdapter()),
self.PointIds.PrepareForInput(DeviceAdapter()),
self.CellLower.PrepareForInput(DeviceAdapter()),
self.CellUpper.PrepareForInput(DeviceAdapter()));
handle.Reset(h);
return true;
}
};
VTKM_CONT
const HandleType PrepareForExecutionImpl(vtkm::cont::DeviceAdapterId deviceId) const override
VTKM_CONT void PrepareExecutionObject(ExecutionObjectHandleType& execObjHandle,
vtkm::cont::DeviceAdapterId deviceId) const override
{
const bool success =
vtkm::cont::TryExecuteOnDevice(deviceId, PrepareForExecutionFunctor(), *this, ExecHandle);
const bool success = vtkm::cont::TryExecuteOnDevice(
deviceId, PrepareExecutionObjectFunctor(), *this, execObjHandle);
if (!success)
{
throwFailedRuntimeDeviceTransfer("PointLocatorUniformGrid", deviceId);
}
return ExecHandle;
}
bool IsRangeInvalid() const
{
return (this->Range[0].Max < this->Range[0].Min) || (this->Range[1].Max < this->Range[1].Min) ||
(this->Range[2].Max < this->Range[2].Min);
}
private:
vtkm::Vec<vtkm::FloatDefault, 3> Min;
vtkm::Vec<vtkm::FloatDefault, 3> Max;
vtkm::Vec<vtkm::Id, 3> Dims;
RangeType Range = { { 0.0, -1.0 } };
vtkm::Id3 Dims = { 32 };
// TODO: how to convert CoordinateSystem to ArrayHandle<Vec<Float, 3>>?
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::FloatDefault, 3>> coords;
vtkm::cont::ArrayHandle<vtkm::Id> pointIds;
vtkm::cont::ArrayHandle<vtkm::Id> cellIds;
vtkm::cont::ArrayHandle<vtkm::Id> cellLower;
vtkm::cont::ArrayHandle<vtkm::Id> cellUpper;
// TODO: std::unique_ptr/std::shared_ptr?
mutable HandleType ExecHandle;
vtkm::cont::ArrayHandle<vtkm::Id> PointIds;
vtkm::cont::ArrayHandle<vtkm::Id> CellLower;
vtkm::cont::ArrayHandle<vtkm::Id> CellUpper;
};
}
}

@ -21,8 +21,6 @@
#ifndef vtk_m_cont_testing_TestingPointLocatorUniformGrid_h
#define vtk_m_cont_testing_TestingPointLocatorUniformGrid_h
//#define VTKM_DEVICE_ADAPTER VTKM_DEVICE_ADAPTER_SERIAL
#include <random>
#include <vtkm/cont/testing/Testing.h>
@ -124,13 +122,13 @@ public:
vtkm::cont::CoordinateSystem coord("points", coordi_Handle);
// TODO: locator needs to be a pointer to have runtime polymorphism.
//vtkm::cont::PointLocator * locator = new vtkm::cont::PointLocatorUniformGrid(
// { 0.0f, 0.0f, 0.0f }, { 10.0f, 10.0f, 10.0f }, { 5, 5, 5 });
vtkm::cont::PointLocatorUniformGrid locator(
{ 0.0f, 0.0f, 0.0f }, { 10.0f, 10.0f, 10.0f }, { 5, 5, 5 });
locator.SetCoordinates(coord);
locator.Update();
vtkm::cont::PointLocatorUniformGrid pointLocatorUG;
pointLocatorUG.SetCoordinates(coord);
pointLocatorUG.SetRange({ { 0.0, 10.0 } });
pointLocatorUG.SetNumberOfBins({ 5, 5, 5 });
vtkm::cont::PointLocator* locator = &pointLocatorUG;
locator->Update();
///// randomly generate testing points/////
std::vector<vtkm::Vec<vtkm::Float32, 3>> qcVec;

@ -20,7 +20,6 @@
#ifndef vtk_m_exec_PointLocatorUniformGrid_h
#define vtk_m_exec_PointLocatorUniformGrid_h
#include <vtkm/cont/ArrayHandleCounting.h>
#include <vtkm/cont/DeviceAdapter.h>
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
#include <vtkm/worklet/DispatcherMapField.h>
@ -35,35 +34,33 @@ namespace vtkm
namespace exec
{
// TODO: remove template T
template <typename DeviceAdapter>
class PointLocatorUniformGrid : public vtkm::exec::PointLocator
{
public:
// TODO: figure hout how to parametize/passing DeviceAdapter.
//using DeviceAdapter = vtkm::cont::DeviceAdapterTagSerial;
using CoordPortalType = typename vtkm::cont::ArrayHandle<
vtkm::Vec<vtkm::FloatDefault, 3>>::template ExecutionTypes<DeviceAdapter>::PortalConst;
using CoordPortalType =
typename vtkm::cont::ArrayHandleVirtualCoordinates::template ExecutionTypes<
DeviceAdapter>::PortalConst;
using IdPortalType =
typename vtkm::cont::ArrayHandle<vtkm::Id>::template ExecutionTypes<DeviceAdapter>::PortalConst;
PointLocatorUniformGrid() = default;
PointLocatorUniformGrid(const vtkm::Vec<vtkm::FloatDefault, 3>& _min,
const vtkm::Vec<vtkm::FloatDefault, 3>& _max,
const vtkm::Vec<vtkm::Id, 3>& _dims,
const CoordPortalType& _coords,
const IdPortalType& _pointIds,
const IdPortalType& _cellLower,
const IdPortalType& _cellUpper)
: Min(_min)
, Dims(_dims)
, Dxdydz((_max - Min) / Dims)
, coords(_coords)
, pointIds(_pointIds)
, cellLower(_cellLower)
, cellUpper(_cellUpper)
PointLocatorUniformGrid(const vtkm::Vec<vtkm::FloatDefault, 3>& min,
const vtkm::Vec<vtkm::FloatDefault, 3>& max,
const vtkm::Vec<vtkm::Id, 3>& dims,
const CoordPortalType& coords,
const IdPortalType& pointIds,
const IdPortalType& cellLower,
const IdPortalType& cellUpper)
: Min(min)
, Dims(dims)
, Dxdydz((max - Min) / Dims)
, Coords(coords)
, PointIds(pointIds)
, CellLower(cellLower)
, CellUpper(cellUpper)
{
}
@ -82,7 +79,7 @@ public:
vtkm::FloatDefault& distance2) const override
{
//std::cout << "FindNeareastNeighbor: " << queryPoint << std::endl;
vtkm::Id3 ijk = (queryPoint - Min) / this->Dxdydz;
vtkm::Id3 ijk = (queryPoint - this->Min) / this->Dxdydz;
ijk = vtkm::Max(ijk, vtkm::Id3(0));
ijk = vtkm::Min(ijk, this->Dims - vtkm::Id3(1));
@ -104,12 +101,11 @@ private:
vtkm::Vec<vtkm::Id, 3> Dims;
vtkm::Vec<vtkm::FloatDefault, 3> Dxdydz;
CoordPortalType coords;
CoordPortalType Coords;
IdPortalType pointIds;
IdPortalType cellIds;
IdPortalType cellLower;
IdPortalType cellUpper;
IdPortalType PointIds;
IdPortalType CellLower;
IdPortalType CellUpper;
VTKM_EXEC void FindInCell(const vtkm::Vec<vtkm::FloatDefault, 3>& queryPoint,
const vtkm::Id3& ijk,
@ -117,12 +113,12 @@ private:
vtkm::FloatDefault& nearestDistance2) const
{
vtkm::Id cellId = ijk[0] + (ijk[1] * this->Dims[0]) + (ijk[2] * this->Dims[0] * this->Dims[1]);
vtkm::Id lower = cellLower.Get(cellId);
vtkm::Id upper = cellUpper.Get(cellId);
vtkm::Id lower = this->CellLower.Get(cellId);
vtkm::Id upper = this->CellUpper.Get(cellId);
for (vtkm::Id index = lower; index < upper; index++)
{
vtkm::Id pointid = pointIds.Get(index);
vtkm::Vec<vtkm::FloatDefault, 3> point = coords.Get(pointid);
vtkm::Id pointid = this->PointIds.Get(index);
vtkm::Vec<vtkm::FloatDefault, 3> point = this->Coords.Get(pointid);
vtkm::FloatDefault distance2 = vtkm::MagnitudeSquared(point - queryPoint);
if (distance2 < nearestDistance2)
{