struct Program::Impl
{
Impl(const ProgramSource& _src,
- const String& _buildflags, String& errmsg)
+ const String& _buildflags, String& errmsg) :
+ src(_src),
+ buildflags(_buildflags),
+ handle(NULL)
{
- CV_INSTRUMENT_REGION_OPENCL_COMPILE(cv::format("Compile: %" PRIx64 " options: %s", _src.hash(), _buildflags.c_str()).c_str());
refcount = 1;
- const Context& ctx = Context::getDefault();
- src = _src;
- buildflags = _buildflags;
+ compile(Context::getDefault(), errmsg);
+ }
+
+ bool compile(const Context& ctx, String& errmsg)
+ {
+ CV_Assert(handle == NULL);
+ CV_INSTRUMENT_REGION_OPENCL_COMPILE(cv::format("Compile: %" PRIx64 " options: %s", src.hash(), buildflags.c_str()).c_str());
const String& srcstr = src.source();
const char* srcptr = srcstr.c_str();
size_t srclen = srcstr.size();
cl_int retval = 0;
handle = clCreateProgramWithSource((cl_context)ctx.ptr(), 1, &srcptr, &srclen, &retval);
- if( handle && retval == CL_SUCCESS )
+ CV_OclDbgAssert(handle && retval == CL_SUCCESS);
+ if (handle && retval == CL_SUCCESS)
{
int i, n = (int)ctx.ndevices();
AutoBuffer<void*> deviceListBuf(n+1);
(const cl_device_id*)deviceList,
buildflags.c_str(), 0, 0);
#if !CV_OPENCL_ALWAYS_SHOW_BUILD_LOG
- if( retval != CL_SUCCESS )
+ if (retval != CL_SUCCESS)
#endif
{
+ AutoBuffer<char, 4096> buffer; buffer[0] = 0;
+
size_t retsz = 0;
- cl_int buildInfo_retval = clGetProgramBuildInfo(handle, (cl_device_id)deviceList[0],
- CL_PROGRAM_BUILD_LOG, 0, 0, &retsz);
- if (buildInfo_retval == CL_SUCCESS && retsz > 1)
+ cl_int log_retval = clGetProgramBuildInfo(handle, (cl_device_id)deviceList[0],
+ CL_PROGRAM_BUILD_LOG, 0, 0, &retsz);
+ if (log_retval == CL_SUCCESS && retsz > 1)
{
- AutoBuffer<char> bufbuf(retsz + 16);
- char* buf = bufbuf;
- buildInfo_retval = clGetProgramBuildInfo(handle, (cl_device_id)deviceList[0],
- CL_PROGRAM_BUILD_LOG, retsz+1, buf, &retsz);
- if (buildInfo_retval == CL_SUCCESS)
+ buffer.resize(retsz + 16);
+ log_retval = clGetProgramBuildInfo(handle, (cl_device_id)deviceList[0],
+ CL_PROGRAM_BUILD_LOG, retsz+1, (char*)buffer, &retsz);
+ if (log_retval == CL_SUCCESS)
+ {
+ if (retsz < buffer.size())
+ buffer[retsz] = 0;
+ else
+ buffer[buffer.size() - 1] = 0;
+ }
+ else
{
- // TODO It is useful to see kernel name & program file name also
- errmsg = String(buf);
- printf("OpenCL program build log: %s\n%s\n", buildflags.c_str(), errmsg.c_str());
- fflush(stdout);
+ buffer[0] = 0;
}
}
+
+ errmsg = String(buffer);
+ printf("OpenCL program build log: %s (%s)\nStatus %d: %s\n%s\n%s\n",
+ src.getImpl()->name_.c_str(), src.getImpl()->module_.c_str(),
+ retval, getOpenCLErrorString(retval),
+ buildflags.c_str(), errmsg.c_str());
+ fflush(stdout);
+
+ // don't remove "retval != CL_SUCCESS" condition here:
+ // it would break CV_OPENCL_ALWAYS_SHOW_BUILD_LOG mode
if (retval != CL_SUCCESS && handle)
{
clReleaseProgram(handle);
}
}
}
+ return handle != NULL;
}
Impl(const String& _buf, const String& _buildflags)