nareshmlx/opencv-pr huggingface dataset:
**File:** modules/highgui/src/window_w32.cpp
**Change Type:** modified
**Context:** PR #19411: pollKey implementation for w32 backend of highgui

**Code Changes:**
```diff
@@ -1981,6 +1981,97 @@ static void showSaveDialog(CvWindow* window)
     }
 }
 
+/*
+ * message received. check if it belongs to our windows (frame, hwnd).
+ * returns true (and value in keyCode) if a key was pressed.
+ * otherwise returns false (indication to continue event loop).
+ */
+static bool handleMessage(MSG& message, int& keyCode)
```

Review comment:
I'll rename it and the corresponding instances in waitKey and pollKey
**File:** modules/core/include/opencv2/core/cuda.hpp
**Change Type:** modified
**Context:** PR #19259: Minimal implementation of GpuMatND

**Code Changes:**
```diff
@@ -340,6 +340,201 @@ class CV_EXPORTS_W GpuMat
     Allocator* allocator;
 };
 
+struct CV_EXPORTS_W GpuData
+{
+    explicit GpuData(size_t _size);
+     ~GpuData();
+
+    GpuData(const GpuData&) = delete;
```

Review comment:
Perhaps `size_t offset` should be more suitable.
**File:** modules/core/include/opencv2/core/cuda.hpp
**Change Type:** modified
**Context:** PR #19259: Minimal implementation of GpuMatND

**Code Changes:**
```diff
@@ -340,6 +340,201 @@ class CV_EXPORTS_W GpuMat
     Allocator* allocator;
 };
 
+struct CV_EXPORTS_W GpuData
+{
+    explicit GpuData(size_t _size);
+     ~GpuData();
+
+    GpuData(const GpuData&) = delete;
```

Review comment:
> DevicePtr It make sense to move this class on upper level, make it more generic, and change its name: - `GpuData` (like `UMatData`) - or `GpuBuffer` - or `GpuDataContainer` In the future, we can reuse/share this "container" with existed `GpuMat`. --- Please add `size_t size` field (size of allocated buffer in bytes) to perform accurate validation checks.
**File:** modules/core/src/cuda/gpu_mat_nd.cu
**Change Type:** added
**Context:** PR #19259: Minimal implementation of GpuMatND
**Review Line:** 5

**Code Changes:**
```diff
@@ -0,0 +1,269 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+
+#include "opencv2/opencv_modules.hpp"
+
+#ifndef HAVE_OPENCV_CUDEV
+
+#error "opencv_cudev is required"
+
```

Review comment:
Please use short license header: https://github.com/opencv/opencv/wiki/Coding_Style_Guide#file-structure ``` // This file is part of OpenCV project. // It is subject to the license terms in the LICENSE file found in the top-level directory // of this distribution and at http://opencv.org/license.html. ```
**File:** modules/core/include/opencv2/core/cuda.hpp
**Change Type:** modified
**Context:** PR #19259: Minimal implementation of GpuMatND

**Code Changes:**
```diff
@@ -340,6 +340,201 @@ class CV_EXPORTS_W GpuMat
     Allocator* allocator;
 };
 
+struct CV_EXPORTS_W GpuData
+{
+    explicit GpuData(size_t _size);
+     ~GpuData();
+
+    GpuData(const GpuData&) = delete;
```

Review comment:
`uchar* data` is private now along with a new member `size_t offset`. I have also added a public member function `getDevicePtr()` to get the first byte.
**File:** modules/core/include/opencv2/core/cuda.hpp
**Change Type:** modified
**Context:** PR #19259: Minimal implementation of GpuMatND

**Code Changes:**
```diff
@@ -340,6 +340,201 @@ class CV_EXPORTS_W GpuMat
     Allocator* allocator;
 };
 
+struct CV_EXPORTS_W GpuData
+{
+    explicit GpuData(size_t _size);
+     ~GpuData();
+
+    GpuData(const GpuData&) = delete;
```

Review comment:
`GpuData` is a global struct now with a new member `size_t size`.
**File:** modules/core/src/cuda/gpu_mat_nd.cu
**Change Type:** added
**Context:** PR #19259: Minimal implementation of GpuMatND
**Review Line:** 5

**Code Changes:**
```diff
@@ -0,0 +1,269 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+
+#include "opencv2/opencv_modules.hpp"
+
+#ifndef HAVE_OPENCV_CUDEV
+
+#error "opencv_cudev is required"
+
```

