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 BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 18 // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 19 // OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 // SOFTWARE. 21 // 22 23 #include "api/util.hpp" 24 #include "core/context.hpp" 25 26 using namespace clover; 27 28 PUBLIC cl_context 29 clCreateContext(const cl_context_properties *props, cl_uint num_devs, 30 const cl_device_id *devs, 31 void (CL_CALLBACK *pfn_notify)(const char *, const void *, 32 size_t, void *), 33 void *user_data, cl_int *errcode_ret) try { 34 auto mprops = property_map(props); 35 36 if (!devs || !num_devs || 37 (!pfn_notify && user_data)) 38 throw error(CL_INVALID_VALUE); 39 40 if (any_of(is_zero<cl_device_id>(), devs, devs + num_devs)) 41 throw error(CL_INVALID_DEVICE); 42 43 for (auto p : mprops) { 44 if (!(p.first == CL_CONTEXT_PLATFORM && 45 (cl_platform_id)p.second == NULL)) 46 throw error(CL_INVALID_PROPERTY); 47 } 48 49 ret_error(errcode_ret, CL_SUCCESS); 50 return new context( 51 property_vector(mprops), 52 std::vector<cl_device_id>(devs, devs + num_devs)); 53 54 } catch(error &e) { 55 ret_error(errcode_ret, e); 56 return NULL; 57 } 58 59 PUBLIC cl_context 60 clCreateContextFromType(const cl_context_properties *props, 61 cl_device_type type, 62 void (CL_CALLBACK *pfn_notify)( 63 const char *, const void *, size_t, void *), 64 void *user_data, cl_int *errcode_ret) { 65 cl_device_id dev; 66 cl_int ret; 67 68 ret = clGetDeviceIDs(0, type, 1, &dev, 0); 69 if (ret) { 70 ret_error(errcode_ret, ret); 71 return NULL; 72 } 73 74 return clCreateContext(props, 1, &dev, pfn_notify, user_data, errcode_ret); 75 } 76 77 PUBLIC cl_int 78 clRetainContext(cl_context ctx) { 79 if (!ctx) 80 return CL_INVALID_CONTEXT; 81 82 ctx->retain(); 83 return CL_SUCCESS; 84 } 85 86 PUBLIC cl_int 87 clReleaseContext(cl_context ctx) { 88 if (!ctx) 89 return CL_INVALID_CONTEXT; 90 91 if (ctx->release()) 92 delete ctx; 93 94 return CL_SUCCESS; 95 } 96 97 PUBLIC cl_int 98 clGetContextInfo(cl_context ctx, cl_context_info param, 99 size_t size, void *buf, size_t *size_ret) { 100 if (!ctx) 101 return CL_INVALID_CONTEXT; 102 103 switch (param) { 104 case CL_CONTEXT_REFERENCE_COUNT: 105 return scalar_property<cl_uint>(buf, size, size_ret, ctx->ref_count()); 106 107 case CL_CONTEXT_NUM_DEVICES: 108 return scalar_property<cl_uint>(buf, size, size_ret, ctx->devs.size()); 109 110 case CL_CONTEXT_DEVICES: 111 return vector_property<cl_device_id>(buf, size, size_ret, ctx->devs); 112 113 case CL_CONTEXT_PROPERTIES: 114 return vector_property<cl_context_properties>(buf, size, size_ret, 115 ctx->props()); 116 117 default: 118 return CL_INVALID_VALUE; 119 } 120 } 121