Helios++
Helios software for LiDAR simulations
MultiThreadKDTreeFactory Class Reference

Decorator for any KDTree factory which provides support for multi thread KDTree building. More...

#include <MultiThreadKDTreeFactory.h>

Inheritance diagram for MultiThreadKDTreeFactory:
Collaboration diagram for MultiThreadKDTreeFactory:

Public Member Functions

 MultiThreadKDTreeFactory (shared_ptr< SimpleKDTreeFactory > const kdtf, shared_ptr< SimpleKDTreeGeometricStrategy > const gs, size_t const numJobs=2, size_t const geomJobs=2)
 MultiThreadKDTreeFactory default constructor. More...
 
KDTreeFactoryclone () const override
 
void _clone (KDTreeFactory *kdtf) const override
 Assign attributes from MultiThreadKDTreeFactory to its clone.
 
KDTreeNodeRootmakeFromPrimitivesUnsafe (vector< Primitive * > &primitives, bool const computeStats=false, bool const reportStats=false) override
 Build a KDTree which type depends on current KDTree factory (MultiThreadKDTreeFactory::kdtf) on a multi thread basis. More...
 
virtual shared_ptr< SimpleKDTreeFactorygetKdtf () const
 Obtain the SimpleKDTreeFactory used to build tree nodes. More...
 
virtual size_t getPoolSize () const
 Obtain the pool size of the thread pool (num jobs) More...
 
virtual size_t getNumJobs () const
 Obtain the number of threads for node-level parallelization. More...
 
virtual size_t getGeomJobs () const
 Obtain the number of threads for geometry-level parallelization. More...
 
virtual shared_ptr< SimpleKDTreeGeometricStrategygetGS () const
 Obtain the geometric strategy. More...
 
- Public Member Functions inherited from SimpleKDTreeFactory
 SimpleKDTreeFactory ()
 SimpleKDTreeFactory default constructor. More...
 
KDTreeFactoryclone () const override
 
KDTreeNodeRootmakeFromPrimitivesUnsafe (vector< Primitive * > &primitives, bool const computeStats=false, bool const reportStats=false) override
 Build a simple KDTree from given primitives. More...
 
- Public Member Functions inherited from KDTreeFactory
 KDTreeFactory ()
 K dimensional tree factory default constructor.
 
virtual KDTreeNodeRootmakeFromPrimitives (vector< Primitive * > const &primitives, bool const computeStats=false, bool const reportStats=false)
 Safe wrapper from makeFromPrimitivesUnsafe which handles a copy to make from primitives by default. This function behavior might be overridden by any derived/child class. It is expected that any implementation of makeFromPrimitives provides a way to implement the makeFromPrimitivesUnsafe method without modifying vector of input primitives. Notice this does not mean primitives themselves cannot be modified, that depends on the type of KDTreeFactory. It only means that the vector itself will not be modified, for instance due to sorting purposes. More...
 
virtual bool isBuildingLightNodes ()
 Check if KDTreeFactory is building light nodes. More...
 
virtual void setBuildingLightNodes (bool const buildLightNodes)
 Set KDTreeFactory so it build light nodes (true) or not (false) More...
 
virtual void setChild (LightKDTreeNode *&child, KDTreeNode *node)
 Set child to given node if and only if node is not null. It must be used to assign children nodes in a thread-safe way. More...
 

Protected Member Functions

KDTreeNodebuildRecursive (KDTreeNode *parent, bool const left, vector< Primitive * > &primitives, int const depth, int const index) override
 Recursively build a KDTree for given primitives using given KDTreeFactory (kdtf). The building of upper nodes is delegated to the MultiThreadKDTreeFactory::buildRecursiveGeometryLevel method, while the building of middle and lower nodes is assumed by the MultiThreadKDTreeFactory::buildRecursiveNodeLevel method. More...
 
KDTreeNodebuildRecursiveGeometryLevel (KDTreeNode *parent, bool const left, vector< Primitive * > &primitives, int const depth, int const index)
 Recursively build a KDTree for given primitives using given KDTreeFactory (kdtf) in a geometry-level parallelization context. The geometry-level parallelization implies distributing threads among splits as uniform as possible, while satisfying the constraint that any split must have at least one associated thread. It is the way to go for building the upper levels of the KDTree. For the sake of understanding, let \(P_i\left[a, b\right]\) note the \(i\)-th split associated to threads from \(a\)-th (inclusive) to \(b\)-th (inclusive). Thus, if \(d\) is said to be the tree depth and \(k\) is the number of threads, then it is possible to modellize the behavior of the geometry level parallel building process as follows: More...
 
void buildChildrenGeometryLevel (KDTreeNode *node, KDTreeNode *parent, vector< Primitive * > const &primitives, int const depth, int const index, vector< Primitive * > &leftPrimitives, vector< Primitive * > &rightPrimitives, int const auxiliarThreads)
 Provide an alternative implementation for the building of left and right children nodes. More...
 
KDTreeNodebuildRecursiveNodeLevel (KDTreeNode *parent, bool const left, vector< Primitive * > &primitives, int const depth, int const index)
 Recursively build a KDTree for given primitives using given KDTreeFactory (kdtf) in a node-level parallelization context. The node-level parallelization implies a one thread per node distribution. While it can be used to build the entire KDTree, at the upper levels it leads to idle threads. This problem is easy to see at the first node (root node), because there is only one node and thus only one thread can be working on it. The same would apply for the second node if the number of threads is \(>2\), because there would be only two working threads while the others will remain idle. However, this is inefficient and can be solved by delegating upper nodes to a geometry-level parallelization strategy instead of a node-level one. More...
 
void computeKDTreeStats (KDTreeNodeRoot *root) const override
 Call the compute KDTree stats method of decorated KDTree factory. More...
 
void reportKDTreeStats (KDTreeNodeRoot *root, vector< Primitive * > const &primitives) const override
 Call the report KDTree stats method of decorated KDTree factory. More...
 
virtual void prepareToMake ()
 Prepare the MultiThreadKDTreeFactory so it is ready to start making a new KDTree. More...
 
virtual void increaseFinishedGeomJobsCount (size_t const amount)
 Increase count of finished geometry-level jobs in a thread safe way. More...
 
- Protected Member Functions inherited from SimpleKDTreeFactory
virtual KDTreeNodebuildRecursiveRecipe (KDTreeNode *parent, bool const left, vector< Primitive * > &primitives, int const depth, int const index, std::function< void(KDTreeNode *node, KDTreeNode *parent, bool const left, vector< Primitive * > const &primitives)> f_computeNodeBoundaries, std::function< void(KDTreeNode *node, KDTreeNode *parent, vector< Primitive * > &primitives, int const depth)> f_defineSplit, std::function< void(vector< Primitive * > const &primitives, int const splitAxis, double const splitPos, vector< Primitive * > &leftPrimitives, vector< Primitive * > &rightPrimitives)> f_populateSplits, std::function< void(KDTreeNode *node, KDTreeNode *parent, vector< Primitive * > const &primitives, int const depth, int const index, vector< Primitive * > &leftPrimitives, vector< Primitive * > &rightPrimitives)> f_buildChildrenNodes)
 The recipe of the recursive building algorithm. It is meant to be used by the SimpleKDTreeFactory::buildRecursive but also by any alternative implementation which shares the same recipe (global logic) but changes the way some parts are computed. For instance, it is used by the MultiThreadKDTreeFactory to handle geometry-level parallelization. More...
 
virtual void defineSplit (KDTreeNode *node, KDTreeNode *parent, vector< Primitive * > &primitives, int const depth) const
 Define the split axis and position for current node. More...
 
virtual void populateSplits (vector< Primitive * > const &primitives, int const splitAxis, double const splitPos, vector< Primitive * > &leftPrimitives, vector< Primitive * > &rightPrimitives) const
 Populate list of primitives for left and right splits from given primitives of node being splitted. More...
 
