130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun//
230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// Copyright 2012 Francisco Jerez
330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun//
430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// Permission is hereby granted, free of charge, to any person obtaining a
530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// copy of this software and associated documentation files (the "Software"),
630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// to deal in the Software without restriction, including without limitation
730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// the rights to use, copy, modify, merge, publish, distribute, sublicense,
830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// and/or sell copies of the Software, and to permit persons to whom the
930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// Software is furnished to do so, subject to the following conditions:
1030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun//
1130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// The above copyright notice and this permission notice shall be included in
1230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// all copies or substantial portions of the Software.
1330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun//
1430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
1830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
1930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// SOFTWARE.
2130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun//
2230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
2330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "api/util.hpp"
2430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "core/program.hpp"
2530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
2630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunusing namespace clover;
2730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
2830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunPUBLIC cl_program
2930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunclCreateProgramWithSource(cl_context ctx, cl_uint count,
3030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                          const char **strings, const size_t *lengths,
3130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                          cl_int *errcode_ret) try {
3230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   std::string source;
3330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
3430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   if (!ctx)
3530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      throw error(CL_INVALID_CONTEXT);
3630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
3730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   if (!count || !strings ||
3830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun       any_of(is_zero<const char *>(), strings, strings + count))
3930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      throw error(CL_INVALID_VALUE);
4030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
4130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   // Concatenate all the provided fragments together
4230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   for (unsigned i = 0; i < count; ++i)
4330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun         source += (lengths && lengths[i] ?
4430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                    std::string(strings[i], strings[i] + lengths[i]) :
4530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                    std::string(strings[i]));
4630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
4730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   // ...and create a program object for them.
4830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   ret_error(errcode_ret, CL_SUCCESS);
4930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   return new program(*ctx, source);
5030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
5130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} catch (error &e) {
5230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   ret_error(errcode_ret, e);
5330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   return NULL;
5430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
5530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
5630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunPUBLIC cl_program
5730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunclCreateProgramWithBinary(cl_context ctx, cl_uint count,
5830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                          const cl_device_id *devs, const size_t *lengths,
5930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                          const unsigned char **binaries, cl_int *status_ret,
6030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                          cl_int *errcode_ret) try {
6130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   if (!ctx)
6230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      throw error(CL_INVALID_CONTEXT);
6330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
6430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   if (!count || !devs || !lengths || !binaries)
6530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      throw error(CL_INVALID_VALUE);
6630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
6730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   if (any_of([&](const cl_device_id dev) {
6830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun            return !ctx->has_device(dev);
6930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun         }, devs, devs + count))
7030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      throw error(CL_INVALID_DEVICE);
7130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
7230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   // Deserialize the provided binaries,
7330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   auto modules = map(
7430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      [](const unsigned char *p, size_t l) -> std::pair<cl_int, module> {
7530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun         if (!p || !l)
7630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun            return { CL_INVALID_VALUE, {} };
7730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
7830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun         try {
7930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun            compat::istream::buffer_t bin(p, l);
8030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun            compat::istream s(bin);
8130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
8230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun            return { CL_SUCCESS, module::deserialize(s) };
8330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
8430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun         } catch (compat::istream::error &e) {
8530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun            return { CL_INVALID_BINARY, {} };
8630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun         }
8730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      },
8830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      binaries, binaries + count, lengths);
8930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
9030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   // update the status array,
9130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   if (status_ret)
9230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      std::transform(modules.begin(), modules.end(), status_ret,
9330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                     keys<cl_int, module>);
9430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
9530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   if (any_of(key_equals<cl_int, module>(CL_INVALID_VALUE),
9630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun              modules.begin(), modules.end()))
9730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      throw error(CL_INVALID_VALUE);
9830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
9930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   if (any_of(key_equals<cl_int, module>(CL_INVALID_BINARY),
10030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun              modules.begin(), modules.end()))
10130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      throw error(CL_INVALID_BINARY);
10230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
10330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   // initialize a program object with them.
10430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   ret_error(errcode_ret, CL_SUCCESS);
10530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   return new program(*ctx, { devs, devs + count },
10630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                      map(values<cl_int, module>,
10730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                          modules.begin(), modules.end()));
10830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
10930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} catch (error &e) {
11030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   ret_error(errcode_ret, e);
11130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   return NULL;
11230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
11330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
11430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunPUBLIC cl_int
11530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunclRetainProgram(cl_program prog) {
11630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   if (!prog)
11730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      return CL_INVALID_PROGRAM;
11830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
11930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   prog->retain();
12030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   return CL_SUCCESS;
12130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
12230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
12330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunPUBLIC cl_int
12430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunclReleaseProgram(cl_program prog) {
12530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   if (!prog)
12630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      return CL_INVALID_PROGRAM;
12730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
12830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   if (prog->release())
12930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      delete prog;
13030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
13130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   return CL_SUCCESS;
13230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
13330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
13430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunPUBLIC cl_int
13530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunclBuildProgram(cl_program prog, cl_uint count, const cl_device_id *devs,
13630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun               const char *opts, void (*pfn_notify)(cl_program, void *),
13730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun               void *user_data) try {
13830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   if (!prog)
13930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      throw error(CL_INVALID_PROGRAM);
14030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
14130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   if (bool(count) != bool(devs) ||
14230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun       (!pfn_notify && user_data))
14330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      throw error(CL_INVALID_VALUE);
14430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
14530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   if (devs) {
14630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      if (any_of([&](const cl_device_id dev) {
14730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun               return !prog->ctx.has_device(dev);
14830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun            }, devs, devs + count))
14930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun         throw error(CL_INVALID_DEVICE);
15030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
15130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      prog->build({ devs, devs + count });
15230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   } else {
15330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      prog->build(prog->ctx.devs);
15430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   }
15530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
15630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   return CL_SUCCESS;
15730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
15830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} catch (error &e) {
15930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   return e.get();
16030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
16130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
16230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunPUBLIC cl_int
16330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunclUnloadCompiler() {
16430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   return CL_SUCCESS;
16530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
16630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
16730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunPUBLIC cl_int
16830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunclGetProgramInfo(cl_program prog, cl_program_info param,
16930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                 size_t size, void *buf, size_t *size_ret) {
17030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   if (!prog)
17130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      return CL_INVALID_PROGRAM;
17230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
17330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   switch (param) {
17430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   case CL_PROGRAM_REFERENCE_COUNT:
17530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      return scalar_property<cl_uint>(buf, size, size_ret,
17630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                                      prog->ref_count());
17730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
17830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   case CL_PROGRAM_CONTEXT:
17930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      return scalar_property<cl_context>(buf, size, size_ret,
18030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                                         &prog->ctx);
18130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
18230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   case CL_PROGRAM_NUM_DEVICES:
18330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      return scalar_property<cl_uint>(buf, size, size_ret,
18430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                                      prog->binaries().size());
18530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
18630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   case CL_PROGRAM_DEVICES:
18730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      return vector_property<cl_device_id>(
18830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun         buf, size, size_ret,
18930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun         map(keys<device *, module>,
19030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun             prog->binaries().begin(), prog->binaries().end()));
19130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
19230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   case CL_PROGRAM_SOURCE:
19330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      return string_property(buf, size, size_ret, prog->source());
19430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
19530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   case CL_PROGRAM_BINARY_SIZES:
19630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      return vector_property<size_t>(
19730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun         buf, size, size_ret,
19830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun         map([](const std::pair<device *, module> &ent) {
19930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun               compat::ostream::buffer_t bin;
20030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun               compat::ostream s(bin);
20130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun               ent.second.serialize(s);
20230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun               return bin.size();
20330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun            },
20430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun            prog->binaries().begin(), prog->binaries().end()));
20530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
20630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   case CL_PROGRAM_BINARIES:
20730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      return matrix_property<unsigned char>(
20830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun         buf, size, size_ret,
20930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun         map([](const std::pair<device *, module> &ent) {
21030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun               compat::ostream::buffer_t bin;
21130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun               compat::ostream s(bin);
21230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun               ent.second.serialize(s);
21330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun               return bin;
21430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun            },
21530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun            prog->binaries().begin(), prog->binaries().end()));
21630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
21730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   default:
21830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      return CL_INVALID_VALUE;
21930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   }
22030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
22130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
22230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunPUBLIC cl_int
22330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunclGetProgramBuildInfo(cl_program prog, cl_device_id dev,
22430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                      cl_program_build_info param,
22530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                      size_t size, void *buf, size_t *size_ret) {
22630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   if (!prog)
22730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      return CL_INVALID_PROGRAM;
22830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
22930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   if (!prog->ctx.has_device(dev))
23030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      return CL_INVALID_DEVICE;
23130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
23230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   switch (param) {
23330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   case CL_PROGRAM_BUILD_STATUS:
23430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      return scalar_property<cl_build_status>(buf, size, size_ret,
23530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                                              prog->build_status(dev));
23630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
23730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   case CL_PROGRAM_BUILD_OPTIONS:
23830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      return string_property(buf, size, size_ret, prog->build_opts(dev));
23930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
24030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   case CL_PROGRAM_BUILD_LOG:
24130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      return string_property(buf, size, size_ret, prog->build_log(dev));
24230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
243   default:
244      return CL_INVALID_VALUE;
245   }
246}
247