SkePU  1.2
 All Classes Namespaces Files Functions Variables Enumerations Friends Macros Groups Pages
device_mem_pointer_cl.h
Go to the documentation of this file.
1 
5 #ifndef DEVICE_MEM_POINTER_CL_H
6 #define DEVICE_MEM_POINTER_CL_H
7 
8 #ifdef SKEPU_OPENCL
9 
10 #include <iostream>
11 #ifdef USE_MAC_OPENCL
12 #include <OpenCL/opencl.h>
13 #else
14 #include <CL/cl.h>
15 #endif
16 
17 #include <skepu/src/environment.h>
18 
19 #include "device_cl.h"
20 
21 
22 namespace skepu
23 {
24 
37 template <typename T>
39 {
40 
41 public:
42  DeviceMemPointer_CL(T* root, T* start, int numElements, Device_CL* device);
43  DeviceMemPointer_CL(T* start, int numElements, Device_CL* device);
45 
46  void copyHostToDevice(int numElements = -1, bool copyLast=false) const;
47  void copyDeviceToHost(int numElements = -1, bool copyLast=false) const;
48 
49  void copyDeviceToDevice(cl_mem copyToPointer,int numElements, int dstOffset = 0, int srcOffset = 0) const;
50 
51  cl_mem getDeviceDataPointer() const;
52  void changeDeviceData();
53 
54  // marks first initialization, useful when want to separate actual OpenCL allocation and memory copy (HTD) such as when using mulit-GPU OpenCL.
55  mutable bool m_initialized;
56 
57 private:
58  void copyHostToDevice_internal(T* src, cl_mem dest, int numElements, int offset=0) const;
59 
60  T* m_rootHostDataPointer;
61  T* m_effectiveHostDataPointer;
62  T* m_hostDataPointer;
63 
64 
65  int m_effectiveNumElements;
66 
67  cl_mem m_deviceDataPointer;
68  cl_mem m_effectiveDeviceDataPointer;
69 
70  int m_numElements;
71  Device_CL* m_device;
72 
73  mutable bool deviceDataHasChanged;
74 };
75 
84 template <typename T>
85 DeviceMemPointer_CL<T>::DeviceMemPointer_CL(T* start, int numElements, Device_CL* device) : m_effectiveHostDataPointer(start), m_hostDataPointer(start), m_numElements(numElements), m_effectiveNumElements(numElements), m_device(device), m_initialized(false)
86 {
87  cl_int err;
88  size_t sizeVec = numElements*sizeof(T);
89 
90  DEBUG_TEXT_LEVEL1("Alloc: " <<numElements <<"\n")
91 #ifdef SKEPU_MEASURE_TIME_DISTRIBUTION
92 
93 #ifdef SKEPU_MEASURE_ONLY_COPY
94  clFinish(m_device->getQueue());
95 #endif
96 
97  devMemAllocTimer.start();
98 #endif
99 
100  m_deviceDataPointer = clCreateBuffer(m_device->getContext(), CL_MEM_READ_WRITE, sizeVec, NULL, &err);
101  if(err != CL_SUCCESS)
102  {
103  SKEPU_ERROR("Error allocating memory on device. size: " << sizeVec << "\n");
104  }
105 
106  m_effectiveDeviceDataPointer = m_deviceDataPointer;
107 
108 #ifdef SKEPU_MEASURE_TIME_DISTRIBUTION
109 
110 #ifdef SKEPU_MEASURE_ONLY_COPY
111  clFinish(m_device->getQueue());
112 #endif
113 
114  devMemAllocTimer.stop();
115 #endif
116  deviceDataHasChanged = false;
117 }
118 
119 
120 
130 template <typename T>
131 DeviceMemPointer_CL<T>::DeviceMemPointer_CL(T* root, T* start, int numElements, Device_CL* device) : m_effectiveHostDataPointer(start), m_hostDataPointer(root), m_numElements(numElements), m_effectiveNumElements(numElements), m_device(device), m_initialized(false)
132 {
133  cl_int err;
134  size_t sizeVec = numElements*sizeof(T);
135 
136  DEBUG_TEXT_LEVEL1("Alloc: " <<numElements <<"\n")
137 #ifdef SKEPU_MEASURE_TIME_DISTRIBUTION
138 
139 #ifdef SKEPU_MEASURE_ONLY_COPY
140  clFinish(m_device->getQueue());
141 #endif
142 
143  devMemAllocTimer.start();
144 #endif
145 
146  m_deviceDataPointer = clCreateBuffer(m_device->getContext(), CL_MEM_READ_WRITE, sizeVec, NULL, &err);
147  if(err != CL_SUCCESS)
148  {
149  SKEPU_ERROR("Error allocating memory on device. size: " << sizeVec << "\n");
150  }
151 
152  m_effectiveDeviceDataPointer = m_deviceDataPointer;
153 
154 #ifdef SKEPU_MEASURE_TIME_DISTRIBUTION
155 
156 #ifdef SKEPU_MEASURE_ONLY_COPY
157  clFinish(m_device->getQueue());
158 #endif
159 
160  devMemAllocTimer.stop();
161 #endif
162  deviceDataHasChanged = false;
163 }
164 
165 
166 
170 template <typename T>
172 {
173  DEBUG_TEXT_LEVEL1("DeAlloc: " <<m_numElements <<"\n")
174 
175  clReleaseMemObject(m_deviceDataPointer);
176 }
177 
178 
179 
188 template <typename T>
189 void DeviceMemPointer_CL<T>::copyDeviceToDevice(cl_mem copyToPointer,int numElements, int dstOffset, int srcOffset) const
190 {
191  if(m_hostDataPointer != NULL)
192  {
193  DEBUG_TEXT_LEVEL1("DEVICE_TO_DEVICE!!!\n")
194 
195  cl_int err;
196  size_t sizeVec;
197 
198  if(numElements == -1)
199  sizeVec = m_numElements*sizeof(T);
200  else
201  sizeVec = numElements*sizeof(T);
202 
203 #ifdef SKEPU_MEASURE_TIME_DISTRIBUTION
204 #ifdef SKEPU_MEASURE_ONLY_COPY
205  clFinish(m_device->getQueue());
206 #endif
207  copyUpTimer.start();
208 #endif
209 
210  err = clEnqueueCopyBuffer(m_device->getQueue(),m_deviceDataPointer, copyToPointer, srcOffset*sizeof(T), dstOffset*sizeof(T), sizeVec, 0, NULL, NULL);
211 
212  if(err != CL_SUCCESS)
213  {
214  SKEPU_ERROR("Error copying data to device. size: " << sizeVec << "\n");
215  }
216 
217 #ifdef SKEPU_MEASURE_TIME_DISTRIBUTION
218 #ifdef SKEPU_MEASURE_ONLY_COPY
219  clFinish(m_device->getQueue());
220 #endif
221  copyUpTimer.stop();
222 #endif
223 
224  deviceDataHasChanged = true;
225  }
226 }
227 
228 
238 template <typename T>
239 void DeviceMemPointer_CL<T>::copyHostToDevice_internal(T* src_ptr, cl_mem dest_ptr, int numElements, int offset) const
240 {
241  DEBUG_TEXT_LEVEL1("HOST_TO_DEVICE INTERNAL!!!\n")
242 
243  cl_int err;
244  size_t sizeVec;
245 
246  sizeVec = numElements*sizeof(T);
247 
248 #ifdef SKEPU_MEASURE_TIME_DISTRIBUTION
249 #ifdef SKEPU_MEASURE_ONLY_COPY
250  clFinish(m_device->getQueue());
251 #endif
252  copyUpTimer.start();
253 #endif
254 
255  err = clEnqueueWriteBuffer(m_device->getQueue(), dest_ptr, CL_TRUE, offset*sizeof(T), sizeVec, (void*)src_ptr, 0, NULL, NULL);
256 
257  if(err != CL_SUCCESS)
258  {
259  SKEPU_ERROR("Error copying data to device. size: "<< sizeVec << "\n");
260  }
261 
262 #ifdef SKEPU_MEASURE_TIME_DISTRIBUTION
263 #ifdef SKEPU_MEASURE_ONLY_COPY
264  clFinish(m_device->getQueue());
265 #endif
266  copyUpTimer.stop();
267 #endif
268 
269  if(!m_initialized) // set that it is initialized
270  m_initialized = true;
271 
272 // deviceDataHasChanged = false;
273 }
274 
275 
282 template <typename T>
283 void DeviceMemPointer_CL<T>::copyHostToDevice(int numElements, bool copyLast) const
284 {
285  DEBUG_TEXT_LEVEL1("HOST_TO_DEVICE!!!\n")
286 
287  cl_int err;
288  size_t sizeVec;
289  if(numElements == -1)
290  if(copyLast)
291  sizeVec = m_numElements*sizeof(T);
292  else
293  sizeVec = m_effectiveNumElements*sizeof(T);
294  else
295  sizeVec = numElements*sizeof(T);
296 
297 #ifdef SKEPU_MEASURE_TIME_DISTRIBUTION
298 #ifdef SKEPU_MEASURE_ONLY_COPY
299  clFinish(m_device->getQueue());
300 #endif
301  copyUpTimer.start();
302 #endif
303 
304  if(copyLast)
305  err = clEnqueueWriteBuffer(m_device->getQueue(), m_deviceDataPointer, CL_TRUE, 0, sizeVec, (void*)m_hostDataPointer, 0, NULL, NULL);
306  else
307  err = clEnqueueWriteBuffer(m_device->getQueue(), m_effectiveDeviceDataPointer, CL_TRUE, 0, sizeVec, (void*)m_effectiveHostDataPointer, 0, NULL, NULL);
308 
309  if(err != CL_SUCCESS)
310  {
311  SKEPU_ERROR("Error copying data to device. size: " << sizeVec << "\n");
312  }
313 
314 #ifdef SKEPU_MEASURE_TIME_DISTRIBUTION
315 #ifdef SKEPU_MEASURE_ONLY_COPY
316  clFinish(m_device->getQueue());
317 #endif
318  copyUpTimer.stop();
319 #endif
320 
321  if(!m_initialized) // set that it is initialized
322  m_initialized = true;
323 
324  deviceDataHasChanged = false;
325 }
326 
333 template <typename T>
334 void DeviceMemPointer_CL<T>::copyDeviceToHost(int numElements, bool copyLast) const
335 {
336  if(deviceDataHasChanged)
337  {
338  DEBUG_TEXT_LEVEL1("DEVICE_TO_HOST!!!\n")
339 
340  cl_int err;
341  size_t sizeVec;
342  if(numElements == -1)
343  if(copyLast)
344  sizeVec = m_numElements*sizeof(T);
345  else
346  sizeVec = m_effectiveNumElements*sizeof(T);
347  else
348  sizeVec = numElements*sizeof(T);
349 
350 #ifdef SKEPU_MEASURE_TIME_DISTRIBUTION
351 #ifdef SKEPU_MEASURE_ONLY_COPY
352  clFinish(m_device->getQueue());
353 #endif
354  copyDownTimer.start();
355 #endif
356 
357  if(copyLast)
358  err = clEnqueueReadBuffer(m_device->getQueue(), m_deviceDataPointer, CL_TRUE, 0, sizeVec, (void*)m_hostDataPointer, 0, NULL, NULL);
359  else
360  err = clEnqueueReadBuffer(m_device->getQueue(), m_effectiveDeviceDataPointer, CL_TRUE, 0, sizeVec, (void*)m_effectiveHostDataPointer, 0, NULL, NULL);
361 
362  if(err != CL_SUCCESS)
363  {
364  SKEPU_ERROR("Error copying data from device. size:"<<sizeVec<<"\n");
365  }
366 
367 #ifdef SKEPU_MEASURE_TIME_DISTRIBUTION
368 #ifdef SKEPU_MEASURE_ONLY_COPY
369  clFinish(m_device->getQueue());
370 #endif
371  copyDownTimer.stop();
372 #endif
373  deviceDataHasChanged = false;
374  }
375 }
376 
380 template <typename T>
382 {
383  return m_deviceDataPointer;
384 }
385 
389 template <typename T>
391 {
392  DEBUG_TEXT_LEVEL1("CHANGE_DEVICE_DATA!!!\n")
393  deviceDataHasChanged = true;
394  m_initialized = true;
395 }
396 
397 }
398 
399 #endif
400 
401 #endif
402 
403 
void copyHostToDevice(int numElements=-1, bool copyLast=false) const
Definition: device_mem_pointer_cl.h:283
DeviceMemPointer_CL(T *root, T *start, int numElements, Device_CL *device)
Definition: device_mem_pointer_cl.h:131
A class representing an OpenCL device memory allocation for container.
Definition: device_mem_pointer_cl.h:38
cl_mem getDeviceDataPointer() const
Definition: device_mem_pointer_cl.h:381
const cl_command_queue & getQueue() const
Definition: device_cl.h:178
void copyDeviceToDevice(cl_mem copyToPointer, int numElements, int dstOffset=0, int srcOffset=0) const
Definition: device_mem_pointer_cl.h:189
Contains a class declaration for the object that represents an OpenCL device.
void copyDeviceToHost(int numElements=-1, bool copyLast=false) const
Definition: device_mem_pointer_cl.h:334
const cl_context & getContext() const
Definition: device_cl.h:170
void changeDeviceData()
Definition: device_mem_pointer_cl.h:390
~DeviceMemPointer_CL()
Definition: device_mem_pointer_cl.h:171
Contains a class declaration for Environment class.
A class representing an OpenCL device.
Definition: device_cl.h:36