File indexing completed on 2025-01-18 09:12:17
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include "Acts/Plugins/Cuda/Utilities/MemoryManager.hpp"
0011
0012 #include "ErrorCheck.cuh"
0013
0014
0015 #include <cuda_runtime.h>
0016
0017
0018 #include <cmath>
0019 #include <stdexcept>
0020
0021 namespace Acts {
0022 namespace Cuda {
0023
0024 MemoryManager::~MemoryManager() {
0025
0026 for (DeviceMemory& mem : m_memory) {
0027 if (mem.m_ptr == nullptr) {
0028 continue;
0029 }
0030 ACTS_CUDA_ERROR_CHECK(cudaFree(mem.m_ptr));
0031 }
0032 }
0033
0034 MemoryManager& MemoryManager::instance() {
0035 static MemoryManager mm;
0036 return mm;
0037 }
0038
0039 void MemoryManager::setMemorySize(std::size_t sizeInBytes, int device) {
0040
0041
0042 if (device == -1) {
0043 ACTS_CUDA_ERROR_CHECK(cudaGetDevice(&device));
0044 }
0045
0046
0047 if (static_cast<std::size_t>(device) >= m_memory.size()) {
0048 m_memory.resize(device + 1);
0049 }
0050
0051
0052 DeviceMemory& mem = m_memory[device];
0053
0054
0055 if (mem.m_ptr) {
0056 ACTS_CUDA_ERROR_CHECK(cudaFree(mem.m_ptr));
0057 }
0058
0059
0060 ACTS_CUDA_ERROR_CHECK(cudaSetDevice(device));
0061 ACTS_CUDA_ERROR_CHECK(cudaMalloc(&(mem.m_ptr), sizeInBytes));
0062
0063
0064 mem.m_size = sizeInBytes;
0065 mem.m_nextAllocation = mem.m_ptr;
0066 return;
0067 }
0068
0069 std::size_t MemoryManager::availableMemory(int device) const {
0070
0071
0072 if (device == -1) {
0073 ACTS_CUDA_ERROR_CHECK(cudaGetDevice(&device));
0074 }
0075
0076
0077 if (m_memory.size() <= static_cast<std::size_t>(device)) {
0078 throw std::bad_alloc();
0079 }
0080 const DeviceMemory& mem = m_memory[device];
0081
0082
0083 return (mem.m_size - (mem.m_nextAllocation - mem.m_ptr));
0084 }
0085
0086 void* MemoryManager::allocate(std::size_t sizeInBytes, int device) {
0087
0088
0089 if (device == -1) {
0090 ACTS_CUDA_ERROR_CHECK(cudaGetDevice(&device));
0091 }
0092
0093
0094 if (m_memory.size() <= static_cast<std::size_t>(device)) {
0095 throw std::bad_alloc();
0096 }
0097 DeviceMemory& mem = m_memory[device];
0098
0099
0100 void* result = mem.m_nextAllocation;
0101
0102
0103 static constexpr std::size_t ALIGN_SIZE = 8;
0104 const std::size_t misalignment = sizeInBytes % ALIGN_SIZE;
0105 const std::size_t padding =
0106 ((misalignment != 0) ? (ALIGN_SIZE - misalignment) : 0);
0107
0108
0109 mem.m_nextAllocation += sizeInBytes + padding;
0110
0111 if (mem.m_nextAllocation - mem.m_ptr >= mem.m_size) {
0112 throw std::bad_alloc();
0113 }
0114
0115
0116 return result;
0117 }
0118
0119 void MemoryManager::reset(int device) {
0120
0121
0122 if (device == -1) {
0123 ACTS_CUDA_ERROR_CHECK(cudaGetDevice(&device));
0124 }
0125
0126
0127 if (m_memory.size() <= static_cast<std::size_t>(device)) {
0128 throw std::bad_alloc();
0129 }
0130 DeviceMemory& mem = m_memory[device];
0131
0132
0133 mem.m_maxUsage = std::max(mem.m_maxUsage, mem.m_nextAllocation - mem.m_ptr);
0134
0135 mem.m_nextAllocation = mem.m_ptr;
0136 return;
0137 }
0138
0139 MemoryManager::MemoryManager() {
0140
0141 setMemorySize(1500 * 1024l * 1024l);
0142 }
0143
0144 }
0145 }