Skip to content

Commit 15afc82

Browse files
authored
Merge pull request #1024 from danrbailey/nodemanagergrainsize
DynamicNodeManager Grain Size
2 parents aa4ed7e + 1ca5586 commit 15afc82

File tree

3 files changed

+78
-55
lines changed

3 files changed

+78
-55
lines changed

openvdb/openvdb/tree/NodeManager.h

Lines changed: 74 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -808,41 +808,45 @@ class DynamicNodeManagerLink
808808
DynamicNodeManagerLink() = default;
809809

810810
template<typename NodeOpT, typename RootT>
811-
void foreachTopDown(const NodeOpT& op, RootT& root, bool threaded, size_t grainSize)
811+
void foreachTopDown(const NodeOpT& op, RootT& root, bool threaded,
812+
size_t leafGrainSize, size_t nonLeafGrainSize)
812813
{
813814
if (!op(root, /*index=*/0)) return;
814815
if (!mList.initRootChildren(root)) return;
815816
ForeachFilterOp<NodeOpT> filterOp(op, mList.nodeCount());
816-
mList.foreachWithIndex(filterOp, threaded, grainSize);
817-
mNext.foreachTopDownRecurse(filterOp, mList, threaded, grainSize);
817+
mList.foreachWithIndex(filterOp, threaded, LEVEL == 0 ? leafGrainSize : nonLeafGrainSize);
818+
mNext.foreachTopDownRecurse(filterOp, mList, threaded, leafGrainSize, nonLeafGrainSize);
818819
}
819820

820821
template<typename FilterOpT, typename ParentT>
821-
void foreachTopDownRecurse(const FilterOpT& filterOp, ParentT& parent, bool threaded, size_t grainSize)
822+
void foreachTopDownRecurse(const FilterOpT& filterOp, ParentT& parent, bool threaded,
823+
size_t leafGrainSize, size_t nonLeafGrainSize)
822824
{
823825
if (!mList.initNodeChildren(parent, filterOp, !threaded)) return;
824826
FilterOpT childFilterOp(filterOp.op(), mList.nodeCount());
825-
mList.foreachWithIndex(childFilterOp, threaded, grainSize);
826-
mNext.foreachTopDownRecurse(childFilterOp, mList, threaded, grainSize);
827+
mList.foreachWithIndex(childFilterOp, threaded, LEVEL == 0 ? leafGrainSize : nonLeafGrainSize);
828+
mNext.foreachTopDownRecurse(childFilterOp, mList, threaded, leafGrainSize, nonLeafGrainSize);
827829
}
828830

829831
template<typename NodeOpT, typename RootT>
830-
void reduceTopDown(NodeOpT& op, RootT& root, bool threaded, size_t grainSize)
832+
void reduceTopDown(NodeOpT& op, RootT& root, bool threaded,
833+
size_t leafGrainSize, size_t nonLeafGrainSize)
831834
{
832835
if (!op(root, /*index=*/0)) return;
833836
if (!mList.initRootChildren(root)) return;
834837
ReduceFilterOp<NodeOpT> filterOp(op, mList.nodeCount());
835-
mList.reduceWithIndex(filterOp, threaded, grainSize);
836-
mNext.reduceTopDownRecurse(filterOp, mList, threaded, grainSize);
838+
mList.reduceWithIndex(filterOp, threaded, LEVEL == 0 ? leafGrainSize : nonLeafGrainSize);
839+
mNext.reduceTopDownRecurse(filterOp, mList, threaded, leafGrainSize, nonLeafGrainSize);
837840
}
838841

839842
template<typename FilterOpT, typename ParentT>
840-
void reduceTopDownRecurse(FilterOpT& filterOp, ParentT& parent, bool threaded, size_t grainSize)
843+
void reduceTopDownRecurse(FilterOpT& filterOp, ParentT& parent, bool threaded,
844+
size_t leafGrainSize, size_t nonLeafGrainSize)
841845
{
842846
if (!mList.initNodeChildren(parent, filterOp, !threaded)) return;
843847
FilterOpT childFilterOp(filterOp.op(), mList.nodeCount());
844-
mList.reduceWithIndex(childFilterOp, threaded, grainSize);
845-
mNext.reduceTopDownRecurse(childFilterOp, mList, threaded, grainSize);
848+
mList.reduceWithIndex(childFilterOp, threaded, LEVEL == 0 ? leafGrainSize : nonLeafGrainSize);
849+
mNext.reduceTopDownRecurse(childFilterOp, mList, threaded, leafGrainSize, nonLeafGrainSize);
846850
}
847851

