diff --git a/vtkm/cont/CMakeLists.txt b/vtkm/cont/CMakeLists.txt index c02091c5a..2a888db39 100644 --- a/vtkm/cont/CMakeLists.txt +++ b/vtkm/cont/CMakeLists.txt @@ -165,6 +165,8 @@ set(sources FieldRangeCompute.cxx FieldRangeGlobalCompute.cxx MultiBlock.cxx + PointLocator.cxx + PointLocatorUniformGrid.cxx RuntimeDeviceInformation.cxx StorageVirtual.cxx Timer.cxx diff --git a/vtkm/cont/PointLocator.cxx b/vtkm/cont/PointLocator.cxx new file mode 100644 index 000000000..a27b0e80a --- /dev/null +++ b/vtkm/cont/PointLocator.cxx @@ -0,0 +1,29 @@ +//============================================================================ +// 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. +// +// Copyright 2019 National Technology & Engineering Solutions of Sandia, LLC (NTESS). +// Copyright 2019 UT-Battelle, LLC. +// Copyright 2019 Los Alamos National Security. +// +// Under the terms of Contract DE-NA0003525 with NTESS, +// the U.S. Government retains certain rights in this software. +// +// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National +// Laboratory (LANL), the U.S. Government retains certain rights in +// this software. +//============================================================================ + +#include + +namespace vtkm +{ +namespace cont +{ +PointLocator::~PointLocator() = default; +} +} diff --git a/vtkm/cont/PointLocator.h b/vtkm/cont/PointLocator.h index 059c455e8..280df8eea 100644 --- a/vtkm/cont/PointLocator.h +++ b/vtkm/cont/PointLocator.h @@ -20,9 +20,11 @@ namespace vtkm namespace cont { -class PointLocator : public vtkm::cont::ExecutionObjectBase +class VTKM_CONT_EXPORT PointLocator : public vtkm::cont::ExecutionObjectBase { public: + virtual ~PointLocator(); + PointLocator() : Modified(true) { diff --git a/vtkm/cont/PointLocatorUniformGrid.cxx b/vtkm/cont/PointLocatorUniformGrid.cxx new file mode 100644 index 000000000..7070e6b74 --- /dev/null +++ b/vtkm/cont/PointLocatorUniformGrid.cxx @@ -0,0 +1,138 @@ +//============================================================================ +// 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. +// +// Copyright 2017 National Technology & Engineering Solutions of Sandia, LLC (NTESS). +// Copyright 2014 UT-Battelle, LLC. +// Copyright 2017 Los Alamos National Security. +// +// Under the terms of Contract DE-NA0003525 with NTESS, +// the U.S. Government retains certain rights in this software. +// +// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National +// Laboratory (LANL), the U.S. Government retains certain rights in +// this software. +//============================================================================ +#include + +namespace vtkm +{ +namespace cont +{ + +namespace internal +{ + +class BinPointsWorklet : public vtkm::worklet::WorkletMapField +{ +public: + using ControlSignature = void(FieldIn coord, FieldOut label); + + using ExecutionSignature = void(_1, _2); + + VTKM_CONT + BinPointsWorklet(vtkm::Vec min, + vtkm::Vec max, + vtkm::Vec dims) + : Min(min) + , Dims(dims) + , Dxdydz((max - Min) / Dims) + { + } + + template + VTKM_EXEC void operator()(const CoordVecType& coord, IdType& label) const + { + vtkm::Vec ijk = (coord - Min) / Dxdydz; + label = ijk[0] + ijk[1] * Dims[0] + ijk[2] * Dims[0] * Dims[1]; + } + +private: + vtkm::Vec Min; + vtkm::Vec Dims; + vtkm::Vec Dxdydz; +}; + +} // internal + +void PointLocatorUniformGrid::Build() +{ + if (this->IsRangeInvalid()) + { + this->Range = this->GetCoordinates().GetRange(); + } + + auto rmin = vtkm::make_Vec(static_cast(this->Range[0].Min), + static_cast(this->Range[1].Min), + static_cast(this->Range[2].Min)); + auto rmax = vtkm::make_Vec(static_cast(this->Range[0].Max), + static_cast(this->Range[1].Max), + static_cast(this->Range[2].Max)); + + // generate unique id for each input point + vtkm::cont::ArrayHandleCounting pointCounting( + 0, 1, this->GetCoordinates().GetNumberOfValues()); + vtkm::cont::ArrayCopy(pointCounting, this->PointIds); + + using internal::BinPointsWorklet; + + // bin points into cells and give each of them the cell id. + vtkm::cont::ArrayHandle cellIds; + BinPointsWorklet cellIdWorklet(rmin, rmax, this->Dims); + vtkm::worklet::DispatcherMapField dispatchCellId(cellIdWorklet); + dispatchCellId.Invoke(this->GetCoordinates(), cellIds); + + // Group points of the same cell together by sorting them according to the cell ids + 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 cell_ids_counting( + 0, 1, this->Dims[0] * this->Dims[1] * this->Dims[2]); + vtkm::cont::Algorithm::UpperBounds(cellIds, cell_ids_counting, this->CellUpper); + vtkm::cont::Algorithm::LowerBounds(cellIds, cell_ids_counting, this->CellLower); +} + +struct PointLocatorUniformGrid::PrepareExecutionObjectFunctor +{ + template + VTKM_CONT bool operator()(DeviceAdapter, + const vtkm::cont::PointLocatorUniformGrid& self, + ExecutionObjectHandleType& handle) const + { + auto rmin = vtkm::make_Vec(static_cast(self.Range[0].Min), + static_cast(self.Range[1].Min), + static_cast(self.Range[2].Min)); + auto rmax = vtkm::make_Vec(static_cast(self.Range[0].Max), + static_cast(self.Range[1].Max), + static_cast(self.Range[2].Max)); + vtkm::exec::PointLocatorUniformGrid* h = + new vtkm::exec::PointLocatorUniformGrid( + rmin, + rmax, + self.Dims, + self.GetCoordinates().GetData().PrepareForInput(DeviceAdapter()), + self.PointIds.PrepareForInput(DeviceAdapter()), + self.CellLower.PrepareForInput(DeviceAdapter()), + self.CellUpper.PrepareForInput(DeviceAdapter())); + handle.Reset(h); + return true; + } +}; + +VTKM_CONT void PointLocatorUniformGrid::PrepareExecutionObject( + ExecutionObjectHandleType& execObjHandle, + vtkm::cont::DeviceAdapterId deviceId) const +{ + const bool success = + vtkm::cont::TryExecuteOnDevice(deviceId, PrepareExecutionObjectFunctor(), *this, execObjHandle); + if (!success) + { + throwFailedRuntimeDeviceTransfer("PointLocatorUniformGrid", deviceId); + } +} +} +} // vtkm::cont diff --git a/vtkm/cont/PointLocatorUniformGrid.h b/vtkm/cont/PointLocatorUniformGrid.h index 157592aa1..26ccbd777 100644 --- a/vtkm/cont/PointLocatorUniformGrid.h +++ b/vtkm/cont/PointLocatorUniformGrid.h @@ -24,50 +24,11 @@ namespace vtkm namespace cont { -namespace internal -{ -namespace point_locator_uniform_grid -{ - -class BinPointsWorklet : public vtkm::worklet::WorkletMapField -{ -public: - using ControlSignature = void(FieldIn coord, FieldOut label); - - using ExecutionSignature = void(_1, _2); - - VTKM_CONT - BinPointsWorklet(vtkm::Vec min, - vtkm::Vec max, - vtkm::Vec dims) - : Min(min) - , Dims(dims) - , Dxdydz((max - Min) / Dims) - { - } - - template - VTKM_EXEC void operator()(const CoordVecType& coord, IdType& label) const - { - vtkm::Vec ijk = (coord - Min) / Dxdydz; - label = ijk[0] + ijk[1] * Dims[0] + ijk[2] * Dims[0] * Dims[1]; - } - -private: - vtkm::Vec Min; - vtkm::Vec Dims; - vtkm::Vec Dxdydz; -}; -} -} // internal::point_locator_uniform_grid - -class PointLocatorUniformGrid : public vtkm::cont::PointLocator +class VTKM_CONT_EXPORT PointLocatorUniformGrid : public vtkm::cont::PointLocator { public: using RangeType = vtkm::Vec; - PointLocatorUniformGrid() = default; - void SetRange(const RangeType& range) { if (this->Range != range) @@ -100,80 +61,12 @@ public: const vtkm::Id3& GetNumberOfBins() const { return this->Dims; } protected: - void Build() override - { - if (this->IsRangeInvalid()) - { - this->Range = this->GetCoordinates().GetRange(); - } + void Build() override; - auto rmin = vtkm::make_Vec(static_cast(this->Range[0].Min), - static_cast(this->Range[1].Min), - static_cast(this->Range[2].Min)); - auto rmax = vtkm::make_Vec(static_cast(this->Range[0].Max), - static_cast(this->Range[1].Max), - static_cast(this->Range[2].Max)); - - // generate unique id for each input point - vtkm::cont::ArrayHandleCounting 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. - vtkm::cont::ArrayHandle cellIds; - BinPointsWorklet cellIdWorklet(rmin, rmax, this->Dims); - vtkm::worklet::DispatcherMapField dispatchCellId(cellIdWorklet); - dispatchCellId.Invoke(this->GetCoordinates(), cellIds); - - // Group points of the same cell together by sorting them according to the cell ids - 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 cell_ids_counting( - 0, 1, this->Dims[0] * this->Dims[1] * this->Dims[2]); - vtkm::cont::Algorithm::UpperBounds(cellIds, cell_ids_counting, this->CellUpper); - vtkm::cont::Algorithm::LowerBounds(cellIds, cell_ids_counting, this->CellLower); - } - - struct PrepareExecutionObjectFunctor - { - template - VTKM_CONT bool operator()(DeviceAdapter, - const vtkm::cont::PointLocatorUniformGrid& self, - ExecutionObjectHandleType& handle) const - { - auto rmin = vtkm::make_Vec(static_cast(self.Range[0].Min), - static_cast(self.Range[1].Min), - static_cast(self.Range[2].Min)); - auto rmax = vtkm::make_Vec(static_cast(self.Range[0].Max), - static_cast(self.Range[1].Max), - static_cast(self.Range[2].Max)); - vtkm::exec::PointLocatorUniformGrid* h = - new vtkm::exec::PointLocatorUniformGrid( - rmin, - rmax, - self.Dims, - self.GetCoordinates().GetData().PrepareForInput(DeviceAdapter()), - self.PointIds.PrepareForInput(DeviceAdapter()), - self.CellLower.PrepareForInput(DeviceAdapter()), - self.CellUpper.PrepareForInput(DeviceAdapter())); - handle.Reset(h); - return true; - } - }; + struct PrepareExecutionObjectFunctor; VTKM_CONT void PrepareExecutionObject(ExecutionObjectHandleType& execObjHandle, - vtkm::cont::DeviceAdapterId deviceId) const override - { - const bool success = vtkm::cont::TryExecuteOnDevice( - deviceId, PrepareExecutionObjectFunctor(), *this, execObjHandle); - if (!success) - { - throwFailedRuntimeDeviceTransfer("PointLocatorUniformGrid", deviceId); - } - } + vtkm::cont::DeviceAdapterId deviceId) const override; bool IsRangeInvalid() const { diff --git a/vtkm/cont/internal/VirtualObjectTransfer.cxx b/vtkm/cont/internal/VirtualObjectTransfer.cxx index c7d0edc96..e11a214dc 100644 --- a/vtkm/cont/internal/VirtualObjectTransfer.cxx +++ b/vtkm/cont/internal/VirtualObjectTransfer.cxx @@ -24,6 +24,8 @@ namespace cont namespace internal { +VTKM_CONT TransferInterface::~TransferInterface() = default; + bool TransferState::DeviceIdIsValid(vtkm::cont::DeviceAdapterId deviceId) const { auto index = static_cast(deviceId.GetValue()); diff --git a/vtkm/cont/internal/VirtualObjectTransfer.h b/vtkm/cont/internal/VirtualObjectTransfer.h index 54229b7e1..0dcfda8cd 100644 --- a/vtkm/cont/internal/VirtualObjectTransfer.h +++ b/vtkm/cont/internal/VirtualObjectTransfer.h @@ -56,10 +56,10 @@ struct VirtualObjectTransfer #endif ; -class TransferInterface +class VTKM_CONT_EXPORT TransferInterface { public: - VTKM_CONT virtual ~TransferInterface() = default; + VTKM_CONT virtual ~TransferInterface(); VTKM_CONT virtual const vtkm::VirtualObjectBase* PrepareForExecution(vtkm::Id) = 0; VTKM_CONT virtual void ReleaseResources() = 0;