Clover Git
OpenCL 1.1 software implementation

api_program.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2011, Denis Steckelmacher <steckdenis@yahoo.fr>
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  *     * Redistributions of source code must retain the above copyright
00008  *       notice, this list of conditions and the following disclaimer.
00009  *     * Redistributions in binary form must reproduce the above copyright
00010  *       notice, this list of conditions and the following disclaimer in the
00011  *       documentation and/or other materials provided with the distribution.
00012  *     * Neither the name of the copyright holder nor the
00013  *       names of its contributors may be used to endorse or promote products
00014  *       derived from this software without specific prior written permission.
00015  *
00016  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00017  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00018  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00019  * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
00020  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00021  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00022  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00023  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00024  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00025  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026  */
00027 
00033 #include "CL/cl.h"
00034 #include <core/program.h>
00035 #include <core/context.h>
00036 
00037 #include <cstdlib>
00038 
00039 // Program Object APIs
00040 cl_program
00041 clCreateProgramWithSource(cl_context        context,
00042                           cl_uint           count,
00043                           const char **     strings,
00044                           const size_t *    lengths,
00045                           cl_int *          errcode_ret)
00046 {
00047     cl_int dummy_errcode;
00048 
00049     if (!errcode_ret)
00050         errcode_ret = &dummy_errcode;
00051 
00052     if (!context->isA(Coal::Object::T_Context))
00053     {
00054         *errcode_ret = CL_INVALID_CONTEXT;
00055         return 0;
00056     }
00057 
00058     if (!count || !strings)
00059     {
00060         *errcode_ret = CL_INVALID_VALUE;
00061         return 0;
00062     }
00063 
00064     Coal::Program *program = new Coal::Program(context);
00065 
00066     *errcode_ret = CL_SUCCESS;
00067     *errcode_ret = program->loadSources(count, strings, lengths);
00068 
00069     if (*errcode_ret != CL_SUCCESS)
00070     {
00071         delete program;
00072         return 0;
00073     }
00074 
00075     return (cl_program)program;
00076 }
00077 
00078 cl_program
00079 clCreateProgramWithBinary(cl_context            context,
00080                           cl_uint               num_devices,
00081                           const cl_device_id *  device_list,
00082                           const size_t *        lengths,
00083                           const unsigned char **binaries,
00084                           cl_int *              binary_status,
00085                           cl_int *              errcode_ret)
00086 {
00087     cl_int dummy_errcode;
00088 
00089     if (!errcode_ret)
00090         errcode_ret = &dummy_errcode;
00091 
00092     if (!context->isA(Coal::Object::T_Context))
00093     {
00094         *errcode_ret = CL_INVALID_CONTEXT;
00095         return 0;
00096     }
00097 
00098     if (!num_devices || !device_list || !lengths || !binaries)
00099     {
00100         *errcode_ret = CL_INVALID_VALUE;
00101         return 0;
00102     }
00103 
00104     // Check the devices for compliance
00105     cl_uint context_num_devices = 0;
00106     cl_device_id *context_devices;
00107 
00108     *errcode_ret = context->info(CL_CONTEXT_NUM_DEVICES, sizeof(cl_uint),
00109                                  &context_num_devices, 0);
00110 
00111     if (*errcode_ret != CL_SUCCESS)
00112         return 0;
00113 
00114     context_devices =
00115         (cl_device_id *)std::malloc(context_num_devices * sizeof(cl_device_id));
00116 
00117     *errcode_ret = context->info(CL_CONTEXT_DEVICES,
00118                                  context_num_devices * sizeof(cl_device_id),
00119                                  context_devices, 0);
00120 
00121     if (*errcode_ret != CL_SUCCESS)
00122         return 0;
00123 
00124     for (cl_uint i=0; i<num_devices; ++i)
00125     {
00126         bool found = false;
00127 
00128         if (!lengths[i] || !binaries[i])
00129         {
00130             if (binary_status)
00131                 binary_status[i] = CL_INVALID_VALUE;
00132 
00133             *errcode_ret = CL_INVALID_VALUE;
00134             return 0;
00135         }
00136 
00137         for (cl_uint j=0; j<context_num_devices; ++j)
00138         {
00139             if (device_list[i] == context_devices[j])
00140             {
00141                 found = true;
00142                 break;
00143             }
00144         }
00145 
00146         if (!found)
00147         {
00148             *errcode_ret = CL_INVALID_DEVICE;
00149             return 0;
00150         }
00151     }
00152 
00153     // Create a program
00154     Coal::Program *program = new Coal::Program(context);
00155     *errcode_ret = CL_SUCCESS;
00156 
00157     // Init program
00158     *errcode_ret = program->loadBinaries(binaries,
00159                                          lengths, binary_status, num_devices,
00160                                          (Coal::DeviceInterface * const*)device_list);
00161 
00162     if (*errcode_ret != CL_SUCCESS)
00163     {
00164         delete program;
00165         return 0;
00166     }
00167 
00168     return (cl_program)program;
00169 }
00170 
00171 cl_int
00172 clRetainProgram(cl_program program)
00173 {
00174     if (!program->isA(Coal::Object::T_Program))
00175         return CL_INVALID_PROGRAM;
00176 
00177     program->reference();
00178 
00179     return CL_SUCCESS;
00180 }
00181 
00182 cl_int
00183 clReleaseProgram(cl_program program)
00184 {
00185     if (!program->isA(Coal::Object::T_Program))
00186         return CL_INVALID_PROGRAM;
00187 
00188     if (program->dereference())
00189         delete program;
00190 
00191     return CL_SUCCESS;
00192 }
00193 
00194 cl_int
00195 clBuildProgram(cl_program           program,
00196                cl_uint              num_devices,
00197                const cl_device_id * device_list,
00198                const char *         options,
00199                void (*pfn_notify)(cl_program program, void * user_data),
00200                void *               user_data)
00201 {
00202     if (!program->isA(Coal::Object::T_Program))
00203         return CL_INVALID_PROGRAM;
00204 
00205     if (!device_list && num_devices > 0)
00206         return CL_INVALID_VALUE;
00207 
00208     if (!num_devices && device_list)
00209         return CL_INVALID_VALUE;
00210 
00211     if (!pfn_notify && user_data)
00212         return CL_INVALID_VALUE;
00213 
00214     // Check the devices for compliance
00215     if (num_devices)
00216     {
00217         cl_uint context_num_devices = 0;
00218         cl_device_id *context_devices;
00219         Coal::Context *context = (Coal::Context *)program->parent();
00220         cl_int result;
00221 
00222         result = context->info(CL_CONTEXT_NUM_DEVICES, sizeof(cl_uint),
00223                                      &context_num_devices, 0);
00224 
00225         if (result != CL_SUCCESS)
00226             return result;
00227 
00228         context_devices =
00229             (cl_device_id *)std::malloc(context_num_devices * sizeof(cl_device_id));
00230 
00231         result = context->info(CL_CONTEXT_DEVICES,
00232                                      context_num_devices * sizeof(cl_device_id),
00233                                      context_devices, 0);
00234 
00235         if (result != CL_SUCCESS)
00236             return result;
00237 
00238         for (cl_uint i=0; i<num_devices; ++i)
00239         {
00240             bool found = false;
00241 
00242             for (cl_uint j=0; j<context_num_devices; ++j)
00243             {
00244                 if (device_list[i] == context_devices[j])
00245                 {
00246                     found = true;
00247                     break;
00248                 }
00249             }
00250 
00251             if (!found)
00252                 return CL_INVALID_DEVICE;
00253         }
00254     }
00255 
00256     // We cannot try to build a previously-failed program
00257     if (program->state() != Coal::Program::Loaded)
00258         return CL_INVALID_OPERATION;
00259 
00260     // Build program
00261     return program->build(options, pfn_notify, user_data, num_devices,
00262                           (Coal::DeviceInterface * const*)device_list);
00263 }
00264 
00265 cl_int
00266 clUnloadCompiler(void)
00267 {
00268     return CL_SUCCESS;
00269 }
00270 
00271 cl_int
00272 clGetProgramInfo(cl_program         program,
00273                  cl_program_info    param_name,
00274                  size_t             param_value_size,
00275                  void *             param_value,
00276                  size_t *           param_value_size_ret)
00277 {
00278     if (!program->isA(Coal::Object::T_Program))
00279         return CL_INVALID_PROGRAM;
00280 
00281     return program->info(param_name, param_value_size, param_value,
00282                          param_value_size_ret);
00283 }
00284 
00285 cl_int
00286 clGetProgramBuildInfo(cl_program            program,
00287                       cl_device_id          device,
00288                       cl_program_build_info param_name,
00289                       size_t                param_value_size,
00290                       void *                param_value,
00291                       size_t *              param_value_size_ret)
00292 {
00293     if (!program->isA(Coal::Object::T_Program))
00294         return CL_INVALID_PROGRAM;
00295 
00296     return program->buildInfo((Coal::DeviceInterface *)device, param_name,
00297                               param_value_size, param_value,
00298                               param_value_size_ret);
00299 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines