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 const 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 const 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 const 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
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 DebugTimer timerSimplify;
349 timerSimplify.reStart();
350 const SimplexId tmpMerge =
351
352 parallelData_.trees[i].getJoinTree()->localSimplify<scalarType>(
353 std::get<0>(seedsPos), std::get<1>(seedsPos));
354#ifdef TTK_ENABLE_OPENMP
355#pragma omp atomic update
356#endif
357 timeSimplify[i] += timerSimplify.getElapsedTime();
358#ifdef TTK_ENABLE_OPENMP
359#pragma omp atomic update
360#endif
361 nbPairMerged += tmpMerge;
362#endif
363 }
364 }
365
366#ifdef TTK_ENABLE_OPENMP
367#pragma omp section
368#endif
369 {
370 if(params_->treeType == TreeType::Split
371 || params_->treeType == TreeType::Contour
372 || params_->treeType == TreeType::JoinAndSplit) {
373
374 DebugTimer timerBuild;
375 parallelData_.trees[i].getSplitTree()->build(
376 vect_baseUF_ST[i], std::get<1>(overlaps), std::get<0>(overlaps),
377 std::get<0>(rangeST), std::get<1>(rangeST),
378 std::get<0>(seedsPos), std::get<1>(seedsPos), mesh);
379 speedProcess[parallelParams_.nbPartitions + i]
380 = partitionSize / timerBuild.getElapsedTime();
381
382#ifdef TTK_ENABLE_CONTOUR_FORESTS_PARALLEL_SIMPLIFY
383 DebugTimer timerSimplify;
384 timerSimplify.reStart();
385 const SimplexId tmpMerge =
386
387 parallelData_.trees[i]
388 .getSplitTree()
389 ->localSimplify<scalarType>(
390 std::get<0>(seedsPos), std::get<1>(seedsPos));
391#ifdef TTK_ENABLE_OPENMP
392#pragma omp atomic update
393#endif
394 timeSimplify[i] += timerSimplify.getElapsedTime();
395#ifdef TTK_ENABLE_OPENMP
396#pragma omp atomic update
397#endif
398 nbPairMerged += tmpMerge;
399#endif
400 }
401 }
402 }
403
404 this->printMsg("Constructed Merge Tree " + std::to_string(i), 1.0,
405 timerMergeTree.getElapsedTime(), this->threadNumber_);
406
407 // Update segmentation of each arc if needed
408 if(params_->simplifyThreshold
409 || params_->treeType != TreeType::Contour) {
410 DebugTimer timerUpdateSegm;
411 parallelData_.trees[i].getJoinTree()->updateSegmentation();
412 parallelData_.trees[i].getSplitTree()->updateSegmentation();
413
414 if(params_->debugLevel >= 3) {
415 this->printMsg("Local MT updated", 1.0,
416 timerUpdateSegm.getElapsedTime(),
417 this->threadNumber_);
418 }
419 }
420
421 // ---------------
422 // Combine JT & ST
423 // ---------------
424
425 if(params_->treeType == TreeType::Contour) {
426 DebugTimer timerCombine;
427
428 // clone here if we do not want to destroy original merge trees!
429 auto *jt = parallelData_.trees[i].getJoinTree();
430 auto *st = parallelData_.trees[i].getSplitTree();
431
432 // Copy missing nodes of a tree to the other one
433 // Maintain this traversal order for good insertion
434 for(idNode t = 0; t < st->getNumberOfNodes(); ++t) {
435 if(!st->getNode(t)->isHidden()) {
436 // std::cout << "insert in jt : " <<
437 // st->getNode(t)->getVertexId() << std::endl;
438 jt->insertNode(st->getNode(t), true);
439 }
440 }
441 // and vice versa
442 for(idNode t = 0; t < jt->getNumberOfNodes(); ++t) {
443 if(!jt->getNode(t)->isHidden()) {
444 // std::cout << "insert in st : " <<
445 // jt->getNode(t)->getVertexId() << std::endl;
446 st->insertNode(jt->getNode(t), true);
447 }
448 }
449
450 // debug print current JT / ST
451 if(params_->debugLevel >= 6) {
452 std::cout << "Local JT :" << std::endl;
453 parallelData_.trees[i].getJoinTree()->printTree2();
454 std::cout << "Local ST :" << std::endl;
455 parallelData_.trees[i].getSplitTree()->printTree2();
456 std::cout << "combine" << std::endl;
457 }
458
459 // Combine, destroy JT and ST to compute CT
460 parallelData_.trees[i].combine(
461 std::get<0>(seedsPos), std::get<1>(seedsPos), this->storage_);
462 parallelData_.trees[i].updateSegmentation();
463
464 if(params_->debugLevel > 2) {
465 printDebug(timerCombine, "Trees combined in ");
466 }
467
468 // debug print CT
469 if(params_->debugLevel >= 4) {
470 parallelData_.trees[i].printTree2();
471 }
472 } else {
473 if(params_->debugLevel >= 6) {
474 std::cout << "Local JT :" << std::endl;
475 parallelData_.trees[i].getJoinTree()->printTree2();
476 std::cout << "Local ST :" << std::endl;
477 parallelData_.trees[i].getSplitTree()->printTree2();
478 std::cout << "combine" << std::endl;
479 }
480 }
481 } // namespace ttk
482
483 // -------------------------------------
484 // Print process speed and simplify info
485 // -------------------------------------
486
487 if(params_->debugLevel > 2) {
488#ifdef TTK_ENABLE_CONTOUR_FORESTS_PARALLEL_SIMPLIFY
489 if(params_->simplifyThreshold) {
490 auto maxSimplifIt
491 = max_element(timeSimplify.cbegin(), timeSimplify.cend());
492 float maxSimplif = *maxSimplifIt;
493 std::cout << "Local simplification maximum time :" << maxSimplif;
494 std::cout << " ( " << nbPairMerged << " pairs merged )" << std::endl;
495 }
496#endif
497 auto maxProcSpeed
498 = max_element(speedProcess.cbegin(), speedProcess.cend());
499 auto minProcSpeed
500 = min_element(speedProcess.cbegin(), speedProcess.cend());
501 std::stringstream msg;
502 msg << "process speed : ";
503 msg << " min is " << *minProcSpeed << " vert/sec";
504 msg << " max is " << *maxProcSpeed << " vert/sec";
505 this->printMsg(msg.str());
506 }
507
508 return 0;
509 }
510
511 template <typename triangulationType>
512 void ContourForests::initOverlap(const triangulationType &mesh) {
513 const SimplexId nbEdges = mesh->getNumberOfEdges();
514
515 // if we choose to have less partition, we still want to use all thread
516 // for overlap init.
517
518 // ------------------
519 // Parallel find border vertices
520 // ------------------
521 // {
522
523 std::vector<std::vector<std::vector<SimplexId>>> lowers(
524 parallelParams_.nbThreads);
525 std::vector<std::vector<std::vector<SimplexId>>> uppers(
526 parallelParams_.nbThreads);
527
528 for(numThread p = 0; p < parallelParams_.nbThreads; p++) {
529 lowers[p].resize(parallelParams_.nbInterfaces);
530 uppers[p].resize(parallelParams_.nbInterfaces);
531 }
532
533#ifdef TTK_ENABLE_OPENMP
534#pragma omp parallel for num_threads(parallelParams_.nbThreads) schedule(static)
535#endif
536 for(SimplexId e = 0; e < nbEdges; e++) {
537
538#ifdef TTK_ENABLE_OPENMP
539 idPartition const part = omp_get_thread_num();
540#else
541 idPartition part = 0;
542#endif
543
544 std::vector<std::vector<SimplexId>> &localUppers = uppers[part];
545 std::vector<std::vector<SimplexId>> &localLowers = lowers[part];
546
547 SimplexId v0, v1;
548 mesh->getEdgeVertex(e, 0, v0);
549 mesh->getEdgeVertex(e, 1, v1);
550
551 for(idInterface i = 0; i < parallelParams_.nbInterfaces; i++) {
552 const bool side0
553 = isHigher(v0, parallelData_.interfaces[i].getSeed());
554 const bool side1
555 = isHigher(v1, parallelData_.interfaces[i].getSeed());
556
557 if(side0 != side1) {
558 // edge cross this interface, add both extrema in it
559 if(side0) {
560 // The seed is already in the partition, we do not want to have it
561 // twice
562 // if (v0 != vect_interfaces_[i].getSeed()) {
563 localUppers[i].emplace_back(v0);
564 //}
565 localLowers[i].emplace_back(v1);
566 } else {
567 // if (v1 != vect_interfaces_[i].getSeed()) {
568 localUppers[i].emplace_back(v1);
569 //}
570 localLowers[i].emplace_back(v0);
571 }
572 }
573 }
574 }
575
576 // }
577 // --------------------------
578 // Insert in interfaces
579 // --------------------------
580 // {
581
582 // reserve
583 std::vector<SimplexId> sizeReserveUp(parallelParams_.nbInterfaces, 0);
584 std::vector<SimplexId> sizeReserveLo(parallelParams_.nbInterfaces, 0);
585 for(numThread p = 0; p < parallelParams_.nbThreads; p++) {
586 for(idInterface i = 0; i < parallelParams_.nbInterfaces; i++) {
587 sizeReserveUp[i] += uppers[p][i].size();
588 sizeReserveLo[i] += lowers[p][i].size();
589 }
590 }
591
592 for(idInterface i = 0; i < parallelParams_.nbInterfaces; i++) {
593 parallelData_.interfaces[i].upReserve(sizeReserveUp[i]);
594 parallelData_.interfaces[i].loReserve(sizeReserveLo[i]);
595 }
596
597 // append
598 for(numThread p = 0; p < parallelParams_.nbThreads; p++) {
599 for(idInterface i = 0; i < parallelParams_.nbInterfaces; i++) {
600 parallelData_.interfaces[i].appendUpper(uppers[p][i]);
601 parallelData_.interfaces[i].appendLower(lowers[p][i]);
602 }
603 }
604
605 // }
606 // -----------------
607 // Sort the overlap
608 // ----------------
609 // {
610
611 auto vertComp
612 = [&](const SimplexId &a, const SimplexId &b) { return isLower(a, b); };
613
614#ifdef TTK_ENABLE_OPENMP
615#pragma omp parallel for num_threads(parallelParams_.nbThreads) schedule(static)
616#endif
617 for(idInterface i = 0; i < parallelParams_.nbInterfaces; i++) {
618 std::vector<SimplexId> &upOverlap
619 = parallelData_.interfaces[i].getUpper();
620 std::vector<SimplexId> &loOverlap
621 = parallelData_.interfaces[i].getLower();
622
623 // sort & unique via set
624
625 // LESS EFFICIENT IN PARALLEL
626 // {
627 // set<SimplexId, decltype(vertComp)> setUpOverlap(upOverlap.begin(),
628 // upOverlap.end(), vertComp); vector<SimplexId>
629 // vectUpOverlap(setUpOverlap.begin(), setUpOverlap.end());
630 // parallelData_.interfaces[i].swapUpper(vectUpOverlap);
631
632 // set<SimplexId, decltype(vertComp)> setLoOverlap(loOverlap.begin(),
633 // loOverlap.end(), vertComp); vector<SimplexId>
634 // vectLoOverlap(setLoOverlap.begin(), setLoOverlap.end());
635 // parallelData_.interfaces[i].swapLower(vectLoOverlap);
636 // }
637
638 // sort & unique via functions
639
640 sort(upOverlap.begin(), upOverlap.end(), vertComp);
641 auto upLast = unique(upOverlap.begin(), upOverlap.end());
642 upOverlap.erase(upLast, upOverlap.end());
643
644 sort(loOverlap.begin(), loOverlap.end(), vertComp);
645 auto loLast = unique(loOverlap.begin(), loOverlap.end());
646 loOverlap.erase(loLast, loOverlap.end());
647 }
648
649 // }
650 // -----------
651 // Debug print
652 // -----------
653 // {
654
655 // for (idInterface i = 0; i < parallelParams_.nbInterfaces; i++) {
656 // cout << "interface : " << i << endl;
657
658 // cout << "upper" << endl;
659 // for (const SimplexId &v : parallelData_.interfaces[i].getUpper()) {
660 // cout << v << ", ";
661 //}
662
663 // cout << endl << "lower" << endl;
664 // for (const SimplexId &v : parallelData_.interfaces[i].getLower()) {
665 // cout << v << ", ";
666 //}
667
668 // cout << endl;
669 //}
670
671 // }
672 }
673
674 } // namespace cf
675} // namespace ttk
Legacy backward compatibility.
Definition Debug.h:472
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
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)
void updateSegmentation()
Definition MergeTree.cpp:44
std::shared_ptr< Params > params_
Definition MergeTree.h:43
std::string to_string(__int128)
Definition ripserpy.cpp:99
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
printMsg(debug::output::BOLD+" | | | | | . \\ | | (__| | / __/| |_| / __/|__ _|"+debug::output::ENDCOLOR, debug::Priority::PERFORMANCE, debug::LineMode::NEW, stream)