diff --git a/source/adios2/CMakeLists.txt b/source/adios2/CMakeLists.txt index c63ffa6140..ff96f8e2c1 100644 --- a/source/adios2/CMakeLists.txt +++ b/source/adios2/CMakeLists.txt @@ -80,6 +80,7 @@ add_library(adios2_core toolkit/format/buffer/chunk/ChunkV.cpp toolkit/format/buffer/ffs/BufferFFS.cpp toolkit/format/buffer/heap/BufferSTL.cpp + toolkit/format/buffer/heap/BufferMalloc.cpp toolkit/format/buffer/malloc/MallocV.cpp toolkit/format/bp/BPBase.cpp toolkit/format/bp/BPBase.tcc diff --git a/source/adios2/engine/bp5/BP5Reader.cpp b/source/adios2/engine/bp5/BP5Reader.cpp index cb0b9aa570..636f67ace4 100644 --- a/source/adios2/engine/bp5/BP5Reader.cpp +++ b/source/adios2/engine/bp5/BP5Reader.cpp @@ -70,8 +70,8 @@ void BP5Reader::InstallMetadataForTimestep(size_t Step) { // variable metadata for timestep size_t ThisMDSize = - helper::ReadValue(m_Metadata.m_Buffer, Position, m_Minifooter.IsLittleEndian); - char *ThisMD = m_Metadata.m_Buffer.data() + MDPosition; + helper::ReadValue(m_Metadata.Data(), Position, m_Minifooter.IsLittleEndian); + char *ThisMD = m_Metadata.Data() + MDPosition; if (m_OpenMode == Mode::ReadRandomAccess) { m_BP5Deserializer->InstallMetaData(ThisMD, ThisMDSize, WriterRank, Step); @@ -86,8 +86,8 @@ void BP5Reader::InstallMetadataForTimestep(size_t Step) { // attribute metadata for timestep size_t ThisADSize = - helper::ReadValue(m_Metadata.m_Buffer, Position, m_Minifooter.IsLittleEndian); - char *ThisAD = m_Metadata.m_Buffer.data() + MDPosition; + helper::ReadValue(m_Metadata.Data(), Position, m_Minifooter.IsLittleEndian); + char *ThisAD = m_Metadata.Data() + MDPosition; if (ThisADSize > 0) m_BP5Deserializer->InstallAttributeData(ThisAD, ThisADSize); MDPosition += ThisADSize; @@ -820,8 +820,7 @@ void BP5Reader::UpdateBuffer(const TimePoint &timeoutInstant, const Seconds &pol for (auto p : m_FilteredMetadataInfo) { m_JSONProfiler.AddBytes("metadataread", p.second); - m_MDFileManager.ReadFile(m_Metadata.m_Buffer.data() + mempos, p.second, - p.first); + m_MDFileManager.ReadFile(m_Metadata.Data() + mempos, p.second, p.first); mempos += p.second; } m_MDFileAlreadyReadSize = expectedMinFileSize; @@ -863,14 +862,20 @@ void BP5Reader::UpdateBuffer(const TimePoint &timeoutInstant, const Seconds &pol } } - // broadcast buffer to all ranks from zero - m_Comm.BroadcastVector(m_Metadata.m_Buffer); - // broadcast metadata index buffer to all ranks from zero m_Comm.BroadcastVector(m_MetaMetadata.m_Buffer); InstallMetaMetaData(m_MetaMetadata); + size_t inputSize = m_Comm.BroadcastValue(m_Metadata.Size(), 0); + + if (m_Comm.Rank() != 0) + { + m_Metadata.Resize(inputSize, "metadata broadcast"); + } + + m_Comm.Bcast(m_Metadata.Data(), inputSize, 0); + if (m_OpenMode == Mode::ReadRandomAccess) { for (size_t Step = 0; Step < m_MetadataIndexTable.size(); Step++) diff --git a/source/adios2/engine/bp5/BP5Reader.h b/source/adios2/engine/bp5/BP5Reader.h index cc73944c2f..440158e509 100644 --- a/source/adios2/engine/bp5/BP5Reader.h +++ b/source/adios2/engine/bp5/BP5Reader.h @@ -4,8 +4,6 @@ * * BP5Reader.h * - * Created on: Aug 1, 2018 - * Author: Lipeng Wan wanl@ornl.gov */ #ifndef ADIOS2_ENGINE_BP5_BP5READER_H_ @@ -18,6 +16,7 @@ #include "adios2/helper/adiosComm.h" #include "adios2/helper/adiosRangeFilter.h" #include "adios2/toolkit/format/bp5/BP5Deserializer.h" +#include "adios2/toolkit/format/buffer/heap/BufferMalloc.h" #include "adios2/toolkit/remote/Remote.h" #include "adios2/toolkit/transportman/TransportMan.h" @@ -225,7 +224,7 @@ class BP5Reader : public BP5Engine, public Engine format::BufferSTL m_MetadataIndex; format::BufferSTL m_MetaMetadata; - format::BufferSTL m_Metadata; + format::BufferMalloc m_Metadata; void InstallMetaMetaData(format::BufferSTL MetaMetadata); void InstallMetadataForTimestep(size_t Step); diff --git a/source/adios2/helper/adiosMemory.h b/source/adios2/helper/adiosMemory.h index 10076fd8c7..7c56dd9823 100644 --- a/source/adios2/helper/adiosMemory.h +++ b/source/adios2/helper/adiosMemory.h @@ -5,8 +5,6 @@ * adiosMemory.h : Memory copy operations functions using std::copy std::insert * and std::memcpy * - * Created on: May 17, 2017 - * Author: William F Godoy godoywf@ornl.gov */ #ifndef ADIOS2_HELPER_ADIOSMEMORY_H_ @@ -83,7 +81,7 @@ void CopyToBufferThreads(std::vector &buffer, size_t &position, const T *s const size_t elements = 1, const unsigned int threads = 1) noexcept; template -void ReverseCopyFromBuffer(const std::vector &buffer, size_t &position, T *destination, +void ReverseCopyFromBuffer(const char *buffer, size_t &position, T *destination, const size_t elements = 1) noexcept; /** @@ -95,7 +93,7 @@ void ReverseCopyFromBuffer(const std::vector &buffer, size_t &position, T * @param elements number of elements of destination type */ template -void CopyFromBuffer(const std::vector &buffer, size_t &position, T *destination, +void CopyFromBuffer(const char *buffer, size_t &position, T *destination, const size_t elements = 1) noexcept; /** @@ -110,6 +108,9 @@ template T ReadValue(const std::vector &buffer, size_t &position, const bool isLittleEndian = true) noexcept; +template +T ReadValue(const char *buffer, size_t &position, const bool isLittleEndian = true) noexcept; + /** Read in 'nElems' elements from buffer into output array * output must be pre-allocated. */ diff --git a/source/adios2/helper/adiosMemory.inl b/source/adios2/helper/adiosMemory.inl index 7854056c37..25928198c7 100644 --- a/source/adios2/helper/adiosMemory.inl +++ b/source/adios2/helper/adiosMemory.inl @@ -4,8 +4,6 @@ * * adiosMemory.inl definition of template functions in adiosMemory.h * - * Created on: May 17, 2017 - * Author: William F Godoy godoywf@ornl.gov */ #ifndef ADIOS2_HELPER_ADIOSMEMORY_INL_ @@ -33,8 +31,7 @@ namespace helper #ifdef ADIOS2_HAVE_ENDIAN_REVERSE template -inline void CopyEndianReverse(const char *src, const size_t payloadStride, - T *dest) +inline void CopyEndianReverse(const char *src, const size_t payloadStride, T *dest) { if (sizeof(T) == 1) { @@ -47,8 +44,7 @@ inline void CopyEndianReverse(const char *src, const size_t payloadStride, } template <> -inline void CopyEndianReverse>(const char *src, - const size_t payloadStride, +inline void CopyEndianReverse>(const char *src, const size_t payloadStride, std::complex *dest) { std::reverse_copy(src, src + payloadStride, reinterpret_cast(dest)); @@ -57,8 +53,7 @@ inline void CopyEndianReverse>(const char *src, } template <> -inline void CopyEndianReverse>(const char *src, - const size_t payloadStride, +inline void CopyEndianReverse>(const char *src, const size_t payloadStride, std::complex *dest) { std::reverse_copy(src, src + payloadStride, reinterpret_cast(dest)); @@ -68,26 +63,23 @@ inline void CopyEndianReverse>(const char *src, #endif template -void InsertToBuffer(std::vector &buffer, const T *source, - const size_t elements) noexcept +void InsertToBuffer(std::vector &buffer, const T *source, const size_t elements) noexcept { const char *src = reinterpret_cast(source); buffer.insert(buffer.end(), src, src + elements * sizeof(T)); } template -void CopyFromGPUToBuffer(std::vector &dest, size_t &position, - const T *GPUbuffer, MemorySpace memSpace, - const size_t elements) noexcept +void CopyFromGPUToBuffer(std::vector &dest, size_t &position, const T *GPUbuffer, + MemorySpace memSpace, const size_t elements) noexcept { - CopyFromGPUToBuffer(dest.data(), position, GPUbuffer, memSpace, - elements * sizeof(T)); + CopyFromGPUToBuffer(dest.data(), position, GPUbuffer, memSpace, elements * sizeof(T)); position += elements * sizeof(T); } template -void CopyFromGPUToBuffer(char *dest, size_t position, const T *GPUbuffer, - MemorySpace memSpace, const size_t size) noexcept +void CopyFromGPUToBuffer(char *dest, size_t position, const T *GPUbuffer, MemorySpace memSpace, + const size_t size) noexcept { #ifdef ADIOS2_HAVE_GPU_SUPPORT if (memSpace == MemorySpace::GPU) @@ -99,8 +91,8 @@ void CopyFromGPUToBuffer(char *dest, size_t position, const T *GPUbuffer, } template -void CopyFromBufferToGPU(T *GPUbuffer, size_t position, const char *source, - MemorySpace memSpace, const size_t size) noexcept +void CopyFromBufferToGPU(T *GPUbuffer, size_t position, const char *source, MemorySpace memSpace, + const size_t size) noexcept { #ifdef ADIOS2_HAVE_GPU_SUPPORT if (memSpace == MemorySpace::GPU) @@ -111,9 +103,8 @@ void CopyFromBufferToGPU(T *GPUbuffer, size_t position, const char *source, #endif } -static inline void NdCopyGPU(const char *&inOvlpBase, char *&outOvlpBase, - CoreDims &inOvlpGapSize, CoreDims &outOvlpGapSize, - CoreDims &ovlpCount, size_t minContDim, +static inline void NdCopyGPU(const char *&inOvlpBase, char *&outOvlpBase, CoreDims &inOvlpGapSize, + CoreDims &outOvlpGapSize, CoreDims &ovlpCount, size_t minContDim, size_t blockSize, MemorySpace memSpace) { DimsArray pos(ovlpCount.size(), (size_t)0); @@ -152,9 +143,8 @@ void CopyToBuffer(std::vector &buffer, size_t &position, const T *source, } template -void CopyToBufferThreads(std::vector &buffer, size_t &position, - const T *source, const size_t elements, - const unsigned int threads) noexcept +void CopyToBufferThreads(std::vector &buffer, size_t &position, const T *source, + const size_t elements, const unsigned int threads) noexcept { if (elements == 0) { @@ -182,9 +172,8 @@ void CopyToBufferThreads(std::vector &buffer, size_t &position, const size_t srcStart = stride * t * sizeof(T); if (t == threads - 1) // last thread takes stride + remainder { - copyThreads.push_back(std::thread(std::memcpy, &buffer[bufferStart], - &src[srcStart], - last * sizeof(T))); + copyThreads.push_back( + std::thread(std::memcpy, &buffer[bufferStart], &src[srcStart], last * sizeof(T))); // std::copy not working properly with std::thread...why? // copyThreads.push_back(std::thread(std::copy, // &src[srcStart], @@ -195,9 +184,8 @@ void CopyToBufferThreads(std::vector &buffer, size_t &position, } else { - copyThreads.push_back(std::thread(std::memcpy, &buffer[bufferStart], - &src[srcStart], - stride * sizeof(T))); + copyThreads.push_back( + std::thread(std::memcpy, &buffer[bufferStart], &src[srcStart], stride * sizeof(T))); // std::copy not working properly with std::thread...why? // copyThreads.push_back(std::thread( // std::copy, &src[srcStart], &src[srcStart] + stride @@ -215,22 +203,18 @@ void CopyToBufferThreads(std::vector &buffer, size_t &position, } template -inline void ReverseCopyFromBuffer(const std::vector &buffer, - size_t &position, T *destination, +inline void ReverseCopyFromBuffer(const char *buffer, size_t &position, T *destination, const size_t elements) noexcept { - std::reverse_copy(buffer.begin() + position, - buffer.begin() + position + sizeof(T) * elements, + std::reverse_copy(buffer + position, buffer + position + sizeof(T) * elements, reinterpret_cast(destination)); position += elements * sizeof(T); } template -void CopyFromBuffer(const std::vector &buffer, size_t &position, - T *destination, size_t elements) noexcept +void CopyFromBuffer(const char *buffer, size_t &position, T *destination, size_t elements) noexcept { - std::copy(buffer.begin() + position, - buffer.begin() + position + sizeof(T) * elements, + std::copy(buffer + position, buffer + position + sizeof(T) * elements, reinterpret_cast(destination)); position += elements * sizeof(T); } @@ -248,6 +232,26 @@ inline T ReadValue(const std::vector &buffer, size_t &position, { T value; +#ifdef ADIOS2_HAVE_ENDIAN_REVERSE + if (IsLittleEndian() != isLittleEndian) + { + ReverseCopyFromBuffer(buffer.data(), position, &value); + } + else + { + CopyFromBuffer(buffer.data(), position, &value); + } +#else + CopyFromBuffer(buffer.data(), position, &value); +#endif + return value; +} + +template +inline T ReadValue(const char *buffer, size_t &position, const bool isLittleEndian) noexcept +{ + T value; + #ifdef ADIOS2_HAVE_ENDIAN_REVERSE if (IsLittleEndian() != isLittleEndian) { @@ -264,129 +268,120 @@ inline T ReadValue(const std::vector &buffer, size_t &position, } template <> -inline std::complex -ReadValue>(const std::vector &buffer, - size_t &position, - const bool isLittleEndian) noexcept +inline std::complex ReadValue>(const std::vector &buffer, + size_t &position, + const bool isLittleEndian) noexcept { std::complex value; #ifdef ADIOS2_HAVE_ENDIAN_REVERSE if (IsLittleEndian() != isLittleEndian) { - ReverseCopyFromBuffer(buffer, position, &value); + ReverseCopyFromBuffer(buffer.data(), position, &value); return std::complex(value.imag(), value.real()); } else { - CopyFromBuffer(buffer, position, &value); + CopyFromBuffer(buffer.data(), position, &value); } #else - CopyFromBuffer(buffer, position, &value); + CopyFromBuffer(buffer.data(), position, &value); #endif return value; } template <> -inline std::complex -ReadValue>(const std::vector &buffer, - size_t &position, - const bool isLittleEndian) noexcept +inline std::complex ReadValue>(const std::vector &buffer, + size_t &position, + const bool isLittleEndian) noexcept { std::complex value; #ifdef ADIOS2_HAVE_ENDIAN_REVERSE if (IsLittleEndian() != isLittleEndian) { - ReverseCopyFromBuffer(buffer, position, &value); + ReverseCopyFromBuffer(buffer.data(), position, &value); return std::complex(value.imag(), value.real()); } else { - CopyFromBuffer(buffer, position, &value); + CopyFromBuffer(buffer.data(), position, &value); } #else - CopyFromBuffer(buffer, position, &value); + CopyFromBuffer(buffer.data(), position, &value); #endif return value; } template -inline void ReadArray(const std::vector &buffer, size_t &position, - T *output, const size_t nElems, - const bool isLittleEndian) noexcept +inline void ReadArray(const std::vector &buffer, size_t &position, T *output, + const size_t nElems, const bool isLittleEndian) noexcept { #ifdef ADIOS2_HAVE_ENDIAN_REVERSE if (IsLittleEndian() != isLittleEndian) { - ReverseCopyFromBuffer(buffer, position, output, nElems); + ReverseCopyFromBuffer(buffer.data(), position, output, nElems); } else { - CopyFromBuffer(buffer, position, output, nElems); + CopyFromBuffer(buffer.data(), position, output, nElems); } #else - CopyFromBuffer(buffer, position, output, nElems); + CopyFromBuffer(buffer.data(), position, output, nElems); #endif } template <> -inline void ReadArray>(const std::vector &buffer, - size_t &position, - std::complex *output, - const size_t nElems, +inline void ReadArray>(const std::vector &buffer, size_t &position, + std::complex *output, const size_t nElems, const bool isLittleEndian) noexcept { #ifdef ADIOS2_HAVE_ENDIAN_REVERSE if (IsLittleEndian() != isLittleEndian) { - ReverseCopyFromBuffer(buffer, position, output, nElems); + ReverseCopyFromBuffer(buffer.data(), position, output, nElems); } else { - CopyFromBuffer(buffer, position, output, nElems); + CopyFromBuffer(buffer.data(), position, output, nElems); } #else - CopyFromBuffer(buffer, position, output, nElems); + CopyFromBuffer(buffer.data(), position, output, nElems); #endif } template <> -inline void ReadArray>(const std::vector &buffer, - size_t &position, - std::complex *output, - const size_t nElems, +inline void ReadArray>(const std::vector &buffer, size_t &position, + std::complex *output, const size_t nElems, const bool isLittleEndian) noexcept { #ifdef ADIOS2_HAVE_ENDIAN_REVERSE if (IsLittleEndian() != isLittleEndian) { - ReverseCopyFromBuffer(buffer, position, output, nElems); + ReverseCopyFromBuffer(buffer.data(), position, output, nElems); } else { - CopyFromBuffer(buffer, position, output, nElems); + CopyFromBuffer(buffer.data(), position, output, nElems); } #else - CopyFromBuffer(buffer, position, output, nElems); + CopyFromBuffer(buffer.data(), position, output, nElems); #endif } template -void ClipVector(std::vector &vec, const size_t start, - const size_t end) noexcept +void ClipVector(std::vector &vec, const size_t start, const size_t end) noexcept { vec.resize(end); vec.erase(vec.begin(), vec.begin() + start); } template -void CopyMemoryBlock(T *dest, const Dims &destStart, const Dims &destCount, - const bool destRowMajor, const U *src, - const Dims &srcStart, const Dims &srcCount, - const bool srcRowMajor, const bool endianReverse, - const Dims &destMemStart, const Dims &destMemCount, - const Dims &srcMemStart, const Dims &srcMemCount) noexcept +void CopyMemoryBlock(T *dest, const Dims &destStart, const Dims &destCount, const bool destRowMajor, + const U *src, const Dims &srcStart, const Dims &srcCount, + const bool srcRowMajor, const bool endianReverse, const Dims &destMemStart, + const Dims &destMemCount, const Dims &srcMemStart, + const Dims &srcMemCount) noexcept { // transform everything to payload dims const Dims destStartPayload = PayloadDims(destStart, destRowMajor); @@ -399,28 +394,23 @@ void CopyMemoryBlock(T *dest, const Dims &destStart, const Dims &destCount, const Dims srcMemStartPayload = PayloadDims(srcMemStart, srcRowMajor); const Dims srcMemCountPayload = PayloadDims(srcMemCount, srcRowMajor); - CopyPayload(reinterpret_cast(dest), destStartPayload, - destCountPayload, destRowMajor, - reinterpret_cast(src), srcStartPayload, - srcCountPayload, srcRowMajor, destMemStartPayload, - destMemCountPayload, srcMemStartPayload, srcMemCountPayload, + CopyPayload(reinterpret_cast(dest), destStartPayload, destCountPayload, destRowMajor, + reinterpret_cast(src), srcStartPayload, srcCountPayload, srcRowMajor, + destMemStartPayload, destMemCountPayload, srcMemStartPayload, srcMemCountPayload, endianReverse, GetDataType()); } template void ClipContiguousMemory(T *dest, const Dims &destStart, const Dims &destCount, - const char *contiguousMemory, - const Box &blockBox, - const Box &intersectionBox, - const bool isRowMajor, const bool reverseDimensions, - const bool endianReverse, const MemorySpace memSpace) + const char *contiguousMemory, const Box &blockBox, + const Box &intersectionBox, const bool isRowMajor, + const bool reverseDimensions, const bool endianReverse, + const MemorySpace memSpace) { auto lf_ClipRowMajor = - [](T *dest, const Dims &destStart, const Dims &destCount, - const char *contiguousMemory, const Box &blockBox, - const Box &intersectionBox, const bool isRowMajor, - const bool reverseDimensions, const bool endianReverse, - const MemorySpace memSpace) + [](T *dest, const Dims &destStart, const Dims &destCount, const char *contiguousMemory, + const Box &blockBox, const Box &intersectionBox, const bool isRowMajor, + const bool reverseDimensions, const bool endianReverse, const MemorySpace memSpace) { const Dims &istart = intersectionBox.first; @@ -429,8 +419,7 @@ void ClipContiguousMemory(T *dest, const Dims &destStart, const Dims &destCount, Dims currentPoint(istart); // current point for memory copy // convert selection to EndBox and reverse if we are inside a // column-major reader - const Box selectionBox = - helper::StartEndBox(destStart, destCount, reverseDimensions); + const Box selectionBox = helper::StartEndBox(destStart, destCount, reverseDimensions); const size_t dimensions = istart.size(); @@ -441,14 +430,10 @@ void ClipContiguousMemory(T *dest, const Dims &destStart, const Dims &destCount, */ size_t nContDim = 1; while (nContDim <= dimensions - 1 && - blockBox.first[dimensions - nContDim] == - istart[dimensions - nContDim] && - blockBox.second[dimensions - nContDim] == - iend[dimensions - nContDim] && - blockBox.first[dimensions - nContDim] == - selectionBox.first[dimensions - nContDim] && - blockBox.second[dimensions - nContDim] == - selectionBox.second[dimensions - nContDim]) + blockBox.first[dimensions - nContDim] == istart[dimensions - nContDim] && + blockBox.second[dimensions - nContDim] == iend[dimensions - nContDim] && + blockBox.first[dimensions - nContDim] == selectionBox.first[dimensions - nContDim] && + blockBox.second[dimensions - nContDim] == selectionBox.second[dimensions - nContDim]) { ++nContDim; } @@ -462,22 +447,19 @@ void ClipContiguousMemory(T *dest, const Dims &destStart, const Dims &destCount, const size_t stride = nContElems * sizeof(T); const size_t intersectionStart = - helper::LinearIndex(blockBox, intersectionBox.first, true) * - sizeof(T); + helper::LinearIndex(blockBox, intersectionBox.first, true) * sizeof(T); bool run = true; while (run) { // here copy current linear memory between currentPoint and end const size_t contiguousStart = - helper::LinearIndex(blockBox, currentPoint, true) * sizeof(T) - - intersectionStart; + helper::LinearIndex(blockBox, currentPoint, true) * sizeof(T) - intersectionStart; - const size_t variableStart = - helper::LinearIndex(selectionBox, currentPoint, true); + const size_t variableStart = helper::LinearIndex(selectionBox, currentPoint, true); - CopyContiguousMemory(contiguousMemory + contiguousStart, stride, - dest + variableStart, endianReverse, memSpace); + CopyContiguousMemory(contiguousMemory + contiguousStart, stride, dest + variableStart, + endianReverse, memSpace); // Here update each non-contiguous dim recursively if (nContDim >= dimensions) @@ -513,11 +495,9 @@ void ClipContiguousMemory(T *dest, const Dims &destStart, const Dims &destCount, }; auto lf_ClipColumnMajor = - [](T *dest, const Dims &destStart, const Dims &destCount, - const char *contiguousMemory, const Box &blockBox, - const Box &intersectionBox, const bool isRowMajor, - const bool reverseDimensions, const bool endianReverse, - const MemorySpace memSpace) + [](T *dest, const Dims &destStart, const Dims &destCount, const char *contiguousMemory, + const Box &blockBox, const Box &intersectionBox, const bool isRowMajor, + const bool reverseDimensions, const bool endianReverse, const MemorySpace memSpace) { const Dims &istart = intersectionBox.first; @@ -525,8 +505,7 @@ void ClipContiguousMemory(T *dest, const Dims &destStart, const Dims &destCount, Dims currentPoint(istart); // current point for memory copy - const Box selectionBox = - helper::StartEndBox(destStart, destCount, reverseDimensions); + const Box selectionBox = helper::StartEndBox(destStart, destCount, reverseDimensions); const size_t dimensions = istart.size(); /* Determine how many dimensions we can copy at once. @@ -535,12 +514,10 @@ void ClipContiguousMemory(T *dest, const Dims &destStart, const Dims &destCount, nContDim = 1: line by line */ size_t nContDim = 1; - while ( - nContDim <= dimensions - 1 && - blockBox.first[nContDim - 1] == istart[nContDim - 1] && - blockBox.second[nContDim - 1] == iend[nContDim - 1] && - blockBox.first[nContDim - 1] == selectionBox.first[nContDim - 1] && - blockBox.second[nContDim - 1] == selectionBox.second[nContDim - 1]) + while (nContDim <= dimensions - 1 && blockBox.first[nContDim - 1] == istart[nContDim - 1] && + blockBox.second[nContDim - 1] == iend[nContDim - 1] && + blockBox.first[nContDim - 1] == selectionBox.first[nContDim - 1] && + blockBox.second[nContDim - 1] == selectionBox.second[nContDim - 1]) { ++nContDim; } @@ -554,22 +531,19 @@ void ClipContiguousMemory(T *dest, const Dims &destStart, const Dims &destCount, const size_t stride = nContElems * sizeof(T); const size_t intersectionStart = - helper::LinearIndex(blockBox, intersectionBox.first, false) * - sizeof(T); + helper::LinearIndex(blockBox, intersectionBox.first, false) * sizeof(T); bool run = true; while (run) { // here copy current linear memory between currentPoint and end const size_t contiguousStart = - helper::LinearIndex(blockBox, currentPoint, false) * sizeof(T) - - intersectionStart; + helper::LinearIndex(blockBox, currentPoint, false) * sizeof(T) - intersectionStart; - const size_t variableStart = - helper::LinearIndex(selectionBox, currentPoint, false); + const size_t variableStart = helper::LinearIndex(selectionBox, currentPoint, false); - CopyContiguousMemory(contiguousMemory + contiguousStart, stride, - dest + variableStart, endianReverse, memSpace); + CopyContiguousMemory(contiguousMemory + contiguousStart, stride, dest + variableStart, + endianReverse, memSpace); // Here update each non-contiguous dim recursively. if (nContDim >= dimensions) @@ -613,37 +587,33 @@ void ClipContiguousMemory(T *dest, const Dims &destStart, const Dims &destCount, const Dims &end = intersectionBox.second; const size_t stride = (end.back() - start.back() + 1) * sizeof(T); - CopyContiguousMemory(contiguousMemory, stride, dest + normalizedStart, - endianReverse, memSpace); + CopyContiguousMemory(contiguousMemory, stride, dest + normalizedStart, endianReverse, + memSpace); return; } if (isRowMajor) // stored with C, C++, Python { - lf_ClipRowMajor(dest, destStart, destCount, contiguousMemory, blockBox, - intersectionBox, isRowMajor, reverseDimensions, - endianReverse, memSpace); + lf_ClipRowMajor(dest, destStart, destCount, contiguousMemory, blockBox, intersectionBox, + isRowMajor, reverseDimensions, endianReverse, memSpace); } else // stored with Fortran, R { - lf_ClipColumnMajor(dest, destStart, destCount, contiguousMemory, - blockBox, intersectionBox, isRowMajor, - reverseDimensions, endianReverse, memSpace); + lf_ClipColumnMajor(dest, destStart, destCount, contiguousMemory, blockBox, intersectionBox, + isRowMajor, reverseDimensions, endianReverse, memSpace); } } template void ClipContiguousMemory(T *dest, const Dims &destStart, const Dims &destCount, - const std::vector &contiguousMemory, - const Box &blockBox, - const Box &intersectionBox, - const bool isRowMajor, const bool reverseDimensions, - const bool endianReverse, const MemorySpace memSpace) + const std::vector &contiguousMemory, const Box &blockBox, + const Box &intersectionBox, const bool isRowMajor, + const bool reverseDimensions, const bool endianReverse, + const MemorySpace memSpace) { - ClipContiguousMemory(dest, destStart, destCount, contiguousMemory.data(), - blockBox, intersectionBox, isRowMajor, - reverseDimensions, endianReverse, memSpace); + ClipContiguousMemory(dest, destStart, destCount, contiguousMemory.data(), blockBox, + intersectionBox, isRowMajor, reverseDimensions, endianReverse, memSpace); } template @@ -681,8 +651,7 @@ void CopyContiguousMemory(const char *src, const size_t payloadStride, T *dest, } template -void Resize(std::vector &vec, const size_t dataSize, const std::string hint, - T value) +void Resize(std::vector &vec, const size_t dataSize, const std::string hint, T value) { try { @@ -692,10 +661,9 @@ void Resize(std::vector &vec, const size_t dataSize, const std::string hint, } catch (...) { - helper::ThrowNested( - "Helper", "adiosMemory", "Resize", - "buffer overflow when resizing to " + std::to_string(dataSize) + - " bytes, " + hint); + helper::ThrowNested("Helper", "adiosMemory", "Resize", + "buffer overflow when resizing to " + + std::to_string(dataSize) + " bytes, " + hint); } } @@ -710,11 +678,10 @@ void Resize(std::vector &vec, const size_t dataSize, const std::string hint, // functions) and copies to the output buffer in blocks. the memory address // calculation complexity for copying each block is minimized to O(1), which is // independent of the number of dimensions. -static inline void -NdCopyRecurDFSeqPadding(size_t curDim, const char *&inOvlpBase, - char *&outOvlpBase, CoreDims &inOvlpGapSize, - CoreDims &outOvlpGapSize, CoreDims &ovlpCount, - size_t &minContDim, size_t &blockSize) +static inline void NdCopyRecurDFSeqPadding(size_t curDim, const char *&inOvlpBase, + char *&outOvlpBase, CoreDims &inOvlpGapSize, + CoreDims &outOvlpGapSize, CoreDims &ovlpCount, + size_t &minContDim, size_t &blockSize) { // note: all elements in and below this node are contiguous on input and // output @@ -732,9 +699,8 @@ NdCopyRecurDFSeqPadding(size_t curDim, const char *&inOvlpBase, { for (size_t i = 0; i < ovlpCount[curDim]; i++) { - NdCopyRecurDFSeqPadding(curDim + 1, inOvlpBase, outOvlpBase, - inOvlpGapSize, outOvlpGapSize, ovlpCount, - minContDim, blockSize); + NdCopyRecurDFSeqPadding(curDim + 1, inOvlpBase, outOvlpBase, inOvlpGapSize, + outOvlpGapSize, ovlpCount, minContDim, blockSize); } // the gap between current node and the next needs to be padded so that // next contigous block starts at the correct position for both input @@ -754,12 +720,11 @@ NdCopyRecurDFSeqPadding(size_t curDim, const char *&inOvlpBase, // each element is minimized to average O(1), which is independent of // the number of dimensions. -static inline void -NdCopyRecurDFSeqPaddingRevEndian(size_t curDim, const char *&inOvlpBase, - char *&outOvlpBase, CoreDims &inOvlpGapSize, - CoreDims &outOvlpGapSize, CoreDims &ovlpCount, - size_t minCountDim, size_t blockSize, - size_t elmSize, size_t numElmsPerBlock) +static inline void NdCopyRecurDFSeqPaddingRevEndian(size_t curDim, const char *&inOvlpBase, + char *&outOvlpBase, CoreDims &inOvlpGapSize, + CoreDims &outOvlpGapSize, CoreDims &ovlpCount, + size_t minCountDim, size_t blockSize, + size_t elmSize, size_t numElmsPerBlock) { if (curDim == minCountDim) { @@ -780,10 +745,9 @@ NdCopyRecurDFSeqPaddingRevEndian(size_t curDim, const char *&inOvlpBase, { for (size_t i = 0; i < ovlpCount[curDim]; i++) { - NdCopyRecurDFSeqPaddingRevEndian( - curDim + 1, inOvlpBase, outOvlpBase, inOvlpGapSize, - outOvlpGapSize, ovlpCount, minCountDim, blockSize, elmSize, - numElmsPerBlock); + NdCopyRecurDFSeqPaddingRevEndian(curDim + 1, inOvlpBase, outOvlpBase, inOvlpGapSize, + outOvlpGapSize, ovlpCount, minCountDim, blockSize, + elmSize, numElmsPerBlock); } } inOvlpBase += inOvlpGapSize[curDim]; @@ -795,11 +759,10 @@ NdCopyRecurDFSeqPaddingRevEndian(size_t curDim, const char *&inOvlpBase, // used for buffer of Column major // the memory address calculation complexity for copying each element is // minimized to average O(1), which is independent of the number of dimensions. -static inline void -NdCopyRecurDFNonSeqDynamic(size_t curDim, const char *inBase, char *outBase, - CoreDims &inRltvOvlpSPos, CoreDims &outRltvOvlpSPos, - CoreDims &inStride, CoreDims &outStride, - CoreDims &ovlpCount, size_t elmSize) +static inline void NdCopyRecurDFNonSeqDynamic(size_t curDim, const char *inBase, char *outBase, + CoreDims &inRltvOvlpSPos, CoreDims &outRltvOvlpSPos, + CoreDims &inStride, CoreDims &outStride, + CoreDims &ovlpCount, size_t elmSize) { if (curDim == inStride.size()) { @@ -810,11 +773,9 @@ NdCopyRecurDFNonSeqDynamic(size_t curDim, const char *inBase, char *outBase, for (size_t i = 0; i < ovlpCount[curDim]; i++) { NdCopyRecurDFNonSeqDynamic( - curDim + 1, - inBase + (inRltvOvlpSPos[curDim] + i) * inStride[curDim], - outBase + (outRltvOvlpSPos[curDim] + i) * outStride[curDim], - inRltvOvlpSPos, outRltvOvlpSPos, inStride, outStride, ovlpCount, - elmSize); + curDim + 1, inBase + (inRltvOvlpSPos[curDim] + i) * inStride[curDim], + outBase + (outRltvOvlpSPos[curDim] + i) * outStride[curDim], inRltvOvlpSPos, + outRltvOvlpSPos, inStride, outStride, ovlpCount, elmSize); } } } @@ -825,10 +786,11 @@ NdCopyRecurDFNonSeqDynamic(size_t curDim, const char *inBase, char *outBase, // The memory address calculation complexity for copying each element is // minimized to average O(1), which is independent of the number of dimensions. -static inline void NdCopyRecurDFNonSeqDynamicRevEndian( - size_t curDim, const char *inBase, char *outBase, CoreDims &inRltvOvlpSPos, - CoreDims &outRltvOvlpSPos, CoreDims &inStride, CoreDims &outStride, - CoreDims &ovlpCount, size_t elmSize) +static inline void NdCopyRecurDFNonSeqDynamicRevEndian(size_t curDim, const char *inBase, + char *outBase, CoreDims &inRltvOvlpSPos, + CoreDims &outRltvOvlpSPos, + CoreDims &inStride, CoreDims &outStride, + CoreDims &ovlpCount, size_t elmSize) { if (curDim == inStride.size()) { @@ -842,19 +804,16 @@ static inline void NdCopyRecurDFNonSeqDynamicRevEndian( for (size_t i = 0; i < ovlpCount[curDim]; i++) { NdCopyRecurDFNonSeqDynamicRevEndian( - curDim + 1, - inBase + (inRltvOvlpSPos[curDim] + i) * inStride[curDim], - outBase + (outRltvOvlpSPos[curDim] + i) * outStride[curDim], - inRltvOvlpSPos, outRltvOvlpSPos, inStride, outStride, ovlpCount, - elmSize); + curDim + 1, inBase + (inRltvOvlpSPos[curDim] + i) * inStride[curDim], + outBase + (outRltvOvlpSPos[curDim] + i) * outStride[curDim], inRltvOvlpSPos, + outRltvOvlpSPos, inStride, outStride, ovlpCount, elmSize); } } } -static inline void -NdCopyIterDFSeqPadding(const char *&inOvlpBase, char *&outOvlpBase, - CoreDims &inOvlpGapSize, CoreDims &outOvlpGapSize, - CoreDims &ovlpCount, size_t minContDim, size_t blockSize) +static inline void NdCopyIterDFSeqPadding(const char *&inOvlpBase, char *&outOvlpBase, + CoreDims &inOvlpGapSize, CoreDims &outOvlpGapSize, + CoreDims &ovlpCount, size_t minContDim, size_t blockSize) { DimsArray pos(ovlpCount.size(), (size_t)0); size_t curDim = 0; @@ -882,10 +841,11 @@ NdCopyIterDFSeqPadding(const char *&inOvlpBase, char *&outOvlpBase, } } -static inline void NdCopyIterDFSeqPaddingRevEndian( - const char *&inOvlpBase, char *&outOvlpBase, CoreDims &inOvlpGapSize, - CoreDims &outOvlpGapSize, CoreDims &ovlpCount, size_t minContDim, - size_t blockSize, size_t elmSize, size_t numElmsPerBlock) +static inline void NdCopyIterDFSeqPaddingRevEndian(const char *&inOvlpBase, char *&outOvlpBase, + CoreDims &inOvlpGapSize, + CoreDims &outOvlpGapSize, CoreDims &ovlpCount, + size_t minContDim, size_t blockSize, + size_t elmSize, size_t numElmsPerBlock) { DimsArray pos(ovlpCount.size(), (size_t)0); size_t curDim = 0; @@ -918,11 +878,9 @@ static inline void NdCopyIterDFSeqPaddingRevEndian( } while (pos[curDim] == ovlpCount[curDim]); } } -static inline void NdCopyIterDFDynamic(const char *inBase, char *outBase, - CoreDims &inRltvOvlpSPos, - CoreDims &outRltvOvlpSPos, - CoreDims &inStride, CoreDims &outStride, - CoreDims &ovlpCount, size_t elmSize) +static inline void NdCopyIterDFDynamic(const char *inBase, char *outBase, CoreDims &inRltvOvlpSPos, + CoreDims &outRltvOvlpSPos, CoreDims &inStride, + CoreDims &outStride, CoreDims &ovlpCount, size_t elmSize) { size_t curDim = 0; DimsArray pos(ovlpCount.size() + 1, (size_t)0); @@ -935,11 +893,9 @@ static inline void NdCopyIterDFDynamic(const char *inBase, char *outBase, while (curDim != inStride.size()) { inAddr[curDim + 1] = - inAddr[curDim] + - (inRltvOvlpSPos[curDim] + pos[curDim]) * inStride[curDim]; + inAddr[curDim] + (inRltvOvlpSPos[curDim] + pos[curDim]) * inStride[curDim]; outAddr[curDim + 1] = - outAddr[curDim] + - (outRltvOvlpSPos[curDim] + pos[curDim]) * outStride[curDim]; + outAddr[curDim] + (outRltvOvlpSPos[curDim] + pos[curDim]) * outStride[curDim]; pos[curDim]++; curDim++; } @@ -956,10 +912,10 @@ static inline void NdCopyIterDFDynamic(const char *inBase, char *outBase, } } -static inline void NdCopyIterDFDynamicRevEndian( - const char *inBase, char *outBase, CoreDims &inRltvOvlpSPos, - CoreDims &outRltvOvlpSPos, CoreDims &inStride, CoreDims &outStride, - CoreDims &ovlpCount, size_t elmSize) +static inline void NdCopyIterDFDynamicRevEndian(const char *inBase, char *outBase, + CoreDims &inRltvOvlpSPos, CoreDims &outRltvOvlpSPos, + CoreDims &inStride, CoreDims &outStride, + CoreDims &ovlpCount, size_t elmSize) { size_t curDim = 0; DimsArray pos(ovlpCount.size() + 1, (size_t)0); @@ -972,11 +928,9 @@ static inline void NdCopyIterDFDynamicRevEndian( while (curDim != inStride.size()) { inAddr[curDim + 1] = - inAddr[curDim] + - (inRltvOvlpSPos[curDim] + pos[curDim]) * inStride[curDim]; + inAddr[curDim] + (inRltvOvlpSPos[curDim] + pos[curDim]) * inStride[curDim]; outAddr[curDim + 1] = - outAddr[curDim] + - (outRltvOvlpSPos[curDim] + pos[curDim]) * outStride[curDim]; + outAddr[curDim] + (outRltvOvlpSPos[curDim] + pos[curDim]) * outStride[curDim]; pos[curDim]++; curDim++; } @@ -999,8 +953,8 @@ static inline void NdCopyIterDFDynamicRevEndian( template size_t PayloadSize(const T * /*data*/, const Dims &count) noexcept { - const bool isZeros = std::all_of(count.begin(), count.end(), - [](const size_t i) { return i == 0; }); + const bool isZeros = + std::all_of(count.begin(), count.end(), [](const size_t i) { return i == 0; }); if (isZeros) { @@ -1011,8 +965,7 @@ size_t PayloadSize(const T * /*data*/, const Dims &count) noexcept } template <> -inline size_t PayloadSize(const std::string *data, - const Dims & /*count*/) noexcept +inline size_t PayloadSize(const std::string *data, const Dims & /*count*/) noexcept { return data->size() + 2; // 2 bytes for the string size } diff --git a/source/adios2/toolkit/format/bp/BPBase.tcc b/source/adios2/toolkit/format/bp/BPBase.tcc index 19b8a0d31c..fd73fc8d36 100644 --- a/source/adios2/toolkit/format/bp/BPBase.tcc +++ b/source/adios2/toolkit/format/bp/BPBase.tcc @@ -232,17 +232,17 @@ inline void BPBase::ParseCharacteristics(const std::vector &buffer, size_t #ifdef ADIOS2_HAVE_ENDIAN_REVERSE if (helper::IsLittleEndian() != isLittleEndian) { - helper::ReverseCopyFromBuffer(buffer, position, + helper::ReverseCopyFromBuffer(buffer.data(), position, characteristics.Statistics.Values.data(), size); } else { - helper::CopyFromBuffer(buffer, position, + helper::CopyFromBuffer(buffer.data(), position, characteristics.Statistics.Values.data(), size); } #else - helper::CopyFromBuffer(buffer, position, characteristics.Statistics.Values.data(), - size); + helper::CopyFromBuffer(buffer.data(), position, + characteristics.Statistics.Values.data(), size); #endif } break; diff --git a/source/adios2/toolkit/format/bp5/BP5Serializer.cpp b/source/adios2/toolkit/format/bp5/BP5Serializer.cpp index 2f618089dc..2030023d79 100644 --- a/source/adios2/toolkit/format/bp5/BP5Serializer.cpp +++ b/source/adios2/toolkit/format/bp5/BP5Serializer.cpp @@ -1567,13 +1567,13 @@ std::vector BP5Serializer::BreakoutContiguousMetadata( for (size_t Rank = 0; Rank < Counts.size(); Rank++) { uint64_t NMMBCount, MBCount, ABCount, DSCount, WDPCount; - helper::CopyFromBuffer(Aggregate, Position, &NMMBCount); + helper::CopyFromBuffer(Aggregate.data(), Position, &NMMBCount); for (uint64_t i = 0; i < NMMBCount; i++) { uint64_t IDLen; uint64_t InfoLen; - helper::CopyFromBuffer(Aggregate, Position, &IDLen); - helper::CopyFromBuffer(Aggregate, Position, &InfoLen); + helper::CopyFromBuffer(Aggregate.data(), Position, &IDLen); + helper::CopyFromBuffer(Aggregate.data(), Position, &InfoLen); uint64_t IDPosition = Position; uint64_t InfoPosition = Position + IDLen; Position = InfoPosition + InfoLen; @@ -1592,33 +1592,33 @@ std::vector BP5Serializer::BreakoutContiguousMetadata( UniqueMetaMetaBlocks.push_back(New); } } - helper::CopyFromBuffer(Aggregate, Position, &MBCount); + helper::CopyFromBuffer(Aggregate.data(), Position, &MBCount); for (uint64_t i = 0; i < MBCount; ++i) { uint64_t MEBSize; - helper::CopyFromBuffer(Aggregate, Position, &MEBSize); + helper::CopyFromBuffer(Aggregate.data(), Position, &MEBSize); MetadataBlocks.push_back({Aggregate.data() + Position, MEBSize}); Position += MEBSize; } - helper::CopyFromBuffer(Aggregate, Position, &ABCount); + helper::CopyFromBuffer(Aggregate.data(), Position, &ABCount); for (uint64_t i = 0; i < ABCount; ++i) { uint64_t AEBSize; - helper::CopyFromBuffer(Aggregate, Position, &AEBSize); + helper::CopyFromBuffer(Aggregate.data(), Position, &AEBSize); AttributeBlocks.push_back({Aggregate.data() + Position, AEBSize}); Position += AEBSize; } uint64_t element; - helper::CopyFromBuffer(Aggregate, Position, &DSCount); + helper::CopyFromBuffer(Aggregate.data(), Position, &DSCount); for (uint64_t i = 0; i < DSCount; ++i) { - helper::CopyFromBuffer(Aggregate, Position, &element); + helper::CopyFromBuffer(Aggregate.data(), Position, &element); DataSizes.push_back(element); } - helper::CopyFromBuffer(Aggregate, Position, &WDPCount); + helper::CopyFromBuffer(Aggregate.data(), Position, &WDPCount); for (uint64_t i = 0; i < WDPCount; ++i) { - helper::CopyFromBuffer(Aggregate, Position, &element); + helper::CopyFromBuffer(Aggregate.data(), Position, &element); WriterDataPositions.push_back(element); } } diff --git a/source/adios2/toolkit/format/buffer/heap/BufferMalloc.cpp b/source/adios2/toolkit/format/buffer/heap/BufferMalloc.cpp new file mode 100644 index 0000000000..f68a73ccd0 --- /dev/null +++ b/source/adios2/toolkit/format/buffer/heap/BufferMalloc.cpp @@ -0,0 +1,101 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * BufferMalloc.cpp + * + */ + +#include "BufferMalloc.h" +#include "BufferMalloc.tcc" +#include "adios2/helper/adiosLog.h" +#include "time.h" +#include +#include +#include + +namespace adios2 +{ +namespace format +{ + +BufferMalloc::BufferMalloc() : Buffer("BufferMalloc") {} +BufferMalloc::~BufferMalloc() +{ + if (m_size) + free(m_buffer); +} + +char *BufferMalloc::Data() noexcept { return (char *)m_buffer; } + +const char *BufferMalloc::Data() const noexcept { return (const char *)m_buffer; } + +void BufferMalloc::Resize(const size_t size, const std::string hint) +{ + if (size == 0) + return; + if (m_size == 0) + { + m_buffer = (char *)malloc(size); + if (m_buffer == NULL) + helper::ThrowNested( + "Toolkit::Format", "buffer::heap::BufferMalloc", "BufferSystemV", + "buffer overflow when resizing to " + std::to_string(size) + " bytes, " + hint); + } + else + { + char *tmp = (char *)realloc(m_buffer, size); + if (tmp == NULL) + helper::ThrowNested( + "Toolkit::Format", "buffer::heap::BufferMalloc", "BufferSystemV", + "buffer overflow when resizing to " + std::to_string(size) + " bytes, " + hint); + m_buffer = tmp; + } + m_size = size; +} + +void BufferMalloc::Reset(const bool resetAbsolutePosition, const bool zeroInitialize) +{ + m_Position = 0; + if (resetAbsolutePosition) + { + m_AbsolutePosition = 0; + } + if (zeroInitialize) + { + // std::fill(m_Buffer.begin(), m_Buffer.end(), 0); + } + else + { + // just zero out the first and last 1kb + const size_t bufsize = m_size; + size_t s = (bufsize < 1024 ? bufsize : 1024); + std::fill_n(m_buffer, s, 0); + if (bufsize > 1024) + { + size_t pos = bufsize - 1024; + if (pos < 1024) + { + pos = 1024; + } + s = bufsize - pos; + std::fill_n(m_buffer + bufsize - pos, s, 0); + } + } +} + +size_t BufferMalloc::GetAvailableSize() const { return m_size - m_Position; } + +void BufferMalloc::Delete() +{ + if (m_size) + free(m_buffer); + m_size = 0; +} + +size_t BufferMalloc::DebugGetSize() const { return m_size; }; + +size_t BufferMalloc::Size() const { return m_size; }; + +} // end namespace format +} // end namespace adios2 diff --git a/source/adios2/toolkit/format/buffer/heap/BufferMalloc.h b/source/adios2/toolkit/format/buffer/heap/BufferMalloc.h new file mode 100644 index 0000000000..0f64a786c1 --- /dev/null +++ b/source/adios2/toolkit/format/buffer/heap/BufferMalloc.h @@ -0,0 +1,52 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * BufferMalloc.h + * + */ + +#ifndef ADIOS2_TOOLKIT_FORMAT_BUFFER_HEAP_BUFFERMALLOC_H_ +#define ADIOS2_TOOLKIT_FORMAT_BUFFER_HEAP_BUFFERMALLOC_H_ + +#include "adios2/toolkit/format/buffer/Buffer.h" + +#include "adios2/common/ADIOSMacros.h" + +namespace adios2 +{ +namespace format +{ + +class BufferMalloc : public Buffer +{ +public: + BufferMalloc(); + ~BufferMalloc(); + + char *Data() noexcept final; + const char *Data() const noexcept final; + + void Resize(const size_t size, const std::string hint) final; + + void Reset(const bool resetAbsolutePosition, const bool zeroInitialize) final; + + size_t GetAvailableSize() const final; + + template + size_t Align() const noexcept; + + void Delete(); + + size_t DebugGetSize() const; + size_t Size() const; + +private: + size_t m_size = 0; + char *m_buffer = NULL; +}; + +} // end namespace format +} // end namespace adios2 + +#endif /* ADIOS2_TOOLKIT_FORMAT_BUFFER_HEAP_BUFFERMALLOC_H_ */ diff --git a/source/adios2/toolkit/format/buffer/heap/BufferMalloc.tcc b/source/adios2/toolkit/format/buffer/heap/BufferMalloc.tcc new file mode 100644 index 0000000000..c2cbf63fb2 --- /dev/null +++ b/source/adios2/toolkit/format/buffer/heap/BufferMalloc.tcc @@ -0,0 +1,54 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + * + * BufferMalloc.tcc + * + */ + +#ifndef ADIOS2_TOOLKIT_FORMAT_BUFFER_HEAP_BUFFERMALLOC_TCC_ +#define ADIOS2_TOOLKIT_FORMAT_BUFFER_HEAP_BUFFERMALLOC_TCC_ + +#include "BufferMalloc.h" + +#include + +#ifdef _WIN32 +#pragma warning(disable : 4146) // Windows complains about unsigned minus +#endif + +namespace adios2 +{ +namespace format +{ + +template +size_t BufferMalloc::Align() const noexcept +{ + // std::align implementation from llvm libc++ + // needed due to bug in gcc 4.8 + auto lf_align = [](const size_t alignment, const size_t size, void *&ptr, size_t &space) { + if (size <= space) + { + const char *p1 = static_cast(ptr); + const char *p2 = reinterpret_cast( + reinterpret_cast(p1 + (alignment - 1)) & -alignment); + const size_t d = static_cast(p2 - p1); + if (d <= space - size) + { + space -= d; + } + } + }; + + void *currentAddress = + reinterpret_cast(const_cast((char *)Data() + m_Position)); + size_t size = GetAvailableSize(); + lf_align(alignof(T), sizeof(T), currentAddress, size); + return GetAvailableSize() - size; +} + +} // end namespace format +} // end namespace adios2 + +#endif /* ADIOS2_TOOLKIT_FORMAT_BUFFER_HEAP_BUFFERMALLOC_TCC_ */