## Coverage Report

#### Created: 2026-05-04 15:30

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"