OpenLB 1.7
Loading...
Searching...
No Matches
Public Member Functions | List of all members
olb::HeuristicLoadBalancer< T > Class Template Referencefinal

Constructs a load balancer from a given cuboid geometry using a heurist. More...

#include <heuristicLoadBalancer.h>

+ Inheritance diagram for olb::HeuristicLoadBalancer< T >:
+ Collaboration diagram for olb::HeuristicLoadBalancer< T >:

Public Member Functions

 HeuristicLoadBalancer ()
 
 ~HeuristicLoadBalancer () override
 
 HeuristicLoadBalancer (CuboidGeometry3D< T > &cGeometry3d, const double ratioFullEmpty=1., const double weightEmpty=.0)
 
 HeuristicLoadBalancer (CuboidGeometry2D< T > &cGeometry2d, const double ratioFullEmpty=1., const double weightEmpty=.0)
 
void reInit (CuboidGeometry3D< T > &cGeometry3d, const double ratioFullEmpty=1., const double weightEmpty=.0)
 
void reInit (CuboidGeometry2D< T > &cGeometry2d, const double ratioFullEmpty=1., const double weightEmpty=.0)
 
void swap (HeuristicLoadBalancer< T > &loadBalancer)
 
- Public Member Functions inherited from olb::LoadBalancer< T >
 LoadBalancer (int size=1)
 Default empty constructor.
 
 LoadBalancer (int size, std::map< int, int > &loc, std::vector< int > &glob, std::map< int, int > &rank)
 Constructor accepting existing balancing.
 
 LoadBalancer (int size, std::map< int, int > &loc, std::vector< int > &glob, std::map< int, int > &rank, std::map< int, Platform > &platform)
 Constructor accepting existing heterogeneous balancing.
 
virtual ~LoadBalancer ()
 Default empty destructor.
 
void swap (LoadBalancer< T > &loadBalancer)
 Swap method.
 
bool isLocal (const int &glob)
 returns whether glob is on this process
 
int loc (const int &glob)
 
int loc (int glob) const
 
int glob (int loc) const
 
int rank (const int &glob)
 
int rank (int glob) const
 
int size () const
 
int getRankSize () const
 
virtual Platform platform (int loc) const
 
virtual void setPlatform (int loc, Platform platform)
 
bool operator== (const LoadBalancer< T > &rhs) const
 equal operator
 
std::size_t getNblock () const override
 Number of data blocks for the serializable interface.
 
std::size_t getSerializableSize () const override
 Binary size for the serializer.
 
bool * getBlock (std::size_t iBlock, std::size_t &sizeBlock, bool loadingMode) override
 Return a pointer to the memory of the current block and its size for the serializable interface.
 
void print (bool multiOutput=false) const
 
- Public Member Functions inherited from olb::Serializable
virtual ~Serializable ()=default
 
template<bool includeLogOutputDir = true>
bool save (std::string fileName="", const bool enforceUint=false)
 Save Serializable into file fileName
 
template<bool includeLogOutputDir = true>
bool load (std::string fileName="", const bool enforceUint=false)
 Load Serializable from file fileName
 
bool save (std::uint8_t *buffer)
 Save Serializable into buffer of length getSerializableSize
 
bool load (const std::uint8_t *buffer)
 Load Serializable from buffer of length getSerializableSize
 
virtual void postLoad ()
 

Additional Inherited Members

- Protected Member Functions inherited from olb::BufferSerializable
template<typename DataType >
void registerSerializable (const std::size_t iBlock, std::size_t &sizeBlock, std::size_t &currentBlock, size_t &sizeBufferIndex, bool *&dataPtr, DataType &data, const bool loadingMode=false)
 Register Serializable object of dynamic size.
 
template<typename DataType >
void registerStdVectorOfVars (const std::size_t iBlock, std::size_t &sizeBlock, std::size_t &currentBlock, size_t &sizeBufferIndex, bool *&dataPtr, std::vector< DataType > &data, const bool loadingMode=false)
 Method for registering a std::vector<DataType> of primitive DataType (int, double, ...)
 
template<typename DataType >
void registerStdVectorOfSerializablesOfConstSize (const std::size_t iBlock, std::size_t &sizeBlock, std::size_t &currentBlock, size_t &sizeBufferIndex, bool *&dataPtr, std::vector< DataType > &data, const bool loadingMode=false)
 Method for registering a std::vector<DataType> of constant-sized Serializable
 
