/home/liu/actions-runner/_work/ccv/ccv/test/unit/nnc/upsample.tests.c
Line | Count | Source |
1 | | #include "ccv.h" |
2 | | #include "nnc/ccv_nnc.h" |
3 | | #include "nnc/ccv_nnc_easy.h" |
4 | | #include "case.h" |
5 | | #include "ccv_case.h" |
6 | | |
7 | | TEST_SETUP() |
8 | | { |
9 | | ccv_nnc_init(); |
10 | | } |
11 | | |
12 | | #ifdef HAVE_LIBPNG |
13 | | TEST_CASE("upsample chessbox") |
14 | 1 | { |
15 | 1 | ccv_dense_matrix_t* image = 0; |
16 | 1 | ccv_read("../../../samples/chessbox.png", &image, CCV_IO_ANY_FILE | CCV_IO_RGB_COLOR); |
17 | 1 | ccv_dense_matrix_t* fimage = 0; |
18 | 1 | ccv_shift(image, (ccv_matrix_t**)&fimage, CCV_32F, 0, 0); |
19 | 1 | ccv_nnc_tensor_t* const a = (ccv_nnc_tensor_t*)fimage; |
20 | 1 | ccv_nnc_tensor_t* const b = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, image->rows * 2, image->cols * 2, 3), 0); |
21 | 1 | ccv_nnc_cmd_exec(CMD_UPSAMPLE_FORWARD(CCV_NNC_UPSAMPLE_BILINEAR, 2, 2, 0), ccv_nnc_no_hint, 0, TENSOR_LIST(a), TENSOR_LIST(b), 0); |
22 | 1 | REQUIRE_MATRIX_FILE_EQ((ccv_matrix_t*)b, "data/upsample.forward.bin", "the forward of upsample should be equal"); |
23 | 1 | ccv_nnc_tensor_free(b); |
24 | 1 | ccv_matrix_free(image); |
25 | 1 | ccv_matrix_free(fimage); |
26 | 1 | } |
27 | | |
28 | | TEST_CASE("downsample chessbox") |
29 | 1 | { |
30 | 1 | ccv_dense_matrix_t* image = 0; |
31 | 1 | ccv_read("../../../samples/chessbox.png", &image, CCV_IO_ANY_FILE | CCV_IO_RGB_COLOR); |
32 | 1 | ccv_dense_matrix_t* fimage = 0; |
33 | 1 | ccv_shift(image, (ccv_matrix_t**)&fimage, CCV_32F, 0, 0); |
34 | 1 | ccv_nnc_tensor_t* const a = (ccv_nnc_tensor_t*)fimage; |
35 | 1 | ccv_nnc_tensor_t* const b = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, image->rows / 2, image->cols / 2, 3), 0); |
36 | 1 | ccv_nnc_cmd_exec(CMD_UPSAMPLE_BACKWARD(CCV_NNC_UPSAMPLE_BILINEAR, 2, 2, 0), ccv_nnc_no_hint, 0, TENSOR_LIST(a), TENSOR_LIST(b), 0); |
37 | 1 | REQUIRE_MATRIX_FILE_EQ((ccv_matrix_t*)b, "data/upsample.backward.bin", "the backward of upsample should be equal"); |
38 | 1 | ccv_nnc_tensor_free(b); |
39 | 1 | ccv_matrix_free(image); |
40 | 1 | ccv_matrix_free(fimage); |
41 | 1 | } |
42 | | |
43 | | TEST_CASE("upsample chessbox in NCHW") |
44 | 1 | { |
45 | 1 | ccv_dense_matrix_t* image = 0; |
46 | 1 | ccv_read("../../../samples/chessbox.png", &image, CCV_IO_ANY_FILE | CCV_IO_RGB_COLOR); |
47 | 1 | ccv_dense_matrix_t* fimage = 0; |
48 | 1 | ccv_shift(image, (ccv_matrix_t**)&fimage, CCV_32F, 0, 0); |
49 | 1 | ccv_nnc_tensor_t* const a = ccv_nnc_tensor_new(0, CPU_TENSOR_NCHW(32F, 3, image->rows, image->cols), 0); |
50 | 1 | ccv_nnc_cmd_exec(CMD_FORMAT_TRANSFORM_FORWARD(), ccv_nnc_no_hint, 0, TENSOR_LIST((ccv_nnc_tensor_t*)fimage), TENSOR_LIST(a), 0); |
51 | 1 | ccv_matrix_free(fimage); |
52 | 1 | ccv_nnc_tensor_t* const b = ccv_nnc_tensor_new(0, CPU_TENSOR_NCHW(32F, 3, image->rows * 2, image->cols * 2), 0); |
53 | 1 | ccv_nnc_cmd_exec(CMD_UPSAMPLE_FORWARD(CCV_NNC_UPSAMPLE_BILINEAR, 2, 2, 0), ccv_nnc_no_hint, 0, TENSOR_LIST(a), TENSOR_LIST(b), 0); |
54 | 1 | ccv_nnc_tensor_free(a); |
55 | 1 | ccv_nnc_tensor_t* const bt = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, image->rows * 2, image->cols * 2, 3), 0); |
56 | 1 | ccv_nnc_cmd_exec(CMD_FORMAT_TRANSFORM_FORWARD(), ccv_nnc_no_hint, 0, TENSOR_LIST(b), TENSOR_LIST(bt), 0); |
57 | 1 | ccv_nnc_tensor_free(b); |
58 | 1 | REQUIRE_MATRIX_FILE_EQ((ccv_matrix_t*)bt, "data/upsample.forward.bin", "the forward of upsample should be equal"); |
59 | 1 | ccv_matrix_free(image); |
60 | 1 | ccv_nnc_tensor_free(bt); |
61 | 1 | } |
62 | | |
63 | | TEST_CASE("downsample chessbox in NCHW") |
64 | 1 | { |
65 | 1 | ccv_dense_matrix_t* image = 0; |
66 | 1 | ccv_read("../../../samples/chessbox.png", &image, CCV_IO_ANY_FILE | CCV_IO_RGB_COLOR); |
67 | 1 | ccv_dense_matrix_t* fimage = 0; |
68 | 1 | ccv_shift(image, (ccv_matrix_t**)&fimage, CCV_32F, 0, 0); |
69 | 1 | ccv_nnc_tensor_t* const a = ccv_nnc_tensor_new(0, CPU_TENSOR_NCHW(32F, 3, image->rows, image->cols), 0); |
70 | 1 | ccv_nnc_cmd_exec(CMD_FORMAT_TRANSFORM_FORWARD(), ccv_nnc_no_hint, 0, TENSOR_LIST((ccv_nnc_tensor_t*)fimage), TENSOR_LIST(a), 0); |
71 | 1 | ccv_matrix_free(fimage); |
72 | 1 | ccv_nnc_tensor_t* const b = ccv_nnc_tensor_new(0, CPU_TENSOR_NCHW(32F, 3, image->rows / 2, image->cols / 2), 0); |
73 | 1 | ccv_nnc_cmd_exec(CMD_UPSAMPLE_BACKWARD(CCV_NNC_UPSAMPLE_BILINEAR, 2, 2, 0), ccv_nnc_no_hint, 0, TENSOR_LIST(a), TENSOR_LIST(b), 0); |
74 | 1 | ccv_nnc_tensor_free(a); |
75 | 1 | ccv_nnc_tensor_t* const bt = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, image->rows / 2, image->cols / 2, 3), 0); |
76 | 1 | ccv_nnc_cmd_exec(CMD_FORMAT_TRANSFORM_FORWARD(), ccv_nnc_no_hint, 0, TENSOR_LIST(b), TENSOR_LIST(bt), 0); |
77 | 1 | ccv_nnc_tensor_free(b); |
78 | 1 | REQUIRE_MATRIX_FILE_EQ((ccv_matrix_t*)bt, "data/upsample.backward.bin", "the backward of upsample should be equal"); |
79 | 1 | ccv_matrix_free(image); |
80 | 1 | ccv_nnc_tensor_free(bt); |
81 | 1 | } |
82 | | #endif |
83 | | |
84 | | TEST_CASE("upsample nearest") |
85 | 1 | { |
86 | 1 | ccv_nnc_tensor_t* const a = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 2, 2, 2), 0); |
87 | 1 | int i; |
88 | 9 | for (i = 0; i < 8; i++8 ) |
89 | 8 | a->data.f32[i] = i; |
90 | 1 | ccv_nnc_tensor_t* const b = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 4, 4, 2), 0); |
91 | 1 | ccv_nnc_cmd_exec(CMD_UPSAMPLE_FORWARD(CCV_NNC_UPSAMPLE_NEAREST, 2, 2, 0), ccv_nnc_no_hint, 0, TENSOR_LIST(a), TENSOR_LIST(b), 0); |
92 | 1 | float bt[32] = { |
93 | 1 | 0, 1, 0, 1, 2, 3, 2, 3, |
94 | 1 | 0, 1, 0, 1, 2, 3, 2, 3, |
95 | 1 | 4, 5, 4, 5, 6, 7, 6, 7, |
96 | 1 | 4, 5, 4, 5, 6, 7, 6, 7, |
97 | 1 | }; |
98 | 1 | REQUIRE_ARRAY_EQ_WITH_TOLERANCE(float, b->data.f32, bt, 32, 1e-5, "should match ground truth"); |
99 | 1 | ccv_nnc_tensor_free(a); |
100 | 1 | ccv_nnc_tensor_free(b); |
101 | 1 | } |
102 | | |
103 | | TEST_CASE("upsample nearest, align corners") |
104 | 1 | { |
105 | 1 | ccv_nnc_tensor_t* const a = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 3, 3, 1), 0); |
106 | 1 | a->data.f32[0] = 1; |
107 | 1 | a->data.f32[1] = 2; |
108 | 1 | a->data.f32[2] = 0; |
109 | 1 | a->data.f32[3] = 3; |
110 | 1 | a->data.f32[4] = 4; |
111 | 1 | a->data.f32[5] = 0; |
112 | 1 | a->data.f32[6] = 0; |
113 | 1 | a->data.f32[7] = 0; |
114 | 1 | a->data.f32[8] = 0; |
115 | 1 | ccv_nnc_tensor_t* const b = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 6, 6, 1), 0); |
116 | 1 | ccv_nnc_cmd_exec(CMD_UPSAMPLE_FORWARD(CCV_NNC_UPSAMPLE_NEAREST, 2, 2, 1), ccv_nnc_no_hint, 0, TENSOR_LIST(a), TENSOR_LIST(b), 0); |
117 | 1 | float bt[36] = { |
118 | 1 | 1, 1, 2, 2, 0, 0, |
119 | 1 | 1, 1, 2, 2, 0, 0, |
120 | 1 | 3, 3, 4, 4, 0, 0, |
121 | 1 | 3, 3, 4, 4, 0, 0, |
122 | 1 | 0, 0, 0, 0, 0, 0, |
123 | 1 | 0, 0, 0, 0, 0, 0, |
124 | 1 | }; |
125 | 1 | REQUIRE_ARRAY_EQ_WITH_TOLERANCE(float, b->data.f32, bt, 32, 1e-5, "should match ground truth"); |
126 | 1 | ccv_nnc_tensor_free(a); |
127 | 1 | ccv_nnc_tensor_free(b); |
128 | 1 | } |
129 | | |
130 | | TEST_CASE("upsample bilinear, align corners") |
131 | 1 | { |
132 | 1 | ccv_nnc_tensor_t* const a = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 3, 3, 1), 0); |
133 | 1 | a->data.f32[0] = 1; |
134 | 1 | a->data.f32[1] = 2; |
135 | 1 | a->data.f32[2] = 0; |
136 | 1 | a->data.f32[3] = 3; |
137 | 1 | a->data.f32[4] = 4; |
138 | 1 | a->data.f32[5] = 0; |
139 | 1 | a->data.f32[6] = 0; |
140 | 1 | a->data.f32[7] = 0; |
141 | 1 | a->data.f32[8] = 0; |
142 | 1 | ccv_nnc_tensor_t* const b = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 6, 6, 1), 0); |
143 | 1 | ccv_nnc_cmd_exec(CMD_UPSAMPLE_FORWARD(CCV_NNC_UPSAMPLE_BILINEAR, 2, 2, 1), ccv_nnc_no_hint, 0, TENSOR_LIST(a), TENSOR_LIST(b), 0); |
144 | 1 | float bt[36] = { |
145 | 1 | 1, 1.4, 1.8, 1.6, 0.8, 0.0, |
146 | 1 | 1.8, 2.2, 2.6, 2.24, 1.12, 0.0, |
147 | 1 | 2.6, 3.0, 3.4, 2.88, 1.44, 0.0, |
148 | 1 | 2.4, 2.72, 3.04, 2.56, 1.28, 0.0, |
149 | 1 | 1.2, 1.36, 1.52, 1.28, 0.64, 0.0, |
150 | 1 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, |
151 | 1 | }; |
152 | 1 | REQUIRE_ARRAY_EQ_WITH_TOLERANCE(float, b->data.f32, bt, 32, 1e-5, "should match ground truth"); |
153 | 1 | ccv_nnc_tensor_free(a); |
154 | 1 | ccv_nnc_tensor_free(b); |
155 | 1 | } |
156 | | |
157 | | TEST_CASE("downsample nearest") |
158 | 1 | { |
159 | 1 | ccv_nnc_tensor_t* const a = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 4, 4, 2), 0); |
160 | 1 | ccv_nnc_tensor_t* const b = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 2, 2, 2), 0); |
161 | 1 | int i; |
162 | 33 | for (i = 0; i < 32; i++32 ) |
163 | 32 | a->data.f32[i] = i; |
164 | 1 | ccv_nnc_cmd_exec(CMD_UPSAMPLE_BACKWARD(CCV_NNC_UPSAMPLE_NEAREST, 2, 2, 0), ccv_nnc_no_hint, 0, TENSOR_LIST(a), TENSOR_LIST(b), 0); |
165 | 1 | float bt[8] = { |
166 | 1 | 0 + 2 + 8 + 10, 1 + 3 + 9 + 11, 4 + 6 + 12 + 14, 5 + 7 + 13 + 15, |
167 | 1 | 16 + 18 + 24 + 26, 17 + 19 + 25 + 27, 20 + 22 + 28 + 30, 21 + 23 + 29 + 31, |
168 | | |
169 | 1 | }; |
170 | 1 | REQUIRE_ARRAY_EQ_WITH_TOLERANCE(float, b->data.f32, bt, 8, 1e-5, "should match ground truth"); |
171 | 1 | ccv_nnc_tensor_free(a); |
172 | 1 | ccv_nnc_tensor_free(b); |
173 | 1 | } |
174 | | |
175 | | TEST_CASE("upsample nearest in NCHW") |
176 | 1 | { |
177 | 1 | ccv_nnc_tensor_t* const a = ccv_nnc_tensor_new(0, CPU_TENSOR_NCHW(32F, 2, 2, 2), 0); |
178 | 1 | int i; |
179 | 9 | for (i = 0; i < 8; i++8 ) |
180 | 8 | a->data.f32[i] = i; |
181 | 1 | ccv_nnc_tensor_t* const b = ccv_nnc_tensor_new(0, CPU_TENSOR_NCHW(32F, 2, 4, 4), 0); |
182 | 1 | ccv_nnc_cmd_exec(CMD_UPSAMPLE_FORWARD(CCV_NNC_UPSAMPLE_NEAREST, 2, 2, 0), ccv_nnc_no_hint, 0, TENSOR_LIST(a), TENSOR_LIST(b), 0); |
183 | 1 | float bt[32] = { |
184 | 1 | 0, 0, 1, 1, |
185 | 1 | 0, 0, 1, 1, |
186 | 1 | 2, 2, 3, 3, |
187 | 1 | 2, 2, 3, 3, |
188 | 1 | 4, 4, 5, 5, |
189 | 1 | 4, 4, 5, 5, |
190 | 1 | 6, 6, 7, 7, |
191 | 1 | 6, 6, 7, 7, |
192 | 1 | }; |
193 | 1 | REQUIRE_ARRAY_EQ_WITH_TOLERANCE(float, b->data.f32, bt, 32, 1e-5, "should match ground truth"); |
194 | 1 | ccv_nnc_tensor_free(a); |
195 | 1 | ccv_nnc_tensor_free(b); |
196 | 1 | } |
197 | | |
198 | | TEST_CASE("downsample nearest in NCHW") |
199 | 1 | { |
200 | 1 | ccv_nnc_tensor_t* const a = ccv_nnc_tensor_new(0, CPU_TENSOR_NCHW(32F, 2, 4, 4), 0); |
201 | 1 | ccv_nnc_tensor_t* const b = ccv_nnc_tensor_new(0, CPU_TENSOR_NCHW(32F, 2, 2, 2), 0); |
202 | 1 | int i; |
203 | 33 | for (i = 0; i < 32; i++32 ) |
204 | 32 | a->data.f32[i] = i; |
205 | 1 | ccv_nnc_cmd_exec(CMD_UPSAMPLE_BACKWARD(CCV_NNC_UPSAMPLE_NEAREST, 2, 2, 0), ccv_nnc_no_hint, 0, TENSOR_LIST(a), TENSOR_LIST(b), 0); |
206 | 1 | float bt[8] = { |
207 | 1 | 0 + 1 + 4 + 5, 2 + 3 + 6 + 7, |
208 | 1 | 8 + 9 + 12 + 13, 10 + 11 + 14 + 15, |
209 | 1 | 16 + 17 + 20 + 21, 18 + 19 + 22 + 23, |
210 | 1 | 24 + 25 + 28 + 29, 26 + 27 + 30 + 31, |
211 | 1 | }; |
212 | 1 | REQUIRE_ARRAY_EQ_WITH_TOLERANCE(float, b->data.f32, bt, 8, 1e-5, "should match ground truth"); |
213 | 1 | ccv_nnc_tensor_free(a); |
214 | 1 | ccv_nnc_tensor_free(b); |
215 | 1 | } |
216 | | |
217 | | #include "case_main.h" |