Commit 6be25727 authored by Alexander Alekhin's avatar Alexander Alekhin Committed by Alexander Alekhin

ocl: refactor program compilation

parent 04b44954
...@@ -613,8 +613,10 @@ public: ...@@ -613,8 +613,10 @@ public:
String getPrefix() const; String getPrefix() const;
static String getPrefix(const String& buildflags); static String getPrefix(const String& buildflags);
protected:
struct Impl; struct Impl;
inline Impl* getImpl() const { return (Impl*)p; }
protected:
Impl* p; Impl* p;
}; };
...@@ -635,8 +637,9 @@ public: ...@@ -635,8 +637,9 @@ public:
const String& source() const; const String& source() const;
hash_t hash() const; // deprecated hash_t hash() const; // deprecated
protected:
struct Impl; struct Impl;
inline Impl* getImpl() const { return (Impl*)p; }
protected:
Impl* p; Impl* p;
}; };
......
...@@ -2618,20 +2618,27 @@ internal::ProgramEntry::operator ProgramSource&() const ...@@ -2618,20 +2618,27 @@ internal::ProgramEntry::operator ProgramSource&() const
struct Program::Impl struct Program::Impl
{ {
Impl(const ProgramSource& _src, 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; refcount = 1;
const Context& ctx = Context::getDefault(); compile(Context::getDefault(), errmsg);
src = _src; }
buildflags = _buildflags;
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 String& srcstr = src.source();
const char* srcptr = srcstr.c_str(); const char* srcptr = srcstr.c_str();
size_t srclen = srcstr.size(); size_t srclen = srcstr.size();
cl_int retval = 0; cl_int retval = 0;
handle = clCreateProgramWithSource((cl_context)ctx.ptr(), 1, &srcptr, &srclen, &retval); 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(); int i, n = (int)ctx.ndevices();
AutoBuffer<void*> deviceListBuf(n+1); AutoBuffer<void*> deviceListBuf(n+1);
...@@ -2649,26 +2656,41 @@ struct Program::Impl ...@@ -2649,26 +2656,41 @@ struct Program::Impl
(const cl_device_id*)deviceList, (const cl_device_id*)deviceList,
buildflags.c_str(), 0, 0); buildflags.c_str(), 0, 0);
#if !CV_OPENCL_ALWAYS_SHOW_BUILD_LOG #if !CV_OPENCL_ALWAYS_SHOW_BUILD_LOG
if( retval != CL_SUCCESS ) if (retval != CL_SUCCESS)
#endif #endif
{ {
AutoBuffer<char, 4096> buffer; buffer[0] = 0;
size_t retsz = 0; size_t retsz = 0;
cl_int buildInfo_retval = clGetProgramBuildInfo(handle, (cl_device_id)deviceList[0], cl_int log_retval = clGetProgramBuildInfo(handle, (cl_device_id)deviceList[0],
CL_PROGRAM_BUILD_LOG, 0, 0, &retsz); CL_PROGRAM_BUILD_LOG, 0, 0, &retsz);
if (buildInfo_retval == CL_SUCCESS && retsz > 1) if (log_retval == CL_SUCCESS && retsz > 1)
{ {
AutoBuffer<char> bufbuf(retsz + 16); buffer.resize(retsz + 16);
char* buf = bufbuf; log_retval = clGetProgramBuildInfo(handle, (cl_device_id)deviceList[0],
buildInfo_retval = clGetProgramBuildInfo(handle, (cl_device_id)deviceList[0], CL_PROGRAM_BUILD_LOG, retsz+1, (char*)buffer, &retsz);
CL_PROGRAM_BUILD_LOG, retsz+1, buf, &retsz); if (log_retval == CL_SUCCESS)
if (buildInfo_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 buffer[0] = 0;
errmsg = String(buf);
printf("OpenCL program build log: %s\n%s\n", buildflags.c_str(), errmsg.c_str());
fflush(stdout);
} }
} }
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) if (retval != CL_SUCCESS && handle)
{ {
clReleaseProgram(handle); clReleaseProgram(handle);
...@@ -2676,6 +2698,7 @@ struct Program::Impl ...@@ -2676,6 +2698,7 @@ struct Program::Impl
} }
} }
} }
return handle != NULL;
} }
Impl(const String& _buf, const String& _buildflags) Impl(const String& _buf, const String& _buildflags)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment