@@ -180,6 +180,7 @@ void traceOpenCLCheck(cl_int status, const char* message)
180
180
static const bool CV_OPENCL_CACHE_ENABLE = utils::getConfigurationParameterBool(" OPENCV_OPENCL_CACHE_ENABLE" , true );
181
181
static const bool CV_OPENCL_CACHE_WRITE = utils::getConfigurationParameterBool(" OPENCV_OPENCL_CACHE_WRITE" , true );
182
182
static const bool CV_OPENCL_CACHE_LOCK_ENABLE = utils::getConfigurationParameterBool(" OPENCV_OPENCL_CACHE_LOCK_ENABLE" , true );
183
+ static const bool CV_OPENCL_CACHE_CLEANUP = utils::getConfigurationParameterBool(" OPENCV_OPENCL_CACHE_CLEANUP" , true );
183
184
184
185
#if CV_OPENCL_VALIDATE_BINARY_PROGRAMS
185
186
static const bool CV_OPENCL_VALIDATE_BINARY_PROGRAMS_VALUE = utils::getConfigurationParameterBool(" OPENCV_OPENCL_VALIDATE_BINARY_PROGRAMS" , false );
@@ -254,6 +255,7 @@ struct OpenCLBinaryCacheConfigurator
254
255
255
256
typedef std::map<std::string, std::string> ContextCacheType;
256
257
ContextCacheType prepared_contexts_;
258
+ Mutex mutex_prepared_contexts_;
257
259
258
260
OpenCLBinaryCacheConfigurator ()
259
261
{
@@ -355,14 +357,17 @@ struct OpenCLBinaryCacheConfigurator
355
357
cache_lock_.release ();
356
358
}
357
359
358
- std::string prepareCacheDirectoryForContext (const std::string& ctx_prefix)
360
+ std::string prepareCacheDirectoryForContext (const std::string& ctx_prefix,
361
+ const std::string& cleanup_prefix)
359
362
{
360
363
if (cache_path_.empty ())
361
364
return std::string ();
362
365
363
- ContextCacheType::iterator i = prepared_contexts_.find (ctx_prefix);
364
- if (i != prepared_contexts_.end ())
365
- return i->second ;
366
+ AutoLock lock (mutex_prepared_contexts_);
367
+
368
+ ContextCacheType::iterator found_it = prepared_contexts_.find (ctx_prefix);
369
+ if (found_it != prepared_contexts_.end ())
370
+ return found_it->second ;
366
371
367
372
CV_LOG_INFO (NULL , " Preparing OpenCL cache configuration for context: " << ctx_prefix);
368
373
@@ -390,8 +395,59 @@ struct OpenCLBinaryCacheConfigurator
390
395
target_directory = result ? target_directory : std::string ();
391
396
prepared_contexts_.insert (std::pair<std::string, std::string>(ctx_prefix, target_directory));
392
397
393
- CV_LOG_VERBOSE (NULL , 1 , " Result: " << (target_directory.empty () ? std::string (" Failed" ) : target_directory));
398
+ if (result && CV_OPENCL_CACHE_CLEANUP && CV_OPENCL_CACHE_WRITE && !cleanup_prefix.empty ())
399
+ {
400
+ try
401
+ {
402
+ std::vector<String> entries;
403
+ utils::fs::glob_relative (cache_path_, cleanup_prefix + " *" , entries, false , true );
404
+ std::vector<String> remove_entries;
405
+ for (size_t i = 0 ; i < entries.size (); i++)
406
+ {
407
+ const String& name = entries[i];
408
+ if (0 == name.find (cleanup_prefix))
409
+ {
410
+ if (0 == name.find (ctx_prefix))
411
+ continue ; // skip current
412
+ remove_entries.push_back (name);
413
+ }
414
+ }
415
+ if (!remove_entries.empty ())
416
+ {
417
+ CV_LOG_WARNING (NULL , (remove_entries.size () == 1
418
+ ? " Detected OpenCL cache directory for other version of OpenCL device."
419
+ : " Detected OpenCL cache directories for other versions of OpenCL device." )
420
+ << " We assume that these directories are obsolete after OpenCL runtime/drivers upgrade." );
421
+ CV_LOG_WARNING (NULL , " Trying to remove these directories..." );
422
+ for (size_t i = 0 ; i < remove_entries.size (); i++)
423
+ {
424
+ CV_LOG_WARNING (NULL , " - " << remove_entries[i]);
425
+ }
426
+ CV_LOG_WARNING (NULL ," Note: You can disable this behavior via this option: CV_OPENCL_CACHE_CLEANUP=0" );
427
+
428
+ for (size_t i = 0 ; i < remove_entries.size (); i++)
429
+ {
430
+ const String& name = remove_entries[i];
431
+ cv::String path = utils::fs::join (cache_path_, name);
432
+ try
433
+ {
434
+ utils::fs::remove_all (path);
435
+ CV_LOG_WARNING (NULL , " Removed: " << path);
436
+ }
437
+ catch (const cv::Exception& e)
438
+ {
439
+ CV_LOG_ERROR (NULL , " Exception during removal of obsolete OpenCL cache directory: " << path << std::endl << e.what ());
440
+ }
441
+ }
442
+ }
443
+ }
444
+ catch (...)
445
+ {
446
+ CV_LOG_WARNING (NULL , " Can't check for obsolete OpenCL cache directories" );
447
+ }
448
+ }
394
449
450
+ CV_LOG_VERBOSE (NULL , 1 , " Result: " << (target_directory.empty () ? std::string (" Failed" ) : target_directory));
395
451
return target_directory;
396
452
}
397
453
@@ -1969,7 +2025,7 @@ struct Context::Impl
1969
2025
}
1970
2026
}
1971
2027
1972
- std::string getPrefixString ()
2028
+ std::string& getPrefixString ()
1973
2029
{
1974
2030
if (prefix.empty ())
1975
2031
{
@@ -1988,12 +2044,32 @@ struct Context::Impl
1988
2044
return prefix;
1989
2045
}
1990
2046
2047
+ std::string& getPrefixBase ()
2048
+ {
2049
+ if (prefix_base.empty ())
2050
+ {
2051
+ const Device& d = devices[0 ];
2052
+ prefix_base = d.vendorName () + " --" + d.name () + " --" ;
2053
+ // sanitize chars
2054
+ for (size_t i = 0 ; i < prefix_base.size (); i++)
2055
+ {
2056
+ char c = prefix_base[i];
2057
+ if (!((c >= ' 0' && c <= ' 9' ) || (c >= ' a' && c <= ' z' ) || (c >= ' A' && c <= ' Z' ) || c == ' _' || c == ' -' ))
2058
+ {
2059
+ prefix_base[i] = ' _' ;
2060
+ }
2061
+ }
2062
+ }
2063
+ return prefix_base;
2064
+ }
2065
+
1991
2066
IMPLEMENT_REFCOUNTABLE ();
1992
2067
1993
2068
cl_context handle;
1994
2069
std::vector<Device> devices;
1995
2070
1996
2071
std::string prefix;
2072
+ std::string prefix_base;
1997
2073
1998
2074
cv::Mutex program_cache_mutex;
1999
2075
typedef std::map<std::string, Program> phash_t ;
@@ -3233,7 +3309,10 @@ struct Program::Impl
3233
3309
{
3234
3310
#if OPENCV_HAVE_FILESYSTEM_SUPPORT
3235
3311
OpenCLBinaryCacheConfigurator& config = OpenCLBinaryCacheConfigurator::getSingletonInstance ();
3236
- const std::string base_dir = config.prepareCacheDirectoryForContext (ctx.getImpl ()->getPrefixString ());
3312
+ const std::string base_dir = config.prepareCacheDirectoryForContext (
3313
+ ctx.getImpl ()->getPrefixString (),
3314
+ ctx.getImpl ()->getPrefixBase ()
3315
+ );
3237
3316
const std::string fname = base_dir.empty () ? std::string () :
3238
3317
std::string (base_dir + src.getImpl ()->module_ .c_str () + " --" + src.getImpl ()->name_ + " _" + src.getImpl ()->codeHash_ + " .bin" );
3239
3318
const cv::Ptr<utils::fs::FileLock> fileLock = config.cache_lock_ ; // can be empty
0 commit comments