StdMpi.cc 13.8 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
//
// Software License for AMDiS
//
// Copyright (c) 2010 Dresden University of Technology 
// All rights reserved.
// Authors: Simon Vey, Thomas Witkowski et al.
//
// This file is part of AMDiS
//
// See also license.opensource.txt in the distribution.


13
14
15
16
#include "StdMpi.h"

namespace AMDiS {

17
  MPI_Datatype StdMpiHelper<int>::mpiDataType = MPI_INT;
18
19
20
21
22
  MPI_Datatype StdMpiHelper<vector<int> >::mpiDataType = MPI_INT;
  MPI_Datatype StdMpiHelper<std::set<int> >::mpiDataType = MPI_INT;
  MPI_Datatype StdMpiHelper<vector<std::set<int> > >::mpiDataType = MPI_INT;
  MPI_Datatype StdMpiHelper<vector<double> >::mpiDataType = MPI_DOUBLE;
  MPI_Datatype StdMpiHelper<vector<vector<double> > >::mpiDataType = MPI_DOUBLE;
23
  MPI_Datatype StdMpiHelper<vector<MeshStructure> >::mpiDataType = MPI_UNSIGNED_LONG_LONG;
24
25
26
27
28
  MPI_Datatype StdMpiHelper<vector<AtomicBoundary> >::mpiDataType = MPI_INT;
  MPI_Datatype StdMpiHelper<map<BoundaryType, map<DegreeOfFreedom, DegreeOfFreedom> > >::mpiDataType = MPI_INT;
  MPI_Datatype StdMpiHelper<vector<std::pair<int, int> > >::mpiDataType = MPI_INT;
  MPI_Datatype StdMpiHelper<vector<WorldVector<double> > >::mpiDataType = MPI_DOUBLE;
  MPI_Datatype StdMpiHelper<map<WorldVector<double>, int> >::mpiDataType = MPI_DOUBLE;
29
  MPI_Datatype StdMpiHelper<vector<vector<WorldVector<double> > > >::mpiDataType = MPI_DOUBLE;
30
31
32
33

  // T = int

