522 lines
23 KiB
C++
522 lines
23 KiB
C++
/*
|
|
# <<BEGIN-copyright>>
|
|
# Copyright 2019, Lawrence Livermore National Security, LLC.
|
|
# This file is part of the gidiplus package (https://github.com/LLNL/gidiplus).
|
|
# gidiplus is licensed under the MIT license (see https://opensource.org/licenses/MIT).
|
|
# SPDX-License-Identifier: MIT
|
|
# <<END-copyright>>
|
|
*/
|
|
|
|
#ifndef LUPI_data_buffer_hpp_included
|
|
#define LUPI_data_buffer_hpp_included 1
|
|
|
|
#include <cstdint>
|
|
|
|
#include <LUPI_defines.hpp>
|
|
#include <LUPI_declareMacro.hpp>
|
|
|
|
namespace LUPI {
|
|
|
|
/*
|
|
============================================================
|
|
========================= DataBuffer =======================
|
|
============================================================
|
|
*/
|
|
class DataBuffer {
|
|
|
|
public:
|
|
std::size_t m_intIndex;
|
|
std::size_t m_floatIndex;
|
|
std::size_t m_doubleIndex;
|
|
std::size_t m_charIndex;
|
|
std::size_t m_longIndex;
|
|
std::size_t m_size_tIndex;
|
|
|
|
int *m_intData;
|
|
float *m_floatData;
|
|
double *m_doubleData;
|
|
char *m_charData;
|
|
std::uint64_t *m_longData;
|
|
std::size_t *m_size_tData;
|
|
|
|
// For unpacking into pre-allocated memory
|
|
char *m_placementStart;
|
|
char *m_placement;
|
|
std::size_t m_maxPlacementSize;
|
|
|
|
// If m_sharedPlacementStart is not a nullPtr, place int and double vector information here
|
|
// m_sharedMaxPlacementSize is how much shared memory will be used.
|
|
char *m_sharedPlacementStart;
|
|
char *m_sharedPlacement;
|
|
std::size_t m_sharedMaxPlacementSize;
|
|
|
|
enum class Mode { Count, Pack, Unpack, Reset, Memory };
|
|
|
|
LUPI_HOST_DEVICE DataBuffer( void ) :
|
|
m_intIndex( 0 ),
|
|
m_floatIndex( 0 ),
|
|
m_doubleIndex( 0 ),
|
|
m_charIndex( 0 ),
|
|
m_longIndex( 0 ),
|
|
m_size_tIndex( 0 ),
|
|
|
|
m_intData( nullptr ),
|
|
m_floatData( nullptr ),
|
|
m_doubleData( nullptr ),
|
|
m_charData( nullptr ),
|
|
m_longData( nullptr ),
|
|
m_size_tData( nullptr ),
|
|
|
|
m_placementStart( nullptr ),
|
|
m_placement( nullptr ),
|
|
m_maxPlacementSize( 0 ),
|
|
m_sharedPlacementStart( nullptr ),
|
|
m_sharedPlacement( nullptr ),
|
|
m_sharedMaxPlacementSize( 0 ) {
|
|
}
|
|
|
|
LUPI_HOST_DEVICE DataBuffer( DataBuffer const &rhs ) :
|
|
m_intIndex( 0 ),
|
|
m_floatIndex( 0 ),
|
|
m_doubleIndex( 0 ),
|
|
m_charIndex( 0 ),
|
|
m_longIndex( 0 ),
|
|
m_size_tIndex( 0 ),
|
|
|
|
m_intData( nullptr ),
|
|
m_floatData( nullptr ),
|
|
m_doubleData( nullptr ),
|
|
m_charData( nullptr ),
|
|
m_longData( nullptr ),
|
|
m_size_tData( nullptr ),
|
|
|
|
m_placementStart( nullptr ),
|
|
m_placement( nullptr ),
|
|
m_maxPlacementSize( 0 ),
|
|
m_sharedPlacementStart( nullptr ),
|
|
m_sharedPlacement( nullptr ),
|
|
m_sharedMaxPlacementSize( 0 ) {
|
|
|
|
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.
|
|
|
|
}
|
|
|
|
LUPI_HOST_DEVICE ~DataBuffer( ) {
|
|
|
|
delete [] m_intData;
|
|
delete [] m_floatData;
|
|
delete [] m_doubleData;
|
|
delete [] m_charData;
|
|
delete [] m_longData;
|
|
delete [] m_size_tData;
|
|
}
|
|
|
|
LUPI_HOST_DEVICE void zeroIndexes( void ) {
|
|
|
|
m_intIndex = m_floatIndex = m_doubleIndex = m_charIndex = m_longIndex = m_size_tIndex = 0;
|
|
}
|
|
|
|
LUPI_HOST_DEVICE void copyIndexes( DataBuffer const &a_input ) {
|
|
|
|
m_intIndex = a_input.m_intIndex;
|
|
m_floatIndex = a_input.m_floatIndex;
|
|
m_doubleIndex = a_input.m_doubleIndex;
|
|
m_charIndex = a_input.m_charIndex;
|
|
m_longIndex = a_input.m_longIndex;
|
|
m_size_tIndex = a_input.m_size_tIndex;
|
|
}
|
|
|
|
LUPI_HOST_DEVICE void simpleCopy( DataBuffer const &a_input ) {
|
|
|
|
m_intIndex = a_input.m_intIndex;
|
|
m_floatIndex = a_input.m_floatIndex;
|
|
m_doubleIndex = a_input.m_doubleIndex;
|
|
m_charIndex = a_input.m_charIndex;
|
|
m_longIndex = a_input.m_longIndex;
|
|
m_size_tIndex = a_input.m_size_tIndex;
|
|
|
|
m_intData = a_input.m_intData;
|
|
m_floatData = a_input.m_floatData;
|
|
m_doubleData = a_input.m_doubleData;
|
|
m_charData = a_input.m_charData;
|
|
m_longData = a_input.m_longData;
|
|
m_size_tData = a_input.m_size_tData;
|
|
|
|
m_placementStart = a_input.m_placementStart;
|
|
m_placement = a_input.m_placement;
|
|
m_maxPlacementSize = a_input.m_maxPlacementSize;
|
|
m_sharedPlacementStart = a_input.m_sharedPlacementStart;
|
|
m_sharedPlacement = a_input.m_sharedPlacement;
|
|
m_sharedMaxPlacementSize = a_input.m_sharedMaxPlacementSize;
|
|
}
|
|
|
|
// Useful for temporary buffers that we don't want destroying the data in the destructor
|
|
LUPI_HOST_DEVICE void nullOutPointers( void ) {
|
|
|
|
m_intData = nullptr;
|
|
m_floatData = nullptr;
|
|
m_doubleData = nullptr;
|
|
m_charData = nullptr;
|
|
m_longData = nullptr;
|
|
m_size_tData = nullptr;
|
|
}
|
|
|
|
LUPI_HOST_DEVICE void allocateBuffers( void ) {
|
|
|
|
m_intData = new int[m_intIndex];
|
|
m_floatData = new float[m_floatIndex];
|
|
m_doubleData = new double[m_doubleIndex];
|
|
m_charData = new char[m_charIndex];
|
|
m_longData = new std::uint64_t[m_longIndex];
|
|
m_size_tData = new std::size_t[m_size_tIndex];
|
|
}
|
|
|
|
LUPI_HOST_DEVICE void freeMemory( void ) {
|
|
|
|
delete [] m_intData;
|
|
delete [] m_floatData;
|
|
delete [] m_doubleData;
|
|
delete [] m_charData;
|
|
delete [] m_longData;
|
|
delete [] m_size_tData;
|
|
|
|
zeroIndexes( );
|
|
nullOutPointers( );
|
|
}
|
|
|
|
LUPI_HOST_DEVICE bool compareIndexes( LUPI_maybeUnused char const *a_file, LUPI_maybeUnused int a_line, DataBuffer const &a_input ) {
|
|
|
|
return( ( a_input.m_intIndex == m_intIndex ) && ( a_input.m_floatIndex == m_floatIndex ) &&
|
|
( a_input.m_doubleIndex == m_doubleIndex ) &&
|
|
( a_input.m_charIndex == m_charIndex ) && ( a_input.m_longIndex == m_longIndex ) &&
|
|
( a_input.m_size_tIndex == m_size_tIndex ) );
|
|
}
|
|
|
|
LUPI_HOST_DEVICE void incrementPlacement(std::size_t a_delta) {
|
|
|
|
std::size_t sub = a_delta % 8;
|
|
if (sub != 0) a_delta += (8-sub);
|
|
m_placement += a_delta;
|
|
}
|
|
|
|
LUPI_HOST_DEVICE void incrementSharedPlacement(std::size_t a_delta) {
|
|
|
|
std::size_t sub = a_delta % 8;
|
|
if (sub != 0) a_delta += (8-sub);
|
|
m_sharedPlacement += a_delta;
|
|
}
|
|
|
|
// Returns true if data buffer has not gone over any memory limits
|
|
LUPI_HOST_DEVICE bool validate() {
|
|
|
|
if (m_placementStart == 0 && m_sharedPlacementStart == 0) return true;
|
|
if (m_placement > m_maxPlacementSize + m_placementStart) return false;
|
|
if (m_sharedPlacement > m_sharedMaxPlacementSize + m_sharedPlacementStart) return false;
|
|
return true;
|
|
}
|
|
|
|
#if defined(__CUDACC__) || defined (__HIP__)
|
|
#ifdef __CUDACC__
|
|
#define LUPI_GPU_MALLOC cudaMalloc
|
|
#define LUPI_GPU_MEMCPY cudaMemcpy
|
|
#define LUPI_GPU_HTOD cudaMemcpyHostToDevice
|
|
#else
|
|
#define LUPI_GPU_MALLOC hipMalloc
|
|
#define LUPI_GPU_MEMCPY hipMemcpy
|
|
#define LUPI_GPU_HTOD hipMemcpyHostToDevice
|
|
#endif
|
|
// Copy this host object to the device and return its pointer
|
|
LUPI_HOST DataBuffer *copyToDevice(std::size_t a_cpuSize, char *&a_protarePtr) {
|
|
|
|
DataBuffer *devicePtr = nullptr;
|
|
DataBuffer buf_tmp;
|
|
|
|
buf_tmp.copyIndexes(*this);
|
|
buf_tmp.m_maxPlacementSize = a_cpuSize;
|
|
|
|
gpuErrorCheck( LUPI_GPU_MALLOC( (void **) &buf_tmp.m_intData, sizeof(int) * m_intIndex) );
|
|
gpuErrorCheck( LUPI_GPU_MEMCPY( buf_tmp.m_intData, m_intData, sizeof(int) * m_intIndex, LUPI_GPU_HTOD ) );
|
|
gpuErrorCheck( LUPI_GPU_MALLOC( (void **) &buf_tmp.m_floatData, sizeof(float) * m_floatIndex ) );
|
|
gpuErrorCheck( LUPI_GPU_MEMCPY( buf_tmp.m_floatData, m_floatData, sizeof(float) * m_floatIndex, LUPI_GPU_HTOD ) );
|
|
gpuErrorCheck( LUPI_GPU_MALLOC( (void **) &buf_tmp.m_doubleData, sizeof(double) * m_doubleIndex ) );
|
|
gpuErrorCheck( LUPI_GPU_MEMCPY( buf_tmp.m_doubleData, m_doubleData, sizeof(double) * m_doubleIndex, LUPI_GPU_HTOD ) );
|
|
gpuErrorCheck( LUPI_GPU_MALLOC( (void **) &buf_tmp.m_charData, sizeof(char) * m_charIndex ) );
|
|
gpuErrorCheck( LUPI_GPU_MEMCPY( buf_tmp.m_charData, m_charData, sizeof(char) * m_charIndex, LUPI_GPU_HTOD ) );
|
|
gpuErrorCheck( LUPI_GPU_MALLOC( (void **) &buf_tmp.m_longData, sizeof(std::uint64_t) * m_longIndex ) );
|
|
gpuErrorCheck( LUPI_GPU_MEMCPY( buf_tmp.m_longData, m_longData, sizeof(std::uint64_t) * m_longIndex, LUPI_GPU_HTOD ) );
|
|
gpuErrorCheck( LUPI_GPU_MALLOC( (void **) &buf_tmp.m_size_tData, sizeof(std::size_t) * m_size_tIndex ) );
|
|
gpuErrorCheck( LUPI_GPU_MEMCPY( buf_tmp.m_size_tData, m_size_tData, sizeof(std::size_t) * m_size_tIndex, LUPI_GPU_HTOD ) );
|
|
|
|
gpuErrorCheck( LUPI_GPU_MALLOC( (void **) &buf_tmp.m_placementStart, buf_tmp.m_maxPlacementSize ) );
|
|
// Set to 0 for easier byte comparisons. This may be removed after testing is done
|
|
//gpuErrorCheck( cudaMemset( (void *) buf_tmp.m_placementStart, 0, buf_tmp.m_maxPlacementSize ) );
|
|
buf_tmp.m_placement = buf_tmp.m_placementStart;
|
|
|
|
a_protarePtr = buf_tmp.m_placementStart;
|
|
|
|
gpuErrorCheck( LUPI_GPU_MALLOC( (void **) &devicePtr, sizeof(DataBuffer) ) );
|
|
gpuErrorCheck( LUPI_GPU_MEMCPY( devicePtr, &buf_tmp, sizeof(DataBuffer), LUPI_GPU_HTOD ) );
|
|
|
|
// Don't need destructor trying to free the device memory.
|
|
buf_tmp.nullOutPointers( );
|
|
|
|
return devicePtr;
|
|
}
|
|
#undef LUPI_GPU_MALLOC
|
|
#undef LUPI_GPU_MEMCPY
|
|
#undef LUPI_GPU_HTOD
|
|
#endif
|
|
|
|
private:
|
|
DataBuffer &operator=( DataBuffer const &tmp ); // disable assignment operator
|
|
|
|
};
|
|
|
|
} // End of namespace LUPI.
|
|
|
|
#define DATA_MEMBER_SIMPLE(member, buffer, index, mode) \
|
|
{if ( mode == LUPI::DataBuffer::Mode::Count ) {(index)++; } \
|
|
else if ( mode == LUPI::DataBuffer::Mode::Pack ) {(buffer)[ (index)++ ] = (member); } \
|
|
else if ( mode == LUPI::DataBuffer::Mode::Unpack ) {member = (buffer)[ (index)++ ]; } \
|
|
else if ( mode == LUPI::DataBuffer::Mode::Reset ) {(index)++; member = 0; }}
|
|
|
|
#define DATA_MEMBER_CAST(member, buf, mode, someType) \
|
|
{if ( mode == LUPI::DataBuffer::Mode::Count ) {((buf).m_intIndex)++; } \
|
|
else if ( mode == LUPI::DataBuffer::Mode::Pack ) {(buf).m_intData[ ((buf).m_intIndex)++ ] = (int)(member); } \
|
|
else if ( mode == LUPI::DataBuffer::Mode::Unpack ) {member = (someType) (buf).m_intData[ ((buf).m_intIndex)++ ]; } \
|
|
else if ( mode == LUPI::DataBuffer::Mode::Reset ) {((buf).m_intIndex)++; member = (someType) 0; }}
|
|
|
|
#define DATA_MEMBER_CHAR( member, buf, mode) DATA_MEMBER_SIMPLE(member, (buf).m_charData, (buf).m_charIndex, mode)
|
|
#define DATA_MEMBER_INT( member, buf, mode) DATA_MEMBER_SIMPLE(member, (buf).m_intData, (buf).m_intIndex, mode)
|
|
#define DATA_MEMBER_FLOAT(member, buf, mode) DATA_MEMBER_SIMPLE(member, (buf).m_floatData, (buf).m_floatIndex, mode)
|
|
#define DATA_MEMBER_DOUBLE(member, buf, mode) DATA_MEMBER_SIMPLE(member, (buf).m_doubleData, (buf).m_doubleIndex, mode)
|
|
#define DATA_MEMBER_SIZE_T(member, buf, mode) DATA_MEMBER_SIMPLE(member, (buf).m_size_tData, (buf).m_size_tIndex, mode)
|
|
|
|
#define DATA_MEMBER_STRING(member, buf, mode) \
|
|
{if ( mode == LUPI::DataBuffer::Mode::Count ) {((buf).m_charIndex) += member.size(); ((buf).m_size_tIndex)++; } \
|
|
else if ( mode == LUPI::DataBuffer::Mode::Pack ) {std::size_t array_size = member.size(); \
|
|
(buf).m_size_tData[((buf).m_size_tIndex)++] = array_size; \
|
|
for (std::size_t size_index = 0; size_index < array_size; size_index++)\
|
|
{(buf).m_charData[ ((buf).m_charIndex)++ ] = (member[size_index]); }} \
|
|
else if ( mode == LUPI::DataBuffer::Mode::Unpack ) {std::size_t array_size = (buf).m_size_tData[((buf).m_size_tIndex)++]; \
|
|
member.resize(array_size, &(buf).m_placement); \
|
|
for (std::size_t size_index = 0; size_index < array_size; size_index++) \
|
|
{member[size_index] = (buf).m_charData[ ((buf).m_charIndex)++ ]; }} \
|
|
else if ( mode == LUPI::DataBuffer::Mode::Reset ) {std::size_t array_size = member.size(); \
|
|
for (std::size_t size_index = 0; size_index < array_size; size_index++) \
|
|
{((buf).m_charIndex)++; member[size_index] = '\0'; }} \
|
|
else if ( mode == LUPI::DataBuffer::Mode::Memory ) { (buf).incrementPlacement(sizeof(char) * (member.size()+1)); } }
|
|
|
|
#define DATA_MEMBER_STD_STRING(member, buf, mode) { \
|
|
if ( mode == LUPI::DataBuffer::Mode::Count ) \
|
|
{((buf).m_charIndex) += member.size(); ((buf).m_size_tIndex)++; } \
|
|
else if ( mode == LUPI::DataBuffer::Mode::Pack ) {std::size_t array_size = member.size(); \
|
|
(buf).m_size_tData[((buf).m_size_tIndex)++] = array_size; \
|
|
for (std::size_t size_index = 0; size_index < array_size; size_index++)\
|
|
{(buf).m_charData[((buf).m_charIndex)++] = (member[size_index]); }} \
|
|
else if ( mode == LUPI::DataBuffer::Mode::Unpack ) {std::size_t array_size = (std::size_t) (buf).m_size_tData[((buf).m_size_tIndex)++]; \
|
|
member.resize(array_size); \
|
|
for (std::size_t size_index = 0; size_index < array_size; size_index++) \
|
|
{member[size_index] = (buf).m_charData[ ((buf).m_charIndex)++ ]; }} }
|
|
|
|
#if LUPI_WARP_SIZE > 1 && defined(LUPI_ON_GPU)
|
|
#define DATA_MEMBER_VECTOR_FLOAT(member, buf, mode) \
|
|
{ \
|
|
std::size_t vector_size = member.size(); \
|
|
DATA_MEMBER_SIZE_T(vector_size, (buf), mode); \
|
|
if ( mode == LUPI::DataBuffer::Mode::Unpack ) member.resize(vector_size, &(buf).m_placement); \
|
|
std::size_t bufferIndex = (buf).m_floatIndex; \
|
|
for ( std::size_t member_index = 0; member_index < vector_size; member_index += LUPI_WARP_SIZE, bufferIndex += LUPI_WARP_SIZE ) \
|
|
{ \
|
|
std::size_t thrMemberId = member_index + LUPI_THREADID; \
|
|
if (thrMemberId >= vector_size) continue; \
|
|
member[thrMemberId] = (buf).m_floatData[bufferIndex + LUPI_THREADID]; \
|
|
} \
|
|
(buf).m_floatIndex += vector_size; \
|
|
}
|
|
#define DATA_MEMBER_VECTOR_DOUBLE(member, buf, mode) \
|
|
{ \
|
|
std::size_t vector_size = member.size(); \
|
|
DATA_MEMBER_SIZE_T(vector_size, (buf), mode); \
|
|
if ( mode == LUPI::DataBuffer::Mode::Unpack ) member.resize(vector_size, &(buf).m_placement); \
|
|
std::size_t bufferIndex = (buf).m_doubleIndex; \
|
|
for ( std::size_t member_index = 0; member_index < vector_size; member_index += LUPI_WARP_SIZE, bufferIndex += LUPI_WARP_SIZE ) \
|
|
{ \
|
|
std::size_t thrMemberId = member_index + LUPI_THREADID; \
|
|
if (thrMemberId >= vector_size) continue; \
|
|
member[thrMemberId] = (buf).m_doubleData[bufferIndex + LUPI_THREADID]; \
|
|
} \
|
|
(buf).m_doubleIndex += vector_size; \
|
|
}
|
|
#else
|
|
#define DATA_MEMBER_VECTOR_FLOAT(member, buf, mode) \
|
|
{ \
|
|
std::size_t vector_size = member.size(); \
|
|
DATA_MEMBER_SIZE_T(vector_size, (buf), mode); \
|
|
if ( mode == LUPI::DataBuffer::Mode::Unpack ) { \
|
|
if ((buf).m_sharedPlacement == nullptr) { \
|
|
member.resize(vector_size, &(buf).m_placement); \
|
|
} else { \
|
|
member.resize(vector_size, &(buf).m_sharedPlacement); \
|
|
} \
|
|
}\
|
|
if ( mode == LUPI::DataBuffer::Mode::Memory ) { \
|
|
(buf).incrementSharedPlacement(sizeof(float) * member.capacity()); \
|
|
} \
|
|
for ( std::size_t member_index = 0; member_index < vector_size; member_index++ ) \
|
|
{ \
|
|
DATA_MEMBER_FLOAT(member[member_index], (buf), mode); \
|
|
} \
|
|
}
|
|
#define DATA_MEMBER_VECTOR_DOUBLE(member, buf, mode) \
|
|
{ \
|
|
std::size_t vector_size = member.size(); \
|
|
DATA_MEMBER_SIZE_T(vector_size, (buf), mode); \
|
|
if ( mode == LUPI::DataBuffer::Mode::Unpack ) { \
|
|
if ((buf).m_sharedPlacement == nullptr) { \
|
|
member.resize(vector_size, &(buf).m_placement); \
|
|
} else { \
|
|
member.resize(vector_size, &(buf).m_sharedPlacement); \
|
|
} \
|
|
}\
|
|
if ( mode == LUPI::DataBuffer::Mode::Memory ) { \
|
|
(buf).incrementSharedPlacement(sizeof(double) * member.capacity()); \
|
|
} \
|
|
for ( std::size_t member_index = 0; member_index < vector_size; member_index++ ) \
|
|
{ \
|
|
DATA_MEMBER_DOUBLE(member[member_index], (buf), mode); \
|
|
} \
|
|
}
|
|
#endif
|
|
|
|
#if LUPI_WARP_SIZE > 1 && defined(LUPI_ON_GPU)
|
|
#define DATA_MEMBER_VECTOR_INT(member, buf, mode) \
|
|
{ \
|
|
std::size_t vector_size = member.size(); \
|
|
DATA_MEMBER_SIZE_T(vector_size, (buf), mode); \
|
|
if ( mode == LUPI::DataBuffer::Mode::Unpack ) member.resize(vector_size, &(buf).m_placement); \
|
|
std::size_t bufferIndex = (buf).m_intIndex; \
|
|
for ( std::size_t member_index = 0; member_index < vector_size; member_index += LUPI_WARP_SIZE, bufferIndex += LUPI_WARP_SIZE ) \
|
|
{ \
|
|
std::size_t thrMemberId = member_index + LUPI_THREADID; \
|
|
if (thrMemberId >= vector_size) continue; \
|
|
member[thrMemberId] = (buf).m_intData[bufferIndex + LUPI_THREADID]; \
|
|
} \
|
|
(buf).m_intIndex += vector_size; \
|
|
}
|
|
#else
|
|
#define DATA_MEMBER_VECTOR_INT(member, buf, mode) \
|
|
{ \
|
|
std::size_t vector_size = member.size(); \
|
|
DATA_MEMBER_SIZE_T(vector_size, (buf), mode); \
|
|
if ( mode == LUPI::DataBuffer::Mode::Unpack ) { \
|
|
if ((buf).m_sharedPlacement == nullptr) { \
|
|
member.resize(vector_size, &(buf).m_placement); \
|
|
} else { \
|
|
member.resize(vector_size, &(buf).m_sharedPlacement); \
|
|
} \
|
|
}\
|
|
if ( mode == LUPI::DataBuffer::Mode::Memory ) { \
|
|
(buf).incrementSharedPlacement(sizeof(int) * member.capacity()); \
|
|
} \
|
|
for ( std::size_t member_index = 0; member_index < vector_size; member_index++ ) \
|
|
{ \
|
|
DATA_MEMBER_INT(member[member_index], (buf), mode); \
|
|
} \
|
|
}
|
|
#endif
|
|
|
|
#if LUPI_WARP_SIZE > 1 && defined(LUPI_ON_GPU)
|
|
#define DATA_MEMBER_VECTOR_BOOL(member, buf, mode) \
|
|
{ \
|
|
std::size_t vector_size = member.size(); \
|
|
DATA_MEMBER_SIZE_T(vector_size, (buf), mode); \
|
|
if ( mode == LUPI::DataBuffer::Mode::Unpack ) member.resize(vector_size, &(buf).m_placement); \
|
|
std::size_t bufferIndex = (buf).m_intIndex; \
|
|
for ( std::size_t member_index = 0; member_index < vector_size; member_index += LUPI_WARP_SIZE, bufferIndex += LUPI_WARP_SIZE ) \
|
|
{ \
|
|
std::size_t thrMemberId = member_index + LUPI_THREADID; \
|
|
if (thrMemberId >= vector_size) continue; \
|
|
member[thrMemberId] = (buf).m_intData[bufferIndex + LUPI_THREADID]; \
|
|
} \
|
|
(buf).m_intIndex += vector_size; \
|
|
}
|
|
#else
|
|
#define DATA_MEMBER_VECTOR_BOOL(member, buf, mode) \
|
|
{ \
|
|
std::size_t vector_size = member.size(); \
|
|
DATA_MEMBER_SIZE_T(vector_size, (buf), mode); \
|
|
if ( mode == LUPI::DataBuffer::Mode::Unpack ) { \
|
|
if ((buf).m_sharedPlacement == nullptr) { \
|
|
member.resize(vector_size, &(buf).m_placement); \
|
|
} else { \
|
|
member.resize(vector_size, &(buf).m_sharedPlacement); \
|
|
} \
|
|
}\
|
|
if ( mode == LUPI::DataBuffer::Mode::Memory ) { \
|
|
(buf).incrementSharedPlacement(sizeof(int) * member.capacity()); \
|
|
} \
|
|
for ( std::size_t member_index = 0; member_index < vector_size; member_index++ ) \
|
|
{ \
|
|
DATA_MEMBER_CAST(member[member_index], (buf), mode, bool); \
|
|
} \
|
|
}
|
|
#endif
|
|
|
|
#if LUPI_WARP_SIZE > 1 && defined(LUPI_ON_GPU)
|
|
#define DATA_MEMBER_CHAR_ARRAY( member, buf, mode ) { \
|
|
std::size_t array_size = sizeof( member ); \
|
|
std::size_t bufferIndex = (buf).m_charIndex; \
|
|
for ( std::size_t member_index = 0; member_index < array_size; member_index += LUPI_WARP_SIZE, bufferIndex += LUPI_WARP_SIZE ) { \
|
|
std::size_t thrMemberId = member_index + LUPI_THREADID; \
|
|
if( thrMemberId >= array_size ) continue; \
|
|
member[thrMemberId] = (buf).m_charData[bufferIndex + LUPI_THREADID]; \
|
|
} \
|
|
(buf).m_charIndex += array_size; \
|
|
}
|
|
#else
|
|
#define DATA_MEMBER_CHAR_ARRAY( member, buf, mode ) { \
|
|
std::size_t array_size = sizeof( member ); \
|
|
for ( std::size_t member_index = 0; member_index < array_size; member_index++ ) DATA_MEMBER_CHAR( member[member_index], (buf), mode ); \
|
|
}
|
|
#endif
|
|
|
|
#if LUPI_WARP_SIZE > 1 && defined(LUPI_ON_GPU)
|
|
#define DATA_MEMBER_VECTOR_SIZE_T(member, buf, mode) \
|
|
{ \
|
|
std::size_t vector_size = member.size(); \
|
|
DATA_MEMBER_SIZE_T(vector_size, (buf), mode); \
|
|
if ( mode == LUPI::DataBuffer::Mode::Unpack ) member.resize(vector_size, &(buf).m_placement); \
|
|
std::size_t bufferIndex = (buf).m_size_tIndex; \
|
|
for ( std::size_t member_index = 0; member_index < vector_size; member_index += LUPI_WARP_SIZE, bufferIndex += LUPI_WARP_SIZE ) \
|
|
{ \
|
|
std::size_t thrMemberId = member_index + LUPI_THREADID; \
|
|
if (thrMemberId >= vector_size) continue; \
|
|
member[thrMemberId] = (buf).m_size_tData[bufferIndex + LUPI_THREADID]; \
|
|
} \
|
|
(buf).m_size_tIndex += vector_size; \
|
|
}
|
|
#else
|
|
#define DATA_MEMBER_VECTOR_SIZE_T(member, buf, mode) \
|
|
{ \
|
|
std::size_t vector_size = member.size(); \
|
|
DATA_MEMBER_SIZE_T(vector_size, (buf), mode); \
|
|
if ( mode == LUPI::DataBuffer::Mode::Unpack ) { \
|
|
if ((buf).m_sharedPlacement == nullptr) { \
|
|
member.resize(vector_size, &(buf).m_placement); \
|
|
} else { \
|
|
member.resize(vector_size, &(buf).m_sharedPlacement); \
|
|
} \
|
|
}\
|
|
if ( mode == LUPI::DataBuffer::Mode::Memory ) { \
|
|
(buf).incrementSharedPlacement(sizeof(std::size_t) * member.capacity()); \
|
|
} \
|
|
for ( std::size_t member_index = 0; member_index < vector_size; member_index++ ) \
|
|
{ \
|
|
DATA_MEMBER_SIZE_T(member[member_index], (buf), mode); \
|
|
} \
|
|
}
|
|
#endif
|
|
|
|
#endif // End of LUPI_data_buffer_hpp_included
|