From d9ab31490c3204a561e9b8e9d716af3d5b21560e Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Fri, 8 Sep 2017 18:57:26 +0300 Subject: [PATCH] ocl: profiling queue --- modules/core/include/opencv2/core/ocl.hpp | 6 ++- modules/core/src/ocl.cpp | 66 ++++++++++++++++++++++- 2 files changed, 69 insertions(+), 3 deletions(-) diff --git a/modules/core/include/opencv2/core/ocl.hpp b/modules/core/include/opencv2/core/ocl.hpp index 12814e179f..08258235b9 100644 --- a/modules/core/include/opencv2/core/ocl.hpp +++ b/modules/core/include/opencv2/core/ocl.hpp @@ -333,8 +333,12 @@ public: void* ptr() const; static Queue& getDefault(); + /// @brief Returns OpenCL command queue with enable profiling mode support + const Queue& getProfilingQueue() const; + + struct Impl; friend struct Impl; + inline Impl* getImpl() const { return p; } protected: - struct Impl; Impl* p; }; diff --git a/modules/core/src/ocl.cpp b/modules/core/src/ocl.cpp index 8fea1d2b1e..fec2ab956d 100644 --- a/modules/core/src/ocl.cpp +++ b/modules/core/src/ocl.cpp @@ -1840,9 +1840,35 @@ void initializeContextFromHandle(Context& ctx, void* platform, void* _context, v struct Queue::Impl { - Impl(const Context& c, const Device& d) + inline void __init() { refcount = 1; + handle = 0; + isProfilingQueue_ = false; + } + + Impl(cl_command_queue q) + { + __init(); + handle = q; + + cl_command_queue_properties props = 0; + cl_int result = clGetCommandQueueInfo(handle, CL_QUEUE_PROPERTIES, sizeof(cl_command_queue_properties), &props, NULL); + CV_Assert(result && "clGetCommandQueueInfo(CL_QUEUE_PROPERTIES)"); + isProfilingQueue_ = !!(props & CL_QUEUE_PROFILING_ENABLE); + } + + Impl(cl_command_queue q, bool isProfilingQueue) + { + __init(); + handle = q; + isProfilingQueue_ = isProfilingQueue; + } + + Impl(const Context& c, const Device& d, bool withProfiling = false) + { + __init(); + const Context* pc = &c; cl_context ch = (cl_context)pc->ptr(); if( !ch ) @@ -1854,8 +1880,10 @@ struct Queue::Impl if( !dh ) dh = (cl_device_id)pc->device(0).ptr(); cl_int retval = 0; - handle = clCreateCommandQueue(ch, dh, 0, &retval); + cl_command_queue_properties props = withProfiling ? CL_QUEUE_PROFILING_ENABLE : 0; + handle = clCreateCommandQueue(ch, dh, props, &retval); CV_OclDbgAssert(retval == CL_SUCCESS); + isProfilingQueue_ = withProfiling; } ~Impl() @@ -1873,9 +1901,37 @@ struct Queue::Impl } } + const cv::ocl::Queue& getProfilingQueue(const cv::ocl::Queue& self) + { + if (isProfilingQueue_) + return self; + + if (profiling_queue_.ptr()) + return profiling_queue_; + + cl_context ctx = 0; + CV_Assert(CL_SUCCESS == clGetCommandQueueInfo(handle, CL_QUEUE_CONTEXT, sizeof(cl_context), &ctx, NULL)); + + cl_device_id device = 0; + CV_Assert(CL_SUCCESS == clGetCommandQueueInfo(handle, CL_QUEUE_DEVICE, sizeof(cl_device_id), &device, NULL)); + + cl_int result = CL_SUCCESS; + cl_command_queue_properties props = CL_QUEUE_PROFILING_ENABLE; + cl_command_queue q = clCreateCommandQueue(ctx, device, props, &result); + CV_Assert(result == CL_SUCCESS && "clCreateCommandQueue(with CL_QUEUE_PROFILING_ENABLE)"); + + Queue queue; + queue.p = new Impl(q, true); + profiling_queue_ = queue; + + return profiling_queue_; + } + IMPLEMENT_REFCOUNTABLE(); cl_command_queue handle; + bool isProfilingQueue_; + cv::ocl::Queue profiling_queue_; }; Queue::Queue() @@ -1929,6 +1985,12 @@ void Queue::finish() } } +const Queue& Queue::getProfilingQueue() const +{ + CV_Assert(p); + return p->getProfilingQueue(*this); +} + void* Queue::ptr() const { return p ? p->handle : 0;