Newer
Older
#include <cstddef>
#include <cuda_runtime.h>
#include "CudaMemory.cuh"
#include "cuda_macro.h"

Pietro Incardona
committed
#include <cstring>
/*! \brief Allocate a chunk of memory
*
* Allocate a chunk of memory
*
* \param sz size of the chunk of memory to allocate in byte
*
*/
bool CudaMemory::allocate(size_t sz)
{
//! Allocate the device memory
if (dm == NULL)

Pietro Incardona
committed
{CUDA_SAFE_CALL(cudaMalloc(&dm,sz));}
this->sz = sz;
return true;
}
/*! \brief destroy a chunk of memory
*
* Destroy a chunk of memory
*
*/
void CudaMemory::destroy()
{

Pietro Incardona
committed
CUDA_SAFE_CALL(cudaFree(dm));

Pietro Incardona
committed
/*! \brief Allocate the host buffer

Pietro Incardona
committed
* Allocate the host buffer

Pietro Incardona
committed
void CudaMemory::allocate_host(size_t sz)
{
if (hm == NULL)
{CUDA_SAFE_CALL(cudaHostAlloc(&hm,sz,cudaHostAllocMapped))}
}
/*! \brief copy the data from a pointer
*
* copy the data from a pointer
*
* \param ptr
* \return true if success
*/
bool CudaMemory::copyFromPointer(void * ptr)
{
// check if we have a host buffer, if not allocate it

Pietro Incardona
committed
allocate_host(sz);
// get the device pointer

Pietro Incardona
committed
void * dvp;
CUDA_SAFE_CALL(cudaHostGetDevicePointer(&dvp,hm,0));

Pietro Incardona
committed
// memory copy

Pietro Incardona
committed
memcpy(ptr,dvp,sz);
return true;

Pietro Incardona
committed
/*! \brief copy from device to device
*
* copy a piece of memory from device to device
*
* \param CudaMemory from where to copy
*
* \return true is success
*/
bool CudaMemory::copyDeviceToDevice(CudaMemory & m)

Pietro Incardona
committed
//! The source buffer is too big to copy it
if (m.sz > sz)
{
std::cerr << "Error " << __LINE__ << __FILE__ << ": source buffer is too big to copy";
return false;
}

Pietro Incardona
committed
//! Copy the memory
CUDA_SAFE_CALL(cudaMemcpy(m.dm,dm,m.sz,cudaMemcpyDeviceToDevice));
return true;

Pietro Incardona
committed
/*! \brief copy from memory
*
* copy from memory
*
* \param m a memory interface
*
*/
bool CudaMemory::copy(memory & m)
{
//! Here we try to cast memory into OpenFPMwdeviceCudaMemory

Pietro Incardona
committed
CudaMemory * ofpm = dynamic_cast<CudaMemory *>(&m);
//! if we fail we get the pointer and simply copy from the pointer
if (ofpm == NULL)
{
// copy the memory from device to host and from host to device

Pietro Incardona
committed
return copyFromPointer(m.getPointer());
}
else
{
// they are the same memory type, use cuda/thrust buffer copy

Pietro Incardona
committed
return copyDeviceToDevice(*ofpm);

Pietro Incardona
committed
/*! \brief Get the size of the allocated memory
*
* Get the size of the allocated memory
*
* \return the size of the allocated memory
*
*/

Pietro Incardona
committed
return sz;

Pietro Incardona
committed
/*! \brief Resize the allocated memory
*
* Resize the allocated memory, if request is smaller than the allocated memory
* is not resized
*
* \param sz size
* \return true if the resize operation complete correctly
*
*/
bool CudaMemory::resize(size_t sz)
{

Pietro Incardona
committed
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
//! Allocate the device memory if not done yet
if (size() == 0)
return allocate(sz);
//! Create a new buffer if sz is bigger than the actual size
void * tdm;
if (this->sz < sz)
CUDA_SAFE_CALL(cudaMalloc(&tdm,sz));
//! copy from the old buffer to the new one
CUDA_SAFE_CALL(cudaMemcpy(dm,tdm,size(),cudaMemcpyDeviceToDevice));
//! free the old buffer
destroy();
//! change to the new buffer
dm = tdm;
this->sz = sz;
return true;
}
/*! \brief Return a readable pointer with your data
*
* Return a readable pointer with your data
*
*/
void * CudaMemory::getPointer()
{
//! if the host buffer is synchronized with the device buffer return the host buffer
if (is_hm_sync)
return hm;
//! we have to synchronize
//| allocate an host mempory
if (hm == NULL)
allocate_host(sz);
//! copy from device to host memory
CUDA_SAFE_CALL(cudaMemcpy(dm,hm,sz,cudaMemcpyDeviceToHost));
return hm;