Review comment:
I have added the license header.
**File:** modules/core/include/opencv2/core/cuda.hpp
**Change Type:** modified
**Context:** PR #19259: Minimal implementation of GpuMatND

**Code Changes:**
```diff
@@ -340,6 +340,201 @@ class CV_EXPORTS_W GpuMat
     Allocator* allocator;
 };
 
+struct CV_EXPORTS_W GpuData
+{
+    explicit GpuData(size_t _size);
+     ~GpuData();
+
+    GpuData(const GpuData&) = delete;
```

Review comment:
> _size > _type No need to use underscores in declarations without implementation code. Lets keep docs and bindings clear
**File:** modules/core/include/opencv2/core/cuda.hpp
**Change Type:** modified
**Context:** PR #19259: Minimal implementation of GpuMatND

**Code Changes:**
```diff
@@ -340,6 +340,201 @@ class CV_EXPORTS_W GpuMat
     Allocator* allocator;
 };
 
+struct CV_EXPORTS_W GpuData
+{
+    explicit GpuData(size_t _size);
+     ~GpuData();
+
+    GpuData(const GpuData&) = delete;
```

Review comment:
> = default It makes sense to have implementation (empty) in .cpp file for that. There are several non-trivial fields.
**File:** modules/core/src/cuda/gpu_mat_nd.cu
**Change Type:** added
**Context:** PR #19259: Minimal implementation of GpuMatND
**Review Line:** 107

**Code Changes:**
```diff
+    return true;
+}
+
+GpuMatND GpuMatND::clone() const
+{
+    CV_DbgAssert(!empty());
+
+    GpuMatND ret(size, type());
+
+    if (isContinuous())
+    {
```

Review comment:
Why is not just `return clone(Stream::Null());`? (reduce duplicated code, DRY principle)
**File:** modules/core/include/opencv2/core/cuda.hpp
**Change Type:** modified
**Context:** PR #19259: Minimal implementation of GpuMatND

**Code Changes:**
```diff
@@ -340,6 +340,201 @@ class CV_EXPORTS_W GpuMat
     Allocator* allocator;
 };
 
+struct CV_EXPORTS_W GpuData
+{
+    explicit GpuData(size_t _size);
+     ~GpuData();
+
+    GpuData(const GpuData&) = delete;
```

Review comment:
`_data` is GPU memory, is not it?
**File:** modules/core/include/opencv2/core/cuda.hpp
**Change Type:** modified
**Context:** PR #19259: Minimal implementation of GpuMatND

**Code Changes:**
```diff
@@ -340,6 +340,201 @@ class CV_EXPORTS_W GpuMat
     Allocator* allocator;
 };
 
+struct CV_EXPORTS_W GpuData
+{
+    explicit GpuData(size_t _size);
+     ~GpuData();
+
+    GpuData(const GpuData&) = delete;
```

Review comment:
`upload` call handles the case with regular cv::Mat
**File:** modules/core/src/cuda/gpu_mat_nd.cu
**Change Type:** added
**Context:** PR #19259: Minimal implementation of GpuMatND
**Review Line:** 107

**Code Changes:**
```diff
+    return true;
+}
+
+GpuMatND GpuMatND::clone() const
+{
+    CV_DbgAssert(!empty());
+
+    GpuMatND ret(size, type());
+
+    if (isContinuous())
+    {
```

Review comment:
The one with the empty parameter list calls synchronous CUDA APIs: `cudaMemcpy` and `cudaMemcpy2D`, whereas the overloaded function with one argument calls asynchronous CUDA APIs: `cudaMemcpyAsync` and `cudaMemcpyAsync2D`. `GpuMat::upload()` and `GpuMat::download()` also have overloades for asynchronous CUDA API calls. However, I agree that we should reduce duplicated code. So I suggest we need to keep the two overloads while reducing duplication as much as possible.
**File:** modules/core/include/opencv2/core/cuda.hpp
**Change Type:** modified
**Context:** PR #19259: Minimal implementation of GpuMatND

**Code Changes:**
```diff
@@ -340,6 +340,201 @@ class CV_EXPORTS_W GpuMat
     Allocator* allocator;
 };
 
+struct CV_EXPORTS_W GpuData
+{
+    explicit GpuData(size_t _size);
+     ~GpuData();
+
+    GpuData(const GpuData&) = delete;
```

