PlasCom2  1.0
XPACC Multi-physics simluation application
State.C
Go to the documentation of this file.
1 #include "State.H"
2 #include "PCPPReport.H"
3 
4 using namespace pcpp::util;
5 
6 namespace simulation {
7 
8  namespace state {
9 
10 
17  int base::ConfigureState(ConfigurationType &inConfig,std::ostream &messageStream)
18  {
19  std::string configName(inConfig.GetValue("ConfigName"));
20  std::ostringstream Ostr;
21  if(!configName.empty())
22  Ostr << configName << ":";
23  Ostr << "Data";
24  std::string solutionKey(Ostr.str());
25  std::vector<std::string> fieldNames(inConfig.GetValueVector<std::string>(ConfigKey(solutionKey,"Fields")));
26  if(fieldNames.empty()){
27  messageStream << "No fields specified for domain"
28  << (configName.empty() ? std::string(" ") : std::string(" ("+configName+") "))
29  << "state" << std::endl;
30  return(1);
31  }
32  std::vector<std::string>::iterator fieldIt = fieldNames.begin();
33  while(fieldIt != fieldNames.end()){
34  std::string fieldName(*fieldIt++);
35  std::string fieldKey(solutionKey+std::string(":")+fieldName);
36  std::string fieldUnits = inConfig.GetValue<std::string>(ConfigKey(fieldKey,"Units"));
37  int numComponents = inConfig.GetValue<int>(ConfigKey(fieldKey,"Components"));
38  int dataSize = inConfig.GetValue<int>(ConfigKey(fieldKey,"DataSize"));
39  std::string fieldLocation = inConfig.GetValue<std::string>(ConfigKey(fieldKey,"Location"));
40  if(dataSize <= 0 || dataSize > 8){
41  messageStream << "ConfigureState:Warning: invalid data size for "
42  << fieldName << ", defaulting to double(8)." << std::endl;
43 
44  dataSize = 8; // default to double data
45  }
46  if(numComponents <= 0)
47  numComponents = 1; // default to scalar field
48  if(fieldLocation.empty())
49  fieldLocation = "n";
50  if(fieldLocation.size() != 1)
51  fieldLocation = fieldLocation.substr(0,1);
52  fieldLocation[0] = std::tolower(fieldLocation[0]);
53  if(fieldLocation != "n" && fieldLocation != "c" &&
54  fieldLocation != "m" && fieldLocation != "s" &&
55  fieldLocation != "d"){
56  messageStream << "ConfigureState:Warning: invalid solution location for "
57  << fieldName << ", defaulting to nodes." << std::endl;
58  fieldLocation = "n";
59  }
60  AddField(fieldName,fieldLocation[0],numComponents,dataSize,fieldUnits);
61  }
62  return(0);
63  };
64 
65 
66 
67  void halo::ConfigureHalo(const pcpp::IndexIntervalType &partitionExtent,
68  const std::vector<pcpp::IndexIntervalType> &haloExtents,
69  size_t numHaloVar)
70  {
71  numStateComponents = numHaloVar;
72  globalPartitionExtent = partitionExtent;
73  remoteHaloExtents = haloExtents;
74  };
75 
76  // Simple halo extent creation - takes a size in each (+/-) direction (i.e. 2*NumDim sizes)
77  // and creates the extents that specify the remote halo regions
78  std::vector<pcpp::IndexIntervalType> halo::CreateRemoteHaloExtents(const pcpp::IndexIntervalType &globalExtent,
79  const pcpp::IndexIntervalType &partitionExtent,
80  std::vector<size_t> &haloSizes)
81  {
82  std::vector<pcpp::IndexIntervalType> haloExtents;
83  int numDim = haloSizes.size()/2;
84  haloExtents.resize(numDim*2);
85  for(int iDim = 0;iDim < numDim;iDim++){
86  size_t numNodesDim = partitionExtent[iDim].second - partitionExtent[iDim].first + 1;
87  bool leftHaloRequired = false;
88  if(haveNeighbor.empty()){
89  if(partitionExtent[iDim].first > globalExtent[iDim].first)
90  leftHaloRequired = true;
91  } else if (haveNeighbor[2*iDim]) {
92  leftHaloRequired = true;
93  }
94  if(leftHaloRequired){
95  size_t haloSize = haloSizes[iDim*2];
96  pcpp::IndexIntervalType leftHaloExtent(partitionExtent);
97 // if((partitionExtent[iDim].first - globalExtent[iDim].first) < haloSize)
98 // haloSize = partitionExtent[iDim].first - globalExtent[iDim].first;
99  assert(haloSize < numNodesDim);
100  for(int hDim = 0;hDim < numDim;hDim++){
101  if(hDim == iDim){
102  if(partitionExtent[iDim].first == 0){
103  leftHaloExtent[hDim].first = globalExtent[iDim].second - haloSize + 1;
104  leftHaloExtent[hDim].second = globalExtent[iDim].second;
105  } else {
106  leftHaloExtent[hDim].first = partitionExtent[iDim].first - haloSize;
107  leftHaloExtent[hDim].second = leftHaloExtent[hDim].first + haloSize - 1;
108  }
109  } else {
110  leftHaloExtent[hDim] = partitionExtent[hDim];
111  }
112  }
113  haloExtents[iDim*2].Copy(leftHaloExtent);
114  }
115  bool rightHaloRequired = false;
116  if(haveNeighbor.empty()){
117  if(partitionExtent[iDim].second < globalExtent[iDim].second)
118  rightHaloRequired = true;
119  } else if (haveNeighbor[2*iDim+1]) {
120  rightHaloRequired = true;
121  }
122  if(rightHaloRequired){ // right halo will be required
123  size_t haloSize = haloSizes[iDim*2+1];
124  pcpp::IndexIntervalType rightHaloExtent(partitionExtent);
125 // if((globalExtent[iDim].second - partitionExtent[iDim].second) < haloSize)
126 // haloSize = globalExtent[iDim].second - partitionExtent[iDim].second;
127  assert(haloSize < numNodesDim);
128  for(int hDim = 0;hDim < numDim;hDim++){
129  if(hDim == iDim){
130  if(partitionExtent[iDim].second == globalExtent[iDim].second){
131  rightHaloExtent[hDim].second = globalExtent[iDim].first + haloSize - 1;
132  rightHaloExtent[hDim].first = globalExtent[iDim].first;
133  } else {
134  rightHaloExtent[hDim].first = partitionExtent[iDim].second + 1;
135  rightHaloExtent[hDim].second = rightHaloExtent[hDim].first + haloSize - 1;
136  }
137  } else {
138  rightHaloExtent[hDim] = partitionExtent[hDim];
139  }
140  }
141  haloExtents[iDim*2+1].Copy(rightHaloExtent);
142  }
143  }
144  return(haloExtents);
145  };
146 
147  std::vector<pcpp::IndexIntervalType> halo::CreateRemoteHaloExtents(std::vector<size_t> &haloSizes)
148  {
149  std::vector<pcpp::IndexIntervalType> haloExtents(CreateRemoteHaloExtents(globalGridExtent,globalPartitionExtent,haloSizes));
150  return(haloExtents);
151  }
152 
153  // Simple halo extent creation - takes a size in each (+/-) direction (i.e. 2*NumDim sizes)
154  // and creates the extents that specify the local halos (i.e. the local data upon which remote procs depend)
155  std::vector<pcpp::IndexIntervalType> halo::CreateLocalHaloExtents(const pcpp::IndexIntervalType &globalExtent,
156  const pcpp::IndexIntervalType &partitionExtent,
157  std::vector<size_t> &haloSizes)
158  {
159  std::vector<pcpp::IndexIntervalType> haloExtents;
160  int numDim = haloSizes.size()/2;
161  haloExtents.resize(numDim*2);
162  for(int iDim = 0;iDim < numDim;iDim++){
163  size_t numNodesDim = partitionExtent[iDim].second - partitionExtent[iDim].first + 1;
164  bool leftHaloRequired = false;
165  if(haveNeighbor.empty()){
166  if(partitionExtent[iDim].first > globalExtent[iDim].first) // left halo will be required
167  leftHaloRequired = true;
168  } else if (haveNeighbor[iDim*2]) {
169  leftHaloRequired = true;
170  }
171  if(leftHaloRequired){
172  size_t haloSize = haloSizes[iDim*2];
173  pcpp::IndexIntervalType leftHaloExtent(partitionExtent);
174 // if((partitionExtent[iDim].first - globalExtent[iDim].first) < haloSize)
175 // haloSize = partitionExtent[iDim].first - globalExtent[iDim].first;
176  assert(haloSize < numNodesDim);
177  for(int hDim = 0;hDim < numDim;hDim++){
178  if(hDim == iDim){
179  leftHaloExtent[hDim].first = partitionExtent[iDim].first;
180  leftHaloExtent[hDim].second = leftHaloExtent[hDim].first + haloSize - 1;
181  } else {
182  leftHaloExtent[hDim] = partitionExtent[hDim];
183  }
184  }
185  haloExtents[iDim*2].Copy(leftHaloExtent);
186  }
187  bool rightHaloRequired = false;
188  if(haveNeighbor.empty()){
189  if(partitionExtent[iDim].second < globalExtent[iDim].second) // right halo will be required
190  rightHaloRequired = true;
191  } else if(haveNeighbor[2*iDim+1]) {
192  rightHaloRequired = true;
193  }
194  if(rightHaloRequired){
195  size_t haloSize = haloSizes[iDim*2+1];
196  pcpp::IndexIntervalType rightHaloExtent(partitionExtent);
197 // if((globalExtent[iDim].second - partitionExtent[iDim].second) < haloSize)
198 // haloSize = globalExtent[iDim].second - partitionExtent[iDim].second;
199  assert(haloSize < numNodesDim);
200  for(int hDim = 0;hDim < numDim;hDim++){
201  if(hDim == iDim){
202  rightHaloExtent[hDim].first = partitionExtent[iDim].second - haloSize + 1;
203  rightHaloExtent[hDim].second = partitionExtent[hDim].second;
204  } else {
205  rightHaloExtent[hDim] = partitionExtent[hDim];
206  }
207  }
208  haloExtents[iDim*2+1].Copy(rightHaloExtent);
209  }
210  }
211  return(haloExtents);
212  };
213 
214  std::vector<pcpp::IndexIntervalType> halo::CreateLocalHaloExtents(std::vector<size_t> &haloSizes)
215  {
216  std::vector<pcpp::IndexIntervalType> haloExtents(CreateLocalHaloExtents(globalGridExtent,globalPartitionExtent,haloSizes));
217  return(haloExtents);
218  }
219 
220  void halo::ConfigureHalo(const pcpp::IndexIntervalType &globalExtent,
221  const pcpp::IndexIntervalType &partitionExtent,
222  const std::vector<pcpp::IndexIntervalType> &haloExtents)
223  {
224  // numStateComponents = numHaloVar;
225  globalGridExtent = globalExtent;
226  globalPartitionExtent = partitionExtent;
227  remoteHaloExtents = haloExtents;
228  };
229 
230  void halo::ConfigureHalo(const pcpp::IndexIntervalType &globalExtent,
231  const pcpp::IndexIntervalType &partitionExtent)
232  {
233  // numStateComponents = numHaloVar;
234  globalGridExtent = globalExtent;
235  globalPartitionExtent = partitionExtent;
236  };
237 
238  void halo::CreateHaloBuffers()
239  {
240  if(remoteHaloExtents.empty())
241  return;
242  DestroyHaloBuffers();
243  ownHaloBuffers = true;
244  haloBuffers.resize(numStateFields);
245  for(int iField = 0;iField < numStateFields;iField++){
246  haloBuffers[iField].resize(remoteHaloExtents.size(),NULL);
247  std::vector<pcpp::IndexIntervalType>::iterator haloExtentIt = remoteHaloExtents.begin();
248  while(haloExtentIt != remoteHaloExtents.end()){
249  int haloIndex = haloExtentIt - remoteHaloExtents.begin();
250  pcpp::IndexIntervalType &haloExtent(*haloExtentIt++);
251  size_t numNodes = haloExtent.NNodes();
252  size_t numVar = numStateComponents * numNodes;
253  if(numVar > 0){
254  haloBuffers[iField][haloIndex] = new double [numVar];
255  if(doFill){
256  double *haloBufferPtr = haloBuffers[iField][haloIndex];
257  for(size_t iVar = 0;iVar < numVar;iVar++)
258  haloBufferPtr[iVar] = -100.0;
259  }
260  }
261  }
262  }
263  };
264 
265  void halo::DestroySendBuffers(){
266  if(ownSendBuffers){
267  std::vector<double *>::iterator sbIt = sendBuffers.begin();
268  while(sbIt != sendBuffers.end()){
269  double *sendBuffer = *sbIt++;
270  if(sendBuffer != NULL)
271  delete [] sendBuffer;
272  }
273  }
274  sendBuffers.resize(0);
275  sendIndices.resize(0);
276  };
277 
278  void halo::DestroyHaloBuffers(){
279  if(ownHaloBuffers){
280  int numHalos = remoteHaloExtents.size();
281  int numHaloBuffers = haloBuffers.size();
282  for(int i = 0;i < numHaloBuffers;i++){
283  for(int j = 0;j < numHalos;j++)
284  if(haloBuffers[i][j]) delete [] haloBuffers[i][j];
285  haloBuffers[i].resize(0);
286  }
287  }
288  haloBuffers.resize(0);
289  };
290 
291  void halo::DestroyRecvBuffers(){
292  if(ownRecvBuffers){
293  std::vector<double *>::iterator sbIt = recvBuffers.begin();
294  while(sbIt != recvBuffers.end()){
295  double *recvBuffer = *sbIt++;
296  if(recvBuffer) delete [] recvBuffer;
297  }
298  }
299  recvBuffers.resize(0);
300  // recvIndices.resize(0);
301  haloRecvIndices.resize(0);
302  };
303 
305  int halo::CreateSimpleSendIndices()
306  {
307  haveSendData = false;
308  size_t totalNumSend = 0;
309  if(localHaloExtents.empty())
310  return(0);
311 
312  int numSendIntervals = localHaloExtents.size();
313  sendIndices.resize(numSendIntervals);
314  for(int i = 0;i < numSendIntervals;i++){
315  size_t numPointsSend = localHaloExtents[i].NNodes();
316  if(numPointsSend > 0){
317 
318  // Local halo extents are wrt the global grid size. We need the flat array of source
319  // buffer indices (i.e. wrt the local buffer size) that will be used to populate
320  // the send buffers. If the local buffer includes "halos" or other buffer zones,
321  // then it is a bit more complicated to obtain the source buffer indices.
322  // The following code determines the source buffer indices.
323  if(localPartitionExtent.empty()){ // then halos are not integrated, globalPartitionExtent
324  // represents the entire local buffer
325  globalPartitionExtent.GetFlatIndices(localHaloExtents[i],sendIndices[i]);
326 
327  } else { // the global partition interval is a sub-interval of the local buffer, deal with it
328  //assert(!bufferSizes.empty());
329  // Adjust to local numbering: subHaloExtent = localHaloExtents - globalPartitionExtent
330  pcpp::IndexIntervalType subHaloExtent(localHaloExtents[i] - globalPartitionExtent);
331  // Adjust to the buffer numbering: subHaloExtent = subHaloExtent + localPartitionInterval
332  subHaloExtent += localPartitionExtent;
333  // Obtain flat indices: bufferExtent.GetFlatIndices(subHaloExtent,sendIndices[i]);
335  bufferInterval.InitSimple(localBufferSizes);
336  bufferInterval.GetFlatIndices(subHaloExtent,sendIndices[i]);
337  }
338 
339  totalNumSend += numPointsSend;
340  }
341  }
342  haveSendData = (totalNumSend > 0);
343  return(totalNumSend);
344  }
345 
347  int halo::CreateSimpleSendBuffers()
348  {
349  haveSendData = false;
350  size_t totalNumSend = 0;
351  if(localHaloExtents.empty())
352  return(0);
353  DestroySendBuffers();
354  ownSendBuffers = true;
355  int numSendBuffers = localHaloExtents.size();
356  sendBuffers.resize(numSendBuffers,NULL);
357  sendIndices.resize(numSendBuffers);
358  for(int i = 0;i < numSendBuffers;i++){
359  size_t numSend = localHaloExtents[i].NNodes() * numStateComponents;
360  if(numSend > 0){
361  // Local halo extents are wrt the global mesh. We need the flat array of source
362  // buffer indices that will be used to populate the send buffers. If the local
363  // buffer includes "halos" or other buffer zones, then it is a bit more
364  // complicated to obtain the source buffer indices. The following code
365  // determines the source buffer indices.
366  if(localPartitionExtent.empty()){ // then halos are not integrated, globalPartitionExtent
367  // represents the entire local buffer
368  globalPartitionExtent.GetFlatIndices(localHaloExtents[i],sendIndices[i]);
369  } else { // the global partition interval is a sub-interval of the local buffer, deal with it
370  //assert(!bufferSizes.empty());
371  // Adjust to local numbering: subHaloExtent = localHaloExtents - globalPartitionExtent
372  pcpp::IndexIntervalType subHaloExtent(localHaloExtents[i] - globalPartitionExtent);
373  // Adjust to the buffer numbering: subHaloExtent = subHaloExtent + localPartitionInterval
374  subHaloExtent += localPartitionExtent;
375  // Obtain flat indices: bufferExtent.GetFlatIndices(subHaloExtent,sendIndices[i]);
377  bufferInterval.InitSimple(localBufferSizes);
378  bufferInterval.GetFlatIndices(subHaloExtent,sendIndices[i]);
379  }
380 
381  sendBuffers[i] = new double [numSend];
382  // std::cout << "SENDADDRESS(" << i << "): " << sendBuffers[i]
383  // << std::endl;
384  if(doFill){
385  double *bufPtr = &sendBuffers[i][0];
386  for(size_t iSend = 0;iSend < numSend;iSend++)
387  bufPtr[iSend] = -100.0*(i+1);
388  }
389  totalNumSend += numSend;
390  }
391  }
392  haveSendData = (totalNumSend > 0);
393  return(totalNumSend);
394  }
395 
397  int halo::CreateThreadSendIndices(int threadId)
398  {
399  if(!haveSendData)
400  return(0);
401  if(localHaloExtents.empty())
402  return(0);
403  int numSendBuffers = localHaloExtents.size();
404  threadSendIndices[threadId].resize(numSendBuffers);
405  threadSendBufferIndices[threadId].resize(numSendBuffers);
406  pcpp::IndexIntervalType &threadInterval(threadExtents[threadId]);
407  for(int i = 0;i < numSendBuffers;i++){
408  double *sendBuffer = sendBuffers[i];
409  size_t numSendNodes = localHaloExtents[i].NNodes();
410  std::vector<size_t> &threadSendInds(threadSendIndices[threadId][i]);
411  std::vector<size_t> &threadSendBufferInds(threadSendBufferIndices[threadId][i]);
412  if(numSendNodes > 0){
413 
414  //
415  // - debugging prints
416  // std::cout << "Num nodes in Halo = " << numSendNodes << std::endl;
417  // std::cout << "Halo Extent: ";
418  // localHaloExtents[i].PrettyPrint(std::cout);
419  // std::cout << std::endl;
420  // std::cout << "Thread Extent: ";
421  // threadInterval.PrettyPrint(std::cout);
422  // std::cout << std::endl;
423  // - debugging
424  //
425 
426  // collide thread Interval with the halo interval; gets the portion of the thread interval
427  // that needs to be sent for this particular border
428  pcpp::IndexIntervalType threadSendInterval(threadInterval.Overlap(localHaloExtents[i]));
429  size_t numThreadSendNodes = threadSendInterval.NNodes();
430  if(numThreadSendNodes > 0){
431  //
432  // debugging
433  // std::cout << "Thread Send Extent: ";
434  // threadSendInterval.PrettyPrint(std::cout);
435  // std::cout << std::endl;
436  // std::cout << "Thread collides with " << numThreadSendNodes << " nodes to send." << std::endl;
437  // debugging
438  //
439 
440  // Get the linear thread-specific source indices; these are the indices of the partition
441  // buffer from which to source send data for this thread
442  if(localPartitionExtent.empty()){ // then partition extent is not a sub-interval of the buffer
443  globalPartitionExtent.GetFlatIndices(threadSendInterval,threadSendInds);
444  } else { // partition is a subinterval of the local buffer, deal with it
445  //assert(!bufferSizes.empty());
446  // Adjust to local numbering: extentWRTLocal = extentWRTGlobal - globalPartitionExtent
447  pcpp::IndexIntervalType subThreadSendExtent(threadSendInterval - globalPartitionExtent);
448  // Adjust to the buffer numbering: extentWRTLocalBuffer = extentWRTLocal + localPartitionInterval
449  subThreadSendExtent += localPartitionExtent;
450  // Obtain flat indices: bufferExtent.GetFlatIndices(subHaloExtent,sendIndices[i]);
452  bufferInterval.InitSimple(localBufferSizes);
453  bufferInterval.GetFlatIndices(subThreadSendExtent,threadSendInds);
454  }
455 
456  // Get the linear thread-specific target/pack indices; these are the indices of the send buffer
457  // to which to source data is copied for this thread
458  localHaloExtents[i].GetFlatIndices(threadSendInterval,threadSendBufferInds);
459  if(threadSendInds.size() != numThreadSendNodes){
460  exit(1);
461  }
462  // if the collision interval is not empty, touch the send buffer
463  // to situate the page in appropriate NUMA region
464  size_t *indexPtr = &threadSendBufferInds[0];
465  for(int iComponent = 0;iComponent < numStateComponents;iComponent++){
466  for(size_t iSend = 0;iSend < numThreadSendNodes;iSend++){
467  // Set to some arbitrary value just to "first touch"
468  sendBuffer[indexPtr[iSend]+iComponent*numSendNodes] = -100.0*(threadId+1)*(i+1);
469  }
470  }
471  }
472  }
473  }
474  return(0);
475  }
476 
477 
481  int halo::CreateSendBuffers(const std::vector<pcpp::RemoteCollisionType> &inCollisions)
482  {
483  if(inCollisions.empty())
484  return(0);
485  DestroySendBuffers();
486  ownSendBuffers = true;
487  int numCollisions = inCollisions.size();
488  sendBuffers.resize(numCollisions);
489  sendIndices.resize(numCollisions);
490  for(int i = 0;i < numCollisions;i++){
491  const pcpp::RemoteCollisionType &remoteCollision(inCollisions[i]);
492  const pcpp::IndexIntervalType &collisionExtent(remoteCollision.second);
493  globalPartitionExtent.GetFlatIndices(collisionExtent,sendIndices[i]);
494  // int numSend = flatIndices.size() * stateVarIndices.size();
495  size_t numSend = sendIndices[i].size() * numStateComponents; // numStateVar includes vector field components
496  sendBuffers[i] = new double [numSend];
497  }
498  return(0);
499  };
500 
501 
504  int halo::CreateRecvBuffers(const std::vector<pcpp::RemoteCollisionType> &inCollisions)
505  {
506 
507  recvCollisions = inCollisions;
508 
509  if(inCollisions.empty())
510  return(0);
511  DestroyRecvBuffers();
512  int numRecvBuffers = 0;
513 
514  // collide the input collision extents with the global halo extents to figure out
515  // the required buffer sizes. this allows multiple remote processors to feed the
516  // local halos
517  std::vector<pcpp::RemoteCollisionType>::const_iterator collIt = inCollisions.begin();
518  while(collIt != inCollisions.end()){
519 
520  int collisionIndex = collIt - inCollisions.begin();
521  const pcpp::IndexIntervalType &collisionExtent(collIt++->second);
522  size_t numRecv = collisionExtent.NNodes();
523  std::vector<pcpp::IndexIntervalType>::iterator haloExtentIt = remoteHaloExtents.begin();
524 
525  while(haloExtentIt != remoteHaloExtents.end()){
526 
527  int haloIndex = haloExtentIt - remoteHaloExtents.begin();
528 
529  pcpp::IndexIntervalType &haloExtent(*haloExtentIt++);
530  pcpp::IndexIntervalType haloCollision(haloExtent.Overlap(collisionExtent));
531 
532  int numCollisions = 0;
533  std::vector<size_t> recvIndices;
534  if(!haloCollision.empty()){
535 
536  numCollisions++;
537  haloExtent.GetFlatIndices(collisionExtent,recvIndices);
538  assert(recvIndices.size() == numRecv);
539 
540  haloRecvIndices.push_back(std::make_pair(haloIndex,recvIndices));
541  size_t numRecvItems = numRecv * numStateComponents;
542  double *recvBuffer = new double [numRecvItems];
543  recvBuffers.push_back(recvBuffer);
544 
545  }
546  assert(numCollisions == 1);
547  }
548  }
549  return(0);
550  };
551 
554  int halo::CreateSimpleRecvBuffers()
555  {
556  haveRecvData = false;
557  if(remoteHaloExtents.empty()){
558  std::cout << "halo::CreateSimpleRecvBuffers: WARNING No remote halos." << std::endl;
559  return(0);
560  }
561  DestroyRecvBuffers();
562  size_t totalNumRecv = 0;
563  int numRecvBuffers = remoteHaloExtents.size();
564  recvBuffers.resize(numRecvBuffers,NULL);
565  haloRecvIndices.resize(numRecvBuffers);
566  for(int i = 0;i < numRecvBuffers;i++){
567  std::vector<size_t> recvIndices;
568  size_t numRemoteHaloNodes = remoteHaloExtents[i].NNodes();
569  if(numRemoteHaloNodes > 0){
570  if(localPartitionExtent.empty()){
571  remoteHaloExtents[i].GetFlatIndices(remoteHaloExtents[i],recvIndices);
572  } else {
573  pcpp::IndexIntervalType localBufferExtent;
574  localBufferExtent.InitSimple(localBufferSizes);
575  localBufferExtent.GetFlatIndices(remoteHaloBufferExtents[i],recvIndices);
576  }
577  assert(recvIndices.size() == remoteHaloExtents[i].NNodes());
578  haloRecvIndices[i].first = i;
579  haloRecvIndices[i].second = recvIndices;
580  size_t numRecvItems = remoteHaloExtents[i].NNodes() * numStateComponents;
581  if(numRecvItems > 0) {
582  recvBuffers[i] = new double [numRecvItems];
583  // std::cout << "RECVADDRESS(" << i << "): " << recvBuffers[i]
584  // << std::endl;
585  if(doFill){
586  double *recvBufferPtr = recvBuffers[i];
587  for(size_t iItem = 0;iItem < numRecvItems;iItem++)
588  recvBufferPtr[iItem] = -1.0*(i+1);
589  }
590  }
591  totalNumRecv += numRecvItems;
592  } else {
593  haloRecvIndices[i].first = -1;
594  recvBuffers[i] = NULL;
595  }
596  }
597  haveRecvData = (totalNumRecv > 0);
598  return(totalNumRecv);
599  };
600 
601  int halo::CreateSimpleRecvIndices()
602  {
603  haveRecvData = false;
604  if(remoteHaloExtents.empty()){
605  std::cout << "halo::CreateSimpleRecvBuffers: WARNING No remote halos." << std::endl;
606  return(0);
607  }
608  // DestroyRecvBuffers();
609  size_t totalNumRecv = 0;
610  int numRecvIntervals = remoteHaloExtents.size();
611  // recvBuffers.resize(numRecvBuffers,NULL);
612  recvIndices.resize(numRecvIntervals);
613  for(int i = 0;i < numRecvIntervals;i++){
614  std::vector<size_t> &recvIndex(recvIndices[i]);
615  size_t numRemoteHaloNodes = remoteHaloExtents[i].NNodes();
616  if(numRemoteHaloNodes > 0){
617  if(localPartitionExtent.empty()){
618  remoteHaloExtents[i].GetFlatIndices(remoteHaloExtents[i],recvIndex);
619  } else {
620  pcpp::IndexIntervalType localBufferExtent;
621  localBufferExtent.InitSimple(localBufferSizes);
622  localBufferExtent.GetFlatIndices(remoteHaloBufferExtents[i],recvIndex);
623  }
624  assert(recvIndex.size() == remoteHaloExtents[i].NNodes());
625 
626  totalNumRecv += numRemoteHaloNodes;
627  }
628  }
629  haveRecvData = (totalNumRecv > 0);
630  return(totalNumRecv);
631  };
632 
633  int halo::CreateMessageBuffers(int numComponents)
634  {
635  int numCommunication = recvIndices.size();
636  if(numCommunication != sendIndices.size())
637  return(-1);
638  int messageId = communicationBuffers.size();
639  halo::messagebuffers newMessageBuffers;
640  newMessageBuffers.numComponents = numComponents;
641  newMessageBuffers.sendBuffers.resize(numCommunication);
642  newMessageBuffers.recvBuffers.resize(numCommunication);
643  newMessageBuffers.numPointsSend.resize(numCommunication);
644  newMessageBuffers.numPointsRecv.resize(numCommunication);
645  for(int iComm = 0;iComm < numCommunication;iComm++){
646  int numRecv = recvIndices[iComm].size();
647  int numSend = sendIndices[iComm].size();
648  newMessageBuffers.numPointsSend[iComm] = numSend;
649  newMessageBuffers.numPointsRecv[iComm] = numRecv;
650  newMessageBuffers.sendBuffers[iComm] = new double [numComponents * numSend];
651  newMessageBuffers.recvBuffers[iComm] = new double [numComponents * numRecv];
652  }
653  communicationBuffers.push_back(newMessageBuffers);
654  return(messageId);
655  };
656 
666  int halo::PackMessageBuffers(const int messageId,const int componentId,
667  const int numComponents,const double *sourceBuffer)
668  {
669  assert(messageId < communicationBuffers.size());
670  halo::messagebuffers &messageBuffers(communicationBuffers[messageId]);
671  assert((componentId+numComponents) <= messageBuffers.numComponents);
672  int numMessages = sendIndices.size();
673  for(int iMessage = 0;iMessage < numMessages;iMessage++){
674  std::vector<size_t> &sendIndex(sendIndices[iMessage]);
675  size_t numSend = sendIndex.size();
676  for(int componentIndex = 0;componentIndex < numComponents;componentIndex++){
677  for(size_t pointIndex = 0;pointIndex < numSend;pointIndex++){
678  size_t sendBufferIndex = pointIndex + (componentId+componentIndex)*numSend;
679  size_t sourceBufferIndex = componentIndex*numPointsBuffer;
680  messageBuffers.sendBuffers[iMessage][sendBufferIndex] =
681  sourceBuffer[sourceBufferIndex+sendIndex[pointIndex]];
682  }
683  }
684  }
685  return(0);
686  };
687 
697  int halo::PackMessageBuffers(const int messageId,const int componentId,
698  const int numComponents,const double *sourceBuffer,
699  const int threadId)
700  {
701  assert(messageId < communicationBuffers.size());
702  halo::messagebuffers &messageBuffers(communicationBuffers[messageId]);
703  assert((componentId+numComponents) <= messageBuffers.numComponents);
704  int numMessages = sendIndices.size();
705  for(int iMessage = 0;iMessage < numMessages;iMessage++){
706  std::vector<size_t> &threadSendIndex(threadSendIndices[threadId][iMessage]);
707  std::vector<size_t> &threadSendBufferIndex(threadSendBufferIndices[threadId][iMessage]);
708  std::vector<size_t> &sendIndex(sendIndices[iMessage]);
709  size_t numThreadSend = threadSendIndex.size();
710  size_t numSend = sendIndex.size();
711  for(int componentIndex = 0;componentIndex < numComponents;componentIndex++){
712  for(size_t pointIndex = 0;pointIndex < numThreadSend;pointIndex++){
713  size_t sendBufferIndex = threadSendBufferIndex[pointIndex] + (componentId+componentIndex)*numSend;
714  size_t sourceBufferIndex = componentIndex*numPointsBuffer + threadSendIndex[pointIndex];
715  messageBuffers.sendBuffers[iMessage][sendBufferIndex] = sourceBuffer[sourceBufferIndex];
716  }
717  }
718  }
719  return(0);
720  };
721 
722  int halo::SendMessage(const int messageId,const std::vector<int> &neighborRanks,
723  CommunicatorType &inComm)
724  {
725  assert(messageId < communicationBuffers.size());
726  halo::messagebuffers &messageBuffers(communicationBuffers[messageId]);
727  int numMessages = neighborRanks.size();
728  int numComponents = messageBuffers.numComponents;
729  assert(numMessages == messageBuffers.sendBuffers.size());
730  int messageTagBase = messageId*100;
731  for(int iMessage = 0;iMessage < numMessages;iMessage++){
732  int numPointsSend = messageBuffers.numPointsSend[iMessage];
733  double *sendBuffer = messageBuffers.sendBuffers[iMessage];
734  int numSendItems = numPointsSend*numComponents;
735  int remoteRank = neighborRanks[iMessage];
736  int messageTag = messageTagBase + iMessage;
737  inComm.ASendBuf(sendBuffer,numSendItems,remoteRank,messageTag);
738  }
739  return(0);
740  };
741 
742  int halo::ReceiveMessage(const int messageId,const std::vector<int> &neighborRanks,
743  CommunicatorType &inComm)
744  {
745  assert(messageId < communicationBuffers.size());
746  halo::messagebuffers &messageBuffers(communicationBuffers[messageId]);
747  int numMessages = neighborRanks.size();
748  int numComponents = messageBuffers.numComponents;
749  assert(numMessages == messageBuffers.sendBuffers.size());
750  int messageTagBase = messageId*100;
751  for(int iMessage = 0;iMessage < numMessages;iMessage++){
752  int iDir = iMessage%2;
753  int numPointsRecv = messageBuffers.numPointsSend[iMessage];
754  double *recvBuffer = messageBuffers.recvBuffers[iMessage];
755  int numRecvItems = numPointsRecv*numComponents;
756  int remoteRank = neighborRanks[iMessage];
757  int messageTag = messageTagBase + iMessage;
758  if(iDir == 0)
759  messageTag++;
760  else
761  messageTag--;
762  inComm.ARecvBuf(recvBuffer,numRecvItems,remoteRank,messageTag);
763  }
764  inComm.WaitAll();
765  return(0);
766  };
767 
777  int halo::UnPackMessageBuffers(const int messageId,const int componentId,
778  const int numComponents,double *targetBuffer)
779  {
780  assert(messageId < communicationBuffers.size());
781  halo::messagebuffers &messageBuffers(communicationBuffers[messageId]);
782  assert((componentId+numComponents) <= messageBuffers.numComponents);
783  int numMessages = recvIndices.size();
784  for(int iMessage = 0;iMessage < numMessages;iMessage++){
785  std::vector<size_t> &recvIndex(recvIndices[iMessage]);
786  size_t numRecv = recvIndex.size();
787  for(int componentIndex = 0;componentIndex < numComponents;componentIndex++){
788  for(size_t pointIndex = 0;pointIndex < numRecv;pointIndex++){
789  size_t recvBufferIndex = pointIndex + (componentId+componentIndex)*numRecv;
790  size_t targetBufferIndex = componentIndex*numPointsBuffer + recvIndex[pointIndex];
791  targetBuffer[targetBufferIndex] = messageBuffers.recvBuffers[iMessage][recvBufferIndex];
792  }
793  }
794  }
795  return(0);
796  };
797 
798  int halo::UnPackMessageBuffers(const int messageId,const int componentId,
799  const int numComponents,double *targetBuffer,
800  const int threadId)
801  {
802  assert(messageId < communicationBuffers.size());
803  halo::messagebuffers &messageBuffers(communicationBuffers[messageId]);
804  assert((componentId+numComponents) <= messageBuffers.numComponents);
805  int numMessages = recvIndices.size();
806  for(int iMessage = 0;iMessage < numMessages;iMessage++){
807  std::vector<size_t> &threadRecvIndex(threadHaloBufferIndices[threadId][iMessage]);
808  std::vector<size_t> &threadRecvBufferIndex(threadRecvBufferIndices[threadId][iMessage]);
809  size_t recvBufferSize = recvIndices[iMessage].size();
810  size_t numThreadRecv = threadRecvIndex.size();
811  for(int componentIndex = 0;componentIndex < numComponents;componentIndex++){
812  for(size_t pointIndex = 0;pointIndex < numThreadRecv;pointIndex++){
813  size_t recvBufferIndex = threadRecvBufferIndex[pointIndex] +
814  (componentId+componentIndex)*recvBufferSize;
815  size_t targetBufferIndex = componentIndex*numPointsBuffer + threadRecvIndex[pointIndex];
816  targetBuffer[targetBufferIndex] = messageBuffers.recvBuffers[iMessage][recvBufferIndex];
817  }
818  }
819  }
820  return(0);
821  };
822 
823 
826  int halo::CreateThreadRecvIndices(int threadId)
827  {
828  if(remoteHaloExtents.empty()){
829  std::cout << "halo::CreateThreadRecvIndices: WARNING No remote halos." << std::endl;
830  return(0);
831  }
832 
833 
834  // thread extent (excluding remote halos) wrt global grid size
835  pcpp::IndexIntervalType &threadExtent(threadExtents[threadId]);
836  // buffer extent includes remote halos
837  pcpp::IndexIntervalType &threadBufferExtent(threadBufferExtents[threadId]);
838 
839 
840  int numRecvBuffers = remoteHaloExtents.size();
841  // if(threadRecvIndices[threadId].empty())
842  // threadRecvIndices[threadId].resize(numRecvBuffers);
843  threadRecvBufferIndices[threadId].resize(numRecvBuffers);
844  threadHaloBufferIndices[threadId].resize(numRecvBuffers);
845 // std::cout << "Thread Extent: ";
846 // threadExtent.PrettyPrint(std::cout);
847 // std::cout << std::endl;
848  for(int i = 0;i < numRecvBuffers;i++){
849  // Check to make sure thread needs to recv (i.e. it owns part of part boundary)
850  int recvDirection = i/2;
851  int recvOrientation = i%2;
852  std::vector<size_t> recvIndices;
853 
854  pcpp::IndexIntervalType &remoteHaloExtent(remoteHaloExtents[i]);
855  pcpp::IndexIntervalType &remoteHaloBufferExtent(remoteHaloBufferExtents[i]);
856 
857  std::vector<size_t> &threadRecvBufferIndex(threadRecvBufferIndices[threadId][i]);
858  std::vector<size_t> &threadHaloBufferIndex(threadHaloBufferIndices[threadId][i]);
859 
860  if(!localPartitionExtent.empty()){
861  pcpp::IndexIntervalType localBufferExtent;
862  localBufferExtent.InitSimple(localBufferSizes);
863  pcpp::IndexIntervalType overlapInterval(threadBufferExtent.Overlap(remoteHaloBufferExtent));
864  if(overlapInterval.NNodes() > 0){
865  remoteHaloBufferExtent.GetFlatIndices(overlapInterval,threadRecvBufferIndex);
866  localBufferExtent.GetFlatIndices(overlapInterval,threadHaloBufferIndex);
867  }
868  } else {
869 
870 
871  size_t numRemoteHaloNodes = remoteHaloExtent.NNodes();
872  // std::cout << "numRemoteHaloNodes = " << numRemoteHaloNodes << std::endl;
873  // std::cout << "HaloExtent(" << i << "): ";
874  // remoteHaloExtent.PrettyPrint(std::cout);
875  // std::cout << std::endl;
876  if(numRemoteHaloNodes > 0){
877 
878  if(recvOrientation){
879  if(threadExtent[recvDirection].second != globalPartitionExtent[recvDirection].second)
880  continue;
881  } else {
882  if(threadExtent[recvDirection].first != globalPartitionExtent[recvDirection].first)
883  continue;
884  }
885 
886  pcpp::IndexIntervalType checkExtent(threadExtent);
887  checkExtent[recvDirection] = remoteHaloExtent[recvDirection];
888  pcpp::IndexIntervalType threadRecvExtent(checkExtent.Overlap(remoteHaloExtent));
889  size_t totalNumComponents = 0;
890  size_t numThreadRecvNodes = threadRecvExtent.NNodes();
891  // std::cout << "numThreadRecvNodes = " << numThreadRecvNodes << std::endl;
892 
893  if(numThreadRecvNodes > 0){
894 
895  remoteHaloExtent.GetFlatIndices(threadRecvExtent,threadRecvBufferIndex);
896  size_t *threadRecvBufferIndexPtr = &threadRecvBufferIndex[0];
897  // std::vector<size_t> &threadRecvIndex(threadRecvIndices[threadId][i]);
898  // globalPartitionExtent.GetFlatIndices(threadRecvExtent,threadRecvIndex);
899  // size_t totalNumRecvItems = numRemoteHaloNodes * numStateComponents;
900  double *recvBufferPtr = recvBuffers[i];
901  for(int iField = 0;iField < numStateFields;iField++){
902  int numComponents = numFieldComponents[iField];
903  double *haloBufferPtr = NULL;
904  haloBufferPtr = haloBuffers[iField][i];
905  threadHaloBufferIndex = threadRecvBufferIndex;
906  if(doFill){
907  for(int iComponent = 0;iComponent < numComponents;iComponent++){
908  size_t componentRecvIndex = numRemoteHaloNodes*totalNumComponents++;
909  size_t componentHaloIndex = iComponent*numRemoteHaloNodes;
910  for(size_t iItem = 0;iItem < numThreadRecvNodes;iItem++){
911  size_t recvIndex = threadRecvBufferIndexPtr[iItem];
912  recvBufferPtr[recvIndex+componentRecvIndex] = -100.0*(threadId+1)+(i+1);
913  if(haloBufferPtr != NULL) // Halo buffers DNE when halos are integrated
914  haloBufferPtr[recvIndex+componentHaloIndex] = -100.0*(threadId+1)+(i+1);
915  }
916  }
917  }
918  }
919  }
920  }
921  }
922  }
923  return(0);
924  };
925 
926  int halo::UnpackReceiveBuffers()
927  {
928  if(!haveRecvData)
929  return(0);
930 
931  std::vector<std::pair<int,std::vector<size_t> > >::iterator haloRecvIndicesIt =
932  haloRecvIndices.begin();
933 
934  while(haloRecvIndicesIt != haloRecvIndices.end()){
935 
936  int recvIndex = haloRecvIndicesIt - haloRecvIndices.begin();
937  std::pair<int,std::vector<size_t> > &haloRecvInfo(*haloRecvIndicesIt++);
938  int haloIndex = haloRecvInfo.first; // encodes direction x{0,1},y{2,3},z{4,5}
939  if(haloIndex < 0)
940  continue;
941  std::vector<size_t> &targetIndices(haloRecvInfo.second);
942  size_t numRecv = targetIndices.size();
943  if(numRecv <= 0)
944  continue;
945  double *sourceBuffer = recvBuffers[recvIndex];
946  size_t numHalo = remoteHaloExtents[haloIndex].NNodes();
947  int iVar = 0;
948  int recvBufferIndex = 0;
949  for(int iField = 0;iField < numStateFields;iField++){
950  double *haloBufferPtr = haloBuffers[iField][haloIndex];
951  int numComponents = numFieldComponents[iField];
952  for(int iComponent = 0;iComponent < numComponents;iComponent++){
953  for(size_t iRecv = 0;iRecv < numRecv;iRecv++){
954  size_t targetIndex = targetIndices[iRecv] + iComponent*numHalo;
955  haloBufferPtr[targetIndex] = sourceBuffer[recvBufferIndex++];
956  }
957  }
958  }
959  }
960  return(0);
961  };
962 
963  int halo::UnpackSimpleRecvBuffers()
964  {
965  if(!haveRecvData){
966  std::cout << "halo::UnpackSimpleRecvBuffers: WARNING NO RECEIVE DATA!!" << std::endl;
967  return(0);
968  }
969 
970  std::vector<std::pair<int,std::vector<size_t> > >::iterator haloRecvIndicesIt =
971  haloRecvIndices.begin();
972 
973  while(haloRecvIndicesIt != haloRecvIndices.end()){
974 
975  // int recvIndex = haloRecvIndicesIt - haloRecvIndices.begin();
976  std::pair<int,std::vector<size_t> > &haloRecvInfo(*haloRecvIndicesIt++);
977  int haloIndex = haloRecvInfo.first; // encodes direction x{0,1},y{2,3},z{4,5}
978  if(haloIndex < 0)
979  continue;
980  std::vector<size_t> &targetIndices(haloRecvInfo.second);
981  size_t *targetIndPtr = &targetIndices[0];
982  size_t numRecv = targetIndices.size();
983  double *sourceBuffer = recvBuffers[haloIndex];
984  size_t numHalo = remoteHaloExtents[haloIndex].NNodes();
985 // std::cout << "Number of halo(" << haloIndex << ") nodes: "
986 // << numHalo << std::endl;
987 // std::cout << "NumRecv(" << haloIndex << "): " << numRecv << std::endl;
988  if(numRecv <= 0)
989  continue;
990  // std::cout << "halo::UnpackSimpleRecvBuffers: Unpacking recvIndex(" << recvIndex
991  // << ") Direction/recvbufferid(" << haloIndex << ") ADDRESS:"
992  // << sourceBuffer << std::endl;
993  int recvBufferIndex = 0;
994  for(int iField = 0;iField < numStateFields;iField++){
995  double *haloBufferPtr = haloBuffers[iField][haloIndex];
996  int numComponents = numFieldComponents[iField];
997  for(int iComponent = 0;iComponent < numComponents;iComponent++){
998  size_t componentIndex = iComponent*numHalo;
999  for(size_t iRecv = 0;iRecv < numRecv;iRecv++){
1000  size_t targetIndex = targetIndPtr[iRecv] + componentIndex;
1001  haloBufferPtr[targetIndex] = sourceBuffer[recvBufferIndex++];
1002  }
1003  }
1004  }
1005  }
1006  return(0);
1007  };
1008 
1009  int halo::UnpackSimpleRecvBuffers(int threadId)
1010  {
1011  if(!haveRecvData){
1012  std::cout << "halo::UnpackSimpleRecvBuffers: WARNING NO RECEIVE DATA!!" << std::endl;
1013  return(0);
1014  }
1015 
1016  std::vector<std::pair<int,std::vector<size_t> > >::iterator haloRecvIndicesIt =
1017  haloRecvIndices.begin();
1018 
1019  while(haloRecvIndicesIt != haloRecvIndices.end()){
1020 
1021  // int recvIndex = haloRecvIndicesIt - haloRecvIndices.begin();
1022  std::pair<int,std::vector<size_t> > &haloRecvInfo(*haloRecvIndicesIt++);
1023  int haloIndex = haloRecvInfo.first; // encodes direction x{0,1},y{2,3},z{4,5}
1024  if(haloIndex < 0){
1025  continue;
1026  }
1027  // std::cout << "HaloIndex/ThreadId: " << haloIndex << "/" << threadId << std::endl;
1028  std::vector<size_t> &haloIndices(haloRecvInfo.second);
1029  if(haloIndices.empty()){
1030  continue;
1031  }
1032 
1033  std::vector<size_t> &targetIndices(threadRecvBufferIndices[threadId][haloIndex]);
1034  size_t numRecv = targetIndices.size();
1035  size_t numHalo = remoteHaloExtents[haloIndex].NNodes();
1036 // std::cout << "Number of halo(" << haloIndex << "," << threadId << ") nodes: "
1037 // << numHalo << std::endl;
1038 // std::cout << "NumRecv(" << haloIndex << "," << threadId
1039 // << "): " << numRecv << std::endl;
1040  if(numRecv <= 0 || numHalo == 0){
1041  continue;
1042  }
1043 
1044  size_t *targetIndPtr = &targetIndices[0];
1045  double *sourceBuffer = recvBuffers[haloIndex];
1046 
1047  // std::cout << "halo::UnpackSimpleRecvBuffers: Unpacking recvIndex(" << recvIndex
1048  // << ") Direction/recvbufferid(" << haloIndex << ") ADDRESS:"
1049  // << sourceBuffer << std::endl;
1050 
1051  int componentId = 0;
1052  for(int iField = 0;iField < numStateFields;iField++){
1053  double *haloBufferPtr = haloBuffers[iField][haloIndex];
1054  int numComponents = numFieldComponents[iField];
1055  for(int iComponent = 0;iComponent < numComponents;iComponent++){
1056  size_t targetComponentIndex = iComponent*numHalo;
1057  size_t sourceComponentIndex = numHalo*componentId++;
1058  for(size_t iRecv = 0;iRecv < numRecv;iRecv++){
1059  size_t targetIndex = targetIndPtr[iRecv] + targetComponentIndex;
1060  size_t sourceIndex = targetIndPtr[iRecv] + sourceComponentIndex;
1061  haloBufferPtr[targetIndex] = sourceBuffer[sourceIndex];
1062  }
1063  }
1064  }
1065  }
1066  return(0);
1067  };
1068 
1070  int halo::PackSendBuffers(const state::base &inState)
1071  {
1072  if(!haveSendData)
1073  return(0);
1074 
1075  const pcpp::field::dataset::DataContainerType &solnData(inState.Data());
1076  const pcpp::field::metadataset &solnMetaData(inState.Meta());
1077  const std::vector<int> &stateFieldIndices(inState.StateFieldIndices());
1078 
1079  std::vector<double *>::iterator sendBufIt = sendBuffers.begin();
1080  std::vector<std::vector<size_t> >::iterator sendIndIt = sendIndices.begin();
1081 
1082  while(sendBufIt != sendBuffers.end()){
1083 
1084  double *sendBuffer = *sendBufIt++;
1085  std::vector<size_t> &sendIndex(*sendIndIt++);
1086  std::vector<int>::const_iterator fieldIndexIt = stateFieldIndices.begin();
1087  size_t iVar = 0;
1088  size_t numSend = sendIndex.size();
1089  size_t *sIndex = NULL;
1090  if(numSend > 0) sIndex = &sendIndex[0];
1091 
1092  while(fieldIndexIt != stateFieldIndices.end()){
1093 
1094  int fieldIndex = *fieldIndexIt++;
1095  const pcpp::field::dataset::DataBufferType &fieldData(solnData[fieldIndex]);
1096  const pcpp::field::metadata &fieldMetaData(solnMetaData[fieldIndex]);
1097  const double *sourceBuffer = fieldData.Data<double>();
1098  size_t sourceSize = fieldData.NItems();
1099  int numComponents = fieldMetaData.ncomp;
1100  size_t dataIndex = iVar * numSend;
1101 
1102  for(int iComponent = 0;iComponent < numComponents;iComponent++){
1103  size_t sourceIndex = iComponent*sourceSize;
1104  for(size_t iData = 0;iData < numSend;iData++)
1105  sendBuffer[dataIndex++] = sourceBuffer[sourceIndex+sIndex[iData]];
1106  iVar++;
1107  }
1108 
1109  }
1110 
1111  }
1112  return(0);
1113  };
1114 
1115  int halo::SimpleSend(std::vector<int> &neighborRanks,CommunicatorType &inComm)
1116  {
1117 
1118 // if(inComm.NProc() <= 1)
1119 // return(0);
1120 
1121  if(!haveSendData){
1122  std::cout << "halo::SimpleSend: WARNING: No Send Data!!" << std::endl;
1123  return(0);
1124  }
1125 
1126  std::vector<double *> &sendBuffers(this->SendBuffers());
1127 
1128  int numSendBuffers = sendBuffers.size();
1129 
1130  for(int i = 0;i < numSendBuffers;i++){
1131  if(sendBuffers[i] == NULL)
1132  continue;
1133  pcpp::IndexIntervalType &localHaloExtent(localHaloExtents[i]);
1134  if(localHaloExtent.empty())
1135  return(1);
1136  int remoteRank = neighborRanks[i];
1137  size_t numPoints = localHaloExtent.NNodes();
1138  size_t numSend = numPoints * this->numStateComponents;
1139  // std::cout << "Rank(" << inComm.Rank() << ") send in tag["
1140  // << i << "] direction to rank (" << remoteRank
1141  // << ") ADDRESS: " << sendBuffers[i] << std::endl;
1142  // if(numSend < 11){
1143  // std::cout << "=============" << std::endl;
1144  // for(int isend = 0;isend < numSend;isend++){
1145  // std::cout << sendBuffers[i][isend] << " ";
1146  // }
1147  // std::cout << std::endl
1148  // << "==============" << std::endl;
1149  // }
1150  inComm.ASendBuf(sendBuffers[i],numSend,remoteRank,i);
1151  }
1152  return(0);
1153  };
1154 
1156 // int halo::PackSimpleSendBuffers(const state::base &inState)
1157 // {
1158 // if(!haveSendData) {
1159 // std::cout << "halo::PackSimpleSendBuffers: WARNING: No Send data!!"
1160 // << std::endl;
1161 // return(0);
1162 // }
1163 
1164 // const pcpp::field::dataset::DataContainerType &solnData(inState.Data());
1165 // const pcpp::field::metadataset &solnMetaData(inState.Meta());
1166 // // std::vector<double *>::iterator sendBufIt = sendBuffers.begin();
1167 // std::vector<std::vector<size_t> >::iterator sendIndIt = sendIndices.begin();
1168 // int numSendBuffers = sendBuffers.size();
1169 // // while(sendBufIt != sendBuffers.end()){
1170 // for(int iSend = 0;iSend < numSendBuffers;iSend++){
1171 
1172 // int bufferIndex = 0;
1173 // double *sendBuffer = sendBuffers[iSend];
1174 
1175 // std::vector<size_t> &sendIndex(sendIndices[iSend]);
1176 
1177 // std::vector<int>::const_iterator fieldIndexIt = stateFieldIndices.begin();
1178 
1179 // int numSend = sendIndex.size();
1180 
1181 // while(fieldIndexIt != stateFieldIndices.end()){
1182 
1183 // int fieldIndex = *fieldIndexIt++;
1184 // const pcpp::field::dataset::DataBufferType &fieldData(solnData[fieldIndex]);
1185 // const pcpp::field::metadata &fieldMetaData(solnMetaData[fieldIndex]);
1186 // const double *sourceBuffer = fieldData.Data<double>();
1187 
1188 // int numComponents = fieldMetaData.ncomp;
1189 // size_t sourceSize = fieldData.NItems()/numComponents;
1190 
1191 // for(int iComponent = 0;iComponent < numComponents;iComponent++){
1192 // int sourceIndex = iComponent*sourceSize;
1193 // for(int iData = 0;iData < numSend;iData++)
1194 // sendBuffer[bufferIndex++] = sourceBuffer[sourceIndex+sendIndex[iData]];
1195 // }
1196 
1197 // }
1198 
1199 // }
1200 // return(0);
1201 // };
1202 
1204  int halo::PackSimpleSendBuffers(double inA,const state::base &inX,const state::base &inY)
1205  {
1206  if(!haveSendData){
1207  std::cout << "halo::PackSimpleSendBuffersAXPY: WARNING: No send data!!" << std::endl;
1208  return(0);
1209  }
1210 
1211  const pcpp::field::dataset::DataContainerType &yData(inY.Data());
1212  const pcpp::field::dataset::DataContainerType &xData(inX.Data());
1213  const pcpp::field::metadataset &solnMetaData(inY.Meta());
1214  std::vector<double *>::iterator sendBufIt = sendBuffers.begin();
1215  std::vector<std::vector<size_t> >::iterator sendIndIt = sendIndices.begin();
1216 
1217  while(sendBufIt != sendBuffers.end()){
1218 
1219  size_t bufferIndex = 0;
1220  double *sendBuffer = *sendBufIt++;
1221  std::vector<size_t> &sendIndex(*sendIndIt++);
1222  size_t *sIndex = &sendIndex[0];
1223  std::vector<int>::const_iterator fieldIndexIt = stateFieldIndices.begin();
1224 
1225  size_t numSend = sendIndex.size();
1226 
1227  while(fieldIndexIt != stateFieldIndices.end()){
1228 
1229  int fieldIndex = *fieldIndexIt++;
1230 
1231  const pcpp::field::dataset::DataBufferType &yFieldData(yData[fieldIndex]);
1232  const pcpp::field::dataset::DataBufferType &xFieldData(xData[fieldIndex]);
1233  const pcpp::field::metadata &fieldMetaData(solnMetaData[fieldIndex]);
1234 
1235  const double *yBuffer = yFieldData.Data<double>();
1236  const double *xBuffer = xFieldData.Data<double>();
1237 
1238  int numComponents = fieldMetaData.ncomp;
1239  size_t sourceSize = yFieldData.NItems()/numComponents;
1240 
1241  for(int iComponent = 0;iComponent < numComponents;iComponent++){
1242  size_t sourceIndex = iComponent*sourceSize;
1243  for(size_t iData = 0;iData < numSend;iData++){
1244  size_t dataIndex = sourceIndex + sIndex[iData];
1245  sendBuffer[bufferIndex++] = inA*xBuffer[dataIndex]+yBuffer[dataIndex];
1246  }
1247  }
1248  }
1249  }
1250  return(0);
1251  };
1252 
1254  int halo::PackSimpleSendBuffers(const state::base &inX)
1255  {
1256  if(!haveSendData){
1257  std::cout << "halo::PackSimpleSendBuffers2: WARNING: No send data!!" << std::endl;
1258  return(0);
1259  }
1260 
1261  const pcpp::field::dataset::DataContainerType &xData(inX.Data());
1262  const pcpp::field::metadataset &solnMetaData(inX.Meta());
1263  std::vector<double *>::iterator sendBufIt = sendBuffers.begin();
1264  std::vector<std::vector<size_t> >::iterator sendIndIt = sendIndices.begin();
1265 
1266  while(sendBufIt != sendBuffers.end()){
1267 
1268  size_t bufferIndex = 0;
1269  double *sendBuffer = *sendBufIt++;
1270  std::vector<size_t> &sendIndex(*sendIndIt++);
1271  size_t *sIndex = &sendIndex[0];
1272  std::vector<int>::const_iterator fieldIndexIt = stateFieldIndices.begin();
1273 
1274  size_t numSend = sendIndex.size();
1275 
1276  while(fieldIndexIt != stateFieldIndices.end()){
1277 
1278  int fieldIndex = *fieldIndexIt++;
1279 
1280  const pcpp::field::dataset::DataBufferType &xFieldData(xData[fieldIndex]);
1281  const pcpp::field::metadata &fieldMetaData(solnMetaData[fieldIndex]);
1282 
1283  const double *xBuffer = xFieldData.Data<double>();
1284 
1285  int numComponents = fieldMetaData.ncomp;
1286  size_t sourceSize = xFieldData.NItems()/numComponents;
1287 
1288  for(int iComponent = 0;iComponent < numComponents;iComponent++){
1289  size_t sourceIndex = iComponent*sourceSize;
1290  for(size_t iData = 0;iData < numSend;iData++){
1291  size_t dataIndex = sourceIndex + sIndex[iData];
1292  sendBuffer[bufferIndex++] = xBuffer[dataIndex];
1293  }
1294  }
1295  }
1296  }
1297  return(0);
1298  };
1299 
1301  int halo::PackSimpleSendBuffers(const state::base &inX, int threadId)
1302  {
1303  if(localHaloExtents.empty())
1304  return(0);
1305 
1306  if(!haveSendData){
1307  std::cout << "halo::PackSimpleSendBuffers2: WARNING: No send data!!" << std::endl;
1308  return(0);
1309  }
1310 
1311  const pcpp::field::dataset::DataContainerType &xData(inX.Data());
1312  const pcpp::field::metadataset &solnMetaData(inX.Meta());
1313  std::vector<double *>::iterator sendBufIt = sendBuffers.begin();
1314 
1315  std::vector<std::vector<size_t> >::iterator sendIndIt = threadSendIndices[threadId].begin();
1316  std::vector<std::vector<size_t> >::iterator sendBufferIndIt = threadSendBufferIndices[threadId].begin();
1317  std::vector<std::vector<size_t> >::iterator sendAllIndIt = sendIndices.begin();
1318 
1319  while(sendBufIt != sendBuffers.end()){
1320 
1321  double *sendBuffer = *sendBufIt++;
1322  std::vector<size_t> &sendIndex(*sendIndIt++);
1323  std::vector<size_t> &sendBufferIndex(*sendBufferIndIt++);
1324  size_t *sIndex = &sendIndex[0];
1325  size_t *sBufferIndex = &sendBufferIndex[0];
1326 
1327  int numPackedComponents = 0;
1328  std::vector<int>::const_iterator fieldIndexIt = stateFieldIndices.begin();
1329  size_t totalNumSend = sendAllIndIt++->size();
1330  size_t numSend = sendIndex.size();
1331 
1332  while(fieldIndexIt != stateFieldIndices.end()){
1333 
1334  int fieldIndex = *fieldIndexIt++;
1335 
1336  const pcpp::field::dataset::DataBufferType &xFieldData(xData[fieldIndex]);
1337  const pcpp::field::metadata &fieldMetaData(solnMetaData[fieldIndex]);
1338 
1339  const double *xBuffer = xFieldData.Data<double>();
1340 
1341  int numComponents = fieldMetaData.ncomp;
1342  size_t sourceSize = xFieldData.NItems()/numComponents;
1343 
1344  for(int iComponent = 0;iComponent < numComponents;iComponent++){
1345  size_t sourceIndex = iComponent*sourceSize;
1346  size_t targetIndex = (numPackedComponents++)*totalNumSend;
1347  for(size_t iData = 0;iData < numSend;iData++){
1348  size_t dataIndex = sourceIndex + sIndex[iData];
1349  size_t bufferIndex = targetIndex + sBufferIndex[iData];
1350  sendBuffer[bufferIndex] = xBuffer[dataIndex];
1351  }
1352  }
1353  }
1354  }
1355  return(0);
1356  };
1357 
1359 // int halo::PackSimpleSendBuffers(const state::base &inX,int myThreadId)
1360 // {
1361 // if(!haveSendData){
1362 // std::cout << "halo::PackSimpleSendBuffers2: WARNING: No send data!!" << std::endl;
1363 // return(0);
1364 // }
1365 
1366 // const pcpp::field::dataset::DataContainerType &xData(inX.Data());
1367 // const pcpp::field::metadataset &solnMetaData(inX.Meta());
1368 // std::vector<double *>::iterator sendBufIt = sendBuffers.begin();
1369 // std::vector<std::vector<size_t> >::iterator sendIndIt = sendIndices.begin();
1370 
1371 // while(sendBufIt != sendBuffers.end()){
1372 
1373 // int bufferIndex = 0;
1374 // double *sendBuffer = *sendBufIt++;
1375 // int sendIndex = *sendIndIt++;
1376 // std::vector<size_t> &threadPackIndex(sendIndex,myThreadId);
1377 // std::vector<size_t> &threadSendIndex(sendIndex,myThreadId);
1378 // std::vector<int>::const_iterator fieldIndexIt = stateFieldIndices.begin();
1379 
1380 // int numSend = threadSendIndex.size();
1381 
1382 // while(fieldIndexIt != stateFieldIndices.end()){
1383 
1384 // int fieldIndex = *fieldIndexIt++;
1385 
1386 // const pcpp::field::dataset::DataBufferType &xFieldData(xData[fieldIndex]);
1387 // const pcpp::field::metadata &fieldMetaData(solnMetaData[fieldIndex]);
1388 
1389 // const double *xBuffer = xFieldData.Data<double>();
1390 
1391 // int numComponents = fieldMetaData.ncomp;
1392 // size_t sourceSize = xFieldData.NItems()/numComponents;
1393 
1394 // for(int iComponent = 0;iComponent < numComponents;iComponent++){
1395 // int sourceIndex = iComponent*sourceSize;
1396 // int bufferIndex = iComponent*numSend;
1397 // for(int iData = 0;iData < numSend;iData++){
1398 // int dataIndex = sourceIndex + threadSendIndex[iData];
1399 // int packIndex = bufferIndex + threadPackIndex[iData];
1400 // sendBuffer[packIndex] = xBuffer[dataIndex];
1401 // }
1402 // }
1403 // }
1404 // }
1405 // return(0);
1406 // };
1407 
1408  int halo::Send(CommunicatorType &inComm)
1409  {
1410  if(inComm.NProc() <= 1)
1411  return(0);
1412  if(!haveSendData)
1413  return(0);
1414  std::vector<double *> &sendBuffers(this->SendBuffers());
1415  std::vector<pcpp::RemoteCollisionType> &sendCollisions(this->SendCollisions());
1416 
1417  int numSendBuffers = sendBuffers.size();
1418 
1419  for(int i = 0;i < numSendBuffers;i++){
1420  pcpp::RemoteCollisionType &sendInfo(sendCollisions[i]);
1421  int remoteRank = sendInfo.first;
1422  size_t numPoints = sendInfo.second.NNodes();
1423  size_t numSend = numPoints * this->numStateComponents;
1424  inComm.ASendBuf(sendBuffers[i],numSend,remoteRank);
1425  }
1426 
1427  return(0);
1428  };
1429 
1430 
1431 
1432  int halo::PostReceives(CommunicatorType &inComm)
1433  {
1434  if(inComm.NProc() <= 1)
1435  return(0);
1436  if(this->RecvCollisions().empty())
1437  return(0);
1438  if(!haveRecvData)
1439  return(0);
1440  int numStateComponents = this->numStateComponents;
1441  std::vector<pcpp::RemoteCollisionType> &recvCollisions(this->RecvCollisions());
1442  std::vector<double *> &recvBuffers(this->RecvBuffers());
1443  int numRecvs = recvBuffers.size();
1444 
1445  for(int i = 0;i < numRecvs;i++){
1446  pcpp::RemoteCollisionType &recvInfo(recvCollisions[i]);
1447  int remoteRank = recvInfo.first;
1448  size_t numPoints = recvInfo.second.NNodes();
1449  size_t numRecv = numPoints * numStateComponents;
1450  inComm.ARecvBuf(recvBuffers[i],numRecv,remoteRank);
1451  }
1452 
1453  return(0);
1454  };
1455 
1456  int halo::PostSimpleReceives(std::vector<int> &sourceRanks,CommunicatorType &inComm)
1457  {
1458  // if(inComm.NProc() <= 1)
1459  // return(0);
1460 
1461  if(!haveRecvData){
1462  std::cout << "halo::PostSimpleRecveives: WARNING: No data to receive!!" << std::endl;
1463  return(0);
1464  }
1465 
1466  int numStateComponents = this->numStateComponents;
1467  std::vector<double *> &recvBuffers(this->RecvBuffers());
1468  size_t numRecvs = haloRecvIndices.size();
1469 
1470  for(size_t i = 0;i < numRecvs;i++){
1471 
1472  int recvBufferIndex = haloRecvIndices[i].first;
1473 
1474  if(recvBufferIndex < 0){
1475  continue;
1476  }
1477 
1478  int remoteRank = sourceRanks[i];
1479 
1480  if(remoteRank < 0){
1481  if(recvBuffers[recvBufferIndex] != NULL){
1482  return(1);
1483  }
1484  else{
1485  continue;
1486  }
1487  }
1488 
1489  if(recvBuffers[recvBufferIndex] == NULL){
1490  std::cout << "No receive buffer exists for this neighbor: " << remoteRank << std::endl;
1491  return(1);
1492  }
1493  // std::cout << "Recv buffer index " << (i==recvBufferIndex ? "matches" : "does not match")
1494  // << " direction index." << std::endl;
1495  std::vector<size_t> &recvIndices(haloRecvIndices[i].second);
1496  size_t numPoints = recvIndices.size();
1497  size_t numRecv = numPoints * numStateComponents;
1498  int recvDir = i%2;
1499  int tag = 0;
1500  if(recvDir == 0)
1501  tag = i + 1;
1502  if(recvDir == 1)
1503  tag = i - 1;
1504  // std::cout << "Rank(" << inComm.Rank() << ") recv local direction ["
1505  // << i << "," << recvDir << "] in remote direction tag[" << tag << "] from rank ("
1506  // << remoteRank << ") in RecvBuffer ID (" << recvBufferIndex
1507  // << ") ADDRESS: " << recvBuffers[recvBufferIndex] << std::endl;
1508  inComm.ARecvBuf(recvBuffers[recvBufferIndex],numRecv,remoteRank,tag);
1509  }
1510  return(0);
1511  };
1512 
1513  void halo::ConfigureData(const state::base &inState)
1514  {
1515  std::vector<int> selectFields(inState.StateFieldIndices());
1516  ConfigureData(inState,selectFields);
1517  };
1518 
1519  void halo::ConfigureData(const state::base &inState,const std::vector<int> &selectFields)
1520  {
1521 
1522  stateFieldIndices = selectFields;
1523  numStateFields = stateFieldIndices.size();
1524  numFieldComponents.resize(numStateFields);
1525  numStateComponents = 0;
1526  int fieldCount = 0;
1527  std::vector<int>::iterator fieldIndexIt = stateFieldIndices.begin();
1528  while(fieldIndexIt != stateFieldIndices.end()){
1529  int fieldIndex(*fieldIndexIt++);
1530  numFieldComponents[fieldCount] = inState.Meta()[fieldIndex].ncomp;
1531  numStateComponents += numFieldComponents[fieldCount];
1532  fieldCount++;
1533  }
1534  };
1535 
1536  int halo::CompleteReceives(CommunicatorType &inComm)
1537  {
1538  if(!haveRecvData)
1539  return(0);
1540  inComm.WaitAll();
1541  this->UnpackReceiveBuffers();
1542  return(0);
1543  };
1544 
1545  int halo::Wait(CommunicatorType &inComm)
1546  {
1547  if(!haveRecvData)
1548  return(0);
1549  inComm.WaitAll();
1550  return(0);
1551  };
1552 
1553  int halo::CompleteSimpleReceives(CommunicatorType &inComm)
1554  {
1555  if(!haveRecvData){
1556  std::cout << "halo::CompleteSimpleReceives: WARNING: No Data!!"
1557  << std::endl;;
1558  return(0);
1559  }
1560  inComm.WaitAll();
1561  this->UnpackSimpleRecvBuffers();
1562  return(0);
1563  };
1564 
1565  void halo::ReportSimpleBufferContents(std::ostream &outStream)
1566  {
1567  if(!localHaloExtents.empty()){
1568  int numLocalHalos = localHaloExtents.size();
1569  for(int iHalo = 0;iHalo < numLocalHalos;iHalo++){
1570  pcpp::IndexIntervalType &localHaloExtent(localHaloExtents[iHalo]);
1571  if(!localHaloExtent.empty()){
1572  size_t nNodesSend = localHaloExtent.NNodes();
1573  outStream << "Local halo " << iHalo << " send buffer: ";
1574  if(!(sendBuffers[iHalo] == NULL)){
1575  outStream << std::endl;
1576  int tcomp = 0;
1577  for(int iField = 0;iField < numStateFields;iField++){
1578  for(int iComp = 0;iComp < numFieldComponents[iField];iComp++){
1580  sendBuffers[iHalo+(tcomp*nNodesSend)+iComp*nNodesSend],
1581  localHaloExtent);
1582  outStream << std::endl;
1583  }
1584  tcomp += numFieldComponents[iField];
1585  }
1586  } else {
1587  outStream << "[NULL]" << std::endl;
1588  }
1589  }
1590  }
1591  }
1592  if(!remoteHaloExtents.empty()){
1593  int numRemoteHalos = remoteHaloExtents.size();
1594  for(int iHalo = 0;iHalo < numRemoteHalos;iHalo++){
1595  pcpp::IndexIntervalType &remoteHaloExtent(remoteHaloExtents[iHalo]);
1596  if(!remoteHaloExtent.empty()){
1597  size_t numPointsHalo = remoteHaloExtent.NNodes();
1598  outStream << "Remote halo " << iHalo << ": ";
1599  for(int iField = 0;iField < numStateFields;iField++){
1600  outStream << "Field " << iField << ": ";
1601  if(!(haloBuffers[iField][iHalo] == NULL)){
1602  outStream << std::endl;
1603  for(int iComp = 0;iComp < numFieldComponents[iField];iComp++){
1604  pcpp::report::StructuredBufferContents<double>
1605  (outStream,haloBuffers[iField][iHalo],remoteHaloExtent);
1606  outStream << std::endl;
1607  }
1608  } else {
1609  outStream << "[NULL]" << std::endl;
1610  }
1611  }
1612  }
1613  }
1614  }
1615  if(!remoteHaloExtents.empty()){
1616  int numRemoteHalos = remoteHaloExtents.size();
1617  for(int iHalo = 0;iHalo < numRemoteHalos;iHalo++){
1618  pcpp::IndexIntervalType &remoteHaloExtent(remoteHaloExtents[iHalo]);
1619  if(!remoteHaloExtent.empty()){
1620  size_t nNodesRecv = remoteHaloExtent.NNodes();
1621  outStream << "Remote halo " << iHalo << " recv buffer: ";
1622  if(!(recvBuffers[iHalo] == NULL)){
1623  outStream << std::endl;
1624  int tcomp = 0;
1625  for(int iField = 0;iField < numStateFields;iField++){
1626  for(int iComp = 0;iComp < numFieldComponents[iField];iComp++){
1628  recvBuffers[iHalo+(tcomp*nNodesRecv)+iComp*nNodesRecv],
1629  remoteHaloExtent);
1630  outStream << std::endl;
1631  }
1632  tcomp += numFieldComponents[iField];
1633  }
1634  } else {
1635  outStream << "[NULL]" << std::endl;
1636  }
1637  }
1638  }
1639  }
1640  };
1641  void probe::SetProbeFields(const std::vector<std::string> &inFields)
1642  {
1643  if(!fieldIndices.empty())
1644  fieldIndices.resize(0);
1645  probeFields = inFields;
1646  };
1647  void probe::SetDelimiter(const std::string &inPointDelimiter)
1648  {
1649  pointDelimiter = inPointDelimiter;
1650  }
1651  void probe::SetState(const simulation::state::base &inState)
1652  {
1653  statePtr = &inState;
1654  fieldIndices.resize(0);
1655  };
1656  void probe::SetDataInterval(const pcpp::IndexIntervalType &inInterval)
1657  {
1658  if(!flatProbeIndices.empty())
1659  flatProbeIndices.resize(0);
1660  dataInterval = inInterval;
1661  };
1662  void probe::SetProbeInterval(const pcpp::IndexIntervalType &inInterval)
1663  {
1664  if(!flatProbeIndices.empty())
1665  flatProbeIndices.resize(0);
1666  probeInterval = inInterval;
1667  };
1668  int probe::Probe(const simulation::state::base &inState,std::ostream &outStream)
1669  {
1670  SetState(inState);
1671  return(Probe(outStream));
1672  };
1673  int probe::Probe(std::ostream &outStream)
1674  {
1675  if(statePtr == NULL)
1676  return(1);
1677  if(fieldIndices.empty()){
1678  if(InitFieldIndices())
1679  return(2);
1680  }
1681  if(flatProbeIndices.empty()){
1682  if(InitFlatProbeIndices())
1683  return(3);
1684  }
1685  std::ostringstream Ostr;
1686  const pcpp::field::dataset::DataContainerType &probeData(statePtr->Data());
1687  const pcpp::field::metadataset &probeMeta(statePtr->Meta());
1688  size_t numNodes = flatProbeIndices.size();
1689  int numFields = fieldIndices.size();
1690  for(size_t iNode = 0;iNode < numNodes;iNode++){
1691  size_t probeIndex = flatProbeIndices[iNode];
1692  for(int iField = 0;iField < numFields;iField++){
1693  int fieldIndex = fieldIndices[iField];
1694  const pcpp::field::metadata &fieldMeta(probeMeta[fieldIndex]);
1695  const pcpp::field::databuffer &fieldData(probeData[fieldIndex]);
1696  int numComponents = fieldMeta.ncomp;
1697  int dsize = fieldMeta.dsize;
1698  int nItems = fieldData.NItems();
1699  int nPerComponent = nItems/numComponents;
1700  for(int iComp = 0;iComp < numComponents;iComp++){
1701  if(dsize == 1){
1702  const char *dataPtr = fieldData.Data<char>();
1703  outStream << dataPtr[probeIndex+nPerComponent*iComp];
1704  } else if (dsize == 4){
1705  const int *dataPtr = fieldData.Data<int>();
1706  outStream << dataPtr[probeIndex+nPerComponent*iComp];
1707  } else if (dsize == 8){
1708  const double *dataPtr = fieldData.Data<double>();
1709  outStream << dataPtr[probeIndex+nPerComponent*iComp];
1710  }
1711  outStream << " ";
1712  }
1713  }
1714  outStream << pointDelimiter;
1715  }
1716  return(0);
1717  };
1718  int probe::InitFieldIndices(){
1719  fieldIndices.resize(0);
1720  std::vector<std::string>::iterator fieldNameIt = probeFields.begin();
1721  while(fieldNameIt != probeFields.end()){
1722  std::string &fieldName(*fieldNameIt++);
1723  int fieldIndex = statePtr->GetFieldIndex(fieldName);
1724  if(fieldIndex < 0)
1725  return(-1);
1726  fieldIndices.push_back(fieldIndex);
1727  }
1728  return(0);
1729  };
1730  int probe::InitFlatProbeIndices(){
1731  flatProbeIndices.resize(0);
1732  pcpp::IndexIntervalType overlapInterval;
1733  dataInterval.Overlap(probeInterval,overlapInterval);
1734  if(overlapInterval != probeInterval)
1735  return(1);
1736  dataInterval.GetFlatIndices(probeInterval,flatProbeIndices);
1737  if(flatProbeIndices.empty())
1738  return(1);
1739  numNodes = flatProbeIndices.size();
1740  return(0);
1741  };
1742  };
1743 };
DataContainerType & Data()
void GetFlatIndices(const sizeextent &extent, ContainerType &indices) const
Definition: IndexUtil.H:302
int ARecvBuf(DataType *recvbuf, size_t nVal, unsigned int remote_rank, int tag=0)
Definition: COMM.H:163
void const size_t * numPoints
Definition: EulerKernels.H:10
void StructuredBufferContents(std::ostream &outStream, const BufferDataType *dataBuffer, const pcpp::IndexIntervalType &bufferExtent)
Definition: PCPPReport.H:23
const std::vector< int > & StateFieldIndices() const
Definition: State.H:307
std::vector< size_t > numPointsSend
Definition: State.H:417
std::vector< double * > recvBuffers
Definition: State.H:420
int ASendBuf(DataType *sendBuf, size_t nVal, unsigned int remote_rank, int tag=-1)
Definition: COMM.H:155
size_t NNodes() const
Definition: IndexUtil.H:254
metadataset & Meta()
std::vector< size_t > numPointsRecv
Definition: State.H:418
Main encapsulation of MPI.
Definition: COMM.H:62
std::string GetValue(const std::string &key) const
Definition: Parameters.C:24
std::vector< std::string > GetValueVector(const std::string &key) const
Definition: Parameters.C:36
void Overlap(const sizeextent &inextent, sizeextent &outextent) const
Definition: IndexUtil.H:324
std::vector< DataBufferType > DataContainerType
void size_t int size_t int size_t int int int int double int int double double *void size_t int size_t int int int int int double int size_t size_t size_t double double *void size_t int size_t int size_t size_t int double int double double *void size_t size_t size_t * bufferInterval
std::string ConfigKey(const std::string &configName, const std::string &keyName)
Definition: PCPPUtil.C:191
std::vector< double * > sendBuffers
Definition: State.H:419
Simple Block Structured Mesh object.
Definition: IndexUtil.H:21
void size_t int * numComponents
void InitSimple(const ContainerType &inSize)
Definition: IndexUtil.H:169
void const size_t * numPointsBuffer
Definition: MetricKernels.H:19
std::pair< int, IndexIntervalType > RemoteCollisionType
Definition: PCPPTypes.H:27