Coverage Report

Created: 2024-08-19 11:27

/home/liu/actions-runner/_work/ccv/ccv/test/unit/nnc/symbolic.graph.compile.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
static int _case_of(ccv_nnc_tensor_t* const *const inputs, const int input_size, const void *const case_of_data)
15
4
{
16
4
  if (inputs[0]->data.f32[0] < 0)
17
1
    return -1;
18
3
  else if (inputs[0]->data.f32[0] < 1)
19
1
    return 0;
20
2
  else if (inputs[0]->data.f32[0] < 2)
21
1
    return 2;
22
1
  else
23
1
    return 1;
24
4
}
25
26
TEST_CASE("compile symbolic graph with case..of")
27
1
{
28
1
  ccv_nnc_symbolic_graph_t* const symbolic_graph = ccv_nnc_symbolic_graph_new();
29
1
  ccv_nnc_tensor_symbol_t x = ccv_nnc_tensor_symbol_new(symbolic_graph, CPU_TENSOR_NHWC(32F, 2), "x");
30
1
  ccv_nnc_tensor_symbol_t y = ccv_nnc_tensor_symbol_new(symbolic_graph, CPU_TENSOR_NHWC(32F, 2), "y");
31
1
  ccv_nnc_graph_exec_symbol_t case_of = ccv_nnc_symbolic_graph_case_of_new(symbolic_graph, CCV_NNC_GRAPH_FORWARD, TENSOR_SYMBOL_LIST(x), TENSOR_SYMBOL_MAP(KV(x, y)), "case of");
32
1
  ccv_nnc_symbolic_graph_t* const case_0 = ccv_nnc_symbolic_graph_new();
33
1
  ccv_nnc_tensor_symbol_t y0 = ccv_nnc_tensor_symbol_new(case_0, CPU_TENSOR_NHWC(32F, 2), "y0");
34
1
  ccv_nnc_symbolic_graph_set_case_of(symbolic_graph, case_of, case_0, 0, TENSOR_SYMBOL_MAP(KV(y0, y)));
35
1
  ccv_nnc_symbolic_graph_set_case_of_expr(symbolic_graph, case_of, _case_of, 0);
36
1
  ccv_nnc_tensor_symbol_t w01 = ccv_nnc_tensor_symbol_new(case_0, CPU_TENSOR_NHWC(32F, 1, 2), "w01");
37
1
  ccv_nnc_tensor_symbol_t b01 = ccv_nnc_tensor_symbol_new(case_0, CPU_TENSOR_NHWC(32F, 1), "b01");
38
1
  ccv_nnc_tensor_symbol_t z01 = ccv_nnc_tensor_symbol_new(case_0, CPU_TENSOR_NHWC(32F, 1), "z01");
39
1
  ccv_nnc_graph_exec_symbol_new(case_0, CMD_GEMM_FORWARD(NO_TRANSPOSE, TRANSPOSE(0, 1)), TENSOR_SYMBOL_LIST(x, w01, b01), TENSOR_SYMBOL_LIST(z01), "mul01");
40
1
  ccv_nnc_tensor_symbol_t w02 = ccv_nnc_tensor_symbol_new(case_0, CPU_TENSOR_NHWC(32F, 3, 1), "w02");
41
1
  ccv_nnc_tensor_symbol_t b02 = ccv_nnc_tensor_symbol_new(case_0, CPU_TENSOR_NHWC(32F, 3), "b02");
42
1
  ccv_nnc_tensor_symbol_t z02 = ccv_nnc_tensor_symbol_new(case_0, CPU_TENSOR_NHWC(32F, 3), "z02");
43
1
  ccv_nnc_graph_exec_symbol_new(case_0, CMD_GEMM_FORWARD(NO_TRANSPOSE, TRANSPOSE(0, 1)), TENSOR_SYMBOL_LIST(z01, w02, b02), TENSOR_SYMBOL_LIST(z02), "mul02");
44
1
  ccv_nnc_tensor_symbol_t w03 = ccv_nnc_tensor_symbol_new(case_0, CPU_TENSOR_NHWC(32F, 2, 3), "w03");
45
1
  ccv_nnc_tensor_symbol_t b03 = ccv_nnc_tensor_symbol_new(case_0, CPU_TENSOR_NHWC(32F, 2), "b03");
46
1
  ccv_nnc_tensor_symbol_t y01 = ccv_nnc_tensor_symbol_new(case_0, CPU_TENSOR_NHWC(32F, 2), "y01");
47
1
  ccv_nnc_graph_exec_symbol_new(case_0, CMD_GEMM_FORWARD(NO_TRANSPOSE, TRANSPOSE(0, 1)), TENSOR_SYMBOL_LIST(z02, w03, b03), TENSOR_SYMBOL_LIST(y01), "mul03");
48
1
  ccv_nnc_tensor_symbol_t w04 = ccv_nnc_tensor_symbol_new(case_0, CPU_TENSOR_NHWC(32F, 1, 2), "w04");
49
1
  ccv_nnc_tensor_symbol_t b04 = ccv_nnc_tensor_symbol_new(case_0, CPU_TENSOR_NHWC(32F, 1), "b04");
50
1
  ccv_nnc_tensor_symbol_t z04 = ccv_nnc_tensor_symbol_new(case_0, CPU_TENSOR_NHWC(32F, 1), "z04");
51
1
  ccv_nnc_graph_exec_symbol_new(case_0, CMD_GEMM_FORWARD(NO_TRANSPOSE, TRANSPOSE(0, 1)), TENSOR_SYMBOL_LIST(x, w04, b04), TENSOR_SYMBOL_LIST(z04), "mul04");
52
1
  ccv_nnc_tensor_symbol_t w05 = ccv_nnc_tensor_symbol_new(case_0, CPU_TENSOR_NHWC(32F, 2, 1), "w05");
53
1
  ccv_nnc_tensor_symbol_t b05 = ccv_nnc_tensor_symbol_new(case_0, CPU_TENSOR_NHWC(32F, 2), "b05");
54
1
  ccv_nnc_tensor_symbol_t y02 = ccv_nnc_tensor_symbol_new(case_0, CPU_TENSOR_NHWC(32F, 2), "y02");
55
1
  ccv_nnc_graph_exec_symbol_new(case_0, CMD_GEMM_FORWARD(NO_TRANSPOSE, TRANSPOSE(0, 1)), TENSOR_SYMBOL_LIST(z04, w05, b05), TENSOR_SYMBOL_LIST(y02), "mul05");
56
1
  ccv_nnc_graph_exec_symbol_new(case_0, CMD_EWSUM_FORWARD(), TENSOR_SYMBOL_LIST(y01, y02), TENSOR_SYMBOL_LIST(y0), "sum");
57
1
  ccv_nnc_graph_exec_symbol_autogen(case_0, 0, 0, CCV_NNC_AUTOGEN_ALL_EXECS | CCV_NNC_AUTOGEN_SOURCES_AND_DESTINATIONS);
58
1
  ccv_nnc_symbolic_graph_t* const case_2 = ccv_nnc_symbolic_graph_new();
59
1
  ccv_nnc_tensor_symbol_t y2 = ccv_nnc_tensor_symbol_new(case_2, CPU_TENSOR_NHWC(32F, 2), "y2");
60
1
  ccv_nnc_symbolic_graph_set_case_of(symbolic_graph, case_of, case_2, 1, TENSOR_SYMBOL_MAP(KV(y2, y)));
61
1
  ccv_nnc_tensor_symbol_t w21 = ccv_nnc_tensor_symbol_new(case_2, CPU_TENSOR_NHWC(32F, 8, 2), "w21");
62
1
  ccv_nnc_tensor_symbol_t b21 = ccv_nnc_tensor_symbol_new(case_2, CPU_TENSOR_NHWC(32F, 8), "b21");
63
1
  ccv_nnc_tensor_symbol_t z2 = ccv_nnc_tensor_symbol_new(case_2, CPU_TENSOR_NHWC(32F, 8), "z2");
64
1
  ccv_nnc_graph_exec_symbol_new(case_2, CMD_GEMM_FORWARD(NO_TRANSPOSE, TRANSPOSE(0, 1)), TENSOR_SYMBOL_LIST(x, w21, b21), TENSOR_SYMBOL_LIST(z2), "mul21");
65
1
  ccv_nnc_tensor_symbol_t w22 = ccv_nnc_tensor_symbol_new(case_2, CPU_TENSOR_NHWC(32F, 2, 8), "w22");
66
1
  ccv_nnc_tensor_symbol_t b22 = ccv_nnc_tensor_symbol_new(case_2, CPU_TENSOR_NHWC(32F, 2), "b22");
67
1
  ccv_nnc_graph_exec_symbol_new(case_2, CMD_GEMM_FORWARD(NO_TRANSPOSE, TRANSPOSE(0, 1)), TENSOR_SYMBOL_LIST(z2, w22, b22), TENSOR_SYMBOL_LIST(y2), "mul22");
68
1
  ccv_nnc_graph_exec_symbol_autogen(case_2, 0, 0, CCV_NNC_AUTOGEN_ALL_EXECS | CCV_NNC_AUTOGEN_SOURCES_AND_DESTINATIONS);
69
1
  ccv_nnc_symbolic_graph_t* const case_1 = ccv_nnc_symbolic_graph_new();
70
1
  ccv_nnc_tensor_symbol_t y1 = ccv_nnc_tensor_symbol_new(case_1, CPU_TENSOR_NHWC(32F, 2), "y0");
71
1
  ccv_nnc_symbolic_graph_set_case_of(symbolic_graph, case_of, case_1, 2, TENSOR_SYMBOL_MAP(KV(y1, y)));
72
1
  ccv_nnc_tensor_symbol_t w11 = ccv_nnc_tensor_symbol_new(case_1, CPU_TENSOR_NHWC(32F, 16, 2), "w11");
73
1
  ccv_nnc_tensor_symbol_t b11 = ccv_nnc_tensor_symbol_new(case_1, CPU_TENSOR_NHWC(32F, 16), "b11");
74
1
  ccv_nnc_tensor_symbol_t z1 = ccv_nnc_tensor_symbol_new(case_1, CPU_TENSOR_NHWC(32F, 16), "z1");
75
1
  ccv_nnc_graph_exec_symbol_new(case_1, CMD_GEMM_FORWARD(NO_TRANSPOSE, TRANSPOSE(0, 1)), TENSOR_SYMBOL_LIST(x, w11, b11), TENSOR_SYMBOL_LIST(z1), "mul11");
76
1
  ccv_nnc_tensor_symbol_t w12 = ccv_nnc_tensor_symbol_new(case_1, CPU_TENSOR_NHWC(32F, 2, 16), "w12");
77
1
  ccv_nnc_tensor_symbol_t b12 = ccv_nnc_tensor_symbol_new(case_1, CPU_TENSOR_NHWC(32F, 2), "b12");
78
1
  ccv_nnc_graph_exec_symbol_new(case_1, CMD_GEMM_FORWARD(NO_TRANSPOSE, TRANSPOSE(0, 1)), TENSOR_SYMBOL_LIST(z1, w12, b12), TENSOR_SYMBOL_LIST(y1), "mul12");
79
1
  ccv_nnc_graph_exec_symbol_autogen(case_1, 0, 0, CCV_NNC_AUTOGEN_ALL_EXECS | CCV_NNC_AUTOGEN_SOURCES_AND_DESTINATIONS);
80
1
  ccv_nnc_graph_exec_symbol_autogen(symbolic_graph, 0, 0, CCV_NNC_AUTOGEN_ALL_EXECS | CCV_NNC_AUTOGEN_SOURCES_AND_DESTINATIONS);
81
1
  SYMBOLIC_GRAPH_GEN(symbolic_graph, CCV_NNC_LONG_DOT_GRAPH);
82
1
  ccv_nnc_graph_t* graph;
83
1
  ccv_nnc_tensor_arena_t* tensor_arena;
84
1
  ccv_nnc_graph_exec_arena_t* graph_exec_arena;
85
1
  ccv_nnc_symbolic_graph_compile(symbolic_graph, ccv_nnc_default_compile_params, 0, 0, 0, 0, SYMBOLIC_GRAPH_SOURCES(symbolic_graph), SYMBOLIC_GRAPH_DESTINATIONS(symbolic_graph), &graph, &tensor_arena, &graph_exec_arena);
86
1
  GRAPH_GEN(graph, CCV_NNC_LONG_DOT_GRAPH);
87
88
1
  ccv_nnc_tensor_t* const x_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, x);
