1 #ifndef HeterogeneousCore_AlpakaInterface_interface_CachingAllocator_h 2 #define HeterogeneousCore_AlpakaInterface_interface_CachingAllocator_h 14 #include <type_traits> 16 #include <alpaka/alpaka.hpp> 29 unsigned int power = 1;
44 }
else if (
value >= (1ul << 40) and
value % (1ul << 40) == 0) {
46 }
else if (
value >= (1ul << 30) and
value % (1ul << 30) == 0) {
48 }
else if (
value >= (1ul << 20) and
value % (1ul << 20) == 0) {
50 }
else if (
value >= (1ul << 10) and
value % (1ul << 10) == 0) {
88 template <
typename TDev,
typename TQueue>
91 #ifdef ALPAKA_ACC_GPU_CUDA_ENABLED 92 friend class alpaka_cuda_async::AlpakaService;
94 #ifdef ALPAKA_ACC_GPU_HIP_ENABLED 95 friend class alpaka_rocm_async::AlpakaService;
97 #ifdef ALPAKA_ACC_CPU_B_SEQ_T_SEQ_ENABLED 98 friend class alpaka_serial_sync::AlpakaService;
100 #ifdef ALPAKA_ACC_CPU_B_TBB_T_SEQ_ENABLED 101 friend class alpaka_tbb_async::AlpakaService;
107 using Buffer = alpaka::Buf<Device, std::byte, alpaka::DimInt<1u>,
size_t>;
110 static_assert(alpaka::isDevice<Device>,
"TDev should be an alpaka Device type.");
111 static_assert(alpaka::isQueue<Queue>,
"TQueue should be an alpaka Queue type.");
112 static_assert(std::is_same_v<
Device, alpaka::Dev<Queue>>
or std::is_same_v<Device, alpaka::DevCpu>,
113 "The \"memory device\" type can either be the same as the \"synchronisation device\" type, or be the " 125 bool reuseSameQueueAllocations,
148 std::ostringstream
out;
149 out <<
"CachingAllocator settings\n" 151 <<
" min bin " <<
minBin_ <<
"\n" 152 <<
" max bin " <<
maxBin_ <<
"\n" 153 <<
" resulting bins:\n";
190 std::memset(
buffer.data(),
value, alpaka::getExtentProduct(
buffer) *
sizeof(alpaka::Elem<Buffer>));
201 block.requested = bytes;
220 return block.buffer->data();
229 std::stringstream
ss;
230 ss <<
"Trying to free a non-live block at " << ptr;
231 throw std::runtime_error(
ss.str());
256 alpaka::enqueue(*(
block.queue), *(
block.event));
259 std::ostringstream
out;
260 out <<
"CachingAllocator::free() caught an alpaka error: " <<
e.what() <<
"\n";
262 << ptr <<
" from associated queue " <<
block.queue->m_spQueueImpl.get() <<
", event " 265 <<
" live blocks (" <<
cachedBytes_.
live <<
" bytes) outstanding." << std::endl;
276 std::ostringstream
out;
278 << ptr <<
" from associated queue " <<
block.queue->m_spQueueImpl.get() <<
" , event " 279 <<
block.event->m_spEventImpl.get() <<
" .\n\t\t " <<
cachedBlocks_.size() <<
" available blocks cached (" 281 <<
" bytes) outstanding." << std::endl;
298 std::ostringstream
out;
299 out <<
"CachingAllocator::free() caught an alpaka error: " <<
e.what() <<
"\n";
301 << ptr <<
" from associated queue " <<
block.queue->m_spQueueImpl.get() <<
", event " 304 <<
" live blocks (" <<
cachedBytes_.
live <<
" bytes) outstanding." << std::endl;
311 std::ostringstream
out;
313 << ptr <<
" from associated queue " <<
block.queue->m_spQueueImpl.get() <<
", event " 314 <<
block.event->m_spEventImpl.get() <<
" .\n\t\t " <<
cachedBlocks_.size() <<
" available blocks cached (" 316 <<
" bytes) outstanding." << std::endl;
339 size_t totalMemory = alpaka::getMemBytes(
device_);
345 if (memoryFraction > 0 and memoryFraction <
size) {
346 size = memoryFraction;
352 std::tuple<unsigned int, size_t>
findBin(
size_t bytes)
const {
357 throw std::runtime_error(
"Requested allocation size " +
std::to_string(bytes) +
358 " bytes is too large for the caching detail with maximum bin " +
360 " bytes. You might want to increase the maximum bin size");
364 while (binBytes < bytes) {
368 return std::make_tuple(
bin, binBytes);
376 for (
auto iBlock = begin; iBlock != end; ++iBlock) {
378 alpaka::isComplete(*(iBlock->second.event))) {
382 block = iBlock->second;
386 if (
block.device() != alpaka::getDev(*(
block.event))) {
400 std::ostringstream
out;
402 <<
block.buffer->data() <<
" (" <<
block.bytes <<
" bytes) for queue " 403 <<
block.queue->m_spQueueImpl.get() <<
", event " <<
block.event->m_spEventImpl.get()
404 <<
" (previously associated with queue " << iBlock->second.queue->m_spQueueImpl.get() <<
" , event " 405 << iBlock->second.event->m_spEventImpl.get() <<
")." << std::endl;
421 return alpaka::allocBuf<std::byte, size_t>(
device_, bytes);
422 }
else if constexpr (std::is_same_v<Device, alpaka::DevCpu>) {
424 using Platform = alpaka::Platform<alpaka::Dev<Queue>>;
425 return alpaka::allocMappedBuf<Platform, std::byte, size_t>(
device_, platform<Platform>(), bytes);
428 static_assert(std::is_same_v<
Device, alpaka::Dev<Queue>>
or std::is_same_v<Device, alpaka::DevCpu>,
429 "The \"memory device\" type can either be the same as the \"synchronisation device\" type, or be " 437 }
catch (std::runtime_error
const&
e) {
440 std::ostringstream
out;
442 <<
" bytes for queue " <<
block.queue->m_spQueueImpl.get()
443 <<
", retrying after freeing cached allocations" << std::endl;
465 std::ostringstream
out;
467 <<
block.buffer->data() <<
" (" <<
block.bytes <<
" bytes associated with queue " 468 <<
block.queue->m_spQueueImpl.get() <<
", event " <<
block.event->m_spEventImpl.get() <<
"." << std::endl;
481 std::ostringstream
out;
530 #endif // HeterogeneousCore_AlpakaInterface_interface_CachingAllocator_h
constexpr unsigned int maxBin
constexpr size_t maxCachedBytes
static std::string to_string(const XMLCh *ch)
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
std::string getName(const G4String &)
constexpr unsigned int binGrowth
constexpr unsigned int minBin
constexpr double maxCachedFraction