Add parent index to BIH tree

This will help us traverse back up the tree without a call stack (which
is causing issues on CUDA).
This commit is contained in:
Kenneth Moreland 2018-07-12 00:27:57 -06:00
parent 8ca2cc9fc4
commit c463bbec93
4 changed files with 39 additions and 14 deletions

@ -296,13 +296,16 @@ public:
vtkm::Id nodesIndexOffset = 0;
vtkm::Id numSegments = 1;
IdArrayHandle discardKeys;
IdArrayHandle segmentStarts;
IdArrayHandle segmentSizes;
segmentSizes.Allocate(1);
segmentSizes.GetPortalControl().Set(0, numCells);
Self->ProcessedCellIds.Allocate(numCells);
vtkm::Id cellIdsOffset = 0;
IdArrayHandle parentIndices;
parentIndices.Allocate(1);
parentIndices.GetPortalControl().Set(0, -1);
while (!done)
{
//std::cout << "**** Iteration " << (++iteration) << " ****\n";
@ -411,7 +414,7 @@ public:
IdArrayHandle nonSplitSegmentIndices;
Algorithms::ScanExclusive(nonSplitSegmentSizes, nonSplitSegmentIndices);
IdArrayHandle runningSplitSegmentCounts;
Algorithms::ScanExclusive(splitChoices, runningSplitSegmentCounts);
vtkm::Id numNewSegments = Algorithms::ScanExclusive(splitChoices, runningSplitSegmentCounts);
//PRINT_TIMER("4.1", s41);
//START_TIMER(s42);
@ -438,6 +441,9 @@ public:
newTree.Allocate(nodesSize);
Algorithms::CopySubRange(Self->Nodes, 0, Self->Nodes.GetNumberOfValues(), newTree);
IdArrayHandle nextParentIndices;
nextParentIndices.Allocate(2 * numNewSegments);
CountingIdArrayHandle nodesIndices(nodesIndexOffset, 1, numSegments);
vtkm::worklet::spatialstructure::TreeLevelAdder nodesAdder(
cellIdsOffset, nodesSize, Self->MaxLeafSize);
@ -447,7 +453,9 @@ public:
nonSplitSegmentIndices,
segmentSizes,
runningSplitSegmentCounts,
newTree);
parentIndices,
newTree,
nextParentIndices);
nodesIndexOffset = nodesSize;
cellIdsOffset += doneCellIds.GetNumberOfValues();
Self->Nodes = newTree;
@ -463,6 +471,7 @@ public:
Algorithms::Unique(uniqueSegmentIds);
numSegments = uniqueSegmentIds.GetNumberOfValues();
done = segmentIds.GetNumberOfValues() == 0;
parentIndices = nextParentIndices;
//PRINT_TIMER("5.1", s51);
//std::cout << "Iteration time: " << iterationTimer.GetElapsedTime() << "\n";
}

@ -31,6 +31,7 @@ namespace cont
struct BoundingIntervalHierarchyNode
{
vtkm::IdComponent Dimension;
vtkm::Id ParentIndex;
vtkm::Id ChildIndex;
union {
struct
@ -48,6 +49,7 @@ struct BoundingIntervalHierarchyNode
VTKM_EXEC_CONT
BoundingIntervalHierarchyNode()
: Dimension()
, ParentIndex()
, ChildIndex()
, Node{ 0, 0 }
{

@ -87,10 +87,12 @@ private:
vtkm::Id id2 = -1;
if (c <= node.Node.LMax)
{
VTKM_ASSERT(Nodes.Get(node.ChildIndex).ParentIndex == index);
id1 = Find(node.ChildIndex, point, parametric, worklet);
}
if (id1 == -1 && c >= node.Node.RMin)
{
VTKM_ASSERT(Nodes.Get(node.ChildIndex + 1).ParentIndex == index);
id2 = Find(node.ChildIndex + 1, point, parametric, worklet);
}
if (id1 == -1 && id2 == -1)

@ -504,8 +504,15 @@ struct NonSplitIndexCalculator : public vtkm::worklet::WorkletMapField
struct TreeLevelAdder : public vtkm::worklet::WorkletMapField
{
typedef void ControlSignature(FieldIn, FieldIn, FieldIn, FieldIn, FieldIn, WholeArrayInOut);
typedef void ExecutionSignature(_1, _2, _3, _4, _5, _6);
typedef void ControlSignature(FieldIn nodeIndices,
FieldIn segmentSplits,
FieldIn nonSplitSegmentIndices,
FieldIn segmentSizes,
FieldIn runningSplitSegmentCounts,
FieldIn parentIndices,
WholeArrayInOut newTree,
WholeArrayOut nextParentIndices);
typedef void ExecutionSignature(_1, _2, _3, _4, _5, _6, _7, _8);
using InputDomain = _1;
VTKM_CONT
@ -516,26 +523,31 @@ struct TreeLevelAdder : public vtkm::worklet::WorkletMapField
{
}
template <typename BoundingIntervalHierarchyPortal>
VTKM_EXEC void operator()(const vtkm::Id& index,
template <typename BoundingIntervalHierarchyPortal, typename NextParentPortal>
VTKM_EXEC void operator()(vtkm::Id index,
const TreeNode& split,
const vtkm::Id& start,
const vtkm::Id& count,
const vtkm::Id& numPreviousSplits,
BoundingIntervalHierarchyPortal& treePortal) const
vtkm::Id start,
vtkm::Id count,
vtkm::Id numPreviousSplits,
vtkm::Id parentIndex,
BoundingIntervalHierarchyPortal& treePortal,
NextParentPortal& nextParentPortal) const
{
vtkm::cont::BoundingIntervalHierarchyNode node;
if (count > MaxLeafSize)
node.ParentIndex = parentIndex;
if (count > this->MaxLeafSize)
{
node.Dimension = split.Dimension;
node.ChildIndex = TreeOffset + 2 * numPreviousSplits;
node.ChildIndex = this->TreeOffset + 2 * numPreviousSplits;
node.Node.LMax = split.LMax;
node.Node.RMin = split.RMin;
nextParentPortal.Set(2 * numPreviousSplits, index);
nextParentPortal.Set(2 * numPreviousSplits + 1, index);
}
else
{
node.ChildIndex = -1;
node.Leaf.Start = CellIdsOffset + start;
node.Leaf.Start = this->CellIdsOffset + start;
node.Leaf.Size = count;
}
treePortal.Set(index, node);