ls1-MarDyn
ls1-MarDyn molecular dynamics code
LoadCalc.h
1/*
2 * LoadCalc.h
3 *
4 * Created on: 10.06.2017
5 * Author: griebel_s
6 */
7
8#pragma once
9
10#include <array>
11#include <vector>
12#include <algorithm>
13#ifdef ENABLE_MPI
14#include <mpi.h>
15#endif
16
17#include <utils/Logger.h>
18
20
21#include "Simulation.h"
22
23
24class LoadCalc {
25public:
26
27 virtual ~~LoadCalc() {
28 }
29
30 virtual double getOwn(int index1, int index2) const = 0;
31
32 virtual double getFace(int index1, int index2) const = 0;
33
34 virtual double getEdge(int index1, int index2) const = 0;
35
36 virtual double getCorner(int index1, int index2) const = 0;
37};
38
44class TunerLoad: public LoadCalc {
45public:
46
51 TunerLoad(int count1, int count2, std::vector<double>&& ownTime, std::vector<double>&& faceTime,
52 std::vector<double>&& edgeTime, std::vector<double>&& cornerTime);
53
58 _count1 { 0 }, _count2 { 0 } {
59 }
60
65 double getOwn(int index1, int index2) const override {
66 if (index2 < _count2 && index1 < _count1) {
67 return accessVec(_ownTime, index1, index2);
68 } else {
69 // extrapolation
70 return index1 * (index1 - 1) / 2 * _ownConst[0] + index2 * (index2 - 1) / 2 * _ownConst[1]
71 + index2 * index1 * _ownConst[2];
72 }
73 }
74
75 double getFace(int index1, int index2) const override {
76 if (index2 < _count2 && index1 < _count1) {
77 return accessVec(_faceTime, index1, index2);
78 } else {
79 return costsNeighbour(index1, index2, _faceConst);
80 }
81 }
82
83 double getEdge(int index1, int index2) const override {
84 if (index2 < _count2 && index1 < _count1) {
85 return accessVec(_edgeTime, index1, index2);
86 } else {
87 return costsNeighbour(index1, index2, _edgeConst);
88 }
89 }
90
91 double getCorner(int index1, int index2) const override {
92 if (index2 < _count2 && index1 < _count1) {
93 return accessVec(_cornerTime, index1, index2);
94 } else {
95 return costsNeighbour(index1, index2, _cornerConst);
96 }
97 }
98
99 int getCount1() const noexcept {
100 return _count1;
101 }
102
103 int getCount2() const noexcept {
104 return _count2;
105 }
106
110 static void write(std::ostream& stream, const TunerLoad& time) {
111 stream << "Vectorization Tuner File" << std::endl;
112 stream << "own" << std::endl;
113 time.writeVec(stream, time._ownTime);
114 stream << "face" << std::endl;
115 time.writeVec(stream, time._faceTime);
116 stream << "edge" << std::endl;
117 time.writeVec(stream, time._edgeTime);
118 stream << "corner" << std::endl;
119 time.writeVec(stream, time._cornerTime);
120 }
121
125 static TunerLoad read(std::istream& stream);
126
127private:
132 static std::vector<double> readVec(std::istream& in, int& count1, int& count2);
133
137 static double costsNeighbour(int index1, int index2, std::array<double, 3> consts) noexcept {
138 return index1 * index1 * consts[0] + index2 * index2 * consts[1] + index1 * index2 * 2 * consts[2];
139 }
140
146 void writeVec(std::ostream& out, const std::vector<double>& vec) const {
147 for (int index1 = 0; index1 < _count1; ++index1) {
148 for (int index2 = 0; index2 < _count2 - 1; ++index2) {
149 out << accessVec(vec, index1, index2) << ";";
150 }
151 //no terminating ; for the last entry
152 if (vec.size() != 0) {
153 out << accessVec(vec, index1, _count2 - 1);
154 }
155 out << std::endl;
156 }
157 }
158
165 std::array<double, 3> calcConsts(const std::vector<double>& timeVec, bool inner);
166
167 double accessVec(const std::vector<double>& vec, int index1, int index2) const {
168 return vec[index2 + _count2 * index1];
169 }
170
171 /*
172 * Number of particles up to which the times where still measured and are stored in the vectors (per type)
173 * This means each vector has the size _count1*_count2.
174 */
175 int _count1;
176 int _count2;
177 /*
178 * Storing the measured times for the different neighbor types.
179 *
180 * These are 2D-arrays
181 */
182 std::vector<double> _ownTime;
183 std::vector<double> _faceTime;
184 std::vector<double> _edgeTime;
185 std::vector<double> _cornerTime;
186
187 /*
188 * Store the constants needed for the extrapolation. These represent the time needed for a single transaction,
189 * so to extrapolate then simply multiplies these constants times the number of
190 *
191 * The first value is the constant for interactions between particles of type 1, the second between particles of type 2
192 * and the the third for an interaction between particles of type 1 and 2
193 */
194 std::array<double, 3> _ownConst{};
195 std::array<double, 3> _faceConst{};
196 std::array<double, 3> _edgeConst{};
197 std::array<double, 3> _cornerConst{};
198};
199
203class TradLoad: public LoadCalc {
204public:
205 double getOwn(int index1, int index2) const override {
206 return (index1 + index2) * (index1 + index2);
207 }
208
209 double getFace(int index1, int index2) const override {
210 return 0.5 * (index1 + index2) * (index1 + index2);
211 }
212
213 double getEdge(int index1, int index2) const override {
214 return 0.5 * (index1 + index2) * (index1 + index2);
215 }
216
217 double getCorner(int index1, int index2) const override {
218 return 0.5 * (index1 + index2) * (index1 + index2);
219 }
220};
221
222
227class MeasureLoad: public LoadCalc {
228 static std::string TIMER_NAME;
229
230public:
231 MeasureLoad(bool timeValuesShouldBeIncreasing, int interpolationStartsAt);
232
233 double getOwn(int index1, int index2) const override {
234 return getValue(index1 + index2);
235 }
236
237 double getFace(int index1, int index2) const override {
238 return getValue(index1 + index2);
239 }
240
241 double getEdge(int index1, int index2) const override {
242 return getValue(index1 + index2);
243 }
244
245 double getCorner(int index1, int index2) const override {
246 return getValue(index1 + index2);
247 }
248
249#ifdef ENABLE_MPI
250 int prepareLoads(DomainDecompBase* decomp, MPI_Comm& comm);
251#endif
252private:
253 double getValue(int numParticles) const;
254 void calcConstants();
255
257 std::vector<double> _times;
258
263 std::array<double, 3> _interpolationConstants{};
264
265 bool _preparedLoad{false};
266 double _previousTime{0.};
267 int _interpolationStartsAt{1};
268 bool _timeValuesShouldBeIncreasing{true};
269};
handle boundary region and multiple processes
Definition: DomainDecompBase.h:51
Definition: LoadCalc.h:24
Definition: LoadCalc.h:227
Definition: LoadCalc.h:203
Definition: LoadCalc.h:44
static TunerLoad read(std::istream &stream)
Definition: LoadCalc.cpp:143
TunerLoad()
Definition: LoadCalc.h:57
static void write(std::ostream &stream, const TunerLoad &time)
Definition: LoadCalc.h:110
double getOwn(int index1, int index2) const override
Definition: LoadCalc.h:65
::xsd::cxx::tree::time< char, simple_type > time
C++ type corresponding to the time XML Schema built-in type.
Definition: vtk-punstructured.h:438
::xsd::cxx::tree::string< char, simple_type > string
C++ type corresponding to the string XML Schema built-in type.
Definition: vtk-punstructured.h:270