TTK
Loading...
Searching...
No Matches
Graph.h
Go to the documentation of this file.
1
12
13#pragma once
14
15#include "FTRAtomicVector.h"
16#include "FTRCommon.h"
17#include "FTRDataTypes.h"
18#include "FTRNode.h"
19#include "FTRPropagation.h"
20#include "FTRScalars.h"
21#include "FTRSuperArc.h"
22
23#ifndef TTK_ENABLE_KAMIKAZE
24#include <iostream>
25#endif
26
27#include <map>
28#include <random>
29#include <vector>
30
31namespace ttk {
32 namespace ftr {
33 struct SegmInfo {
34 idNode corNode = nullNode;
35 idSuperArc corArc = nullSuperArc;
36 };
37
38 class Graph : public Allocable {
39 private:
40 // update operator =
44
45 std::vector<SegmInfo> segmentation_;
46
47#ifdef TTK_ENABLE_FTR_VERT_STATS
48 std::vector<idVertex> nbTouch_;
49 std::vector<idSuperArc> nbArcActif_;
50 idVertex avoided_;
51#endif
52
53 public:
54 // For openmp capture, we need direct access...
55 std::vector<valence> valDown_, valUp_;
56
58 Graph(Graph &&other) noexcept = default;
59 Graph(const Graph &other) = delete;
60 ~Graph() override;
61
62 Graph &operator=(Graph &&other) noexcept {
63 if(this != &other) {
64 leaves_ = std::move(other.leaves_);
65 nodes_ = std::move(other.nodes_);
66 arcs_ = std::move(other.arcs_);
67 segmentation_ = std::move(other.segmentation_);
68 valDown_ = std::move(other.valDown_);
69 valUp_ = std::move(other.valUp_);
70#ifdef TTK_ENABLE_FTR_VERT_STATS
71 nbTouch_ = std::move(other.nbTouch_);
72 nbArcActif_ = std::move(other.nbArcActif_);
73 avoided_ = std::move(other.avoided_);
74#endif
75 }
76 return *this;
77 }
78
79 Graph &operator=(Graph &other) = delete;
80
81 // Accessor on structure
82 // ---------------------
83
85 return nodes_.size();
86 }
87
89 return arcs_.size();
90 }
91
93 idSuperArc res = 0;
94 for(const auto &arc : arcs_) {
95 if(arc.isVisible())
96 ++res;
97 }
98 return res;
99 }
100
102 return leaves_.size();
103 }
104
105 idVertex getLeaf(const idNode id) const {
106 return std::get<0>(leaves_[id]);
107 }
108
109 bool isLeafFromMin(const idNode id) const {
110 return std::get<1>(leaves_[id]);
111 }
112
113 const Node &getNode(const idNode id) const {
114 return nodes_[id];
115 }
116
117 Node &getNode(const idNode id) {
118 return nodes_[id];
119 }
120
121 const SuperArc &getArc(const idSuperArc id) const {
122 return arcs_[id];
123 }
124
126 return arcs_[id];
127 }
128
129 bool isVisited(const idVertex v) const {
130 return segmentation_[v].corArc != nullSuperArc
131 || segmentation_[v].corNode != nullNode;
132 }
133
134 void visit(const idVertex v, const idSegmentation id, bool isArc = true) {
135 if(isArc) {
136 if(segmentation_[v].corArc == nullSuperArc) {
137 segmentation_[v].corArc = id;
138 }
139 } else {
140 if(segmentation_[v].corNode == nullNode) {
141 segmentation_[v].corNode = id;
142 }
143 }
144 }
145
146#ifdef TTK_ENABLE_FTR_VERT_STATS
147 void incTouch(const idVertex v) {
148#ifdef TTK_ENABLE_OPENMP
149#pragma omp atomic update
150#endif
151 nbTouch_[v]++;
152 }
153
154 idVertex getNbTouch(const idVertex v) const {
155 return nbTouch_[v];
156 }
157
158 void setNbArcActive(const idVertex v, const idSuperArc nb) {
159#ifdef TTK_ENABLE_OPENMP
160#pragma omp atomic write
161#endif
162 nbArcActif_[v] = nb;
163 }
164
165 idSuperArc getNbArcActive(const idVertex v) const {
166 return nbArcActif_[v];
167 }
168
169 void incAvoid() {
170#ifdef TTK_ENABLE_OPENMP
171#pragma omp atomic update
172#endif
173 avoided_++;
174 }
175
176 idVertex getNbAvoided() const {
177 return avoided_;
178 }
179
180 idVertex getNbMultiTouch() const {
181 auto gt1 = [](uint i) { return i > 1; };
182 return std::count_if(nbTouch_.cbegin(), nbTouch_.cend(), gt1);
183 }
184#endif
185
186 void setArc(const idVertex v, const idSegmentation id) {
187 segmentation_[v].corArc = id;
188 }
189
190 std::tuple<idNode, idSuperArc> visit(const idVertex v) const {
191 return {segmentation_[v].corNode, segmentation_[v].corArc};
192 }
193
194 bool isArc(const idVertex v) const {
195 return segmentation_[v].corArc != nullSuperArc;
196 }
197
198 bool isArc(const idVertex v, const idSuperArc id) const {
199 return segmentation_[v].corArc == id;
200 }
201
202 bool isNode(const idVertex v) const {
203 return segmentation_[v].corNode != nullNode;
204 }
205
206 bool isNode(const idVertex v, const idNode id) const {
207 return segmentation_[v].corNode != id;
208 }
209
210 idNode getNodeId(const idVertex v) const {
211 return segmentation_[v].corNode;
212 }
213
214 idSuperArc getArcId(const idVertex v) const {
215 return segmentation_[v].corArc;
216 }
217
218 const Node &getDownNode(const idSuperArc a) const {
219 return getNode(getArc(a).getDownNodeId());
220 }
221
222 // direct access for openmp capture
223 const valence &valUp(const idVertex v) const {
224 return valUp_[v];
225 }
226
228 return valUp_[v];
229 }
230
231 const valence &valDown(const idVertex v) const {
232 return valDown_[v];
233 }
234
236 return valDown_[v];
237 }
238
239 // Build structure
240 // ---------------
241
242 void addLeaf(const idVertex v, bool isMax) {
243 leaves_.emplace_back(std::make_tuple(v, isMax));
244 }
245
246 // return either a new node or the existing one if this vertex
247 // already corresponds to a node.
249 return std::get<0>(getOrCreateNode(v));
250 }
251
252 // create a node in v if no node exists yet, then
253 // return the id of the node on v.
254 // The bool is true if a node has been created
255 // This method is not thread safe
256 std::tuple<idNode, bool> getOrCreateNode(const idVertex v) {
257 if(isNode(v)) {
258 return {getNodeId(v), false};
259 }
260
261 const idNode newNode = nodes_.getNext();
262 nodes_[newNode].setVerterIdentifier(v);
263 visit(v, newNode, false);
264 return {newNode, true};
265 }
266
267 idSuperArc openArc(const idNode downId, Propagation *p = nullptr) {
268 idSuperArc const newArc = arcs_.getNext();
269 arcs_[newArc].setDownNodeId(downId);
270 if(p) {
271 arcs_[newArc].setUfProp(p->getId());
272 }
273#ifndef TTK_ENABLE_KAMIKAZE
274 else {
275 std::cout << "NULL PROP IN ARC " << static_cast<unsigned>(newArc)
276 << std::endl;
277 }
278#endif
279 return newArc;
280 }
281
282 void closeArc(const idSuperArc arc, const idNode upId) {
283 arcs_[arc].setUpNodeId(upId);
284 }
285
286 void makeArc(const idNode downId, const idNode upId) {
287 arcs_.emplace_back(SuperArc{downId, upId});
288 }
289
291 idSuperArc const newArc = arcs_.getNext();
292 arcs_[newArc].hide();
293 arcs_[newArc].setUfProp(lp->getId());
294 return newArc;
295 }
296
297 // Process
298 // -------
299
300 // sort leaves vector by scalar value,
301 // can be done in parallel
302 template <typename ScalarType>
304 const bool parallel = false) {
305 auto compare_fun
306 = [&](std::tuple<idVertex, bool> a, std::tuple<idVertex, bool> b) {
307 return s->isLower(std::get<0>(a), std::get<0>(b));
308 };
309 if(parallel) {
310 TTK_PSORT(
311 this->threadNumber_, leaves_.begin(), leaves_.end(), compare_fun);
312 } else {
313 std::sort(leaves_.begin(), leaves_.end(), compare_fun);
314 }
315 }
316
318 std::shuffle(leaves_.begin(), leaves_.end(), std::random_device());
319 }
320
321 // some arc may be pending due to symbolic merge during computation
322 // if tasks from both min and max.
323 // here we replace them by one consistent arc
324 template <typename ScalarType>
325 void mergeArcs(const Scalars<ScalarType> *const s);
326
327 // Link nodes to arcs when arc are completely created
328 template <typename ScalarType>
329 void arcs2nodes(const Scalars<ScalarType> *const s);
330
331 // Build the list of regular vertices of each arc
332 template <typename ScalarType>
333 void buildArcSegmentation(const Scalars<ScalarType> *const s);
334
335 // Tools
336 // -----
337
338 std::string print(const int verbosity) const;
339
340 std::string printArc(const idSuperArc arcId) const;
341
342 std::string printNode(const idNode nodeId) const;
343
344 std::string printVisit(const idVertex v) const;
345
346 // DEBUG function
347 std::string printVisit() const;
348
349 // Initialize functions
350 // --------------------
351
352 void alloc() override;
353
354 void init() override;
355
356 private:
357 // tools
358
359 // ensure that main arc have valid up/down node even if the merge of
360 // the two arc occurred during the computation, leaving some unfinished
361 // arcs.
362 template <typename ScalarType>
363 void consolidateArc(const idSuperArc mainArc,
364 const idSuperArc mergedArc,
365 const Scalars<ScalarType> *const s);
366 };
367
368 } // namespace ftr
369} // namespace ttk
370
371#include "Graph_Template.h"
#define TTK_PSORT(NTHREADS,...)
Parallel sort macro.
Definition OpenMP.h:46
TTK processing package that manage a parallel version of vector Same as in FTM: Common ?
std::size_t size() const
void emplace_back(const type &elmt)
TTK FTRGraph graph skeleton.
Definition Graph.h:38
void shuffleLeaves()
Definition Graph.h:317
std::tuple< idNode, bool > getOrCreateNode(const idVertex v)
Definition Graph.h:256
idSuperArc openArc(const idNode downId, Propagation *p=nullptr)
Definition Graph.h:267
bool isLeafFromMin(const idNode id) const
Definition Graph.h:109
const valence & valUp(const idVertex v) const
Definition Graph.h:223
idNode makeNode(const idVertex v)
Definition Graph.h:248
std::string printNode(const idNode nodeId) const
Definition Graph.cpp:90
void closeArc(const idSuperArc arc, const idNode upId)
Definition Graph.h:282
bool isArc(const idVertex v, const idSuperArc id) const
Definition Graph.h:198
idNode getNumberOfLeaves() const
Definition Graph.h:101
bool isNode(const idVertex v, const idNode id) const
Definition Graph.h:206
Graph & operator=(Graph &&other) noexcept
Definition Graph.h:62
const valence & valDown(const idVertex v) const
Definition Graph.h:231
idNode getNumberOfNodes() const
Definition Graph.h:84
void arcs2nodes(const Scalars< ScalarType > *const s)
void buildArcSegmentation(const Scalars< ScalarType > *const s)
SuperArc & getArc(const idSuperArc id)
Definition Graph.h:125
idSuperArc getNumberOfArcs() const
Definition Graph.h:88
bool isArc(const idVertex v) const
Definition Graph.h:194
void sortLeaves(const Scalars< ScalarType > *s, const bool parallel=false)
Definition Graph.h:303
std::string printArc(const idSuperArc arcId) const
Definition Graph.cpp:54
std::string printVisit() const
Definition Graph.cpp:117
std::vector< valence > valUp_
Definition Graph.h:55
void visit(const idVertex v, const idSegmentation id, bool isArc=true)
Definition Graph.h:134
bool isNode(const idVertex v) const
Definition Graph.h:202
Graph(Graph &&other) noexcept=default
valence & valDown(const idVertex v)
Definition Graph.h:235
idSuperArc getArcId(const idVertex v) const
Definition Graph.h:214
const SuperArc & getArc(const idSuperArc id) const
Definition Graph.h:121
const Node & getNode(const idNode id) const
Definition Graph.h:113
~Graph() override
bool isVisited(const idVertex v) const
Definition Graph.h:129
std::vector< valence > valDown_
Definition Graph.h:55
idVertex getLeaf(const idNode id) const
Definition Graph.h:105
Graph(const Graph &other)=delete
void init() override
Definition Graph.cpp:150
idSuperArc makeHiddenArc(Propagation *const lp)
Definition Graph.h:290
Node & getNode(const idNode id)
Definition Graph.h:117
void makeArc(const idNode downId, const idNode upId)
Definition Graph.h:286
idNode getNodeId(const idVertex v) const
Definition Graph.h:210
void addLeaf(const idVertex v, bool isMax)
Definition Graph.h:242
void alloc() override
Definition Graph.cpp:130
void setArc(const idVertex v, const idSegmentation id)
Definition Graph.h:186
void mergeArcs(const Scalars< ScalarType > *const s)
Graph & operator=(Graph &other)=delete
const Node & getDownNode(const idSuperArc a) const
Definition Graph.h:218
std::tuple< idNode, idSuperArc > visit(const idVertex v) const
Definition Graph.h:190
valence & valUp(const idVertex v)
Definition Graph.h:227
std::string print(const int verbosity) const
Definition Graph.cpp:14
idSuperArc getNumberOfVisibleArcs() const
Definition Graph.h:92
TTK FTRGraph node of the Graph.
Definition FTRNode.h:20
TTK fTRGraph propagation management with Fibonacci heaps.
bool isLower(const idVertex a, const idVertex b) const
Definition FTRScalars.h:119
TTK FTRGraph graph arc.
Definition FTRSuperArc.h:30
long int idSegmentation
retains history
long unsigned int idSuperArc
SuperArc index in vect_superArcs_.
SimplexId valence
for vertex up/down valence
SimplexId idVertex
Vertex index in scalars_.
unsigned int idNode
Node index in vect_nodes_.
The Topology ToolKit.
idSuperArc corArc
Definition Graph.h:35
idNode corNode
Definition Graph.h:34