Deprecate KdTree3D worklets
The implementation of the search in the k-d tree is problematic because it uses unbounded recursion. This is a problem for GPU devices, which have very short stacks set by how many calls the compiler determines. This is fixable, but the fix is not trivial. This class is not used anywhere in VTK-m other than a trivial test. Thus, I am just deprecating the class. I am also deleting the test, so the code is not run anymore.
This commit is contained in:
parent
5fa402ac28
commit
4bf8bfb1fa
@ -36,7 +36,7 @@ set(headers
|
||||
FieldStatistics.h
|
||||
Gradient.h
|
||||
ImageDifference.h
|
||||
KdTree3D.h
|
||||
KdTree3D.h # Deprecated
|
||||
KernelSplatter.h
|
||||
Keys.h
|
||||
LagrangianStructures.h
|
||||
|
@ -18,7 +18,8 @@ namespace vtkm
|
||||
namespace worklet
|
||||
{
|
||||
|
||||
class KdTree3D
|
||||
class VTKM_DEPRECATED(1.7,
|
||||
"K-D tree recursive searches are not well supported on GPU devices.") KdTree3D
|
||||
{
|
||||
public:
|
||||
KdTree3D() = default;
|
||||
|
@ -10,8 +10,8 @@
|
||||
|
||||
set(headers
|
||||
BoundingIntervalHierarchy.h
|
||||
KdTree3DConstruction.h
|
||||
KdTree3DNNSearch.h
|
||||
KdTree3DConstruction.h # Deprecated
|
||||
KdTree3DNNSearch.h # Deprecated
|
||||
)
|
||||
|
||||
vtkm_declare_headers(${headers})
|
||||
|
@ -11,6 +11,7 @@
|
||||
#ifndef vtk_m_worklet_KdTree3DConstruction_h
|
||||
#define vtk_m_worklet_KdTree3DConstruction_h
|
||||
|
||||
#include <vtkm/Deprecated.h>
|
||||
#include <vtkm/Math.h>
|
||||
#include <vtkm/cont/Algorithm.h>
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
@ -32,7 +33,8 @@ namespace worklet
|
||||
namespace spatialstructure
|
||||
{
|
||||
|
||||
class KdTree3DConstruction
|
||||
class VTKM_DEPRECATED(1.7, "K-D tree recursive searches are not well supported on GPU devices.")
|
||||
KdTree3DConstruction
|
||||
{
|
||||
public:
|
||||
////////// General WORKLET for Kd-tree //////
|
||||
|
@ -35,7 +35,8 @@ namespace worklet
|
||||
namespace spatialstructure
|
||||
{
|
||||
|
||||
class KdTree3DNNSearch
|
||||
class VTKM_DEPRECATED(1.7, "K-D tree recursive searches are not well supported on GPU devices.")
|
||||
KdTree3DNNSearch
|
||||
{
|
||||
public:
|
||||
class NearestNeighborSearch3DWorklet : public vtkm::worklet::WorkletMapField
|
||||
|
@ -40,7 +40,6 @@ set(unit_tests
|
||||
UnitTestGraphConnectivity.cxx
|
||||
UnitTestInnerJoin.cxx
|
||||
UnitTestImageConnectivity.cxx
|
||||
UnitTestKdTreeBuildNNS.cxx
|
||||
UnitTestKeys.cxx
|
||||
UnitTestMagnitude.cxx
|
||||
UnitTestMask.cxx
|
||||
|
@ -1,138 +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 <random>
|
||||
#include <vtkm/cont/Algorithm.h>
|
||||
#include <vtkm/worklet/KdTree3D.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
using Algorithm = vtkm::cont::Algorithm;
|
||||
|
||||
////brute force method /////
|
||||
template <typename CoordiVecT, typename CoordiPortalT, typename CoordiT>
|
||||
VTKM_EXEC_CONT vtkm::Id NNSVerify3D(CoordiVecT qc, CoordiPortalT coordiPortal, CoordiT& dis)
|
||||
{
|
||||
dis = std::numeric_limits<CoordiT>::max();
|
||||
vtkm::Id nnpIdx = 0;
|
||||
|
||||
for (vtkm::Int32 i = 0; i < coordiPortal.GetNumberOfValues(); i++)
|
||||
{
|
||||
CoordiT splitX = coordiPortal.Get(i)[0];
|
||||
CoordiT splitY = coordiPortal.Get(i)[1];
|
||||
CoordiT splitZ = coordiPortal.Get(i)[2];
|
||||
CoordiT _dis =
|
||||
vtkm::Sqrt((splitX - qc[0]) * (splitX - qc[0]) + (splitY - qc[1]) * (splitY - qc[1]) +
|
||||
(splitZ - qc[2]) * (splitZ - qc[2]));
|
||||
if (_dis < dis)
|
||||
{
|
||||
dis = _dis;
|
||||
nnpIdx = i;
|
||||
}
|
||||
}
|
||||
return nnpIdx;
|
||||
}
|
||||
|
||||
class NearestNeighborSearchBruteForce3DWorklet : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
using ControlSignature = void(FieldIn qcIn,
|
||||
WholeArrayIn treeCoordiIn,
|
||||
FieldOut nnIdOut,
|
||||
FieldOut nnDisOut);
|
||||
using ExecutionSignature = void(_1, _2, _3, _4);
|
||||
|
||||
VTKM_CONT
|
||||
NearestNeighborSearchBruteForce3DWorklet() {}
|
||||
|
||||
template <typename CoordiVecType, typename CoordiPortalType, typename IdType, typename CoordiType>
|
||||
VTKM_EXEC void operator()(const CoordiVecType& qc,
|
||||
const CoordiPortalType& coordiPortal,
|
||||
IdType& nnId,
|
||||
CoordiType& nnDis) const
|
||||
{
|
||||
nnDis = std::numeric_limits<CoordiType>::max();
|
||||
|
||||
nnId = NNSVerify3D(qc, coordiPortal, nnDis);
|
||||
}
|
||||
};
|
||||
|
||||
void TestKdTreeBuildNNS(vtkm::cont::DeviceAdapterId deviceId)
|
||||
{
|
||||
vtkm::Int32 nTrainingPoints = 1000;
|
||||
vtkm::Int32 nTestingPoint = 1000;
|
||||
|
||||
std::vector<vtkm::Vec3f_32> coordi;
|
||||
|
||||
///// randomly generate training points/////
|
||||
std::default_random_engine dre;
|
||||
std::uniform_real_distribution<vtkm::Float32> dr(0.0f, 10.0f);
|
||||
|
||||
for (vtkm::Int32 i = 0; i < nTrainingPoints; i++)
|
||||
{
|
||||
coordi.push_back(vtkm::make_Vec(dr(dre), dr(dre), dr(dre)));
|
||||
}
|
||||
|
||||
///// preprare data to build 3D kd tree /////
|
||||
auto coordi_Handle = vtkm::cont::make_ArrayHandle(coordi, vtkm::CopyFlag::On);
|
||||
|
||||
// Run data
|
||||
vtkm::worklet::KdTree3D kdtree3d;
|
||||
kdtree3d.Build(coordi_Handle);
|
||||
|
||||
//Nearest Neighbor worklet Testing
|
||||
/// randomly generate testing points /////
|
||||
std::vector<vtkm::Vec3f_32> qcVec;
|
||||
for (vtkm::Int32 i = 0; i < nTestingPoint; i++)
|
||||
{
|
||||
qcVec.push_back(vtkm::make_Vec(dr(dre), dr(dre), dr(dre)));
|
||||
}
|
||||
|
||||
///// preprare testing data /////
|
||||
auto qc_Handle = vtkm::cont::make_ArrayHandle(qcVec, vtkm::CopyFlag::On);
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> nnId_Handle;
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32> nnDis_Handle;
|
||||
|
||||
kdtree3d.Run(coordi_Handle, qc_Handle, nnId_Handle, nnDis_Handle, deviceId);
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> bfnnId_Handle;
|
||||
vtkm::cont::ArrayHandle<vtkm::Float32> bfnnDis_Handle;
|
||||
NearestNeighborSearchBruteForce3DWorklet nnsbf3dWorklet;
|
||||
vtkm::worklet::DispatcherMapField<NearestNeighborSearchBruteForce3DWorklet> nnsbf3DDispatcher(
|
||||
nnsbf3dWorklet);
|
||||
nnsbf3DDispatcher.Invoke(qc_Handle,
|
||||
vtkm::cont::make_ArrayHandle(coordi, vtkm::CopyFlag::On),
|
||||
bfnnId_Handle,
|
||||
bfnnDis_Handle);
|
||||
|
||||
///// verfity search result /////
|
||||
bool passTest = true;
|
||||
for (vtkm::Int32 i = 0; i < nTestingPoint; i++)
|
||||
{
|
||||
vtkm::Id workletIdx = nnId_Handle.WritePortal().Get(i);
|
||||
vtkm::Id bfworkletIdx = bfnnId_Handle.WritePortal().Get(i);
|
||||
|
||||
if (workletIdx != bfworkletIdx)
|
||||
{
|
||||
passTest = false;
|
||||
}
|
||||
}
|
||||
|
||||
VTKM_TEST_ASSERT(passTest, "Kd tree NN search result incorrect.");
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
int UnitTestKdTreeBuildNNS(int argc, char* argv[])
|
||||
{
|
||||
return vtkm::cont::testing::Testing::RunOnDevice(TestKdTreeBuildNNS, argc, argv);
|
||||
}
|
Loading…
Reference in New Issue
Block a user