PUBLIC cl_program
clCreateProgramWithBinary(cl_context ctx, cl_uint count,
                          const cl_device_id *devs, const size_t *lengths,
                          const unsigned char **binaries, cl_int *status_ret,
                          cl_int *errcode_ret) try {
   if (!ctx)
      throw error(CL_INVALID_CONTEXT);

   if (!count || !devs || !lengths || !binaries)
      throw error(CL_INVALID_VALUE);

   if (any_of([&](const cl_device_id dev) {
            return !ctx->has_device(dev);
         }, devs, devs + count))
      throw error(CL_INVALID_DEVICE);

   // Deserialize the provided binaries,
   auto modules = map(
      [](const unsigned char *p, size_t l) -> std::pair<cl_int, module> {
         if (!p || !l)
            return { CL_INVALID_VALUE, {} };

         try {
            compat::istream::buffer_t bin(p, l);
            compat::istream s(bin);

            return { CL_SUCCESS, module::deserialize(s) };

         } catch (compat::istream::error &e) {
            return { CL_INVALID_BINARY, {} };
         }
      },
      binaries, binaries + count, lengths);

   // update the status array,
   if (status_ret)
      std::transform(modules.begin(), modules.end(), status_ret,
                     keys<cl_int, module>);

   if (any_of(key_equals<cl_int, module>(CL_INVALID_VALUE),
              modules.begin(), modules.end()))
      throw error(CL_INVALID_VALUE);

   if (any_of(key_equals<cl_int, module>(CL_INVALID_BINARY),
              modules.begin(), modules.end()))
      throw error(CL_INVALID_BINARY);

   // initialize a program object with them.
   ret_error(errcode_ret, CL_SUCCESS);
   return new program(*ctx, { devs, devs + count },
                      map(values<cl_int, module>,
                          modules.begin(), modules.end()));

} catch (error &e) {
   ret_error(errcode_ret, e);
   return NULL;
}
Esempio n. 2
0
PUBLIC cl_command_queue
clCreateCommandQueue(cl_context ctx, cl_device_id dev,
                     cl_command_queue_properties props,
                     cl_int *errcode_ret) try {
   if (!ctx)
      throw error(CL_INVALID_CONTEXT);

   if (!ctx->has_device(dev))
      throw error(CL_INVALID_DEVICE);

   if (props & ~(CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE |
                 CL_QUEUE_PROFILING_ENABLE))
      throw error(CL_INVALID_VALUE);

   ret_error(errcode_ret, CL_SUCCESS);
   return new command_queue(*ctx, *dev, props);

} catch (error &e) {
   ret_error(errcode_ret, e);
   return NULL;
}