GEOS
BufferOps_inline.hpp
1 /*
2  * ------------------------------------------------------------------------------------------------------------
3  * SPDX-License-Identifier: LGPL-2.1-only
4  *
5  * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC
6  * Copyright (c) 2018-2024 TotalEnergies
7  * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University
8  * Copyright (c) 2023-2024 Chevron
9  * Copyright (c) 2019- GEOS/GEOSX Contributors
10  * All rights reserved
11  *
12  * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details.
13  * ------------------------------------------------------------------------------------------------------------
14  */
15 
16 #ifndef GEOS_DATAREPOSITORY_BUFFEROPS_INLINE_HPP_
17 #define GEOS_DATAREPOSITORY_BUFFEROPS_INLINE_HPP_
18 
19 #include "common/DataTypes.hpp"
20 #include "common/TimingMacros.hpp"
21 #include "codingUtilities/Utilities.hpp"
22 #include "codingUtilities/traits.hpp"
23 #include "LvArray/src/limits.hpp"
24 #include "common/GEOS_RAJA_Interface.hpp"
25 
26 #include <type_traits>
27 
28 namespace geos
29 {
30 
31 namespace bufferOps
32 {
33 
34 template< bool DO_PACKING, typename T >
35 typename std::enable_if< std::is_trivial< T >::value, localIndex >::type
36 Pack( buffer_unit_type * & buffer, T const & var )
37 {
38  localIndex const sizeOfPackedChars = sizeof(T);
39  if( DO_PACKING )
40  {
41  memcpy( buffer, &var, sizeOfPackedChars );
42  buffer += sizeOfPackedChars;
43  }
44  return sizeOfPackedChars;
45 }
46 
47 template< bool DO_PACKING, typename T, typename INDEX_TYPE >
48 typename std::enable_if< std::is_trivial< T >::value, localIndex >::type
49 Pack( buffer_unit_type * & buffer, T const * const GEOS_RESTRICT var, INDEX_TYPE const length )
50 {
51  localIndex sizeOfPackedChars = Pack< DO_PACKING >( buffer, length );
52 
53  sizeOfPackedChars += length * sizeof(T);
54  if( DO_PACKING )
55  {
56  memcpy( buffer, var, length * sizeof(T) );
57  buffer += length * sizeof(T);
58  }
59 
60  return sizeOfPackedChars;
61 }
62 
63 template< typename T, typename INDEX_TYPE >
64 typename std::enable_if< std::is_trivial< T >::value, localIndex >::type
65 Unpack( buffer_unit_type const * & buffer, T * const GEOS_RESTRICT var, INDEX_TYPE const expectedLength )
66 {
67  INDEX_TYPE length;
68  localIndex sizeOfUnpackedChars = Unpack( buffer, length );
69 
70  GEOS_ASSERT_MSG( length == expectedLength, "expectedLength != length: " <<
71  expectedLength << " != " << length );
72  GEOS_DEBUG_VAR( expectedLength );
73 
74  memcpy( var, buffer, length * sizeof(T) );
75  sizeOfUnpackedChars += length * sizeof(T);
76  buffer += length * sizeof(T);
77 
78  return sizeOfUnpackedChars;
79 }
80 
81 template< bool DO_PACKING >
82 localIndex Pack( buffer_unit_type * & buffer, const string & var )
83 {
84  const string::size_type varSize = var.size();
85  localIndex sizeOfPackedChars = Pack< DO_PACKING >( buffer, varSize );
86 
87  if( DO_PACKING )
88  {
89  memcpy( buffer, var.data(), varSize );
90  buffer += varSize;
91  }
92 
93  sizeOfPackedChars += varSize;
94  return sizeOfPackedChars;
95 }
96 
97 template< bool DO_PACKING, typename T, typename SET >
99 PackSet( buffer_unit_type * & buffer,
100  SET const & var )
101 {
102  const localIndex length = LvArray::integerConversion< localIndex >( var.size() );
103  localIndex sizeOfPackedChars = Pack< DO_PACKING >( buffer, length );
104  for( T const & val : var )
105  {
106  sizeOfPackedChars += Pack< DO_PACKING >( buffer, val );
107  }
108  return sizeOfPackedChars;
109 }
110 
111 template< bool DO_PACKING, typename T, int SIZE >
112 localIndex Pack( buffer_unit_type * & buffer, Tensor< T, SIZE > const & var )
113 {
114  localIndex sizeOfPackedChars = 0;
115  sizeOfPackedChars += PackPointer< DO_PACKING >( buffer, var.data, SIZE );
116  return sizeOfPackedChars;
117 }
118 
119 template< bool DO_PACKING, typename T, int NDIM, int USD >
120 typename std::enable_if< is_packable< T >, localIndex >::type
121 Pack( buffer_unit_type * & buffer,
122  ArrayView< T, NDIM, USD > const & var )
123 {
124  localIndex sizeOfPackedChars = PackPointer< DO_PACKING >( buffer, var.dims(), NDIM );
125  sizeOfPackedChars += PackPointer< DO_PACKING >( buffer, var.strides(), NDIM );
126  const localIndex length = var.size();
127  T const * const data = var.data();
128  sizeOfPackedChars += PackPointer< DO_PACKING >( buffer, data, length );
129  return sizeOfPackedChars;
130 }
131 
132 template< bool DO_PACKING, typename T >
133 inline
135 Pack( buffer_unit_type * & buffer,
136  std::vector< T > const & var )
137 {
138  size_t const length = var.size();
139  localIndex sizeOfPackedChars = Pack< DO_PACKING >( buffer, length );
140  for( T const & str : var )
141  {
142  sizeOfPackedChars += Pack< DO_PACKING >( buffer, str );
143  }
144  return sizeOfPackedChars;
145 }
146 
147 template< bool DO_PACKING, typename T >
148 localIndex Pack( buffer_unit_type * & buffer,
149  ArrayOfArrays< T > const & var )
150 {
151  localIndex sizeOfPackedChars = 0;
152  sizeOfPackedChars += Pack< DO_PACKING >( buffer, var.size() );
153  for( localIndex a=0; a<var.size(); ++a )
154  {
155  sizeOfPackedChars += Pack< DO_PACKING >( buffer, var.sizeOfArray( a ) );
156  T const * const data = var[a];
157  sizeOfPackedChars += PackPointer< DO_PACKING >( buffer, data, var.sizeOfArray( a ) );
158  }
159  return sizeOfPackedChars;
160 }
161 
162 template< bool DO_PACKING, typename T >
163 localIndex Pack( buffer_unit_type * & buffer,
164  ArrayOfSets< T > const & var )
165 {
166  localIndex sizeOfPackedChars = 0;
167  sizeOfPackedChars += Pack< DO_PACKING >( buffer, var.size() );
168  for( localIndex a=0; a<var.size(); ++a )
169  {
170  sizeOfPackedChars += Pack< DO_PACKING >( buffer, var.sizeOfSet( a ) );
171  T const * const data = var[a];
172  sizeOfPackedChars += PackPointer< DO_PACKING >( buffer, data, var.sizeOfSet( a ) );
173  }
174  return sizeOfPackedChars;
175 }
176 
177 template< bool DO_PACKING, typename MAP_TYPE >
178 typename std::enable_if< is_packable_map< MAP_TYPE >, localIndex >::type
179 Pack( buffer_unit_type * & buffer, MAP_TYPE const & var )
180 {
181  const typename MAP_TYPE::size_type length = var.size();
182  localIndex sizeOfPackedChars = Pack< DO_PACKING >( buffer, length );
183  for( typename MAP_TYPE::const_iterator i = var.begin(); i != var.end(); ++i )
184  {
185  sizeOfPackedChars += Pack< DO_PACKING >( buffer, i->first );
186  sizeOfPackedChars += Pack< DO_PACKING >( buffer, i->second );
187  }
188  return sizeOfPackedChars;
189 }
190 
191 template< bool DO_PACKING, typename T_FIRST, typename T_SECOND >
193 Pack( buffer_unit_type * & buffer, std::pair< T_FIRST, T_SECOND > const & var )
194 {
195  localIndex sizeOfPackedChars = Pack< DO_PACKING >( buffer, var.first );
196  sizeOfPackedChars += Pack< DO_PACKING >( buffer, var.second );
197  return sizeOfPackedChars;
198 }
199 
200 template< bool DO_PACKING, typename T >
201 localIndex Pack( buffer_unit_type * & buffer, InterObjectRelation< T > const & var )
202 {
203  return Pack< DO_PACKING >( buffer, static_cast< T const & >(var));
204 }
205 
206 //------------------------------------------------------------------------------
207 // PackArray(buffer,var,length)
208 //------------------------------------------------------------------------------
209 template< bool DO_PACKING, typename T, typename INDEX_TYPE >
210 typename std::enable_if< std::is_trivial< T >::value, localIndex >::type
211 PackPointer( buffer_unit_type * & buffer, T const * const GEOS_RESTRICT var, INDEX_TYPE const length )
212 {
213  localIndex sizeOfPackedChars = Pack< DO_PACKING >( buffer, length );
214  sizeOfPackedChars += length * sizeof(T);
215  if( DO_PACKING )
216  {
217  memcpy( buffer, var, length * sizeof(T) );
218  buffer += length * sizeof(T);
219  }
220  return sizeOfPackedChars;
221 }
222 
223 template< bool DO_PACKING, typename T, typename INDEX_TYPE >
224 typename std::enable_if< !std::is_trivial< T >::value, localIndex >::type
225 PackPointer( buffer_unit_type * & buffer,
226  T const * const GEOS_RESTRICT var,
227  INDEX_TYPE const length )
228 
229 {
230  localIndex sizeOfPackedChars = Pack< DO_PACKING >( buffer, length );
231  for( INDEX_TYPE a = 0; a < length; ++a )
232  {
233  sizeOfPackedChars += Pack< DO_PACKING >( buffer, var[ a ] );
234  }
235 
236  return sizeOfPackedChars;
237 }
238 
239 template< bool DO_PACKING, typename T, typename INDEX_TYPE, int USD >
240 typename std::enable_if< std::is_trivial< T >::value, localIndex >::type
241 PackArray( buffer_unit_type * & buffer,
242  arraySlice1d< T, USD > const & var,
243  INDEX_TYPE const length )
244 {
245  localIndex sizeOfPackedChars = Pack< DO_PACKING >( buffer, length );
246  sizeOfPackedChars += length * sizeof(T);
247  if( DO_PACKING )
248  {
249  T * const GEOS_RESTRICT buffer_T = reinterpret_cast< T * >( buffer );
250  for( INDEX_TYPE i = 0; i < length; ++i )
251  {
252  buffer_T[ i ] = var[ i ];
253  }
254  buffer += length * sizeof(T);
255  }
256  return sizeOfPackedChars;
257 }
258 
259 template< bool DO_PACKING, typename T, typename INDEX_TYPE, int USD >
260 typename std::enable_if< !std::is_trivial< T >::value, localIndex >::type
261 PackArray( buffer_unit_type * & buffer,
262  arraySlice1d< T, USD > const & var,
263  INDEX_TYPE const length )
264 {
265  localIndex sizeOfPackedChars = Pack< DO_PACKING >( buffer, length );
266  for( INDEX_TYPE a = 0; a < length; ++a )
267  {
268  sizeOfPackedChars += Pack< DO_PACKING >( buffer, var[ a ] );
269  }
270  return sizeOfPackedChars;
271 }
272 
273 //------------------------------------------------------------------------------
274 // PackByIndex(buffer,var,indices)
275 //------------------------------------------------------------------------------
276 template< bool DO_PACKING, typename T, typename T_indices >
277 typename std::enable_if< is_packable< T >, localIndex >::type
278 PackByIndex( buffer_unit_type * & buffer,
279  std::vector< T > const & var,
280  const T_indices & indices )
281 {
282  localIndex sizeOfPackedChars = Pack< DO_PACKING >( buffer, indices.size() );
283  for( auto a = 0; a < indices.size(); ++a )
284  {
285  sizeOfPackedChars += Pack< DO_PACKING >( buffer, var[indices[a]] );
286  }
287  return sizeOfPackedChars;
288 }
289 
290 
291 
292 template< bool DO_PACKING, typename T, int NDIM, int USD, typename T_indices >
293 typename std::enable_if< is_packable< T >, localIndex >::type
294 PackByIndex( buffer_unit_type * & buffer,
295  ArrayView< T, NDIM, USD > const & var,
296  const T_indices & indices )
297 {
298  localIndex sizeOfPackedChars = PackPointer< DO_PACKING >( buffer, var.strides(), NDIM );
299  for( localIndex a = 0; a < indices.size(); ++a )
300  {
301  LvArray::forValuesInSlice( var[ indices[ a ] ],
302  [&sizeOfPackedChars, &buffer]( T const & value )
303  {
304  sizeOfPackedChars += Pack< DO_PACKING >( buffer, value );
305  }
306  );
307  }
308  return sizeOfPackedChars;
309 }
310 
311 template< bool DO_PACKING, typename T, typename T_indices >
312 localIndex PackByIndex( buffer_unit_type * & buffer,
313  ArrayOfArrays< T > const & var,
314  T_indices const & indices )
315 {
316  localIndex sizeOfPackedChars = 0;
317  sizeOfPackedChars += Pack< DO_PACKING >( buffer, indices.size() );
318  for( localIndex a = 0; a < indices.size(); ++a )
319  {
320  sizeOfPackedChars += Pack< DO_PACKING >( buffer, var.sizeOfArray( indices[a] ) );
321  T const * const data = var[indices[a]];
322  sizeOfPackedChars += PackPointer< DO_PACKING >( buffer, data, var.sizeOfArray( indices[a] ) );
323  }
324  return sizeOfPackedChars;
325 }
326 
327 template< bool DO_PACKING, typename MAP_TYPE, typename T_INDICES >
328 typename std::enable_if< is_map_packable_by_index< MAP_TYPE >, localIndex >::type
329 PackByIndex( buffer_unit_type * & buffer,
330  MAP_TYPE const & var,
331  T_INDICES const & packIndices )
332 {
333  const typename MAP_TYPE::size_type length = var.size();
334  localIndex sizeOfPackedChars = Pack< DO_PACKING >( buffer, length );
335  for( typename MAP_TYPE::const_iterator i = var.begin(); i != var.end(); ++i )
336  {
337  sizeOfPackedChars += Pack< DO_PACKING >( buffer, i->first );
338  sizeOfPackedChars += PackByIndex< DO_PACKING >( buffer, i->second, packIndices );
339  }
340  return sizeOfPackedChars;
341 }
342 
343 //------------------------------------------------------------------------------
344 // Unpack(buffer,var)
345 //------------------------------------------------------------------------------
346 template< typename T >
347 typename std::enable_if< std::is_trivial< T >::value, localIndex >::type
348 Unpack( buffer_unit_type const * & buffer,
349  T & var )
350 {
351  localIndex const sizeOfUnpackedChars = sizeof(T);
352  memcpy( &var, buffer, sizeOfUnpackedChars );
353  buffer += sizeOfUnpackedChars;
354  return sizeOfUnpackedChars;
355 }
356 
357 inline
359 Unpack( buffer_unit_type const * & buffer,
360  string & var )
361 {
362  string::size_type stringsize = 0;
363  localIndex sizeOfUnpackedChars = Unpack( buffer, stringsize );
364  var.resize( stringsize );
365  memcpy( &var[0], buffer, stringsize );
366  buffer += stringsize;
367  sizeOfUnpackedChars += stringsize;
368  return sizeOfUnpackedChars;
369 }
370 
371 template< typename T, int SIZE >
373 Unpack( buffer_unit_type const * & buffer,
374  Tensor< T, SIZE > & var )
375 {
376  localIndex sizeOfUnpackedChars = 0;
377  sizeOfUnpackedChars += UnpackPointer( buffer, var.data, SIZE );
378  return sizeOfUnpackedChars;
379 }
380 
381 template< typename T, typename SET >
383 UnpackSet( buffer_unit_type const * & buffer,
384  SET & var )
385 {
386  var.clear();
387  localIndex set_length;
388  localIndex sizeOfUnpackedChars = Unpack( buffer, set_length );
389  for( localIndex a=0; a<set_length; ++a )
390  {
391  T temp;
392  sizeOfUnpackedChars += Unpack( buffer, temp );
393  var.insert( temp );
394  }
395  return sizeOfUnpackedChars;
396 }
397 
398 template< typename T, int NDIM, typename PERMUTATION >
399 typename std::enable_if< is_packable< T >, localIndex >::type
400 Unpack( buffer_unit_type const * & buffer,
401  Array< T, NDIM, PERMUTATION > & var )
402 {
403  localIndex dims[NDIM];
404  localIndex sizeOfUnpackedChars = UnpackPointer( buffer, dims, NDIM );
405  var.resize( NDIM, dims );
406 
407  localIndex strides[NDIM];
408  sizeOfUnpackedChars += UnpackPointer( buffer, strides, NDIM );
409  for( int i=0; i<NDIM; ++i )
410  {
411  GEOS_ASSERT_EQ( strides[i], var.strides()[i] );
412  }
413 
414  sizeOfUnpackedChars += UnpackPointer( buffer, var.data(), var.size() );
415  return sizeOfUnpackedChars;
416 }
417 
418 
419 template< typename T >
420 typename std::enable_if< is_packable< T >, localIndex >::type
421 Unpack( buffer_unit_type const * & buffer,
422  std::vector< T > & var )
423 {
424  size_t length;
425  localIndex sizeOfUnpackedChars = Unpack( buffer, length );
426  var.resize( length );
427  for( T & val : var )
428  {
429  sizeOfUnpackedChars += Unpack( buffer, val );
430  }
431  return sizeOfUnpackedChars;
432 }
433 
434 template< typename T >
435 localIndex Unpack( buffer_unit_type const * & buffer,
436  ArrayOfArrays< T > & var )
437 {
438  localIndex sizeOfUnpackedChars = 0;
439  localIndex numOfArrays;
440  sizeOfUnpackedChars += Unpack( buffer, numOfArrays );
441  var.resize( numOfArrays );
442  for( localIndex a=0; a<numOfArrays; ++a )
443  {
444  localIndex sizeOfArray;
445  sizeOfUnpackedChars += Unpack( buffer, sizeOfArray );
446  var.resizeArray( a, sizeOfArray );
447  T * data = var[a];
448  sizeOfUnpackedChars += UnpackPointer( buffer, data, sizeOfArray );
449  }
450  return sizeOfUnpackedChars;
451 }
452 
453 inline
455 Unpack( buffer_unit_type const * & buffer,
456  ArrayOfArrays< array1d< globalIndex > > & var,
457  localIndex const subArrayIndex )
458 {
459  localIndex length;
460  localIndex sizeOfUnpackedChars = bufferOps::Unpack( buffer, length );
461 
462  var.resizeArray( subArrayIndex, length );
463 
464  for( localIndex a = 0; a < length; ++a )
465  {
466  array1d< globalIndex > & tmp = var( subArrayIndex, a );
467  sizeOfUnpackedChars += bufferOps::Unpack( buffer, tmp );
468  }
469 
470  return sizeOfUnpackedChars;
471 }
472 
473 
474 template< typename T >
475 localIndex Unpack( buffer_unit_type const * & buffer,
476  ArrayOfSets< T > & var )
477 {
478  ArrayOfArrays< T > varAsArray;
479  localIndex sizeOfUnpackedChars = Unpack( buffer, varAsArray );
480  var.template assimilate< parallelHostPolicy >( std::move( varAsArray ), LvArray::sortedArrayManipulation::SORTED_UNIQUE );
481  return sizeOfUnpackedChars;
482 }
483 
484 template< typename MAP_TYPE >
485 typename std::enable_if< is_packable_map< MAP_TYPE >, localIndex >::type
486 Unpack( buffer_unit_type const * & buffer,
487  MAP_TYPE & map )
488 {
489  map.clear();
490  typename MAP_TYPE::size_type map_length;
491  localIndex sizeOfUnpackedChars = Unpack( buffer, map_length );
492  for( typename MAP_TYPE::size_type a = 0; a < map_length; ++a )
493  {
494  typename MAP_TYPE::key_type key;
495  typename MAP_TYPE::mapped_type value;
496  sizeOfUnpackedChars += Unpack( buffer, key );
497  sizeOfUnpackedChars += Unpack( buffer, value );
498  map[key] = std::move( value );
499  }
500  return sizeOfUnpackedChars;
501 }
502 
503 template< typename T_FIRST, typename T_SECOND >
504 localIndex Unpack( buffer_unit_type const * & buffer,
505  std::pair< T_FIRST, T_SECOND > & var )
506 {
507  localIndex sizeOfUnpackedChars = Unpack( buffer, var.first );
508  sizeOfUnpackedChars += Unpack( buffer, var.second );
509  return sizeOfUnpackedChars;
510 }
511 
512 template< typename T >
513 localIndex Unpack( buffer_unit_type const * & buffer,
514  InterObjectRelation< T > & var )
515 {
516  return Unpack( buffer, static_cast< T & >(var));
517 }
518 
519 //------------------------------------------------------------------------------
520 // UnpackArray(buffer,var,expectedLength)
521 //------------------------------------------------------------------------------
522 template< typename T, typename INDEX_TYPE >
523 typename std::enable_if< std::is_trivial< T >::value, localIndex >::type
524 UnpackPointer( buffer_unit_type const * & buffer,
525  T * const GEOS_RESTRICT var,
526  INDEX_TYPE const expectedLength )
527 {
528  INDEX_TYPE length;
529  localIndex sizeOfUnpackedChars = Unpack( buffer, length );
530  GEOS_ASSERT_MSG( length == expectedLength, "expectedLength != length: " <<
531  expectedLength << " != " << length );
532  GEOS_DEBUG_VAR( expectedLength );
533  memcpy( var, buffer, length * sizeof(T) );
534  sizeOfUnpackedChars += length * sizeof(T);
535  buffer += length * sizeof(T);
536  return sizeOfUnpackedChars;
537 }
538 
539 template< typename T, typename INDEX_TYPE >
540 typename std::enable_if< !std::is_trivial< T >::value, localIndex >::type
541 UnpackPointer( buffer_unit_type const * & buffer,
542  T * const GEOS_RESTRICT var,
543  INDEX_TYPE const expectedLength )
544 {
545  INDEX_TYPE length;
546  localIndex sizeOfUnpackedChars = Unpack( buffer, length );
547  GEOS_ASSERT_EQ( length, expectedLength );
548  GEOS_DEBUG_VAR( expectedLength );
549 
550  for( INDEX_TYPE a=0; a<length; ++a )
551  {
552  sizeOfUnpackedChars += Unpack( buffer, var[a] );
553  }
554 
555  return sizeOfUnpackedChars;
556 }
557 
558 template< typename T, typename INDEX_TYPE, int USD >
559 typename std::enable_if< std::is_trivial< T >::value, localIndex >::type
560 UnpackArray( buffer_unit_type const * & buffer,
561  arraySlice1d< T, USD > const & var,
562  INDEX_TYPE const expectedLength )
563 {
564  INDEX_TYPE length;
565  localIndex sizeOfUnpackedChars = Unpack( buffer, length );
566  GEOS_DEBUG_VAR( expectedLength );
567  GEOS_ASSERT_EQ( length, expectedLength );
568 
569  T const * const GEOS_RESTRICT buffer_T = reinterpret_cast< T const * >( buffer );
570  for( INDEX_TYPE i = 0; i < length; ++i )
571  {
572  var[ i ] = buffer_T[ i ];
573  }
574 
575  buffer += length * sizeof(T);
576  sizeOfUnpackedChars += length * sizeof(T);
577  return sizeOfUnpackedChars;
578 }
579 
580 template< typename T, typename INDEX_TYPE, int USD >
581 typename std::enable_if< !std::is_trivial< T >::value, localIndex >::type
582 UnpackArray( buffer_unit_type const * & buffer,
583  arraySlice1d< T, USD > const & var,
584  INDEX_TYPE const expectedLength )
585 {
586  INDEX_TYPE length;
587  localIndex sizeOfUnpackedChars = Unpack( buffer, length );
588  GEOS_DEBUG_VAR( expectedLength );
589  GEOS_ASSERT_EQ( length, expectedLength );
590 
591  for( INDEX_TYPE a=0; a<length; ++a )
592  {
593  sizeOfUnpackedChars += Unpack( buffer, var[a] );
594  }
595 
596  return sizeOfUnpackedChars;
597 }
598 
599 //------------------------------------------------------------------------------
600 // UnpackByIndex(buffer,var,indices)
601 //------------------------------------------------------------------------------
602 template< typename T, typename T_indices >
604 UnpackByIndex( buffer_unit_type const * & buffer,
605  std::vector< T > & var,
606  T_indices const & indices )
607 {
608  localIndex sizeOfUnpackedChars = 0;
609  localIndex numUnpackedIndices;
610  sizeOfUnpackedChars += Unpack( buffer, numUnpackedIndices );
611  GEOS_ERROR_IF( numUnpackedIndices != indices.size(), "number of unpacked indices does not equal expected number" );
612 
613  for( localIndex a = 0; a < indices.size(); ++a )
614  {
615  sizeOfUnpackedChars += Unpack( buffer, var[ indices[ a ] ] );
616  }
617  return sizeOfUnpackedChars;
618 }
619 
620 template< typename T, int NDIM, int USD, typename T_indices >
622 UnpackByIndex( buffer_unit_type const * & buffer,
623  ArrayView< T, NDIM, USD > const & var,
624  const T_indices & indices )
625 {
626  localIndex strides[NDIM];
627  localIndex sizeOfUnpackedChars = UnpackPointer( buffer, strides, NDIM );
628 
629  for( localIndex a=0; a<indices.size(); ++a )
630  {
631  LvArray::forValuesInSlice( var[ indices[ a ] ],
632  [&sizeOfUnpackedChars, &buffer] ( T & value )
633  {
634  sizeOfUnpackedChars += Unpack( buffer, value );
635  }
636  );
637  }
638  return sizeOfUnpackedChars;
639 }
640 
641 template< typename T, typename T_indices >
643 UnpackByIndex( buffer_unit_type const * & buffer,
644  ArrayOfArrays< T > & var,
645  T_indices const & indices )
646 {
647  localIndex sizeOfUnpackedChars = 0;
648  localIndex numUnpackedIndices = 0;
649  sizeOfUnpackedChars += Unpack( buffer, numUnpackedIndices );
650  GEOS_ERROR_IF( numUnpackedIndices != indices.size(), "number of unpacked indices does not equal expected number" );
651  for( localIndex a = 0; a < indices.size(); ++a )
652  {
653  localIndex sizeOfSubArray;
654  sizeOfUnpackedChars += Unpack( buffer, sizeOfSubArray );
655  var.resizeArray( indices[a], sizeOfSubArray );
656  sizeOfUnpackedChars += UnpackArray( buffer, var[indices[a]], sizeOfSubArray );
657  }
658  return sizeOfUnpackedChars;
659 }
660 
661 template< typename MAP_TYPE, typename T_INDICES >
662 typename std::enable_if< is_map_packable_by_index< MAP_TYPE >, localIndex >::type
663 UnpackByIndex( buffer_unit_type const * & buffer,
664  MAP_TYPE & map,
665  T_INDICES const & unpackIndices )
666 {
667  map.clear();
668  typename MAP_TYPE::size_type map_length;
669  localIndex sizeOfUnpackedChars = Unpack( buffer, map_length );
670  for( typename MAP_TYPE::size_type a = 0; a < map_length; ++a )
671  {
672  typename MAP_TYPE::key_type key;
673  typename MAP_TYPE::mapped_type value;
674  sizeOfUnpackedChars += Unpack( buffer, key );
675  sizeOfUnpackedChars += UnpackByIndex( buffer, value, unpackIndices );
676  map[key] = std::move( value );
677  }
678  return sizeOfUnpackedChars;
679 }
680 
681 template< bool DO_PACKING, typename T, typename INDEX_TYPE >
682 localIndex Pack( buffer_unit_type * & buffer,
683  T const * const GEOS_RESTRICT var,
684  arraySlice1d< INDEX_TYPE const > const & indices,
685  INDEX_TYPE const length )
686 {
687  localIndex sizeOfPackedChars = Pack< DO_PACKING >( buffer, length );
688 
689  for( localIndex a=0; a<length; ++a )
690  {
691  sizeOfPackedChars += Pack< DO_PACKING >( buffer, var[ indices[a] ] );
692  }
693 
694  return sizeOfPackedChars;
695 }
696 
697 template< typename T, typename INDEX_TYPE >
698 localIndex Unpack( buffer_unit_type const * & buffer,
699  T * const GEOS_RESTRICT var,
700  arraySlice1d< INDEX_TYPE const > const & indices,
701  INDEX_TYPE & length )
702 {
703  localIndex sizeOfUnpackedChars = Unpack( buffer, length );
704 
705  for( INDEX_TYPE a=0; a<length; ++a )
706  {
707  sizeOfUnpackedChars += Unpack( buffer, var[ indices[a] ] );
708  }
709 
710  return sizeOfUnpackedChars;
711 }
712 
713 #ifdef GEOS_USE_ARRAY_BOUNDS_CHECK
714 
715 template< bool DO_PACKING, typename T, typename INDEX_TYPE >
716 typename std::enable_if< !std::is_trivial< T >::value, localIndex >::type
717 Pack( buffer_unit_type * & buffer,
718  arraySlice1d< T > const & var,
719  INDEX_TYPE const length )
720 {
721  localIndex sizeOfPackedChars = Pack< DO_PACKING >( buffer, length );
722 
723  for( INDEX_TYPE a=0; a<length; ++a )
724  {
725  sizeOfPackedChars += Pack< DO_PACKING >( buffer, var[ a ] );
726  }
727 
728  return sizeOfPackedChars;
729 }
730 
731 template< typename T, typename INDEX_TYPE >
732 typename std::enable_if< std::is_trivial< T >::value, localIndex >::type
733 Unpack( buffer_unit_type const * & buffer,
734  arraySlice1d< T > & var,
735  INDEX_TYPE const expectedLength )
736 {
737  INDEX_TYPE length;
738  localIndex sizeOfUnpackedChars = Unpack( buffer, length );
739  GEOS_DEBUG_VAR( expectedLength );
740  GEOS_ASSERT_EQ( length, expectedLength );
741 
742  T const * const GEOS_RESTRICT buffer_T = reinterpret_cast< T const * >( buffer );
743  for( INDEX_TYPE i = 0; i < length; ++i )
744  {
745  var[ i ] = buffer_T[ i ];
746  }
747 
748  buffer += length * sizeof(T);
749  sizeOfUnpackedChars += length * sizeof(T);
750 
751  return sizeOfUnpackedChars;
752 }
753 
754 template< typename T, typename INDEX_TYPE >
755 typename std::enable_if< !std::is_trivial< T >::value, localIndex >::type
756 Unpack( buffer_unit_type const * & buffer,
757  arraySlice1d< T > & var,
758  INDEX_TYPE const expectedLength )
759 {
760  INDEX_TYPE length;
761  localIndex sizeOfUnpackedChars = Unpack( buffer, length );
762  GEOS_DEBUG_VAR( expectedLength );
763  GEOS_ASSERT_EQ( length, expectedLength );
764 
765  for( INDEX_TYPE a=0; a<length; ++a )
766  {
767  sizeOfUnpackedChars += Unpack( buffer, var[a] );
768  }
769 
770  return sizeOfUnpackedChars;
771 }
772 
773 
774 template< bool DO_PACKING, typename T, typename INDEX_TYPE >
776 Pack( buffer_unit_type * & buffer,
777  arraySlice1d< T > const & var,
778  arraySlice1d< INDEX_TYPE > const & indices,
779  INDEX_TYPE const length )
780 {
781  localIndex sizeOfPackedChars = Pack< DO_PACKING >( buffer, length );
782 
783  for( INDEX_TYPE a=0; a<length; ++a )
784  {
785  sizeOfPackedChars += Pack< DO_PACKING >( buffer, var[ indices[a] ] );
786  }
787 
788  return sizeOfPackedChars;
789 }
790 
791 
792 template< typename T, typename INDEX_TYPE >
793 
795 Unpack( buffer_unit_type const * & buffer,
796  arraySlice1d< T > & var,
797  arraySlice1d< INDEX_TYPE > const & indices,
798  INDEX_TYPE & length )
799 {
800  localIndex sizeOfUnpackedChars = 0;
801 
802  sizeOfUnpackedChars += Unpack( buffer, length );
803 
804  for( INDEX_TYPE a=0; a<length; ++a )
805  {
806  sizeOfUnpackedChars += Unpack( buffer, var[ indices[a] ] );
807  }
808 
809  return sizeOfUnpackedChars;
810 }
811 
812 #endif /* GEOS_USE_ARRAY_BOUNDS_CHECK */
813 
814 template< bool DO_PACKING, int USD >
815 localIndex Pack( buffer_unit_type * & buffer,
816  SortedArray< localIndex > const & var,
817  SortedArray< globalIndex > const & unmappedGlobalIndices,
818  arraySlice1d< globalIndex const, USD > const & localToGlobal )
819 {
820  const localIndex length = LvArray::integerConversion< localIndex >( var.size()+unmappedGlobalIndices.size());
821  localIndex sizeOfPackedChars = Pack< DO_PACKING >( buffer, length );
822 
823  for( localIndex const lid : var )
824  {
825  sizeOfPackedChars += Pack< DO_PACKING >( buffer, localToGlobal[ lid ] );
826  }
827 
828  for( globalIndex const gid : unmappedGlobalIndices )
829  {
830  sizeOfPackedChars += Pack< DO_PACKING >( buffer, gid );
831  }
832 
833 
834  return sizeOfPackedChars;
835 }
836 
837 template< typename SORTED >
838 inline
839 localIndex Unpack( buffer_unit_type const * & buffer,
840  SortedArray< localIndex > & var,
841  SortedArray< globalIndex > & unmappedGlobalIndices,
842  mapBase< globalIndex, localIndex, SORTED > const & globalToLocalMap,
843  bool const clearExistingSet )
844 {
845  if( clearExistingSet )
846  {
847  var.clear();
848  }
849  localIndex set_length;
850  localIndex sizeOfUnpackedChars = Unpack( buffer, set_length );
851 
852  for( localIndex a=0; a<set_length; ++a )
853  {
854  globalIndex temp;
855  sizeOfUnpackedChars += Unpack( buffer, temp );
856  typename mapBase< globalIndex, localIndex, SORTED >::const_iterator iter = globalToLocalMap.find( temp );
857  if( iter==globalToLocalMap.end() )
858  {
859  unmappedGlobalIndices.insert( temp );
860  }
861  else
862  {
863  var.insert( iter->second );
864  }
865  }
866 
867  return sizeOfUnpackedChars;
868 }
869 
870 template< bool DO_PACKING >
871 localIndex Pack( buffer_unit_type * & buffer,
872  SortedArrayView< localIndex const > const & var,
873  arrayView1d< localIndex const > const & packList,
874  arraySlice1d< globalIndex const > const & localToGlobal )
875 {
876  localIndex length = 0;
877  for( auto a : packList )
878  {
879  length += var.count( a );
880  }
881 
882  localIndex sizeOfPackedChars = Pack< DO_PACKING >( buffer, length );
883 
884  for( localIndex a=0; a< packList.size(); ++a )
885  {
886  if( var.count( packList[ a ] ) )
887  {
888  sizeOfPackedChars += Pack< DO_PACKING >( buffer, localToGlobal[packList[a]] );
889  }
890  }
891 
892  return sizeOfPackedChars;
893 }
894 
895 template< bool DO_PACKING >
896 localIndex Pack( buffer_unit_type * & buffer,
897  SortedArrayView< localIndex const > const & var,
898  arrayView1d< localIndex const > const & packList,
899  SortedArrayView< globalIndex const > const & unmappedGlobalIndices,
900  arraySlice1d< globalIndex const > const & localToGlobal )
901 {
902 
903  localIndex length = 0;
904  array1d< localIndex > temp( var.size() );
905 
906  for( auto a : packList )
907  {
908  if( var.count( a ) )
909  {
910  temp[length] = a;
911  ++length;
912  }
913  }
914  temp.resize( length );
915  localIndex sizeOfPackedChars = Pack< DO_PACKING >( buffer, length );
916 
917 
918  for( localIndex a=0; a<length; ++a )
919  {
920  sizeOfPackedChars += Pack< DO_PACKING >( buffer, localToGlobal[temp[a]] );
921  }
922 
923  for( globalIndex const gid : unmappedGlobalIndices )
924  {
925  sizeOfPackedChars += Pack< DO_PACKING >( buffer, gid );
926  }
927 
928  return sizeOfPackedChars;
929 }
930 
931 template< bool DO_PACKING, typename T, typename T_indices >
933 Pack( buffer_unit_type * & buffer,
934  ArrayOfArrays< T > const & var,
935  T_indices const & indices )
936 {
937  localIndex sizeOfPackedChars = 0;
938 
939  sizeOfPackedChars += Pack< DO_PACKING >( buffer, indices.size() );
940  for( localIndex a=0; a<indices.size(); ++a )
941  {
942  sizeOfPackedChars += Pack< DO_PACKING >( buffer, var.sizeOfArray( indices[a] ) );
943  T const * const data = var[indices[a]];
944  sizeOfPackedChars += Pack< DO_PACKING >( buffer, data, var.sizeOfArray( indices[a] ) );
945  }
946  return sizeOfPackedChars;
947 }
948 
949 
950 template< typename T, typename T_indices >
952 Unpack( buffer_unit_type const * & buffer,
953  ArrayOfArrays< T > & var,
954  T_indices const & indices )
955 {
956  localIndex sizeOfUnpackedChars = 0;
957  localIndex numUnpackedIndices;
958  sizeOfUnpackedChars += Unpack( buffer, numUnpackedIndices );
959 
960  GEOS_ERROR_IF( numUnpackedIndices!=indices.size(), "number of unpacked indices does not equal expected number" );
961 
962  for( localIndex a=0; a<indices.size(); ++a )
963  {
964  localIndex sizeOfSubArray;
965  sizeOfUnpackedChars += Unpack( buffer, sizeOfSubArray );
966  var.resizeArray( indices[a], sizeOfSubArray );
967  sizeOfUnpackedChars += Unpack( buffer, var[indices[a]], sizeOfSubArray );
968  }
969 
970 
971  return sizeOfUnpackedChars;
972 }
973 
974 template< bool DO_PACKING, int USD >
975 localIndex Pack( buffer_unit_type * & buffer,
976  arraySlice1d< localIndex const, USD > const & var,
977  globalIndex const * const unmappedGlobalIndices,
978  localIndex const length,
979  arraySlice1d< globalIndex const > const & localToGlobalMap )
980 {
981  localIndex sizeOfPackedChars = Pack< DO_PACKING >( buffer, length );
982  sizeOfPackedChars += length*sizeof(globalIndex);
983 
984  if( DO_PACKING )
985  {
986  globalIndex * const buffer_GI = reinterpret_cast< globalIndex * >(buffer);
987  for( localIndex a=0; a<length; ++a )
988  {
989  if( var[a] != unmappedLocalIndexValue )
990  {
991  buffer_GI[a] = localToGlobalMap[var[a]];
992  }
993  else
994  {
995  buffer_GI[a] = unmappedGlobalIndices[a];
996  }
997  }
998 
999  buffer += length * sizeof(globalIndex);
1000  }
1001 
1002  return sizeOfPackedChars;
1003 }
1004 
1005 template< typename SORTED >
1006 inline
1007 localIndex
1008 Unpack( buffer_unit_type const * & buffer,
1009  localIndex_array & var,
1010  array1d< globalIndex > & unmappedGlobalIndices,
1011  mapBase< globalIndex, localIndex, SORTED > const & globalToLocalMap )
1012 {
1013  localIndex length;
1014  localIndex sizeOfUnpackedChars = Unpack( buffer, length );
1015  var.resize( length );
1016  unmappedGlobalIndices.resize( length );
1017  unmappedGlobalIndices.setValues< serialPolicy >( unmappedLocalIndexValue );
1018 
1019  bool unpackedGlobalFlag = false;
1020  for( localIndex a=0; a<length; ++a )
1021  {
1022  globalIndex unpackedGlobalIndex;
1023  sizeOfUnpackedChars += Unpack( buffer, unpackedGlobalIndex );
1024 
1025  typename mapBase< globalIndex, localIndex, SORTED >::const_iterator
1026  iter = globalToLocalMap.find( unpackedGlobalIndex );
1027  if( iter == globalToLocalMap.end() )
1028  {
1029  var[a] = unmappedLocalIndexValue;
1030  unmappedGlobalIndices[a] = unpackedGlobalIndex;
1031  unpackedGlobalFlag = true;
1032  }
1033  else
1034  {
1035  var[a] = iter->second;
1036  }
1037  }
1038  if( !unpackedGlobalFlag )
1039  {
1040  unmappedGlobalIndices.clear();
1041  }
1042 
1043  return sizeOfUnpackedChars;
1044 }
1045 
1046 inline
1047 localIndex
1048 UnpackSyncList( buffer_unit_type const * & buffer,
1049  localIndex_array & var,
1050  std::unordered_map< globalIndex, localIndex > const & globalToLocalMap )
1051 {
1052  localIndex length;
1053  localIndex sizeOfUnpackedChars = Unpack( buffer, length );
1054  var.resize( length );
1055 
1056  for( localIndex a=0; a<length; ++a )
1057  {
1058  globalIndex unpackedGlobalIndex;
1059  sizeOfUnpackedChars += Unpack( buffer, unpackedGlobalIndex );
1060  var[a] = globalToLocalMap.at( unpackedGlobalIndex );
1061  }
1062 
1063  return sizeOfUnpackedChars;
1064 }
1065 
1066 template< typename SORTED >
1067 inline
1068 localIndex
1069 Unpack( buffer_unit_type const * & buffer,
1070  ArrayOfArrays< localIndex > & var,
1071  localIndex const subArrayIndex,
1072  array1d< globalIndex > & unmappedGlobalIndices,
1073  mapBase< globalIndex, localIndex, SORTED > const & globalToLocalMap )
1074 {
1075  localIndex length;
1076  localIndex sizeOfUnpackedChars = Unpack( buffer, length );
1077 
1078  var.resizeArray( subArrayIndex, length );
1079  unmappedGlobalIndices.resize( length );
1080  unmappedGlobalIndices.setValues< serialPolicy >( unmappedLocalIndexValue );
1081 
1082  bool unpackedGlobalFlag = false;
1083  for( localIndex a=0; a<length; ++a )
1084  {
1085  globalIndex unpackedGlobalIndex;
1086  sizeOfUnpackedChars += Unpack( buffer, unpackedGlobalIndex );
1087 
1088  typename mapBase< globalIndex, localIndex, SORTED >::const_iterator
1089  iter = globalToLocalMap.find( unpackedGlobalIndex );
1090  if( iter == globalToLocalMap.end() )
1091  {
1092  var( subArrayIndex, a ) = unmappedLocalIndexValue;
1093  unmappedGlobalIndices[a] = unpackedGlobalIndex;
1094  unpackedGlobalFlag = true;
1095  }
1096  else
1097  {
1098  var( subArrayIndex, a ) = iter->second;
1099  }
1100  }
1101  if( !unpackedGlobalFlag )
1102  {
1103  unmappedGlobalIndices.clear();
1104  }
1105 
1106  return sizeOfUnpackedChars;
1107 }
1108 
1109 template< typename SORTED, int USD >
1110 inline
1111 localIndex
1112 Unpack( buffer_unit_type const * & buffer,
1113  arraySlice1d< localIndex, USD > & var,
1114  array1d< globalIndex > & unmappedGlobalIndices,
1115  localIndex const expectedLength,
1116  mapBase< globalIndex, localIndex, SORTED > const & globalToLocalMap )
1117 {
1118  localIndex sizeOfUnpackedChars = 0;
1119 
1120  localIndex length;
1121  sizeOfUnpackedChars += Unpack( buffer, length );
1122 
1123  GEOS_ASSERT_EQ( length, expectedLength );
1124  GEOS_DEBUG_VAR( expectedLength );
1125 
1126  unmappedGlobalIndices.resize( length );
1127  unmappedGlobalIndices.setValues< serialPolicy >( unmappedLocalIndexValue );
1128 
1129  bool unpackedGlobalFlag = false;
1130  for( localIndex a=0; a<length; ++a )
1131  {
1132  globalIndex unpackedGlobalIndex;
1133  sizeOfUnpackedChars += Unpack( buffer, unpackedGlobalIndex );
1134 
1135  typename mapBase< globalIndex, localIndex, SORTED >::const_iterator
1136  iter = globalToLocalMap.find( unpackedGlobalIndex );
1137  if( iter == globalToLocalMap.end() )
1138  {
1139  var[a] = unmappedLocalIndexValue;
1140  unmappedGlobalIndices[a] = unpackedGlobalIndex;
1141  unpackedGlobalFlag = true;
1142  }
1143  else
1144  {
1145  var[a] = iter->second;
1146  }
1147  }
1148  if( !unpackedGlobalFlag )
1149  {
1150  unmappedGlobalIndices.clear();
1151  }
1152 
1153  return sizeOfUnpackedChars;
1154 }
1155 
1156 
1157 template< bool DO_PACKING >
1158 localIndex
1159 Pack( buffer_unit_type * & buffer,
1160  arrayView1d< localIndex const > const & var,
1161  arrayView1d< localIndex const > const & indices,
1162  arrayView1d< globalIndex const > const & localToGlobalMap,
1163  arrayView1d< globalIndex const > const & relatedObjectLocalToGlobalMap )
1164 {
1165  localIndex sizeOfPackedChars=0;
1166 
1167  sizeOfPackedChars += Pack< DO_PACKING >( buffer, indices.size() );
1168  for( localIndex a=0; a<indices.size(); ++a )
1169  {
1170  localIndex const li = indices[a];
1171  sizeOfPackedChars += Pack< DO_PACKING >( buffer, localToGlobalMap[li] );
1172  if( var[li] != -1 )
1173  {
1174  sizeOfPackedChars += Pack< DO_PACKING >( buffer,
1175  relatedObjectLocalToGlobalMap[var[li]] );
1176  }
1177  else
1178  {
1179  sizeOfPackedChars += Pack< DO_PACKING >( buffer,
1180  globalIndex( -1 ) );
1181  }
1182  }
1183 
1184  return sizeOfPackedChars;
1185 }
1186 
1187 template< bool DO_PACKING >
1188 localIndex
1189 Pack( buffer_unit_type * & buffer,
1190  ArrayOfArraysView< array1d< globalIndex > const > const & var,
1191  arrayView1d< localIndex const > const & indices,
1192  arrayView1d< globalIndex const > const & localToGlobalMap )
1193 {
1194  localIndex sizeOfPackedChars = 0;
1195 
1196  sizeOfPackedChars += bufferOps::Pack< DO_PACKING >( buffer, indices.size() );
1197  for( localIndex a = 0; a < indices.size(); ++a )
1198  {
1199  localIndex const li = indices[a];
1200  sizeOfPackedChars += bufferOps::Pack< DO_PACKING >( buffer, localToGlobalMap[li] );
1201 
1202  sizeOfPackedChars += bufferOps::PackArray< DO_PACKING >( buffer,
1203  var[li],
1204  var.sizeOfArray( li ) );
1205  }
1206 
1207  return sizeOfPackedChars;
1208 }
1209 
1210 template< typename SORTED0, typename SORTED1 >
1211 inline
1212 localIndex
1213 Unpack( buffer_unit_type const * & buffer,
1214  arrayView1d< localIndex > const & var,
1215  array1d< localIndex > const & indices,
1216  mapBase< globalIndex, localIndex, SORTED0 > const & globalToLocalMap,
1217  mapBase< globalIndex, localIndex, SORTED1 > const & relatedObjectGlobalToLocalMap )
1218 {
1219  localIndex numIndicesUnpacked;
1220  localIndex const sizeOfIndicesPassedIn = indices.size();
1221 
1222  localIndex sizeOfUnpackedChars = Unpack( buffer, numIndicesUnpacked );
1223 
1224  GEOS_ERROR_IF( sizeOfIndicesPassedIn!=0 && numIndicesUnpacked!=indices.size(),
1225  "number of unpacked indices("<<numIndicesUnpacked<<") does not equal size of "
1226  "indices passed into Unpack function("<<sizeOfIndicesPassedIn );
1227 
1228  for( localIndex a=0; a<indices.size(); ++a )
1229  {
1230  globalIndex gi;
1231  sizeOfUnpackedChars += Unpack( buffer, gi );
1232  localIndex & li = indices[a];
1233  if( sizeOfIndicesPassedIn > 0 )
1234  {
1235  GEOS_ERROR_IF( li!=globalToLocalMap.at( gi ),
1236  "global index "<<gi<<" unpacked from buffer does not equal the lookup "
1237  <<li<<" for localIndex "<<li<<" on this rank" );
1238  }
1239  else
1240  {
1241  li = globalToLocalMap.at( gi );
1242  }
1243 
1244  globalIndex mappedGlobalIndex;
1245  sizeOfUnpackedChars += Unpack( buffer, mappedGlobalIndex );
1246  if( mappedGlobalIndex != -1 )
1247  {
1248  var[li] = relatedObjectGlobalToLocalMap.at( mappedGlobalIndex );
1249  }
1250  else
1251  {
1252  var[li] = -1;
1253  }
1254 
1255  }
1256  return sizeOfUnpackedChars;
1257 }
1258 
1259 template< bool DO_PACKING, typename SORTED >
1260 localIndex
1261 Pack( buffer_unit_type * & buffer,
1262  arrayView1d< arrayView1d< localIndex const > const > const & var,
1263  mapBase< localIndex, array1d< globalIndex >, SORTED > const & unmappedGlobalIndices,
1264  arrayView1d< localIndex const > const & indices,
1265  arrayView1d< globalIndex const > const & localToGlobalMap,
1266  arrayView1d< globalIndex const > const & relatedObjectLocalToGlobalMap )
1267 {
1268  localIndex sizeOfPackedChars=0;
1269 
1270  sizeOfPackedChars += Pack< DO_PACKING >( buffer, indices.size() );
1271  for( localIndex a=0; a<indices.size(); ++a )
1272  {
1273  localIndex const li = indices[a];
1274  sizeOfPackedChars += Pack< DO_PACKING >( buffer, localToGlobalMap[li] );
1275 
1276  typename mapBase< localIndex, array1d< globalIndex >, SORTED >::const_iterator
1277  iterUnmappedGI = unmappedGlobalIndices.find( li );
1278 
1279  array1d< globalIndex > junk;
1280  array1d< globalIndex > const & unmappedGI = iterUnmappedGI==unmappedGlobalIndices.end() ?
1281  junk :
1282  iterUnmappedGI->second;
1283 
1284  sizeOfPackedChars += Pack< DO_PACKING >( buffer,
1285  var[li].toSliceConst(),
1286  unmappedGI.data(),
1287  var[li].size(),
1288  relatedObjectLocalToGlobalMap );
1289  }
1290 
1291  return sizeOfPackedChars;
1292 }
1293 
1294 template< typename SORTED0, typename SORTED1, typename SORTED2 >
1295 inline
1296 localIndex
1297 Unpack( buffer_unit_type const * & buffer,
1298  arrayView1d< localIndex_array > & var,
1299  array1d< localIndex > & indices,
1300  mapBase< localIndex, array1d< globalIndex >, SORTED0 > & unmappedGlobalIndices,
1301  mapBase< globalIndex, localIndex, SORTED1 > const & globalToLocalMap,
1302  mapBase< globalIndex, localIndex, SORTED2 > const & relatedObjectGlobalToLocalMap )
1303 {
1304  localIndex numIndicesUnpacked;
1305  localIndex const sizeOfIndicesPassedIn = indices.size();
1306 
1307  localIndex sizeOfUnpackedChars = Unpack( buffer, numIndicesUnpacked );
1308 
1309  GEOS_ERROR_IF( sizeOfIndicesPassedIn!=0 && numIndicesUnpacked!=indices.size(),
1310  "number of unpacked indices("<<numIndicesUnpacked<<") does not equal size of "
1311  "indices passed into Unpack function("<<sizeOfIndicesPassedIn );
1312 
1313  indices.resize( numIndicesUnpacked );
1314 
1315  for( localIndex a=0; a<indices.size(); ++a )
1316  {
1317  globalIndex gi;
1318  sizeOfUnpackedChars += Unpack( buffer, gi );
1319 
1320  localIndex & li = indices[a];
1321  if( sizeOfIndicesPassedIn > 0 )
1322  {
1323  GEOS_ERROR_IF( li!=globalToLocalMap.at( gi ),
1324  "global index "<<gi<<" unpacked from buffer does not equal the lookup "
1325  <<li<<" for localIndex "<<li<<" on this rank" );
1326  }
1327  else
1328  {
1329  li = globalToLocalMap.at( gi );
1330  }
1331 
1332  array1d< globalIndex > unmappedIndices;
1333  sizeOfUnpackedChars += Unpack( buffer,
1334  var[li],
1335  unmappedIndices,
1336  relatedObjectGlobalToLocalMap );
1337 
1338  if( unmappedIndices.size() > 0 )
1339  {
1340  unmappedGlobalIndices[li] = unmappedIndices;
1341  }
1342  }
1343  return sizeOfUnpackedChars;
1344 }
1345 
1346 template< bool DO_PACKING, typename SORTED >
1347 localIndex
1348 Pack( buffer_unit_type * & buffer,
1349  ArrayOfArraysView< localIndex const > const & var,
1350  mapBase< localIndex, array1d< globalIndex >, SORTED > const & unmappedGlobalIndices,
1351  arrayView1d< localIndex const > const & indices,
1352  arrayView1d< globalIndex const > const & localToGlobalMap,
1353  arrayView1d< globalIndex const > const & relatedObjectLocalToGlobalMap )
1354 {
1355  localIndex sizeOfPackedChars=0;
1356  array1d< globalIndex > junk;
1357 
1358  sizeOfPackedChars += Pack< DO_PACKING >( buffer, indices.size() );
1359  for( localIndex a=0; a<indices.size(); ++a )
1360  {
1361  localIndex const li = indices[a];
1362  sizeOfPackedChars += Pack< DO_PACKING >( buffer, localToGlobalMap[li] );
1363 
1364  typename mapBase< localIndex, array1d< globalIndex >, SORTED >::const_iterator
1365  iterUnmappedGI = unmappedGlobalIndices.find( li );
1366 
1367  array1d< globalIndex > const & unmappedGI = iterUnmappedGI==unmappedGlobalIndices.end() ?
1368  junk :
1369  iterUnmappedGI->second;
1370 
1371  sizeOfPackedChars += Pack< DO_PACKING >( buffer,
1372  var[li],
1373  unmappedGI.data(),
1374  var.sizeOfArray( li ),
1375  relatedObjectLocalToGlobalMap );
1376  }
1377 
1378  return sizeOfPackedChars;
1379 }
1380 
1381 template< bool DO_PACKING, typename SORTED >
1382 localIndex
1383 Pack( buffer_unit_type * & buffer,
1384  ArrayOfArraysView< localIndex const > const & var,
1385  mapBase< localIndex, SortedArray< globalIndex >, SORTED > const & unmappedGlobalIndices,
1386  arrayView1d< localIndex const > const & indices,
1387  arrayView1d< globalIndex const > const & localToGlobalMap,
1388  arrayView1d< globalIndex const > const & relatedObjectLocalToGlobalMap )
1389 {
1390  localIndex sizeOfPackedChars=0;
1391  SortedArray< globalIndex > junk;
1392 
1393  sizeOfPackedChars += Pack< DO_PACKING >( buffer, indices.size() );
1394  for( localIndex a=0; a<indices.size(); ++a )
1395  {
1396  localIndex const li = indices[a];
1397  sizeOfPackedChars += Pack< DO_PACKING >( buffer, localToGlobalMap[li] );
1398 
1399  typename mapBase< localIndex, SortedArray< globalIndex >, SORTED >::const_iterator
1400  iterUnmappedGI = unmappedGlobalIndices.find( li );
1401 
1402  SortedArray< globalIndex > const & unmappedGI = iterUnmappedGI==unmappedGlobalIndices.end() ?
1403  junk :
1404  iterUnmappedGI->second;
1405 
1406  sizeOfPackedChars += Pack< DO_PACKING >( buffer,
1407  var[li],
1408  unmappedGI.data(),
1409  var.sizeOfArray( li ),
1410  relatedObjectLocalToGlobalMap );
1411  }
1412 
1413  return sizeOfPackedChars;
1414 }
1415 
1416 template< typename SORTED0, typename SORTED1, typename SORTED2 >
1417 inline
1418 localIndex
1419 Unpack( buffer_unit_type const * & buffer,
1420  ArrayOfArrays< localIndex > & var,
1421  array1d< localIndex > & indices,
1422  mapBase< localIndex, array1d< globalIndex >, SORTED0 > & unmappedGlobalIndices,
1423  mapBase< globalIndex, localIndex, SORTED1 > const & globalToLocalMap,
1424  mapBase< globalIndex, localIndex, SORTED2 > const & relatedObjectGlobalToLocalMap )
1425 {
1426  localIndex numIndicesUnpacked;
1427  localIndex const sizeOfIndicesPassedIn = indices.size();
1428 
1429  localIndex sizeOfUnpackedChars = Unpack( buffer, numIndicesUnpacked );
1430 
1431  GEOS_ERROR_IF( sizeOfIndicesPassedIn!=0 && numIndicesUnpacked!=indices.size(),
1432  "number of unpacked indices("<<numIndicesUnpacked<<") does not equal size of "
1433  "indices passed into Unpack function("<<sizeOfIndicesPassedIn );
1434 
1435  indices.resize( numIndicesUnpacked );
1436  array1d< globalIndex > unmappedIndices;
1437 
1438  for( localIndex a=0; a<indices.size(); ++a )
1439  {
1440  globalIndex gi;
1441  sizeOfUnpackedChars += Unpack( buffer, gi );
1442 
1443  localIndex & li = indices[a];
1444  if( sizeOfIndicesPassedIn > 0 )
1445  {
1446  GEOS_ERROR_IF( li!=globalToLocalMap.at( gi ),
1447  "global index "<<gi<<" unpacked from buffer does not equal the lookup "
1448  <<li<<" for localIndex "<<li<<" on this rank" );
1449  }
1450  else
1451  {
1452  li = globalToLocalMap.at( gi );
1453  }
1454 
1455  unmappedIndices.resize( 0 );
1456  sizeOfUnpackedChars += Unpack( buffer,
1457  var,
1458  li,
1459  unmappedIndices,
1460  relatedObjectGlobalToLocalMap );
1461 
1462  if( unmappedIndices.size() > 0 )
1463  {
1464  unmappedGlobalIndices[li] = unmappedIndices;
1465  }
1466  }
1467  return sizeOfUnpackedChars;
1468 }
1469 
1470 template< typename SORTED0 >
1471 inline
1472 localIndex
1473 Unpack( buffer_unit_type const * & buffer,
1474  ArrayOfArrays< array1d< globalIndex > > & var,
1475  array1d< localIndex > & indices,
1476  mapBase< globalIndex, localIndex, SORTED0 > const & globalToLocalMap )
1477 {
1478  localIndex numIndicesUnpacked;
1479  localIndex const sizeOfIndicesPassedIn = indices.size();
1480 
1481  localIndex sizeOfUnpackedChars = bufferOps::Unpack( buffer, numIndicesUnpacked );
1482 
1483  GEOS_ERROR_IF( sizeOfIndicesPassedIn != 0 && numIndicesUnpacked != indices.size(),
1484  "number of unpacked indices(" << numIndicesUnpacked << ") does not equal size of "
1485  "indices passed into Unpack function(" << sizeOfIndicesPassedIn );
1486 
1487  indices.resize( numIndicesUnpacked );
1488  array1d< globalIndex > unmappedIndices;
1489 
1490  for( localIndex a=0; a<indices.size(); ++a )
1491  {
1492  globalIndex gi;
1493  sizeOfUnpackedChars += bufferOps::Unpack( buffer, gi );
1494 
1495  localIndex & li = indices[a];
1496  if( sizeOfIndicesPassedIn > 0 )
1497  {
1498  GEOS_ERROR_IF( li != globalToLocalMap.at( gi ),
1499  "global index " << gi << " unpacked from buffer does not equal the lookup "
1500  << li << " for localIndex " << li << " on this rank" );
1501  }
1502  else
1503  {
1504  li = globalToLocalMap.at( gi );
1505  }
1506 
1507  unmappedIndices.resize( 0 );
1508  sizeOfUnpackedChars += Unpack( buffer,
1509  var,
1510  li );
1511  }
1512  return sizeOfUnpackedChars;
1513 }
1514 
1515 
1516 template< bool DO_PACKING, typename SORTED >
1517 localIndex
1518 Pack( buffer_unit_type * & buffer,
1519  arrayView1d< SortedArray< localIndex > const > const & var,
1520  mapBase< localIndex, SortedArray< globalIndex >, SORTED > const & unmappedGlobalIndices,
1521  arrayView1d< localIndex const > const & indices,
1522  arrayView1d< globalIndex const > const & localToGlobalMap,
1523  arrayView1d< globalIndex const > const & relatedObjectLocalToGlobalMap )
1524 {
1525  localIndex sizeOfPackedChars = Pack< DO_PACKING >( buffer, indices.size() );
1526 
1527  for( localIndex a=0; a<indices.size(); ++a )
1528  {
1529  localIndex li = indices[a];
1530  sizeOfPackedChars += Pack< DO_PACKING >( buffer, localToGlobalMap[li] );
1531 
1532  typename mapBase< localIndex, SortedArray< globalIndex >, SORTED >::const_iterator
1533  iterUnmappedGI = unmappedGlobalIndices.find( li );
1534 
1535  SortedArray< globalIndex > junk;
1536  SortedArray< globalIndex > const & unmappedGI = iterUnmappedGI==unmappedGlobalIndices.end() ?
1537  junk :
1538  iterUnmappedGI->second;
1539 
1540  sizeOfPackedChars += Pack< DO_PACKING >( buffer,
1541  var[li],
1542  unmappedGI,
1543  relatedObjectLocalToGlobalMap );
1544  }
1545 
1546  return sizeOfPackedChars;
1547 }
1548 
1549 
1550 template< typename SORTED0, typename SORTED1, typename SORTED2 >
1551 inline
1552 localIndex
1553 Unpack( buffer_unit_type const * & buffer,
1554  arrayView1d< SortedArray< localIndex > > & var,
1555  localIndex_array & indices,
1556  mapBase< localIndex, SortedArray< globalIndex >, SORTED0 > & unmappedGlobalIndices,
1557  mapBase< globalIndex, localIndex, SORTED1 > const & globalToLocalMap,
1558  mapBase< globalIndex, localIndex, SORTED2 > const & relatedObjectGlobalToLocalMap,
1559  bool const clearFlag )
1560 {
1561  localIndex sizeOfUnpackedChars=0;
1562  localIndex const sizeOfIndicesPassedIn = indices.size();
1563 
1564  localIndex numIndicesUnpacked;
1565  sizeOfUnpackedChars += Unpack( buffer, numIndicesUnpacked );
1566  GEOS_ERROR_IF( sizeOfIndicesPassedIn!=0 && numIndicesUnpacked!=indices.size(),
1567  "number of unpacked indices("<<numIndicesUnpacked<<") does not equal size of "
1568  "indices passed into Unpack function("<<sizeOfIndicesPassedIn );
1569 
1570  indices.resize( numIndicesUnpacked );
1571 
1572  for( localIndex a=0; a<numIndicesUnpacked; ++a )
1573  {
1574 
1575  globalIndex gi;
1576  sizeOfUnpackedChars += Unpack( buffer, gi );
1577 
1578  localIndex & li = indices[a];
1579  if( sizeOfIndicesPassedIn > 0 )
1580  {
1581  GEOS_ERROR_IF( li!=globalToLocalMap.at( gi ),
1582  "global index "<<gi<<" unpacked from buffer does equal the lookup "
1583  <<li<<" for localIndex "<<li<<" on this rank" );
1584  }
1585  else
1586  {
1587  li = globalToLocalMap.at( gi );
1588  }
1589 
1590  SortedArray< globalIndex > unmappedIndices;
1591  sizeOfUnpackedChars += Unpack( buffer,
1592  var[li],
1593  unmappedIndices,
1594  relatedObjectGlobalToLocalMap,
1595  clearFlag );
1596 
1597  if( unmappedIndices.size() > 0 )
1598  {
1599  unmappedGlobalIndices[li].insert( unmappedIndices.data(), unmappedIndices.size() );
1600  }
1601  }
1602  return sizeOfUnpackedChars;
1603 }
1604 
1605 template< typename SORTED0, typename SORTED1, typename SORTED2 >
1606 inline
1607 localIndex
1608 Unpack( buffer_unit_type const * & buffer,
1609  ArrayOfSets< localIndex > & var,
1610  localIndex_array & indices,
1611  mapBase< localIndex, SortedArray< globalIndex >, SORTED0 > & unmappedGlobalIndices,
1612  mapBase< globalIndex, localIndex, SORTED1 > const & globalToLocalMap,
1613  mapBase< globalIndex, localIndex, SORTED2 > const & relatedObjectGlobalToLocalMap,
1614  bool const clearFlag )
1615 {
1616  localIndex sizeOfUnpackedChars=0;
1617  localIndex const sizeOfIndicesPassedIn = indices.size();
1618 
1619  localIndex numIndicesUnpacked;
1620  sizeOfUnpackedChars += Unpack( buffer, numIndicesUnpacked );
1621  GEOS_ERROR_IF( sizeOfIndicesPassedIn!=0 && numIndicesUnpacked!=indices.size(),
1622  "number of unpacked indices("<<numIndicesUnpacked<<") does not equal size of "
1623  "indices passed into Unpack function("<<sizeOfIndicesPassedIn );
1624 
1625  indices.resize( numIndicesUnpacked );
1626 
1627  // for objects related to the above local index li (e.g. up/down mappings)
1628  // global indices not yet known on the local rank
1629  std::vector< globalIndex > unmapped;
1630 
1631  // local indices of known global indices
1632  std::vector< localIndex > mapped;
1633 
1634  // local indices of known objects not yet present in the map
1635  std::vector< localIndex > mappedNew;
1636 
1637  // storage for new values that don't fit into existing capacity
1638  array1d< localIndex > indiciesToInsert;
1639  ArrayOfSets< localIndex > valuesToInsert;
1640  indiciesToInsert.reserve( numIndicesUnpacked );
1641  valuesToInsert.reserve( numIndicesUnpacked );
1642  valuesToInsert.reserveValues( numIndicesUnpacked * 12 ); // guesstimate
1643 
1644  for( localIndex a=0; a<numIndicesUnpacked; ++a )
1645  {
1646  globalIndex gi;
1647  sizeOfUnpackedChars += Unpack( buffer, gi );
1648 
1649  localIndex & li = indices[a];
1650  if( sizeOfIndicesPassedIn > 0 )
1651  {
1652  GEOS_ERROR_IF( li!=globalToLocalMap.at( gi ),
1653  "global index "<<gi<<" unpacked from buffer does equal the lookup "
1654  <<li<<" for localIndex "<<li<<" on this rank" );
1655  }
1656  else
1657  {
1658  li = globalToLocalMap.at( gi );
1659  }
1660 
1661  if( clearFlag )
1662  {
1663  var.clearSet( li );
1664  }
1665 
1666  localIndex set_length;
1667  sizeOfUnpackedChars += Unpack( buffer, set_length );
1668 
1669  mapped.clear();
1670  mappedNew.clear();
1671  unmapped.clear();
1672 
1673  // again, the global indices being unpacked here are for
1674  // objects related to the global index recvd and
1675  // mapped to a local index above (e.g. up/down maps)
1676  for( localIndex b = 0; b < set_length; ++b )
1677  {
1678  globalIndex temp;
1679  sizeOfUnpackedChars += Unpack( buffer, temp );
1680  auto iter = relatedObjectGlobalToLocalMap.find( temp );
1681  // if we have no existing global-to-local information
1682  // for the recv'd global index
1683  if( iter == relatedObjectGlobalToLocalMap.end() )
1684  {
1685  unmapped.push_back( temp );
1686  }
1687  // if we have existing global-to-local information
1688  // use that mapping and store the local index
1689  else
1690  {
1691  mapped.push_back( iter->second );
1692  }
1693  }
1694 
1695  // insert known local indices into the set of indices related to the local index
1696  mapped.resize( LvArray::sortedArrayManipulation::makeSortedUnique( mapped.begin(), mapped.end() ) );
1697  std::set_difference( mapped.begin(), mapped.end(), var[li].begin(), var[li].end(), std::back_inserter( mappedNew ) );
1698  localIndex const numNewValues = LvArray::integerConversion< localIndex >( mappedNew.size() );
1699 
1700  // check if we have enough capacity to insert new indices
1701  if( numNewValues <= var.capacityOfSet( li ) - var.sizeOfSet( li ) )
1702  {
1703  // all good, just insert new entries
1704  var.insertIntoSet( li, mappedNew.begin(), mappedNew.end() );
1705  }
1706  else
1707  {
1708  // need to stash away and rebuild the map later
1709  localIndex const k = indiciesToInsert.size();
1710  indiciesToInsert.emplace_back( li );
1711  valuesToInsert.appendSet( numNewValues );
1712  valuesToInsert.insertIntoSet( k, mappedNew.begin(), mappedNew.end() );
1713  }
1714 
1715  // insert unknown global indices related to the local index into an additional mapping to resolve externally
1716  unmapped.resize( LvArray::sortedArrayManipulation::makeSortedUnique( unmapped.begin(), unmapped.end() ) );
1717  if( unmapped.size() > 0 )
1718  {
1719  unmappedGlobalIndices[li].insert( unmapped.begin(), unmapped.end() );
1720  }
1721  }
1722 
1723  // If there were element lists that didn't fit in the map, rebuild the whole thing
1724  if( !indiciesToInsert.empty() )
1725  {
1726  // Copy old capacities (no way to direct copy, must kernel launch)
1727  array1d< localIndex > newCapacities( var.size() );
1728  forAll< parallelHostPolicy >( var.size(), [var = var.toViewConst(), newCapacities = newCapacities.toView()]( localIndex const k )
1729  {
1730  newCapacities[k] = var.capacityOfSet( k );
1731  } );
1732 
1733  // Add new capacities where needed
1734  for( localIndex i = 0; i < indiciesToInsert.size(); ++i )
1735  {
1736  newCapacities[indiciesToInsert[i]] += valuesToInsert.sizeOfSet( i );
1737  }
1738 
1739  // Allocate new map
1740  ArrayOfSets< localIndex > newVar;
1741  newVar.resizeFromCapacities< parallelHostPolicy >( var.size(), newCapacities.data() );
1742 
1743  // Fill new map with old values
1744  forAll< parallelHostPolicy >( var.size(), [var = var.toViewConst(), newVar = newVar.toView()]( localIndex const k )
1745  {
1746  newVar.insertIntoSet( k, var[k].begin(), var[k].end() );
1747  } );
1748 
1749  // Insert new values
1750  for( localIndex i = 0; i < indiciesToInsert.size(); ++i )
1751  {
1752  localIndex const k = indiciesToInsert[i];
1753  newVar.insertIntoSet( k, valuesToInsert[i].begin(), valuesToInsert[i].end() );
1754  }
1755 
1756  // Replace the old map
1757  var = std::move( newVar );
1758  }
1759 
1760  return sizeOfUnpackedChars;
1761 }
1762 
1763 
1764 template< bool DO_PACKING, int USD0, int USD1 >
1765 localIndex
1766 Pack( buffer_unit_type * & buffer,
1767  arrayView2d< localIndex const, USD0 > const & var,
1768  arrayView1d< localIndex > const & indices,
1769  arraySlice1d< globalIndex const, USD1 > const & localToGlobalMap )
1770 {
1771  localIndex sizeOfPackedChars = Pack< DO_PACKING >( buffer, indices.size() );
1772  for( localIndex a=0; a<indices.size(); ++a )
1773  {
1774  localIndex li = indices[a];
1775  sizeOfPackedChars += Pack< DO_PACKING >( buffer, localToGlobalMap[li] );
1776 
1777  sizeOfPackedChars += PackArray< DO_PACKING >( buffer, var[li], var.size( 1 ) );
1778  }
1779 
1780  return sizeOfPackedChars;
1781 }
1782 
1783 template< typename SORTED, int USD >
1784 inline
1785 localIndex
1786 Unpack( buffer_unit_type const * & buffer,
1787  arrayView2d< localIndex, USD > const & var,
1788  array1d< localIndex > & indices,
1789  mapBase< globalIndex, localIndex, SORTED > const & globalToLocalMap )
1790 {
1791  localIndex sizeOfUnpackedChars = 0;
1792  localIndex const sizeOfIndicesPassedIn = indices.size();
1793 
1794  localIndex numIndicesUnpacked;
1795  sizeOfUnpackedChars += Unpack( buffer, numIndicesUnpacked );
1796 
1797  GEOS_ERROR_IF( sizeOfIndicesPassedIn!=0 && numIndicesUnpacked!=indices.size(),
1798  "number of unpacked indices("<<numIndicesUnpacked<<") does not equal size of "
1799  "indices passed into Unpack function("<<sizeOfIndicesPassedIn );
1800 
1801  indices.resize( numIndicesUnpacked );
1802 
1803  for( localIndex a=0; a<numIndicesUnpacked; ++a )
1804  {
1805  globalIndex gi;
1806  sizeOfUnpackedChars += Unpack( buffer, gi );
1807 
1808  localIndex & li = indices[a];
1809  if( sizeOfIndicesPassedIn > 0 )
1810  {
1811  GEOS_ERROR_IF( li!=globalToLocalMap.at( gi ),
1812  "global index "<<gi<<" unpacked from buffer does equal the lookup "
1813  <<li<<" for localIndex "<<li<<" on this rank" );
1814  }
1815  else
1816  {
1817  li = globalToLocalMap.at( gi );
1818  }
1819 
1820  localIndex * const varSlice = var[li];
1821  sizeOfUnpackedChars += UnpackPointer( buffer, varSlice, var.size( 1 ) );
1822  }
1823 
1824  return sizeOfUnpackedChars;
1825 }
1826 
1827 
1828 template< bool DO_PACKING, typename SORTED, int USD0 >
1829 localIndex
1830 Pack( buffer_unit_type * & buffer,
1831  arrayView2d< localIndex const, USD0 > const & var,
1832  mapBase< localIndex, array1d< globalIndex >, SORTED > const & unmappedGlobalIndices,
1833  arrayView1d< localIndex const > const & indices,
1834  arraySlice1d< globalIndex const > const & localToGlobalMap,
1835  arraySlice1d< globalIndex const > const & relatedObjectLocalToGlobalMap )
1836 {
1837  localIndex sizeOfPackedChars = 0;
1838  array1d< globalIndex > invalidGlobalIndices( var.size( 1 ) );
1839  for( localIndex a=0; a<var.size( 1 ); ++a )
1840  {
1841  invalidGlobalIndices[a] = -1;
1842  }
1843 
1844  sizeOfPackedChars += Pack< DO_PACKING >( buffer, indices.size() );
1845  for( localIndex a=0; a<indices.size(); ++a )
1846  {
1847  localIndex li = indices[a];
1848  sizeOfPackedChars += Pack< DO_PACKING >( buffer, localToGlobalMap[li] );
1849 
1850  typename mapBase< localIndex, array1d< globalIndex >, SORTED >::const_iterator
1851  iterUnmappedGI = unmappedGlobalIndices.find( li );
1852 
1853  array1d< globalIndex > const & unmappedGI = iterUnmappedGI==unmappedGlobalIndices.end() ?
1854  invalidGlobalIndices :
1855  iterUnmappedGI->second;
1856 
1857  sizeOfPackedChars += Pack< DO_PACKING >( buffer,
1858  var[li],
1859  unmappedGI.data(),
1860  var.size( 1 ),
1861  relatedObjectLocalToGlobalMap );
1862  }
1863 
1864  return sizeOfPackedChars;
1865 }
1866 
1867 
1868 template< typename SORTED0, typename SORTED1, typename SORTED2, int USD >
1869 inline
1870 localIndex
1871 Unpack( buffer_unit_type const * & buffer,
1872  arrayView2d< localIndex, USD > const & var,
1873  localIndex_array & indices,
1874  mapBase< localIndex, array1d< globalIndex >, SORTED0 > & unmappedGlobalIndices,
1875  mapBase< globalIndex, localIndex, SORTED1 > const & globalToLocalMap,
1876  mapBase< globalIndex, localIndex, SORTED2 > const & relatedObjectGlobalToLocalMap )
1877 {
1878  localIndex sizeOfUnpackedChars = 0;
1879  localIndex const sizeOfIndicesPassedIn = indices.size();
1880 
1881  localIndex numIndicesUnpacked;
1882  sizeOfUnpackedChars += Unpack( buffer, numIndicesUnpacked );
1883  GEOS_ERROR_IF( sizeOfIndicesPassedIn!=0 && numIndicesUnpacked!=indices.size(),
1884  "number of unpacked indices("<<numIndicesUnpacked<<") does not equal size of "
1885  "indices passed into Unpack function("<<sizeOfIndicesPassedIn );
1886 
1887  indices.resize( numIndicesUnpacked );
1888  array1d< globalIndex > unmappedIndices;
1889 
1890  for( localIndex a=0; a<numIndicesUnpacked; ++a )
1891  {
1892  globalIndex gi;
1893  sizeOfUnpackedChars += Unpack( buffer, gi );
1894 
1895  localIndex & li = indices[a];
1896  if( sizeOfIndicesPassedIn > 0 )
1897  {
1898  GEOS_ERROR_IF( li!=globalToLocalMap.at( gi ),
1899  "global index "<<gi<<" unpacked from buffer does equal the lookup "
1900  <<li<<" for localIndex "<<li<<" on this rank" );
1901  }
1902  else
1903  {
1904  li = globalToLocalMap.at( gi );
1905  }
1906 
1907  arraySlice1d< localIndex, USD - 1 > varSlice = var[li];
1908 
1909  unmappedIndices.resize( 0 );
1910  sizeOfUnpackedChars += Unpack( buffer,
1911  varSlice,
1912  unmappedIndices,
1913  var.size( 1 ),
1914  relatedObjectGlobalToLocalMap );
1915 
1916  if( unmappedIndices.size()>0 )
1917  {
1918  unmappedGlobalIndices[li] = unmappedIndices;
1919  }
1920 
1921  }
1922 
1923  return sizeOfUnpackedChars;
1924 }
1925 
1926 template< bool DO_PACKING, typename MAP_TYPE, typename T_INDICES >
1927 typename std::enable_if< is_map_packable_by_index< MAP_TYPE >, localIndex >::type
1928 Pack( buffer_unit_type * & buffer, MAP_TYPE const & var, T_INDICES const & packIndices )
1929 {
1930  typename MAP_TYPE::size_type const length = var.size();
1931  localIndex sizeOfPackedChars = Pack< DO_PACKING >( buffer, length );
1932 
1933  for( typename MAP_TYPE::const_iterator i=var.begin(); i!=var.end(); ++i )
1934  {
1935  sizeOfPackedChars += Pack< DO_PACKING >( buffer, i->first );
1936  sizeOfPackedChars += Pack< DO_PACKING >( buffer, i->second, packIndices );
1937  }
1938 
1939  return sizeOfPackedChars;
1940 }
1941 
1942 
1943 template< typename MAP_TYPE, typename T_INDICES >
1944 typename std::enable_if< is_map_packable_by_index< MAP_TYPE >, localIndex >::type
1945 Unpack( buffer_unit_type const * & buffer, MAP_TYPE & map, T_INDICES const & unpackIndices )
1946 {
1947  map.clear();
1948  typename MAP_TYPE::size_type map_length;
1949 
1950  localIndex sizeOfUnpackedChars = Unpack( buffer, map_length );
1951 
1952  for( typename MAP_TYPE::size_type a=0; a<map_length; ++a )
1953  {
1954  typename MAP_TYPE::key_type key;
1955  typename MAP_TYPE::mapped_type value;
1956  sizeOfUnpackedChars += Unpack( buffer, key );
1957  sizeOfUnpackedChars += Unpack( buffer, value, unpackIndices );
1958 
1959  map[key] = value;
1960  }
1961 
1962  return sizeOfUnpackedChars;
1963 }
1964 
1965 } /* namespace bufferOps */
1966 } /* namespace geos */
1967 
1968 #endif
#define GEOS_RESTRICT
preprocessor variable for the C99 restrict keyword for use with pointers
#define GEOS_DEBUG_VAR(...)
Mark a debug variable and silence compiler warnings.
Definition: GeosxMacros.hpp:87
#define GEOS_ERROR_IF(EXP, msg)
Conditionally raise a hard error and terminate the program.
Definition: Logger.hpp:142
#define GEOS_ASSERT_MSG(EXP, msg)
Assert a condition in debug builds.
Definition: Logger.hpp:171
#define GEOS_ASSERT_EQ(lhs, rhs)
Assert that two values compare equal in debug builds.
Definition: Logger.hpp:410
ArrayView< T, 1 > arrayView1d
Alias for 1D array view.
Definition: DataTypes.hpp:180
array1d< localIndex > localIndex_array
A 1-dimensional array of geos::localIndex types.
Definition: DataTypes.hpp:399
GEOS_GLOBALINDEX_TYPE globalIndex
Global index type (for indexing objects across MPI partitions).
Definition: DataTypes.hpp:88
constexpr static localIndex unmappedLocalIndexValue
A global variable for the value of a object that has not been assigned a geos::globalIndex.
Definition: DataTypes.hpp:461
LvArray::ArrayOfArraysView< T, INDEX_TYPE const, CONST_SIZES, LvArray::ChaiBuffer > ArrayOfArraysView
View of array of variable-sized arrays. See LvArray::ArrayOfArraysView for details.
Definition: DataTypes.hpp:286
GEOS_LOCALINDEX_TYPE localIndex
Local index type (for indexing objects within an MPI partition).
Definition: DataTypes.hpp:85
ArraySlice< T, 1, USD > arraySlice1d
Alias for 1D array slice.
Definition: DataTypes.hpp:184
mapBase< TKEY, TVAL, std::integral_constant< bool, true > > map
Ordered map type.
Definition: DataTypes.hpp:369
signed char buffer_unit_type
Type stored in communication buffers.
Definition: DataTypes.hpp:109
LvArray::ArrayOfArrays< T, INDEX_TYPE, LvArray::ChaiBuffer > ArrayOfArrays
Array of variable-sized arrays. See LvArray::ArrayOfArrays for details.
Definition: DataTypes.hpp:282