89
1
  x_tensor->data.f32[0] = -1;
90
1
  x_tensor->data.f32[1] = 10;
91
1
  ccv_nnc_tensor_t* const yt = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 2), 0);
92
1
  yt->data.f32[0] = -1;
93
1
  yt->data.f32[1] = 10;
94
1
  ccv_nnc_graph_run(graph, 0, TRAVERSE_FULL, 0, 0);
95
1
  ccv_nnc_tensor_t* y_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, y);
96
1
  REQUIRE_TENSOR_EQ(y_tensor, yt, "skip any computation");
97
98
1
  dsfmt_t dsfmt;
99
1
  dsfmt_init_gen_rand(&dsfmt, 0);
100
1
  int i;
101
102
1
  x_tensor->data.f32[0] = 0.5;
103
1
  x_tensor->data.f32[1] = 1;
104
1
  ccv_nnc_tensor_t* w01_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, w01);
105
1
  w01_tensor->data.f32[0] = 0.1;
106
1
  w01_tensor->data.f32[1] = -0.28;
107
1
  ccv_nnc_tensor_t* b01_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, b01);
108
1
  b01_tensor->data.f32[0] = 1;
109
1
  ccv_nnc_tensor_t* w02_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, w02);
110
1
  float w02t[3];
111
4
  for (i = 0; i < 3; 
i++3
)
112
3
    w02t[i] = w02_tensor->data.f32[i] = dsfmt_genrand_open_close(&dsfmt);
