summaryrefslogtreecommitdiff
path: root/src/communication/loadBalancer.h
blob: fd6107835f744c1b1f595e8c9bb1d0eb36d12676 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
/*  This file is part of the OpenLB library
 *
 *  Copyright (C) 2007, 2014 Mathias Krause, Peter Weisbrod
 *  E-mail contact: info@openlb.net
 *  The most recent release of OpenLB can be downloaded at
 *  <http://www.openlb.net/>
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License
 *  as published by the Free Software Foundation; either version 2
 *  of the License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public
 *  License along with this program; if not, write to the Free
 *  Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 *  Boston, MA  02110-1301, USA.
*/


#ifndef LOAD_BALANCER_H
#define LOAD_BALANCER_H

#include <vector>
#include <map>
#include "core/singleton.h"
#include "core/serializer.h"
#include "io/xmlReader.h"

namespace olb {


//template<typename T, typename BaseType> class Vector;
template<typename T> class CuboidGeometry3D;
template<typename T> class CuboidGeometry2D;
template<typename T> class HeuristicLoadBalancer;

/** Base class for all LoadBalancer.
 *  Sketch: assume we have 6 cuboids and 2 threads. Thread number 1 owns cuboid 0 and 1.
 *  Thread number 2 owns cuboid 2, 3, 4 and 5.
 *  Then we get the following configuration:
 *
 *  global cuboid number:               0   1   2   3   4   5
 *  local cuboid number of thread 0:    0   1
 *  local cuboid number of thread 1:            0   1   2   3
 *
 *  \param _glob  is a vector from 0,1,...,numberOfCuboids-1
 *  \param _loc   indicates local cuboid number in actual thread, for given global cuboid number
 *  \param _rank  indicates the processing thread of a global cuboid number
 *
 */
template<typename T>
class LoadBalancer : public BufferSerializable {
protected:
  /// number of cuboids after shrink -1 in appropriate thread
  int _size;
  /// maps global cuboid to (local) thread cuboid
  std::map<int,int> _loc;
  /// content is 0,1,2,...,_size
  std::vector<int>  _glob;
  /// maps global cuboid number to the processing thread
  std::map<int,int> _rank;
public:
  /// Default empty constructor
  LoadBalancer(int size=1);
  /// Load constructor
  LoadBalancer(int size, std::map<int,int>& loc, std::vector<int>& glob, std::map<int,int>& rank);
  /// Default empty destructor
  virtual ~LoadBalancer();
  /// Swap method
  void swap(LoadBalancer<T>& loadBalancer);
  /// returns whether `glob` is on this process
  bool isLocal(const int& glob);
  /// \return local cuboid number of relevant thread
  int loc(const int& glob);
  /// \return local cuboid number of relevant thread
  int loc(int glob) const;
  /// \return global cuboid number of given local cuboid
  int glob(int loc) const;
  /// \param glob is the global cuboid number \return rank that owns the given global cuboid number
  int rank(const int& glob);
  /// \param glob is the global cuboid number \return rank that owns the given global cuboid number
  int rank(int glob) const;
  /// \return read only acess to _size
  int size() const;

  /// equal operator
  bool operator==(const LoadBalancer<T>& rhs) const;

  /// Number of data blocks for the serializable interface
  std::size_t getNblock() const override;
  /// Binary size for the serializer
  std::size_t getSerializableSize() const override;
  /// Return a pointer to the memory of the current block and its size for the serializable interface
  bool* getBlock(std::size_t iBlock, std::size_t& sizeBlock, bool loadingMode) override;

  void print(bool multiOutput = false) const;

  virtual void reInit(CuboidGeometry3D<T>& cGeometry3d, const double ratioFullEmpty=1., const double weightEmpty=.0) {}

  virtual void reInit(CuboidGeometry2D<T>& cGeometry2d, const double ratioFullEmpty=1., const double weightEmpty=.0) {}

  /// Write itself into Stringstream
  virtual void writeToStream(std::ostream& stream)
  {
    std::cout << "Error: LoadBalancer.writeToStream not implemented yet." << std::endl;
    exit(-1);
  };
  /// Write itself into File
  virtual void writeToFile(std::string fileName)
  {
    std::cout << "Error: LoadBalancer.writeToFile not implemented yet." << std::endl;
    exit(-1);
  };

};


/// Creator Function for LoadBalancer from XMLreader.
/// * LoadBalancer Data may be either in an extra file (given by the "file" attribute of the xmlReader)
//    or within the reader (XML tag) itself. Either choice is saved in lbXml.
/// * LoadBalancer Mode is determined by the "mode" attribute of lbXml.
template<typename T>
LoadBalancer<T>* createLoadBalancer(XMLreader const& xmlReader, CuboidGeometry3D<T>* cGeo = NULL)
{
  OstreamManager clout(std::cout, "createLoadBalancer");
  std::string defaultMode = "Block";

  LoadBalancer<T>* lb; // The LoadBalancer to be returned

  // Read file attribute to decide if a new XML reader has to be created
  XMLreader const* lbXml;
  std::string fileAttr = xmlReader.getAttribute("file");
  bool newFile = ( fileAttr != "Attribute not found." );
  if ( newFile ) {
    lbXml = new XMLreader(fileAttr);
  } else {
    lbXml = &xmlReader;
  }

  bool verbose = false;
  (*lbXml).setWarningsOn(false);

  std::string mode = lbXml->getAttribute("mode");
  if ( mode == "Attribute not found.") {
    clout << "Warning: Cannot read parameter from Xml-file: Mode. Set default: mode = " << defaultMode << std::endl;
    mode = defaultMode;
  }

  // Heuristic Mode
  if ( mode == "Heuristic" ) {
    // only read ratioFullEmpty - Heuristic LB will constructed from cuboidGeometry deterministicly
    double ratioFullEmpty;
    if (!(*lbXml)["RatioFullEmpty"].read<double>(ratioFullEmpty, verbose)) {
      lb = new HeuristicLoadBalancer<T>(*cGeo);
    } else {
      lb = new HeuristicLoadBalancer<T>(*cGeo, ratioFullEmpty);
    }
  }

  // Base Mode
  else if ( mode == "Base" ) {
    //LoadBalancer<T>* loadBalancer = new LoadBalancer<T>();
    //loadBalancer->load(fileName);
    clout << "LOADING BASE LB NOT IMPLEMENTED YET!" << std::endl;
    (*lbXml).setWarningsOn(true);
    //return loadBalancer;
    lb = NULL;
  }

  // Block Mode
  else if ( mode == "Block" ) {
    int size = 1;
    if (!(*lbXml)["Size"].read<int>(size, verbose)) {
      clout << "Warning: Cannot read parameter from Xml-file: Size. Set default: size = 1"
            << std::endl;
    }
    lb = new LoadBalancer<T>(size);
  }


  (*lbXml).setWarningsOn(true);

  // Delete XMLreader if it was created for the LB file
  if ( newFile ) {
    delete lbXml;
  }

  return lb;
}


/// Creator Function for LoadBalancer from fileName
template<typename T>
LoadBalancer<T>* createLoadBalancer(std::string const& fileName, CuboidGeometry3D<T>* cGeo = NULL)
{
  std::string fname = singleton::directories().getLogOutDir() + fileName + ".xml";
  XMLreader lbReader(fname);
  return createLoadBalancer(lbReader["LoadBalancer"], cGeo);
}

}  // namespace olb

#endif