virtual void buildChildrenNodes (KDTreeNode *node, KDTreeNode *parent, vector< Primitive * > const &primitives, int const depth, int const index, vector< Primitive * > &leftPrimitives, vector< Primitive * > &rightPrimitives)
 Build children nodes for given node. If no children nodes must be built, then the node is configured as a leaf node. More...
 
virtual void computeNodeBoundaries (KDTreeNode *node, KDTreeNode *parent, bool const left, vector< Primitive * > const &primitives) const
 Compute min and max position and surface area of bounding cuboid for given node. More...
 
virtual void onPopulateSplitsDigestPrimitive (Primitive *p, int const splitAxis, double const splitPos, vector< Primitive * > &leftPrimitives, vector< Primitive * > &rightPrimitives) const
 Function to assist SimpleKDTreeFactory::populateSplits by providing the logic of digesting a primitive. More...
 
virtual void computeMinMaxSAHForChild (KDTreeNode *node, KDTreeNode *parent, bool const left, vector< Primitive * > const &primitives) const
 Function to assist SimpleKDTreeFactory::computeNodeBoundaries when computing surface area heuristic and minimum and maximum positions for child nodes. More...
 
virtual void onRootBoundariesDigestPrimitive (Primitive *primitive, double &ax, double &ay, double &az, double &bx, double &by, double &bz) const
 Function to assist SimpleKDTreeFactory::computeNodeBoundaries by providing the logic of digesting a primitive. More...
 
virtual void onComputeNodeBoundariesCalcSAH (KDTreeNode *node, double const ax, double const ay, double const az, double const bx, double const by, double const bz) const
 Function to assist SimpleKDTreeFactory::computeNodeBoundaries when computing the SAH for a node. More...
 
virtual bool checkNodeMustSplit (vector< Primitive * > const &primitives, vector< Primitive * > const &leftPrimitives, vector< Primitive * > const &rightPrimitives) const
 Check wheter the node must be splitted (true) or not (false) depending on its total primitives and the ones that would be assigned to left and right children. More...
 
virtual void makeLeaf (KDTreeNode *node, vector< Primitive * > const &primitives) const
 Make given node a leaf one. More...
 
- Protected Member Functions inherited from KDTreeFactory
virtual void lighten (KDTreeNodeRoot *root)
 Rebuild all children of given root KDTree node as LightKDTeeeNode nodes. More...
 
virtual LightKDTreeNode_lighten (KDTreeNode *node)
 Assist KDTreeFactory::lighten function by handling the lighten of a given non-root node. More...
 

Protected Attributes

shared_ptr< SimpleKDTreeFactorykdtf
 The SimpleKDTreeFactory or derived to be used to build tree nodes.
 
shared_ptr< SimpleKDTreeGeometricStrategygs
 The SimpleKDTreeGeometricStrategy or derived to be used to handle geometry-level parallelization during multi-thread KDTree building.
 
KDTreeFactoryThreadPool tpNode
 The thread pool to handle concurrency during recursive KDTree building at node-level.
 
size_t minTaskPrimitives
 The minimum number of primitives on a given split so a new task is started to handle them.
 
int maxGeometryDepth
 The maximum geometry depth level \(d^*\) as explained in the MultiThreadKDTreeFactory::buildRecursiveGeometryLevel It is updated accordingly always that MultiThreadKDTreeFactory::makeFromPrimitivesUnsafe is called. More...
 
size_t numJobs
 The maximum number of jobs (threads/workers) that this factory is allowed to use.
 
size_t geomJobs
 The number of jobs (threads/workers) that this factory must use when building upper KDTree nodes (geometry-level parallelization)
 
shared_ptr< SharedTaskSequencermasters
 All masters threads (except main thread) are handled by this shared task sequencer. More...
 
size_t finishedGeomJobs
 How many geometry-level jobs have fully finished during current KDT building. More...
 
boost::mutex finishedGeomJobsMutex
 Mutex to handle concurrent access to counter of finished geometry-level jobs. More...
 
bool notUsed
 True if the factory has not been used before, false otherwise.
 
- Protected Attributes inherited from SimpleKDTreeFactory
std::function< KDTreeNode *(KDTreeNode *, bool const, vector< Primitive * > &, int const, int const)> _buildRecursive
 The member function as attribute used to recursively build KDTree nodes. By default it will be assigned to the buildRecursive member function but it might be overridden by other implementations. For instance, to wrap the buildRecursive behavior to handle parallel building of KDTrees. More...
 
size_t minSplitPrimitives
 How many primitives are required for a node to be splitted. More...
 
- Protected Attributes inherited from KDTreeFactory
bool buildLightNodes = true
 When it is true, the KDTreeFactory is expected to build light nodes. It is, built KDTree must have a KDTreeRootNode which children are all LightKDTreeNode. When it is false, KDTreeFactory is allowed to build KDTree with KDTreeNode children, which might require more memory. More...
 
LightKDTreeNodeBlockAllocator lkdtnBlockAllocator
 The block allocator to speed-up lighten of KDTree by reducing allocation calls when instantiating multiple LightKDTreeNode. More...
 

Private Member Functions

template<class Archive >
void serialize (Archive &ar, unsigned int const version)
 Serialize a multi thread KDTree factory to a stream of bytes. More...
 

Friends

class boost::serialization::access
 

Detailed Description

Decorator for any KDTree factory which provides support for multi thread KDTree building.

Author
Alberto M. Esmoris Pena
Version
1.0

When combining geometry-level and node-level parallel building strategies, both are assumed to support the same max number of threads. To better understand this, let \(\Phi(t)\) be the number of currently available threads for the geometry-level strategy at time \(t\) while \(\Psi(t)\) denotes the number of currently available threads for the node-level thread pool at time \(t\). Now, if the maximum number of threads is \(k\), at the beginning it would be \(\Phi(t)=k\) and \(\Psi(t)=0\). Once all geometry-level splits have been done, then \(\Phi(t)=0\) and \(\Psi(t)=k\). At the last depth for geometry-level strategy, always that a split is finished involved threads will go from geometry-level mode to node-level thread pool. At any time, threads for geometry-level and node-level are related by following expresion \(\Psi(t) = k - \Phi(t)\).

Constructor & Destructor Documentation

◆ MultiThreadKDTreeFactory()

MultiThreadKDTreeFactory::MultiThreadKDTreeFactory ( shared_ptr< SimpleKDTreeFactory > const  kdtf,
shared_ptr< SimpleKDTreeGeometricStrategy > const  gs,
size_t const  numJobs = 2,
size_t const  geomJobs = 2 
)

MultiThreadKDTreeFactory default constructor.

Parameters
kdtfThe factory to be used to build the KDTree

Member Function Documentation

◆ buildChildrenGeometryLevel()

void MultiThreadKDTreeFactory::buildChildrenGeometryLevel ( KDTreeNode node,
KDTreeNode parent,
vector< Primitive * > const &  primitives,
int const  depth,
int const  index,
vector< Primitive * > &  leftPrimitives,
vector< Primitive * > &  rightPrimitives,
int const  auxiliarThreads 
)
protected

Provide an alternative implementation for the building of left and right children nodes.

See also
SimpleKDTreeFactory::buildChildrenNodes

◆ buildRecursive()

KDTreeNode * MultiThreadKDTreeFactory::buildRecursive ( KDTreeNode parent,
bool const  left,
vector< Primitive * > &  primitives,
int const  depth,
int const  index 
)
overrideprotectedvirtual

Recursively build a KDTree for given primitives using given KDTreeFactory (kdtf). The building of upper nodes is delegated to the MultiThreadKDTreeFactory::buildRecursiveGeometryLevel method, while the building of middle and lower nodes is assumed by the MultiThreadKDTreeFactory::buildRecursiveNodeLevel method.

Parameters
parentThe parent node if any. For root nodes, it must be a nullptr
leftTrue if given node is a left child, false otherwise. If the node is a root node, it should be false. If node is not a root node and left is true, it means it is a left child. If node is not a root node and left is false, it means it is a right child
primitivesPrimitives to build KDTree splitting them
depthCurrent depth at build process. Useful for tracking recursion level
indexThe node index inside current depth. Each node can be univocally identified by the ordered pair \((d, i)\) where \(d\) stands for the depth level and \(i\) for the index. The root node is identified by \((0, 0)\). Any left child node will be \((d+1, 2i)\) and any right child node will be \((d+1, 2i+1)\), where \(d\) and \(i\) are the depth and index for the parent node. In consequence, all left nodes will have an even index while all right nodes will have an odd one. However, notice that for performance reasons it could preferable to check the left flag argument, as it is faster than checking if index is even or odd.
Returns
Built KDTree node
See also
MultiThreadKDTreeFactory::buildRecursiveGeometryLevel
MultiThreadKDTreeFactory::buildRecursiveNodeLevel
MultiThreadKDTreeFactory::minTaskPrimitives
SimpleKDTreeFactory::buildRecursive

Reimplemented from SimpleKDTreeFactory.

◆ buildRecursiveGeometryLevel()

KDTreeNode * MultiThreadKDTreeFactory::buildRecursiveGeometryLevel ( KDTreeNode parent,
bool const  left,
vector< Primitive * > &  primitives,
int const  depth,
int const  index 
)
protected

Recursively build a KDTree for given primitives using given KDTreeFactory (kdtf) in a geometry-level parallelization context. The geometry-level parallelization implies distributing threads among splits as uniform as possible, while satisfying the constraint that any split must have at least one associated thread. It is the way to go for building the upper levels of the KDTree. For the sake of understanding, let \(P_i\left[a, b\right]\) note the \(i\)-th split associated to threads from \(a\)-th (inclusive) to \(b\)-th (inclusive). Thus, if \(d\) is said to be the tree depth and \(k\) is the number of threads, then it is possible to modellize the behavior of the geometry level parallel building process as follows:

