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