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 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