/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" |