template<typename DataType >
void registerStdVectorOfSerializables (const std::size_t iBlock, std::size_t &sizeBlock, std::size_t &currentBlock, size_t &sizeBufferIndex, bool *&dataPtr, std::vector< DataType > &data, const bool loadingMode=false)
 Method for registering a std::vector<DataType> of dynamic-sized DataType
 
template<typename DataTypeKey , typename DataTypeValue >
void registerMap (const std::size_t iBlock, std::size_t &sizeBlock, std::size_t &currentBlock, size_t &sizeBufferIndex, bool *&dataPtr, std::map< DataTypeKey, DataTypeValue > &data, const bool loadingMode=false)
 Method for registering a std::map<DataTypeKey, DataTypeValue> of fixed-sized types (i.e. int, double)
 
size_t addSizeToBuffer (const std::size_t iBlock, std::size_t &sizeBlock, std::size_t &currentBlock, size_t &sizeBufferIndex, bool *&dataPtr, const size_t data) const
 Add a size_t to the sizeBuffer in the n-th util::round and return that size_t in all successive rounds.
 
- Protected Member Functions inherited from olb::Serializable
template<typename DataType >
void registerVar (const std::size_t iBlock, std::size_t &sizeBlock, std::size_t &currentBlock, bool *&dataPtr, const DataType &data, const size_t arrayLength=1) const
 Register primitive data types (int, double, ...) or arrays of those.
 
template<typename DataType >
void registerSerializableOfConstSize (const std::size_t iBlock, std::size_t &sizeBlock, std::size_t &currentBlock, bool *&dataPtr, DataType &data, const bool loadingMode=false)
 Register Serializable object of constant size.
 
template<typename DataType >
void registerSerializablesOfConstSize (const std::size_t iBlock, std::size_t &sizeBlock, std::size_t &currentBlock, bool *&dataPtr, DataType *data, const size_t arrayLength, const bool loadingMode=false)
 Register an array of Serializable objects of constant size.
 
- Protected Attributes inherited from olb::LoadBalancer< T >
int _size
 number of cuboids after shrink -1 in appropriate thread
 
std::map< int, int > _loc
 maps global cuboid to (local) thread cuboid
 
std::vector< int > _glob
 content is 0,1,2,...,_size
 
std::map< int, int > _rank
 maps global cuboid number to the processing thread
 
std::map< int, Platform_platform
 maps global cuboid number to local platform
 
- Protected Attributes inherited from olb::BufferSerializable
std::vector< bool * > _dataBuffer
 Data buffer for data that has to be buffered between two getBlock() iterations.
 
std::vector< size_t > _sizeBuffer
 std::vector of integer buffers (e.g. for std::vector size) to be buffered for the whole iteration process
 

Detailed Description

template<typename T>
class olb::HeuristicLoadBalancer< T >

Constructs a load balancer from a given cuboid geometry using a heurist.

Parameters
cGeometrycuboid geometry to base the load balance on
blockGeometryused to determine number of full and empty cells if given
ratioFullEmptytime it takes for full cells in relation to empty cells

This class has a virtual method call in its destructor and should therefore not be used as a base class.

Definition at line 51 of file heuristicLoadBalancer.h.

Constructor & Destructor Documentation

◆ HeuristicLoadBalancer() [1/3]

template<typename T >
olb::HeuristicLoadBalancer< T >::HeuristicLoadBalancer ( )
inline

Definition at line 63 of file heuristicLoadBalancer.h.

63{};

◆ ~HeuristicLoadBalancer()

template<typename T >
olb::HeuristicLoadBalancer< T >::~HeuristicLoadBalancer ( )
override

Definition at line 60 of file heuristicLoadBalancer.hh.

61{
62}

◆ HeuristicLoadBalancer() [2/3]

template<typename T >
olb::HeuristicLoadBalancer< T >::HeuristicLoadBalancer ( CuboidGeometry3D< T > & cGeometry3d,
const double ratioFullEmpty = 1.,
const double weightEmpty = .0 )

Definition at line 44 of file heuristicLoadBalancer.hh.

46 : _ratioFullEmpty(ratioFullEmpty)
47{
48 reInit(cGeometry3d, ratioFullEmpty, weightEmpty);
49}
void reInit(CuboidGeometry3D< T > &cGeometry3d, const double ratioFullEmpty=1., const double weightEmpty=.0)

References olb::HeuristicLoadBalancer< T >::reInit().

+ Here is the call graph for this function:

◆ HeuristicLoadBalancer() [3/3]

