1c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez//
2c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// Copyright 2012 Francisco Jerez
3c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez//
4c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// Permission is hereby granted, free of charge, to any person obtaining a
5c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// copy of this software and associated documentation files (the "Software"),
6c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// to deal in the Software without restriction, including without limitation
7c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// the rights to use, copy, modify, merge, publish, distribute, sublicense,
8c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// and/or sell copies of the Software, and to permit persons to whom the
9c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// Software is furnished to do so, subject to the following conditions:
10c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez//
11c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// The above copyright notice and this permission notice shall be included in
12c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// all copies or substantial portions of the Software.
13c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez//
14c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// SOFTWARE.
21c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez//
22c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez
23c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez#include "api/util.hpp"
24c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez#include "core/context.hpp"
25c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez
26c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerezusing namespace clover;
27c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez
28c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco JerezPUBLIC cl_context
29c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco JerezclCreateContext(const cl_context_properties *props, cl_uint num_devs,
30c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez                const cl_device_id *devs,
31c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez                void (CL_CALLBACK *pfn_notify)(const char *, const void *,
32c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez                                               size_t, void *),
33c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez                void *user_data, cl_int *errcode_ret) try {
34c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez   auto mprops = property_map(props);
35c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez
36c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez   if (!devs || !num_devs ||
37c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez       (!pfn_notify && user_data))
38c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez      throw error(CL_INVALID_VALUE);
39c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez
40c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez   if (any_of(is_zero<cl_device_id>(), devs, devs + num_devs))
41c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez      throw error(CL_INVALID_DEVICE);
42c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez
43c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez   for (auto p : mprops) {
44c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez      if (!(p.first == CL_CONTEXT_PLATFORM &&
45c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez            (cl_platform_id)p.second == NULL))
46c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez         throw error(CL_INVALID_PROPERTY);
47c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez   }
48c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez
49c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez   ret_error(errcode_ret, CL_SUCCESS);
50c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez   return new context(
51c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez      property_vector(mprops),
52c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez      std::vector<cl_device_id>(devs, devs + num_devs));
53c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez
54c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez} catch(error &e) {
55c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez   ret_error(errcode_ret, e);
56c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez   return NULL;
57c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez}
58c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez
59c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco JerezPUBLIC cl_context
60c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco JerezclCreateContextFromType(const cl_context_properties *props,
61c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez                        cl_device_type type,
62c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez                        void (CL_CALLBACK *pfn_notify)(
63c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez                           const char *, const void *, size_t, void *),
64c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez                        void *user_data, cl_int *errcode_ret) {
65c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez   cl_device_id dev;
66c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez   cl_int ret;
67c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez
68c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez   ret = clGetDeviceIDs(0, type, 1, &dev, 0);
69c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez   if (ret) {
70c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez      ret_error(errcode_ret, ret);
71c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez      return NULL;
72c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez   }
73c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez
74c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez   return clCreateContext(props, 1, &dev, pfn_notify, user_data, errcode_ret);
75c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez}
76c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez
77c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco JerezPUBLIC cl_int
78c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco JerezclRetainContext(cl_context ctx) {
79c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez   if (!ctx)
80c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez      return CL_INVALID_CONTEXT;
81c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez
82c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez   ctx->retain();
83c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez   return CL_SUCCESS;
84c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez}
85c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez
86c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco JerezPUBLIC cl_int
87c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco JerezclReleaseContext(cl_context ctx) {
88c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez   if (!ctx)
89c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez      return CL_INVALID_CONTEXT;
90c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez
91c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez   if (ctx->release())
92c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez      delete ctx;
93c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez
94c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez   return CL_SUCCESS;
95c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez}
96c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez
97c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco JerezPUBLIC cl_int
98c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco JerezclGetContextInfo(cl_context ctx, cl_context_info param,
99c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez                 size_t size, void *buf, size_t *size_ret) {
100c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez   if (!ctx)
101c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez      return CL_INVALID_CONTEXT;
102c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez
103c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez   switch (param) {
104c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez   case CL_CONTEXT_REFERENCE_COUNT:
105c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez      return scalar_property<cl_uint>(buf, size, size_ret, ctx->ref_count());
106c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez
107c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez   case CL_CONTEXT_NUM_DEVICES:
108c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez      return scalar_property<cl_uint>(buf, size, size_ret, ctx->devs.size());
109c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez
110c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez   case CL_CONTEXT_DEVICES:
111c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez      return vector_property<cl_device_id>(buf, size, size_ret, ctx->devs);
112c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez
113c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez   case CL_CONTEXT_PROPERTIES:
114c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez      return vector_property<cl_context_properties>(buf, size, size_ret,
115c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez                                                    ctx->props());
116c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez
117c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez   default:
118c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez      return CL_INVALID_VALUE;
119c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez   }
120c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez}
121