1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 //  By downloading, copying, installing or using the software you agree to this license.
6 //  If you do not agree to this license, do not download, install,
7 //  copy or use the software.
8 //
9 //
10 //                           License Agreement
11 //                For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2013, OpenCV Foundation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
15 //
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
18 //
19 //   * Redistribution's of source code must retain the above copyright notice,
20 //     this list of conditions and the following disclaimer.
21 //
22 //   * Redistribution's in binary form must reproduce the above copyright notice,
23 //     this list of conditions and the following disclaimer in the documentation
24 //     and/or other materials provided with the distribution.
25 //
26 //   * The name of the copyright holders may not be used to endorse or promote products
27 //     derived from this software without specific prior written permission.
28 //
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the OpenCV Foundation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
39 //
40 //M*/
41 
42 #ifndef OPENCV_OPENCL_HPP
43 #define OPENCV_OPENCL_HPP
44 
45 #include "opencv2/core.hpp"
46 #include <typeinfo>
47 #include <typeindex>
48 
49 namespace cv { namespace ocl {
50 
51 //! @addtogroup core_opencl
52 //! @{
53 
54 CV_EXPORTS_W bool haveOpenCL();
55 CV_EXPORTS_W bool useOpenCL();
56 CV_EXPORTS_W bool haveAmdBlas();
57 CV_EXPORTS_W bool haveAmdFft();
58 CV_EXPORTS_W void setUseOpenCL(bool flag);
59 CV_EXPORTS_W void finish();
60 
61 CV_EXPORTS bool haveSVM();
62 
63 class CV_EXPORTS Context;
64 class CV_EXPORTS_W_SIMPLE Device;
65 class CV_EXPORTS Kernel;
66 class CV_EXPORTS Program;
67 class CV_EXPORTS ProgramSource;
68 class CV_EXPORTS Queue;
69 class CV_EXPORTS PlatformInfo;
70 class CV_EXPORTS Image2D;
71 
72 class CV_EXPORTS_W_SIMPLE Device
73 {
74 public:
75     CV_WRAP Device() CV_NOEXCEPT;
76     explicit Device(void* d);
77     Device(const Device& d);
78     Device& operator = (const Device& d);
79     Device(Device&& d) CV_NOEXCEPT;
80     Device& operator = (Device&& d) CV_NOEXCEPT;
81     CV_WRAP ~Device();
82 
83     void set(void* d);
84 
85     enum
86     {
87         TYPE_DEFAULT     = (1 << 0),
88         TYPE_CPU         = (1 << 1),
89         TYPE_GPU         = (1 << 2),
90         TYPE_ACCELERATOR = (1 << 3),
91         TYPE_DGPU        = TYPE_GPU + (1 << 16),
92         TYPE_IGPU        = TYPE_GPU + (1 << 17),
93         TYPE_ALL         = 0xFFFFFFFF
94     };
95 
96     CV_WRAP String name() const;
97     CV_WRAP String extensions() const;
98     CV_WRAP bool isExtensionSupported(const String& extensionName) const;
99     CV_WRAP String version() const;
100     CV_WRAP String vendorName() const;
101     CV_WRAP String OpenCL_C_Version() const;
102     CV_WRAP String OpenCLVersion() const;
103     CV_WRAP int deviceVersionMajor() const;
104     CV_WRAP int deviceVersionMinor() const;
105     CV_WRAP String driverVersion() const;
106     void* ptr() const;
107 
108     CV_WRAP int type() const;
109 
110     CV_WRAP int addressBits() const;
111     CV_WRAP bool available() const;
112     CV_WRAP bool compilerAvailable() const;
113     CV_WRAP bool linkerAvailable() const;
114 
115     enum
116     {
117         FP_DENORM=(1 << 0),
118         FP_INF_NAN=(1 << 1),
119         FP_ROUND_TO_NEAREST=(1 << 2),
120         FP_ROUND_TO_ZERO=(1 << 3),
121         FP_ROUND_TO_INF=(1 << 4),
122         FP_FMA=(1 << 5),
123         FP_SOFT_FLOAT=(1 << 6),
124         FP_CORRECTLY_ROUNDED_DIVIDE_SQRT=(1 << 7)
125     };
126     CV_WRAP int doubleFPConfig() const;
127     CV_WRAP int singleFPConfig() const;
128     CV_WRAP int halfFPConfig() const;
129 
130     CV_WRAP bool endianLittle() const;
131     CV_WRAP bool errorCorrectionSupport() const;
132 
133     enum
134     {
135         EXEC_KERNEL=(1 << 0),
136         EXEC_NATIVE_KERNEL=(1 << 1)
137     };
138     CV_WRAP int executionCapabilities() const;
139 
140     CV_WRAP size_t globalMemCacheSize() const;
141 
142     enum
143     {
144         NO_CACHE=0,
145         READ_ONLY_CACHE=1,
146         READ_WRITE_CACHE=2
147     };
148     CV_WRAP int globalMemCacheType() const;
149     CV_WRAP int globalMemCacheLineSize() const;
150     CV_WRAP size_t globalMemSize() const;
151 
152     CV_WRAP size_t localMemSize() const;
153     enum
154     {
155         NO_LOCAL_MEM=0,
156         LOCAL_IS_LOCAL=1,
157         LOCAL_IS_GLOBAL=2
158     };
159     CV_WRAP int localMemType() const;
160     CV_WRAP bool hostUnifiedMemory() const;
161 
162     CV_WRAP bool imageSupport() const;
163 
164     CV_WRAP bool imageFromBufferSupport() const;
165     uint imagePitchAlignment() const;
166     uint imageBaseAddressAlignment() const;
167 
168     /// deprecated, use isExtensionSupported() method (probably with "cl_khr_subgroups" value)
169     CV_WRAP bool intelSubgroupsSupport() const;
170 
171     CV_WRAP size_t image2DMaxWidth() const;
172     CV_WRAP size_t image2DMaxHeight() const;
173 
174     CV_WRAP size_t image3DMaxWidth() const;
175     CV_WRAP size_t image3DMaxHeight() const;
176     CV_WRAP size_t image3DMaxDepth() const;
177 
178     CV_WRAP size_t imageMaxBufferSize() const;
179     CV_WRAP size_t imageMaxArraySize() const;
180 
181     enum
182     {
183         UNKNOWN_VENDOR=0,
184         VENDOR_AMD=1,
185         VENDOR_INTEL=2,
186         VENDOR_NVIDIA=3
187     };
188     CV_WRAP int vendorID() const;
189     // FIXIT
190     // dev.isAMD() doesn't work for OpenCL CPU devices from AMD OpenCL platform.
191     // This method should use platform name instead of vendor name.
192     // After fix restore code in arithm.cpp: ocl_compare()
isAMD() const193     CV_WRAP inline bool isAMD() const { return vendorID() == VENDOR_AMD; }
isIntel() const194     CV_WRAP inline bool isIntel() const { return vendorID() == VENDOR_INTEL; }
isNVidia() const195     CV_WRAP inline bool isNVidia() const { return vendorID() == VENDOR_NVIDIA; }
196 
197     CV_WRAP int maxClockFrequency() const;
198     CV_WRAP int maxComputeUnits() const;
199     CV_WRAP int maxConstantArgs() const;
200     CV_WRAP size_t maxConstantBufferSize() const;
201 
202     CV_WRAP size_t maxMemAllocSize() const;
203     CV_WRAP size_t maxParameterSize() const;
204 
205     CV_WRAP int maxReadImageArgs() const;
206     CV_WRAP int maxWriteImageArgs() const;
207     CV_WRAP int maxSamplers() const;
208 
209     CV_WRAP size_t maxWorkGroupSize() const;
210     CV_WRAP int maxWorkItemDims() const;
211     void maxWorkItemSizes(size_t*) const;
212 
213     CV_WRAP int memBaseAddrAlign() const;
214 
215     CV_WRAP int nativeVectorWidthChar() const;
216     CV_WRAP int nativeVectorWidthShort() const;
217     CV_WRAP int nativeVectorWidthInt() const;
218     CV_WRAP int nativeVectorWidthLong() const;
219     CV_WRAP int nativeVectorWidthFloat() const;
220     CV_WRAP int nativeVectorWidthDouble() const;
221     CV_WRAP int nativeVectorWidthHalf() const;
222 
223     CV_WRAP int preferredVectorWidthChar() const;
224     CV_WRAP int preferredVectorWidthShort() const;
225     CV_WRAP int preferredVectorWidthInt() const;
226     CV_WRAP int preferredVectorWidthLong() const;
227     CV_WRAP int preferredVectorWidthFloat() const;
228     CV_WRAP int preferredVectorWidthDouble() const;
229     CV_WRAP int preferredVectorWidthHalf() const;
230 
231     CV_WRAP size_t printfBufferSize() const;
232     CV_WRAP size_t profilingTimerResolution() const;
233 
234     CV_WRAP static const Device& getDefault();
235 
236     /**
237      * @param d OpenCL handle (cl_device_id). clRetainDevice() is called on success.
238      */
239     static Device fromHandle(void* d);
240 
241     struct Impl;
getImpl() const242     inline Impl* getImpl() const { return (Impl*)p; }
empty() const243     inline bool empty() const { return !p; }
244 protected:
245     Impl* p;
246 };
247 
248 
249 class CV_EXPORTS Context
250 {
251 public:
252     Context() CV_NOEXCEPT;
253     explicit Context(int dtype);  //!< @deprecated
254     ~Context();
255     Context(const Context& c);
256     Context& operator= (const Context& c);
257     Context(Context&& c) CV_NOEXCEPT;
258     Context& operator = (Context&& c) CV_NOEXCEPT;
259 
260     /** @deprecated */
261     bool create();
262     /** @deprecated */
263     bool create(int dtype);
264 
265     size_t ndevices() const;
266     Device& device(size_t idx) const;
267     Program getProg(const ProgramSource& prog,
268                     const String& buildopt, String& errmsg);
269     void unloadProg(Program& prog);
270 
271 
272     /** Get thread-local OpenCL context (initialize if necessary) */
273 #if 0  // OpenCV 5.0
274     static Context& getDefault();
275 #else
276     static Context& getDefault(bool initialize = true);
277 #endif
278 
279     /** @returns cl_context value */
280     void* ptr() const;
281 
282     /**
283      * @brief Get OpenCL context property specified on context creation
284      * @param propertyId Property id (CL_CONTEXT_* as defined in cl_context_properties type)
285      * @returns Property value if property was specified on clCreateContext, or NULL if context created without the property
286      */
287     void* getOpenCLContextProperty(int propertyId) const;
288 
289     bool useSVM() const;
290     void setUseSVM(bool enabled);
291 
292     /**
293      * @param context OpenCL handle (cl_context). clRetainContext() is called on success
294      */
295     static Context fromHandle(void* context);
296     static Context fromDevice(const ocl::Device& device);
297     static Context create(const std::string& configuration);
298 
299     void release();
300 
301     class CV_EXPORTS UserContext {
302     public:
303         virtual ~UserContext();
304     };
305     template <typename T>
setUserContext(const std::shared_ptr<T> & userContext)306     inline void setUserContext(const std::shared_ptr<T>& userContext) {
307         setUserContext(typeid(T), userContext);
308     }
309     template <typename T>
getUserContext()310     inline std::shared_ptr<T> getUserContext() {
311         return std::dynamic_pointer_cast<T>(getUserContext(typeid(T)));
312     }
313     void setUserContext(std::type_index typeId, const std::shared_ptr<UserContext>& userContext);
314     std::shared_ptr<UserContext> getUserContext(std::type_index typeId);
315 
316     struct Impl;
getImpl() const317     inline Impl* getImpl() const { return (Impl*)p; }
empty() const318     inline bool empty() const { return !p; }
319 // TODO OpenCV 5.0
320 //protected:
321     Impl* p;
322 };
323 
324 /** @deprecated */
325 class CV_EXPORTS Platform
326 {
327 public:
328     Platform() CV_NOEXCEPT;
329     ~Platform();
330     Platform(const Platform& p);
331     Platform& operator = (const Platform& p);
332     Platform(Platform&& p) CV_NOEXCEPT;
333     Platform& operator = (Platform&& p) CV_NOEXCEPT;
334 
335     void* ptr() const;
336 
337     /** @deprecated */
338     static Platform& getDefault();
339 
340     struct Impl;
getImpl() const341     inline Impl* getImpl() const { return (Impl*)p; }
empty() const342     inline bool empty() const { return !p; }
343 protected:
344     Impl* p;
345 };
346 
347 /** @brief Attaches OpenCL context to OpenCV
348 @note
349   OpenCV will check if available OpenCL platform has platformName name, then assign context to
350   OpenCV and call `clRetainContext` function. The deviceID device will be used as target device and
351   new command queue will be created.
352 @param platformName name of OpenCL platform to attach, this string is used to check if platform is available to OpenCV at runtime
353 @param platformID ID of platform attached context was created for
354 @param context OpenCL context to be attached to OpenCV
355 @param deviceID ID of device, must be created from attached context
356 */
357 CV_EXPORTS void attachContext(const String& platformName, void* platformID, void* context, void* deviceID);
358 
359 /** @brief Convert OpenCL buffer to UMat
360 @note
361   OpenCL buffer (cl_mem_buffer) should contain 2D image data, compatible with OpenCV. Memory
362   content is not copied from `clBuffer` to UMat. Instead, buffer handle assigned to UMat and
363   `clRetainMemObject` is called.
364 @param cl_mem_buffer source clBuffer handle
365 @param step num of bytes in single row
366 @param rows number of rows
367 @param cols number of cols
368 @param type OpenCV type of image
369 @param dst destination UMat
370 */
371 CV_EXPORTS void convertFromBuffer(void* cl_mem_buffer, size_t step, int rows, int cols, int type, UMat& dst);
372 
373 /** @brief Convert OpenCL image2d_t to UMat
374 @note
375   OpenCL `image2d_t` (cl_mem_image), should be compatible with OpenCV UMat formats. Memory content
376   is copied from image to UMat with `clEnqueueCopyImageToBuffer` function.
377 @param cl_mem_image source image2d_t handle
378 @param dst destination UMat
379 */
380 CV_EXPORTS void convertFromImage(void* cl_mem_image, UMat& dst);
381 
382 // TODO Move to internal header
383 /// @deprecated
384 void initializeContextFromHandle(Context& ctx, void* platform, void* context, void* device);
385 
386 class CV_EXPORTS Queue
387 {
388 public:
389     Queue() CV_NOEXCEPT;
390     explicit Queue(const Context& c, const Device& d=Device());
391     ~Queue();
392     Queue(const Queue& q);
393     Queue& operator = (const Queue& q);
394     Queue(Queue&& q) CV_NOEXCEPT;
395     Queue& operator = (Queue&& q) CV_NOEXCEPT;
396 
397     bool create(const Context& c=Context(), const Device& d=Device());
398     void finish();
399     void* ptr() const;
400     static Queue& getDefault();
401 
402     /// @brief Returns OpenCL command queue with enable profiling mode support
403     const Queue& getProfilingQueue() const;
404 
405     struct Impl; friend struct Impl;
getImpl() const406     inline Impl* getImpl() const { return p; }
empty() const407     inline bool empty() const { return !p; }
408 protected:
409     Impl* p;
410 };
411 
412 
413 class CV_EXPORTS KernelArg
414 {
415 public:
416     enum { LOCAL=1, READ_ONLY=2, WRITE_ONLY=4, READ_WRITE=6, CONSTANT=8, PTR_ONLY = 16, NO_SIZE=256 };
417     KernelArg(int _flags, UMat* _m, int wscale=1, int iwscale=1, const void* _obj=0, size_t _sz=0);
418     KernelArg() CV_NOEXCEPT;
419 
Local(size_t localMemSize)420     static KernelArg Local(size_t localMemSize)
421     { return KernelArg(LOCAL, 0, 1, 1, 0, localMemSize); }
PtrWriteOnly(const UMat & m)422     static KernelArg PtrWriteOnly(const UMat& m)
423     { return KernelArg(PTR_ONLY+WRITE_ONLY, (UMat*)&m); }
PtrReadOnly(const UMat & m)424     static KernelArg PtrReadOnly(const UMat& m)
425     { return KernelArg(PTR_ONLY+READ_ONLY, (UMat*)&m); }
PtrReadWrite(const UMat & m)426     static KernelArg PtrReadWrite(const UMat& m)
427     { return KernelArg(PTR_ONLY+READ_WRITE, (UMat*)&m); }
ReadWrite(const UMat & m,int wscale=1,int iwscale=1)428     static KernelArg ReadWrite(const UMat& m, int wscale=1, int iwscale=1)
429     { return KernelArg(READ_WRITE, (UMat*)&m, wscale, iwscale); }
ReadWriteNoSize(const UMat & m,int wscale=1,int iwscale=1)430     static KernelArg ReadWriteNoSize(const UMat& m, int wscale=1, int iwscale=1)
431     { return KernelArg(READ_WRITE+NO_SIZE, (UMat*)&m, wscale, iwscale); }
ReadOnly(const UMat & m,int wscale=1,int iwscale=1)432     static KernelArg ReadOnly(const UMat& m, int wscale=1, int iwscale=1)
433     { return KernelArg(READ_ONLY, (UMat*)&m, wscale, iwscale); }
WriteOnly(const UMat & m,int wscale=1,int iwscale=1)434     static KernelArg WriteOnly(const UMat& m, int wscale=1, int iwscale=1)
435     { return KernelArg(WRITE_ONLY, (UMat*)&m, wscale, iwscale); }
ReadOnlyNoSize(const UMat & m,int wscale=1,int iwscale=1)436     static KernelArg ReadOnlyNoSize(const UMat& m, int wscale=1, int iwscale=1)
437     { return KernelArg(READ_ONLY+NO_SIZE, (UMat*)&m, wscale, iwscale); }
WriteOnlyNoSize(const UMat & m,int wscale=1,int iwscale=1)438     static KernelArg WriteOnlyNoSize(const UMat& m, int wscale=1, int iwscale=1)
439     { return KernelArg(WRITE_ONLY+NO_SIZE, (UMat*)&m, wscale, iwscale); }
440     static KernelArg Constant(const Mat& m);
Constant(const _Tp * arr,size_t n)441     template<typename _Tp> static KernelArg Constant(const _Tp* arr, size_t n)
442     { return KernelArg(CONSTANT, 0, 1, 1, (void*)arr, n); }
443 
444     int flags;
445     UMat* m;
446     const void* obj;
447     size_t sz;
448     int wscale, iwscale;
449 };
450 
451 
452 class CV_EXPORTS Kernel
453 {
454 public:
455     Kernel() CV_NOEXCEPT;
456     Kernel(const char* kname, const Program& prog);
457     Kernel(const char* kname, const ProgramSource& prog,
458            const String& buildopts = String(), String* errmsg=0);
459     ~Kernel();
460     Kernel(const Kernel& k);
461     Kernel& operator = (const Kernel& k);
462     Kernel(Kernel&& k) CV_NOEXCEPT;
463     Kernel& operator = (Kernel&& k) CV_NOEXCEPT;
464 
465     bool empty() const;
466     bool create(const char* kname, const Program& prog);
467     bool create(const char* kname, const ProgramSource& prog,
468                 const String& buildopts, String* errmsg=0);
469 
470     int set(int i, const void* value, size_t sz);
471     int set(int i, const Image2D& image2D);
472     int set(int i, const UMat& m);
473     int set(int i, const KernelArg& arg);
set(int i,const _Tp & value)474     template<typename _Tp> int set(int i, const _Tp& value)
475     { return set(i, &value, sizeof(value)); }
476 
477 
478 protected:
479     template<typename _Tp0> inline
set_args_(int i,const _Tp0 & a0)480     int set_args_(int i, const _Tp0& a0) { return set(i, a0); }
481     template<typename _Tp0, typename... _Tps> inline
set_args_(int i,const _Tp0 & a0,const _Tps &...rest_args)482     int set_args_(int i, const _Tp0& a0, const _Tps&... rest_args) { i = set(i, a0); return set_args_(i, rest_args...); }
483 public:
484     /** @brief Setup OpenCL Kernel arguments.
485     Avoid direct using of set(i, ...) methods.
486     @code
487     bool ok = kernel
488         .args(
489             srcUMat, dstUMat,
490             (float)some_float_param
491         ).run(ndims, globalSize, localSize);
492     if (!ok) return false;
493     @endcode
494     */
495     template<typename... _Tps> inline
args(const _Tps &...kernel_args)496     Kernel& args(const _Tps&... kernel_args) { set_args_(0, kernel_args...); return *this; }
497 
498 
499     /** @brief Run the OpenCL kernel.
500     @param dims the work problem dimensions. It is the length of globalsize and localsize. It can be either 1, 2 or 3.
501     @param globalsize work items for each dimension. It is not the final globalsize passed to
502       OpenCL. Each dimension will be adjusted to the nearest integer divisible by the corresponding
503       value in localsize. If localsize is NULL, it will still be adjusted depending on dims. The
504       adjusted values are greater than or equal to the original values.
505     @param localsize work-group size for each dimension.
506     @param sync specify whether to wait for OpenCL computation to finish before return.
507     @param q command queue
508     */
509     bool run(int dims, size_t globalsize[],
510              size_t localsize[], bool sync, const Queue& q=Queue());
511     bool runTask(bool sync, const Queue& q=Queue());
512 
513     /** @brief Similar to synchronized run() call with returning of kernel execution time
514      * Separate OpenCL command queue may be used (with CL_QUEUE_PROFILING_ENABLE)
515      * @return Execution time in nanoseconds or negative number on error
516      */
517     int64 runProfiling(int dims, size_t globalsize[], size_t localsize[], const Queue& q=Queue());
518 
519     size_t workGroupSize() const;
520     size_t preferedWorkGroupSizeMultiple() const;
521     bool compileWorkGroupSize(size_t wsz[]) const;
522     size_t localMemSize() const;
523 
524     void* ptr() const;
525     struct Impl;
526 
527 protected:
528     Impl* p;
529 };
530 
531 class CV_EXPORTS Program
532 {
533 public:
534     Program() CV_NOEXCEPT;
535     Program(const ProgramSource& src,
536             const String& buildflags, String& errmsg);
537     Program(const Program& prog);
538     Program& operator = (const Program& prog);
539     Program(Program&& prog) CV_NOEXCEPT;
540     Program& operator = (Program&& prog) CV_NOEXCEPT;
541     ~Program();
542 
543     bool create(const ProgramSource& src,
544                 const String& buildflags, String& errmsg);
545 
546     void* ptr() const;
547 
548     /**
549      * @brief Query device-specific program binary.
550      *
551      * Returns RAW OpenCL executable binary without additional attachments.
552      *
553      * @sa ProgramSource::fromBinary
554      *
555      * @param[out] binary output buffer
556      */
557     void getBinary(std::vector<char>& binary) const;
558 
559     struct Impl; friend struct Impl;
getImpl() const560     inline Impl* getImpl() const { return (Impl*)p; }
empty() const561     inline bool empty() const { return !p; }
562 protected:
563     Impl* p;
564 public:
565 #ifndef OPENCV_REMOVE_DEPRECATED_API
566     // TODO Remove this
567     CV_DEPRECATED bool read(const String& buf, const String& buildflags); // removed, use ProgramSource instead
568     CV_DEPRECATED bool write(String& buf) const; // removed, use getBinary() method instead (RAW OpenCL binary)
569     CV_DEPRECATED const ProgramSource& source() const; // implementation removed
570     CV_DEPRECATED String getPrefix() const; // deprecated, implementation replaced
571     CV_DEPRECATED static String getPrefix(const String& buildflags); // deprecated, implementation replaced
572 #endif
573 };
574 
575 
576 class CV_EXPORTS ProgramSource
577 {
578 public:
579     typedef uint64 hash_t; // deprecated
580 
581     ProgramSource() CV_NOEXCEPT;
582     explicit ProgramSource(const String& module, const String& name, const String& codeStr, const String& codeHash);
583     explicit ProgramSource(const String& prog); // deprecated
584     explicit ProgramSource(const char* prog); // deprecated
585     ~ProgramSource();
586     ProgramSource(const ProgramSource& prog);
587     ProgramSource& operator = (const ProgramSource& prog);
588     ProgramSource(ProgramSource&& prog) CV_NOEXCEPT;
589     ProgramSource& operator = (ProgramSource&& prog) CV_NOEXCEPT;
590 
591     const String& source() const; // deprecated
592     hash_t hash() const; // deprecated
593 
594 
595     /** @brief Describe OpenCL program binary.
596      * Do not call clCreateProgramWithBinary() and/or clBuildProgram().
597      *
598      * Caller should guarantee binary buffer lifetime greater than ProgramSource object (and any of its copies).
599      *
600      * This kind of binary is not portable between platforms in general - it is specific to OpenCL vendor / device / driver version.
601      *
602      * @param module name of program owner module
603      * @param name unique name of program (module+name is used as key for OpenCL program caching)
604      * @param binary buffer address. See buffer lifetime requirement in description.
605      * @param size buffer size
606      * @param buildOptions additional program-related build options passed to clBuildProgram()
607      * @return created ProgramSource object
608      */
609     static ProgramSource fromBinary(const String& module, const String& name,
610             const unsigned char* binary, const size_t size,
611             const cv::String& buildOptions = cv::String());
612 
613     /** @brief Describe OpenCL program in SPIR format.
614      * Do not call clCreateProgramWithBinary() and/or clBuildProgram().
615      *
616      * Supports SPIR 1.2 by default (pass '-spir-std=X.Y' in buildOptions to override this behavior)
617      *
618      * Caller should guarantee binary buffer lifetime greater than ProgramSource object (and any of its copies).
619      *
620      * Programs in this format are portable between OpenCL implementations with 'khr_spir' extension:
621      * https://www.khronos.org/registry/OpenCL/sdk/2.0/docs/man/xhtml/cl_khr_spir.html
622      * (but they are not portable between different platforms: 32-bit / 64-bit)
623      *
624      * Note: these programs can't support vendor specific extensions, like 'cl_intel_subgroups'.
625      *
626      * @param module name of program owner module
627      * @param name unique name of program (module+name is used as key for OpenCL program caching)
628      * @param binary buffer address. See buffer lifetime requirement in description.
629      * @param size buffer size
630      * @param buildOptions additional program-related build options passed to clBuildProgram()
631      *        (these options are added automatically: '-x spir' and '-spir-std=1.2')
632      * @return created ProgramSource object.
633      */
634     static ProgramSource fromSPIR(const String& module, const String& name,
635             const unsigned char* binary, const size_t size,
636             const cv::String& buildOptions = cv::String());
637 
638     //OpenCL 2.1+ only
639     //static Program fromSPIRV(const String& module, const String& name,
640     //        const unsigned char* binary, const size_t size,
641     //        const cv::String& buildOptions = cv::String());
642 
643     struct Impl; friend struct Impl;
getImpl() const644     inline Impl* getImpl() const { return (Impl*)p; }
empty() const645     inline bool empty() const { return !p; }
646 protected:
647     Impl* p;
648 };
649 
650 class CV_EXPORTS PlatformInfo
651 {
652 public:
653     PlatformInfo() CV_NOEXCEPT;
654     /**
655      * @param id pointer cl_platform_id (cl_platform_id*)
656      */
657     explicit PlatformInfo(void* id);
658     ~PlatformInfo();
659 
660     PlatformInfo(const PlatformInfo& i);
661     PlatformInfo& operator =(const PlatformInfo& i);
662     PlatformInfo(PlatformInfo&& i) CV_NOEXCEPT;
663     PlatformInfo& operator = (PlatformInfo&& i) CV_NOEXCEPT;
664 
665     String name() const;
666     String vendor() const;
667 
668     /// See CL_PLATFORM_VERSION
669     String version() const;
670     int versionMajor() const;
671     int versionMinor() const;
672 
673     int deviceNumber() const;
674     void getDevice(Device& device, int d) const;
675 
676     struct Impl;
empty() const677     bool empty() const { return !p; }
678 protected:
679     Impl* p;
680 };
681 
682 CV_EXPORTS const char* convertTypeStr(int sdepth, int ddepth, int cn, char* buf);
683 CV_EXPORTS const char* typeToStr(int t);
684 CV_EXPORTS const char* memopTypeToStr(int t);
685 CV_EXPORTS const char* vecopTypeToStr(int t);
686 CV_EXPORTS const char* getOpenCLErrorString(int errorCode);
687 CV_EXPORTS String kernelToStr(InputArray _kernel, int ddepth = -1, const char * name = NULL);
688 CV_EXPORTS void getPlatfomsInfo(std::vector<PlatformInfo>& platform_info);
689 
690 
691 enum OclVectorStrategy
692 {
693     // all matrices have its own vector width
694     OCL_VECTOR_OWN = 0,
695     // all matrices have maximal vector width among all matrices
696     // (useful for cases when matrices have different data types)
697     OCL_VECTOR_MAX = 1,
698 
699     // default strategy
700     OCL_VECTOR_DEFAULT = OCL_VECTOR_OWN
701 };
702 
703 CV_EXPORTS int predictOptimalVectorWidth(InputArray src1, InputArray src2 = noArray(), InputArray src3 = noArray(),
704                                          InputArray src4 = noArray(), InputArray src5 = noArray(), InputArray src6 = noArray(),
705                                          InputArray src7 = noArray(), InputArray src8 = noArray(), InputArray src9 = noArray(),
706                                          OclVectorStrategy strat = OCL_VECTOR_DEFAULT);
707 
708 CV_EXPORTS int checkOptimalVectorWidth(const int *vectorWidths,
709                                        InputArray src1, InputArray src2 = noArray(), InputArray src3 = noArray(),
710                                        InputArray src4 = noArray(), InputArray src5 = noArray(), InputArray src6 = noArray(),
711                                        InputArray src7 = noArray(), InputArray src8 = noArray(), InputArray src9 = noArray(),
712                                        OclVectorStrategy strat = OCL_VECTOR_DEFAULT);
713 
714 // with OCL_VECTOR_MAX strategy
715 CV_EXPORTS int predictOptimalVectorWidthMax(InputArray src1, InputArray src2 = noArray(), InputArray src3 = noArray(),
716                                             InputArray src4 = noArray(), InputArray src5 = noArray(), InputArray src6 = noArray(),
717                                             InputArray src7 = noArray(), InputArray src8 = noArray(), InputArray src9 = noArray());
718 
719 CV_EXPORTS void buildOptionsAddMatrixDescription(String& buildOptions, const String& name, InputArray _m);
720 
721 class CV_EXPORTS Image2D
722 {
723 public:
724     Image2D() CV_NOEXCEPT;
725 
726     /**
727     @param src UMat object from which to get image properties and data
728     @param norm flag to enable the use of normalized channel data types
729     @param alias flag indicating that the image should alias the src UMat. If true, changes to the
730         image or src will be reflected in both objects.
731     */
732     explicit Image2D(const UMat &src, bool norm = false, bool alias = false);
733     Image2D(const Image2D & i);
734     ~Image2D();
735 
736     Image2D & operator = (const Image2D & i);
737     Image2D(Image2D &&) CV_NOEXCEPT;
738     Image2D &operator=(Image2D &&) CV_NOEXCEPT;
739 
740     /** Indicates if creating an aliased image should succeed.
741     Depends on the underlying platform and the dimensions of the UMat.
742     */
743     static bool canCreateAlias(const UMat &u);
744 
745     /** Indicates if the image format is supported.
746     */
747     static bool isFormatSupported(int depth, int cn, bool norm);
748 
749     void* ptr() const;
750 protected:
751     struct Impl;
752     Impl* p;
753 };
754 
755 class CV_EXPORTS Timer
756 {
757 public:
758     Timer(const Queue& q);
759     ~Timer();
760     void start();
761     void stop();
762 
763     uint64 durationNS() const; //< duration in nanoseconds
764 
765 protected:
766     struct Impl;
767     Impl* const p;
768 
769 private:
770     Timer(const Timer&); // disabled
771     Timer& operator=(const Timer&); // disabled
772 };
773 
774 CV_EXPORTS MatAllocator* getOpenCLAllocator();
775 
776 
777 class CV_EXPORTS_W OpenCLExecutionContext
778 {
779 public:
780     OpenCLExecutionContext() = default;
781     ~OpenCLExecutionContext() = default;
782 
783     OpenCLExecutionContext(const OpenCLExecutionContext&) = default;
784     OpenCLExecutionContext(OpenCLExecutionContext&&) = default;
785 
786     OpenCLExecutionContext& operator=(const OpenCLExecutionContext&) = default;
787     OpenCLExecutionContext& operator=(OpenCLExecutionContext&&) = default;
788 
789     /** Get associated ocl::Context */
790     Context& getContext() const;
791     /** Get the single default associated ocl::Device */
792     Device& getDevice() const;
793     /** Get the single ocl::Queue that is associated with the ocl::Context and
794      *  the single default ocl::Device
795      */
796     Queue& getQueue() const;
797 
798     bool useOpenCL() const;
799     void setUseOpenCL(bool flag);
800 
801     /** Get OpenCL execution context of current thread.
802      *
803      * Initialize OpenCL execution context if it is empty
804      * - create new
805      * - reuse context of the main thread (threadID = 0)
806      */
807     static OpenCLExecutionContext& getCurrent();
808 
809     /** Get OpenCL execution context of current thread (can be empty) */
810     static OpenCLExecutionContext& getCurrentRef();
811 
812     /** Bind this OpenCL execution context to current thread.
813      *
814      * Context can't be empty.
815      *
816      * @note clFinish is not called for queue of previous execution context
817      */
818     void bind() const;
819 
820     /** Creates new execution context with same OpenCV context and device
821      *
822      * @param q OpenCL queue
823      */
824     OpenCLExecutionContext cloneWithNewQueue(const ocl::Queue& q) const;
825     /** @overload */
826     OpenCLExecutionContext cloneWithNewQueue() const;
827 
828     /** @brief Creates OpenCL execution context
829      * OpenCV will check if available OpenCL platform has platformName name, then assign context to
830      * OpenCV and call `clRetainContext` function. The deviceID device will be used as target device and
831      * new command queue will be created.
832      *
833      * @note Lifetime of passed handles is transferred to OpenCV wrappers on success
834      *
835      * @param platformName name of OpenCL platform to attach, this string is used to check if platform is available to OpenCV at runtime
836      * @param platformID ID of platform attached context was created for (cl_platform_id)
837      * @param context OpenCL context to be attached to OpenCV (cl_context)
838      * @param deviceID OpenCL device (cl_device_id)
839      */
840     static OpenCLExecutionContext create(const std::string& platformName, void* platformID, void* context, void* deviceID);
841 
842     /** @brief Creates OpenCL execution context
843      *
844      * @param context non-empty OpenCL context
845      * @param device non-empty OpenCL device (must be a part of context)
846      * @param queue non-empty OpenCL queue for provided context and device
847      */
848     static OpenCLExecutionContext create(const Context& context, const Device& device, const ocl::Queue& queue);
849     /** @overload */
850     static OpenCLExecutionContext create(const Context& context, const Device& device);
851 
852     struct Impl;
empty() const853     inline bool empty() const { return !p; }
854     void release();
855 protected:
856     std::shared_ptr<Impl> p;
857 };
858 
859 class OpenCLExecutionContextScope
860 {
861     OpenCLExecutionContext ctx_;
862 public:
OpenCLExecutionContextScope(const OpenCLExecutionContext & ctx)863     inline OpenCLExecutionContextScope(const OpenCLExecutionContext& ctx)
864     {
865         CV_Assert(!ctx.empty());
866         ctx_ = OpenCLExecutionContext::getCurrentRef();
867         ctx.bind();
868     }
869 
~OpenCLExecutionContextScope()870     inline ~OpenCLExecutionContextScope()
871     {
872         if (!ctx_.empty())
873         {
874             ctx_.bind();
875         }
876     }
877 };
878 
879 #ifdef __OPENCV_BUILD
880 namespace internal {
881 
882 CV_EXPORTS bool isOpenCLForced();
883 #define OCL_FORCE_CHECK(condition) (cv::ocl::internal::isOpenCLForced() || (condition))
884 
885 CV_EXPORTS bool isPerformanceCheckBypassed();
886 #define OCL_PERFORMANCE_CHECK(condition) (cv::ocl::internal::isPerformanceCheckBypassed() || (condition))
887 
888 CV_EXPORTS bool isCLBuffer(UMat& u);
889 
890 } // namespace internal
891 #endif
892 
893 //! @}
894 
895 }}
896 
897 #endif
898