cf4ocl (C Framework for OpenCL)  v2.1.0
Object-oriented framework for developing and benchmarking OpenCL projects in C/C++
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ccl_memobj_wrapper.c
Go to the documentation of this file.
1 /*
2  * This file is part of cf4ocl (C Framework for OpenCL).
3  *
4  * cf4ocl is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License as
6  * published by the Free Software Foundation, either version 3 of the
7  * License, or (at your option) any later version.
8  *
9  * cf4ocl is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with cf4ocl. If not, see
16  * <http://www.gnu.org/licenses/>.
17  * */
18 
19 #include "ccl_memobj_wrapper.h"
20 #include "_ccl_memobj_wrapper.h"
21 #include "_ccl_defs.h"
22 
43 void ccl_memobj_release_fields(CCLMemObj* mo) {
44 
45  /* Make sure mo wrapper object is not NULL. */
46  g_return_if_fail(mo != NULL);
47 
48  /* Reduce reference count of memory object context wrapper. */
49  if (mo->ctx != NULL)
50  ccl_context_unref(mo->ctx);
51 
52 }
53 
78 CCL_EXPORT
80 
81  /* Make sure number mo is not NULL. */
82  g_return_val_if_fail(mo != NULL, 0);
83  /* Make sure err is NULL or it is not set. */
84  g_return_val_if_fail(err == NULL || *err == NULL, 0);
85 
86  cl_context context;
87  CCLContext* ctx;
88  CCLErr* err_internal = NULL;
89  cl_uint ocl_ver;
90 
91  /* Get cl_context object for this memory object. */
93  mo, CL_MEM_CONTEXT, cl_context, &err_internal);
94  ccl_if_err_propagate_goto(err, err_internal, error_handler);
95 
96  /* Get context wrapper. */
97  ctx = ccl_context_new_wrap(context);
98 
99  /* Get OpenCL version. */
100  ocl_ver = ccl_context_get_opencl_version(ctx, &err_internal);
101  ccl_if_err_propagate_goto(err, err_internal, error_handler);
102 
103  /* Unref. the context wrapper. */
104  ccl_context_unref(ctx);
105 
106  /* If we got here, everything is OK. */
107  g_assert(err == NULL || *err == NULL);
108  goto finish;
109 
110 error_handler:
111 
112  /* If we got here there was an error, verify that it is so. */
113  g_assert(err == NULL || *err != NULL);
114  ocl_ver = 0;
115 
116 finish:
117 
118  /* Return event wrapper. */
119  return ocl_ver;
120 
121 }
122 
141 CCL_EXPORT
143  void* mapped_ptr, CCLEventWaitList* evt_wait_lst, CCLErr** err) {
144 
145  /* Make sure cq is not NULL. */
146  g_return_val_if_fail(cq != NULL, NULL);
147  /* Make sure mo is not NULL. */
148  g_return_val_if_fail(mo != NULL, NULL);
149  /* Make sure err is NULL or it is not set. */
150  g_return_val_if_fail(err == NULL || *err == NULL, NULL);
151 
152  /* OpenCL function status. */
153  cl_int ocl_status;
154  /* OpenCL event. */
155  cl_event event;
156  /* Event wrapper. */
157  CCLEvent* evt;
158 
159  /* Enqueue unmap command. */
160  ocl_status = clEnqueueUnmapMemObject (ccl_queue_unwrap(cq),
161  ccl_memobj_unwrap(mo), mapped_ptr,
162  ccl_event_wait_list_get_num_events(evt_wait_lst),
163  ccl_event_wait_list_get_clevents(evt_wait_lst), &event);
165  CL_SUCCESS != ocl_status, ocl_status, error_handler,
166  "%s: unable to unmap memory object (OpenCL error %d: %s).",
167  CCL_STRD, ocl_status, ccl_err(ocl_status));
168 
169  /* Wrap event and associate it with the respective command queue.
170  * The event object will be released automatically when the command
171  * queue is released. */
172  evt = ccl_queue_produce_event(cq, event);
173 
174  /* Clear event wait list. */
175  ccl_event_wait_list_clear(evt_wait_lst);
176 
177  /* If we got here, everything is OK. */
178  g_assert(err == NULL || *err == NULL);
179  goto finish;
180 
181 error_handler:
182 
183  /* If we got here there was an error, verify that it is so. */
184  g_assert(err == NULL || *err != NULL);
185 
186  /* An error occurred, return NULL to signal it. */
187  evt = NULL;
188 
189 finish:
190 
191  /* Return evt. */
192  return evt;
193 
194 
195 }
196 
212 CCL_EXPORT
215  void *user_data, CCLErr** err) {
216 
217  /* Make sure mo is not NULL. */
218  g_return_val_if_fail(mo != NULL, CL_FALSE);
219  /* Make sure err is NULL or it is not set. */
220  g_return_val_if_fail(err == NULL || *err == NULL, CL_FALSE);
221 
222  /* OpenCL function status. */
223  cl_int ocl_status;
224  /* This function return status. */
225  cl_bool ret_status;
226  /* OpenCL version. */
227  double ocl_ver;
228  /* Internal error handling object. */
229  CCLErr* err_internal = NULL;
230 
231 #ifndef CL_VERSION_1_1
232 
233  CCL_UNUSED(pfn_notify);
234  CCL_UNUSED(user_data);
235  CCL_UNUSED(ocl_status);
236  CCL_UNUSED(ocl_ver);
237  CCL_UNUSED(err_internal);
238 
239  /* If cf4ocl was not compiled with support for OpenCL >= 1.1, always throw
240  * error. */
241  ccl_if_err_create_goto(*err, CCL_ERROR, TRUE,
242  CCL_ERROR_UNSUPPORTED_OCL, error_handler,
243  "%s: Setting destructor callbacks requires cf4ocl to be "
244  "deployed with support for OpenCL version 1.1 or newer.",
245  CCL_STRD);
246 
247 #else
248 
249  /* Check that context platform is >= OpenCL 1.1 */
250  ocl_ver = ccl_memobj_get_opencl_version(mo, &err_internal);
251  ccl_if_err_propagate_goto(err, err_internal, error_handler);
252 
253  /* If OpenCL version is not >= 1.1, throw error. */
254  ccl_if_err_create_goto(*err, CCL_ERROR, ocl_ver < 110,
255  CCL_ERROR_UNSUPPORTED_OCL, error_handler,
256  "%s: memory object destructor callbacks require OpenCL " \
257  "version 1.1 or newer.",
258  CCL_STRD);
259 
260  /* Set destructor callback. */
261  ocl_status = clSetMemObjectDestructorCallback(ccl_memobj_unwrap(mo),
262  pfn_notify, user_data);
264  CL_SUCCESS != ocl_status, ocl_status, error_handler,
265  "%s: unable to set memory object destructor callback "
266  "(OpenCL error %d: %s).",
267  CCL_STRD, ocl_status, ccl_err(ocl_status));
268 
269 #endif
270 
271  /* If we got here, everything is OK. */
272  g_assert(err == NULL || *err == NULL);
273  ret_status = CL_TRUE;
274  goto finish;
275 
276 error_handler:
277 
278  /* If we got here there was an error, verify that it is so. */
279  g_assert(err == NULL || *err != NULL);
280 
281  ret_status = CL_FALSE;
282 
283 finish:
284 
285  /* Return status. */
286  return ret_status;
287 
288 }
289 
309 CCL_EXPORT
311  CCLQueue* cq, cl_mem_migration_flags flags,
312  CCLEventWaitList* evt_wait_lst, CCLErr** err) {
313 
314  /* Make sure cq is not NULL. */
315  g_return_val_if_fail(cq != NULL, NULL);
316  /* Make sure mos is not NULL. */
317  g_return_val_if_fail(mos != NULL, NULL);
318  /* Make sure num_mos > 0 is not NULL. */
319  g_return_val_if_fail(num_mos > 0, NULL);
320  /* Make sure err is NULL or it is not set. */
321  g_return_val_if_fail(err == NULL || *err == NULL, NULL);
322 
323  /* OpenCL function status. */
324  cl_int ocl_status;
325  /* OpenCL event. */
326  cl_event event;
327  /* Event wrapper. */
328  CCLEvent* evt;
329  /* OpenCL version. */
330  double ocl_ver;
331  /* Internal error handling object. */
332  CCLErr* err_internal = NULL;
333  /* Array of OpenCL memory objects. */
334  cl_mem* mem_objects = NULL;
335 
336 #ifndef CL_VERSION_1_2
337 
338  CCL_UNUSED(flags);
339  CCL_UNUSED(evt_wait_lst);
340  CCL_UNUSED(ocl_status);
341  CCL_UNUSED(event);
342  CCL_UNUSED(ocl_ver);
343  CCL_UNUSED(err_internal);
344 
345  /* If cf4ocl was not compiled with support for OpenCL >= 1.2, always throw
346  * error. */
347  ccl_if_err_create_goto(*err, CCL_ERROR, TRUE,
348  CCL_ERROR_UNSUPPORTED_OCL, error_handler,
349  "%s: Memory object migration requires cf4ocl to be "
350  "deployed with support for OpenCL version 1.2 or newer.",
351  CCL_STRD);
352 
353 #else
354 
355  /* Check that context platform is >= OpenCL 1.2 */
356  ocl_ver = ccl_memobj_get_opencl_version(mos[0], &err_internal);
357  ccl_if_err_propagate_goto(err, err_internal, error_handler);
358 
359  /* If OpenCL version is not >= 1.2, throw error. */
360  ccl_if_err_create_goto(*err, CCL_ERROR, ocl_ver < 120,
361  CCL_ERROR_UNSUPPORTED_OCL, error_handler,
362  "%s: memory object migration requires OpenCL version 1.2 or " \
363  "newer.",
364  CCL_STRD);
365 
366  /* Allocate memory for memory objects. */
367  mem_objects = (cl_mem*) g_slice_alloc(sizeof(cl_mem) * num_mos);
368 
369  /* Gather OpenCL memory objects in a array. */
370  for (cl_uint i = 0; i < num_mos; ++i) {
371  mem_objects[i] = ccl_memobj_unwrap(mos[i]);
372  }
373 
374  /* Migrate memory objects. */
375  ocl_status = clEnqueueMigrateMemObjects(ccl_queue_unwrap(cq),
376  num_mos, (const cl_mem*) mem_objects, flags,
377  ccl_event_wait_list_get_num_events(evt_wait_lst),
378  ccl_event_wait_list_get_clevents(evt_wait_lst), &event);
380  CL_SUCCESS != ocl_status, ocl_status, error_handler,
381  "%s: unable to migrate memory objects (OpenCL error %d: %s).",
382  CCL_STRD, ocl_status, ccl_err(ocl_status));
383 
384  /* Wrap event and associate it with the respective command queue.
385  * The event object will be released automatically when the command
386  * queue is released. */
387  evt = ccl_queue_produce_event(cq, event);
388 
389  /* Clear event wait list. */
390  ccl_event_wait_list_clear(evt_wait_lst);
391 
392 #endif
393 
394  /* If we got here, everything is OK. */
395  g_assert(err == NULL || *err == NULL);
396  goto finish;
397 
398 error_handler:
399 
400  /* If we got here there was an error, verify that it is so. */
401  g_assert(err == NULL || *err != NULL);
402 
403  /* An error occurred, return NULL to signal it. */
404  evt = NULL;
405 
406 finish:
407 
408  /* Release stuff. */
409  if (mem_objects) g_slice_free1(sizeof(cl_mem) * num_mos, mem_objects);
410 
411  /* Return evt. */
412  return evt;
413 
414 }
415 
void(* ccl_memobj_destructor_callback)(cl_mem memobj, void *user_data)
Prototype for memory object destructor callback functions.
#define CCL_OCL_ERROR
Resolves to error category identifying string, in this case an error in the OpenCL library...
Definition: ccl_common.h:324
#define ccl_if_err_create_goto(err, quark, error_condition, error_code, label, msg,...)
If error is detected (error_code != no_error_code), create an error object (CCLErr) and go to the spe...
Definition: _ccl_defs.h:91
GPtrArray * CCLEventWaitList
A list of event objects on which enqueued commands can wait.
Useful definitions used internally by cf4ocl.
#define ccl_memobj_unwrap(mo)
Get the OpenCL cl_mem object.
The context wrapper class.
#define ccl_if_err_propagate_goto(err_dest, err_src, label)
Same as ccl_if_err_goto(), but rethrows error in a source CCLErr object to a new destination CCLErr o...
Definition: _ccl_defs.h:120
Base class for memory object wrappers, i.e., CCLBuffer and CCLImage.
Command queue wrapper class.
const char * ccl_err(int code)
Convert OpenCL error code to a readable string.
Definition: ccl_errors.c:118
void ccl_event_wait_list_clear(CCLEventWaitList *evt_wait_lst)
Clears an event wait list.
CCLContext * ccl_context_new_wrap(cl_context context)
Get the context wrapper for the given OpenCL context.
cl_uint ccl_context_get_opencl_version(CCLContext *ctx, CCLErr **err)
Get the OpenCL version of the platform associated with this context.
#define CCL_ERROR
Resolves to error category identifying string, in this case an error in cf4ocl.
Definition: ccl_common.h:320
Event wrapper class.
#define ccl_context_unref(ctx)
Alias to ccl_context_destroy().
#define CCL_UNUSED(x)
Macro to avoid warning in unused variables.
Definition: ccl_common.h:86
cl_uint ccl_memobj_get_opencl_version(CCLMemObj *mo, CCLErr **err)
Get the OpenCL version of the platform associated with this memory object.
Definition of a wrapper class and its methods for OpenCL memory objects.
cl_bool ccl_memobj_set_destructor_callback(CCLMemObj *mo, ccl_memobj_destructor_callback pfn_notify, void *user_data, CCLErr **err)
Wrapper for OpenCL clSetMemObjectDestructorCallback() function.
GError CCLErr
Error handling class.
Definition: ccl_common.h:291
#define ccl_memobj_get_info_scalar(mo, param_name, param_type, err)
Macro which returns a scalar memory object information value.
#define ccl_queue_unwrap(cq)
Get the OpenCL command queue object.
The operation is not supported by the version of the selected OpenCL platform.
Definition: ccl_common.h:311
CCLEvent * ccl_memobj_enqueue_migrate(CCLMemObj **mos, cl_uint num_mos, CCLQueue *cq, cl_mem_migration_flags flags, CCLEventWaitList *evt_wait_lst, CCLErr **err)
Enqueues a command to indicate which device a set of memory objects should be associated with...
CCLEvent * ccl_memobj_enqueue_unmap(CCLMemObj *mo, CCLQueue *cq, void *mapped_ptr, CCLEventWaitList *evt_wait_lst, CCLErr **err)
Enqueues a command to unmap a previously mapped region of a memory object.