Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

FMEMultipoleKernel.h
Go to the documentation of this file.
1 
32 #pragma once
33 
36 
37 namespace ogdf {
38 namespace fast_multipole_embedder {
39 
41  uint32_t begin;
42  uint32_t end;
43 
44  template<typename Func>
45  void for_loop(Func& func) {
46  for (uint32_t i = begin; i <= end; i++) {
47  func(i);
48  }
49  }
50 };
51 
52 class FMEMultipoleKernel : public FMEKernel {
53 public:
54  explicit FMEMultipoleKernel(FMEThread* pThread) : FMEKernel(pThread) { }
55 
58  uint32_t numThreads);
59 
61  static void deallocateContext(FMEGlobalContext* globalContext);
62 
64  void quadtreeConstruction(ArrayPartition& nodePointPartition);
65 
67  void multipoleApproxSingleThreaded(ArrayPartition& nodePointPartition);
68 
70  void multipoleApproxSingleWSPD(ArrayPartition& nodePointPartition);
71 
73  void multipoleApproxNoWSPDStructure(ArrayPartition& nodePointPartition);
74 
76  void multipoleApproxFinal(ArrayPartition& nodePointPartition);
77 
79  void operator()(FMEGlobalContext* globalContext);
80 
82  inline ArrayPartition arrayPartition(uint32_t n) {
83  return arrayPartition(n, threadNr(), numThreads(), 16);
84  }
85 
87  inline ArrayPartition arrayPartition(uint32_t n, uint32_t threadNr, uint32_t numThreads,
88  uint32_t chunkSize) {
89  ArrayPartition result;
90  if (!n) {
91  result.begin = 1;
92  result.end = 0;
93  return result;
94  }
95  if (n >= numThreads * chunkSize) {
96  uint32_t s = n / (numThreads * chunkSize);
97  uint32_t o = s * chunkSize * threadNr;
98  if (threadNr == numThreads - 1) {
99  result.begin = o;
100  result.end = n - 1;
101  } else {
102  result.begin = o;
103  result.end = o + s * chunkSize - 1;
104  }
105  } else {
106  if (threadNr == 0) {
107  result.begin = 0;
108  result.end = n - 1;
109  } else {
110  result.begin = 1;
111  result.end = 0;
112  }
113  }
114  return result;
115  }
116 
118  template<typename F>
119  inline void for_loop(const ArrayPartition& partition, F func) {
120  if (partition.begin > partition.end) {
121  return;
122  }
123  for (uint32_t i = partition.begin; i <= partition.end; i++) {
124  func(i);
125  }
126  }
127 
129  template<typename F>
130  inline void for_tree_partition(F functor) {
132  functor(id);
133  }
134  }
135 
137  template<typename T, typename C>
138  inline void sort_single(T* ptr, uint32_t n, C comparer) {
139  if (isMainThread()) {
140  std::sort(ptr, ptr + n, comparer);
141  }
142  }
143 
145  template<typename T, typename C>
146  inline void sort_parallel(T* ptr, uint32_t n, C comparer) {
147  if (n < numThreads() * 1000 || numThreads() == 1) {
148  sort_single(ptr, n, comparer);
149  } else {
150  sort_parallel(ptr, n, comparer, 0, numThreads());
151  }
152  }
153 
155  template<typename T, typename C>
156  inline void sort_parallel(T* ptr, uint32_t n, C comparer, uint32_t threadNrBegin,
157  uint32_t numThreads) {
158  if (n <= 1) {
159  return;
160  }
161  if (numThreads == 1) {
162  std::sort(ptr, ptr + n, comparer);
163  } else {
164  uint32_t half = n >> 1;
165  uint32_t halfThreads = numThreads >> 1;
166  if (this->threadNr() < threadNrBegin + halfThreads) {
167  sort_parallel(ptr, half, comparer, threadNrBegin, halfThreads);
168  } else {
169  sort_parallel(ptr + half, n - half, comparer, threadNrBegin + halfThreads,
170  halfThreads);
171  }
172 
173  // wait until all threads are ready.
174  sync();
175  if (this->threadNr() == threadNrBegin) {
176  std::inplace_merge(ptr, ptr + half, ptr + n, comparer);
177  }
178  }
179  }
180 
181 private:
184 };
185 
186 }
187 }
ogdf::fast_multipole_embedder::FMEMultipoleKernel::m_pLocalContext
FMELocalContext * m_pLocalContext
Definition: FMEMultipoleKernel.h:183
ogdf
The namespace for all OGDF objects.
Definition: AugmentationModule.h:36
ogdf::fast_multipole_embedder::LinearQuadtree::NodeID
unsigned int NodeID
Definition: LinearQuadtree.h:52
ogdf::fast_multipole_embedder::FMEKernel::sync
void sync()
Definition: FMEKernel.h:48
ogdf::fast_multipole_embedder::ArrayGraph
Definition: ArrayGraph.h:40
ogdf::fast_multipole_embedder::FMEThread
The fast multipole embedder work thread class.
Definition: FMEThread.h:76
ogdf::fast_multipole_embedder::FMEMultipoleKernel
Definition: FMEMultipoleKernel.h:52
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:82
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:119
ogdf::fast_multipole_embedder::FMETreePartition::nodes
std::list< LinearQuadtree::NodeID > nodes
Definition: FMEFunc.h:49
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:146
ogdf::fast_multipole_embedder::ArrayPartition
Definition: FMEMultipoleKernel.h:40
ogdf::fast_multipole_embedder::FMEMultipoleKernel::FMEMultipoleKernel
FMEMultipoleKernel(FMEThread *pThread)
Definition: FMEMultipoleKernel.h:54
FMEFunc.h
Definitions of various auxiliary classes for FME layout.
ogdf::fast_multipole_embedder::FMEKernel
Definition: FMEKernel.h:44
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:66
ogdf::fast_multipole_embedder::FMEGlobalContext
Global Context.
Definition: FMEFunc.h:94
ogdf::fast_multipole_embedder::FMEMultipoleKernel::for_tree_partition
void for_tree_partition(F functor)
for loop on the tree partition
Definition: FMEMultipoleKernel.h:130
ogdf::fast_multipole_embedder::FMELocalContext
Local thread Context.
Definition: FMEFunc.h:115
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:42
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:87
ogdf::fast_multipole_embedder::FMEKernel::threadNr
uint32_t threadNr() const
returns the index of the thread ( 0.. numThreads()-1 )
Definition: FMEKernel.h:51
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:138
ogdf::fast_multipole_embedder::FMEKernel::numThreads
uint32_t numThreads() const
returns the total number of threads in the pool
Definition: FMEKernel.h:54
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:57
ogdf::fast_multipole_embedder::FMEMultipoleKernel::m_pGlobalContext
FMEGlobalContext * m_pGlobalContext
Definition: FMEMultipoleKernel.h:182
FMEKernel.h
Declaration of FME kernel.
ogdf::fast_multipole_embedder::ArrayPartition::for_loop
void for_loop(Func &func)
Definition: FMEMultipoleKernel.h:45
ogdf::fast_multipole_embedder::ArrayPartition::begin
uint32_t begin
Definition: FMEMultipoleKernel.h:41
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:156
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:126