StdMpi.cc 13.9 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
  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;
  }

112
113
  void StdMpiHelper<vector<std::set<int> > >::createBuffer(vector<std::set<int> > &data, 
							   int *buf)
114
115
116
117
118
119
120
121
122
123
124
  {
    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;
    }
  }

125
126
127
  void StdMpiHelper<vector<std::set<int> > >::makeFromBuffer(vector<std::set<int> > &data, 
							     int *buf, 
							     int bufSize)
128
  {
129
    FUNCNAME("StdMpiHelper<vector<set<int> > >::makeFromBuffer()");
130
131
132
133
134
135
136

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

    for (int i = 0; i < buf[0]; i++) {
      data[i].clear();
      int setSize = buf[counter++];
137
138
139
      TEST_EXIT_DBG(setSize <= bufSize - counter)
	("Should not happen: %d %d %d\n", setSize, bufSize, counter);

140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
      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();
  }

157
158
  void StdMpiHelper<vector<double> >::createBuffer(vector<double> &data, 
						   double *buf)
159
  {
160
161
    for (unsigned int i = 0; i < data.size(); i++)
      buf[i] = data[i];
162
163
  }

164
  void StdMpiHelper<vector<double> >::makeFromBuffer(vector<double> &data, double *buf, int bufSize)
165
  {
166
167
168
169
    data.resize(bufSize);

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

172
173


174
  // T = vector<vector<double> >
175

176
  int StdMpiHelper<vector<vector<double> > >::getBufferSize(vector<vector<double> > &data)
177
178
179
180
181
182
183
184
185
  {
    int size = 1;

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

186
  void StdMpiHelper<vector<vector<double> > >::createBuffer(vector<vector<double> > &data, double *buf)
187
  {
188
189
    buf[0] = data.size();
    int counter = 1;
190

191
192
193
194
    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];
195
196
197
    }
  }

198
  void StdMpiHelper<vector<vector<double> > >::makeFromBuffer(vector<vector<double> > &data, double *buf, int bufSize)
199
  {
200
201
    data.resize(static_cast<unsigned int>(buf[0]));
    int counter = 1;
202

203
204
205
206
207
    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++];
208
209
210
211
212
    }
  }



213
  // T = vector<MeshStructure>
214

215
  int StdMpiHelper<vector<MeshStructure> >::getBufferSize(vector<MeshStructure> &data)
216
  {
217
218
    FUNCNAME("StdMpiHelper<vector<MeshStructure> >::getBufferSize()");

219
220
221
    int size = 0;
    for (unsigned int i = 0; i < data.size(); i++)
      size += data[i].getCode().size() + 2;
222

223
    return size;
224
225
  }

226
  void StdMpiHelper<vector<MeshStructure> >::createBuffer(vector<MeshStructure> &data, uint64_t *buf)
227
  {    
228
229
    FUNCNAME("StdMpiHelper<vector<MeshStructure> >::createBuffer()");

230
231
232
233
234
235
236
237
238
239
    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];
    }
  }

240
  void StdMpiHelper<vector<MeshStructure> >::makeFromBuffer(vector<MeshStructure> &data, 
241
							    uint64_t *buf, int bufSize)
242
  {
243
244
    FUNCNAME("StdMpiHelper<vector<MeshStructure> >::makeFromBuffer()");

245
246
    int pos = 0;

247
    while (pos < bufSize) {
248
249
      int codeSize = buf[pos++];
      int nElements = buf[pos++];
250
      vector<uint64_t> code;
251
252
253
254
255
256
257
258
259
260
261
262
263
      code.resize(codeSize);
      for (int i = 0; i < codeSize; i++)
	code[i] = buf[pos++];

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

      data.push_back(meshCode);
    }	
  }



264
  // T = vector<AtomicBoundary>
265

266
  int StdMpiHelper<vector<AtomicBoundary> >::getBufferSize(vector<AtomicBoundary> &data)
267
  {
268
    return data.size() * 6;
269
270
  }

271
  void StdMpiHelper<vector<AtomicBoundary> >::createBuffer(vector<AtomicBoundary> &data, int *buf)
272
273
  {
    for (unsigned int i = 0; i < data.size(); i++) {
274
275
276
277
278
279
      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;
280
281
282
    }
  }

283
  void StdMpiHelper<vector<AtomicBoundary> >::makeFromBuffer(vector<AtomicBoundary> &data, int *buf, int bufSize)
284
285
286
287
  {
    if (bufSize == 0)
      return;

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

290
291
292
293
294
295
296
297
    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];
298
299
300
301
302
    }
  }



