OpenMPCD
DeviceMemoryManager.cpp
2 
6 
7 #include <iostream>
8 #include <sstream>
9 
10 using namespace OpenMPCD::CUDA;
11 
13  : autofree(false)
14 {
15 }
16 
18 {
19  if(allocatedBuffers.empty())
20  return;
21 
22  if(autofree)
23  {
24  for(std::set<const void*>::const_iterator it=allocatedBuffers.begin(); it!=allocatedBuffers.end(); ++it)
25  cudaFree(const_cast<void*>(*it));
26 
27  return;
28  }
29 
30  std::stringstream message;
31 
32  message<<"Unfreed Device memory:";
33 
34  for(std::set<const void*>::const_iterator it=allocatedBuffers.begin(); it!=allocatedBuffers.end(); ++it)
35  message<<" "<<(*it);
36 
37  std::cerr<<message.str()<<"\n";
38 }
39 
40 void DeviceMemoryManager::freeMemory(void* const pointer)
41 {
42  if(pointer == NULL)
43  return;
44 
45  if(allocatedBuffers.count(pointer)==0)
46  OPENMPCD_THROW(MemoryManagementException, "Tried to free invalid pointer.");
47 
48  allocatedBuffers.erase(pointer);
49 
50  freeMemoryUnregistered(pointer);
51 }
52 
54 {
55  if(pointer == NULL)
56  return;
57 
58  #ifdef OPENMPCD_DEBUG
59  if(!isDeviceMemoryPointer(pointer))
60  OPENMPCD_THROW(MemoryManagementException, "not a Device pointer");
61 
62  if(cudaPeekAtLastError() != cudaSuccess)
63  {
64  std::stringstream message;
65  message <<
66  "Failure detected in "
67  "CUDA::DeviceMemoryManager::freeMemoryUnregistered before the "
68  "call to cudaFree:\n";
69  message << cudaGetErrorString(cudaPeekAtLastError()) << "\n";
70 
71  std::cerr << message.str();
72 
73  OPENMPCD_THROW(Exception, message.str());
74  }
75  #endif
76 
77  cudaFree(pointer);
79 }
80 
81 bool DeviceMemoryManager::isDeviceMemoryPointer(const void* const ptr)
82 {
83  cudaPointerAttributes attributes;
84  cudaPointerGetAttributes(&attributes, ptr);
85 
86  switch(cudaGetLastError())
87  {
88  case cudaSuccess:
89  break;
90 
91  case cudaErrorInvalidDevice:
93  break;
94 
95  case cudaErrorInvalidValue:
96  return false;
97 
98  default:
100  }
101 
102  return attributes.memoryType == cudaMemoryTypeDevice;
103 }
104 
105 bool DeviceMemoryManager::isHostMemoryPointer(const void* const ptr)
106 {
107  if(!ptr)
108  return false;
109 
110  return !isDeviceMemoryPointer(ptr);
111 }
112 
113 void* DeviceMemoryManager::allocateMemoryInternal(const std::size_t bufferSize)
114 {
115  if(bufferSize==0)
116  return NULL;
117 
118  void* const pointer = allocateMemoryInternalUnregistered(bufferSize);
119 
120  #ifdef OPENMPCD_DEBUG
121  if(allocatedBuffers.count(pointer) != 0)
122  {
125  "cudaMalloc succeeded, but yielded a used address.");
126  }
127  #endif
128 
129  allocatedBuffers.insert(pointer);
130 
131  return pointer;
132 }
133 
134 void* DeviceMemoryManager::allocateMemoryInternalUnregistered(
135  const std::size_t bufferSize)
136 {
137  if(bufferSize==0)
138  return NULL;
139 
140  void* pointer=NULL;
141  const cudaError_t result = cudaMalloc(&pointer, bufferSize);
142 
143  if(result!=cudaSuccess)
144  {
145  std::stringstream message;
146  message<<"cudaMalloc failed when trying to allocate ";
147  message<<bufferSize<<" bytes. Error code: "<<result;
148  message<<". Error message: "<<cudaGetErrorString(result);
149 
150  cudaGetLastError(); //reset last error to cudaSuccess
151 
152  OPENMPCD_THROW(MemoryManagementException, message.str());
153  }
154 
155  #ifdef OPENMPCD_DEBUG
156  if(pointer == NULL)
157  {
159  MemoryManagementException,
160  "cudaMalloc succeeded, but yielded NULL pointer.");
161  }
162  #endif
163 
164  return pointer;
165 }
OPENMPCD_CUDA_THROW_ON_ERROR
#define OPENMPCD_CUDA_THROW_ON_ERROR
Throws if the last CUDA call was not successful.
Definition: Macros.hpp:96
Exceptions.hpp
OPENMPCD_THROW
#define OPENMPCD_THROW(ExceptionType, message)
Throws the given ExceptionType, passing the given message along with file and line number information...
Definition: Exceptions.hpp:22
OpenMPCD::CUDA::Exception
Base CUDA exception.
Definition: CUDA/Exceptions.hpp:18
OpenMPCD::CUDA::DeviceMemoryManager::isDeviceMemoryPointer
static bool isDeviceMemoryPointer(const void *const ptr)
Returns whether the given pointer is a pointer to CUDA Device memory.
Definition: DeviceMemoryManager.cpp:81
OpenMPCD::MemoryManagementException
Exception for errors in memory management.
Definition: Exceptions.hpp:208
OpenMPCD::CUDA
Namespace for simulations using CUDA.
Definition: Bitset.hpp:15
OpenMPCD::CUDA::DeviceMemoryManager::DeviceMemoryManager
DeviceMemoryManager()
The constructor.
Definition: DeviceMemoryManager.cpp:12
OpenMPCD::CUDA::DeviceMemoryManager::~DeviceMemoryManager
~DeviceMemoryManager()
The destructor.
Definition: DeviceMemoryManager.cpp:17
DeviceMemoryManager.hpp
OpenMPCD::CUDA::DeviceMemoryManager::isHostMemoryPointer
static bool isHostMemoryPointer(const void *const ptr)
Returns whether the given pointer is a pointer to Host memory.
Definition: DeviceMemoryManager.cpp:105
OpenMPCD::CUDA::DeviceMemoryManager::freeMemoryUnregistered
static void freeMemoryUnregistered(void *const pointer)
Frees the Device memory pointed to by the given pointer.
Definition: DeviceMemoryManager.cpp:53
OpenMPCD::CUDA::DeviceMemoryManager::freeMemory
void freeMemory(void *const pointer)
Frees the Device memory pointed to by the given pointer.
Definition: DeviceMemoryManager.cpp:40
Macros.hpp
runtime.hpp