1 // 2 // Copyright 2012 Francisco Jerez 3 // 4 // Permission is hereby granted, free of charge, to any person obtaining a 5 // copy of this software and associated documentation files (the "Software"), 6 // to deal in the Software without restriction, including without limitation 7 // the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 // and/or sell copies of the Software, and to permit persons to whom the 9 // Software is furnished to do so, subject to the following conditions: 10 // 11 // The above copyright notice and this permission notice shall be included in 12 // all copies or substantial portions of the Software. 13 // 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 // OTHER DEALINGS IN THE SOFTWARE. 21 // 22 23 #include "api/util.hpp" 24 #include "core/context.hpp" 25 #include "core/platform.hpp" 26 27 using namespace clover; 28 29 CLOVER_API cl_context 30 clCreateContext(const cl_context_properties *d_props, cl_uint num_devs, 31 const cl_device_id *d_devs, 32 void (CL_CALLBACK *pfn_notify)(const char *, const void *, 33 size_t, void *), 34 void *user_data, cl_int *r_errcode) try { 35 auto props = obj<property_list_tag>(d_props); 36 auto devs = objs(d_devs, num_devs); 37 38 if (!pfn_notify && user_data) 39 throw error(CL_INVALID_VALUE); 40 41 for (auto &prop : props) { 42 if (prop.first == CL_CONTEXT_PLATFORM) 43 obj(prop.second.as<cl_platform_id>()); 44 else 45 throw error(CL_INVALID_PROPERTY); 46 } 47 48 const auto notify = (!pfn_notify ? context::notify_action() : 49 [=](const char *s) { 50 pfn_notify(s, NULL, 0, user_data); 51 }); 52 53 ret_error(r_errcode, CL_SUCCESS); 54 return desc(new context(props, devs, notify)); 55 56 } catch (error &e) { 57 ret_error(r_errcode, e); 58 return NULL; 59 } 60 61 CLOVER_API cl_context 62 clCreateContextFromType(const cl_context_properties *d_props, 63 cl_device_type type, 64 void (CL_CALLBACK *pfn_notify)( 65 const char *, const void *, size_t, void *), 66 void *user_data, cl_int *r_errcode) try { 67 cl_platform_id d_platform; 68 cl_uint num_platforms; 69 cl_int ret; 70 std::vector<cl_device_id> devs; 71 cl_uint num_devices; 72 73 ret = clGetPlatformIDs(1, &d_platform, &num_platforms); 74 if (ret || !num_platforms) 75 throw error(CL_INVALID_PLATFORM); 76 77 ret = clGetDeviceIDs(d_platform, type, 0, NULL, &num_devices); 78 if (ret) 79 throw error(CL_DEVICE_NOT_FOUND); 80 devs.resize(num_devices); 81 ret = clGetDeviceIDs(d_platform, type, num_devices, devs.data(), 0); 82 if (ret) 83 throw error(CL_DEVICE_NOT_FOUND); 84 85 return clCreateContext(d_props, num_devices, devs.data(), pfn_notify, 86 user_data, r_errcode); 87 88 } catch (error &e) { 89 ret_error(r_errcode, e); 90 return NULL; 91 } 92 93 CLOVER_API cl_int 94 clRetainContext(cl_context d_ctx) try { 95 obj(d_ctx).retain(); 96 return CL_SUCCESS; 97 98 } catch (error &e) { 99 return e.get(); 100 } 101 102 CLOVER_API cl_int 103 clReleaseContext(cl_context d_ctx) try { 104 if (obj(d_ctx).release()) 105 delete pobj(d_ctx); 106 107 return CL_SUCCESS; 108 109 } catch (error &e) { 110 return e.get(); 111 } 112 113 CLOVER_API cl_int 114 clGetContextInfo(cl_context d_ctx, cl_context_info param, 115 size_t size, void *r_buf, size_t *r_size) try { 116 property_buffer buf { r_buf, size, r_size }; 117 auto &ctx = obj(d_ctx); 118 119 switch (param) { 120 case CL_CONTEXT_REFERENCE_COUNT: 121 buf.as_scalar<cl_uint>() = ctx.ref_count(); 122 break; 123 124 case CL_CONTEXT_NUM_DEVICES: 125 buf.as_scalar<cl_uint>() = ctx.devices().size(); 126 break; 127 128 case CL_CONTEXT_DEVICES: 129 buf.as_vector<cl_device_id>() = descs(ctx.devices()); 130 break; 131 132 case CL_CONTEXT_PROPERTIES: 133 buf.as_vector<cl_context_properties>() = desc(ctx.properties()); 134 break; 135 136 default: 137 throw error(CL_INVALID_VALUE); 138 } 139 140 return CL_SUCCESS; 141 142 } catch (error &e) { 143 return e.get(); 144 } 145