Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/Geant4/LUPI_dataBuffer.hpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002 # <<BEGIN-copyright>>
0003 # Copyright 2019, Lawrence Livermore National Security, LLC.
0004 # This file is part of the gidiplus package (https://github.com/LLNL/gidiplus).
0005 # gidiplus is licensed under the MIT license (see https://opensource.org/licenses/MIT).
0006 # SPDX-License-Identifier: MIT
0007 # <<END-copyright>>
0008 */
0009 
0010 #ifndef LUPI_data_buffer_hpp_included
0011 #define LUPI_data_buffer_hpp_included 1
0012 
0013 #include <cstdint>
0014 
0015 #include <LUPI_defines.hpp>
0016 #include <LUPI_declareMacro.hpp>
0017 
0018 namespace LUPI {
0019 
0020 /*
0021 ============================================================
0022 ========================= DataBuffer =======================
0023 ============================================================
0024 */
0025 class DataBuffer {
0026 
0027     public:
0028         std::size_t m_intIndex;
0029         std::size_t m_floatIndex;
0030         std::size_t m_doubleIndex;
0031         std::size_t m_charIndex;
0032         std::size_t m_longIndex;
0033         std::size_t m_size_tIndex;
0034 
0035         int *m_intData;
0036         float *m_floatData;
0037         double *m_doubleData;
0038         char *m_charData;
0039         std::uint64_t *m_longData;
0040         std::size_t *m_size_tData;
0041 
0042         // For unpacking into pre-allocated memory
0043         char *m_placementStart;
0044         char *m_placement;
0045         std::size_t m_maxPlacementSize;
0046 
0047         // If m_sharedPlacementStart is not a nullPtr, place int and double vector information here
0048         // m_sharedMaxPlacementSize is how much shared memory will be used.
0049         char *m_sharedPlacementStart;
0050         char *m_sharedPlacement;
0051         std::size_t m_sharedMaxPlacementSize;
0052 
0053         enum class Mode { Count, Pack, Unpack, Reset, Memory };
0054 
0055         LUPI_HOST_DEVICE DataBuffer( void ) :
0056                 m_intIndex( 0 ),
0057                 m_floatIndex( 0 ),
0058                 m_doubleIndex( 0 ),
0059                 m_charIndex( 0 ),
0060                 m_longIndex( 0 ),
0061                 m_size_tIndex( 0 ),
0062 
0063                 m_intData( nullptr ),
0064                 m_floatData( nullptr ),
0065                 m_doubleData( nullptr ),
0066                 m_charData( nullptr ),
0067                 m_longData( nullptr ),
0068                 m_size_tData( nullptr ),
0069 
0070                 m_placementStart( nullptr ),
0071                 m_placement( nullptr ),
0072                 m_maxPlacementSize( 0 ),
0073                 m_sharedPlacementStart( nullptr ),
0074                 m_sharedPlacement( nullptr ),
0075                 m_sharedMaxPlacementSize( 0 ) {
0076         }
0077 
0078         LUPI_HOST_DEVICE DataBuffer( DataBuffer const &rhs ) :
0079                 m_intIndex( 0 ),
0080                 m_floatIndex( 0 ),
0081                 m_doubleIndex( 0 ),
0082                 m_charIndex( 0 ),
0083                 m_longIndex( 0 ),
0084                 m_size_tIndex( 0 ),
0085 
0086                 m_intData( nullptr ),
0087                 m_floatData( nullptr ),
0088                 m_doubleData( nullptr ),
0089                 m_charData( nullptr ),
0090                 m_longData( nullptr ),
0091                 m_size_tData( nullptr ),
0092 
0093                 m_placementStart( nullptr ),
0094                 m_placement( nullptr ),
0095                 m_maxPlacementSize( 0 ),
0096                 m_sharedPlacementStart( nullptr ),
0097                 m_sharedPlacement( nullptr ),
0098                 m_sharedMaxPlacementSize( 0 ) {
0099 
0100             if( rhs.m_placementStart == nullptr ) m_placementStart = rhs.m_placementStart;  // Only to stop compiler warning of unused variable as cannot get [[maybe_unused]] to work.
0101 
0102         }
0103 
0104         LUPI_HOST_DEVICE ~DataBuffer( ) {
0105 
0106             delete [] m_intData;
0107             delete [] m_floatData;
0108             delete [] m_doubleData;
0109             delete [] m_charData;
0110             delete [] m_longData;
0111             delete [] m_size_tData;
0112         }
0113 
0114         LUPI_HOST_DEVICE void zeroIndexes( void ) {
0115 
0116             m_intIndex = m_floatIndex = m_doubleIndex = m_charIndex = m_longIndex = m_size_tIndex = 0;
0117         }
0118 
0119         LUPI_HOST_DEVICE void copyIndexes( DataBuffer const &a_input ) {
0120 
0121             m_intIndex    = a_input.m_intIndex;
0122             m_floatIndex  = a_input.m_floatIndex;
0123             m_doubleIndex = a_input.m_doubleIndex;
0124             m_charIndex   = a_input.m_charIndex;
0125             m_longIndex   = a_input.m_longIndex;
0126             m_size_tIndex = a_input.m_size_tIndex;
0127         }
0128 
0129         LUPI_HOST_DEVICE void simpleCopy( DataBuffer const &a_input ) {
0130 
0131             m_intIndex               = a_input.m_intIndex;
0132             m_floatIndex             = a_input.m_floatIndex;
0133             m_doubleIndex            = a_input.m_doubleIndex;
0134             m_charIndex              = a_input.m_charIndex;
0135             m_longIndex              = a_input.m_longIndex;
0136             m_size_tIndex            = a_input.m_size_tIndex;
0137 
0138             m_intData                = a_input.m_intData;
0139             m_floatData              = a_input.m_floatData;
0140             m_doubleData             = a_input.m_doubleData;
0141             m_charData               = a_input.m_charData;
0142             m_longData               = a_input.m_longData;
0143             m_size_tData             = a_input.m_size_tData;
0144 
0145             m_placementStart         = a_input.m_placementStart;
0146             m_placement              = a_input.m_placement;
0147             m_maxPlacementSize       = a_input.m_maxPlacementSize;
0148             m_sharedPlacementStart   = a_input.m_sharedPlacementStart;
0149             m_sharedPlacement        = a_input.m_sharedPlacement;
0150             m_sharedMaxPlacementSize = a_input.m_sharedMaxPlacementSize;
0151         }
0152 
0153         // Useful for temporary buffers that we don't want destroying the data in the destructor
0154         LUPI_HOST_DEVICE void nullOutPointers( void ) {
0155 
0156             m_intData = nullptr;
0157             m_floatData = nullptr;
0158             m_doubleData = nullptr;
0159             m_charData = nullptr;
0160             m_longData = nullptr;
0161             m_size_tData = nullptr;
0162         }
0163 
0164         LUPI_HOST_DEVICE void allocateBuffers( void ) {
0165 
0166             m_intData = new int[m_intIndex];
0167             m_floatData = new float[m_floatIndex];
0168             m_doubleData = new double[m_doubleIndex];
0169             m_charData = new char[m_charIndex];
0170             m_longData = new std::uint64_t[m_longIndex];
0171             m_size_tData = new std::size_t[m_size_tIndex];
0172         }
0173 
0174         LUPI_HOST_DEVICE void freeMemory( void ) {
0175 
0176             delete [] m_intData;
0177             delete [] m_floatData;
0178             delete [] m_doubleData;
0179             delete [] m_charData;
0180             delete [] m_longData;
0181             delete [] m_size_tData;
0182 
0183             zeroIndexes( );
0184             nullOutPointers( );
0185         }
0186 
0187         LUPI_HOST_DEVICE bool compareIndexes( LUPI_maybeUnused char const *a_file, LUPI_maybeUnused int a_line, DataBuffer const &a_input ) {
0188 
0189             return( ( a_input.m_intIndex  == m_intIndex  ) && ( a_input.m_floatIndex == m_floatIndex ) &&
0190                     ( a_input.m_doubleIndex == m_doubleIndex ) &&
0191                     ( a_input.m_charIndex == m_charIndex ) && ( a_input.m_longIndex  == m_longIndex  ) &&
0192                     ( a_input.m_size_tIndex == m_size_tIndex ) );
0193         }
0194 
0195         LUPI_HOST_DEVICE void incrementPlacement(std::size_t a_delta) {
0196 
0197             std::size_t sub = a_delta % 8;
0198             if (sub != 0) a_delta += (8-sub);
0199             m_placement += a_delta;
0200         }
0201 
0202         LUPI_HOST_DEVICE void incrementSharedPlacement(std::size_t a_delta) {
0203 
0204             std::size_t sub = a_delta % 8;
0205             if (sub != 0) a_delta += (8-sub);
0206             m_sharedPlacement += a_delta;
0207         }
0208 
0209         // Returns true if data buffer has not gone over any memory limits
0210         LUPI_HOST_DEVICE bool validate() {
0211 
0212             if (m_placementStart == 0 && m_sharedPlacementStart == 0) return true;
0213             if (m_placement > m_maxPlacementSize + m_placementStart) return false;
0214             if (m_sharedPlacement > m_sharedMaxPlacementSize + m_sharedPlacementStart) return false;
0215             return true;
0216         }
0217 
0218 #if defined(__CUDACC__) || defined (__HIP__)
0219     #ifdef __CUDACC__
0220         #define LUPI_GPU_MALLOC cudaMalloc
0221         #define LUPI_GPU_MEMCPY cudaMemcpy
0222         #define LUPI_GPU_HTOD   cudaMemcpyHostToDevice
0223     #else
0224         #define LUPI_GPU_MALLOC hipMalloc
0225         #define LUPI_GPU_MEMCPY hipMemcpy
0226         #define LUPI_GPU_HTOD   hipMemcpyHostToDevice
0227     #endif
0228         // Copy this host object to the device and return its pointer
0229         LUPI_HOST DataBuffer *copyToDevice(std::size_t a_cpuSize, char *&a_protarePtr) {
0230 
0231             DataBuffer *devicePtr = nullptr;
0232             DataBuffer buf_tmp;
0233 
0234             buf_tmp.copyIndexes(*this);
0235             buf_tmp.m_maxPlacementSize = a_cpuSize;
0236 
0237             gpuErrorCheck( LUPI_GPU_MALLOC( (void **) &buf_tmp.m_intData, sizeof(int) * m_intIndex) );
0238             gpuErrorCheck( LUPI_GPU_MEMCPY( buf_tmp.m_intData, m_intData, sizeof(int) * m_intIndex, LUPI_GPU_HTOD ) );
0239             gpuErrorCheck( LUPI_GPU_MALLOC( (void **) &buf_tmp.m_floatData, sizeof(float) * m_floatIndex ) );
0240             gpuErrorCheck( LUPI_GPU_MEMCPY( buf_tmp.m_floatData, m_floatData, sizeof(float) * m_floatIndex, LUPI_GPU_HTOD ) );
0241             gpuErrorCheck( LUPI_GPU_MALLOC( (void **) &buf_tmp.m_doubleData, sizeof(double) * m_doubleIndex ) );
0242             gpuErrorCheck( LUPI_GPU_MEMCPY( buf_tmp.m_doubleData, m_doubleData, sizeof(double) * m_doubleIndex, LUPI_GPU_HTOD ) );
0243             gpuErrorCheck( LUPI_GPU_MALLOC( (void **) &buf_tmp.m_charData, sizeof(char) * m_charIndex ) );
0244             gpuErrorCheck( LUPI_GPU_MEMCPY( buf_tmp.m_charData, m_charData, sizeof(char) * m_charIndex, LUPI_GPU_HTOD ) );
0245             gpuErrorCheck( LUPI_GPU_MALLOC( (void **) &buf_tmp.m_longData, sizeof(std::uint64_t) * m_longIndex ) );
0246             gpuErrorCheck( LUPI_GPU_MEMCPY( buf_tmp.m_longData, m_longData, sizeof(std::uint64_t) * m_longIndex, LUPI_GPU_HTOD ) );
0247             gpuErrorCheck( LUPI_GPU_MALLOC( (void **) &buf_tmp.m_size_tData, sizeof(std::size_t) * m_size_tIndex ) );
0248             gpuErrorCheck( LUPI_GPU_MEMCPY( buf_tmp.m_size_tData, m_size_tData, sizeof(std::size_t) * m_size_tIndex, LUPI_GPU_HTOD ) );
0249 
0250             gpuErrorCheck( LUPI_GPU_MALLOC( (void **) &buf_tmp.m_placementStart, buf_tmp.m_maxPlacementSize ) );
0251             // Set to 0 for easier byte comparisons. This may be removed after testing is done
0252             //gpuErrorCheck( cudaMemset( (void *) buf_tmp.m_placementStart, 0, buf_tmp.m_maxPlacementSize ) );
0253             buf_tmp.m_placement = buf_tmp.m_placementStart;
0254 
0255             a_protarePtr = buf_tmp.m_placementStart;
0256 
0257             gpuErrorCheck( LUPI_GPU_MALLOC( (void **) &devicePtr, sizeof(DataBuffer) ) );
0258             gpuErrorCheck( LUPI_GPU_MEMCPY( devicePtr, &buf_tmp, sizeof(DataBuffer), LUPI_GPU_HTOD ) );
0259 
0260             // Don't need destructor trying to free the device memory.
0261             buf_tmp.nullOutPointers( );
0262 
0263             return devicePtr;
0264         }
0265     #undef LUPI_GPU_MALLOC
0266     #undef LUPI_GPU_MEMCPY
0267     #undef LUPI_GPU_HTOD
0268 #endif
0269 
0270     private:
0271         DataBuffer &operator=( DataBuffer const &tmp );     // disable assignment operator
0272 
0273 };
0274 
0275 }       // End of namespace LUPI.
0276 
0277 #define DATA_MEMBER_SIMPLE(member, buffer, index, mode) \
0278     {if (     mode == LUPI::DataBuffer::Mode::Count )  {(index)++; } \
0279      else if ( mode == LUPI::DataBuffer::Mode::Pack   ) {(buffer)[ (index)++ ] = (member); } \
0280      else if ( mode == LUPI::DataBuffer::Mode::Unpack ) {member = (buffer)[ (index)++ ]; }   \
0281      else if ( mode == LUPI::DataBuffer::Mode::Reset )  {(index)++; member = 0; }}
0282 
0283 #define DATA_MEMBER_CAST(member, buf, mode, someType) \
0284     {if (     mode == LUPI::DataBuffer::Mode::Count )  {((buf).m_intIndex)++; } \
0285      else if ( mode == LUPI::DataBuffer::Mode::Pack   ) {(buf).m_intData[ ((buf).m_intIndex)++ ] = (int)(member); } \
0286      else if ( mode == LUPI::DataBuffer::Mode::Unpack ) {member = (someType) (buf).m_intData[ ((buf).m_intIndex)++ ]; } \
0287      else if ( mode == LUPI::DataBuffer::Mode::Reset )  {((buf).m_intIndex)++; member = (someType) 0; }}
0288 
0289 #define DATA_MEMBER_CHAR( member, buf, mode) DATA_MEMBER_SIMPLE(member, (buf).m_charData,  (buf).m_charIndex,  mode)
0290 #define DATA_MEMBER_INT(  member, buf, mode) DATA_MEMBER_SIMPLE(member, (buf).m_intData,   (buf).m_intIndex,   mode)
0291 #define DATA_MEMBER_FLOAT(member, buf, mode) DATA_MEMBER_SIMPLE(member, (buf).m_floatData, (buf).m_floatIndex, mode)
0292 #define DATA_MEMBER_DOUBLE(member, buf, mode) DATA_MEMBER_SIMPLE(member, (buf).m_doubleData, (buf).m_doubleIndex, mode)
0293 #define DATA_MEMBER_SIZE_T(member, buf, mode) DATA_MEMBER_SIMPLE(member, (buf).m_size_tData, (buf).m_size_tIndex, mode)
0294 
0295 #define DATA_MEMBER_STRING(member, buf, mode) \
0296     {if (     mode == LUPI::DataBuffer::Mode::Count ) {((buf).m_charIndex) += member.size(); ((buf).m_size_tIndex)++; } \
0297      else if ( mode == LUPI::DataBuffer::Mode::Pack   ) {std::size_t array_size = member.size(); \
0298              (buf).m_size_tData[((buf).m_size_tIndex)++] = array_size; \
0299              for (std::size_t size_index = 0; size_index < array_size; size_index++)\
0300                  {(buf).m_charData[ ((buf).m_charIndex)++ ] = (member[size_index]); }} \
0301      else if ( mode == LUPI::DataBuffer::Mode::Unpack ) {std::size_t array_size = (buf).m_size_tData[((buf).m_size_tIndex)++]; \
0302          member.resize(array_size, &(buf).m_placement); \
0303          for (std::size_t size_index = 0; size_index < array_size; size_index++) \
0304              {member[size_index] = (buf).m_charData[ ((buf).m_charIndex)++ ]; }} \
0305      else if ( mode == LUPI::DataBuffer::Mode::Reset ) {std::size_t array_size = member.size(); \
0306          for (std::size_t size_index = 0; size_index < array_size; size_index++) \
0307             {((buf).m_charIndex)++; member[size_index] = '\0'; }} \
0308      else if ( mode == LUPI::DataBuffer::Mode::Memory ) { (buf).incrementPlacement(sizeof(char) * (member.size()+1)); } }
0309 
0310 #define DATA_MEMBER_STD_STRING(member, buf, mode) { \
0311     if (     mode == LUPI::DataBuffer::Mode::Count ) \
0312         {((buf).m_charIndex) += member.size(); ((buf).m_size_tIndex)++; } \
0313     else if ( mode == LUPI::DataBuffer::Mode::Pack   ) {std::size_t array_size = member.size(); \
0314              (buf).m_size_tData[((buf).m_size_tIndex)++] = array_size; \
0315              for (std::size_t size_index = 0; size_index < array_size; size_index++)\
0316                  {(buf).m_charData[((buf).m_charIndex)++] = (member[size_index]); }} \
0317     else if ( mode == LUPI::DataBuffer::Mode::Unpack ) {std::size_t array_size = (std::size_t) (buf).m_size_tData[((buf).m_size_tIndex)++]; \
0318          member.resize(array_size); \
0319          for (std::size_t size_index = 0; size_index < array_size; size_index++) \
0320              {member[size_index] = (buf).m_charData[ ((buf).m_charIndex)++ ]; }} }
0321 
0322 #if LUPI_WARP_SIZE > 1 && defined(LUPI_ON_GPU)
0323 #define DATA_MEMBER_VECTOR_FLOAT(member, buf, mode) \
0324     { \
0325         std::size_t vector_size = member.size(); \
0326         DATA_MEMBER_SIZE_T(vector_size, (buf), mode); \
0327         if ( mode == LUPI::DataBuffer::Mode::Unpack ) member.resize(vector_size, &(buf).m_placement); \
0328         std::size_t bufferIndex = (buf).m_floatIndex; \
0329         for ( std::size_t member_index = 0; member_index < vector_size; member_index += LUPI_WARP_SIZE, bufferIndex += LUPI_WARP_SIZE ) \
0330         { \
0331             std::size_t thrMemberId = member_index + LUPI_THREADID; \
0332             if (thrMemberId >= vector_size) continue; \
0333             member[thrMemberId] = (buf).m_floatData[bufferIndex + LUPI_THREADID]; \
0334         } \
0335         (buf).m_floatIndex += vector_size; \
0336     }
0337 #define DATA_MEMBER_VECTOR_DOUBLE(member, buf, mode) \
0338     { \
0339         std::size_t vector_size = member.size(); \
0340         DATA_MEMBER_SIZE_T(vector_size, (buf), mode); \
0341         if ( mode == LUPI::DataBuffer::Mode::Unpack ) member.resize(vector_size, &(buf).m_placement); \
0342         std::size_t bufferIndex = (buf).m_doubleIndex; \
0343         for ( std::size_t member_index = 0; member_index < vector_size; member_index += LUPI_WARP_SIZE, bufferIndex += LUPI_WARP_SIZE ) \
0344         { \
0345             std::size_t thrMemberId = member_index + LUPI_THREADID; \
0346             if (thrMemberId >= vector_size) continue; \
0347             member[thrMemberId] = (buf).m_doubleData[bufferIndex + LUPI_THREADID]; \
0348         } \
0349         (buf).m_doubleIndex += vector_size; \
0350     }
0351 #else
0352 #define DATA_MEMBER_VECTOR_FLOAT(member, buf, mode) \
0353     { \
0354         std::size_t vector_size = member.size(); \
0355         DATA_MEMBER_SIZE_T(vector_size, (buf), mode); \
0356         if ( mode == LUPI::DataBuffer::Mode::Unpack ) { \
0357             if ((buf).m_sharedPlacement == nullptr) { \
0358                 member.resize(vector_size, &(buf).m_placement); \
0359             } else { \
0360                 member.resize(vector_size, &(buf).m_sharedPlacement); \
0361             } \
0362         }\
0363         if ( mode == LUPI::DataBuffer::Mode::Memory ) { \
0364             (buf).incrementSharedPlacement(sizeof(float) * member.capacity()); \
0365         } \
0366         for ( std::size_t member_index = 0; member_index < vector_size; member_index++ ) \
0367         { \
0368             DATA_MEMBER_FLOAT(member[member_index], (buf), mode); \
0369         } \
0370     }
0371 #define DATA_MEMBER_VECTOR_DOUBLE(member, buf, mode) \
0372     { \
0373         std::size_t vector_size = member.size(); \
0374         DATA_MEMBER_SIZE_T(vector_size, (buf), mode); \
0375         if ( mode == LUPI::DataBuffer::Mode::Unpack ) { \
0376             if ((buf).m_sharedPlacement == nullptr) { \
0377                 member.resize(vector_size, &(buf).m_placement); \
0378             } else { \
0379                 member.resize(vector_size, &(buf).m_sharedPlacement); \
0380             } \
0381         }\
0382         if ( mode == LUPI::DataBuffer::Mode::Memory ) { \
0383             (buf).incrementSharedPlacement(sizeof(double) * member.capacity()); \
0384         } \
0385         for ( std::size_t member_index = 0; member_index < vector_size; member_index++ ) \
0386         { \
0387             DATA_MEMBER_DOUBLE(member[member_index], (buf), mode); \
0388         } \
0389     }
0390 #endif
0391 
0392 #if LUPI_WARP_SIZE > 1 && defined(LUPI_ON_GPU)
0393 #define DATA_MEMBER_VECTOR_INT(member, buf, mode) \
0394     { \
0395         std::size_t vector_size = member.size(); \
0396         DATA_MEMBER_SIZE_T(vector_size, (buf), mode); \
0397         if ( mode == LUPI::DataBuffer::Mode::Unpack ) member.resize(vector_size, &(buf).m_placement); \
0398         std::size_t bufferIndex = (buf).m_intIndex; \
0399         for ( std::size_t member_index = 0; member_index < vector_size; member_index += LUPI_WARP_SIZE, bufferIndex += LUPI_WARP_SIZE ) \
0400         { \
0401             std::size_t thrMemberId = member_index + LUPI_THREADID; \
0402             if (thrMemberId >= vector_size) continue; \
0403             member[thrMemberId] = (buf).m_intData[bufferIndex + LUPI_THREADID]; \
0404         } \
0405         (buf).m_intIndex += vector_size; \
0406     }
0407 #else
0408 #define DATA_MEMBER_VECTOR_INT(member, buf, mode) \
0409     { \
0410         std::size_t vector_size = member.size(); \
0411         DATA_MEMBER_SIZE_T(vector_size, (buf), mode); \
0412         if ( mode == LUPI::DataBuffer::Mode::Unpack ) { \
0413             if ((buf).m_sharedPlacement == nullptr) { \
0414                 member.resize(vector_size, &(buf).m_placement); \
0415             } else { \
0416                 member.resize(vector_size, &(buf).m_sharedPlacement); \
0417             } \
0418         }\
0419         if ( mode == LUPI::DataBuffer::Mode::Memory ) { \
0420             (buf).incrementSharedPlacement(sizeof(int) * member.capacity()); \
0421         } \
0422         for ( std::size_t member_index = 0; member_index < vector_size; member_index++ ) \
0423         { \
0424             DATA_MEMBER_INT(member[member_index], (buf), mode); \
0425         } \
0426     }
0427 #endif
0428 
0429 #if LUPI_WARP_SIZE > 1 && defined(LUPI_ON_GPU)
0430 #define DATA_MEMBER_VECTOR_BOOL(member, buf, mode) \
0431     { \
0432         std::size_t vector_size = member.size(); \
0433         DATA_MEMBER_SIZE_T(vector_size, (buf), mode); \
0434         if ( mode == LUPI::DataBuffer::Mode::Unpack ) member.resize(vector_size, &(buf).m_placement); \
0435         std::size_t bufferIndex = (buf).m_intIndex; \
0436         for ( std::size_t member_index = 0; member_index < vector_size; member_index += LUPI_WARP_SIZE, bufferIndex += LUPI_WARP_SIZE ) \
0437         { \
0438             std::size_t thrMemberId = member_index + LUPI_THREADID; \
0439             if (thrMemberId >= vector_size) continue; \
0440             member[thrMemberId] = (buf).m_intData[bufferIndex + LUPI_THREADID]; \
0441         } \
0442         (buf).m_intIndex += vector_size; \
0443     }
0444 #else
0445 #define DATA_MEMBER_VECTOR_BOOL(member, buf, mode) \
0446     { \
0447         std::size_t vector_size = member.size(); \
0448         DATA_MEMBER_SIZE_T(vector_size, (buf), mode); \
0449         if ( mode == LUPI::DataBuffer::Mode::Unpack ) { \
0450             if ((buf).m_sharedPlacement == nullptr) { \
0451                 member.resize(vector_size, &(buf).m_placement); \
0452             } else { \
0453                 member.resize(vector_size, &(buf).m_sharedPlacement); \
0454             } \
0455         }\
0456         if ( mode == LUPI::DataBuffer::Mode::Memory ) { \
0457             (buf).incrementSharedPlacement(sizeof(int) * member.capacity()); \
0458         } \
0459         for ( std::size_t member_index = 0; member_index < vector_size; member_index++ ) \
0460         { \
0461             DATA_MEMBER_CAST(member[member_index], (buf), mode, bool); \
0462         } \
0463     }
0464 #endif
0465 
0466 #if LUPI_WARP_SIZE > 1 && defined(LUPI_ON_GPU)
0467 #define DATA_MEMBER_CHAR_ARRAY( member, buf, mode ) { \
0468         std::size_t array_size = sizeof( member ); \
0469         std::size_t bufferIndex = (buf).m_charIndex; \
0470         for ( std::size_t member_index = 0; member_index < array_size; member_index += LUPI_WARP_SIZE, bufferIndex += LUPI_WARP_SIZE ) { \
0471             std::size_t thrMemberId = member_index + LUPI_THREADID; \
0472             if( thrMemberId >= array_size ) continue; \
0473             member[thrMemberId] = (buf).m_charData[bufferIndex + LUPI_THREADID]; \
0474         } \
0475         (buf).m_charIndex += array_size; \
0476     }
0477 #else
0478 #define DATA_MEMBER_CHAR_ARRAY( member, buf, mode ) { \
0479         std::size_t array_size = sizeof( member ); \
0480         for ( std::size_t member_index = 0; member_index < array_size; member_index++ ) DATA_MEMBER_CHAR( member[member_index], (buf), mode ); \
0481     }
0482 #endif
0483 
0484 #if LUPI_WARP_SIZE > 1 && defined(LUPI_ON_GPU)
0485 #define DATA_MEMBER_VECTOR_SIZE_T(member, buf, mode) \
0486     { \
0487         std::size_t vector_size = member.size(); \
0488         DATA_MEMBER_SIZE_T(vector_size, (buf), mode); \
0489         if ( mode == LUPI::DataBuffer::Mode::Unpack ) member.resize(vector_size, &(buf).m_placement); \
0490         std::size_t bufferIndex = (buf).m_size_tIndex; \
0491         for ( std::size_t member_index = 0; member_index < vector_size; member_index += LUPI_WARP_SIZE, bufferIndex += LUPI_WARP_SIZE ) \
0492         { \
0493             std::size_t thrMemberId = member_index + LUPI_THREADID; \
0494             if (thrMemberId >= vector_size) continue; \
0495             member[thrMemberId] = (buf).m_size_tData[bufferIndex + LUPI_THREADID]; \
0496         } \
0497         (buf).m_size_tIndex += vector_size; \
0498     }
0499 #else
0500 #define DATA_MEMBER_VECTOR_SIZE_T(member, buf, mode) \
0501     { \
0502         std::size_t vector_size = member.size(); \
0503         DATA_MEMBER_SIZE_T(vector_size, (buf), mode); \
0504         if ( mode == LUPI::DataBuffer::Mode::Unpack ) { \
0505             if ((buf).m_sharedPlacement == nullptr) { \
0506                 member.resize(vector_size, &(buf).m_placement); \
0507             } else { \
0508                 member.resize(vector_size, &(buf).m_sharedPlacement); \
0509             } \
0510         }\
0511         if ( mode == LUPI::DataBuffer::Mode::Memory ) { \
0512             (buf).incrementSharedPlacement(sizeof(std::size_t) * member.capacity()); \
0513         } \
0514         for ( std::size_t member_index = 0; member_index < vector_size; member_index++ ) \
0515         { \
0516             DATA_MEMBER_SIZE_T(member[member_index], (buf), mode); \
0517         } \
0518     }
0519 #endif
0520 
0521 #endif      // End of LUPI_data_buffer_hpp_included