Review comment:
I'll move the definition to the .cpp file to hide the implementation.
**File:** modules/core/include/opencv2/core/cuda.hpp
**Change Type:** modified
**Context:** PR #19259: Minimal implementation of GpuMatND

**Code Changes:**
```diff
@@ -340,6 +340,201 @@ class CV_EXPORTS_W GpuMat
     Allocator* allocator;
 };
 
+struct CV_EXPORTS_W GpuData
+{
+    explicit GpuData(size_t _size);
+     ~GpuData();
+
+    GpuData(const GpuData&) = delete;
```

Review comment:
I'll do that in the next commit.
**File:** modules/core/include/opencv2/core/cuda.hpp
**Change Type:** modified
**Context:** PR #19259: Minimal implementation of GpuMatND

**Code Changes:**
```diff
@@ -340,6 +340,201 @@ class CV_EXPORTS_W GpuMat
     Allocator* allocator;
 };
 
+struct CV_EXPORTS_W GpuData
+{
+    explicit GpuData(size_t _size);
+     ~GpuData();
+
+    GpuData(const GpuData&) = delete;
```

Review comment:
I have fixed it.
**File:** modules/core/src/cuda/gpu_mat_nd.cu
**Change Type:** added
**Context:** PR #19259: Minimal implementation of GpuMatND
**Review Line:** 107

**Code Changes:**
```diff
+    return true;
+}
+
+GpuMatND GpuMatND::clone() const
+{
+    CV_DbgAssert(!empty());
+
+    GpuMatND ret(size, type());
+
+    if (isContinuous())
+    {
```