  int StdMpiHelper<int>::getBufferSize(int &data)
34
35
36
37
  {
    return 1;
  }

38
  void StdMpiHelper<int>::createBuffer(int &data, int *buf)
39
  {
40
    buf[0] = data;
41
42
  }

43
  void StdMpiHelper<int>::makeFromBuffer(int &data, int *buf, int bufSize)
44
  {
45
    data = buf[0];
46
47
  }

48
49


50
  // T = vector<int>
51

52
  int StdMpiHelper<vector<int> >::getBufferSize(vector<int> &data)
53
  {
54
    return data.size();
55
56
  }

57
  int StdMpiHelper<vector<int> >::getBufferSize(vector<const int*> &data)
58
59
60
61
  {
    return data.size();
  }

62
  void StdMpiHelper<vector<int> >::createBuffer(vector<int> &data, int *buf)
63
  {
64
65
    for (unsigned int i = 0; i < data.size(); i++)
      buf[i] = data[i];
66
  }
67

68
  void StdMpiHelper<vector<int> >::makeFromBuffer(vector<int> &data, int *buf, int bufSize)
69
  {
70
71
72
73
    data.resize(bufSize);

    for (int i = 0; i < bufSize; i++)
      data[i] = buf[i];
74
75
  }

76
77


78
  // T = std::set<int>
79

80
  int StdMpiHelper<std::set<int> >::getBufferSize(std::set<int> &data)
81
  {
82
    return data.size();
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
  void StdMpiHelper<std::set<int> >::createBuffer(std::set<int> &data, int *buf)
  {
    int i = 0;
    for (std::set<int>::iterator it = data.begin(); it != data.end(); ++it)
      buf[i++] = *it;
  }

  void StdMpiHelper<std::set<int> >::makeFromBuffer(std::set<int> &data, int *buf, int bufSize)
  {
    data.clear();

    for (int i = 0; i < bufSize; i++)
      data.insert(buf[i]);
  }


  // T = vector<std::set<int> >

  int StdMpiHelper<vector<std::set<int> > >::getBufferSize(vector<std::set<int> > &data)
  {
    int dataSize = 1;
    for (unsigned int i = 0; i < data.size(); i++)
      dataSize += data[i].size() + 1;

    return dataSize;
  }

  void StdMpiHelper<vector<std::set<int> > >::createBuffer(vector<std::set<int> > &data, int *buf)
  {
    int counter = 1;
    buf[0] = data.size();

    for (unsigned int i = 0; i < data.size(); i++) {
      buf[counter++] = data[i].size();
      for (std::set<int>::iterator it = data[i].begin(); it != data[i].end(); ++it)
	buf[counter++] = *it;
    }
  }

  void StdMpiHelper<vector<std::set<int> > >::makeFromBuffer(vector<std::set<int> > &data, int *buf, int bufSize)
  {
126
    FUNCNAME("StdMpiHelper<vector<set<int> > >::makeFromBuffer()");
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

    int counter = 1;
    data.resize(buf[0]);

    for (int i = 0; i < buf[0]; i++) {
      data[i].clear();
      int setSize = buf[counter++];
      for (int j = 0; j < setSize; j++)
	data[i].insert(buf[counter++]);
    }

    TEST_EXIT(counter == bufSize)("Counter is %d, but buffer size is %d!\n",
				  counter, bufSize);
  }



  // T = vector<double>

  int StdMpiHelper<vector<double> >::getBufferSize(vector<double> &data)
  {
    return data.size();
  }

  void StdMpiHelper<vector<double> >::createBuffer(vector<double> &data, double *buf)
152
  {
153
154
    for (unsigned int i = 0; i < data.size(); i++)
      buf[i] = data[i];
155
156
  }

157
  void StdMpiHelper<vector<double> >::makeFromBuffer(vector<double> &data, double *buf, int bufSize)
158
  {
159
160
161
162
    data.resize(bufSize);

    for (int i = 0; i < bufSize; i++)
      data[i] = buf[i];
163
164
  }

165
166


167
  // T = vector<vector<double> >
168

169
  int StdMpiHelper<vector<vector<double> > >::getBufferSize(vector<vector<double> > &data)
170
171
172
173
174
175
176
177
178
  {
    int size = 1;

    for (unsigned int i = 0; i < data.size(); i++)
      size += data[i].size() + 1;
    
    return size;
  }

179
  void StdMpiHelper<vector<vector<double> > >::createBuffer(vector<vector<double> > &data, double *buf)
180
  {
181
182
    buf[0] = data.size();
    int counter = 1;
183

184
185
186
187
    for (unsigned int i = 0; i < data.size(); i++) {
      buf[counter++] = data[i].size();
      for (unsigned int j = 0; j < data[i].size(); j++)
	buf[counter++] = data[i][j];
188
189
190
    }
  }

191
  void StdMpiHelper<vector<vector<double> > >::makeFromBuffer(vector<vector<double> > &data, double *buf, int bufSize)
192
  {
193
194
    data.resize(static_cast<unsigned int>(buf[0]));
    int counter = 1;
195

196
197
198
199
200
    for (unsigned int i = 0; i < data.size(); i++) {
      data[i].resize(static_cast<unsigned int>(buf[counter++]));
      
      for (unsigned int j = 0; j < data[i].size(); j++)
	data[i][j] = buf[counter++];
201
202
203
204
205
    }
  }



206
  // T = vector<MeshStructure>
207

208
  int StdMpiHelper<vector<MeshStructure> >::getBufferSize(vector<MeshStructure> &data)
209
  {
210
211
    FUNCNAME("StdMpiHelper<vector<MeshStructure> >::getBufferSize()");

212
213
214
    int size = 0;
    for (unsigned int i = 0; i < data.size(); i++)
      size += data[i].getCode().size() + 2;
215

216
    return size;
217
218
  }

219
  void StdMpiHelper<vector<MeshStructure> >::createBuffer(vector<MeshStructure> &data, uint64_t *buf)
220
  {    
221
222
    FUNCNAME("StdMpiHelper<vector<MeshStructure> >::createBuffer()");

223
224
225
226
227
228
229
230
231
232
    int pos = 0;
    for (unsigned int i = 0; i < data.size(); i++) {
      buf[pos++] = data[i].getCode().size();
      buf[pos++] = data[i].getNumElements();

      for (unsigned int j = 0; j < data[i].getCode().size(); j++)
	buf[pos++] = data[i].getCode()[j];
    }
  }

233
  void StdMpiHelper<vector<MeshStructure> >::makeFromBuffer(vector<MeshStructure> &data, 
234
							    uint64_t *buf, int bufSize)
235
  {
236
237
    FUNCNAME("StdMpiHelper<vector<MeshStructure> >::makeFromBuffer()");

238
239
    int pos = 0;

240
    while (pos < bufSize) {
241
242
      int codeSize = buf[pos++];
      int nElements = buf[pos++];
243
      vector<uint64_t> code;
244
245
246
247
248
249
250
251
252
253
254
255
256
      code.resize(codeSize);
      for (int i = 0; i < codeSize; i++)
	code[i] = buf[pos++];

      MeshStructure meshCode;
      meshCode.init(code, nElements);

      data.push_back(meshCode);
    }	
  }



257
  // T = vector<AtomicBoundary>
258

259
  int StdMpiHelper<vector<AtomicBoundary> >::getBufferSize(vector<AtomicBoundary> &data)
260
  {
261
    return data.size() * 6;
262
263
  }

264
  void StdMpiHelper<vector<AtomicBoundary> >::createBuffer(vector<AtomicBoundary> &data, int *buf)
265
266
  {
    for (unsigned int i = 0; i < data.size(); i++) {
267
268
269
270
271
272
      buf[i * 6] = data[i].rankObj.elIndex;
      buf[i * 6 + 1] = data[i].rankObj.subObj;
      buf[i * 6 + 2] = data[i].rankObj.ithObj;
      buf[i * 6 + 3] = data[i].neighObj.elIndex;
      buf[i * 6 + 4] = data[i].neighObj.subObj;
      buf[i * 6 + 5] = data[i].neighObj.ithObj;
273
274
275
    }
  }

276
  void StdMpiHelper<vector<AtomicBoundary> >::makeFromBuffer(vector<AtomicBoundary> &data, int *buf, int bufSize)
277
278
279
280
  {
    if (bufSize == 0)
      return;

281
    TEST_EXIT(bufSize % 6 == 0)("This should not happen!\n");    
282

283
284
285
286
287
288
289
290
    data.resize(bufSize / 6);
    for (int i = 0; i < bufSize / 6; i++) {
      data[i].rankObj.elIndex = buf[i * 6];
      data[i].rankObj.subObj = static_cast<GeoIndex>(buf[i * 6 + 1]);
      data[i].rankObj.ithObj = buf[i * 6 + 2];
      data[i].neighObj.elIndex = buf[i * 6 + 3];
      data[i].neighObj.subObj = static_cast<GeoIndex>(buf[i * 6 + 4]);
      data[i].neighObj.ithObj = buf[i * 6 + 5];
291
292
293
294
295
    }
  }



296
  // T = map<BoundaryType, map<DegreeOfFreedom, DegreeOfFreedom> >
297

298
  int StdMpiHelper<map<BoundaryType, map<DegreeOfFreedom, DegreeOfFreedom> > >::getBufferSize(map<BoundaryType, map<DegreeOfFreedom, DegreeOfFreedom> > &data)
299
  {
300
    int size = 1;
301

302
    for (map<BoundaryType, map<DegreeOfFreedom, DegreeOfFreedom> >::iterator it = data.begin();
303
304
	 it != data.end(); ++it) {
      size += 2 + it->second.size() * 2;
305
306
    }

307
    return size;
308
309
  }

310
  void StdMpiHelper<map<BoundaryType, map<DegreeOfFreedom, DegreeOfFreedom> > >::createBuffer(map<BoundaryType, map<DegreeOfFreedom, DegreeOfFreedom> > &data, int *buf)
311
312
313
314
  {
    buf[0] = data.size();
    int counter = 1;

315
    for (map<BoundaryType, map<DegreeOfFreedom, DegreeOfFreedom> >::iterator it = data.begin();
316
317
318
319
	 it != data.end(); ++it) {
      buf[counter++] = it->first;
      buf[counter++] = it->second.size();

320
      for (map<DegreeOfFreedom, DegreeOfFreedom>::iterator it2 = it->second.begin();
321
322
323
324
325
326
327
	   it2 != it->second.end(); ++it2) {
	buf[counter++] = it2->first;
	buf[counter++] = it2->second;
      }
    }
  }

328
  void StdMpiHelper<map<BoundaryType, map<DegreeOfFreedom, DegreeOfFreedom> > >::makeFromBuffer(map<BoundaryType, map<DegreeOfFreedom, DegreeOfFreedom> > &data, int *buf, int bufSize)
329
330
331
332
333
334
335
336
337
338
  {
    data.clear();

    if (bufSize == 0)
      return;

    int counter = 1;
    
    for (int i = 0; i < buf[0]; i++) {
      BoundaryType bound = buf[counter++];
339
      map<DegreeOfFreedom, DegreeOfFreedom> dofs;
340
341
342
343
344
345
346
347
348
349
350
351
352
353

      int nDofs = buf[counter++];
      for (int j = 0; j < nDofs; j++) {
	DegreeOfFreedom dof0, dof1;
	dof0 = buf[counter++];
	dof1 = buf[counter++];
	dofs[dof0] = dof1;
      }

      data[bound] = dofs;
    }

    TEST_EXIT(bufSize == counter)("Should not happen!\n");
  }
354
355
356



357
  // T = vector<std::pair<int, int> >
358

359
  int StdMpiHelper<vector<std::pair<int, int> > >::getBufferSize(vector<std::pair<int, int> > &data)
360
361
362
363
  {
    return data.size() * 2;
  }

364
  void StdMpiHelper<vector<std::pair<int, int> > >::createBuffer(vector<std::pair<int, int> > &data, int *buf)
365
366
367
368
369
370
371
  {
    for (unsigned int i = 0; i < data.size(); i++) {
      buf[i * 2] = data[i].first;
      buf[i * 2 + 1] = data[i].second;
    }
  }

372
  void StdMpiHelper<vector<std::pair<int, int> > >::makeFromBuffer(vector<std::pair<int, int> > &data, 
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
									int *buf, int bufSize)
  {    
    if (bufSize == 0)
      return;

    TEST_EXIT(bufSize % 2 == 0)("This should not happen!\n");

    data.clear();
    data.reserve(bufSize / 2);

    for (int i = 0; i < (bufSize / 2); i++)
      data.push_back(std::make_pair(buf[i * 2], buf[i * 2 + 1]));
  }



389
  // T = vector<WorldVector<double> >
390

391
  int StdMpiHelper<vector<WorldVector<double> > >::getBufferSize(vector<WorldVector<double> > &data)
392
393
394
395
  {
    return data.size() * Global::getGeo(WORLD);
  }

396
  void StdMpiHelper<vector<WorldVector<double> > >::createBuffer(vector<WorldVector<double> > &data, double *buf)
397
398
399
400
401
402
403
404
  {
    int dimOfWorld = Global::getGeo(WORLD);
    int pos = 0;
    for (unsigned int i = 0; i < data.size(); i++)
      for (int j = 0; j < dimOfWorld; j++)
	buf[pos++] = data[i][j];
  }

405
  void StdMpiHelper<vector<WorldVector<double> > >::makeFromBuffer(vector<WorldVector<double> > &data, double *buf, int bufSize)
406
407
408
409
410
411
412
413
414
415
416
417
418
  {
    int dimOfWorld = Global::getGeo(WORLD);
    TEST_EXIT(bufSize % Global::getGeo(WORLD) == 0)("This should not happen!\n");

    int pos = 0;
    data.resize(bufSize / Global::getGeo(WORLD));
    for (unsigned int i = 0; i < data.size(); i++)
      for (int j = 0; j < dimOfWorld; j++)
	data[i][j] = buf[pos++];
  }



419
  // T = map<WorldVector<double>, int>
420

421
  int StdMpiHelper<map<WorldVector<double>, int> >::getBufferSize(map<WorldVector<double>, int> &data)
422
423
424
425
  {
    return data.size() * (Global::getGeo(WORLD) + 1);
  }

426
  void StdMpiHelper<map<WorldVector<double>, int> >::createBuffer(map<WorldVector<double>, int> &data, double* buf)
427
428
  {
    int i = 0;
429
    for (map<WorldVector<double>, int>::iterator it = data.begin();
430
431
432
433
434
435
436
	 it != data.end(); ++it) {
      for (int j = 0; j < Global::getGeo(WORLD); j++)
	buf[i++] = it->first[j];
      buf[i++] = static_cast<double>(it->second);      
    }
  }

437
  void StdMpiHelper<map<WorldVector<double>, int> >::makeFromBuffer(map<WorldVector<double>, int> &data, double* buf, int bufSize)
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
  {
    if (bufSize == 0)
      return;

    int oneEntrySize = Global::getGeo(WORLD) + 1;
    int nEntry = bufSize / oneEntrySize;

    TEST_EXIT(bufSize % oneEntrySize == 0)("This should not happen!\n");

    data.clear();
    int i = 0;
    WorldVector<double> coords;

    for (int j = 0; j < nEntry; j++) {
      for (int k = 0; k < Global::getGeo(WORLD); k++)
	coords[k] = buf[i++];
      data[coords] = static_cast<int>(buf[i++]);
    }
  }

458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501

  // T = vector<vector<WorldVector<double> > >

  int StdMpiHelper<vector<vector<WorldVector<double> > > >::getBufferSize(vector<vector<WorldVector<double> > > &data)
  {
    int result = 1;

    for (unsigned int i = 0; i < data.size(); i++)
      result += 1 + (data[i].size() * Global::getGeo(WORLD));

    return result;
  }

  void StdMpiHelper<vector<vector<WorldVector<double> > > >::createBuffer(vector<vector<WorldVector<double> > > &data, 
									  double* buf)
  {
    int counter = 0;

    buf[counter++] = static_cast<double>(data.size());

    for (unsigned int i = 0; i < data.size(); i++) {
      buf[counter++] = data[i].size();
      for (unsigned int j = 0; j < data[i].size(); j++)
	for (unsigned int k = 0; k < Global::getGeo(WORLD); k++) 
	  buf[counter++] = data[i][j][k];
    }
  }

  void StdMpiHelper<vector<vector<WorldVector<double> > > >::makeFromBuffer(vector<vector<WorldVector<double> > > &data, 
									    double* buf, int bufSize)
  {
    int counter = 0;
    data.resize(static_cast<int>(buf[counter++]));

    for (unsigned int i = 0; i < data.size(); i++) {
      data[i].resize(static_cast<int>(buf[counter++]));
      for (unsigned int j = 0; j < data[i].size(); j++) 
	for (unsigned int k = 0; k < Global::getGeo(WORLD); k++) 
	  data[i][j][k] = buf[counter++];
    }

    TEST_EXIT_DBG(counter == bufSize)("There is something very wrong!\n");
  }

502
}