Repository: opencv
Issue: `ocl::Kernel::set()` has inconsistent error behavior, `Kernel::args()` does no error handling
Labels: category: core,category: ocl,RFC

During code review and fixing some OpenCL resource leaks, I see that `ocl::Kernel::set()` has inconsistent error behavior. Sometimes it returns `-1`. Other times it takes a draconian approach of releasing the `Kernel::Impl` and setting the Impl pointer to null. This inconsistency in behavior leads to problems of ownership, ref counting, resource cleanup, etc.

**Recommendation:** when an error occurs in Kernel::set(), it should assert. An assert will clearly and immediately report errors, nicely handles resource cleanup, can be caught by user code, and is consistent with other parts of OpenCV that usually use asserts.

#### System information (version)

- OpenCV => 4.5
- Operating System / Platform => all
- Compiler => all

#### Detailed description

The `int` return of Kernel::set() is not consistently handled by the core OpenCV code. For example

* returning `-1` will lead to improper sequencing of Kernel arguments and more errant code that inconsistently checks for
  negative index values. For example, set(int,void*) will quickly return the same `-1` and report no error. Other signatures
  for set() will report an error with CV_LOG_ERROR but still does not handle the error in a way to stop/isolate the problem.
  It instead continues to allow errant code to run and eventually the Kernel will crash or fail later...making it harder for
  developers to find the true source of the problem.
* template `Kernel& args(const _Tps&... kernel_args)` never checks the return value from Kernel::set(). So with the
  different behaviors above, it doesn't catch the errors reported by `-1` and neglects error handling when set() uses
  the draconian approach. This leads to errors only appearing much later if or when the Kernel is run. This is too late.
  The error is known and can be asserts exactly when the arg is processed/added. And it is there that is useful.
  An unknown amount of code and time later when the Kernel is run is not as useful.

The draconian approach in one codepath of Kernel::set() is itself errant. Just because a UMat arg to a Kernel doesn't
have a handle is no reason to release the `Kernel::Impl` and set its pointer to null. This leads to a cascade of issues
related to ownership and cleanup. And it is inconsistent with equally bad parameters just returning `-1`.

https://github.com/opencv/opencv/blob/46fb88c76fbe8d4b7ff3cc8eb53e5842753f6c3e/modules/core/src/ocl.cpp#L3722-L3729

Core OpenCV code does not consistently use the return parameter. There is an attempt in this set() code to return the "next available parameter index" so that user code can use this return to cascade a series of set() calls. But even within the OpenCV codebase itself, this is not done. For example...

In features2d module, they use the return value as likely intended

https://github.com/opencv/opencv/blob/46fb88c76fbe8d4b7ff3cc8eb53e5842753f6c3e/modules/features2d/src/matchers.cpp#L116-L120

In math functions, the return values are ignored yet maintain their own index incrementer

https://github.com/opencv/opencv/blob/46fb88c76fbe8d4b7ff3cc8eb53e5842753f6c3e/modules/dnn/src/ocl4dnn/src/math_functions.cpp#L370-L375

In the DNN module, the return values are ignored and the indexes to set() are hardcoded.

https://github.com/opencv/opencv/blob/46fb88c76fbe8d4b7ff3cc8eb53e5842753f6c3e/modules/dnn/src/layers/prior_box_layer.cpp#L386-L390

#### Recommendation

Kernel::set() code should assert when there is an error. An assert will clearly and immediately report errors, nicely handles resource cleanup, can be caught by user code, and is consistent with other parts of OpenCV that usually use asserts.

#### Related issues

https://github.com/opencv/opencv/issues/8410

#### Issue submission checklist

 - [X] I report the issue, it's not a question
 - [X] I checked the problem with documentation, FAQ, open issues,
       forum.opencv.org, Stack Overflow, etc and have not found solution
 - [X] I updated to latest OpenCV version and the issue is still there