Skip to content

use opencl GPU:0 (1st gpu) in OpenCLExecutionContext test cases#19053

Closed
diablodale wants to merge 1 commit intoopencv:masterfrom
diablodale:fix18917-testcase-usegpu0
Closed

use opencl GPU:0 (1st gpu) in OpenCLExecutionContext test cases#19053
diablodale wants to merge 1 commit intoopencv:masterfrom
diablodale:fix18917-testcase-usegpu0

Conversation

@diablodale
Copy link
Copy Markdown
Contributor

Fix #18917 by using GPU:0 instead of GPU:1 in two OpenCLExecutionContext test cases. Otherwise, those test cases are using the 2nd GPU or silently fall-back to using a CPU-based OpenCL runtime.

If the opencv test pipeline and its multiple test platforms do not have 2 GPUs in them, then it is possible all the previous results of these two test cases are results of a fallback CPU device. It is important to check the test results of these two test cases on all the test platforms -- it might be the first time these two test cases run on a GPU.

It successfully runs on my two test machines. However, these two machines have two GPUs each.

[==========] Running 4 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 4 tests from OCL_OpenCLExecutionContext
[ RUN      ] OCL_OpenCLExecutionContext.basic
[       OK ] OCL_OpenCLExecutionContext.basic (1 ms)
[ RUN      ] OCL_OpenCLExecutionContext.createAndBind
[       OK ] OCL_OpenCLExecutionContext.createAndBind (45 ms)
[ RUN      ] OCL_OpenCLExecutionContext.createGPU
[       OK ] OCL_OpenCLExecutionContext.createGPU (102 ms)
[ RUN      ] OCL_OpenCLExecutionContext.ScopeTest
[       OK ] OCL_OpenCLExecutionContext.ScopeTest (2 ms)
[----------] 4 tests from OCL_OpenCLExecutionContext (162 ms total)

[----------] Global test environment tear-down
[==========] 4 tests from 1 test case ran. (194 ms total)
[  PASSED  ] 4 tests.

Pull Request Readiness Checklist

  • I agree to contribute to the project under Apache 2 License.
  • To the best of my knowledge, the proposed patch is not based on a code under GPL or other license that is incompatible with OpenCV
  • The PR is proposed to proper branch
  • There is reference to original bug report and related work
  • There is accuracy test, performance test and test data in opencv_extra repository, if applicable
    Patch to opencv_extra has the same branch name.
  • The feature is well documented and sample code can be built with the project CMake

Copy link
Copy Markdown
Member

@alalek alalek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change reduces testing code coverage.
I believe it is better to add context configuration as test parameter with these values:

  • :GPU:0
  • :GPU:1
  • :CPU:0

Note: OpenCV's OpenCL subsystem uses :GPU:0 by default.

@diablodale
Copy link
Copy Markdown
Contributor Author

I'm sure I can make needed changes. What is unclear is the goal.

I disagree with your assessment. Previously, the errant test cases tested the 2nd GPU and as a fallback the CPU. The 1st GPU was never tested. Therefore, the test cases I put in this PR increase coverage. They test the 1st GPU and fallback to the CPU. This is an increase. Why? Because now the test cases will run on computers with 1 GPU or 2 GPUs or more. Previously, the code only worked on systems with 2 GPUs (that is a subset of those with 1 or more GPUs). Therefore, this PR tests more computers...a superset...those computers that have 1 or more GPUs.

If you want to have the same approach of "test any GPU and fallback to a CPU if available", then this PR does that.
If you want a new approach, I can do that also. I'll need to understand what your goal is 🤔

Remember, it is not guaranteed that there is a OpenCL CPU-based engine installed. For example, newer Intel graphic drivers do not include the CPU-based OpenCL engine. It is a separate download.

It is not always easy to switch OpenCL engines. I've gone pretty deep in the OpenCV code to learn that. The ExecutionContext helps as does the environment variable. After I understand your goal with the test cases, then I can make additional changes.

@alalek
Copy link
Copy Markdown
Member

alalek commented Dec 13, 2020

The first "updated" tests is used to test scenario with 2 OpenCL contexts of 2 different OpenCL devices.
If there is the same device for both contexts (GPU:0 is default), then several critical lines of code can be removed without test failure.
Also this test is intended to run on environments with 2 GPUs or GPU+CPU configurations.

"Scope"-based test doesn't really need the requirement with contexts of different devices.
Also due to limitations of CI infrastructure, such requirement is critical - because this test is just skipped (however it could run).

@diablodale
Copy link
Copy Markdown
Contributor Author

I again need to understand your goals...your intentions. Not an explanation of what the tests did (or not) before this PR or with this PR. When I understand your goals, then I can write new or updated code.

My understanding is that you want test cases to exercise code and also pass for the most common scenarios. For example, you don't want an exotic test case that tests 5 GPUs or a test case that exercises code that isn't yet implemented. That is why I made this PR...because requiring 2 GPUs is "exotic".

Your testing pipeline has only 1 GPU. Look at the logs at https://pullrequest.opencv.org/buildbot/builders/precommit_opencl/builds/26992/steps/test_core-ippicv-opencl/logs/stdio where is lists only iGPU: Intel(R) HD Graphics 530 (OpenCL 2.1 NEO ) and CPU: Intel(R) Core(TM) i7-6700K CPU. That means that the existing test cases are falling back on lines 124 and 165 to use a CPU-engine -- which is not the intention of a test case named "createGPU".

Let me give an example of what I want to learn/understand. Here is a list of example goals:

  1. Test on all 6 combinations of: no CPU-engine, yes CPU-engine, 1 GPU, 2 GPU.
  2. Create two Context from the default ExecutionContext and compare if they are equal.
  3. Create two ExecutionContext using the same ocl::Device and ocl::Context, run UMat operations on each ExecContext and check for errors.
  4. Ensure that all test cases run on the default OpenCL device and default OpenCL context.
  5. etc...

But there are potential problems with those examples...

  • In (1), this will cause one or more tests cases to always FAIL if tests are run on machines without both a CPU-engine and 2 GPUs. I don't think this is good because many on the internet will run the tests on their 1 GPU systems and will have multiple tests fail. And not everyone installs the CPU-engine.
  • In (3), this is potentially dangerous and I am surprised we haven't seen failures. This is because the UMat infrastructure is not designed/tested for running on multiple GPU contexts and devices. And since UMats are in buffer pools and those pools are released async (clFinish issue GPU memory still allocated when fastNlMeansDenoising() returns #17789), it is possible a UMat from a previous ExecContext is in the pool when a different ExecContext that has been bind(). Some of these test cases use the same underlying clContext and clDevice therefore even if they are different ocl::ExecContext, it probably doesn't cause a crash since the underlying cl*** are the same. However, test case createGPU doesn't and this could fail test cases here or (due to async buf pools) in other test cases that have OpenCL enabled. This area of OpenCV is not-yet-implemented and exercising it in test cases is premature. This instability is supported by my own testing experience and what you wrote in another issue, "Unfortunately UMat doesn't support context sharing/migration at all. It is assumed that UMat is created, used and destroyed with the same active OpenCL context. UMat requires redesign to support multiple OpenCL contexts."

Evaluating the existing (pre-PR) test cases:

  • createFromDevice is safe. It uses the same ocl::device and ocl::context and makes no UMat operations.
  • basic is safe. It uses the same ocl::device and ocl::context and makes no UMat operations.
  • createAndBind is safe. It uses the same ocl::device and ocl::context and makes UMat operations on those same device+context.
  • createGPU is potentially unsafe. It might create and run UMat operations on different ocl::device+ocl::context. This changes the state of the global OpenCV+OpenCL system and is allocating UMat memory across different device+context combinations.
  • ScopeTest is potentially unsafe. Same as above.

I recommend that I:

  • Probe the system to discovered how many GPU-engines and CPU-engines. And only use the default engine yet access it with various device/context/queue calls like the existing tests.
  • Don't fallback to a CPU-engine. Due to the not-yet-implemented UMat code, it is unsafe to run UMat operations with different device+context.

@diablodale
Copy link
Copy Markdown
Contributor Author

I found proof in your test pipeline logs of undesired skipping of tests, failures and fallbacks. look at https://pullrequest.opencv.org/buildbot/builders/precommit_opencl_linux/builds/27453/steps/test_core-ippicv-opencl/logs/stdio and search for the test cases like OCL_OpenCLExecutionContext.ScopeTest and OCL_OpenCLExecutionContext.createGPU

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

test cases for OpenCL should only use default GPU device 0

2 participants