Review comment:
I have fixed it, but please look at [this comment](https://github.com/opencv/opencv/pull/19259#discussion_r569131873) below.
**File:** modules/core/src/cuda/gpu_mat_nd.cu
**Change Type:** added
**Context:** PR #19259: Minimal implementation of GpuMatND
**Review Line:** 75

**Code Changes:**
```diff
+}
+
+/////////////////////////////////////////////////////
+/// clone
+
+static bool next(uchar*& d, const uchar*& s, std::vector<int>& idx, const int dims, const GpuMatND& dst, const GpuMatND& src)
+{
+    int inc = dims-3;
+
+    while (true)
+    {
```

Review comment:
This function signature does not look so good, but I'd like to keep it as is for now. Making an internal iterator class that iterates each 2d plane seems a better design. I'll make that on the next PR when I implement the `convertTo`, `copyTo`, and `setTo` member functions of `GpuMatND`. A straightforward implementation would be to iterator each 2d plane of `GpuMatND` and apply `GpuMat` counterparts. The iterator class would also fit well for this.
**File:** modules/core/include/opencv2/core/cuda.hpp
**Change Type:** modified
**Context:** PR #19259: Minimal implementation of GpuMatND

**Code Changes:**
```diff
@@ -340,6 +340,201 @@ class CV_EXPORTS_W GpuMat
     Allocator* allocator;
 };
 
+struct CV_EXPORTS_W GpuData
+{
+    explicit GpuData(size_t _size);
+     ~GpuData();
+
+    GpuData(const GpuData&) = delete;
```

Review comment:
Main point here is to use **named** static function instead of constructor (to avoid confusions): ``` static GpuMatND wrapMemoryPtrGPU(...); ```
**File:** modules/core/src/cuda/gpu_mat_nd.cu
**Change Type:** added
**Context:** PR #19259: Minimal implementation of GpuMatND

**Code Changes:**
```diff
@@ -0,0 +1,269 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+
+#include "opencv2/opencv_modules.hpp"
+
+#ifndef HAVE_OPENCV_CUDEV
+
+#error "opencv_cudev is required"
```

Review comment:
Did you check performance of this loop? If this a synchronized call, then the sequence of several synchronized calls may show bad performance. I believe this scheme may perform better: - schedule async tasks - wait for completion (code block behaves as synchronized)
**File:** modules/core/src/cuda/gpu_mat_nd.cu
**Change Type:** added
**Context:** PR #19259: Minimal implementation of GpuMatND

**Code Changes:**
```diff
@@ -0,0 +1,269 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+
+#include "opencv2/opencv_modules.hpp"
+
+#ifndef HAVE_OPENCV_CUDEV
+
+#error "opencv_cudev is required"
```

Review comment:
I have changed `cudaMemcpy2D` to `cudaMemcpy2DAsync` and added `cudaStreamSynchronize(0)` to wait for completion.
**File:** modules/core/include/opencv2/core/cuda.hpp
**Change Type:** modified
**Context:** PR #19286: add cuda::Stream constructor with cuda stream flags

**Code Changes:**
```diff
@@ -656,6 +656,18 @@ class CV_EXPORTS_W Stream
     //! creates a new asynchronous stream with custom allocator
     CV_WRAP Stream(const Ptr<GpuMat::Allocator>& allocator);
 
+    /** @brief creates a new Stream using the cudaFlags argument to determine the behaviors of the stream
+
+    @note The cudaFlags parameter is passed to the underlying api cudaStreamCreateWithFlags() and
+    supports the same parameter values.
+    @code
+        // creates an OpenCV cuda::Stream that manages an asynchronous, non-blocking,
```

Review comment:
It make sense to avoid "void*" ctors in public API (because there is no strong type check and many implicit conversions). Consider using: ``` static Stream fromCudaStream(void*&& cudaStream); ``` Usage: ```.diff -cv::cuda::Stream cvStream(std::move((void*)cudaStream)); +auto cvStream = cv::cuda::Stream::fromCudaStream(std::move((void*)cudaStream)); ```
**File:** modules/core/include/opencv2/core/cuda.hpp
**Change Type:** modified
**Context:** PR #19286: add cuda::Stream constructor with cuda stream flags

**Code Changes:**
```diff
@@ -656,6 +656,18 @@ class CV_EXPORTS_W Stream
     //! creates a new asynchronous stream with custom allocator
     CV_WRAP Stream(const Ptr<GpuMat::Allocator>& allocator);
 
+    /** @brief creates a new Stream using the cudaFlags argument to determine the behaviors of the stream
+
+    @note The cudaFlags parameter is passed to the underlying api cudaStreamCreateWithFlags() and
+    supports the same parameter values.
+    @code
+        // creates an OpenCV cuda::Stream that manages an asynchronous, non-blocking,
```

Review comment:
> cv::ocl::Device(void*) Exactly in this area there are several issues with "void*" type in constructor. > unique_ptr Doesn't make sense, because this class is smart ptr itself. Anyway you can always try to add this "safe" factory: ``` static std::unique_ptr<Stream> makeUniqueFromCudaStream(void*&& cudaStream); ``` > copy elision Try to add move ctor. --- For other proposals there is ABI compatibility (between configurations) with BUILD_CUDA_STUBS CMake option.
**File:** modules/core/include/opencv2/core/cuda.hpp
**Change Type:** modified
**Context:** PR #19286: add cuda::Stream constructor with cuda stream flags

**Code Changes:**
```diff
@@ -656,6 +656,18 @@ class CV_EXPORTS_W Stream
     //! creates a new asynchronous stream with custom allocator
     CV_WRAP Stream(const Ptr<GpuMat::Allocator>& allocator);
 
+    /** @brief creates a new Stream using the cudaFlags argument to determine the behaviors of the stream
+
+    @note The cudaFlags parameter is passed to the underlying api cudaStreamCreateWithFlags() and
+    supports the same parameter values.
+    @code
+        // creates an OpenCV cuda::Stream that manages an asynchronous, non-blocking,
```

Review comment:
> "void*" type in constructor. > does not want to have void* in public opencv APIs The first only. > Static factories return pointers to objects; it returns cuda::Stream * This doesn't follow RAII. --- > StreamAccessor I believe this is the right way. There is already some related strong-typed [code](https://github.com/opencv/opencv/blame/63bb2abadab875fc648a572faccafee134f06fc8/modules/core/src/cuda_stream.cpp#L563-L566) (added in C++98 epoch, so there is no move semantic).
**File:** modules/core/include/opencv2/core/cuda.hpp
**Change Type:** modified
**Context:** PR #19286: add cuda::Stream constructor with cuda stream flags

**Code Changes:**
```diff
@@ -656,6 +656,18 @@ class CV_EXPORTS_W Stream
     //! creates a new asynchronous stream with custom allocator
     CV_WRAP Stream(const Ptr<GpuMat::Allocator>& allocator);
 
+    /** @brief creates a new Stream using the cudaFlags argument to determine the behaviors of the stream
+
+    @note The cudaFlags parameter is passed to the underlying api cudaStreamCreateWithFlags() and
+    supports the same parameter values.
+    @code
+        // creates an OpenCV cuda::Stream that manages an asynchronous, non-blocking,
```

Review comment:
I think the constructor that takes ownership of a `cudaStream_t` would need to check whether the `cudaStream_t` passed as an argument is already initialized with `cudaStreamCreate()` or not. I can't find an API in CUDA that does that. So I think it is hard to implement one. Also, `cudaStream_t` is itself a pointer, so I think there are not many benefits from `std::move`-ing it or taking an rvalue reference to it.
**File:** modules/core/include/opencv2/core/cuda.hpp
**Change Type:** modified
**Context:** PR #19286: add cuda::Stream constructor with cuda stream flags

**Code Changes:**
```diff
@@ -656,6 +656,18 @@ class CV_EXPORTS_W Stream
     //! creates a new asynchronous stream with custom allocator
     CV_WRAP Stream(const Ptr<GpuMat::Allocator>& allocator);
 
+    /** @brief creates a new Stream using the cudaFlags argument to determine the behaviors of the stream
+
+    @note The cudaFlags parameter is passed to the underlying api cudaStreamCreateWithFlags() and
+    supports the same parameter values.
+    @code
+        // creates an OpenCV cuda::Stream that manages an asynchronous, non-blocking,
```

Review comment:
Move is the C++11 and newer semantic to declare and force a transfer of ownership. Without it, ownership is ambigious -- often duplicated, and leading to leaks and/or double-deletes. After the move into the constructor I proposed...the previously owning variable has no data and no memory. I can't be used further in code. These are the good things that C++11 and newer has to help coders write better code. That is the value: clear ownership....less bugs...cleaner code. I previously looked myself, CUDA doesn't have an API to validate a cudaStream_t. However, this is something I would not expect OpenCV to do. OpenCV doesn't validate the `data` pointer for cv::mat, cv::umat or any of many many other classes that have constructors accepting pointers.
**File:** modules/core/include/opencv2/core/cuda.hpp
**Change Type:** modified
**Context:** PR #19286: add cuda::Stream constructor with cuda stream flags

**Code Changes:**
```diff
@@ -656,6 +656,18 @@ class CV_EXPORTS_W Stream
     //! creates a new asynchronous stream with custom allocator
     CV_WRAP Stream(const Ptr<GpuMat::Allocator>& allocator);
 
+    /** @brief creates a new Stream using the cudaFlags argument to determine the behaviors of the stream
+
+    @note The cudaFlags parameter is passed to the underlying api cudaStreamCreateWithFlags() and
+    supports the same parameter values.
+    @code
+        // creates an OpenCV cuda::Stream that manages an asynchronous, non-blocking,
```

Review comment:
I wanted to say that move semantics is not that useful for primitive types such as pointers. https://stackoverflow.com/questions/14679605/do-built-in-types-have-move-semantics Anyway, with this PR approach, the `Stream` object does not take ownership completely. You can still access `cudaStream` after the constructor calls. ```C++ cudaStream_t cudaStream; cudaStreamCreateWithFlags(&cudaStream, cudaStreamNonBlocking); cv::cuda::Stream cvStream(std::move((void*)cudaStream)); // cudaStream <-- still valid ```
**File:** modules/core/include/opencv2/core/cuda.hpp
**Change Type:** modified
**Context:** PR #19286: add cuda::Stream constructor with cuda stream flags

**Code Changes:**
```diff
@@ -656,6 +656,18 @@ class CV_EXPORTS_W Stream
     //! creates a new asynchronous stream with custom allocator
     CV_WRAP Stream(const Ptr<GpuMat::Allocator>& allocator);
 
+    /** @brief creates a new Stream using the cudaFlags argument to determine the behaviors of the stream
+
+    @note The cudaFlags parameter is passed to the underlying api cudaStreamCreateWithFlags() and
+    supports the same parameter values.
+    @code
+        // creates an OpenCV cuda::Stream that manages an asynchronous, non-blocking,
```

Review comment:
I've updated branch and force pushed. It should arrive soon.
**File:** modules/core/include/opencv2/core/cuda.hpp
**Change Type:** modified
**Context:** PR #19286: add cuda::Stream constructor with cuda stream flags

**Code Changes:**
```diff
@@ -656,6 +656,18 @@ class CV_EXPORTS_W Stream
     //! creates a new asynchronous stream with custom allocator
     CV_WRAP Stream(const Ptr<GpuMat::Allocator>& allocator);
 
+    /** @brief creates a new Stream using the cudaFlags argument to determine the behaviors of the stream
+
+    @note The cudaFlags parameter is passed to the underlying api cudaStreamCreateWithFlags() and
+    supports the same parameter values.
+    @code
+        // creates an OpenCV cuda::Stream that manages an asynchronous, non-blocking,
```

Review comment:
Remove CV_WRAP from here to keep this C++ only. We can add `CV_WRAP static Stream create(int cudaFlags)` or similar for bindings later.
**File:** modules/core/include/opencv2/core/cuda.hpp
**Change Type:** modified
**Context:** PR #19286: add cuda::Stream constructor with cuda stream flags

**Code Changes:**
```diff
@@ -656,6 +656,18 @@ class CV_EXPORTS_W Stream
     //! creates a new asynchronous stream with custom allocator
     CV_WRAP Stream(const Ptr<GpuMat::Allocator>& allocator);
 
+    /** @brief creates a new Stream using the cudaFlags argument to determine the behaviors of the stream
+
+    @note The cudaFlags parameter is passed to the underlying api cudaStreamCreateWithFlags() and
+    supports the same parameter values.
+    @code
+        // creates an OpenCV cuda::Stream that manages an asynchronous, non-blocking,
```

Review comment:
I thought of an alternative. I will need to code it and force push to see if it removes the two warnings in the CI platforms. (Functionality has not been a problem...only two warnings on a subset of platforms). I can code the constructor to accept an `int` (you suggest this is preferred in OpenCV) and also reject negative numbers. By accepting only positive `int` values...I can safely cast it to an `unsigned int`. This alternative supports all the values that the NVidia API currently supports. If in the future NVidia defines a value that is larger than a signed int can represent and someone uses that value, then this constructor will fail. And OpenCV will need to make a choice how to handle NVidia's new value. I would prefer to not have the cost of a branch/if in the constructor. What is the OpenCV philosophy to use `CV_DbgAssert(param>=0)`. I would prefer that so there is no cost in release builds. If the core team doesn't like that, then I can use `CV_Assert(param>=0)`.
**File:** modules/core/src/cuda_stream.cpp
**Change Type:** modified
**Context:** PR #19286: add cuda::Stream constructor with cuda stream flags

**Code Changes:**
```diff
@@ -41,6 +41,7 @@
 //M*/
 
 #include "precomp.hpp"
+#include <cstdint>
 
 using namespace cv;
 using namespace cv::cuda;
@@ -293,6 +294,7 @@ class cv::cuda::Stream::Impl
 
```

Review comment:
IMHO, this check doesn't help. My suggestion is to remove that.
**File:** modules/python/test/test_cuda.py
**Change Type:** modified
**Context:** PR #19286: add cuda::Stream constructor with cuda stream flags

**Code Changes:**
```diff
@@ -33,6 +33,8 @@ def test_cuda_interop(self):
         self.assertTrue(cuMat.cudaPtr() != 0)
         stream = cv.cuda_Stream()
         self.assertTrue(stream.cudaPtr() != 0)
+        asyncstream = cv.cuda_Stream(1)  # cudaStreamNonBlocking
+        self.assertTrue(asyncstream.cudaPtr() != 0)
 
 if __name__ == '__main__':
     NewOpenCVTests.bootstrap()
```

Review comment:
Consider adding a comment with description for magic numbers: ``` asyncstream = cv.cuda_Stream(1) # cudaStreamNonBlocking ```
**File:** modules/python/test/test_cuda.py
**Change Type:** modified
**Context:** PR #19286: add cuda::Stream constructor with cuda stream flags

**Code Changes:**
```diff
@@ -33,6 +33,8 @@ def test_cuda_interop(self):
         self.assertTrue(cuMat.cudaPtr() != 0)
         stream = cv.cuda_Stream()
         self.assertTrue(stream.cudaPtr() != 0)
+        asyncstream = cv.cuda_Stream(1)  # cudaStreamNonBlocking
+        self.assertTrue(asyncstream.cudaPtr() != 0)
 
 if __name__ == '__main__':
     NewOpenCVTests.bootstrap()
```

Review comment:
The CUDA api defines are documented in the doxygen for the constructor. I can also add it to this test file, no problem.