-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCLBuffer.hpp
190 lines (168 loc) · 4.15 KB
/
CLBuffer.hpp
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
137
138
139
140
141
142
143
144
145
146
147
148
149
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
#ifndef TCL_BUFFER_HPP
#define TCL_BUFFER_HPP
#ifdef __APPLE__
#include <OpenCL/opencl.h>
#else
#include <CL\cl.h>
#endif
#include <vector>
#include <array>
#include <mutex>
#include "CLInformation.hpp"
#include "CLExecute.hpp"
namespace tcl
{
/**
* デバイス側メモリ領域のラッパークラス
*/
class CLBuffer
{
private:
cl_mem memory;
size_t size;
void* hostDataPtr;
public:
/**
* 確保した容量を取得
* \return 確保した容量
*/
inline const size_t Size() const {
return size;
}
/**
* 確保したメモリオブジェクトを取得
* \return 確保したメモリオブジェクト
*/
inline cl_mem& Memory() {
return memory;
}
private:
/**
* コピー禁止
*/
CLBuffer(const CLBuffer& copy) { }
template <typename T>
void SizeTest(const size_t& size) const
{
auto argSize = size * sizeof(T);
if (this->size < argSize)
{
throw CLFailedAllacException("バッファのサイズよりホスト側のサイズの方が大きい");
}
}
void ResultTest(const cl_int result) const
{
if (result != CL_SUCCESS)
{
throw CLException("WriteかReadに失敗しました", result);
}
}
void ReadTest(const cl_uint result) const
{
if (result != CL_SUCCESS)
{
switch (result)
{
case CL_INVALID_COMMAND_QUEUE:
throw CLException("コマンドキューが無効です");
case CL_INVALID_CONTEXT:
throw CLException("コンテクストが無効です");
case CL_INVALID_MEM_OBJECT:
throw CLException("バッファオブジェクトが無効です");
case CL_INVALID_VALUE:
throw CLException("指定した読み込み領域が範囲外です");
case CL_INVALID_EVENT_WAIT_LIST:
throw CLException("イベント待ちリストが無効です");
case CL_MISALIGNED_SUB_BUFFER_OFFSET:
throw CLException("サブバッファのオフセットがアラインメントされていません");
case CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST:
throw CLException("読み込みコマンドがブロッキングがどうの");
case CL_MEM_OBJECT_ALLOCATION_FAILURE:
throw CLException("バッファと関連付けられたデータ保存領域へのメモリ確保に失敗した");
case CL_OUT_OF_RESOURCES:
throw CLException("デバイス側のリソースの確保に失敗した");
case CL_OUT_OF_HOST_MEMORY:
throw CLException("ホスト側のリソースの確保に失敗した");
}
}
}
void SafeEnqueueRead(const cl_command_queue& command)
{
auto result = clEnqueueReadBuffer(
command, memory, CL_TRUE,
0, size, hostDataPtr,
0, NULL, NULL);
ReadTest(result);
}
void SafeEnqueueWrite(const cl_command_queue& command)
{
auto result = clEnqueueWriteBuffer(
command, memory, CL_TRUE,
0, size, hostDataPtr,
0, NULL, NULL);
ResultTest(result);
}
cl_mem CreateBuffer(const cl_mem_flags& flag)
{
return clCreateBuffer(information.context, flag, size, NULL, &information.result);
}
protected:
/**
* 生で扱うのは危険なのでデフォルトコンストラクタは禁止
*/
CLBuffer()
: size(0) {}
//template <typename T>
//CLBuffer(const cl_mem_flags flag, const size_t& size, void* hostPtr, T* hostDataPtr)
// : size(size), hostDataPtr(hostDataPtr)
//{
// memory = clCreateBuffer(information.context, flag, size, hostPtr, &information.result);
//}
template <typename T>
CLBuffer(const cl_mem_flags& flag, std::vector<T>& data)
: size(data.size() * sizeof(T)), hostDataPtr(&data[0])
{
memory = CreateBuffer(flag);
}
template <typename T, size_t NUM>
CLBuffer(const cl_mem_flags& flag, std::array<T, NUM>& data)
: size(data.size() * sizeof(T)), hostDataPtr(&data[0])
{
memory = CreateBuffer(flag);
}
template <typename T>
CLBuffer(const cl_mem_flags& flag, T& data)
: size(sizeof(T)), hostDataPtr(&data)
{
memory = CreateBuffer(flag);
}
template <typename T>
CLBuffer(const cl_mem_flags& flag, T* data, const size_t& num)
: size(sizeof(T) * num), hostDataPtr(data)
{
memory = CreateBuffer(flag);
}
public:
virtual ~CLBuffer()
{
clReleaseMemObject(memory);
}
/**
* ホスト側からデバイス側に転送
*/
CLBuffer& Write(const cl_command_queue& command)
{
SafeEnqueueWrite(command);
return *this;
}
/**
* デバイス側からホスト側に転送
*/
CLBuffer& Read(const cl_command_queue& command)
{
SafeEnqueueRead(command);
return *this;
}
};
}
#endif