Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

Loading...
Searching...
No Matches
FMEMultipoleKernel.h
Go to the documentation of this file.
1
32#pragma once
33
37
38#include <cstdint>
39#include <list>
40
42class ArrayGraph;
43class FMEThread;
44} // namespace ogdf::fast_multipole_embedder
45
46namespace ogdf {
47namespace fast_multipole_embedder {
48
50 uint32_t begin;
51 uint32_t end;
52
53 template<typename Func>
54 void for_loop(Func& func) {
55 for (uint32_t i = begin; i <= end; i++) {
56 func(i);
57 }
58 }
59};
60
62public:
63 explicit FMEMultipoleKernel(FMEThread* pThread) : FMEKernel(pThread) { }
64
67 uint32_t numThreads);
68
70 static void deallocateContext(FMEGlobalContext* globalContext);
71
73 void quadtreeConstruction(ArrayPartition& nodePointPartition);
74
77
79 void multipoleApproxSingleWSPD(ArrayPartition& nodePointPartition);
80
83
85 void multipoleApproxFinal(ArrayPartition& nodePointPartition);
86
88 void operator()(FMEGlobalContext* globalContext);
89
91 inline ArrayPartition arrayPartition(uint32_t n) {
92 return arrayPartition(n, threadNr(), numThreads(), 16);
93 }
94
96 inline ArrayPartition arrayPartition(uint32_t n, uint32_t threadNr, uint32_t numThreads,
97 uint32_t chunkSize) {
98 ArrayPartition result;
99 if (!n) {
100 result.begin = 1;
101 result.end = 0;
102 return result;
103 }
104 if (n >= numThreads * chunkSize) {
105 uint32_t s = n / (numThreads * chunkSize);
106 uint32_t o = s * chunkSize * threadNr;
107 if (threadNr == numThreads - 1) {
108 result.begin = o;
109 result.end = n - 1;
110 } else {
111 result.begin = o;
112 result.end = o + s * chunkSize - 1;
113 }
114 } else {
115 if (threadNr == 0) {
116 result.begin = 0;
117 result.end = n - 1;
118 } else {
119 result.begin = 1;
120 result.end = 0;
121 }
122 }
123 return result;
124 }
125
127 template<typename F>
128 inline void for_loop(const ArrayPartition& partition, F func) {
129 if (partition.begin > partition.end) {
130 return;
131 }
132 for (uint32_t i = partition.begin; i <= partition.end; i++) {
133 func(i);
134 }
135 }
136
138 template<typename F>
139 inline void for_tree_partition(F functor) {
141 functor(id);
142 }
143 }
144
146 template<typename T, typename C>
147 inline void sort_single(T* ptr, uint32_t n, C comparer) {
148 if (isMainThread()) {
149 std::sort(ptr, ptr + n, comparer);
150 }
151 }
152
154 template<typename T, typename C>
155 inline void sort_parallel(T* ptr, uint32_t n, C comparer) {
156 if (n < numThreads() * 1000 || numThreads() == 1) {
157 sort_single(ptr, n, comparer);
158 } else {
159 sort_parallel(ptr, n, comparer, 0, numThreads());
160 }
161 }
162
164 template<typename T, typename C>
165 inline void sort_parallel(T* ptr, uint32_t n, C comparer, uint32_t threadNrBegin,
166 uint32_t numThreads) {
167 if (n <= 1) {
168 return;
169 }
170 if (numThreads == 1) {
171 std::sort(ptr, ptr + n, comparer);
172 } else {
173 uint32_t half = n >> 1;
174 uint32_t halfThreads = numThreads >> 1;
175 if (this->threadNr() < threadNrBegin + halfThreads) {
176 sort_parallel(ptr, half, comparer, threadNrBegin, halfThreads);
177 } else {
178 sort_parallel(ptr + half, n - half, comparer, threadNrBegin + halfThreads,
179 halfThreads);
180 }
181
182 // wait until all threads are ready.
183 sync();
184 if (this->threadNr() == threadNrBegin) {
185 std::inplace_merge(ptr, ptr + half, ptr + n, comparer);
186 }
187 }
188 }
189
190private:
193};
194
195}
196}
Definitions of various auxiliary classes for FME layout.
Declaration of FME kernel.
Declaration of class LinearQuadtree.
bool isMainThread() const
returns true if this is the main thread ( the main thread is always the first thread )
Definition FMEKernel.h:62
uint32_t threadNr() const
returns the index of the thread ( 0.. numThreads()-1 )
Definition FMEKernel.h:56
uint32_t numThreads() const
returns the total number of threads in the pool
Definition FMEKernel.h:59
ArrayPartition arrayPartition(uint32_t n, uint32_t threadNr, uint32_t numThreads, uint32_t chunkSize)
returns an array partition for the given threadNr and thread count
void multipoleApproxSingleThreaded(ArrayPartition &nodePointPartition)
the single threaded version without fences
static FMEGlobalContext * allocateContext(ArrayGraph *pGraph, FMEGlobalOptions *pOptions, uint32_t numThreads)
allocate the global and local contexts used by an instance of this kernel
void sort_parallel(T *ptr, uint32_t n, C comparer)
lazy parallel sorting for num_threads = power of two
void sort_single(T *ptr, uint32_t n, C comparer)
sorting single threaded
void quadtreeConstruction(ArrayPartition &nodePointPartition)
sub procedure for quadtree construction
void multipoleApproxNoWSPDStructure(ArrayPartition &nodePointPartition)
new but slower method, parallel wspd computation without using the wspd structure
ArrayPartition arrayPartition(uint32_t n)
creates an array partition with a default chunksize of 16
static void deallocateContext(FMEGlobalContext *globalContext)
free the global and local context
void sort_parallel(T *ptr, uint32_t n, C comparer, uint32_t threadNrBegin, uint32_t numThreads)
lazy parallel sorting for num_threads = power of two
void multipoleApproxFinal(ArrayPartition &nodePointPartition)
the final version, the wspd structure is only used for the top of the tree
void multipoleApproxSingleWSPD(ArrayPartition &nodePointPartition)
the original algorithm which runs the WSPD completely single threaded
void for_loop(const ArrayPartition &partition, F func)
for loop on a partition
void for_tree_partition(F functor)
for loop on the tree partition
void operator()(FMEGlobalContext *globalContext)
main function of the kernel
The fast multipole embedder work thread class.
Definition FMEThread.h:77
The namespace for all OGDF objects.
the main global options for a run
Definition FMEFunc.h:73
FMETreePartition treePartition
tree partition assigned to the thread
Definition FMEFunc.h:133
std::list< LinearQuadtree::NodeID > nodes
Definition FMEFunc.h:56