## 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/transform.tests.c

    Line
    Count
    Source
    1
    #include "case.h"
    2
    #include "ccv_case.h"
    3
    #include "ccv_nnc_case.h"
    4
    #include <ccv.h>
    5
    #include <nnc/ccv_nnc.h>
    6
    #include <nnc/ccv_nnc_easy.h>
    7
    #include <3rdparty/dsfmt/dSFMT.h>
    8
    9
    TEST_SETUP()
    10
    {
    11
      ccv_nnc_init();
    12
    }
    13
    14
    TEST_CASE("data transfer between different tensor views")
    15
    {
    16
      ccv_nnc_tensor_t* a = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 56, 56, 128), 0);
    17
      ccv_nnc_tensor_t* b = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 24, 32, 64), 0);
    18
      ccv_nnc_cmd_t cmd = CMD_DATA_TRANSFER_FORWARD();
    19
      int i;
    20
      for (i = 0; i < 128 * 56 * 56; i++)
    21
        a->data.f32[i] = i;
    22
      // 6 values, manageable.
    23
      ccv_nnc_tensor_view_t a_view = ccv_nnc_tensor_view(a, CPU_TENSOR_NHWC(32F, 2, 3, 4), DIM_ALLOC(4, 3, 2), DIM_ALLOC(56 * 128, 128, 1));
    24
      ccv_nnc_tensor_view_t b_view = ccv_nnc_tensor_view(b, CPU_TENSOR_NHWC(32F, 2, 3, 4), DIM_ALLOC(0, 0, 0), DIM_ALLOC(32 * 64, 64, 1));
    25
      memset(b->data.f32, 0, sizeof(float) * 64 * 32 * 24);
    26
      ccv_nnc_cmd_exec(cmd, ccv_nnc_no_hint, 0, TENSOR_LIST((ccv_nnc_tensor_t*)&a_view), TENSOR_LIST((ccv_nnc_tensor_t*)&b_view), 0);
    27
      ccv_nnc_tensor_t* c = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 24, 32, 64), 0);
    28
      memset(c->data.f32, 0, sizeof(float) * 64 * 32 * 24);
    29
      c->data.f32[0] = 128 * 56 * 4 + 128 * 3 + 2;
    30
      c->data.f32[1] = 128 * 56 * 4 + 128 * 3 + 3;
    31
      c->data.f32[2] = 128 * 56 * 4 + 128 * 3 + 4;
    32
      c->data.f32[3] = 128 * 56 * 4 + 128 * 3 + 5;
    33
      c->data.f32[64] = 128 * 56 * 4 + 128 * (3 + 1) + 2;
    34
      c->data.f32[65] = 128 * 56 * 4 + 128 * (3 + 1) + 3;
    35
      c->data.f32[66] = 128 * 56 * 4 + 128 * (3 + 1) + 4;
    36
      c->data.f32[67] = 128 * 56 * 4 + 128 * (3 + 1) + 5;
    37
      c->data.f32[128] = 128 * 56 * 4 + 128 * (3 + 2) + 2;
    38
      c->data.f32[129] = 128 * 56 * 4 + 128 * (3 + 2) + 3;
    39
      c->data.f32[130] = 128 * 56 * 4 + 128 * (3 + 2) + 4;
    40
      c->data.f32[131] = 128 * 56 * 4 + 128 * (3 + 2) + 5;
    41
      c->data.f32[64 * 32] = 128 * 56 * (4 + 1) + 128 * 3 + 2;
    42
      c->data.f32[64 * 32 + 1] = 128 * 56 * (4 + 1) + 128 * 3 + 3;
    43
      c->data.f32[64 * 32 + 2] = 128 * 56 * (4 + 1) + 128 * 3 + 4;
    44
      c->data.f32[64 * 32 + 3] = 128 * 56 * (4 + 1) + 128 * 3 + 5;
    45
      c->data.f32[64 * 32 + 64] = 128 * 56 * (4 + 1) + 128 * (3 + 1) + 2;
    46
      c->data.f32[64 * 32 + 65] = 128 * 56 * (4 + 1) + 128 * (3 + 1) + 3;
    47
      c->data.f32[64 * 32 + 66] = 128 * 56 * (4 + 1) + 128 * (3 + 1) + 4;
    48
      c->data.f32[64 * 32 + 67] = 128 * 56 * (4 + 1) + 128 * (3 + 1) + 5;
    49
      c->data.f32[64 * 32 + 128] = 128 * 56 * (4 + 1) + 128 * (3 + 2) + 2;
    50
      c->data.f32[64 * 32 + 129] = 128 * 56 * (4 + 1) + 128 * (3 + 2) + 3;
    51
      c->data.f32[64 * 32 + 130] = 128 * 56 * (4 + 1) + 128 * (3 + 2) + 4;
    52
      c->data.f32[64 * 32 + 131] = 128 * 56 * (4 + 1) + 128 * (3 + 2) + 5;
    53
      REQUIRE_TENSOR_EQ(b, c, "64x32x24 tensor should be exactly the same.");
    54
      ccv_nnc_tensor_free(a);
    55
      ccv_nnc_tensor_free(b);
    56
      ccv_nnc_tensor_free(c);
    57
    }
    58
    59
    TEST_CASE("format transform between NHWC and NCHW tensors")
    60
    1
    {
    61
    1
      ccv_nnc_tensor_t* a = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 4, 3, 2), 0);
    62
    1
      ccv_nnc_tensor_t* b = ccv_nnc_tensor_new(0, CPU_TENSOR_NCHW(32F, 2, 4, 3), 0);
    63
    1
      ccv_nnc_cmd_t cmd = CMD_FORMAT_TRANSFORM_FORWARD();
    64
    1
      int i;
    65
    25
      for (i = 0; i < 2 * 3 * 4; i++24)
    66
    24
        a->data.f32[i] = i;
    67
    1
      ccv_nnc_cmd_exec(cmd, ccv_nnc_no_hint, 0, TENSOR_LIST(a), TENSOR_LIST(b), 0);
    68
    1
      ccv_nnc_tensor_t* c = ccv_nnc_tensor_new(0, CPU_TENSOR_NCHW(32F, 2, 4, 3), 0);
    69
    1
      c->data.f32[0] = 0;
    70
    1
      c->data.f32[1] = 2;
    71
    1
      c->data.f32[2] = 4;
    72
    1
      c->data.f32[3] = 6;
    73
    1
      c->data.f32[4] = 8;
    74
    1
      c->data.f32[5] = 10;
    75
    1
      c->data.f32[6] = 12;
    76
    1
      c->data.f32[7] = 14;
    77
    1
      c->data.f32[8] = 16;
    78
    1
      c->data.f32[9] = 18;
    79
    1
      c->data.f32[10] = 20;
    80
    1
      c->data.f32[11] = 22;
    81
    1
      c->data.f32[12] = 1;
    82
    1
      c->data.f32[13] = 3;
    83
    1
      c->data.f32[14] = 5;
    84
    1
      c->data.f32[15] = 7;
    85
    1
      c->data.f32[16] = 9;
    86
    1
      c->data.f32[17] = 11;
    87
    1
      c->data.f32[18] = 13;
    88
    1
      c->data.f32[19] = 15;
    89
    1
      c->data.f32[20] = 17;
    90
    1
      c->data.f32[21] = 19;
    91
    1
      c->data.f32[22] = 21;
    92
    1
      c->data.f32[23] = 23;
    93
    1
      REQUIRE_TENSOR_EQ(b, c, "3x4x2 tensor should be exactly the same.");
    94
    1
      ccv_nnc_tensor_t* d = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 4, 3, 2), 0);
    95
    1
      ccv_nnc_cmd_exec(cmd, ccv_nnc_no_hint, 0, TENSOR_LIST(c), TENSOR_LIST(d), 0);
    96
    1
      REQUIRE_TENSOR_EQ(d, a, "2x3x4 tensor should be exactly the same.");
    97
    1
      ccv_nnc_tensor_free(a);
    98
    1
      ccv_nnc_tensor_free(b);
    99
    1
      ccv_nnc_tensor_free(c);
    100
    1
      ccv_nnc_tensor_free(d);
    101
    1
    }
    102
    103
    TEST_CASE("format transform between NHWC and NCHW tensor views")
    104
    1
    {
    105
    1
      ccv_nnc_tensor_t* a = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 7, 6, 5), 0);
    106
    1
      ccv_nnc_tensor_view_t a_view = ccv_nnc_tensor_view(a, CPU_TENSOR_NHWC(32F, 4, 3, 2), DIM_ALLOC(3, 2, 1), DIM_ALLOC(6 * 5, 5, 1));
    107
    1
      memset(a->data.f32, 0, sizeof(float) * 5 * 6 * 7);
    108
    1
      ccv_nnc_tensor_t* b = ccv_nnc_tensor_new(0, CPU_TENSOR_NCHW(32F, 8, 10, 8), 0);
    109
    1
      memset(b->data.f32, 0, sizeof(float) * 8 * 10 * 8);
    110
    1
      ccv_nnc_tensor_view_t b_view = ccv_nnc_tensor_view(b, CPU_TENSOR_NCHW(32F, 2, 4, 3), DIM_ALLOC(0, 0, 0), DIM_ALLOC(10 * 8, 8, 1));
    111
    1
      ccv_nnc_cmd_t cmd = CMD_FORMAT_TRANSFORM_FORWARD();
    112
    1
      int i, j, k;
    113
    5
      for (i = 0; i < 4; i++4)
    114
    16
        for (j = 0; 4j < 3; j++12)
    115
    36
          for (k = 0; 12k < 2; k++24)
    116
    24
            a->data.f32[(i + 3) * 5 * 6 + (j + 2) * 5 + (k + 1)] = k + j * 2 + i * 3 * 2;
    117
    1
      ccv_nnc_cmd_exec(cmd, ccv_nnc_no_hint, 0, TENSOR_LIST((ccv_nnc_tensor_t*)&a_view), TENSOR_LIST((ccv_nnc_tensor_t*)&b_view), 0);
    118
    1
      ccv_nnc_tensor_t* c = ccv_nnc_tensor_new(0, CPU_TENSOR_NCHW(32F, 8, 10, 8), 0);
    119
    1
      memset(c->data.f32, 0, sizeof(float) * 8 * 10 * 8);
    120
    1
      c->data.f32[0] = 0;
    121
    1
      c->data.f32[1] = 2;
    122
    1
      c->data.f32[2] = 4;
    123
    1
      c->data.f32[8] = 6;
    124
    1
      c->data.f32[9] = 8;
    125
    1
      c->data.f32[10] = 10;
    126
    1
      c->data.f32[16] = 12;
    127
    1
      c->data.f32[17] = 14;
    128
    1
      c->data.f32[18] = 16;
    129
    1
      c->data.f32[24] = 18;
    130
    1
      c->data.f32[25] = 20;
    131
    1
      c->data.f32[26] = 22;
    132
    1
      c->data.f32[80] = 1;
    133
    1
      c->data.f32[81] = 3;
    134
    1
      c->data.f32[82] = 5;
    135
    1
      c->data.f32[88] = 7;
    136
    1
      c->data.f32[89] = 9;
    137
    1
      c->data.f32[90] = 11;
    138
    1
      c->data.f32[96] = 13;
    139
    1
      c->data.f32[97] = 15;
    140
    1
      c->data.f32[98] = 17;
    141
    1
      c->data.f32[104] = 19;
    142
    1
      c->data.f32[105] = 21;
    143
    1
      c->data.f32[106] = 23;
    144
    1
      REQUIRE_TENSOR_EQ(b, c, "3x4x2 tensor view should be exactly the same.");
    145
    1
      ccv_nnc_tensor_view_t c_view = ccv_nnc_tensor_view(c, CPU_TENSOR_NCHW(32F, 2, 4, 3), DIM_ALLOC(0, 0, 0), DIM_ALLOC(10 * 8, 8, 1));
    146
    1
      ccv_nnc_tensor_t* d = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 7, 6, 5), 0);
    147
    1
      memset(d->data.f32, 0, sizeof(float) * 5 * 6 * 7);
    148
    1
      ccv_nnc_tensor_view_t d_view = ccv_nnc_tensor_view(d, CPU_TENSOR_NHWC(32F, 4, 3, 2), DIM_ALLOC(3, 2, 1), DIM_ALLOC(6 * 5, 5, 1));
    149
    1
      ccv_nnc_cmd_exec(cmd, ccv_nnc_no_hint, 0, TENSOR_LIST((ccv_nnc_tensor_t*)&c_view), TENSOR_LIST((ccv_nnc_tensor_t*)&d_view), 0);
    150
    1
      REQUIRE_TENSOR_EQ(d, a, "2x3x4 tensor should be exactly the same.");
    151
    1
      ccv_nnc_tensor_free(a);
    152
    1
      ccv_nnc_tensor_free(b);
    153
    1
      ccv_nnc_tensor_free(c);
    154
    1
      ccv_nnc_tensor_free(d);
    155
    1
    }
    156
    157
    TEST_CASE("transpose two 4d tensor views")
    158
    1
    {
    159
    1
      ccv_nnc_tensor_t* const a = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 7, 6, 5, 4), 0);
    160
    1
      memset(a->data.f32, 0, sizeof(float) * 7 * 6 * 5 * 4);
    161
    1
      ccv_nnc_tensor_view_t a_view = ccv_nnc_tensor_view(a, CPU_TENSOR_NHWC(32F, 4, 3, 2, 2), DIM_ALLOC(3, 2, 1, 0), DIM_ALLOC(6 * 5 * 4, 5 * 4, 4, 1));
    162
    1
      ccv_nnc_tensor_t* const b = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 8, 7, 6, 5), 0);
    163
    1
      memset(b->data.f32, 0, sizeof(float) * 8 * 7 * 6 * 5);
    164
    1
      ccv_nnc_tensor_view_t b_view = ccv_nnc_tensor_view(b, CPU_TENSOR_NHWC(32F, 4, 2, 2, 3), DIM_ALLOC(3, 2, 1, 0), DIM_ALLOC(7 * 6 * 5, 6 * 5, 5, 1));
    165
    1
      int i, j, k, l;
    166
    5
      for (i = 0; i < 4; i++4)
    167
    16
        for (j = 0; 4j < 3; j++12)
    168
    36
          for (k = 0; 12k < 2; k++24)
    169
    72
            for (l = 0; 24l < 2; l++48)
    170
    48
              a->data.f32[(i + 3) * 6 * 5 * 4 + (j + 2) * 5 * 4 + (k + 1) * 4 + l] = i * 3 * 2 * 2 + j * 2 * 2 + k * 2 + l;
    171
    1
      ccv_nnc_cmd_exec(CMD_TRANSPOSE_FORWARD(1, 3), ccv_nnc_no_hint, 0, TENSOR_LIST((ccv_nnc_tensor_t*)&a_view), TENSOR_LIST((ccv_nnc_tensor_t*)&b_view), 0);
    172
    1
      ccv_nnc_tensor_t* c = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 8, 7, 6, 5), 0);
    173
    1
      memset(c->data.f32, 0, sizeof(float) * 8 * 7 * 6 * 5);
    174
    5
      for (i = 0; i < 4; i++4)
    175
    16
        for (j = 0; 4j < 3; j++12)
    176
    36
          for (k = 0; 12k < 2; k++24)
    177
    72
            for (l = 0; 24l < 2; l++48)
    178
    48
              c->data.f32[(i + 3) * 7 * 6 * 5 + (l + 2) * 6 * 5 + (k + 1) * 5 + j] = i * 3 * 2 * 2 + j * 2 * 2 + k * 2 + l;
    179
    1
      REQUIRE_TENSOR_EQ(b, c, "4x2x2x3 tensor view should be exactly the same.");
    180
    1
      ccv_nnc_tensor_view_t c_view = ccv_nnc_tensor_view(c, CPU_TENSOR_NHWC(32F, 4, 2, 2, 3), DIM_ALLOC(3, 2, 1, 0), DIM_ALLOC(7 * 6 * 5, 6 * 5, 5, 1));
    181
    1
      ccv_nnc_tensor_t* d = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 7, 6, 5, 4), 0);
    182
    1
      memset(d->data.f32, 0, sizeof(float) * 7 * 6 * 5 * 4);
    183
    1
      ccv_nnc_tensor_view_t d_view = ccv_nnc_tensor_view(d, CPU_TENSOR_NHWC(32F, 4, 3, 2, 2), DIM_ALLOC(3, 2, 1, 0), DIM_ALLOC(6 * 5 * 4, 5 * 4, 4, 1));
    184
    1
      ccv_nnc_cmd_exec(CMD_TRANSPOSE_FORWARD(1, 3), ccv_nnc_no_hint, 0, TENSOR_LIST((ccv_nnc_tensor_t*)&c_view), TENSOR_LIST((ccv_nnc_tensor_t*)&d_view), 0);
    185
    1
      REQUIRE_TENSOR_EQ(d, a, "4x3x2x2 tensor should be exactly the same.");
    186
    1
      ccv_nnc_tensor_free(a);
    187
    1
      ccv_nnc_tensor_free(b);
    188
    1
      ccv_nnc_tensor_free(c);
    189
    1
      ccv_nnc_tensor_free(d);
    190
    1
    }
    191
    192
    TEST_CASE("transpose two 3d tensor views")
    193
    1
    {
    194
    1
      ccv_nnc_tensor_t* const a = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 6, 5, 4), 0);
    195
    1
      memset(a->data.f32, 0, sizeof(float) * 6 * 5 * 4);
    196
    1
      ccv_nnc_tensor_view_t a_view = ccv_nnc_tensor_view(a, CPU_TENSOR_NHWC(32F, 3, 2, 2), DIM_ALLOC(2, 1, 0), DIM_ALLOC(5 * 4, 4, 1));
    197
    1
      ccv_nnc_tensor_t* const b = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 7, 6, 5), 0);
    198
    1
      memset(b->data.f32, 0, sizeof(float) * 7 * 6 * 5);
    199
    1
      ccv_nnc_tensor_view_t b_view = ccv_nnc_tensor_view(b, CPU_TENSOR_NHWC(32F, 2, 2, 3), DIM_ALLOC(2, 1, 0), DIM_ALLOC(6 * 5, 5, 1));
    200
    1
      int j, k, l;
    201
    4
      for (j = 0; j < 3; j++3)
    202
    9
        for (k = 0; 3k < 2; k++6)
    203
    18
          for (l = 0; 6l < 2; l++12)
    204
    12
            a->data.f32[(j + 2) * 5 * 4 + (k + 1) * 4 + l] = j * 2 * 2 + k * 2 + l;
    205
    1
      ccv_nnc_cmd_exec(CMD_TRANSPOSE_FORWARD(0, 2), ccv_nnc_no_hint, 0, TENSOR_LIST((ccv_nnc_tensor_t*)&a_view), TENSOR_LIST((ccv_nnc_tensor_t*)&b_view), 0);
    206
    1
      ccv_nnc_tensor_t* c = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 7, 6, 5), 0);
    207
    1
      memset(c->data.f32, 0, sizeof(float) * 7 * 6 * 5);
    208
    4
      for (j = 0; j < 3; j++3)
    209
    9
        for (k = 0; 3k < 2; k++6)
    210
    18
          for (l = 0; 6l < 2; l++12)
    211
    12
            c->data.f32[(l + 2) * 6 * 5 + (k + 1) * 5 + j] = j * 2 * 2 + k * 2 + l;
    212
    1
      REQUIRE_TENSOR_EQ(b, c, "2x2x3 tensor view should be exactly the same.");
    213
    1
      ccv_nnc_tensor_view_t c_view = ccv_nnc_tensor_view(c, CPU_TENSOR_NHWC(32F, 2, 2, 3), DIM_ALLOC(2, 1, 0), DIM_ALLOC(6 * 5, 5, 1));
    214
    1
      ccv_nnc_tensor_t* d = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 6, 5, 4), 0);
    215
    1
      memset(d->data.f32, 0, sizeof(float) * 6 * 5 * 4);
    216
    1
      ccv_nnc_tensor_view_t d_view = ccv_nnc_tensor_view(d, CPU_TENSOR_NHWC(32F, 3, 2, 2), DIM_ALLOC(2, 1, 0), DIM_ALLOC(5 * 4, 4, 1));
    217
    1
      ccv_nnc_cmd_exec(CMD_TRANSPOSE_FORWARD(0, 2), ccv_nnc_no_hint, 0, TENSOR_LIST((ccv_nnc_tensor_t*)&c_view), TENSOR_LIST((ccv_nnc_tensor_t*)&d_view), 0);
    218
    1
      REQUIRE_TENSOR_EQ(d, a, "3x2x2 tensor should be exactly the same.");
    219
    1
      ccv_nnc_tensor_free(a);
    220
    1
      ccv_nnc_tensor_free(b);
    221
    1
      ccv_nnc_tensor_free(c);
    222
    1
      ccv_nnc_tensor_free(d);
    223
    1
    }
    224
    225
    TEST_CASE("masked fill forward a 3d tensor")
    226
    1
    {
    227
    1
      ccv_nnc_tensor_t* const a = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 6, 5, 4), 0);
    228
    1
      int i, j;
    229
    1
      dsfmt_t dsfmt;
    230
    1
      dsfmt_init_gen_rand(&dsfmt, 0);
    231
    121
      for (i = 0; i < 6 * 5 * 4; i++120)
    232
    120
        a->data.f32[i] = dsfmt_genrand_open_close(&dsfmt);
    233
    1
      ccv_nnc_tensor_t* const b = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32S, 5, 4), 0);
    234
    21
      for (i = 0; i < 5 * 4; i++20)
    235
    20
        b->data.i32[i] = (i % 2 == 1) ? 010 : 110;
    236
    1
      ccv_nnc_tensor_t* const c = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 6, 5, 4), 0);
    237
    1
      ccv_nnc_cmd_exec(CMD_MASKED_FILL_FORWARD(0, -1e8), ccv_nnc_no_hint, 0, TENSOR_LIST(a, b), TENSOR_LIST(c), 0);
    238
    1
      ccv_nnc_tensor_t* const d = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 6, 5, 4), 0);
    239
    7
      for (i = 0; i < 6; i++6)
    240
    126
        for (j = 0; 6j < 5 * 4; j++120)
    241
    120
          d->data.f32[i * 5 * 4 + j] = (j % 2 == 1) ? -1e860 : a->data.f32[i * 5 * 4 + j]60;
    242
    1
      REQUIRE_TENSOR_EQ(d, c, "6x5x4 tensor should be exactly the same.");
    243
    1
      ccv_nnc_tensor_free(a);
    244
    1
      ccv_nnc_tensor_free(b);
    245
    1
      ccv_nnc_tensor_free(c);
    246
    1
      ccv_nnc_tensor_free(d);
    247
    1
    }
    248
    249
    TEST_CASE("masked fill backward a 3d tensor")
    250
    1
    {
    251
    1
      ccv_nnc_tensor_t* const a = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 6, 5, 4), 0);
    252
    1
      int i, j;
    253
    1
      dsfmt_t dsfmt;
    254
    1
      dsfmt_init_gen_rand(&dsfmt, 0);
    255
    121
      for (i = 0; i < 6 * 5 * 4; i++120)
    256
    120
        a->data.f32[i] = dsfmt_genrand_open_close(&dsfmt);
    257
    1
      ccv_nnc_tensor_t* const b = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32S, 5, 4), 0);
    258
    21
      for (i = 0; i < 5 * 4; i++20)
    259
    20
        b->data.i32[i] = (i % 2 == 1) ? 010 : 110;
    260
    1
      ccv_nnc_tensor_t* const c = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 6, 5, 4), 0);
    261
    1
      ccv_nnc_cmd_exec(CMD_MASKED_FILL_BACKWARD(0, -1e8), ccv_nnc_no_hint, 0, TENSOR_LIST(a, 0, b), TENSOR_LIST(c), 0);
    262
    1
      ccv_nnc_tensor_t* const d = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 6, 5, 4), 0);
    263
    7
      for (i = 0; i < 6; i++6)
    264
    126
        for (j = 0; 6j < 5 * 4; j++120)
    265
    120
          d->data.f32[i * 5 * 4 + j] = (j % 2 == 1) ? 060 : a->data.f32[i * 5 * 4 + j]60;
    266
    1
      REQUIRE_TENSOR_EQ(d, c, "6x5x4 tensor should be exactly the same.");
    267
    1
      ccv_nnc_tensor_free(a);
    268
    1
      ccv_nnc_tensor_free(b);
    269
    1
      ccv_nnc_tensor_free(c);
    270
    1
      ccv_nnc_tensor_free(d);
    271
    1
    }
    272
    273
    TEST_CASE("compare permute with transpose")
    274
    1
    {
    275
    1
      ccv_nnc_tensor_t* const a = ccv_nnc_tensor_new(0, CPU_TENSOR_NCHW(32F, 6, 5, 4, 3), 0);
    276
    1
      int i;
    277
    1
      dsfmt_t dsfmt;
    278
    1
      dsfmt_init_gen_rand(&dsfmt, 0);
    279
    361
      for (i = 0; i < 6 * 5 * 4 * 3; i++360)
    280
    360
        a->data.f32[i] = dsfmt_genrand_open_close(&dsfmt);
    281
    1
      ccv_nnc_tensor_view_t* const av = ccv_nnc_tensor_view_new(a, CPU_TENSOR_NCHW(32F, 6, 4, 5, 3), ccv_nnc_no_ofs, DIM_ALLOC(5 * 4 * 3, 3, 4 * 3, 1));
    282
    1
      ccv_nnc_tensor_t* const b = ccv_nnc_tensor_new(0, CPU_TENSOR_NCHW(32F, 6, 4, 5, 3), 0);
    283
    1
      ccv_nnc_tensor_t* const c = ccv_nnc_tensor_new(0, CPU_TENSOR_NCHW(32F, 6, 4, 5, 3), 0);
    284
    1
      ccv_nnc_cmd_exec(CMD_FORMAT_TRANSFORM_FORWARD(), ccv_nnc_no_hint, 0, TENSOR_LIST((ccv_nnc_tensor_t*)av), TENSOR_LIST(b), 0);
    285
    1
      ccv_nnc_cmd_exec(CMD_TRANSPOSE_FORWARD(1, 2), ccv_nnc_no_hint, 0, TENSOR_LIST(a), TENSOR_LIST(c), 0);
    286
    1
      REQUIRE_TENSOR_EQ(b, c, "transposed and permuted should be exactly the same.");
    287
    1
      ccv_nnc_tensor_free(a);
    288
    1
      ccv_nnc_tensor_view_free(av);
    289
    1
      ccv_nnc_tensor_free(b);
    290
    1
      ccv_nnc_tensor_free(c);
    291
    1
    }
    292
    293
    #include "case_main.h"