113
1
  ccv_nnc_tensor_t* b02_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, b02);
114
1
  float b02t[3];
115
4
  for (i = 0; i < 3; 
i++3
)
116
3
    b02t[i] = b02_tensor->data.f32[i] = dsfmt_genrand_open_close(&dsfmt);
117
1
  ccv_nnc_tensor_t* w03_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, w03);
118
1
  float w03t[6];
119
7
  for (i = 0; i < 6; 
i++6
)
120
6
    w03t[i] = w03_tensor->data.f32[i] = dsfmt_genrand_open_close(&dsfmt);
121
1
  ccv_nnc_tensor_t* b03_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, b03);
122
1
  float b03t[2];
123
3
  for (i = 0; i < 2; 
i++2
)
124
2
    b03t[i] = b03_tensor->data.f32[i] = dsfmt_genrand_open_close(&dsfmt);
125
1
  ccv_nnc_tensor_t* w04_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, w04);
126
1
  w04_tensor->data.f32[0] = -1.11;
127
1
  w04_tensor->data.f32[1] = 15;
128
1
  ccv_nnc_tensor_t* b04_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, b04);
129
1
  b04_tensor->data.f32[0] = 0.2;
130
1
  ccv_nnc_tensor_t* w05_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, w05);
131
1
  w05_tensor->data.f32[0] = 3.1;
132
1
  w05_tensor->data.f32[1] = 3.3;
133
1
  ccv_nnc_tensor_t* b05_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, b05);
134
1
  b05_tensor->data.f32[0] = -0.2;
135
1
  b05_tensor->data.f32[1] = -0.3;
136
1
  ccv_nnc_graph_run(graph, 0, TRAVERSE_FULL, 0, 0);
137
1
  y_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, y);
138
1
  const float z01val = 0.5 * 0.1 - 0.28 + 1;
139
1
  yt->data.f32[0] = b03t[0];
140
1
  yt->data.f32[1] = b03t[1];
141
4
  for (i = 0; i < 3; 
i++3
)
142
3
  {
143
3
    const float z02val = z01val * w02t[i] + b02t[i];
144
3
    yt->data.f32[0] += z02val * w03t[i];
145
3
    yt->data.f32[1] += z02val * w03t[i + 3];
146
3
  }
147
1
  const float z04val = 0.5 * -1.11 + 15 + 0.2;
148
1
  yt->data.f32[0] += z04val * 3.1 - 0.2;
149
1
  yt->data.f32[1] += z04val * 3.3 - 0.3;
150
1
  REQUIRE_TENSOR_EQ(y_tensor, yt, "((x * w01 + b01) * w02 + b02) * w03 + b03");
151
152
1
  x_tensor->data.f32[0] = 1.11;
153
1
  x_tensor->data.f32[1] = 2.56;
