Coverage Report

Created: 2021-04-12 03:25

/home/liu/buildslave/linux-x64-runtests/build/test/unit/nnc/tensor.tests.c
Line
Count
Source
1
#include "ccv.h"
2
#include "case.h"
3
#include "ccv_case.h"
4
#include "ccv_nnc_case.h"
5
#include "nnc/ccv_nnc.h"
6
#include "nnc/ccv_nnc_easy.h"
7
#include "3rdparty/sqlite3/sqlite3.h"
8
#include "3rdparty/dsfmt/dSFMT.h"
9
10
TEST_SETUP()
11
{
12
  ccv_nnc_init();
13
}
14
15
TEST_CASE("zero out a tensor")
16
1
{
17
1
  const ccv_nnc_tensor_param_t params = {
18
1
    .type = CCV_TENSOR_CPU_MEMORY,
19
1
    .format = CCV_TENSOR_FORMAT_NHWC,
20
1
    .datatype = CCV_32F,
21
1
    .dim = {
22
1
      10, 20, 30, 4, 5, 6,
23
1
    },
24
1
  };
25
1
  ccv_nnc_tensor_t* tensor = ccv_nnc_tensor_new(0, params, 0);
26
1
  int i;
27
720k
  for (i = 0; i < 10 * 20 * 30 * 4 * 5 * 6; 
i++720k
)
28
720k
    tensor->data.f32[i] = 1;
29
1
  ccv_nnc_tensor_zero(tensor);
30
720k
  for (i = 0; i < 10 * 20 * 30 * 4 * 5 * 6; 
i++720k
)
31
720k
    REQUIRE_EQ(0, tensor->data.f32[i], "should be zero'ed at %d", i);
32
1
  ccv_nnc_tensor_free(tensor);
33
1
}
34
35
TEST_CASE("zero out a tensor view")
36
1
{
37
1
  const ccv_nnc_tensor_param_t params = {
38
1
    .type = CCV_TENSOR_CPU_MEMORY,
39
1
    .format = CCV_TENSOR_FORMAT_NHWC,
40
1
    .datatype = CCV_32F,
41
1
    .dim = {
42
1
      10, 20, 30, 4, 5, 6,
43
1
    },
44
1
  };
45
1
  ccv_nnc_tensor_t* a_tensor = ccv_nnc_tensor_new(0, params, 0);
46
1
  int c;
47
720k
  for (c = 0; c < 10 * 20 * 30 * 4 * 5 * 6; 
c++720k
)
48
720k
    a_tensor->data.f32[c] = 1;
49
1
  int ofs[CCV_NNC_MAX_DIM_ALLOC] = {
50
1
    1, 2, 5, 1, 1, 1,
51
1
  };
52
1
  const ccv_nnc_tensor_param_t new_params = {
53
1
    .type = CCV_TENSOR_CPU_MEMORY,
54
1
    .format = CCV_TENSOR_FORMAT_NHWC,
55
1
    .datatype = CCV_32F,
56
1
    .dim = {
57
1
      8, 12, 15, 2, 3, 4,
58
1
    },
59
1
  };
60
1
  ccv_nnc_tensor_view_t a_tensor_view = ccv_nnc_tensor_view(a_tensor, new_params, ofs, a_tensor->info.dim);
61
1
  ccv_nnc_tensor_zero(&a_tensor_view);
62
1
  ccv_nnc_tensor_t* b_tensor = ccv_nnc_tensor_new(0, params, 0);
63
720k
  for (c = 0; c < 10 * 20 * 30 * 4 * 5 * 6; 
c++720k
)
64
720k
    b_tensor->data.f32[c] = 1;
65
1
  ccv_nnc_tensor_view_t b_tensor_view = ccv_nnc_tensor_view(b_tensor, new_params, ofs, b_tensor->info.dim);
66
1
  int i[6];
67
1
  float* tvp[6];
68
1
  tvp[5] = b_tensor_view.data.f32;
69
9
  for (i[5] = 0; i[5] < b_tensor_view.info.dim[0]; 
i[5]++8
)
70
8
  {
71
8
    tvp[4] = tvp[5];
72
104
    for (i[4] = 0; i[4] < b_tensor_view.info.dim[1]; 
i[4]++96
)
73
96
    {
74
96
      tvp[3] = tvp[4];
75
1.53k
      for (i[3] = 0; i[3] < b_tensor_view.info.dim[2]; 
i[3]++1.44k
)
76
1.44k
      {
77
1.44k
        tvp[2] = tvp[3];
78
4.32k
        for (i[2] = 0; i[2] < b_tensor_view.info.dim[3]; 
i[2]++2.88k
)
79
2.88k
        {
80
2.88k
          tvp[1] = tvp[2];
81
11.5k
          for (i[1] = 0; i[1] < b_tensor_view.info.dim[4]; 
i[1]++8.64k
)
82
8.64k
          {
83
8.64k
            tvp[0] = tvp[1];
84
43.2k
            for (i[0] = 0; i[0] < b_tensor_view.info.dim[5]; 
i[0]++34.5k
)
85
34.5k
            {
86
34.5k
              tvp[0][i[0]] = 0;
87
34.5k
            }
88
8.64k
            tvp[1] += b_tensor_view.inc[5];
89
8.64k
          }
90
2.88k
          tvp[2] += b_tensor_view.inc[4] * b_tensor_view.inc[5];
91
2.88k
        }
92
1.44k
        tvp[3] += b_tensor_view.inc[3] * b_tensor_view.inc[4] * b_tensor_view.inc[5];
93
1.44k
      }
94
96
      tvp[4] += b_tensor_view.inc[2] * b_tensor_view.inc[3] * b_tensor_view.inc[4] * b_tensor_view.inc[5];
95
96
    }
96
8
    tvp[5] += b_tensor_view.inc[1] * b_tensor_view.inc[2] * b_tensor_view.inc[3] * b_tensor_view.inc[4] * b_tensor_view.inc[5];
97
8
  }
98
1
  REQUIRE_TENSOR_EQ(a_tensor, b_tensor, "zero'ed tensor view should be equal");
99
1
  ccv_nnc_tensor_free(a_tensor);
100
1
  ccv_nnc_tensor_free(b_tensor);
101
1
}
102
103
TEST_CASE("hint tensor")
104
1
{
105
1
  ccv_nnc_tensor_param_t a = CPU_TENSOR_NHWC(32F, 234, 128, 3);
106
1
  ccv_nnc_hint_t hint = {
107
1
    .border = {
108
1
      .begin = {1, 1},
109
1
      .end = {1, 2}
110
1
    },
111
1
    .stride = {
112
1
      .dim = {8, 7}
113
1
    }
114
1
  };
115
1
  ccv_nnc_cmd_t cmd = CMD_CONVOLUTION_FORWARD(1, 128, 4, 5, 3);
116
1
  ccv_nnc_tensor_param_t b;
117
1
  ccv_nnc_tensor_param_t w = CPU_TENSOR_NHWC(32F, 128, 4, 5, 3);
118
1
  ccv_nnc_tensor_param_t bias = CPU_TENSOR_NHWC(32F, 128);
119
1
  ccv_nnc_hint_tensor_auto(cmd, TENSOR_PARAM_LIST(a, w, bias), hint, &b, 1);
120
1
  REQUIRE_EQ(b.dim[0], 30, "height should be 30");
121
1
  REQUIRE_EQ(b.dim[1], 19, "width should be 19");
122
1
  REQUIRE_EQ(b.dim[2], 128, "channel should be the convolution filter count");
123
1
}
124
125
TEST_CASE("tensor persistence")
126
1
{
127
1
  sqlite3* handle;
128
1
  sqlite3_open("tensors.sqlite3", &handle);
129
1
  ccv_nnc_tensor_t* const tensor = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 10, 20, 30), 0);
130
1
  int i;
131
1
  dsfmt_t dsfmt;
132
1
  dsfmt_init_gen_rand(&dsfmt, 1);
133
6.00k
  for (i = 0; i < 10 * 20 * 30; 
i++6.00k
)
134
6.00k
    tensor->data.f32[i] = dsfmt_genrand_open_close(&dsfmt) * 2 - 1;
135
1
  ccv_nnc_tensor_write(tensor, handle, "x");
136
1
  sqlite3_close(handle);
137
1
  handle = 0;
138
1
  sqlite3_open("tensors.sqlite3", &handle);
139
1
  ccv_nnc_tensor_t* tensor1 = 0;
140
1
  ccv_nnc_tensor_read(handle, "x", &tensor1);
141
1
  ccv_nnc_tensor_t* tensor2 = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 10), 0);
142
1
  ccv_nnc_tensor_read(handle, "x", &tensor2);
143
1
  sqlite3_close(handle);
144
1
  REQUIRE_TENSOR_EQ(tensor1, tensor, "the first tensor should equal to the second");
145
1
  REQUIRE_ARRAY_EQ_WITH_TOLERANCE(float, tensor2->data.f32, tensor->data.f32, 10, 1e-5, "the first 10 element should be equal");
146
1
  REQUIRE(ccv_nnc_tensor_nd(tensor2->info.dim) == 1, "should be 1-d tensor");
147
1
  REQUIRE_EQ(tensor2->info.dim[0], 10, "should be 1-d tensor with 10-element");
148
1
  ccv_nnc_tensor_free(tensor1);
149
1
  ccv_nnc_tensor_free(tensor2);
150
1
  ccv_nnc_tensor_free(tensor);
151
1
}
152
153
TEST_CASE("resize tensor")
154
1
{
155
1
  ccv_nnc_tensor_t* tensor = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 12, 12, 3), 0);
156
1
  int i;
157
433
  for (i = 0; i < 12 * 12 * 3; 
i++432
)
158
432
    tensor->data.f32[i] = i;
159
1
  tensor = ccv_nnc_tensor_resize(tensor, CPU_TENSOR_NHWC(32F, 23, 23, 3));
160
1.15k
  for (i = 12 * 12 * 3; i < 23 * 23 * 3; 
i++1.15k
)
161
1.15k
    tensor->data.f32[i] = i;
162
1
  ccv_nnc_tensor_t* b = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 23, 23, 3), 0);
163
1.58k
  for (i = 0; i < 23 * 23 * 3; 
i++1.58k
)
164
1.58k
    b->data.f32[i] = i;
165
1
  REQUIRE_TENSOR_EQ(tensor, b, "should retain the content when resize a tensor");
166
1
  ccv_nnc_tensor_free(tensor);
167
1
  ccv_nnc_tensor_free(b);
168
1
}
169
170
#include "case_main.h"