Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

FMEMultipoleKernel.h
Go to the documentation of this file.
1 
32 #pragma once
33 
37 
38 #include <cstdint>
39 #include <list>
40 
42 class ArrayGraph;
43 class FMEThread;
44 } // namespace ogdf::fast_multipole_embedder
45 
46 namespace ogdf {
47 namespace 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 
61 class FMEMultipoleKernel : public FMEKernel {
62 public:
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 
76  void multipoleApproxSingleThreaded(ArrayPartition& nodePointPartition);
77 
79  void multipoleApproxSingleWSPD(ArrayPartition& nodePointPartition);
80 
82  void multipoleApproxNoWSPDStructure(ArrayPartition& nodePointPartition);
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 
190 private:
193 };
194 
195 }
196 }
ogdf::fast_multipole_embedder::FMEMultipoleKernel::m_pLocalContext
FMELocalContext * m_pLocalContext
Definition: FMEMultipoleKernel.h:192
ogdf
The namespace for all OGDF objects.
Definition: multilevelmixer.cpp:39
ogdf::fast_multipole_embedder::LinearQuadtree::NodeID
unsigned int NodeID
Definition: LinearQuadtree.h:55
ogdf::fast_multipole_embedder::FMEKernel::sync
void sync()
Definition: FMEKernel.h:53
LinearQuadtree.h
Declaration of class LinearQuadtree.
ogdf::fast_multipole_embedder::ArrayGraph
Definition: ArrayGraph.h:46
ogdf::fast_multipole_embedder::FMEThread
The fast multipole embedder work thread class.
Definition: FMEThread.h:76
ogdf::fast_multipole_embedder::FMEMultipoleKernel
Definition: FMEMultipoleKernel.h:61
ogdf::fast_multipole_embedder::FMEMultipoleKernel::quadtreeConstruction
void quadtreeConstruction(ArrayPartition &nodePointPartition)
sub procedure for quadtree construction
ogdf::fast_multipole_embedder::FMEMultipoleKernel::arrayPartition
ArrayPartition arrayPartition(uint32_t n)
creates an array partition with a default chunksize of 16
Definition: FMEMultipoleKernel.h:91
ogdf::fast_multipole_embedder::FMEMultipoleKernel::multipoleApproxSingleThreaded
void multipoleApproxSingleThreaded(ArrayPartition &nodePointPartition)
the single threaded version without fences
ogdf::fast_multipole_embedder::FMEMultipoleKernel::for_loop
void for_loop(const ArrayPartition &partition, F func)
for loop on a partition
Definition: FMEMultipoleKernel.h:128
ogdf::fast_multipole_embedder::FMETreePartition::nodes
std::list< LinearQuadtree::NodeID > nodes
Definition: FMEFunc.h:56
ogdf::fast_multipole_embedder::FMEMultipoleKernel::sort_parallel
void sort_parallel(T *ptr, uint32_t n, C comparer)
lazy parallel sorting for num_threads = power of two
Definition: FMEMultipoleKernel.h:155
ogdf::fast_multipole_embedder::ArrayPartition
Definition: FMEMultipoleKernel.h:49
ogdf::fast_multipole_embedder::FMEMultipoleKernel::FMEMultipoleKernel
FMEMultipoleKernel(FMEThread *pThread)
Definition: FMEMultipoleKernel.h:63
FMEFunc.h
Definitions of various auxiliary classes for FME layout.
ogdf::fast_multipole_embedder::FMEKernel
Definition: FMEKernel.h:49
ogdf::fast_multipole_embedder::FMEMultipoleKernel::allocateContext
static FMEGlobalContext * allocateContext(ArrayGraph *pGraph, FMEGlobalOptions *pOptions, uint32_t numThreads)
allocate the global and local contexts used by an instance of this kernel
Minisat::Internal::sort
void sort(T *array, int size, LessThan lt)
Definition: Sort.h:57
ogdf::fast_multipole_embedder::FMEGlobalOptions
the main global options for a run
Definition: FMEFunc.h:73
ogdf::fast_multipole_embedder::FMEGlobalContext
Global Context.
Definition: FMEFunc.h:101
ogdf::fast_multipole_embedder::FMEMultipoleKernel::for_tree_partition
void for_tree_partition(F functor)
for loop on the tree partition
Definition: FMEMultipoleKernel.h:139
ogdf::fast_multipole_embedder::FMELocalContext
Local thread Context.
Definition: FMEFunc.h:122
ogdf::fast_multipole_embedder::FMEMultipoleKernel::operator()
void operator()(FMEGlobalContext *globalContext)
main function of the kernel
ogdf::fast_multipole_embedder::ArrayPartition::end
uint32_t end
Definition: FMEMultipoleKernel.h:51
ogdf::fast_multipole_embedder::FMEMultipoleKernel::arrayPartition
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
Definition: FMEMultipoleKernel.h:96
ogdf::fast_multipole_embedder::FMEKernel::threadNr
uint32_t threadNr() const
returns the index of the thread ( 0.. numThreads()-1 )
Definition: FMEKernel.h:56
ogdf::fast_multipole_embedder::FMEMultipoleKernel::deallocateContext
static void deallocateContext(FMEGlobalContext *globalContext)
free the global and local context
ogdf::fast_multipole_embedder::FMEMultipoleKernel::sort_single
void sort_single(T *ptr, uint32_t n, C comparer)
sorting single threaded
Definition: FMEMultipoleKernel.h:147
ogdf::fast_multipole_embedder::FMEKernel::numThreads
uint32_t numThreads() const
returns the total number of threads in the pool
Definition: FMEKernel.h:59
ogdf::fast_multipole_embedder
Definition: ArrayGraph.h:44
ogdf::fast_multipole_embedder::FMEKernel::isMainThread
bool isMainThread() const
returns true if this is the main thread ( the main thread is always the first thread )
Definition: FMEKernel.h:62
ogdf::fast_multipole_embedder::FMEMultipoleKernel::m_pGlobalContext
FMEGlobalContext * m_pGlobalContext
Definition: FMEMultipoleKernel.h:191
FMEKernel.h
Declaration of FME kernel.
ogdf::fast_multipole_embedder::ArrayPartition::for_loop
void for_loop(Func &func)
Definition: FMEMultipoleKernel.h:54
ogdf::fast_multipole_embedder::ArrayPartition::begin
uint32_t begin
Definition: FMEMultipoleKernel.h:50
ogdf::fast_multipole_embedder::FMEMultipoleKernel::multipoleApproxNoWSPDStructure
void multipoleApproxNoWSPDStructure(ArrayPartition &nodePointPartition)
new but slower method, parallel wspd computation without using the wspd structure
ogdf::fast_multipole_embedder::FMEMultipoleKernel::sort_parallel
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
Definition: FMEMultipoleKernel.h:165
ogdf::fast_multipole_embedder::FMEMultipoleKernel::multipoleApproxFinal
void multipoleApproxFinal(ArrayPartition &nodePointPartition)
the final version, the wspd structure is only used for the top of the tree
ogdf::fast_multipole_embedder::FMEMultipoleKernel::multipoleApproxSingleWSPD
void multipoleApproxSingleWSPD(ArrayPartition &nodePointPartition)
the original algorithm which runs the WSPD completely single threaded
ogdf::fast_multipole_embedder::FMELocalContext::treePartition
FMETreePartition treePartition
tree partition assigned to the thread
Definition: FMEFunc.h:133