Skip to content

Commit 60319b3

Browse files
committed
Test code - GpuMatND & Mat interoperability
1 parent 33ae078 commit 60319b3

File tree

1 file changed

+148
-0
lines changed

1 file changed

+148
-0
lines changed

modules/cudev/test/test_nd.cu

+148
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
#include "test_precomp.hpp"
2+
3+
using namespace cv;
4+
using namespace cv::cuda;
5+
using namespace cvtest;
6+
7+
using ElemTypes = ::testing::Types<
8+
Vec<uchar, 1>, Vec<uchar, 2>, Vec<uchar, 3>, Vec<uchar, 4>, // CV_8U
9+
Vec<schar, 1>, Vec<schar, 2>, Vec<schar, 3>, Vec<schar, 4>, // CV_8S
10+
Vec<ushort, 1>, Vec<ushort, 2>, Vec<ushort, 3>, Vec<ushort, 4>, // CV_16U
11+
Vec<short, 1>, Vec<short, 2>, Vec<short, 3>, Vec<short, 4>, // CV_16S
12+
Vec<int, 1>, Vec<int, 2>, Vec<int, 3>, Vec<int, 4>, // CV_32S
13+
Vec<float, 1>, Vec<float, 2>, Vec<float, 3>, Vec<float, 4>, // CV_32F
14+
Vec<double, 1>, Vec<double, 2>, Vec<double, 3>, Vec<double, 4>, //CV_64F
15+
Vec<float16_t, 1>, Vec<float16_t, 2>, Vec<float16_t, 3>, Vec<float16_t, 4> // CV_16F
16+
>;
17+
18+
template <typename ElemType>
19+
class GpuMatNDTest : public ::testing::Test
20+
{
21+
public:
22+
using MatType = Mat_<ElemType>;
23+
using CnType = typename Mat_<ElemType>::channel_type;
24+
static constexpr int cn = DataType<ElemType>::channels;
25+
using SizeArray = GpuMatND::SizeArray;
26+
27+
static void doTest(const SizeArray& size)
28+
{
29+
const int dims = static_cast<int>(size.size());
30+
31+
MatType gold(dims, size.data());
32+
MatType dst;
33+
34+
// init gold with random data
35+
for (ElemType& elem : gold)
36+
for (int i = 0; i < cn; ++i)
37+
elem[i] = static_cast<CnType>(std::rand());
38+
39+
GpuMatND gmat;
40+
41+
{
42+
// simple upload, download test for GpuMatND
43+
44+
gmat.upload(gold);
45+
gmat.download(dst);
46+
47+
EXPECT_TRUE(std::equal(gold.begin(), gold.end(), dst.begin()));
48+
}
49+
50+
std::vector<Range> ranges;
51+
for (int s : size)
52+
if (s > 2)
53+
ranges.emplace_back(1, s-1);
54+
else
55+
ranges.push_back(Range::all());
56+
57+
if (dims == 1)
58+
{
59+
std::vector<Range> ranges_1dfix = ranges;
60+
ranges_1dfix.push_back(Range::all());
61+
62+
// Mat expects two ranges even in this case
63+
ranges = std::move(ranges_1dfix);
64+
}
65+
66+
MatType goldSub = gold(ranges);
67+
68+
{
69+
// upload partial mat, download it, and compare
70+
71+
gmat.upload(goldSub);
72+
gmat.download(dst);
73+
74+
EXPECT_TRUE(std::equal(goldSub.begin(), goldSub.end(), dst.begin()));
75+
}
76+
77+
{
78+
// upload full mat, extract partial mat from it, download it, and compare
79+
80+
gmat.upload(gold);
81+
gmat = gmat(ranges);
82+
gmat.download(dst);
83+
84+
EXPECT_TRUE(std::equal(goldSub.begin(), goldSub.end(), dst.begin()));
85+
}
86+
87+
// GpuMat::convertTo is not implemented for CV_16F
88+
if (!std::is_same<CnType, float16_t>::value)
89+
{
90+
// Test GpuMatND to GpuMat conversion:
91+
92+
// extract a 2D-plane and set its elements in the extracted region to 1
93+
// compare the values of the full mat between Mat and GpuMatND
94+
95+
gmat.upload(gold);
96+
97+
for (int i = 0; i < dims - 2; ++i)
98+
if (size[i] > 1)
99+
ranges[i] = Range(1, 2);
100+
else
101+
ranges[i] = Range::all();
102+
103+
GpuMat plane = gmat(ranges).createGpuMatHeader();
104+
105+
EXPECT_TRUE(!plane.refcount); // plane points to externally allocated memory(a part of gmat)
106+
107+
const GpuMat dummy = plane.clone();
108+
109+
EXPECT_TRUE(dummy.refcount); // dummy is clone()-ed from plane, so it manages its memory
110+
111+
// currently, plane(GpuMat) points to a sub-matrix of gmat(GpuMatND)
112+
// in this case, dummy and plane have same size and type,
113+
// so plane does not get reallocated inside convertTo,
114+
// so this convertTo sets a sub-matrix region of gmat to 1
115+
dummy.convertTo(plane, -1, 0, 1);
116+
117+
EXPECT_TRUE(!plane.refcount); // plane still points to externally allocated memory(a part of gmat)
118+
119+
gmat.download(dst);
120+
121+
// set a sub-matrix region of gold to 1
122+
Mat plane_ = gold(ranges);
123+
const Mat dummy_ = plane_.clone();
124+
dummy_.convertTo(plane_, -1, 0, 1);
125+
126+
EXPECT_TRUE(std::equal(gold.begin(), gold.end(), dst.begin()));
127+
}
128+
}
129+
};
130+
131+
TYPED_TEST_CASE(GpuMatNDTest, ElemTypes);
132+
133+
TYPED_TEST(GpuMatNDTest, Test1)
134+
{
135+
using SizeArray = GpuMatND::SizeArray;
136+
137+
std::vector<SizeArray> sizes = {
138+
SizeArray{1}, SizeArray{1, 1}, SizeArray{1, 1, 1}, SizeArray{1, 1, 1, 1},
139+
SizeArray{2}, SizeArray{2, 1}, SizeArray{1, 2}, SizeArray{1, 2, 1}, SizeArray{2, 1, 2}, SizeArray{2, 2, 2},
140+
SizeArray{64}, SizeArray{64, 64}, SizeArray{16, 64, 64}, SizeArray{4, 16, 64, 64}, SizeArray{2, 4, 16, 64, 64},
141+
SizeArray{129}, SizeArray{127, 129}, SizeArray{1, 127, 129}, SizeArray{1, 1, 127, 129}, SizeArray{7, 1, 1, 127, 129},
142+
SizeArray{1, 2, 1, 1, 127, 129}, SizeArray{1, 2, 1, 1, 127, 129, 1},
143+
SizeArray{2, 1, 2, 1, 1, 127, 129}, SizeArray{2, 1, 2, 1, 1, 127, 129, 1}
144+
};
145+
146+
for (auto& size : sizes)
147+
GpuMatNDTest<TypeParam>::doTest(size);
148+
}

0 commit comments

Comments
 (0)