|
|
|
@ -2618,20 +2618,27 @@ internal::ProgramEntry::operator ProgramSource&() const |
|
|
|
|
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); |
|
|
|
@ -2649,26 +2656,41 @@ struct Program::Impl |
|
|
|
|
(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); |
|
|
|
@ -2676,6 +2698,7 @@ struct Program::Impl |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return handle != NULL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Impl(const String& _buf, const String& _buildflags) |
|
|
|
|