TTK
Loading...
Searching...
No Matches
ContourForestsTemplate.h
Go to the documentation of this file.
1
19
20#pragma once
21
22#include "ContourForests.h"
23
24namespace ttk {
25 namespace cf {
26
27 // ------------------- Contour Forests
28
29 // Process
30 // {
31
32 template <typename scalarType, typename triangulationType>
33 int ContourForests::build(const triangulationType &mesh) {
34
35#ifdef TTK_ENABLE_OPENMP
36 ParallelGuard pg{parallelParams_.nbThreads};
37#endif
38
39 DebugTimer timerTOTAL;
40
41 // -----------
42 // Parameters
43 // -----------
45 initNbScalars(mesh);
47
48 this->printMsg(std::vector<std::vector<std::string>>{
49 {"#Threads", std::to_string(parallelParams_.nbThreads)},
50 {"#Partitions", std::to_string(parallelParams_.nbPartitions)}});
51
52 if(params_->simplifyThreshold) {
53 this->printMsg(std::vector<std::vector<std::string>>{
54 {"Simplify method", std::to_string(params_->simplifyMethod)},
55 {"Simplify thresh.", std::to_string(params_->simplifyThreshold)}});
56 }
57
58 printDebug(timerTOTAL, "Initialization ");
59
60 // ---------
61 // Sort Step
62 // ---------
63
64 DebugTimer timerSort;
65 sortInput<scalarType>();
66 printDebug(timerSort, "Sort scalars (+mirror) ");
67
68 // -------------------
69 // Interface & Overlap
70 // -------------------
71
72 DebugTimer timerInitOverlap;
74 initOverlap(mesh);
75 if(params_->debugLevel > 3) {
76 for(idInterface i = 0; i < parallelParams_.nbInterfaces; i++) {
77 std::cout << "interface : " << static_cast<unsigned>(i);
78 std::cout << " seed : " << parallelData_.interfaces[i].getSeed();
79 std::cout << std::endl;
80 }
81 }
82 printDebug(timerInitOverlap, "Interface and overlap init. ");
83
84 // -----------------------
85 // Allocate parallel trees
86 // -----------------------
87
88 DebugTimer timerAllocPara;
89 // Union find std::vector for each partition
90 std::vector<std::vector<ExtendedUnionFind *>> vect_baseUF_JT(
91 parallelParams_.nbPartitions),
92
93 vect_baseUF_ST(parallelParams_.nbPartitions);
94 const SimplexId &resSize
95 = (scalars_->size / parallelParams_.nbPartitions) / 10;
96
97 parallelData_.trees.clear();
98 parallelData_.trees.reserve(parallelParams_.nbPartitions);
99
100 for(idPartition tree = 0; tree < parallelParams_.nbPartitions; ++tree) {
101 // Tree array initialization
102 parallelData_.trees.emplace_back(params_, scalars_, tree);
103 }
104
105#ifdef TTK_ENABLE_OPENMP
106#pragma omp parallel for num_threads(parallelParams_.nbPartitions) \
107 schedule(static)
108#endif
109 for(idPartition tree = 0; tree < parallelParams_.nbPartitions; ++tree) {
110 // Tree array initialization
111 parallelData_.trees[tree].flush();
112
113 // UF-array reserve
114 vect_baseUF_JT[tree].resize(scalars_->size);
115 vect_baseUF_ST[tree].resize(scalars_->size);
116
117 // Statistical reserve
118 parallelData_.trees[tree].jt_.treeData_.nodes.reserve(resSize);
119 parallelData_.trees[tree].jt_.treeData_.superArcs.reserve(resSize);
120 parallelData_.trees[tree].st_.treeData_.nodes.reserve(resSize);
121 parallelData_.trees[tree].st_.treeData_.superArcs.reserve(resSize);
122 }
123 printDebug(timerAllocPara, "Parallel allocations ");
124
125 // -------------------------
126 // Build trees in partitions
127 // -------------------------
128
129 DebugTimer timerbuild;
130 parallelBuild<scalarType>(vect_baseUF_JT, vect_baseUF_ST, mesh);
131
132 if(params_->debugLevel >= 4) {
133 if(params_->treeType == TreeType::Contour) {
134 for(idPartition i = 0; i < parallelParams_.nbPartitions; i++) {
135 std::cout << i << " :" << std::endl;
136 parallelData_.trees[i].printTree2();
137 std::cout << "-----" << std::endl;
138 }
139 } else {
140 for(idPartition i = 0; i < parallelParams_.nbPartitions; i++) {
141 std::cout << i << " jt:" << std::endl;
142 parallelData_.trees[i].jt_.printTree2();
143 std::cout << i << " st:" << std::endl;
144 parallelData_.trees[i].st_.printTree2();
145 std::cout << "-----" << std::endl;
146 }
147 }
148 }
149
150 printDebug(timerbuild, "ParallelBuild ");
151
152 // --------------------
153 // Stitching partitions
154 // --------------------
155
156 DebugTimer timerZip;
157 if(parallelParams_.partitionNum == -1
158 && parallelParams_.nbPartitions > 1) {
159 stitch();
160 for(idPartition p = 0; p < parallelParams_.nbPartitions; ++p) {
161
162 parallelData_.trees[p].parallelInitNodeValence(
163 parallelParams_.nbThreads);
164 }
165 }
166
167 if(params_->debugLevel >= 4) {
168 printVectCT();
169 }
170
171 printDebug(timerZip, "Stitch ");
172
173 // -------------------------------------------------
174 // Unification : create one tree from stitched trees
175 // -------------------------------------------------
176
177 DebugTimer timerUnify;
178 if(params_->treeType == TreeType::Contour) {
179 if(parallelParams_.partitionNum >= 0) {
180 if(parallelParams_.partitionNum > parallelParams_.nbInterfaces) {
181 clone(&parallelData_.trees[parallelParams_.nbPartitions - 1]);
182 } else {
183 clone(&parallelData_.trees[parallelParams_.partitionNum]);
184 }
185 } else if(parallelParams_.nbPartitions == 1) {
186 clone(&parallelData_.trees[0]);
187 } else {
188 unify();
189 // for global simlify
190 parallelInitNodeValence(parallelParams_.nbThreads);
191 }
192 } else {
193 if(parallelParams_.partitionNum >= 0) {
194 if(parallelParams_.partitionNum > parallelParams_.nbInterfaces) {
195 jt_.clone(&parallelData_.trees[parallelParams_.nbInterfaces].jt_);
196 st_.clone(&parallelData_.trees[parallelParams_.nbInterfaces].st_);
197 } else {
198 jt_.clone(&parallelData_.trees[parallelParams_.partitionNum].jt_);
199 st_.clone(&parallelData_.trees[parallelParams_.partitionNum].st_);
200 }
201 } else if(parallelParams_.nbPartitions == 1) {
202 jt_.clone(&parallelData_.trees[0].jt_);
203 st_.clone(&parallelData_.trees[0].st_);
204 } else {
205 unify();
206 jt_.parallelInitNodeValence(parallelParams_.nbThreads);
207 st_.parallelInitNodeValence(parallelParams_.nbThreads);
208 }
209 }
210
211 printDebug(timerUnify, "Contour tree created ");
212
213 // -------------------
214 // Simplification step
215 // -------------------
216
217 if(params_->treeType == TreeType::Contour
218 && parallelParams_.partitionNum == -1 && params_->simplifyThreshold) {
219 DebugTimer timerGlobalSimplify;
220 SimplexId simplified
221 = globalSimplify<scalarType>(-1, nullVertex, this->storage_, mesh);
222 if(params_->debugLevel >= 1) {
223 printDebug(timerGlobalSimplify, "Simplify Contour tree ");
224 std::cout << " ( " << simplified << " pairs merged )" << std::endl;
225 }
226 }
227
228 printDebug(timerTOTAL, "TOTAL ");
229
230 // ------------------------------
231 // Debug print and memory reclaim
232 // ------------------------------
233
234 if(params_->debugLevel >= 5) {
235 if(params_->treeType == TreeType::Contour)
236 printTree2();
237 else {
238 std::cout << "JT :" << std::endl;
239 jt_.printTree2();
240 std::cout << "ST :" << std::endl;
241 st_.printTree2();
242 }
243 } else if(params_->debugLevel > 2) {
244 std::stringstream msg;
245 if(params_->treeType == TreeType::Contour)
246 msg << "max node : " << getNumberOfNodes();
247 else {
248 msg << "JT max node : " << jt_.getNumberOfNodes();
249 msg << "ST max node : " << st_.getNumberOfNodes();
250 }
251 this->printMsg(msg.str());
252 }
253
254 if(params_->treeType == TreeType::Contour) {
256 } else {
259 }
260
261 // reclaim memory
262 {
263 for(idPartition tree = 0; tree < parallelParams_.nbPartitions; ++tree) {
264 parallelData_.trees[tree].jt_.treeData_.nodes.shrink_to_fit();
265 parallelData_.trees[tree].jt_.treeData_.superArcs.shrink_to_fit();
266 parallelData_.trees[tree].st_.treeData_.nodes.shrink_to_fit();
267 parallelData_.trees[tree].st_.treeData_.superArcs.shrink_to_fit();
268 }
269 // Not while arc segmentation depends on std::vector in partitions
270 // parallelData_.interfaces.clear();
271 // parallelData_.trees.clear();
272 }
273
274 return 0;
275 }
276
277 template <typename scalarType, typename triangulationType>
279 std::vector<std::vector<ExtendedUnionFind *>> &vect_baseUF_JT,
280 std::vector<std::vector<ExtendedUnionFind *>> &vect_baseUF_ST,
281 const triangulationType &mesh) {
282
283 std::vector<float> timeSimplify(parallelParams_.nbPartitions, 0);
284 std::vector<float> speedProcess(parallelParams_.nbPartitions * 2, 0);
285#ifdef TTK_ENABLE_CONTOUR_FORESTS_PARALLEL_SIMPLIFY
286 SimplexId nbPairMerged = 0;
287#endif
288
289#ifdef TTK_ENABLE_OPENMP
290 omp_set_nested(1);
291#endif
292
293// std::cout << "NO PARALLEL DEBUG MODE" << std::endl;
294#ifdef TTK_ENABLE_OPENMP
295#pragma omp parallel for num_threads(parallelParams_.nbPartitions) \
296 schedule(static)
297#endif
298 for(idPartition i = 0; i < parallelParams_.nbPartitions; ++i) {
299 DebugTimer timerMergeTree;
300
301 // ------------------------------------------------------
302 // Skip partition that are not asked to compute if needed
303 // ------------------------------------------------------
304
305 if(parallelParams_.partitionNum != -1
306 && parallelParams_.partitionNum != i)
307 continue;
308
309 // ------------------------------------------------------
310 // Retrieve boundary & overlap list for current partition
311 // ------------------------------------------------------
312
313 std::tuple<SimplexId, SimplexId> rangeJT = getJTRange(i);
314 std::tuple<SimplexId, SimplexId> rangeST = getSTRange(i);
315 std::tuple<SimplexId, SimplexId> seedsPos = getSeedsPos(i);
316 std::tuple<std::vector<SimplexId>, std::vector<SimplexId>> overlaps
317 = getOverlaps(i);
318 const SimplexId &partitionSize
319 = std::abs(std::get<0>(rangeJT) - std::get<1>(rangeJT))
320 + std::get<0>(overlaps).size() + std::get<1>(overlaps).size();
321
322 // ---------------
323 // Build JT and ST
324 // ---------------
325
326#ifdef TTK_ENABLE_OPENMP
327#pragma omp parallel sections num_threads(2) if(parallelParams_.lessPartition)
328#endif
329 {
330
331 // if less partition : we built JT and ST in parallel
332#ifdef TTK_ENABLE_OPENMP
333#pragma omp section
334#endif
335 {
336 if(params_->treeType == TreeType::Join
337 || params_->treeType == TreeType::Contour
338 || params_->treeType == TreeType::JoinAndSplit) {
339 DebugTimer timerSimplify;
340 DebugTimer timerBuild;
341 parallelData_.trees[i].getJoinTree()->build(
342 vect_baseUF_JT[i], std::get<0>(overlaps), std::get<1>(overlaps),
343 std::get<0>(rangeJT), std::get<1>(rangeJT),
344 std::get<0>(seedsPos), std::get<1>(seedsPos), mesh);
345 speedProcess[i] = partitionSize / timerBuild.getElapsedTime();
346
347#ifdef TTK_ENABLE_CONTOUR_FORESTS_PARALLEL_SIMPLIFY
348 timerSimplify.reStart();
349 const SimplexId tmpMerge =
350
351 parallelData_.trees[i].getJoinTree()->localSimplify<scalarType>(
352 std::get<0>(seedsPos), std::get<1>(seedsPos));
353#ifdef TTK_ENABLE_OPENMP
354#pragma omp atomic update
355#endif
356 timeSimplify[i] += timerSimplify.getElapsedTime();
357#ifdef TTK_ENABLE_OPENMP
358#pragma omp atomic update
359#endif
360 nbPairMerged += tmpMerge;
361#endif
362 }
363 }
364
365#ifdef TTK_ENABLE_OPENMP
366#pragma omp section
367#endif
368 {
369 if(params_->treeType == TreeType::Split
370 || params_->treeType == TreeType::Contour
371 || params_->treeType == TreeType::JoinAndSplit) {
372 DebugTimer timerSimplify;
373 DebugTimer timerBuild;
374 parallelData_.trees[i].getSplitTree()->build(
375 vect_baseUF_ST[i], std::get<1>(overlaps), std::get<0>(overlaps),
376 std::get<0>(rangeST), std::get<1>(rangeST),
377 std::get<0>(seedsPos), std::get<1>(seedsPos), mesh);
378 speedProcess[parallelParams_.nbPartitions + i]
379 = partitionSize / timerBuild.getElapsedTime();
380
381#ifdef TTK_ENABLE_CONTOUR_FORESTS_PARALLEL_SIMPLIFY
382 timerSimplify.reStart();
383 const SimplexId tmpMerge =
384
385 parallelData_.trees[i]
386 .getSplitTree()
387 ->localSimplify<scalarType>(
388 std::get<0>(seedsPos), std::get<1>(seedsPos));
389#ifdef TTK_ENABLE_OPENMP
390#pragma omp atomic update
391#endif
392 timeSimplify[i] += timerSimplify.getElapsedTime();
393#ifdef TTK_ENABLE_OPENMP
394#pragma omp atomic update
395#endif
396 nbPairMerged += tmpMerge;
397#endif
398 }
399 }
400 }
401
402 this->printMsg("Constructed Merge Tree " + std::to_string(i), 1.0,
403 timerMergeTree.getElapsedTime(), this->threadNumber_);
404
405 // Update segmentation of each arc if needed
406 if(params_->simplifyThreshold
407 || params_->treeType != TreeType::Contour) {
408 DebugTimer timerUpdateSegm;
409 parallelData_.trees[i].getJoinTree()->updateSegmentation();
410 parallelData_.trees[i].getSplitTree()->updateSegmentation();
411
412 if(params_->debugLevel >= 3) {
413 this->printMsg("Local MT updated", 1.0,
414 timerUpdateSegm.getElapsedTime(),
415 this->threadNumber_);
416 }
417 }
418
419 // ---------------
420 // Combine JT & ST
421 // ---------------
422
423 if(params_->treeType == TreeType::Contour) {
424 DebugTimer timerCombine;
425
426 // clone here if we do not want to destroy original merge trees!
427 auto *jt = parallelData_.trees[i].getJoinTree();
428 auto *st = parallelData_.trees[i].getSplitTree();
429
430 // Copy missing nodes of a tree to the other one
431 // Maintain this traversal order for good insertion
432 for(idNode t = 0; t < st->getNumberOfNodes(); ++t) {
433 if(!st->getNode(t)->isHidden()) {
434 // std::cout << "insert in jt : " <<
435 // st->getNode(t)->getVertexId() << std::endl;
436 jt->insertNode(st->getNode(t), true);
437 }
438 }
439 // and vice versa
440 for(idNode t = 0; t < jt->getNumberOfNodes(); ++t) {
441 if(!jt->getNode(t)->isHidden()) {
442 // std::cout << "insert in st : " <<
443 // jt->getNode(t)->getVertexId() << std::endl;
444 st->insertNode(jt->getNode(t), true);
445 }
446 }
447
448 // debug print current JT / ST
449 if(params_->debugLevel >= 6) {
450 std::cout << "Local JT :" << std::endl;
451 parallelData_.trees[i].getJoinTree()->printTree2();
452 std::cout << "Local ST :" << std::endl;
453 parallelData_.trees[i].getSplitTree()->printTree2();
454 std::cout << "combine" << std::endl;
455 }
456
457 // Combine, destroy JT and ST to compute CT
458 parallelData_.trees[i].combine(
459 std::get<0>(seedsPos), std::get<1>(seedsPos), this->storage_);
460 parallelData_.trees[i].updateSegmentation();
461
462 if(params_->debugLevel > 2) {
463 printDebug(timerCombine, "Trees combined in ");
464 }
465
466 // debug print CT
467 if(params_->debugLevel >= 4) {
468 parallelData_.trees[i].printTree2();
469 }
470 } else {
471 if(params_->debugLevel >= 6) {
472 std::cout << "Local JT :" << std::endl;
473 parallelData_.trees[i].getJoinTree()->printTree2();
474 std::cout << "Local ST :" << std::endl;
475 parallelData_.trees[i].getSplitTree()->printTree2();
476 std::cout << "combine" << std::endl;
477 }
478 }
479 } // namespace ttk
480
481 // -------------------------------------
482 // Print process speed and simplify info
483 // -------------------------------------
484
485 if(params_->debugLevel > 2) {
486#ifdef TTK_ENABLE_CONTOUR_FORESTS_PARALLEL_SIMPLIFY
487 if(params_->simplifyThreshold) {
488 auto maxSimplifIt
489 = max_element(timeSimplify.cbegin(), timeSimplify.cend());
490 float maxSimplif = *maxSimplifIt;
491 std::cout << "Local simplification maximum time :" << maxSimplif;
492 std::cout << " ( " << nbPairMerged << " pairs merged )" << std::endl;
493 }
494#endif
495 auto maxProcSpeed
496 = max_element(speedProcess.cbegin(), speedProcess.cend());
497 auto minProcSpeed
498 = min_element(speedProcess.cbegin(), speedProcess.cend());
499 std::stringstream msg;
500 msg << "process speed : ";
501 msg << " min is " << *minProcSpeed << " vert/sec";
502 msg << " max is " << *maxProcSpeed << " vert/sec";
503 this->printMsg(msg.str());
504 }
505
506 return 0;
507 }
508
509 template <typename triangulationType>
510 void ContourForests::initOverlap(const triangulationType &mesh) {
511 const SimplexId nbEdges = mesh->getNumberOfEdges();
512
513 // if we choose to have less partition, we still want to use all thread
514 // for overlap init.
515
516 // ------------------
517 // Parallel find border vertices
518 // ------------------
519 // {
520
521 std::vector<std::vector<std::vector<SimplexId>>> lowers(
522 parallelParams_.nbThreads);
523 std::vector<std::vector<std::vector<SimplexId>>> uppers(
524 parallelParams_.nbThreads);
525
526 for(numThread p = 0; p < parallelParams_.nbThreads; p++) {
527 lowers[p].resize(parallelParams_.nbInterfaces);
528 uppers[p].resize(parallelParams_.nbInterfaces);
529 }
530
531#ifdef TTK_ENABLE_OPENMP
532#pragma omp parallel for num_threads(parallelParams_.nbThreads) schedule(static)
533#endif
534 for(SimplexId e = 0; e < nbEdges; e++) {
535
536#ifdef TTK_ENABLE_OPENMP
537 idPartition part = omp_get_thread_num();
538#else
539 idPartition part = 0;
540#endif
541
542 std::vector<std::vector<SimplexId>> &localUppers = uppers[part];
543 std::vector<std::vector<SimplexId>> &localLowers = lowers[part];
544
545 SimplexId v0, v1;
546 mesh->getEdgeVertex(e, 0, v0);
547 mesh->getEdgeVertex(e, 1, v1);
548
549 for(idInterface i = 0; i < parallelParams_.nbInterfaces; i++) {
550 const bool side0
551 = isHigher(v0, parallelData_.interfaces[i].getSeed());
552 const bool side1
553 = isHigher(v1, parallelData_.interfaces[i].getSeed());
554
555 if(side0 != side1) {
556 // edge cross this interface, add both extrema in it
557 if(side0) {
558 // The seed is already in the partition, we do not want to have it
559 // twice
560 // if (v0 != vect_interfaces_[i].getSeed()) {
561 localUppers[i].emplace_back(v0);
562 //}
563 localLowers[i].emplace_back(v1);
564 } else {
565 // if (v1 != vect_interfaces_[i].getSeed()) {
566 localUppers[i].emplace_back(v1);
567 //}
568 localLowers[i].emplace_back(v0);
569 }
570 }
571 }
572 }
573
574 // }
575 // --------------------------
576 // Insert in interfaces
577 // --------------------------
578 // {
579
580 // reserve
581 std::vector<SimplexId> sizeReserveUp(parallelParams_.nbInterfaces, 0);
582 std::vector<SimplexId> sizeReserveLo(parallelParams_.nbInterfaces, 0);
583 for(numThread p = 0; p < parallelParams_.nbThreads; p++) {
584 for(idInterface i = 0; i < parallelParams_.nbInterfaces; i++) {
585 sizeReserveUp[i] += uppers[p][i].size();
586 sizeReserveLo[i] += lowers[p][i].size();
587 }
588 }
589
590 for(idInterface i = 0; i < parallelParams_.nbInterfaces; i++) {
591 parallelData_.interfaces[i].upReserve(sizeReserveUp[i]);
592 parallelData_.interfaces[i].loReserve(sizeReserveLo[i]);
593 }
594
595 // append
596 for(numThread p = 0; p < parallelParams_.nbThreads; p++) {
597 for(idInterface i = 0; i < parallelParams_.nbInterfaces; i++) {
598 parallelData_.interfaces[i].appendUpper(uppers[p][i]);
599 parallelData_.interfaces[i].appendLower(lowers[p][i]);
600 }
601 }
602
603 // }
604 // -----------------
605 // Sort the overlap
606 // ----------------
607 // {
608
609 auto vertComp
610 = [&](const SimplexId &a, const SimplexId &b) { return isLower(a, b); };
611
612#ifdef TTK_ENABLE_OPENMP
613#pragma omp parallel for num_threads(parallelParams_.nbThreads) schedule(static)
614#endif
615 for(idInterface i = 0; i < parallelParams_.nbInterfaces; i++) {
616 std::vector<SimplexId> &upOverlap
617 = parallelData_.interfaces[i].getUpper();
618 std::vector<SimplexId> &loOverlap
619 = parallelData_.interfaces[i].getLower();
620
621 // sort & unique via set
622
623 // LESS EFFICIENT IN PARALLEL
624 // {
625 // set<SimplexId, decltype(vertComp)> setUpOverlap(upOverlap.begin(),
626 // upOverlap.end(), vertComp); vector<SimplexId>
627 // vectUpOverlap(setUpOverlap.begin(), setUpOverlap.end());
628 // parallelData_.interfaces[i].swapUpper(vectUpOverlap);
629
630 // set<SimplexId, decltype(vertComp)> setLoOverlap(loOverlap.begin(),
631 // loOverlap.end(), vertComp); vector<SimplexId>
632 // vectLoOverlap(setLoOverlap.begin(), setLoOverlap.end());
633 // parallelData_.interfaces[i].swapLower(vectLoOverlap);
634 // }
635
636 // sort & unique via functions
637
638 sort(upOverlap.begin(), upOverlap.end(), vertComp);
639 auto upLast = unique(upOverlap.begin(), upOverlap.end());
640 upOverlap.erase(upLast, upOverlap.end());
641
642 sort(loOverlap.begin(), loOverlap.end(), vertComp);
643 auto loLast = unique(loOverlap.begin(), loOverlap.end());
644 loOverlap.erase(loLast, loOverlap.end());
645 }
646
647 // }
648 // -----------
649 // Debug print
650 // -----------
651 // {
652
653 // for (idInterface i = 0; i < parallelParams_.nbInterfaces; i++) {
654 // cout << "interface : " << i << endl;
655
656 // cout << "upper" << endl;
657 // for (const SimplexId &v : parallelData_.interfaces[i].getUpper()) {
658 // cout << v << ", ";
659 //}
660
661 // cout << endl << "lower" << endl;
662 // for (const SimplexId &v : parallelData_.interfaces[i].getLower()) {
663 // cout << v << ", ";
664 //}
665
666 // cout << endl;
667 //}
668
669 // }
670 }
671
672 } // namespace cf
673} // namespace ttk
Legacy backward compatibility.
Definition: Debug.h:472
int printMsg(const std::string &msg, const debug::Priority &priority=debug::Priority::INFO, const debug::LineMode &lineMode=debug::LineMode::NEW, std::ostream &stream=std::cout) const
Definition: Debug.h:118
void reStart()
Definition: Timer.h:21
double getElapsedTime()
Definition: Timer.h:15
std::tuple< SimplexId, SimplexId > getSTRange(const idPartition &i) const
int parallelBuild(std::vector< std::vector< ExtendedUnionFind * > > &baseUF_JT, std::vector< std::vector< ExtendedUnionFind * > > &baseUF_ST, const triangulationType &mesh)
int build(const triangulationType &mesh)
void initOverlap(const triangulationType &mesh)
std::tuple< SimplexId, SimplexId > getJTRange(const idPartition &i) const
void printDebug(DebugTimer &timer, const std::string &str)
std::tuple< SimplexId, SimplexId > getSeedsPos(const idPartition &i) const
std::tuple< std::vector< SimplexId >, std::vector< SimplexId > > getOverlaps(const idPartition &i)
idNode getNumberOfNodes() const
Definition: MergeTree.h:235
std::shared_ptr< Scalars > scalars_
Definition: MergeTree.h:44
void initTreeType()
init the type of the current tree from params
Definition: MergeTree.h:77
std::shared_ptr< MergeTree > clone() const
Definition: MergeTree.cpp:1006
bool isHigher(const SimplexId &a, const SimplexId &b) const
Definition: MergeTree.h:649
bool isLower(const SimplexId &a, const SimplexId &b) const
Definition: MergeTree.h:645
void initNbScalars(const triangulationType &tri)
Definition: MergeTree.h:72
void parallelInitNodeValence(const int nbThreadValence)
Definition: MergeTree.cpp:175
void updateSegmentation()
Definition: MergeTree.cpp:44
std::shared_ptr< Params > params_
Definition: MergeTree.h:43
numThread idInterface
index of the interface/partition in vect_interfaces_
numThread idPartition
unsigned int idNode
Node index in vect_nodes_.
ThreadId numThread
type use to store threads related numbers
The Topology ToolKit.
int SimplexId
Identifier type for simplices of any dimension.
Definition: DataTypes.h:22
std::vector< Interface > interfaces
std::vector< ContourForestsTree > trees