848852
protected:
@@ -861,17 +865,19 @@ class DynamicNodeManagerLink<NodeT, 0>
861865
DynamicNodeManagerLink() = default;
862866

863867
template<typename NodeFilterOp, typename ParentT>
864-
void foreachTopDownRecurse(const NodeFilterOp& nodeFilterOp, ParentT& parent, bool threaded, size_t grainSize)
868+
void foreachTopDownRecurse(const NodeFilterOp& nodeFilterOp, ParentT& parent, bool threaded,
869+
size_t leafGrainSize, size_t /*nonLeafGrainSize*/)
865870
{
866871
if (!mList.initNodeChildren(parent, nodeFilterOp, !threaded)) return;
867-
mList.foreachWithIndex(nodeFilterOp.op(), threaded, grainSize);
872+
mList.foreachWithIndex(nodeFilterOp.op(), threaded, leafGrainSize);
868873
}
869874

870875
template<typename NodeFilterOp, typename ParentT>
871-
void reduceTopDownRecurse(NodeFilterOp& nodeFilterOp, ParentT& parent, bool threaded, size_t grainSize)
876+
void reduceTopDownRecurse(NodeFilterOp& nodeFilterOp, ParentT& parent, bool threaded,
877+
size_t leafGrainSize, size_t /*nonLeafGrainSize*/)
872878
{
873879
if (!mList.initNodeChildren(parent, nodeFilterOp, !threaded)) return;
874-
mList.reduceWithIndex(nodeFilterOp.op(), threaded, grainSize);
880+
mList.reduceWithIndex(nodeFilterOp.op(), threaded, leafGrainSize);
875881
}
876882

877883
protected:
@@ -902,10 +908,12 @@ class DynamicNodeManager
902908
/// @brief Threaded method that applies a user-supplied functor
903909
/// to all the nodes in the tree.
904910
///
905-
/// @param op user-supplied functor, see examples for interface details.
906-
/// @param threaded optional toggle to disable threading, on by default.
907-
/// @param grainSize optional parameter to specify the grainsize
908-
/// for threading, one by default.
911+
/// @param op user-supplied functor, see examples for interface details.
912+
/// @param threaded optional toggle to disable threading, on by default.
913+
/// @param leafGrainSize optional parameter to specify the grainsize
914+
/// for threading over leaf nodes, one by default.
915+
/// @param nonLeafGrainSize optional parameter to specify the grainsize
916+
/// for threading over non-leaf nodes, one by default.
909917
///
910918
/// @note There are two key differences to the interface of the
911919
/// user-supplied functor to the NodeManager class - (1) the operator()
@@ -965,17 +973,20 @@ class DynamicNodeManager
965973
///
966974
/// @endcode
967975
template<typename NodeOp>
968-
void foreachTopDown(const NodeOp& op, bool threaded = true, size_t grainSize=1)
976+
void foreachTopDown(const NodeOp& op, bool threaded = true,
977+
size_t leafGrainSize=1, size_t nonLeafGrainSize=1)
969978
{
970-
mChain.foreachTopDown(op, mRoot, threaded, grainSize);
979+
mChain.foreachTopDown(op, mRoot, threaded, leafGrainSize, nonLeafGrainSize);
971980
}
972981

973982
/// @brief Threaded method that processes nodes with a user supplied functor
974983
///
975984
/// @param op user-supplied functor, see examples for interface details.
976985
/// @param threaded optional toggle to disable threading, on by default.
977-
/// @param grainSize optional parameter to specify the grainsize
978-
/// for threading, one by default.
986+
/// @param leafGrainSize optional parameter to specify the grainsize
987+
/// for threading over leaf nodes, one by default.
988+
/// @param nonLeafGrainSize optional parameter to specify the grainsize
989+
/// for threading over non-leaf nodes, one by default.
979990
///
980991
/// @note There are two key differences to the interface of the
981992
/// user-supplied functor to the NodeManager class - (1) the operator()
@@ -1029,9 +1040,10 @@ class DynamicNodeManager
10291040
///
10301041
/// @endcode
10311042
template<typename NodeOp>
1032-
void reduceTopDown(NodeOp& op, bool threaded = true, size_t grainSize=1)
1043+
void reduceTopDown(NodeOp& op, bool threaded = true,
1044+
size_t leafGrainSize=1, size_t nonLeafGrainSize=1)
10331045
{
1034-
mChain.reduceTopDown(op, mRoot, threaded, grainSize);
1046+
mChain.reduceTopDown(op, mRoot, threaded, leafGrainSize, nonLeafGrainSize);
10351047
}
10361048

10371049
protected:
@@ -1502,25 +1514,27 @@ class DynamicNodeManager<TreeOrLeafManagerT, 1>
15021514
const RootNodeType& root() const { return mRoot; }
15031515

15041516
template<typename NodeOp>
1505-
void foreachTopDown(const NodeOp& op, bool threaded = true, size_t grainSize=1)
1517+
void foreachTopDown(const NodeOp& op, bool threaded = true,
1518+
size_t leafGrainSize=1, size_t /*nonLeafGrainSize*/ =1)
15061519
{
15071520
// root
15081521
if (!op(mRoot, /*index=*/0)) return;
15091522
// list0
15101523
if (!mList0.initRootChildren(mRoot)) return;
15111524
ForeachFilterOp<NodeOp> nodeOp(op, mList0.nodeCount());
1512-
mList0.foreachWithIndex(nodeOp, threaded, grainSize);
1525+
mList0.foreachWithIndex(nodeOp, threaded, leafGrainSize);
15131526
}
15141527

15151528
template<typename NodeOp>
1516-
void reduceTopDown(NodeOp& op, bool threaded = true, size_t grainSize=1)
1529+
void reduceTopDown(NodeOp& op, bool threaded = true,
1530+
size_t leafGrainSize=1, size_t /*nonLeafGrainSize*/ =1)
15171531
{
15181532
// root
15191533
if (!op(mRoot, /*index=*/0)) return;
15201534
// list0
15211535
if (!mList0.initRootChildren(mRoot)) return;
15221536
ReduceFilterOp<NodeOp> nodeOp(op, mList0.nodeCount());
1523-
mList0.reduceWithIndex(nodeOp, threaded, grainSize);
1537+
mList0.reduceWithIndex(nodeOp, threaded, leafGrainSize);
15241538
}
15251539

15261540
protected:
@@ -1556,31 +1570,33 @@ class DynamicNodeManager<TreeOrLeafManagerT, 2>
15561570
const RootNodeType& root() const { return mRoot; }
15571571

15581572
template<typename NodeOp>
1559-
void foreachTopDown(const NodeOp& op, bool threaded = true, size_t grainSize=1)
1573+
void foreachTopDown(const NodeOp& op, bool threaded = true,
1574+
size_t leafGrainSize=1, size_t nonLeafGrainSize=1)
15601575
{
15611576
// root
15621577
if (!op(mRoot, /*index=*/0)) return;
15631578
// list1
15641579
if (!mList1.initRootChildren(mRoot)) return;
15651580
ForeachFilterOp<NodeOp> nodeOp(op, mList1.nodeCount());
1566-
mList1.foreachWithIndex(nodeOp, threaded, grainSize);
1581+
mList1.foreachWithIndex(nodeOp, threaded, nonLeafGrainSize);
15671582
// list0
15681583
if (!mList0.initNodeChildren(mList1, nodeOp, !threaded)) return;
1569-
mList0.foreachWithIndex(op, threaded, grainSize);
1584+
mList0.foreachWithIndex(op, threaded, leafGrainSize);
15701585
}
15711586

