-
-
Notifications
You must be signed in to change notification settings - Fork 56.5k
Description
System information (version)
- OpenCV => 4.5.0 and master
- Operating System / Platform => Microsoft Windows [Version 10.0.19042.630]
- Compiler => VS Community 2019 v16.8.2
Detailed description
The reference count impl->addref() is missing in the supporting functions called by ocl::Context::create(string). PR including two test cases incoming.
opencv/modules/core/src/ocl.cpp
Lines 2437 to 2441 in 0105f8f
| if (impl) | |
| { | |
| CV_LOG_INFO(NULL, "OpenCL: reuse context@" << impl->contextId << " for configuration: " << configuration) | |
| return impl; | |
| } |
This was discovered as I was creating/binding the same GPU across multiple threads. I saw that the entries in the Context::Impl::getGlobalContainer() entries were being released before they should. And, a later ocl::Context::create(string) with the same string config would create a new context rather than reusing the existing one.
Code review also exposes the missing impl->addref() by comparing the three sibling findOrCreateContext().
And in a Debug build, the log to the console will show creation of new context rather than reuse.
Steps to reproduce
See test cases in PR. Or write your own via...
- Save current OpenCLExecutionContext
- Create three empty void* variables: p1, p2, p3
- Open a scope
- Create a new Context via a configuration string
- Create a OpenCLExecutionContext with that Context and the first device
- bind() that OpenCLExecutionContext
- Save handle within the Context via
context.ptr()to the p1 variable - End that scope
- Create a new scope
- Create a new Context via the same configuration string.
- Save handle within the Context via
context.ptr()to the p2 variable - End that 2nd scope. Note...due to this issue, the ref count of the Context stored in the getGlobalContainer() will go to zero and be deallocated/released.
- Create a new scope
- Create a new Context via the same configuration string. Due to this issue, and since the Context was prematurely released, a brand new Context will be created and inserted into the getGlobalContainer().
- Save handle within the Context via
context.ptr()to the p3 variable - End that 3rd scope
- Compare the values of all three void* variables
Result
p1 == p2 This is expected.
p2 != p3 This is errant
Expected
All three void* variables to contain the same memory address.
Notes
The PR includes two new test cases
- Expose this issue and verify its fix
- Verify the reverse behavior and that the correct number of
release()are called and the getGlobalContainer() entry cleared
Issue submission checklist
- I report the issue, it's not a question
- I checked the problem with documentation, FAQ, open issues,
answers.opencv.org, Stack Overflow, etc and have not found solution - I updated to latest OpenCV version and the issue is still there
- There is reproducer code and related data files: videos, images, onnx, etc