template<typename T >
olb::HeuristicLoadBalancer< T >::HeuristicLoadBalancer ( CuboidGeometry2D< T > & cGeometry2d,
const double ratioFullEmpty = 1.,
const double weightEmpty = .0 )

Definition at line 52 of file heuristicLoadBalancer.hh.

54 : _ratioFullEmpty(ratioFullEmpty)
55{
56 reInit(cGeometry2d, ratioFullEmpty, weightEmpty);
57}

References olb::HeuristicLoadBalancer< T >::reInit().

+ Here is the call graph for this function:

Member Function Documentation

◆ reInit() [1/2]

template<typename T >
void olb::HeuristicLoadBalancer< T >::reInit ( CuboidGeometry2D< T > & cGeometry2d,
const double ratioFullEmpty = 1.,
const double weightEmpty = .0 )

Definition at line 221 of file heuristicLoadBalancer.hh.

222{
223 _ratioFullEmpty = ratioFullEmpty;
224 this->_glob.clear();
225 _cGeometry2d = &cGeometry2d;
226 int rank = 0;
227 int size = 1;
228 int nC = _cGeometry2d->getNc();
229#ifdef PARALLEL_MODE_MPI
231 size = util::max<int>(singleton::mpi().getSize(), 1);
232#endif
233 //int xN, yN;
234 //T globX, globY;//, delta;
235 //boost::shared_array<int> tempInCN(new int[nC]);
236
237 std::vector<int> cuboidToThread(nC);
238 std::vector<int> partitionResult(nC);
239 std::vector<int> vwgt(nC); // node weights
240 std::vector<int> taken(nC, 0);
241 std::vector<int> currentLoad(size, 0);
242
243 if (size == 1) {
244 for (int i = 0; i < nC; ++i) {
245 this->_glob.push_back(i);
246 this->_loc[i] = i;
247 this->_rank[i] = 0;
248 };
249 this->_size = nC;
250 return;
251 }
252
253 if (rank == 0) {
254 for ( int iC = 0; iC < nC; iC++) { // assemble neighbourhood information
255
256 int fullCells = _cGeometry2d->get(iC).getWeight();
257 vwgt[iC] = int(weightEmpty*(_cGeometry2d->get(iC).getLatticeVolume() - fullCells)) + int(ratioFullEmpty * fullCells);
258
259 }
260
261 int maxLoad = -1;
262 int maxIC = -1;
263 do {
264 maxLoad = -1;
265 maxIC = -1;
266 for ( int iC = 0 ; iC < nC; iC++) {
267 if (taken[iC] == 0 && vwgt[iC] > maxLoad) {
268 maxLoad = vwgt[iC];
269 maxIC = iC;
270 }
271 }
272
273 if (maxIC != -1) {
274 double minLoad = currentLoad[0];
275 int minJ = 0;
276 for (int j = 1; j < size; j++) {
277 if (currentLoad[j] < minLoad) {
278 minLoad = currentLoad[j];
279 minJ = j;
280 }
281 }
282 taken[maxIC] = 1;
283 currentLoad[minJ] += maxLoad;
284 partitionResult[maxIC] = minJ;
285 }
286 }
287 while (maxLoad != -1);
288#if 0
289 std::cout << "vwgt" << std::endl;
290 for (int i = 0; i < nC; i++) {
291 std::cout << "[" << i << "]="<< vwgt[i] << std::endl;
292 }
293
294 for (int i = 0; i < size; i++) {
295 std::cout << "load[" << i << "]=" << currentLoad[i] << std::endl;
296 }
297
298 std::cout << "vwgt" << std::endl;
299 for (int i = 0; i < nC; i++) {
300 std::cout << vwgt[i] << std::endl;
301 }
302 std::cout << "xadj" << std::endl;
303 for (int i = 0; i < nC+1; i++) {
304 std::cout << xadj[i] << std::endl;
305 }
306 std::cout << "adjncy" << std::endl;
307 for (int i = 0; i <adjncy.size(); i++) {
308 std::cout << adjncy[i] << std::endl;
309 }
310 std::cout << "adjcwgt" << std::endl;
311 for (int i = 0; i < adjcwgt.size(); i++) {
312 std::cout << adjcwgt[i] << std::endl;
313 }
314
315 std::cout << "nC" << nC << " size " << size << " inbalance " <<
316 inbalance << std::endl;
317#endif
318 int count = 0;
319 for (int i = 0; i < nC; ++i) {
320 if (partitionResult[i] == 0) {
321 this->_glob.push_back(i);
322 this->_loc[i] = count;
323 count++;
324 };
325 this->_rank[i] = partitionResult[i];
326 cuboidToThread[i] = partitionResult[i];
327 }
328 this->_size = count;
329 }
330 // Send all threads their number of cuboids
331
332#ifdef PARALLEL_MODE_MPI
333 if (rank == 0) {
334 // Send all threads their respective cuboids
335 _mpiNbHelper.free();
336 _mpiNbHelper.allocate(size-1);
337 for (int i = 1; i < size; i++) {
338 singleton::mpi().iSend(&cuboidToThread.front(),
339 nC, i, &_mpiNbHelper.get_mpiRequest()[i-1], 0);
340 }
341 singleton::mpi().waitAll(_mpiNbHelper);
342 }
343 else {
344 int *tmpCuboids = new int[nC];
345 singleton::mpi().receive(tmpCuboids, nC, 0, 0);
346 int count = 0;
347 for (int i = 0; i < nC; ++i) {
348 if (tmpCuboids[i] == rank) {
349 this->_glob.push_back(i);
350 this->_loc[i] = count;
351 count++;
352 };
353 this->_rank[i] = tmpCuboids[i];
354 }
355 delete[] tmpCuboids;
356 this->_size = count;
357 }
358#endif
359#ifdef OLB_DEBUG
360 this->print();
361#endif
362}
int rank(const int &glob)
void print(bool multiOutput=false) const
std::vector< int > _glob
content is 0,1,2,...,_size
int _size
number of cuboids after shrink -1 in appropriate thread
std::map< int, int > _rank
maps global cuboid number to the processing thread
std::map< int, int > _loc
maps global cuboid to (local) thread cuboid
void iSend(T *buf, int count, int dest, MPI_Request *request, int tag=0, MPI_Comm comm=MPI_COMM_WORLD)
Sends data at *buf, non blocking.
int getRank() const
Returns the process ID.
void waitAll(MpiNonBlockingHelper &mpiNbHelper)
Complete a series of non-blocking MPI operations.
void receive(T *buf, int count, int source, int tag=0, MPI_Comm comm=MPI_COMM_WORLD)
Receives data at *buf, blocking.
void allocate(unsigned i)
Allocates memory.
MPI_Request * get_mpiRequest(int i=0) const
Get the specified request object.
MpiManager & mpi()