154
1
  ccv_nnc_tensor_t* w11_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, w11);
155
1
  float w11t[32];
156
33
  for (i = 0; i < 32; 
i++32
)
157
32
    w11t[i] = w11_tensor->data.f32[i] = dsfmt_genrand_open_close(&dsfmt);
158
1
  ccv_nnc_tensor_t* b11_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, b11);
159
1
  float b11t[16];
160
17
  for (i = 0; i < 16; 
i++16
)
161
16
    b11t[i] = b11_tensor->data.f32[i] = dsfmt_genrand_open_close(&dsfmt);
162
1
  ccv_nnc_tensor_t* w12_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, w12);
163
1
  float w12t[32];
164
33
  for (i = 0; i < 32; 
i++32
)
165
32
    w12t[i] = w12_tensor->data.f32[i] = dsfmt_genrand_open_close(&dsfmt);
166
1
  ccv_nnc_tensor_t* b12_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, b12);
167
1
  b12_tensor->data.f32[0] = 0.32;
168
1
  b12_tensor->data.f32[1] = -0.2;
169
1
  ccv_nnc_graph_autotune(graph, 0, 0, TRAVERSE_FULL);
170
1
  ccv_nnc_graph_run(graph, 0, TRAVERSE_FULL, 0, 0);
171
1
  yt->data.f32[0] = 0.32;
172
1
  yt->data.f32[1] = -0.2;
173
17
  for (i = 0; i < 16; 
i++16
)
174
16
  {
175
16
    float z1val = 1.11 * w11t[i * 2] + 2.56 * w11t[i * 2 + 1] + b11t[i];
176
16
    yt->data.f32[0] += z1val * w12t[i];
177
16
    yt->data.f32[1] += z1val * w12t[i + 16];
178
16
  }
179
1
  y_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, y);
180
1
  REQUIRE_TENSOR_EQ(y_tensor, yt, "(x * w11 + b11) * w12 + b12");
181
182
1
  x_tensor->data.f32[0] = 4.5;
183
1
  x_tensor->data.f32[1] = 3.33;
184
1
  ccv_nnc_tensor_t* w21_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, w21);
185
17
  for (i = 0; i < 16; 
i++16
)
186
16
    w11t[i] = w21_tensor->data.f32[i] = dsfmt_genrand_open_close(&dsfmt);
187
1
  ccv_nnc_tensor_t* b21_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, b21);
188
9
  for (i = 0; i < 8; 
i++8
)
189
8
    b11t[i] = b21_tensor->data.f32[i] = dsfmt_genrand_open_close(&dsfmt);
190
1
  ccv_nnc_tensor_t* w22_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, w22);
191
17
  for (i = 0; i < 16; 
i++16
)
192
16
    w12t[i] = w22_tensor->data.f32[i] = dsfmt_genrand_open_close(&dsfmt);
193
1
  ccv_nnc_tensor_t* b22_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, b22);
194
1
  b22_tensor->data.f32[0] = 3.32;
195
1
  b22_tensor->data.f32[1] = -2;
196
1
  ccv_nnc_graph_run(graph, 0, TRAVERSE_FULL, 0, 0);
197
1
  yt->data.f32[0] = 3.32;
198
1
  yt->data.f32[1] = -2;
199
1
  assert(w11_tensor->data.f32 != w21_tensor->data.f32);
200
9
  
for (i = 0; 1
i < 8;
i++8
)
201
8
  {
202
8
    float z2val = 4.5 * w11t[i * 2] + 3.33 * w11t[i * 2 + 1] + b11t[i];
203
8
    yt->data.f32[0] += z2val * w12t[i];
204
8
    yt->data.f32[1] += z2val * w12t[i + 8];
205
8
  }
206
1
  y_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, y);
207
1
  REQUIRE_TENSOR_EQ(y_tensor, yt, "(x * w21 + b21) * w22 + b22");
208
209
1
  ccv_nnc_tensor_free(yt);
210
1
  ccv_nnc_symbolic_graph_free(symbolic_graph);
211
1
  ccv_nnc_graph_free(graph);
212
1
  ccv_nnc_tensor_arena_free(tensor_arena);
213
1
  ccv_nnc_graph_exec_arena_free(graph_exec_arena);
214
1
}
215
216
#include "case_main.h"