Coverage Report

Created: 2025-02-24 17:43

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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"