References olb::CuboidGeometry2D< T >::getNc(), olb::singleton::MpiManager::getRank(), olb::singleton::MpiManager::iSend(), olb::singleton::mpi(), olb::singleton::MpiManager::receive(), and olb::singleton::MpiManager::waitAll().

+ Here is the call graph for this function:

◆ reInit() [2/2]

template<typename T >
void olb::HeuristicLoadBalancer< T >::reInit ( CuboidGeometry3D< T > & cGeometry3d,
const double ratioFullEmpty = 1.,
const double weightEmpty = .0 )

Definition at line 78 of file heuristicLoadBalancer.hh.

79{
80 _ratioFullEmpty = ratioFullEmpty;
81 this->_glob.clear();
82 _cGeometry3d = &cGeometry3d;
83 int rank = 0;
84 int size = 1;
85 int nC = _cGeometry3d->getNc();
86#ifdef PARALLEL_MODE_MPI
88 size = util::max<int>(singleton::mpi().getSize(), 1);
89#endif
90 //int xN, yN, zN;
91 //T globX, globY, globZ;//, delta;
92 //boost::shared_array<int> tempInCN(new int[nC]);
93
94 std::vector<int> cuboidToThread(nC);
95 std::vector<int> partitionResult(nC);
96 std::vector<int> vwgt(nC); // node weights
97 std::vector<int> taken(nC, 0);
98 std::vector<int> currentLoad(size, 0);
99
100 if (size == 1) {
101 for (int i = 0; i < nC; ++i) {
102 this->_glob.push_back(i);
103 this->_loc[i] = i;
104 this->_rank[i] = 0;
105 };
106 this->_size = nC;
107 return;
108 }
109
110 if (rank == 0) {
111 for ( int iC = 0; iC < nC; iC++) { // assemble neighbourhood information
112
113 int fullCells = _cGeometry3d->get(iC).getWeight();
114 vwgt[iC] = int(weightEmpty*(_cGeometry3d->get(iC).getLatticeVolume() - fullCells)) + int(ratioFullEmpty * fullCells);
115 }
116
117 int maxLoad = -1;
118 int maxIC = -1;
119 do {
120 maxLoad = -1;
121 maxIC = -1;
122 for ( int iC = 0 ; iC < nC; iC++) {
123 if (taken[iC] == 0 && vwgt[iC] > maxLoad) {
124 maxLoad = vwgt[iC];
125 maxIC = iC;
126 }
127 }
128
129 if (maxIC != -1) {
130 double minLoad = currentLoad[0];
131 int minJ = 0;
132 for (int j = 1; j < size; j++) {
133 if (currentLoad[j] < minLoad) {
134 minLoad = currentLoad[j];
135 minJ = j;
136 }
137 }
138 taken[maxIC] = 1;
139 currentLoad[minJ] += maxLoad;
140 partitionResult[maxIC] = minJ;
141 }
142 }
143 while (maxLoad != -1);
144#if 0
145 std::cout << "vwgt" << std::endl;
146 for (int i = 0; i < nC; i++) {
147 std::cout << "[" << i << "]="<< vwgt[i] << std::endl;
148 }
149
150 for (int i = 0; i < size; i++) {
151 std::cout << "load[" << i << "]=" << currentLoad[i] << std::endl;
152 }
153
154 std::cout << "vwgt" << std::endl;
155 for (int i = 0; i < nC; i++) {
156 std::cout << vwgt[i] << std::endl;
157 }
158 std::cout << "xadj" << std::endl;
159 for (int i = 0; i < nC+1; i++) {
160 std::cout << xadj[i] << std::endl;
161 }
162 std::cout << "adjncy" << std::endl;
163 for (int i = 0; i <adjncy.size(); i++) {
164 std::cout << adjncy[i] << std::endl;
165 }
166 std::cout << "adjcwgt" << std::endl;
167 for (int i = 0; i < adjcwgt.size(); i++) {
168 std::cout << adjcwgt[i] << std::endl;
169 }
170
171 std::cout << "nC" << nC << " size " << size << " inbalance " <<
172 inbalance << std::endl;
173#endif
174 int count = 0;
175 for (int i = 0; i < nC; ++i) {
176 if (partitionResult[i] == 0) {
177 this->_glob.push_back(i);
178 this->_loc[i] = count;
179 count++;
180 };
181 this->_rank[i] = partitionResult[i];
182 cuboidToThread[i] = partitionResult[i];
183 }
184 this->_size = count;
185 }
186 // Send all threads their number of cuboids
187
188#ifdef PARALLEL_MODE_MPI
189 if (rank == 0) {
190 // Send all threads their respective cuboids
191 _mpiNbHelper.free();
192 _mpiNbHelper.allocate(size-1);
193 for (int i = 1; i < size; i++) {
194 singleton::mpi().iSend(&cuboidToThread.front(),
195 nC, i, &_mpiNbHelper.get_mpiRequest()[i-1], 0);
196 }
197 singleton::mpi().waitAll(_mpiNbHelper);
198 }
199 else {
200 int *tmpCuboids = new int[nC];
201 singleton::mpi().receive(tmpCuboids, nC, 0, 0);
202 int count = 0;
203 for (int i = 0; i < nC; ++i) {
204 if (tmpCuboids[i] == rank) {
205 this->_glob.push_back(i);
206 this->_loc[i] = count;
207 count++;
208 };
209 this->_rank[i] = tmpCuboids[i];
210 }
211 delete[] tmpCuboids;
212 this->_size = count;
213 }
214#endif
215#ifdef OLB_DEBUG
216 this->print();
217#endif
218}

References olb::CuboidGeometry3D< T >::getNc(), olb::singleton::MpiManager::getRank(), olb::singleton::MpiManager::iSend(), olb::singleton::mpi(), olb::singleton::MpiManager::receive(), and olb::singleton::MpiManager::waitAll().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ swap()

template<typename T >
void olb::HeuristicLoadBalancer< T >::swap ( HeuristicLoadBalancer< T > & loadBalancer)

Definition at line 65 of file heuristicLoadBalancer.hh.

66{
67 LoadBalancer<T>::swap(loadBalancer);
68
69#ifdef PARALLEL_MODE_MPI
70 _mpiNbHelper.swap(loadBalancer._mpiNbHelper);
71#endif
72
73 std::swap(_cGeometry3d, loadBalancer._cGeometry3d);
74 std::swap(_cGeometry2d, loadBalancer._cGeometry2d);
75}
void swap(LoadBalancer< T > &loadBalancer)
Swap method.
void swap(MpiNonBlockingHelper &rhs)
Swap method.

References olb::LoadBalancer< T >::swap().

+ Here is the call graph for this function:

The documentation for this class was generated from the following files: