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_abstract_dev_container_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 
29 #include "_ccl_abstract_dev_container_wrapper.h"
30 #include "_ccl_defs.h"
31 
45 static void ccl_dev_container_init_devices(CCLDevContainer* devcon,
46  ccl_dev_container_get_cldevices get_devices, CCLErr **err) {
47 
48  /* Make sure err is NULL or it is not set. */
49  g_return_if_fail(err == NULL || *err == NULL);
50 
51  /* Make sure devcon is not NULL. */
52  g_return_if_fail(devcon != NULL);
53 
54  /* Make sure device list is not initialized. */
55  g_return_if_fail(devcon->devices == NULL);
56 
57  CCLWrapperInfo* info_devs;
58  CCLErr* err_internal = NULL;
59 
60  /* Get device IDs. */
61  info_devs = get_devices(devcon, &err_internal);
62  ccl_if_err_propagate_goto(err, err_internal, error_handler);
63 
64  /* Determine number of devices. */
65  devcon->num_devices = (cl_uint) (info_devs->size / sizeof(cl_device_id));
66 
67  /* Allocate memory for array of device wrapper objects. */
68  devcon->devices = g_slice_alloc(
69  devcon->num_devices * sizeof(CCLDevice*));
70 
71  /* Wrap device IDs in device wrapper objects. */
72  for (guint i = 0; i < devcon->num_devices; ++i) {
73 
74  /* Add device wrapper object to array of wrapper objects. */
75  devcon->devices[i] = ccl_device_new_wrap(
76  ((cl_device_id*) info_devs->value)[i]);
77  }
78 
79  /* If we got here, everything is OK. */
80  g_assert(err == NULL || *err == NULL);
81  goto finish;
82 
83 error_handler:
84  /* If we got here there was an error, verify that it is so. */
85  g_assert(err == NULL || *err != NULL);
86 
87 finish:
88 
89  /* Terminate function. */
90  return;
91 
92 }
93 
103 void ccl_dev_container_release_devices(CCLDevContainer* devcon) {
104 
105  /* Make sure devcon wrapper object is not NULL. */
106  g_return_if_fail(devcon != NULL);
107 
108  /* Check if any devices are associated with this device container. */
109  if (devcon->devices != NULL) {
110 
111  /* Release devices in device container. */
112  for (guint i = 0; i < devcon->num_devices; ++i) {
113  if (devcon->devices[i])
114  ccl_device_unref(devcon->devices[i]);
115  }
116 
117  /* Free device wrapper array. */
118  g_slice_free1(devcon->num_devices * sizeof(CCLDevice*),
119  devcon->devices);
120  }
121 
122 }
123 
138 CCLDevice* const* ccl_dev_container_get_all_devices(
139  CCLDevContainer* devcon,
140  ccl_dev_container_get_cldevices get_devices, CCLErr** err) {
141 
142  /* Make sure err is NULL or it is not set. */
143  g_return_val_if_fail(err == NULL || *err == NULL, NULL);
144 
145  /* Make sure devcon is not NULL. */
146  g_return_val_if_fail(devcon != NULL, NULL);
147 
148  /* Check if device list is already initialized. */
149  if (devcon->devices == NULL) {
150 
151  /* Not initialized, initialize it. */
152  ccl_dev_container_init_devices(devcon, get_devices, err);
153 
154  }
155 
156  /* Return all devices in platform. */
157  return (CCLDevice* const*) devcon->devices;
158 
159 }
160 
161 
177 CCLDevice* ccl_dev_container_get_device(
178  CCLDevContainer* devcon,
179  ccl_dev_container_get_cldevices get_devices, cl_uint index,
180  CCLErr** err) {
181 
182  /* Make sure err is NULL or it is not set. */
183  g_return_val_if_fail(err == NULL || *err == NULL, NULL);
184 
185  /* Make sure devcon is not NULL. */
186  g_return_val_if_fail(devcon != NULL, NULL);
187 
188  /* The return value. */
189  CCLDevice* device_ret;
190 
191  /* Internal error object. */
192  CCLErr* err_internal = NULL;
193 
194  /* Check if device list is already initialized. */
195  if (devcon->devices == NULL) {
196 
197  /* Not initialized, initialize it. */
198  ccl_dev_container_init_devices(
199  devcon, get_devices, &err_internal);
200 
201  /* Check for errors. */
202  ccl_if_err_propagate_goto(err, err_internal, error_handler);
203 
204  }
205 
206  /* Make sure device index is less than the number of devices. */
207  ccl_if_err_create_goto(*err, CCL_ERROR, index >= devcon->num_devices,
208  CCL_ERROR_DEVICE_NOT_FOUND, error_handler,
209  "%s: device index (%d) out of bounds (%d devices in list).",
210  CCL_STRD, index, devcon->num_devices);
211 
212  /* If we got here, everything is OK. */
213  g_assert(err == NULL || *err == NULL);
214  device_ret = devcon->devices[index];
215  goto finish;
216 
217 error_handler:
218 
219  /* If we got here there was an error, verify that it is so. */
220  g_assert(err == NULL || *err != NULL);
221  device_ret = NULL;
222 
223 finish:
224 
225  /* Return list of device wrappers. */
226  return device_ret;
227 
228 }
229 
244 cl_uint ccl_dev_container_get_num_devices(
245  CCLDevContainer* devcon,
246  ccl_dev_container_get_cldevices get_devices, CCLErr** err) {
247 
248  /* Make sure devcon is not NULL. */
249  g_return_val_if_fail(devcon != NULL, 0);
250 
251  /* Make sure err is NULL or it is not set. */
252  g_return_val_if_fail(err == NULL || *err == NULL, 0);
253 
254  /* Check if device list is already initialized. */
255  if (devcon->devices == NULL) {
256 
257  /* Not initialized, initialize it. */
258  ccl_dev_container_init_devices(devcon, get_devices, err);
259 
260  }
261 
262  /* Return the number of devices in context. */
263  return devcon->num_devices;
264 
265 }
266 
#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
Useful definitions used internally by cf4ocl.
#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 wrappers which contain devices, i.e., CCLPlatform, CCLProgram and CCLContext.
#define CCL_ERROR
Resolves to error category identifying string, in this case an error in cf4ocl.
Definition: ccl_common.h:320
The requested OpenCL device was not found.
Definition: ccl_common.h:308
size_t size
Size in bytes of object information.
#define ccl_device_unref(dev)
Alias to ccl_device_destroy().
void * value
Object information.
Class which represents information about a wrapped OpenCL object.
GError CCLErr
Error handling class.
Definition: ccl_common.h:291
Device wrapper class.
CCLDevice * ccl_device_new_wrap(cl_device_id device)
Get the device wrapper for the given OpenCL device.