303
  // T = map<BoundaryType, map<DegreeOfFreedom, DegreeOfFreedom> >
304

305
  int StdMpiHelper<map<BoundaryType, map<DegreeOfFreedom, DegreeOfFreedom> > >::getBufferSize(map<BoundaryType, map<DegreeOfFreedom, DegreeOfFreedom> > &data)
306
  {
307
    int size = 1;
308

309
    for (map<BoundaryType, map<DegreeOfFreedom, DegreeOfFreedom> >::iterator it = data.begin();
310
311
	 it != data.end(); ++it) {
      size += 2 + it->second.size() * 2;
312
313
    }

314
    return size;
315
316
  }

317
  void StdMpiHelper<map<BoundaryType, map<DegreeOfFreedom, DegreeOfFreedom> > >::createBuffer(map<BoundaryType, map<DegreeOfFreedom, DegreeOfFreedom> > &data, int *buf)
318
319
320
321
  {
    buf[0] = data.size();
    int counter = 1;

322
    for (map<BoundaryType, map<DegreeOfFreedom, DegreeOfFreedom> >::iterator it = data.begin();
323
324
325
326
	 it != data.end(); ++it) {
      buf[counter++] = it->first;
      buf[counter++] = it->second.size();

327
      for (map<DegreeOfFreedom, DegreeOfFreedom>::iterator it2 = it->second.begin();
328
329
330
331
332
333
334
	   it2 != it->second.end(); ++it2) {
	buf[counter++] = it2->first;
	buf[counter++] = it2->second;
      }
    }
  }

335
  void StdMpiHelper<map<BoundaryType, map<DegreeOfFreedom, DegreeOfFreedom> > >::makeFromBuffer(map<BoundaryType, map<DegreeOfFreedom, DegreeOfFreedom> > &data, int *buf, int bufSize)
336
337
338
339
340
341
342
343
344
345
  {
    data.clear();

    if (bufSize == 0)
      return;

    int counter = 1;
    
    for (int i = 0; i < buf[0]; i++) {
      BoundaryType bound = buf[counter++];
346
      map<DegreeOfFreedom, DegreeOfFreedom> dofs;
347
348
349
350
351
352
353
354
355
356
357
358
359
360

      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");
  }
361
362
363



364
  // T = vector<std::pair<int, int> >
365

366
  int StdMpiHelper<vector<std::pair<int, int> > >::getBufferSize(vector<std::pair<int, int> > &data)
367
368
369
370
  {
    return data.size() * 2;
  }

371
  void StdMpiHelper<vector<std::pair<int, int> > >::createBuffer(vector<std::pair<int, int> > &data, int *buf)
372
373
374
375
376
377
378
  {
    for (unsigned int i = 0; i < data.size(); i++) {
      buf[i * 2] = data[i].first;
      buf[i * 2 + 1] = data[i].second;
    }
  }

379
  void StdMpiHelper<vector<std::pair<int, int> > >::makeFromBuffer(vector<std::pair<int, int> > &data, 
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
									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]));
  }



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

398
  int StdMpiHelper<vector<WorldVector<double> > >::getBufferSize(vector<WorldVector<double> > &data)
399
400
401
402
  {
    return data.size() * Global::getGeo(WORLD);
  }

403
  void StdMpiHelper<vector<WorldVector<double> > >::createBuffer(vector<WorldVector<double> > &data, double *buf)
404
405
406
407
408
409
410
411
  {
    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];
  }

412
  void StdMpiHelper<vector<WorldVector<double> > >::makeFromBuffer(vector<WorldVector<double> > &data, double *buf, int bufSize)
413
414
415
416
417
418
419
420
421
422
423
424
425
  {
    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++];
  }



426
  // T = map<WorldVector<double>, int>
427

428
  int StdMpiHelper<map<WorldVector<double>, int> >::getBufferSize(map<WorldVector<double>, int> &data)
429
430
431
432
  {
    return data.size() * (Global::getGeo(WORLD) + 1);
  }

433
  void StdMpiHelper<map<WorldVector<double>, int> >::createBuffer(map<WorldVector<double>, int> &data, double* buf)
434
435
  {
    int i = 0;
436
    for (map<WorldVector<double>, int>::iterator it = data.begin();
437
438
439
440
441
442
443
	 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);      
    }
  }

444
  void StdMpiHelper<map<WorldVector<double>, int> >::makeFromBuffer(map<WorldVector<double>, int> &data, double* buf, int bufSize)
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
  {
    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++]);
    }
  }

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
502
503
504
505
506
507
508

  // 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");
  }

509
}