Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4358 Serge 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/program.hpp"
25
 
26
using namespace clover;
27
 
28
PUBLIC cl_program
29
clCreateProgramWithSource(cl_context ctx, cl_uint count,
30
                          const char **strings, const size_t *lengths,
31
                          cl_int *errcode_ret) try {
32
   std::string source;
33
 
34
   if (!ctx)
35
      throw error(CL_INVALID_CONTEXT);
36
 
37
   if (!count || !strings ||
38
       any_of(is_zero, strings, strings + count))
39
      throw error(CL_INVALID_VALUE);
40
 
41
   // Concatenate all the provided fragments together
42
   for (unsigned i = 0; i < count; ++i)
43
         source += (lengths && lengths[i] ?
44
                    std::string(strings[i], strings[i] + lengths[i]) :
45
                    std::string(strings[i]));
46
 
47
   // ...and create a program object for them.
48
   ret_error(errcode_ret, CL_SUCCESS);
49
   return new program(*ctx, source);
50
 
51
} catch (error &e) {
52
   ret_error(errcode_ret, e);
53
   return NULL;
54
}
55
 
56
PUBLIC cl_program
57
clCreateProgramWithBinary(cl_context ctx, cl_uint count,
58
                          const cl_device_id *devs, const size_t *lengths,
59
                          const unsigned char **binaries, cl_int *status_ret,
60
                          cl_int *errcode_ret) try {
61
   if (!ctx)
62
      throw error(CL_INVALID_CONTEXT);
63
 
64
   if (!count || !devs || !lengths || !binaries)
65
      throw error(CL_INVALID_VALUE);
66
 
67
   if (any_of([&](const cl_device_id dev) {
68
            return !ctx->has_device(dev);
69
         }, devs, devs + count))
70
      throw error(CL_INVALID_DEVICE);
71
 
72
   // Deserialize the provided binaries,
73
   auto modules = map(
74
      [](const unsigned char *p, size_t l) -> std::pair {
75
         if (!p || !l)
76
            return { CL_INVALID_VALUE, {} };
77
 
78
         try {
79
            compat::istream::buffer_t bin(p, l);
80
            compat::istream s(bin);
81
 
82
            return { CL_SUCCESS, module::deserialize(s) };
83
 
84
         } catch (compat::istream::error &e) {
85
            return { CL_INVALID_BINARY, {} };
86
         }
87
      },
88
      binaries, binaries + count, lengths);
89
 
90
   // update the status array,
91
   if (status_ret)
92
      std::transform(modules.begin(), modules.end(), status_ret,
93
                     keys);
94
 
95
   if (any_of(key_equals(CL_INVALID_VALUE),
96
              modules.begin(), modules.end()))
97
      throw error(CL_INVALID_VALUE);
98
 
99
   if (any_of(key_equals(CL_INVALID_BINARY),
100
              modules.begin(), modules.end()))
101
      throw error(CL_INVALID_BINARY);
102
 
103
   // initialize a program object with them.
104
   ret_error(errcode_ret, CL_SUCCESS);
105
   return new program(*ctx, { devs, devs + count },
106
                      map(values,
107
                          modules.begin(), modules.end()));
108
 
109
} catch (error &e) {
110
   ret_error(errcode_ret, e);
111
   return NULL;
112
}
113
 
114
PUBLIC cl_int
115
clRetainProgram(cl_program prog) {
116
   if (!prog)
117
      return CL_INVALID_PROGRAM;
118
 
119
   prog->retain();
120
   return CL_SUCCESS;
121
}
122
 
123
PUBLIC cl_int
124
clReleaseProgram(cl_program prog) {
125
   if (!prog)
126
      return CL_INVALID_PROGRAM;
127
 
128
   if (prog->release())
129
      delete prog;
130
 
131
   return CL_SUCCESS;
132
}
133
 
134
PUBLIC cl_int
135
clBuildProgram(cl_program prog, cl_uint count, const cl_device_id *devs,
136
               const char *opts, void (*pfn_notify)(cl_program, void *),
137
               void *user_data) try {
138
   if (!prog)
139
      throw error(CL_INVALID_PROGRAM);
140
 
141
   if (bool(count) != bool(devs) ||
142
       (!pfn_notify && user_data))
143
      throw error(CL_INVALID_VALUE);
144
 
145
   if (!opts)
146
      opts = "";
147
 
148
   if (devs) {
149
      if (any_of([&](const cl_device_id dev) {
150
               return !prog->ctx.has_device(dev);
151
            }, devs, devs + count))
152
         throw error(CL_INVALID_DEVICE);
153
 
154
      prog->build({ devs, devs + count }, opts);
155
   } else {
156
      prog->build(prog->ctx.devs, opts);
157
   }
158
 
159
   return CL_SUCCESS;
160
 
161
} catch (error &e) {
162
   return e.get();
163
}
164
 
165
PUBLIC cl_int
166
clUnloadCompiler() {
167
   return CL_SUCCESS;
168
}
169
 
170
PUBLIC cl_int
171
clGetProgramInfo(cl_program prog, cl_program_info param,
172
                 size_t size, void *buf, size_t *size_ret) {
173
   if (!prog)
174
      return CL_INVALID_PROGRAM;
175
 
176
   switch (param) {
177
   case CL_PROGRAM_REFERENCE_COUNT:
178
      return scalar_property(buf, size, size_ret,
179
                                      prog->ref_count());
180
 
181
   case CL_PROGRAM_CONTEXT:
182
      return scalar_property(buf, size, size_ret,
183
                                         &prog->ctx);
184
 
185
   case CL_PROGRAM_NUM_DEVICES:
186
      return scalar_property(buf, size, size_ret,
187
                                      prog->binaries().size());
188
 
189
   case CL_PROGRAM_DEVICES:
190
      return vector_property(
191
         buf, size, size_ret,
192
         map(keys,
193
             prog->binaries().begin(), prog->binaries().end()));
194
 
195
   case CL_PROGRAM_SOURCE:
196
      return string_property(buf, size, size_ret, prog->source());
197
 
198
   case CL_PROGRAM_BINARY_SIZES:
199
      return vector_property(
200
         buf, size, size_ret,
201
         map([](const std::pair &ent) {
202
               compat::ostream::buffer_t bin;
203
               compat::ostream s(bin);
204
               ent.second.serialize(s);
205
               return bin.size();
206
            },
207
            prog->binaries().begin(), prog->binaries().end()));
208
 
209
   case CL_PROGRAM_BINARIES:
210
      return matrix_property(
211
         buf, size, size_ret,
212
         map([](const std::pair &ent) {
213
               compat::ostream::buffer_t bin;
214
               compat::ostream s(bin);
215
               ent.second.serialize(s);
216
               return bin;
217
            },
218
            prog->binaries().begin(), prog->binaries().end()));
219
 
220
   default:
221
      return CL_INVALID_VALUE;
222
   }
223
}
224
 
225
PUBLIC cl_int
226
clGetProgramBuildInfo(cl_program prog, cl_device_id dev,
227
                      cl_program_build_info param,
228
                      size_t size, void *buf, size_t *size_ret) {
229
   if (!prog)
230
      return CL_INVALID_PROGRAM;
231
 
232
   if (!prog->ctx.has_device(dev))
233
      return CL_INVALID_DEVICE;
234
 
235
   switch (param) {
236
   case CL_PROGRAM_BUILD_STATUS:
237
      return scalar_property(buf, size, size_ret,
238
                                              prog->build_status(dev));
239
 
240
   case CL_PROGRAM_BUILD_OPTIONS:
241
      return string_property(buf, size, size_ret, prog->build_opts(dev));
242
 
243
   case CL_PROGRAM_BUILD_LOG:
244
      return string_property(buf, size, size_ret, prog->build_log(dev));
245
 
246
   default:
247
      return CL_INVALID_VALUE;
248
   }
249
}