changed UMataData allocatorContext to OpenCLExecutionContext#24326
changed UMataData allocatorContext to OpenCLExecutionContext#24326kallaballa wants to merge 18 commits intoopencv:4.xfrom
Conversation
… it via scope everywhere needed
|
Fixed a problem that was preventing UMat to UMat copy always |
|
@opencv-alalek could you review? |
|
To reproduce problem build locally with |
|
Oh my! Of course. please hold your horses. I'll fix that. |
|
Doc build complains about trailing white space. gonna push a fix once this build has finished |
|
Seeing the fails and will fix. |
|
What is the best way to reproduce those cases? is the build configuration available? |
|
Failed builds are with OpenCL (default). With / without OpenCL device available (both fails). |
|
Thanks! On it right now. |
|
fixed: 784d86a |
|
[ FAILED ] 16 tests, listed below: That sounds serious. Best course of action is a Window 10 VM and building with tests? |
|
It's the same issue. |
opencv-alalek
left a comment
There was a problem hiding this comment.
Please add tests for related use cases here: https://github.com/opencv/opencv/blob/4.x/modules/core/test/test_opencl.cpp
modules/core/src/ocl.cpp
Outdated
| if( arg.m ) | ||
| { | ||
| std::shared_ptr<ocl::OpenCLExecutionContext> pExecCtx = std::static_pointer_cast<ocl::OpenCLExecutionContext>(arg.m->u->allocatorContext); | ||
| OpenCLExecutionContextScope scope(pExecCtx ? *pExecCtx.get() : ocl::OpenCLExecutionContext::getCurrent()); |
There was a problem hiding this comment.
Kernel::
OpenCLExecutionContextScope
We should not change the current context selected by caller.
We need to ensure that:
- kernel is from the current (default)
OpenCLExecutionContext(or assume that) - and all passed buffers are compatible with the current (default)
OpenCLExecutionContext(the same "OpenCL context")
If it is not true, then raise an error.
There was a problem hiding this comment.
How to properly compare to OpenCLExecutionContexts? I'd write the operator, but I don't know what to compare.
There was a problem hiding this comment.
"OpenCL context" means handle of type cl_context.
E.g. compare these values related to OpenCLExecutionContexts: execCtx.getContext().ptr()
modules/core/src/umatrix.cpp
Outdated
| #ifdef HAVE_OPENCL | ||
| std::shared_ptr<ocl::OpenCLExecutionContext> pExecCtxSrc = std::static_pointer_cast<ocl::OpenCLExecutionContext>(u->allocatorContext); | ||
| std::shared_ptr<ocl::OpenCLExecutionContext> pExecCtxDst = std::static_pointer_cast<ocl::OpenCLExecutionContext>(dst.u->allocatorContext); | ||
| if ((pExecCtxSrc && pExecCtxDst && pExecCtxSrc->getContext().ptr() == pExecCtxDst->getContext().ptr()) && u->currAllocator == dst.u->currAllocator) |
There was a problem hiding this comment.
dst should belong to the current context.
if src is not related to the current context then we should force OpenCLExecutionContextScope below
Mat dst = _dst.getMat();
{
OpenCLExecutionContextScope ...
u->currAllocator->download(u, dst.ptr(), dims, sz, srcofs, step.p, dst.step.p);
}
modules/core/src/umatrix.cpp
Outdated
| haveDstUninit ? " -D HAVE_DST_UNINIT" : ""); | ||
|
|
||
| std::shared_ptr<ocl::OpenCLExecutionContext> pExecCtx = std::static_pointer_cast<ocl::OpenCLExecutionContext>(u->allocatorContext); | ||
| ocl::OpenCLExecutionContextScope scope(pExecCtx ? *pExecCtx.get() : ocl::OpenCLExecutionContext::getCurrent()); |
There was a problem hiding this comment.
OpenCLExecutionContextScope
We should not change execution scope here.
If src's scope is not the same (as dst/thread), then .clone() src UMat first.
If mask's scope is not the same (as as dst/thread), then .clone() mask UMat first.
There was a problem hiding this comment.
Done, and i used the same solution for convertTo
|
@kallaballa Friendly reminder. |
1 similar comment
|
@kallaballa Friendly reminder. |
…convertTo clones UMats if they don't match the current context.
|
Waiting for the tests. Apart from that i think the PR is ready. |
|
Local tests failed so i made a new patch. now local tests succeed. |
|
found more cases that slipped by me. local tests succeed. waiting for the CI. |
|
The failing tests look suspicious and i will look into it. anyway it did some testing using my demos of V4D (on a unpublished branch) and I found several problems that prevented me from using UMat with multiple OpenCL contexts. I will add another commit that was necessary to fix the issues i had but I am overall not sure I got this right in the first place. Maybe I misunderstood? @opencv-alalek could you have a second look on my approach to this? Also. I currently do the following to copy cross cl-context: CV_EXPORTS void copy_cross(const cv::UMat& src, cv::UMat& dst) {
if(dst.empty())
dst.create(src.size(), src.type());
src.copyTo(dst.getMat(cv::ACCESS_READ));
}Is that the right/recommended way? I tried several other variants but to no avail. |
|
@kallaballa @opencv-alalek What is the PR status? |
opencv-alalek
left a comment
There was a problem hiding this comment.
Thank you for the update!
Could you prepare test cases which cover new code paths?
E.g, here: https://github.com/opencv/opencv/blob/4.x/modules/core/test/test_opencl.cpp (contains tests for OpenCLExecutionContext)
modules/core/src/ocl.cpp
Outdated
| @@ -1,4 +1,4 @@ | |||
| /*M/////////////////////////////////////////////////////////////////////////////////////// | |||
| /*M/////////////////////////////////////////////////////////////////////////////////////// | |||
| ( | ||
| (currentExecCtx.empty() && !pExecCtxDst->empty()) | ||
| || (!currentExecCtx.empty() && pExecCtxDst->empty()) | ||
| || (pExecCtxDst->getContext().ptr() != currentExecCtx.getContext().ptr()) |
There was a problem hiding this comment.
It makes sense to add method + test (for such method) instead of writing complex conditions multiple times.
// class OpenCLExecutionContext in ocl.hpp
bool isCompatibleContext(const std::shared_ptr<ocl::OpenCLExecutionContext>& other)
{
...
}
Usage:
if (pExecCtxDst && !pExecCtxDst->isCompatibleContext(pExecCtxSrc))
CV_Error(...)
|
This is a prototype that needs rework mostly to improve code-reuse and clarity. That said it does fix the problem and considerably improves performance by avoiding errors and copies (whenever possible) on then many simple and complex tested workloads. |
|
Also when switching between 4.x and this branch i can't find unwanted side effects. |
|
should i pursue this one? i know it looks very ugly but the gains are real. |
… and bind it via scope everywhere needed.
Changing it from Context to OpenCLExecutionContext poses no problem, because everywhere I need the Context I can get it from the OpenCLExecutionContext.
The pertaining issue: #20486
Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
Patch to opencv_extra has the same branch name.