Skip to content

Commit f5dba12

Browse files
committed
Merge pull request opencv#10180 from alalek:ocl_avoid_unnecessary_initialization
2 parents 86ff4a1 + 0ed3209 commit f5dba12

File tree

20 files changed

+114
-64
lines changed

20 files changed

+114
-64
lines changed

modules/calib3d/src/stereobm.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1108,7 +1108,7 @@ class StereoBMImpl : public StereoBM
11081108
int FILTERED = (params.minDisparity - 1) << disp_shift;
11091109

11101110
#ifdef HAVE_OPENCL
1111-
if(ocl::useOpenCL() && disparr.isUMat() && params.textureThreshold == 0)
1111+
if(ocl::isOpenCLActivated() && disparr.isUMat() && params.textureThreshold == 0)
11121112
{
11131113
UMat left, right;
11141114
if(ocl_prefiltering(leftarr, rightarr, left, right, &params))

modules/core/include/opencv2/core/opencl/ocl_defs.hpp

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,30 @@
55
// Copyright (C) 2014, Advanced Micro Devices, Inc., all rights reserved.
66
// Third party copyrights are property of their respective owners.
77

8+
#ifndef OPENCV_CORE_OPENCL_DEFS_HPP
9+
#define OPENCV_CORE_OPENCL_DEFS_HPP
10+
811
#include "opencv2/core/utility.hpp"
12+
#include "cvconfig.h"
13+
14+
namespace cv { namespace ocl {
15+
#ifdef HAVE_OPENCL
16+
/// Call is similar to useOpenCL() but doesn't try to load OpenCL runtime or create OpenCL context
17+
CV_EXPORTS bool isOpenCLActivated();
18+
#else
19+
static inline bool isOpenCLActivated() { return false; }
20+
#endif
21+
}} // namespace
22+
23+
924
//#define CV_OPENCL_RUN_ASSERT
1025

1126
#ifdef HAVE_OPENCL
1227

1328
#ifdef CV_OPENCL_RUN_VERBOSE
1429
#define CV_OCL_RUN_(condition, func, ...) \
1530
{ \
16-
if (cv::ocl::useOpenCL() && (condition) && func) \
31+
if (cv::ocl::isOpenCLActivated() && (condition) && func) \
1732
{ \
1833
printf("%s: OpenCL implementation is running\n", CV_Func); \
1934
fflush(stdout); \
@@ -29,7 +44,7 @@
2944
#elif defined CV_OPENCL_RUN_ASSERT
3045
#define CV_OCL_RUN_(condition, func, ...) \
3146
{ \
32-
if (cv::ocl::useOpenCL() && (condition)) \
47+
if (cv::ocl::isOpenCLActivated() && (condition)) \
3348
{ \
3449
if(func) \
3550
{ \
@@ -44,7 +59,7 @@
4459
}
4560
#else
4661
#define CV_OCL_RUN_(condition, func, ...) \
47-
if (cv::ocl::useOpenCL() && (condition) && func) \
62+
if (cv::ocl::isOpenCLActivated() && (condition) && func) \
4863
{ \
4964
CV_IMPL_ADD(CV_IMPL_OCL); \
5065
return __VA_ARGS__; \
@@ -56,3 +71,5 @@
5671
#endif
5772

5873
#define CV_OCL_RUN(condition, func) CV_OCL_RUN_(condition, func)
74+
75+
#endif // OPENCV_CORE_OPENCL_DEFS_HPP

modules/core/src/convert.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
#include "precomp.hpp"
4545

4646
#include "opencl_kernels_core.hpp"
47+
4748
#include "convert.hpp"
4849

4950
#include "opencv2/core/openvx/ovx_defs.hpp"
@@ -897,14 +898,16 @@ void cv::extractChannel(InputArray _src, OutputArray _dst, int coi)
897898
CV_Assert( 0 <= coi && coi < cn );
898899
int ch[] = { coi, 0 };
899900

900-
if (ocl::useOpenCL() && _src.dims() <= 2 && _dst.isUMat())
901+
#ifdef HAVE_OPENCL
902+
if (ocl::isOpenCLActivated() && _src.dims() <= 2 && _dst.isUMat())
901903
{
902904
UMat src = _src.getUMat();
903905
_dst.create(src.dims, &src.size[0], depth);
904906
UMat dst = _dst.getUMat();
905907
mixChannels(std::vector<UMat>(1, src), std::vector<UMat>(1, dst), ch, 1);
906908
return;
907909
}
910+
#endif
908911

909912
Mat src = _src.getMat();
910913
_dst.create(src.dims, &src.size[0], depth);
@@ -925,12 +928,14 @@ void cv::insertChannel(InputArray _src, InputOutputArray _dst, int coi)
925928
CV_Assert( 0 <= coi && coi < dcn && scn == 1 );
926929

927930
int ch[] = { 0, coi };
928-
if (ocl::useOpenCL() && _src.dims() <= 2 && _dst.isUMat())
931+
#ifdef HAVE_OPENCL
932+
if (ocl::isOpenCLActivated() && _src.dims() <= 2 && _dst.isUMat())
929933
{
930934
UMat src = _src.getUMat(), dst = _dst.getUMat();
931935
mixChannels(std::vector<UMat>(1, src), std::vector<UMat>(1, dst), ch, 1);
932936
return;
933937
}
938+
#endif
934939

935940
Mat src = _src.getMat(), dst = _dst.getMat();
936941

modules/core/src/ocl.cpp

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,7 @@ struct OpenCLBinaryCacheConfigurator
423423
{
424424
CV_LOG_WARNING(NULL, "- " << remove_entries[i]);
425425
}
426-
CV_LOG_WARNING(NULL,"Note: You can disable this behavior via this option: CV_OPENCL_CACHE_CLEANUP=0");
426+
CV_LOG_WARNING(NULL, "Note: You can disable this behavior via this option: OPENCV_OPENCL_CACHE_CLEANUP=0");
427427

428428
for (size_t i = 0; i < remove_entries.size(); i++)
429429
{
@@ -781,18 +781,34 @@ class BinaryProgramFile
781781
#endif // OPENCV_HAVE_FILESYSTEM_SUPPORT
782782

783783

784+
// true if we have initialized OpenCL subsystem with available platforms
785+
static bool g_isOpenCVActivated = false;
786+
784787
bool haveOpenCL()
785788
{
789+
CV_TRACE_FUNCTION();
786790
#ifdef HAVE_OPENCL
787791
static bool g_isOpenCLInitialized = false;
788792
static bool g_isOpenCLAvailable = false;
789793

790794
if (!g_isOpenCLInitialized)
791795
{
796+
CV_TRACE_REGION("Init_OpenCL_Runtime");
797+
const char* envPath = getenv("OPENCV_OPENCL_RUNTIME");
798+
if (envPath)
799+
{
800+
if (cv::String(envPath) == "disabled")
801+
{
802+
g_isOpenCLAvailable = false;
803+
g_isOpenCLInitialized = true;
804+
}
805+
}
806+
CV_LOG_INFO(NULL, "Initialize OpenCL runtime...");
792807
try
793808
{
794809
cl_uint n = 0;
795810
g_isOpenCLAvailable = ::clGetPlatformIDs(0, NULL, &n) == CL_SUCCESS;
811+
g_isOpenCVActivated = n > 0;
796812
}
797813
catch (...)
798814
{
@@ -813,7 +829,7 @@ bool useOpenCL()
813829
{
814830
try
815831
{
816-
data->useOpenCL = (int)haveOpenCL() && Device::getDefault().ptr() && Device::getDefault().available();
832+
data->useOpenCL = (int)(haveOpenCL() && Device::getDefault().ptr() && Device::getDefault().available()) ? 1 : 0;
817833
}
818834
catch (...)
819835
{
@@ -823,12 +839,27 @@ bool useOpenCL()
823839
return data->useOpenCL > 0;
824840
}
825841

842+
#ifdef HAVE_OPENCL
843+
bool isOpenCLActivated()
844+
{
845+
if (!g_isOpenCVActivated)
846+
return false; // prevent unnecessary OpenCL activation via useOpenCL()->haveOpenCL() calls
847+
return useOpenCL();
848+
}
849+
#endif
850+
826851
void setUseOpenCL(bool flag)
827852
{
828-
if( haveOpenCL() )
853+
CV_TRACE_FUNCTION();
854+
855+
CoreTLSData* data = getCoreTlsData().get();
856+
if (!flag)
829857
{
830-
CoreTLSData* data = getCoreTlsData().get();
831-
data->useOpenCL = (flag && Device::getDefault().ptr() != NULL) ? 1 : 0;
858+
data->useOpenCL = 0;
859+
}
860+
else if( haveOpenCL() )
861+
{
862+
data->useOpenCL = (Device::getDefault().ptr() != NULL) ? 1 : 0;
832863
}
833864
}
834865

@@ -5289,9 +5320,15 @@ class OpenCLAllocator : public MatAllocator
52895320
}
52905321
};
52915322

5323+
static OpenCLAllocator* getOpenCLAllocator_() // call once guarantee
5324+
{
5325+
static OpenCLAllocator* g_allocator = new OpenCLAllocator(); // avoid destrutor call (using of this object is too wide)
5326+
g_isOpenCVActivated = true;
5327+
return g_allocator;
5328+
}
52925329
MatAllocator* getOpenCLAllocator()
52935330
{
5294-
CV_SINGLETON_LAZY_INIT(MatAllocator, new OpenCLAllocator())
5331+
CV_SINGLETON_LAZY_INIT(MatAllocator, getOpenCLAllocator_())
52955332
}
52965333

52975334
}} // namespace cv::ocl

modules/core/src/trace.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
#include <opencv2/core/utils/trace.private.hpp>
99
#include <opencv2/core/utils/configuration.private.hpp>
1010

11+
#include <opencv2/core/opencl/ocl_defs.hpp>
12+
1113
#include <cstdarg> // va_start
1214

1315
#include <sstream>
@@ -596,7 +598,7 @@ void Region::destroy()
596598
#endif
597599
#ifdef HAVE_OPENCL
598600
case REGION_FLAG_IMPL_OPENCL:
599-
if (param_synchronizeOpenCL && cv::ocl::useOpenCL())
601+
if (param_synchronizeOpenCL && cv::ocl::isOpenCLActivated())
600602
cv::ocl::finish();
601603
myCodePath = Impl::CODE_PATH_OPENCL;
602604
break;

modules/core/src/umatrix.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ void UMatData::unlock()
141141
MatAllocator* UMat::getStdAllocator()
142142
{
143143
#ifdef HAVE_OPENCL
144-
if( ocl::haveOpenCL() && ocl::useOpenCL() )
144+
if (ocl::useOpenCL())
145145
return ocl::getOpenCLAllocator();
146146
#endif
147147
return Mat::getDefaultAllocator();

modules/features2d/src/fast.cpp

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -422,33 +422,27 @@ void FAST(InputArray _img, std::vector<KeyPoint>& keypoints, int threshold, bool
422422
{
423423
CV_INSTRUMENT_REGION()
424424

425-
#ifdef HAVE_OPENCL
426-
if( ocl::useOpenCL() && _img.isUMat() && type == FastFeatureDetector::TYPE_9_16 &&
427-
ocl_FAST(_img, keypoints, threshold, nonmax_suppression, 10000))
428-
{
429-
CV_IMPL_ADD(CV_IMPL_OCL);
430-
return;
431-
}
432-
#endif
425+
CV_OCL_RUN(_img.isUMat() && type == FastFeatureDetector::TYPE_9_16,
426+
ocl_FAST(_img, keypoints, threshold, nonmax_suppression, 10000));
433427

434428
CV_OVX_RUN(true,
435429
openvx_FAST(_img, keypoints, threshold, nonmax_suppression, type))
436430

437-
switch(type) {
431+
switch(type) {
438432
case FastFeatureDetector::TYPE_5_8:
439-
FAST_t<8>(_img, keypoints, threshold, nonmax_suppression);
440-
break;
433+
FAST_t<8>(_img, keypoints, threshold, nonmax_suppression);
434+
break;
441435
case FastFeatureDetector::TYPE_7_12:
442-
FAST_t<12>(_img, keypoints, threshold, nonmax_suppression);
443-
break;
436+
FAST_t<12>(_img, keypoints, threshold, nonmax_suppression);
437+
break;
444438
case FastFeatureDetector::TYPE_9_16:
445439
#ifdef HAVE_TEGRA_OPTIMIZATION
446-
if(tegra::useTegra() && tegra::FAST(_img, keypoints, threshold, nonmax_suppression))
447-
break;
440+
if(tegra::useTegra() && tegra::FAST(_img, keypoints, threshold, nonmax_suppression))
441+
break;
448442
#endif
449-
FAST_t<16>(_img, keypoints, threshold, nonmax_suppression);
450-
break;
451-
}
443+
FAST_t<16>(_img, keypoints, threshold, nonmax_suppression);
444+
break;
445+
}
452446
}
453447

454448

modules/features2d/src/kaze/AKAZEFeatures.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -520,7 +520,7 @@ convertScalePyramid(const std::vector<Evolution<MatTypeSrc> >& src, std::vector<
520520
*/
521521
void AKAZEFeatures::Create_Nonlinear_Scale_Space(InputArray image)
522522
{
523-
if (ocl::useOpenCL() && image.isUMat()) {
523+
if (ocl::isOpenCLActivated() && image.isUMat()) {
524524
// will run OCL version of scale space pyramid
525525
UMatPyramid uPyr;
526526
// init UMat pyramid with sizes

modules/features2d/src/matchers.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -771,7 +771,7 @@ void BFMatcher::knnMatchImpl( InputArray _queryDescriptors, std::vector<std::vec
771771
Size trainDescSize = trainDescCollection.empty() ? utrainDescCollection[0].size() : trainDescCollection[0].size();
772772
int trainDescOffset = trainDescCollection.empty() ? (int)utrainDescCollection[0].offset : 0;
773773

774-
if ( ocl::useOpenCL() && _queryDescriptors.isUMat() && _queryDescriptors.dims()<=2 && trainDescVectorSize == 1 &&
774+
if ( ocl::isOpenCLActivated() && _queryDescriptors.isUMat() && _queryDescriptors.dims()<=2 && trainDescVectorSize == 1 &&
775775
_queryDescriptors.type() == CV_32FC1 && _queryDescriptors.offset() == 0 && trainDescOffset == 0 &&
776776
trainDescSize.width == _queryDescriptors.size().width && masks.size() == 1 && masks[0].total() == 0 )
777777
{
@@ -919,7 +919,7 @@ void BFMatcher::radiusMatchImpl( InputArray _queryDescriptors, std::vector<std::
919919
Size trainDescSize = trainDescCollection.empty() ? utrainDescCollection[0].size() : trainDescCollection[0].size();
920920
int trainDescOffset = trainDescCollection.empty() ? (int)utrainDescCollection[0].offset : 0;
921921

922-
if ( ocl::useOpenCL() && _queryDescriptors.isUMat() && _queryDescriptors.dims()<=2 && trainDescVectorSize == 1 &&
922+
if ( ocl::isOpenCLActivated() && _queryDescriptors.isUMat() && _queryDescriptors.dims()<=2 && trainDescVectorSize == 1 &&
923923
_queryDescriptors.type() == CV_32FC1 && _queryDescriptors.offset() == 0 && trainDescOffset == 0 &&
924924
trainDescSize.width == _queryDescriptors.size().width && masks.size() == 1 && masks[0].total() == 0 )
925925
{

modules/features2d/src/orb.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -974,7 +974,7 @@ void ORB_Impl::detectAndCompute( InputArray _image, InputArray _mask,
974974
int descPatchSize = cvCeil(halfPatchSize*sqrt(2.0));
975975
int border = std::max(edgeThreshold, std::max(descPatchSize, HARRIS_BLOCK_SIZE/2))+1;
976976

977-
bool useOCL = ocl::useOpenCL() && OCL_FORCE_CHECK(_image.isUMat() || _descriptors.isUMat());
977+
bool useOCL = ocl::isOpenCLActivated() && OCL_FORCE_CHECK(_image.isUMat() || _descriptors.isUMat());
978978

979979
Mat image = _image.getMat(), mask = _mask.getMat();
980980
if( image.type() != CV_8UC1 )

0 commit comments

Comments
 (0)