\[ \left\{\begin{array}{ccc} d = 0 &:& \left\{ P_0[a_0, b_0] \right\} \\ d = 1 &:& \left\{ P_0\left[a_0, b_0\right], P_1\left[a_1, b_1\right] \right\} \\ d = 2 &:& \left\{ P_0\left[a_0, b_0\right], P_1\left[a_1, b_1\right], P_2\left[a_2, b_2\right], P_3\left[a_3, b_3\right] \right\} \\ \vdots & \vdots & \vdots \end{array}\right. \]

It is worth to mention that \(a_{i+1} = b_{i}+1\). Now, for generalization purposes let \(\alpha=\left\lfloor{\frac{k}{2^d}}\right\rfloor\) and \(\beta \equiv k \mod 2^d\). In consequence, at any depth level \(d\) it is possible to define \(\forall i,\; P_i = [a_i, b_i]\) where:

\[ a_i = \left\{\begin{array}{lll} i\alpha &,& i < 2^d - \beta \\ i(\alpha+1) - 2^d + \beta &,& i \geq 2^d - \beta \end{array}\right. \]

\[ b_i = \left\{\begin{array}{lll} \alpha(i+1)-1 &,& i < 2^d - \beta \\ i(\alpha+1)-2^d+\beta+\alpha &,& i \geq 2^d - \beta \end{array}\right. \]

It can be seen that the maximum (also assumed as expected here) number of splits at a given depth is given by \(2^d\). Therefore, geometry level building process is guaranteed to be applicable at least while \(k \geq 2^d\) is satisfied. Moreover, any split can be understood as a set of primitives \(P_i = \left\{ p_j \in \mathbb{R}^{n \times 3} : j \in [\phi \geq 1, \psi \leq m] \right\}\), so the total number of primitives is \(m\) (which is the cardinality of \(P_0\) at \(d=0\)) and each primitive is itself a set of \(n\) points in \(\mathbb{R}^3\). Of course, this is a simplification since different types of primitives are supported by Helios. However, it is not necessary to get into that level of detail to understand this algorithm. Just notice that \(P_i\) at \(d = x\) is distinct that \(P_i\) at \(d = y\) as long as \(x \neq y\) is satisfied. It is because once a node is splitted, it is understood as destroyed in this context so it is simply replaced by its children at next depth level.

Finally, the last depth at which geometry level parallelization applies can be deduced from the fact that the number of threads for a parallel algorithm is going to satisfy \(k>1\). For then it follows that \(\log_2{k} \geq 0\). Notice this would stand even for the sequential case because \(\log_2{1} = 0\). In consequence, it is known that \(k \geq 2^d \iff \log_2{k} \geq d\), because the logarithm will not change the sign. But, from aforementioned inequation, the last depth label can be defined as \(d^* = \left\lfloor{\log_2{k}}\right\rfloor\)

Returns
Built KDTree node
See also
MultiThreadKDTreeFactory::buildRecursive
MultiThreadKDTreeFactory::buildRecursiveNodeLevel
MultiThreadKDTreeFactory::maxGeometryDepth

◆ buildRecursiveNodeLevel()

KDTreeNode * MultiThreadKDTreeFactory::buildRecursiveNodeLevel ( KDTreeNode parent,
bool const  left,
vector< Primitive * > &  primitives,
int const  depth,
int const  index 
)
protected

Recursively build a KDTree for given primitives using given KDTreeFactory (kdtf) in a node-level parallelization context. The node-level parallelization implies a one thread per node distribution. While it can be used to build the entire KDTree, at the upper levels it leads to idle threads. This problem is easy to see at the first node (root node), because there is only one node and thus only one thread can be working on it. The same would apply for the second node if the number of threads is \(>2\), because there would be only two working threads while the others will remain idle. However, this is inefficient and can be solved by delegating upper nodes to a geometry-level parallelization strategy instead of a node-level one.

When using a node-level parallelization if the number of primitives for a given split is \(\geq\) minTaskPrimitives and there are available threads in the thread pool, a new task will be started to handle node building in a parallel fashion.

Returns
Built KDTree node
See also
MultiThreadKDTreeFactory::buildRecursive
MultiThreadKDTreeFactory::buildRecursiveGeometryLevel

◆ clone()

KDTreeFactory * MultiThreadKDTreeFactory::clone ( ) const
overridevirtual
See also
KDTreeFactory::clone

Implements KDTreeFactory.

Reimplemented in MultiThreadSAHKDTreeFactory.

◆ computeKDTreeStats()

void MultiThreadKDTreeFactory::computeKDTreeStats ( KDTreeNodeRoot root) const
inlineoverrideprotectedvirtual

Call the compute KDTree stats method of decorated KDTree factory.

See also
SimpleKDTreeFactory::computeKDTreeStats

Reimplemented from SimpleKDTreeFactory.

◆ getGeomJobs()

virtual size_t MultiThreadKDTreeFactory::getGeomJobs ( ) const
inlinevirtual

Obtain the number of threads for geometry-level parallelization.

Returns
Number of threads for geometry-level parallelization

◆ getGS()

virtual shared_ptr<SimpleKDTreeGeometricStrategy> MultiThreadKDTreeFactory::getGS ( ) const
inlinevirtual

Obtain the geometric strategy.

Returns
Geometric strategy

◆ getKdtf()

virtual shared_ptr<SimpleKDTreeFactory> MultiThreadKDTreeFactory::getKdtf ( ) const
inlinevirtual

Obtain the SimpleKDTreeFactory used to build tree nodes.

Returns
SimpleKDTreeFactory used to build tree nodes

◆ getNumJobs()

virtual size_t MultiThreadKDTreeFactory::getNumJobs ( ) const
inlinevirtual

Obtain the number of threads for node-level parallelization.

Returns
Number of threads for node-level parallelization

◆ getPoolSize()

virtual size_t MultiThreadKDTreeFactory::getPoolSize ( ) const
inlinevirtual

Obtain the pool size of the thread pool (num jobs)

Returns
Pool size of the thread pool (num jobs)

◆ increaseFinishedGeomJobsCount()

virtual void MultiThreadKDTreeFactory::increaseFinishedGeomJobsCount ( size_t const  amount)
inlineprotectedvirtual

Increase count of finished geometry-level jobs in a thread safe way.

See also
MultiThreadKDTreeFactory::finishedGeomJobs

◆ makeFromPrimitivesUnsafe()

KDTreeNodeRoot * MultiThreadKDTreeFactory::makeFromPrimitivesUnsafe ( vector< Primitive * > &  primitives,
bool const  computeStats = false,
bool const  reportStats = false 
)
overridevirtual

Build a KDTree which type depends on current KDTree factory (MultiThreadKDTreeFactory::kdtf) on a multi thread basis.

See also
MultiThreadKDTreeFactory::kdtf
KDTreeFactory::makeFromPrimitivesUnsafe

Implements KDTreeFactory.

◆ prepareToMake()

void MultiThreadKDTreeFactory::prepareToMake ( )
protectedvirtual

Prepare the MultiThreadKDTreeFactory so it is ready to start making a new KDTree.

This implies handling the number of start pending tasks for node thread pool so, when geometry-level parallelization is used, no node-level parallelization occurs before it must (at adequate depth). Besides, the maximum depth for geometry-level parallelization is properly handled. Also, the sequencer is initialized with masters threads for differents nodes if necessary. Finally, the count of finished geometry-level jobs is set to 0.

◆ reportKDTreeStats()

void MultiThreadKDTreeFactory::reportKDTreeStats ( KDTreeNodeRoot root,
vector< Primitive * > const &  primitives 
) const
inlineoverrideprotectedvirtual

Call the report KDTree stats method of decorated KDTree factory.

See also
SimpleKDTreeFactory::reportKDTreeStats

Reimplemented from SimpleKDTreeFactory.

◆ serialize()

template<class Archive >
void MultiThreadKDTreeFactory::serialize ( Archive &  ar,
unsigned int const  version 
)
inlineprivate

Serialize a multi thread KDTree factory to a stream of bytes.

Template Parameters
ArchiveType of rendering
Parameters
arSpecific rendering for the stream of bytes
versionVersion number for the multi thread K dimensional tree factory

Member Data Documentation

◆ finishedGeomJobs

size_t MultiThreadKDTreeFactory::finishedGeomJobs
protected

How many geometry-level jobs have fully finished during current KDT building.

See also
MultiThreadKDTreeFactory::increaseFinishedGeomJobsCount

◆ finishedGeomJobsMutex

boost::mutex MultiThreadKDTreeFactory::finishedGeomJobsMutex
protected

Mutex to handle concurrent access to counter of finished geometry-level jobs.

See also
MultiThreadKDTreeFactory::finishedGeomJobs

◆ masters

shared_ptr<SharedTaskSequencer> MultiThreadKDTreeFactory::masters
protected

All masters threads (except main thread) are handled by this shared task sequencer.

A master thread is any thread that will handle the building of a sub-KDTree composing the original KDTree. Master threads are required when using a geometry-level parallelization, so each node at max geoemtry depth is associated to one master thread.

The master node at \((d^*, 0)\) is not handled by this shared task sequencer because it is associated to the main thread itself.

See also
MultiThreadKDTreeFactory::maxGeometryDepth

◆ maxGeometryDepth

int MultiThreadKDTreeFactory::maxGeometryDepth
protected

The maximum geometry depth level \(d^*\) as explained in the MultiThreadKDTreeFactory::buildRecursiveGeometryLevel It is updated accordingly always that MultiThreadKDTreeFactory::makeFromPrimitivesUnsafe is called.

See also
MultiThreadKDTreeFactory::masters

The documentation for this class was generated from the following files: