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 |
||
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 |
||
96 | modules.begin(), modules.end())) |
||
97 | throw error(CL_INVALID_VALUE); |
||
98 | |||
99 | if (any_of(key_equals |
||
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 |
||
179 | prog->ref_count()); |
||
180 | |||
181 | case CL_PROGRAM_CONTEXT: |
||
182 | return scalar_property |
||
183 | &prog->ctx); |
||
184 | |||
185 | case CL_PROGRAM_NUM_DEVICES: |
||
186 | return scalar_property |
||
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 |
||
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 |
||
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 |
||
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 | }> |