22#ifdef TTK_ENABLE_OMP_PRIORITY
23#define OPTIONAL_PRIORITY(value) priority(value)
25#define OPTIONAL_PRIORITY(value)
35 template <
class triangulationType>
37 std::string treeString;
55 printTime(precomputeTime,
"leafSearch " + treeString, 3 + alreadyDone);
59 printTime(buildTime,
"leafGrowth " + treeString, 3);
63 printTime(bbTime,
"trunk " + treeString, 3);
66 this->
printErr(treeString +
" not a tree!");
73 printTime(segmTime,
"segment " + treeString, 3);
79 template <
class triangulationType>
84 const auto nbScalars =
scalars_->size;
89 for(
SimplexId chunkId = 0; chunkId < chunkNb; ++chunkId) {
90#ifdef TTK_ENABLE_OPENMP4
91#pragma omp task firstprivate(chunkId) OPTIONAL_PRIORITY(isPrior())
94 const SimplexId lowerBound = chunkId * chunkSize;
96 = std::min(nbScalars, (chunkId + 1) * chunkSize);
97 for(
SimplexId v = lowerBound; v < upperBound; ++v) {
98 const auto &neighNumb = mesh->getVertexNeighborNumber(v);
101 for(
valence n = 0; n < neighNumb; ++n) {
103 mesh->getVertexNeighbor(v, n, neigh);
116#ifdef TTK_ENABLE_OPENMP4
129 this->
printMsg(
"found " + std::to_string(nbLeaves) +
" leaves");
134#ifdef TTK_ENABLE_FTM_TREE_STATS_TIME
135 createVector<ActiveTask>(
mt_data_.activeTasksStats);
136 mt_data_.activeTasksStats.resize(nbLeaves * 2 + 1);
144 template <
class triangulationType>
146 _launchGlobalTime.reStart();
176 for(
idNode n = 0; n < nbLeaves; ++n) {
183#ifdef TTK_ENABLE_OPENMP4
184#pragma omp task UNTIED() OPTIONAL_PRIORITY(isPrior())
189#ifdef TTK_ENABLE_OPENMP4
196 template <
class triangulationType>
219 bool seenFirst =
false;
225#ifdef TTK_ENABLE_FTM_TREE_STATS_TIME
227 = _launchGlobalTime.getElapsedTime();
228 (*
mt_data_.activeTasksStats)[currentArc].origin = orig;
232 while(!currentState->
empty()) {
243 if(currentVert == startVert) {
256 bool isSaddle, isLast;
257 std::tie(isSaddle, isLast) =
propagate(mesh, *currentState, startUF);
260#ifdef TTK_ENABLE_OPENMP4
261#pragma omp atomic write seq_cst
268#ifdef TTK_ENABLE_FTM_TREE_STATS_TIME
270 = _launchGlobalTime.getElapsedTime();
273#ifdef TTK_ENABLE_OPENMP4
274#pragma omp atomic write seq_cst
285#ifdef TTK_ENABLE_OPENMP4
286#pragma omp atomic read seq_cst
289 if(remainingTasks == 1) {
295#ifdef TTK_ENABLE_OPENMP4
296#pragma omp atomic write seq_cst
301#ifdef TTK_ENABLE_OPENMP4
307#ifdef TTK_ENABLE_OPENMP4
308#pragma omp atomic update seq_cst
317 if(currentVert != startVert) {
327 idNode const closeNode = (existCloseNode)
335#ifdef TTK_ENABLE_FTM_TREE_STATS_TIME
336 mt_data_.activeTasksStats[currentArc].end
337 = _launchGlobalTime.getElapsedTime();
343 template <
class triangulationType>
347 bool becameSaddle =
false, isLast =
false;
348 const auto nbNeigh = mesh->getVertexNeighborNumber(currentState.
vertex);
352 auto *curUFF = curUF->
find();
355 for(
valence n = 0; n < nbNeigh; ++n) {
357 mesh->getVertexNeighbor(currentState.
vertex, n, neigh);
363 if(!neighUF || neighUF->
find() != curUFF) {
381#ifdef TTK_ENABLE_OPENMP4
382#pragma omp atomic capture
392 return std::make_tuple(becameSaddle, isLast);
397 template <
class triangulationType>
401 std::vector<SimplexId> trunkVerts;
402 const auto &nbScalars =
scalars_->size;
405 trunkVerts.reserve(std::max(
SimplexId{10}, nbScalars / 500));
406 for(
SimplexId v = 0; v < nbScalars; ++v) {
412 if(node->getNumberOfUpSuperArcs() == 0) {
413 trunkVerts.emplace_back(v);
416 trunkVerts.emplace_back(v);
426 const auto &nbNodes = trunkVerts.size();
427 for(
idNode n = 1; n < nbNodes; ++n) {
466 template <
class triangulationType>
472 const auto &nbNeigh = mesh->getVertexNeighborNumber(saddleVert);
473 for(
valence n = 0; n < nbNeigh; ++n) {
475 mesh->getVertexNeighbor(saddleVert, n, neigh);
489 mt_data_.
ufs[saddleVert]->find()->setExtrema(saddleVert);
494 template <
class triangulationType>
500 const auto &nbNeigh = mesh->getVertexNeighborNumber(saddleVert);
501 for(
valence n = 0; n < nbNeigh; ++n) {
503 mesh->getVertexNeighbor(saddleVert, n, neigh);
521 template <
typename scalarType>
524 const auto nbVertices = scalars_->size;
525 scalars_->sortedVertices.resize(nbVertices);
527#ifdef TTK_ENABLE_OPENMP
528#pragma omp parallel for
530 for(
SimplexId i = 0; i < nbVertices; i++) {
531 scalars_->sortedVertices[scalars_->offsets[i]] = i;
int printErr(const std::string &msg, const debug::LineMode &lineMode=debug::LineMode::NEW, std::ostream &stream=std::cerr) const
void addArcToClose(idSuperArc a)
CurrentState * getFirstState()
void addState(CurrentState *s)
size_t getNbStates() const
static AtomicUF * makeUnion(AtomicUF *uf0, AtomicUF *uf1)
bool isCorrespondingNode(const SimplexId val) const
std::shared_ptr< Params > params_
void closeOnBackBone(const triangulationType *mesh, SimplexId saddleVert)
SuperArc * getSuperArc(idSuperArc i)
idNode getNumberOfNodes() const
SimplexId getChunkSize(const SimplexId nbVerts=-1, const SimplexId nbtasks=100) const
bool isCorrespondingNull(const SimplexId val) const
void sortInput()
if sortedVertices_ is null, define and fill it
std::tuple< SimplexId, SimplexId > getBoundsFromVerts(const std::vector< SimplexId > &nodes) const
int leafSearch(const triangulationType *mesh)
void closeArcsUF(idNode closeNode, UF uf)
void closeAndMergeOnSaddle(const triangulationType *mesh, SimplexId saddleVert)
virtual SimplexId trunkSegmentation(const std::vector< SimplexId > &pendingNodesVerts, const SimplexId begin, const SimplexId stop)
std::tuple< bool, bool > propagate(const triangulationType *mesh, CurrentState ¤tState, UF curUF)
idNode getCorrespondingNodeId(const SimplexId val) const
idSuperArc getNumberOfSuperArcs() const
void build(const triangulationType *mesh, const bool ct)
Compute the merge.
int printTime(Timer &t, const std::string &s, const int debugLevel=2) const
SimplexId getChunkCount(const SimplexId nbVerts=-1, const SimplexId nbTasks=100) const
SimplexId trunkCTSegmentation(const std::vector< SimplexId > &pendingNodesVerts, const SimplexId begin, const SimplexId stop)
idSuperArc openSuperArc(idNode downNodeId)
SimplexId trunk(const triangulationType *mesh, const bool ct)
idNode makeNode(SimplexId vertexId, SimplexId linked=nullVertex)
void buildSegmentation()
use vert2tree to compute the segmentation of the fresh built merge tree.
void leafGrowth(const triangulationType *mesh)
idSuperArc makeSuperArc(idNode downNodeId, idNode upNodeId)
Node * getNode(idNode nodeId)
void closeSuperArc(idSuperArc superArcId, idNode upNodeId)
std::shared_ptr< Scalars > scalars_
void initVectStates(const SimplexId nbLeaves)
void updateCorrespondingArc(const SimplexId vert, const idSuperArc arc)
void arcGrowth(const triangulationType *mesh, const SimplexId startVert, const SimplexId orig)
SimplexId getVertexId() const
SimplexId getLastVisited() const
void setLastVisited(SimplexId vertId)
long unsigned int idSuperArc
SuperArc index in vect_superArcs_.
SimplexId valence
for vertex up/down valence
unsigned int idNode
Node index in vect_nodes_.
int SimplexId
Identifier type for simplices of any dimension.
T end(std::pair< T, T > &p)
T begin(std::pair< T, T > &p)
void setStartVert(const SimplexId v)
SimplexId getNextMinVertex()
void addNewVertex(const SimplexId v)
std::shared_ptr< FTMAtomicVector< SuperArc > > superArcs
std::vector< AtomicUF > storage
std::shared_ptr< FTMAtomicVector< CurrentState > > states
std::shared_ptr< FTMAtomicVector< Node > > nodes
std::vector< SimplexId > visitOrder
std::vector< UF > propagation
std::shared_ptr< FTMAtomicVector< idNode > > roots
std::vector< valence > valences
std::vector< idNode > leaves
std::vector< char > openedNodes
printMsg(debug::output::BOLD+" | | | | | . \\ | | (__| | / __/| |_| / __/|__ _|"+debug::output::ENDCOLOR, debug::Priority::PERFORMANCE, debug::LineMode::NEW, stream)