15721587
template<typename NodeOp>
1573-
void reduceTopDown(NodeOp& op, bool threaded = true, size_t grainSize=1)
1588+
void reduceTopDown(NodeOp& op, bool threaded = true,
1589+
size_t leafGrainSize=1, size_t nonLeafGrainSize=1)
15741590
{
15751591
// root
15761592
if (!op(mRoot, /*index=*/0)) return;
15771593
// list1
15781594
if (!mList1.initRootChildren(mRoot)) return;
15791595
ReduceFilterOp<NodeOp> nodeOp(op, mList1.nodeCount());
1580-
mList1.reduceWithIndex(nodeOp, threaded, grainSize);
1596+
mList1.reduceWithIndex(nodeOp, threaded, nonLeafGrainSize);
15811597
// list0
15821598
if (!mList0.initNodeChildren(mList1, nodeOp, !threaded)) return;
1583-
mList0.reduceWithIndex(op, threaded, grainSize);
1599+
mList0.reduceWithIndex(op, threaded, leafGrainSize);
15841600
}
15851601

15861602
protected:
@@ -1621,39 +1637,41 @@ class DynamicNodeManager<TreeOrLeafManagerT, 3>
16211637
const RootNodeType& root() const { return mRoot; }
16221638

16231639
template<typename NodeOp>
1624-
void foreachTopDown(const NodeOp& op, bool threaded = true, size_t grainSize=1)
1640+
void foreachTopDown(const NodeOp& op, bool threaded = true,
1641+
size_t leafGrainSize=1, size_t nonLeafGrainSize=1)
16251642
{
16261643
// root
16271644
if (!op(mRoot, /*index=*/0)) return;
16281645
// list2
16291646
if (!mList2.initRootChildren(mRoot)) return;
16301647
ForeachFilterOp<NodeOp> nodeOp2(op, mList2.nodeCount());
1631-
mList2.foreachWithIndex(nodeOp2, threaded, grainSize);
1648+
mList2.foreachWithIndex(nodeOp2, threaded, nonLeafGrainSize);
16321649
// list1
16331650
if (!mList1.initNodeChildren(mList2, nodeOp2, !threaded)) return;
16341651
ForeachFilterOp<NodeOp> nodeOp1(op, mList1.nodeCount());
1635-
mList1.foreachWithIndex(nodeOp1, threaded, grainSize);
1652+
mList1.foreachWithIndex(nodeOp1, threaded, nonLeafGrainSize);
16361653
// list0
16371654
if (!mList0.initNodeChildren(mList1, nodeOp1, !threaded)) return;
1638-
mList0.foreachWithIndex(op, threaded, grainSize);
1655+
mList0.foreachWithIndex(op, threaded, leafGrainSize);
16391656
}
16401657

16411658
template<typename NodeOp>
1642-
void reduceTopDown(NodeOp& op, bool threaded = true, size_t grainSize=1)
1659+
void reduceTopDown(NodeOp& op, bool threaded = true,
1660+
size_t leafGrainSize=1, size_t nonLeafGrainSize=1)
16431661
{
16441662
// root
16451663
if (!op(mRoot, /*index=*/0)) return;
16461664
// list2
16471665
if (!mList2.initRootChildren(mRoot)) return;
16481666
ReduceFilterOp<NodeOp> nodeOp2(op, mList2.nodeCount());
1649-
mList2.reduceWithIndex(nodeOp2, threaded, grainSize);
1667+
mList2.reduceWithIndex(nodeOp2, threaded, nonLeafGrainSize);
16501668
// list1
16511669
if (!mList1.initNodeChildren(mList2, nodeOp2, !threaded)) return;
16521670
ReduceFilterOp<NodeOp> nodeOp1(op, mList1.nodeCount());
1653-
mList1.reduceWithIndex(nodeOp1, threaded, grainSize);
1671+
mList1.reduceWithIndex(nodeOp1, threaded, nonLeafGrainSize);
16541672
// list0
16551673
if (!mList0.initNodeChildren(mList1, nodeOp1, !threaded)) return;
1656-
mList0.reduceWithIndex(op, threaded, grainSize);
1674+
mList0.reduceWithIndex(op, threaded, leafGrainSize);
16571675
}
16581676

16591677
protected:
@@ -1698,47 +1716,49 @@ class DynamicNodeManager<TreeOrLeafManagerT, 4>
16981716
const RootNodeType& root() const { return mRoot; }
16991717

17001718
template<typename NodeOp>
1701-
void foreachTopDown(const NodeOp& op, bool threaded = true, size_t grainSize=1)
1719+
void foreachTopDown(const NodeOp& op, bool threaded = true,
1720+
size_t leafGrainSize=1, size_t nonLeafGrainSize=1)
17021721
{
17031722
// root
17041723
if (!op(mRoot, /*index=*/0)) return;
17051724
// list3
17061725
if (!mList3.initRootChildren(mRoot)) return;
17071726
ForeachFilterOp<NodeOp> nodeOp3(op, mList3.nodeCount());
1708-
mList3.foreachWithIndex(nodeOp3, threaded, grainSize);
1727+
mList3.foreachWithIndex(nodeOp3, threaded, nonLeafGrainSize);
17091728
// list2
17101729
if (!mList2.initNodeChildren(mList3, nodeOp3, !threaded)) return;
17111730
ForeachFilterOp<NodeOp> nodeOp2(op, mList2.nodeCount());
1712-
mList2.foreachWithIndex(nodeOp2, threaded, grainSize);
1731+
mList2.foreachWithIndex(nodeOp2, threaded, nonLeafGrainSize);
17131732
// list1
17141733
if (!mList1.initNodeChildren(mList2, nodeOp2, !threaded)) return;
17151734
ForeachFilterOp<NodeOp> nodeOp1(op, mList1.nodeCount());
1716-
mList1.foreachWithIndex(nodeOp1, threaded, grainSize);
1735+
mList1.foreachWithIndex(nodeOp1, threaded, nonLeafGrainSize);
17171736
// list0
17181737
if (!mList0.initNodeChildren(mList1, nodeOp1, !threaded)) return;
1719-
mList0.foreachWithIndex(op, threaded, grainSize);
1738+
mList0.foreachWithIndex(op, threaded, leafGrainSize);
17201739
}
17211740

17221741
template<typename NodeOp>
1723-
void reduceTopDown(NodeOp& op, bool threaded = true, size_t grainSize=1)
1742+
void reduceTopDown(NodeOp& op, bool threaded = true,
1743+
size_t leafGrainSize=1, size_t nonLeafGrainSize=1)
17241744
{
17251745
// root
17261746
if (!op(mRoot, /*index=*/0)) return;
17271747
// list3
17281748
if (!mList3.initRootChildren(mRoot)) return;
17291749
ReduceFilterOp<NodeOp> nodeOp3(op, mList3.nodeCount());
1730-
mList3.reduceWithIndex(nodeOp3, threaded, grainSize);
1750+
mList3.reduceWithIndex(nodeOp3, threaded, nonLeafGrainSize);
17311751
// list2
17321752
if (!mList2.initNodeChildren(mList3, nodeOp3, !threaded)) return;
17331753
ReduceFilterOp<NodeOp> nodeOp2(op, mList2.nodeCount());
1734-
mList2.reduceWithIndex(nodeOp2, threaded, grainSize);
1754+
mList2.reduceWithIndex(nodeOp2, threaded, nonLeafGrainSize);
17351755
// list1
17361756
if (!mList1.initNodeChildren(mList2, nodeOp2, !threaded)) return;
17371757
ReduceFilterOp<NodeOp> nodeOp1(op, mList1.nodeCount());
1738-
mList1.reduceWithIndex(nodeOp1, threaded, grainSize);
1758+
mList1.reduceWithIndex(nodeOp1, threaded, nonLeafGrainSize);
17391759
// list0
17401760
if (!mList0.initNodeChildren(mList1, nodeOp1, !threaded)) return;
1741-
mList0.reduceWithIndex(op, threaded, grainSize);
1761+
mList0.reduceWithIndex(op, threaded, leafGrainSize);
17421762
}
17431763

17441764
protected:

openvdb/openvdb/unittest/TestNodeManager.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ TEST_F(TestNodeManager, testDynamic)
323323
{ // use DynamicNodeManager::foreachTopDown
324324
Int32Tree tree(sourceTree);
325325
openvdb::tree::DynamicNodeManager<Int32Tree> manager(tree);
326-
manager.foreachTopDown(expandOp);
326+
manager.foreachTopDown(expandOp, /*threaded=*/true, /*leafGrainSize=*/32, /*nonLeafGrainSize=*/8);
327327
EXPECT_EQ(Index32(32768), tree.leafCount());
328328

329329
SumOp<Int32Tree> sumOp;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
API:
2+
- DynamicNodeManager can now set one grain size for threading across leaf nodes
3+
and another for threading across non-leaf nodes.

0 commit comments

Comments
 (0)