Home | History | Annotate | Download | only in api
      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