Repository navigation
Expand file tree
/
Copy pathgpuHelper.h
More file actions
136 lines (121 loc) · 3.55 KB
/
Copy pathgpuHelper.h
File metadata and controls
136 lines (121 loc) · 3.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#ifndef GPUHELPER_H_
#define GPUHELPER_H_
#include <stdio.h>
#include <stdexcept>
#include <algorithm>
#include <cuda_runtime.h>
template <class T>
class gpuHelper
{
// public functions
public:
explicit gpuHelper() : begin(0), end(0)
{}
// Constructor
explicit gpuHelper(size_t size, char memoryType)
{
if(memoryType == 'M') // M => cudaMallocHost
{
// Allcoate memory with cudaMallocHost
allocate(size);
}
else if (memoryType == 'P') // P => Pinned-Memory
{
allocatePinnedMemory(size);
}
else if (memoryType == 'Z') // Z => Zero-Copy
{
allocateZeroCopyMemory(size);
}
}
// Destructor
~gpuHelper()
{
free();
}
// get the size of the array
size_t getSize() const
{
return end - begin;
}
// get data
const T* getData() const
{
return begin;
}
T* getData()
{
return begin;
}
/*
* See cuda error types: https://docs.nvidia.com/cuda/cuda-runtime-api/group__CUDART__TYPES.html
* under "enum cudaError"
* Or see here: http://developer.download.nvidia.com/compute/cuda/3_1/toolkit/docs/online/group__CUDART__TYPES_g3f51e3575c2178246db0a94a430e0038.html
*
*/
// set
void set(const T* src, size_t size)
{
size_t min = std::min(size, getSize());
cudaError_t cudaResult = cudaMemcpy(begin, src, min * sizeof(T), cudaMemcpyHostToDevice);
cudaError_t cudaLastError = cudaGetLastError();
handleCudaResult(cudaResult, cudaLastError);
}
// get
void get(T* dest, size_t size)
{
size_t min = std::min(size, getSize());
cudaError_t cudaResult = cudaMemcpy(dest, begin, min * sizeof(T), cudaMemcpyDeviceToHost);
cudaError_t cudaLastError = cudaGetLastError();
handleCudaResult(cudaResult, cudaLastError);
}
// handle cuda result
void handleCudaResult(cudaError_t result, cudaError_t lastError)
{
if(result != cudaSuccess)
{
printf("\nCuda error string: %s\n", cudaGetErrorString(result));
printf("Cuda last error string: %s\n", cudaGetErrorString(lastError));
throw std::runtime_error("Cuda error");
}
}
// private functions
private:
// allocate memory on the device
void allocate(size_t size)
{
cudaError_t cudaResult = cudaMallocHost((void**)&begin, size * sizeof(T));
cudaError_t cudaLastError = cudaGetLastError();
handleCudaResult(cudaResult, cudaLastError);
end = begin + size;
}
// allocate pinned memory on the device
void allocatePinnedMemory(size_t size)
{
cudaError_t cudaResult = cudaHostAlloc( (void**)&begin, size * sizeof(T), cudaHostAllocDefault );
cudaError_t cudaLastError = cudaGetLastError();
handleCudaResult(cudaResult, cudaLastError);
end = begin + size;
}
// allocate pinned memory on the device
void allocateZeroCopyMemory(size_t size)
{
cudaError_t cudaResult = cudaHostAlloc( (void**)&begin, size * sizeof(T), cudaHostAllocWriteCombined | cudaHostAllocMapped );
cudaError_t cudaLastError = cudaGetLastError();
handleCudaResult(cudaResult, cudaLastError);
end = begin + size;
}
// free memory on the device
void free()
{
if (begin != 0)
{
cudaFree(begin);
cudaFreeHost(begin);
begin = end = 0;
}
}
T* begin;
T* end;
};
#endif