/home/liu/actions-runner/_work/ccv/ccv/test/unit/nnc/while.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 while_5(ccv_nnc_tensor_t* const* const inputs, const int input_size, const void* const data) |
15 | 96 | { |
16 | 96 | int i; |
17 | 234 | for (i = 0; i < input_size; i++138 ) |
18 | 138 | { assert(!CCV_IS_TENSOR_MULTIVIEW(inputs[i])); } |
19 | 96 | return inputs[0]->data.i64[0] < 5; |
20 | 96 | } |
21 | | |
22 | | TEST_CASE("graph for a while loop to compute 0.34 * 1.11 ^ 5") |
23 | 1 | { |
24 | 1 | ccv_nnc_graph_t* graph = ccv_nnc_graph_new(); |
25 | 1 | ccv_nnc_tensor_t* x = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 1), 0); |
26 | 1 | ccv_nnc_tensor_t* y = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 1), 0); |
27 | 1 | ccv_nnc_tensor_t* z = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 1), 0); |
28 | 1 | ccv_nnc_graph_t* while_graph = ccv_nnc_graph_new(); |
29 | 1 | ccv_nnc_graph_exec_t noop = ccv_nnc_graph_exec_new(while_graph, CMD_NOOP(), ccv_nnc_no_hint, 0, 0, 0, 0); |
30 | 1 | ccv_nnc_graph_exec_t prod0 = ccv_nnc_graph_exec_new(while_graph, CMD_EWPROD_FORWARD(), ccv_nnc_no_hint, TENSOR_LIST(y, z), TENSOR_LIST(z)); |
31 | 1 | ccv_nnc_graph_exec_concat(while_graph, noop, prod0); |
32 | 1 | ccv_nnc_graph_exec_t loop = ccv_nnc_graph_while(graph, CCV_NNC_GRAPH_FORWARD, while_graph); |
33 | 1 | ccv_nnc_graph_set_sources(while_graph, GRAPH_EXEC_LIST(noop)); |
34 | 1 | ccv_nnc_graph_set_destinations(while_graph, GRAPH_EXEC_LIST(prod0)); |
35 | 1 | ccv_nnc_tensor_t count_tensor = ccv_nnc_tensor_for_while_count(while_graph); |
36 | 1 | ccv_nnc_graph_set_while_expr(while_graph, while_5, 0, TENSOR_LIST(&count_tensor), GRAPH_EXEC_LIST(noop)); |
37 | 1 | ccv_nnc_graph_exec_t prod1 = ccv_nnc_graph_exec_new(graph, CMD_EWPROD_FORWARD(), ccv_nnc_no_hint, TENSOR_LIST(x, z), TENSOR_LIST(z)); |
38 | 1 | ccv_nnc_graph_exec_concat(graph, loop, prod1); |
39 | 1 | GRAPH_GEN(graph, CCV_NNC_LONG_DOT_GRAPH); |
40 | 1 | x->data.f32[0] = 0.34; |
41 | 1 | y->data.f32[0] = 1.11; |
42 | 1 | z->data.f32[0] = 1; |
43 | 1 | ccv_nnc_graph_autotune(graph, 0, 0, TRAVERSE_FULL); |
44 | 1 | ccv_nnc_graph_run(graph, 0, GRAPH_EXEC_LIST(loop), GRAPH_EXEC_LIST(prod1), 0, 0); |
45 | 1 | ccv_nnc_graph_free(graph); |
46 | 1 | REQUIRE_EQ_WITH_TOLERANCE(z->data.f32[0], 0.34 * 1.11 * 1.11 * 1.11 * 1.11 * 1.11, 1e-6, "computed result of 0.34 * 1.11 ^ 5 should be the same"); |
47 | 1 | ccv_nnc_tensor_free(x); |
48 | 1 | ccv_nnc_tensor_free(y); |
49 | 1 | ccv_nnc_tensor_free(z); |
50 | 1 | } |
51 | | |
52 | | TEST_CASE("graph for a while loop by reuse tensor allocations for 0.32 * 2.8 ^ 5") |
53 | 1 | { |
54 | 1 | ccv_nnc_graph_t* graph = ccv_nnc_graph_new(); |
55 | 1 | ccv_nnc_graph_t* while_graph = ccv_nnc_graph_new(); |
56 | 1 | ccv_nnc_graph_exec_t loop = ccv_nnc_graph_while(graph, CCV_NNC_GRAPH_FORWARD, while_graph); |
57 | 1 | ccv_nnc_graph_exec_t noop = ccv_nnc_graph_exec_new(while_graph, CMD_NOOP(), ccv_nnc_no_hint, 0, 0, 0, 0); |
58 | 1 | ccv_nnc_tensor_t* x = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 1), 0); |
59 | 1 | ccv_nnc_tensor_t* y = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 1), 0); |
60 | 1 | ccv_nnc_tensor_t* z = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 1), 0); |
61 | 1 | ccv_nnc_tensor_multiview_t xx; |
62 | 1 | ccv_nnc_tensor_multiview((ccv_nnc_tensor_t*[]){ |
63 | 1 | x, z |
64 | 1 | }, CCV_NNC_MULTIVIEW_K0N, 2, while_graph, &xx); |
65 | 1 | ccv_nnc_tensor_multiview_t zz; |
66 | 1 | ccv_nnc_tensor_multiview((ccv_nnc_tensor_t*[]){ |
67 | 1 | z, x |
68 | 1 | }, CCV_NNC_MULTIVIEW_K0N, 2, while_graph, &zz); |
69 | 1 | ccv_nnc_tensor_t zbb = ccv_nnc_tensor(0, CPU_TENSOR_NHWC(32F, 1), 0); |
70 | 1 | ccv_nnc_tensor_synchronize_to_multiview(&zz, &zbb); |
71 | 1 | ccv_nnc_graph_exec_t prod = ccv_nnc_graph_exec_new(while_graph, CMD_EWPROD_FORWARD(), ccv_nnc_no_hint, TENSOR_LIST((ccv_nnc_tensor_t*)&xx, y), TENSOR_LIST((ccv_nnc_tensor_t*)&zz)); |
72 | 1 | ccv_nnc_graph_set_sources(while_graph, GRAPH_EXEC_LIST(noop)); |
73 | 1 | ccv_nnc_graph_set_destinations(while_graph, GRAPH_EXEC_LIST(prod)); |
74 | 1 | ccv_nnc_tensor_t count_tensor = ccv_nnc_tensor_for_while_count(while_graph); |
75 | 1 | ccv_nnc_graph_set_while_expr(while_graph, while_5, 0, TENSOR_LIST(&count_tensor), GRAPH_EXEC_LIST(noop)); |
76 | 1 | ccv_nnc_graph_exec_concat(while_graph, noop, prod); |
77 | 1 | GRAPH_GEN(graph, CCV_NNC_LONG_DOT_GRAPH); |
78 | 1 | x->data.f32[0] = 0.32; |
79 | 1 | y->data.f32[0] = 2.8; |
80 | 1 | ccv_nnc_graph_autotune(graph, 0, 0, TRAVERSE_FULL); |
81 | 1 | ccv_nnc_graph_run(graph, 0, GRAPH_EXEC_LIST(loop), GRAPH_EXEC_LIST(loop), 0, 0); |
82 | 1 | REQUIRE_EQ_WITH_TOLERANCE(z->data.f32[0], 0.32 * 2.8 * 2.8 * 2.8 * 2.8 * 2.8, 1e-5, "computed result of 0.32 * 2.8 ^ 5 should be the same"); |
83 | 1 | REQUIRE(z->data.f32 == zbb.data.f32, "Two pointers should be the same"); |
84 | 1 | ccv_nnc_tensor_multiview_free(xx); |
85 | 1 | ccv_nnc_tensor_multiview_free(zz); |
86 | 1 | ccv_nnc_graph_free(graph); |
87 | 1 | ccv_nnc_tensor_free(x); |
88 | 1 | ccv_nnc_tensor_free(y); |
89 | 1 | ccv_nnc_tensor_free(z); |
90 | 1 | } |
91 | | |
92 | | TEST_CASE("while graph add and re-add reuse tensor allocations for 0.47 * 5.5 ^ 5") |
93 | 1 | { |
94 | 1 | ccv_nnc_graph_t* graph = ccv_nnc_graph_new(); |
95 | 1 | ccv_nnc_graph_t* while_graph = ccv_nnc_graph_new(); |
96 | 1 | ccv_nnc_graph_exec_t loop = ccv_nnc_graph_while(graph, CCV_NNC_GRAPH_FORWARD, while_graph); |
97 | 1 | ccv_nnc_graph_exec_t noop = ccv_nnc_graph_exec_new(while_graph, CMD_NOOP(), ccv_nnc_no_hint, 0, 0, 0, 0); |
98 | 1 | ccv_nnc_tensor_t* x = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 1), 0); |
99 | 1 | ccv_nnc_tensor_t* y = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 1), 0); |
100 | 1 | ccv_nnc_tensor_t* z = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 1), 0); |
101 | 1 | ccv_nnc_tensor_multiview_t xx; |
102 | 1 | ccv_nnc_tensor_multiview((ccv_nnc_tensor_t*[]){ |
103 | 1 | x, z |
104 | 1 | }, CCV_NNC_MULTIVIEW_K0N, 2, while_graph, &xx); |
105 | 1 | ccv_nnc_tensor_multiview_t zz; |
106 | 1 | ccv_nnc_tensor_multiview((ccv_nnc_tensor_t*[]){ |
107 | 1 | z, x |
108 | 1 | }, CCV_NNC_MULTIVIEW_K0N, 2, while_graph, &zz); |
109 | 1 | ccv_nnc_graph_exec_t prod = ccv_nnc_graph_exec_new(while_graph, CMD_EWPROD_FORWARD(), ccv_nnc_no_hint, TENSOR_LIST((ccv_nnc_tensor_t*)&xx, y), TENSOR_LIST((ccv_nnc_tensor_t*)&zz)); |
110 | 1 | ccv_nnc_graph_set_sources(while_graph, GRAPH_EXEC_LIST(noop)); |
111 | 1 | ccv_nnc_graph_set_destinations(while_graph, GRAPH_EXEC_LIST(prod)); |
112 | 1 | ccv_nnc_tensor_t count_tensor = ccv_nnc_tensor_for_while_count(while_graph); |
113 | 1 | ccv_nnc_graph_set_while_expr(while_graph, while_5, 0, TENSOR_LIST(&count_tensor), GRAPH_EXEC_LIST(noop)); |
114 | 1 | ccv_nnc_graph_exec_concat(while_graph, noop, prod); |
115 | 1 | ccv_nnc_graph_exec_set_io(while_graph, prod, TENSOR_LIST(x, y), TENSOR_LIST(z)); |
116 | 1 | ccv_nnc_graph_exec_set_io(while_graph, prod, TENSOR_LIST((ccv_nnc_tensor_t*)&zz, y), TENSOR_LIST((ccv_nnc_tensor_t*)&xx)); |
117 | 1 | GRAPH_GEN(graph, CCV_NNC_LONG_DOT_GRAPH); |
118 | 1 | x->data.f32[0] = 0.32; |
119 | 1 | z->data.f32[0] = 0.47; |
120 | 1 | y->data.f32[0] = 5.5; |
121 | 1 | ccv_nnc_graph_autotune(graph, 0, 0, TRAVERSE_FULL); |
122 | 1 | ccv_nnc_graph_run(graph, 0, GRAPH_EXEC_LIST(loop), GRAPH_EXEC_LIST(loop), 0, 0); |
123 | 1 | REQUIRE_EQ_WITH_TOLERANCE(x->data.f32[0], 0.47 * 5.5 * 5.5 * 5.5 * 5.5 * 5.5, 1e-2, "computed result of 0.47 * 5.5 ^ 5 should be the same"); |
124 | 1 | ccv_nnc_graph_free(graph); |
125 | 1 | ccv_nnc_tensor_free(x); |
126 | 1 | ccv_nnc_tensor_free(y); |
127 | 1 | ccv_nnc_tensor_free(z); |
128 | 1 | } |
129 | | |
130 | | TEST_CASE("symbolic graph get while graph from symbol") |
131 | 1 | { |
132 | 1 | ccv_nnc_symbolic_graph_t* const symbolic_graph = ccv_nnc_symbolic_graph_new(); |
133 | 1 | ccv_nnc_symbolic_graph_t* const while_graph_0 = ccv_nnc_symbolic_graph_new(); |
134 | 1 | ccv_nnc_graph_exec_symbol_t while_0 = ccv_nnc_symbolic_graph_while(symbolic_graph, CCV_NNC_GRAPH_FORWARD, while_graph_0, "while 0"); |
135 | 1 | ccv_nnc_symbolic_graph_t* const while_graph_1 = ccv_nnc_symbolic_graph_new(); |
136 | 1 | ccv_nnc_graph_exec_symbol_t while_1 = ccv_nnc_symbolic_graph_while(symbolic_graph, CCV_NNC_GRAPH_FORWARD, while_graph_1, "while 1"); |
137 | 1 | REQUIRE(while_graph_0 == ccv_nnc_symbolic_graph_from_while_symbol(symbolic_graph, while_0), "graph extracted from symbol should be equal"); |
138 | 1 | REQUIRE(while_graph_1 == ccv_nnc_symbolic_graph_from_while_symbol(symbolic_graph, while_1), "graph extracted from symbol should be equal"); |
139 | 1 | ccv_nnc_symbolic_graph_free(symbolic_graph); |
140 | 1 | } |
141 | | |
142 | | TEST_CASE("symbolic graph for a while loop to compute x ^ 5 * y") |
143 | 1 | { |
144 | 1 | ccv_nnc_symbolic_graph_t* symbolic_graph = ccv_nnc_symbolic_graph_new(); |
145 | 1 | ccv_nnc_tensor_symbol_t x = ccv_nnc_tensor_symbol_new(symbolic_graph, CPU_TENSOR_NHWC(32F, 1), "x"); |
146 | 1 | ccv_nnc_tensor_symbol_t y = ccv_nnc_tensor_symbol_new(symbolic_graph, CPU_TENSOR_NHWC(32F, 1), "y"); |
147 | 1 | ccv_nnc_symbolic_graph_t* while_graph = ccv_nnc_symbolic_graph_new(); |
148 | 1 | ccv_nnc_symbolic_graph_while(symbolic_graph, CCV_NNC_GRAPH_FORWARD, while_graph, "for 1..5"); |
149 | 1 | ccv_nnc_tensor_symbol_t z0 = ccv_nnc_tensor_symbol_new(while_graph, CPU_TENSOR_NHWC(32F, 1), "z0"); |
150 | 1 | ccv_nnc_tensor_symbol_t z1 = ccv_nnc_tensor_symbol_new(while_graph, CPU_TENSOR_NHWC(32F, 1), "z1"); |
151 | 1 | ccv_nnc_graph_exec_symbol_t noop = ccv_nnc_graph_exec_symbol_new(while_graph, CMD_NOOP(), 0, 0, 0, 0, "noop"); |
152 | 1 | ccv_nnc_graph_exec_symbol_t prod0 = ccv_nnc_graph_exec_symbol_new(while_graph, CMD_EWPROD_FORWARD(), TENSOR_SYMBOL_LIST(z0, x), TENSOR_SYMBOL_LIST(z1), "prod0"); |
153 | 1 | ccv_nnc_graph_exec_symbol_concat(while_graph, noop, prod0); |
154 | 1 | ccv_nnc_tensor_symbol_t z2 = ccv_nnc_tensor_symbol_new(symbolic_graph, CPU_TENSOR_NHWC(32F, 1), "z2"); |
155 | 1 | ccv_nnc_graph_exec_symbol_new(symbolic_graph, CMD_EWPROD_FORWARD(), TENSOR_SYMBOL_LIST(z1, y), TENSOR_SYMBOL_LIST(z2), "prod1"); |
156 | 1 | ccv_nnc_graph_exec_symbol_autogen(symbolic_graph, 0, 0, CCV_NNC_AUTOGEN_ALL_EXECS | CCV_NNC_AUTOGEN_SOURCES_AND_DESTINATIONS); |
157 | | // Test whether we can ignore the noop graph properly in compilation. |
158 | 1 | ccv_nnc_symbolic_graph_t* noop_graph = ccv_nnc_symbolic_graph_new(); |
159 | 1 | ccv_nnc_symbolic_graph_while(symbolic_graph, CCV_NNC_GRAPH_FORWARD, noop_graph, "no op"); |
160 | 1 | ccv_nnc_symbolic_graph_set_while_expr(while_graph, while_5, 0, TENSOR_SYMBOL_LIST(ccv_nnc_tensor_symbol_for_while_count(while_graph)), GRAPH_EXEC_SYMBOL_LIST(noop)); |
161 | 1 | ccv_nnc_symbolic_graph_set_carry_overs(while_graph, TENSOR_SYMBOL_MAP(KV(z1, z0))); |
162 | 1 | ccv_nnc_symbolic_graph_set_sources(while_graph, GRAPH_EXEC_SYMBOL_LIST(noop)); |
163 | 1 | ccv_nnc_symbolic_graph_set_destinations(while_graph, GRAPH_EXEC_SYMBOL_LIST(prod0)); |
164 | 1 | ccv_nnc_graph_t* graph = 0; |
165 | 1 | ccv_nnc_tensor_arena_t* tensor_arena = 0; |
166 | 1 | ccv_nnc_graph_exec_arena_t* graph_exec_arena = 0; |
167 | 1 | ccv_nnc_symbolic_graph_compile(symbolic_graph, ccv_nnc_default_compile_params, 0, 0, 0, 0, ccv_nnc_symbolic_graph_sources(symbolic_graph), ccv_nnc_symbolic_graph_source_size(symbolic_graph), ccv_nnc_symbolic_graph_destinations(symbolic_graph), ccv_nnc_symbolic_graph_destination_size(symbolic_graph), &graph, &tensor_arena, &graph_exec_arena); |
168 | 1 | SYMBOLIC_GRAPH_GEN(symbolic_graph, CCV_NNC_LONG_DOT_GRAPH); |
169 | 1 | GRAPH_GEN(graph, CCV_NNC_LONG_DOT_GRAPH); |
170 | 1 | ccv_nnc_tensor_t* x_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, x); |
171 | 1 | ccv_nnc_tensor_t* y_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, y); |
172 | 1 | ccv_nnc_tensor_t* z0_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, z0); |
173 | 1 | ccv_nnc_tensor_t* z_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, z2); |
174 | 1 | x_tensor->data.f32[0] = 0.92; |
175 | 1 | y_tensor->data.f32[0] = 3.2; |
176 | 1 | z0_tensor->data.f32[0] = 1; |
177 | 1 | ccv_nnc_graph_autotune(graph, 0, 0, TRAVERSE_FULL); |
178 | 1 | ccv_nnc_graph_run(graph, 0, TRAVERSE_FULL, 0, 0); |
179 | 1 | REQUIRE_EQ_WITH_TOLERANCE(z_tensor->data.f32[0], 0.92 * 0.92 * 0.92 * 0.92 * 0.92 * 3.2, 1e-6, "z should be equal to x ^ 5 * y"); |
180 | 1 | ccv_nnc_symbolic_graph_free(symbolic_graph); |
181 | 1 | ccv_nnc_graph_exec_arena_free(graph_exec_arena); |
182 | 1 | ccv_nnc_tensor_arena_free(tensor_arena); |
183 | 1 | ccv_nnc_graph_free(graph); |
184 | 1 | } |
185 | | |
186 | | TEST_CASE("symbolic graph for a while loop to compute z * x ^ 5 * y + z") |
187 | 1 | { |
188 | 1 | ccv_nnc_symbolic_graph_t* symbolic_graph = ccv_nnc_symbolic_graph_new(); |
189 | 1 | ccv_nnc_tensor_symbol_t x = ccv_nnc_tensor_symbol_new(symbolic_graph, CPU_TENSOR_NHWC(32F, 1), "x"); |
190 | 1 | ccv_nnc_tensor_symbol_t y = ccv_nnc_tensor_symbol_new(symbolic_graph, CPU_TENSOR_NHWC(32F, 1), "y"); |
191 | 1 | ccv_nnc_tensor_symbol_t z0 = ccv_nnc_tensor_symbol_new(symbolic_graph, CPU_TENSOR_NHWC(32F, 1), "z0"); |
192 | 1 | ccv_nnc_symbolic_graph_t* while_graph = ccv_nnc_symbolic_graph_new(); |
193 | 1 | ccv_nnc_symbolic_graph_while(symbolic_graph, CCV_NNC_GRAPH_FORWARD, while_graph, "for 1..5"); |
194 | 1 | ccv_nnc_tensor_symbol_t z1 = ccv_nnc_tensor_symbol_new(while_graph, CPU_TENSOR_NHWC(32F, 1), "z1"); |
195 | 1 | ccv_nnc_graph_exec_symbol_t noop = ccv_nnc_graph_exec_symbol_new(while_graph, CMD_NOOP(), 0, 0, 0, 0, "noop"); |
196 | 1 | ccv_nnc_graph_exec_symbol_t prod0 = ccv_nnc_graph_exec_symbol_new(while_graph, CMD_EWPROD_FORWARD(), TENSOR_SYMBOL_LIST(z0, x), TENSOR_SYMBOL_LIST(z1), "prod0"); |
197 | 1 | ccv_nnc_graph_exec_symbol_concat(while_graph, noop, prod0); |
198 | 1 | ccv_nnc_tensor_symbol_t z2 = ccv_nnc_tensor_symbol_new(symbolic_graph, CPU_TENSOR_NHWC(32F, 1), "z2"); |
199 | 1 | ccv_nnc_tensor_symbol_t z3 = ccv_nnc_tensor_symbol_new(symbolic_graph, CPU_TENSOR_NHWC(32F, 1), "z3"); |
200 | 1 | ccv_nnc_graph_exec_symbol_new(symbolic_graph, CMD_EWPROD_FORWARD(), TENSOR_SYMBOL_LIST(z1, y), TENSOR_SYMBOL_LIST(z2), "prod1"); |
201 | 1 | ccv_nnc_graph_exec_symbol_new(symbolic_graph, CMD_EWSUM_FORWARD(), TENSOR_SYMBOL_LIST(z2, z0), TENSOR_SYMBOL_LIST(z3), "sum"); |
202 | 1 | ccv_nnc_graph_exec_symbol_autogen(symbolic_graph, 0, 0, CCV_NNC_AUTOGEN_ALL_EXECS | CCV_NNC_AUTOGEN_SOURCES_AND_DESTINATIONS); |
203 | 1 | ccv_nnc_symbolic_graph_set_while_expr(while_graph, while_5, 0, TENSOR_SYMBOL_LIST(ccv_nnc_tensor_symbol_for_while_count(while_graph), z0), GRAPH_EXEC_SYMBOL_LIST(noop)); |
204 | 1 | ccv_nnc_symbolic_graph_set_carry_overs(while_graph, TENSOR_SYMBOL_MAP(KV(z1, z0))); |
205 | 1 | ccv_nnc_symbolic_graph_set_sources(while_graph, GRAPH_EXEC_SYMBOL_LIST(noop)); |
206 | 1 | ccv_nnc_symbolic_graph_set_destinations(while_graph, GRAPH_EXEC_SYMBOL_LIST(prod0)); |
207 | 1 | ccv_nnc_graph_t* graph = 0; |
208 | 1 | ccv_nnc_tensor_arena_t* tensor_arena = 0; |
209 | 1 | ccv_nnc_graph_exec_arena_t* graph_exec_arena = 0; |
210 | 1 | ccv_nnc_symbolic_graph_compile(symbolic_graph, ccv_nnc_default_compile_params, 0, 0, 0, 0, ccv_nnc_symbolic_graph_sources(symbolic_graph), ccv_nnc_symbolic_graph_source_size(symbolic_graph), ccv_nnc_symbolic_graph_destinations(symbolic_graph), ccv_nnc_symbolic_graph_destination_size(symbolic_graph), &graph, &tensor_arena, &graph_exec_arena); |
211 | 1 | SYMBOLIC_GRAPH_GEN(symbolic_graph, CCV_NNC_LONG_DOT_GRAPH); |
212 | 1 | GRAPH_GEN(graph, CCV_NNC_LONG_DOT_GRAPH); |
213 | 1 | ccv_nnc_tensor_t* x_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, x); |
214 | 1 | ccv_nnc_tensor_t* y_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, y); |
215 | 1 | ccv_nnc_tensor_t* z0_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, z0); |
216 | 1 | x_tensor->data.f32[0] = 0.92; |
217 | 1 | y_tensor->data.f32[0] = 3.2; |
218 | 1 | z0_tensor->data.f32[0] = 1.2; |
219 | 1 | ccv_nnc_graph_autotune(graph, 0, 0, TRAVERSE_FULL); |
220 | 1 | ccv_nnc_graph_run(graph, 0, TRAVERSE_FULL, 0, 0); |
221 | 1 | ccv_nnc_tensor_t* z_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, z3); |
222 | 1 | REQUIRE_EQ_WITH_TOLERANCE(z_tensor->data.f32[0], 1.2 * 0.92 * 0.92 * 0.92 * 0.92 * 0.92 * 3.2 + 1.2, 1e-6, "z should be equal to z * x ^ 5 * y + z"); |
223 | 1 | ccv_nnc_symbolic_graph_free(symbolic_graph); |
224 | 1 | ccv_nnc_graph_exec_arena_free(graph_exec_arena); |
225 | 1 | ccv_nnc_tensor_arena_free(tensor_arena); |
226 | 1 | ccv_nnc_graph_free(graph); |
227 | 1 | } |
228 | | |
229 | | TEST_CASE("symbolic graph for a while loop to compute x = max(conv(x, w, b), 3x3) 5 times") |
230 | 1 | { |
231 | 1 | ccv_nnc_symbolic_graph_t* symbolic_graph = ccv_nnc_symbolic_graph_new(); |
232 | 1 | ccv_nnc_symbolic_graph_t* while_graph = ccv_nnc_symbolic_graph_new(); |
233 | 1 | ccv_nnc_symbolic_graph_while(symbolic_graph, CCV_NNC_GRAPH_FORWARD, while_graph, "while 1..5"); |
234 | 1 | ccv_nnc_tensor_symbol_t x = ccv_nnc_tensor_symbol_new(symbolic_graph, CPU_TENSOR_NHWC(32F, 5, 5, 4), "x"); |
235 | 1 | ccv_nnc_tensor_symbol_t w = ccv_nnc_tensor_symbol_new(while_graph, CPU_TENSOR_NHWC(32F, 4, 3, 3, 4), "w"); |
236 | 1 | ccv_nnc_tensor_symbol_t b = ccv_nnc_tensor_symbol_new(while_graph, CPU_TENSOR_NHWC(32F, 4), "b"); |
237 | 1 | ccv_nnc_tensor_symbol_t y = ccv_nnc_tensor_symbol_new(while_graph, CPU_TENSOR_NHWC(32F, 5, 5, 4), "y"); |
238 | 1 | ccv_nnc_tensor_symbol_t z = ccv_nnc_tensor_symbol_new(while_graph, CPU_TENSOR_NHWC(32F, 5, 5, 4), "z"); |
239 | 1 | ccv_nnc_graph_exec_symbol_t noop = ccv_nnc_graph_exec_symbol_new(while_graph, CMD_NOOP(), 0, 0, 0, 0, "noop"); |
240 | 1 | ccv_nnc_graph_exec_symbol_t conv = ccv_nnc_graph_exec_symbol_new(while_graph, CMD_CONVOLUTION_FORWARD(1, 4, 3, 3, 4), TENSOR_SYMBOL_LIST(x, w, b), TENSOR_SYMBOL_LIST(y), "conv"); |
241 | 1 | ccv_nnc_graph_exec_symbol_t avg = ccv_nnc_graph_exec_symbol_new(while_graph, CMD_AVERAGE_POOL_FORWARD(3, 3), TENSOR_SYMBOL_LIST(y), TENSOR_SYMBOL_LIST(z), "avg"); |
242 | 1 | ccv_nnc_graph_exec_symbol_concat(while_graph, noop, conv); |
243 | 1 | ccv_nnc_symbolic_graph_set_while_expr(while_graph, while_5, 0, TENSOR_SYMBOL_LIST(ccv_nnc_tensor_symbol_for_while_count(while_graph), w), GRAPH_EXEC_SYMBOL_LIST(noop)); |
244 | 1 | ccv_nnc_symbolic_graph_set_carry_overs(while_graph, TENSOR_SYMBOL_MAP(KV(z, x))); |
245 | 1 | ccv_nnc_symbolic_graph_set_sources(while_graph, GRAPH_EXEC_SYMBOL_LIST(noop)); |
246 | 1 | ccv_nnc_symbolic_graph_set_destinations(while_graph, GRAPH_EXEC_SYMBOL_LIST(avg)); |
247 | 1 | ccv_nnc_graph_t* graph = 0; |
248 | 1 | ccv_nnc_tensor_arena_t* tensor_arena = 0; |
249 | 1 | ccv_nnc_graph_exec_arena_t* graph_exec_arena = 0; |
250 | 1 | ccv_nnc_graph_exec_symbol_autogen(symbolic_graph, 0, 0, CCV_NNC_AUTOGEN_ALL_EXECS | CCV_NNC_AUTOGEN_SOURCES_AND_DESTINATIONS); |
251 | 1 | ccv_nnc_symbolic_graph_compile(symbolic_graph, ccv_nnc_default_compile_params, 0, 0, 0, 0, ccv_nnc_symbolic_graph_sources(symbolic_graph), ccv_nnc_symbolic_graph_source_size(symbolic_graph), ccv_nnc_symbolic_graph_destinations(symbolic_graph), ccv_nnc_symbolic_graph_destination_size(symbolic_graph), &graph, &tensor_arena, &graph_exec_arena); |
252 | 1 | SYMBOLIC_GRAPH_GEN(symbolic_graph, CCV_NNC_LONG_DOT_GRAPH); |
253 | 1 | GRAPH_GEN(graph, CCV_NNC_LONG_DOT_GRAPH); |
254 | 1 | ccv_nnc_tensor_t* x_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, x); |
255 | 1 | ccv_nnc_tensor_t* w_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, w); |
256 | 1 | ccv_nnc_tensor_t* b_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, b); |
257 | 1 | int i; |
258 | 1 | dsfmt_t dsfmt; |
259 | 1 | dsfmt_init_gen_rand(&dsfmt, 0); |
260 | 101 | for (i = 0; i < 5 * 5 * 4; i++100 ) |
261 | 100 | x_tensor->data.f32[i] = dsfmt_genrand_open_close(&dsfmt); |
262 | 145 | for (i = 0; i < 4 * 3 * 3 * 4; i++144 ) |
263 | 144 | w_tensor->data.f32[i] = dsfmt_genrand_open_close(&dsfmt) / (4 * 3 * 3); |
264 | 5 | for (i = 0; i < 4; i++4 ) |
265 | 4 | b_tensor->data.f32[i] = 3.2; |
266 | 1 | ccv_nnc_tensor_t* x1 = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 5, 5, 4), 0); |
267 | 1 | memcpy(x1->data.f32, x_tensor->data.f32, sizeof(float) * 5 * 5 * 4); |
268 | 1 | ccv_nnc_tensor_t* y1 = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 5, 5, 4), 0); |
269 | 6 | for (i = 0; i < 5; i++5 ) |
270 | 5 | { |
271 | 5 | ccv_nnc_cmd_exec(CMD_CONVOLUTION_FORWARD(1, 4, 3, 3, 4), HINT((1, 1), (1, 1)), 0, TENSOR_LIST(x1, w_tensor, b_tensor), TENSOR_LIST(y1), 0); |
272 | 5 | ccv_nnc_cmd_exec(CMD_AVERAGE_POOL_FORWARD(3, 3), HINT((1, 1), (1, 1)), 0, TENSOR_LIST(y1), TENSOR_LIST(x1), 0); |
273 | 5 | } |
274 | 1 | ccv_nnc_graph_autotune(graph, 0, 0, TRAVERSE_FULL); |
275 | 1 | ccv_nnc_graph_run(graph, 0, TRAVERSE_FULL, 0, 0); |
276 | 1 | ccv_nnc_tensor_t* z_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, z); |
277 | 1 | REQUIRE_MATRIX_EQ(x1, z_tensor, "5x5x4 matrix should be exactly the same"); |
278 | 1 | ccv_nnc_tensor_free(x1); |
279 | 1 | ccv_nnc_tensor_free(y1); |
280 | 1 | ccv_nnc_symbolic_graph_free(symbolic_graph); |
281 | 1 | ccv_nnc_graph_exec_arena_free(graph_exec_arena); |
282 | 1 | ccv_nnc_tensor_arena_free(tensor_arena); |
283 | 1 | ccv_nnc_graph_free(graph); |
284 | 1 | } |
285 | | |
286 | | TEST_CASE("symbolic graph for a while loop to compute x = conv(x, w, b) 5 times") |
287 | 1 | { |
288 | 1 | ccv_nnc_symbolic_graph_t* symbolic_graph = ccv_nnc_symbolic_graph_new(); |
289 | 1 | ccv_nnc_symbolic_graph_t* while_graph = ccv_nnc_symbolic_graph_new(); |
290 | 1 | ccv_nnc_symbolic_graph_while(symbolic_graph, CCV_NNC_GRAPH_FORWARD, while_graph, "while 1..5"); |
291 | 1 | ccv_nnc_tensor_symbol_t x = ccv_nnc_tensor_symbol_new(symbolic_graph, CPU_TENSOR_NHWC(32F, 5, 5, 4), "x"); |
292 | 1 | ccv_nnc_tensor_symbol_t w = ccv_nnc_tensor_symbol_new(while_graph, CPU_TENSOR_NHWC(32F, 4, 3, 3, 4), "w"); |
293 | 1 | ccv_nnc_tensor_symbol_t b = ccv_nnc_tensor_symbol_new(while_graph, CPU_TENSOR_NHWC(32F, 4), "b"); |
294 | 1 | ccv_nnc_tensor_symbol_t y = ccv_nnc_tensor_symbol_new(while_graph, CPU_TENSOR_NHWC(32F, 5, 5, 4), "y"); |
295 | 1 | ccv_nnc_tensor_symbol_t z0 = ccv_nnc_tensor_symbol_alias_new(while_graph, y, DIM_ALLOC(0, 0, 1), DIM_ALLOC(5 * 4, 4, 1), CPU_TENSOR_NHWC(32F, 5, 5, 3), "z0"); |
296 | 1 | ccv_nnc_tensor_symbol_t z1 = ccv_nnc_tensor_symbol_alias_new(while_graph, y, DIM_ALLOC(4), DIM_ALLOC(1), CPU_TENSOR_NHWC(32F, 6), "z1"); |
297 | 1 | ccv_nnc_graph_exec_symbol_t noop = ccv_nnc_graph_exec_symbol_new(while_graph, CMD_NOOP(), 0, 0, 0, 0, "noop"); |
298 | 1 | ccv_nnc_graph_exec_symbol_t conv = ccv_nnc_graph_exec_symbol_new(while_graph, CMD_CONVOLUTION_FORWARD(1, 4, 3, 3, 4), TENSOR_SYMBOL_LIST(x, w, b), TENSOR_SYMBOL_LIST(y), "conv"); |
299 | 1 | ccv_nnc_graph_exec_symbol_concat(while_graph, noop, conv); |
300 | 1 | ccv_nnc_symbolic_graph_set_while_expr(while_graph, while_5, 0, TENSOR_SYMBOL_LIST(ccv_nnc_tensor_symbol_for_while_count(while_graph)), GRAPH_EXEC_SYMBOL_LIST(noop)); |
301 | 1 | ccv_nnc_symbolic_graph_set_carry_overs(while_graph, TENSOR_SYMBOL_MAP(KV(y, x))); |
302 | 1 | ccv_nnc_symbolic_graph_set_sources(while_graph, GRAPH_EXEC_SYMBOL_LIST(noop)); |
303 | 1 | ccv_nnc_symbolic_graph_set_destinations(while_graph, GRAPH_EXEC_SYMBOL_LIST(conv)); |
304 | 1 | ccv_nnc_graph_t* graph = 0; |
305 | 1 | ccv_nnc_tensor_arena_t* tensor_arena = 0; |
306 | 1 | ccv_nnc_graph_exec_arena_t* graph_exec_arena = 0; |
307 | 1 | ccv_nnc_graph_exec_symbol_autogen(symbolic_graph, 0, 0, CCV_NNC_AUTOGEN_ALL_EXECS | CCV_NNC_AUTOGEN_SOURCES_AND_DESTINATIONS); |
308 | 1 | ccv_nnc_symbolic_graph_compile(symbolic_graph, ccv_nnc_default_compile_params, 0, 0, 0, 0, ccv_nnc_symbolic_graph_sources(symbolic_graph), ccv_nnc_symbolic_graph_source_size(symbolic_graph), ccv_nnc_symbolic_graph_destinations(symbolic_graph), ccv_nnc_symbolic_graph_destination_size(symbolic_graph), &graph, &tensor_arena, &graph_exec_arena); |
309 | 1 | SYMBOLIC_GRAPH_GEN(symbolic_graph, CCV_NNC_LONG_DOT_GRAPH); |
310 | 1 | GRAPH_GEN(graph, CCV_NNC_LONG_DOT_GRAPH); |
311 | 1 | ccv_nnc_tensor_t* x_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, x); |
312 | 1 | ccv_nnc_tensor_t* w_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, w); |
313 | 1 | ccv_nnc_tensor_t* b_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, b); |
314 | 1 | ccv_nnc_tensor_t* y_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, y); |
315 | 1 | ccv_nnc_tensor_t* z0_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, z0); |
316 | 1 | ccv_nnc_tensor_t* z1_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, z1); |
317 | 1 | int i; |
318 | 1 | dsfmt_t dsfmt; |
319 | 1 | dsfmt_init_gen_rand(&dsfmt, 0); |
320 | 101 | for (i = 0; i < 5 * 5 * 4; i++100 ) |
321 | 100 | x_tensor->data.f32[i] = dsfmt_genrand_open_close(&dsfmt); |
322 | 1 | ccv_nnc_tensor_t* x1 = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 5, 5, 4), 0); |
323 | 1 | memcpy(x1->data.f32, x_tensor->data.f32, sizeof(float) * 5 * 5 * 4); |
324 | 145 | for (i = 0; i < 4 * 3 * 3 * 4; i++144 ) |
325 | 144 | w_tensor->data.f32[i] = dsfmt_genrand_open_close(&dsfmt) / (4 * 3 * 3); |
326 | 5 | for (i = 0; i < 4; i++4 ) |
327 | 4 | b_tensor->data.f32[i] = 0.1; |
328 | 101 | for (i = 0; i < 5 * 5 * 4; i++100 ) |
329 | 100 | y_tensor->data.f32[i] = 1; |
330 | 1 | REQUIRE(y_tensor->data.f32 != x_tensor->data.f32, "y tensor and x tensor should point to different data"); |
331 | 1 | ccv_nnc_tensor_t* y1 = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 5, 5, 4), 0); |
332 | 6 | for (i = 0; i < 5; i++5 ) |
333 | 5 | { |
334 | 5 | ccv_nnc_cmd_exec(CMD_CONVOLUTION_FORWARD(1, 4, 3, 3, 4), HINT((1, 1), (1, 1)), 0, TENSOR_LIST(x1, w_tensor, b_tensor), TENSOR_LIST(y1), 0); |
335 | 5 | memcpy(x1->data.f32, y1->data.f32, sizeof(float) * 5 * 5 * 4); |
336 | 5 | } |
337 | 1 | ccv_nnc_graph_autotune(graph, 0, 0, TRAVERSE_FULL); |
338 | 1 | ccv_nnc_graph_run(graph, 0, TRAVERSE_FULL, 0, 0); |
339 | 1 | REQUIRE_MATRIX_EQ(y1, y_tensor, "5x5x4 matrix should be exactly the same"); |
340 | 1 | REQUIRE(z0_tensor->data.f32 == y_tensor->data.f32 + 1, "z0 should point to the same memory region as y, offset by 1"); |
341 | | // z0 and z1 trigger different code path (z1 will trigger one additional tensor setup). |
342 | 1 | REQUIRE(z1_tensor->data.f32 == y_tensor->data.f32 + 4, "z1 should point to the same memory region as y, offset by 4"); |
343 | 1 | ccv_nnc_tensor_free(x1); |
344 | 1 | ccv_nnc_tensor_free(y1); |
345 | 1 | ccv_nnc_symbolic_graph_free(symbolic_graph); |
346 | 1 | ccv_nnc_graph_exec_arena_free(graph_exec_arena); |
347 | 1 | ccv_nnc_tensor_arena_free(tensor_arena); |
348 | 1 | ccv_nnc_graph_free(graph); |
349 | 1 | } |
350 | | |
351 | | TEST_CASE("symbolic graph for a while loop to compute x = conv(x, w, b) 5 times then z = x0 + x") |
352 | 1 | { |
353 | 1 | ccv_nnc_symbolic_graph_t* symbolic_graph = ccv_nnc_symbolic_graph_new(); |
354 | 1 | ccv_nnc_symbolic_graph_t* while_graph = ccv_nnc_symbolic_graph_new(); |
355 | 1 | ccv_nnc_symbolic_graph_while(symbolic_graph, CCV_NNC_GRAPH_FORWARD, while_graph, "while 1..5"); |
356 | 1 | ccv_nnc_tensor_symbol_t x = ccv_nnc_tensor_symbol_new(symbolic_graph, CPU_TENSOR_NHWC(32F, 5, 5, 4), "x"); |
357 | 1 | ccv_nnc_tensor_symbol_t w = ccv_nnc_tensor_symbol_new(while_graph, CPU_TENSOR_NHWC(32F, 4, 3, 3, 4), "w"); |
358 | 1 | ccv_nnc_tensor_symbol_t b = ccv_nnc_tensor_symbol_new(while_graph, CPU_TENSOR_NHWC(32F, 4), "b"); |
359 | 1 | ccv_nnc_tensor_symbol_t y = ccv_nnc_tensor_symbol_new(while_graph, CPU_TENSOR_NHWC(32F, 5, 5, 4), "y"); |
360 | 1 | ccv_nnc_graph_exec_symbol_t noop = ccv_nnc_graph_exec_symbol_new(while_graph, CMD_NOOP(), 0, 0, 0, 0, "noop"); |
361 | 1 | ccv_nnc_graph_exec_symbol_t conv = ccv_nnc_graph_exec_symbol_new(while_graph, CMD_CONVOLUTION_FORWARD(1, 4, 3, 3, 4), TENSOR_SYMBOL_LIST(x, w, b), TENSOR_SYMBOL_LIST(y), "conv"); |
362 | 1 | ccv_nnc_graph_exec_symbol_concat(while_graph, noop, conv); |
363 | 1 | ccv_nnc_tensor_symbol_t xz = ccv_nnc_tensor_symbol_alias_new(symbolic_graph, x, ccv_nnc_no_ofs, DIM_ALLOC(1), CPU_TENSOR_NHWC(32F, 5 * 5 * 4), "x0"); |
364 | 1 | ccv_nnc_tensor_symbol_t yz = ccv_nnc_tensor_symbol_alias_new(while_graph, y, ccv_nnc_no_ofs, DIM_ALLOC(1), CPU_TENSOR_NHWC(32F, 5 * 5 * 4), "y0"); |
365 | 1 | ccv_nnc_tensor_symbol_t z = ccv_nnc_tensor_symbol_new(symbolic_graph, CPU_TENSOR_NHWC(32F, 5 * 5 * 4), "z"); |
366 | 1 | ccv_nnc_graph_exec_symbol_new(symbolic_graph, CMD_EWSUM_FORWARD(), TENSOR_SYMBOL_LIST(xz, yz), TENSOR_SYMBOL_LIST(z), "sum"); |
367 | 1 | ccv_nnc_symbolic_graph_set_while_expr(while_graph, while_5, 0, TENSOR_SYMBOL_LIST(ccv_nnc_tensor_symbol_for_while_count(while_graph)), GRAPH_EXEC_SYMBOL_LIST(noop)); |
368 | 1 | ccv_nnc_symbolic_graph_set_carry_overs(while_graph, TENSOR_SYMBOL_MAP(KV(y, x))); |
369 | 1 | ccv_nnc_symbolic_graph_set_sources(while_graph, GRAPH_EXEC_SYMBOL_LIST(noop)); |
370 | 1 | ccv_nnc_symbolic_graph_set_destinations(while_graph, GRAPH_EXEC_SYMBOL_LIST(conv)); |
371 | 1 | ccv_nnc_graph_t* graph = 0; |
372 | 1 | ccv_nnc_tensor_arena_t* tensor_arena = 0; |
373 | 1 | ccv_nnc_graph_exec_arena_t* graph_exec_arena = 0; |
374 | 1 | ccv_nnc_graph_exec_symbol_autogen(symbolic_graph, 0, 0, CCV_NNC_AUTOGEN_ALL_EXECS | CCV_NNC_AUTOGEN_SOURCES_AND_DESTINATIONS); |
375 | 1 | ccv_nnc_symbolic_graph_compile(symbolic_graph, ccv_nnc_default_compile_params, 0, 0, 0, 0, ccv_nnc_symbolic_graph_sources(symbolic_graph), ccv_nnc_symbolic_graph_source_size(symbolic_graph), ccv_nnc_symbolic_graph_destinations(symbolic_graph), ccv_nnc_symbolic_graph_destination_size(symbolic_graph), &graph, &tensor_arena, &graph_exec_arena); |
376 | 1 | SYMBOLIC_GRAPH_GEN(symbolic_graph, CCV_NNC_LONG_DOT_GRAPH); |
377 | 1 | GRAPH_GEN(graph, CCV_NNC_LONG_DOT_GRAPH); |
378 | 1 | ccv_nnc_tensor_t* x_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, x); |
379 | 1 | ccv_nnc_tensor_t* w_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, w); |
380 | 1 | ccv_nnc_tensor_t* b_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, b); |
381 | 1 | ccv_nnc_tensor_t* y_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, y); |
382 | 1 | ccv_nnc_tensor_t* z_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, z); |
383 | 1 | int i; |
384 | 1 | dsfmt_t dsfmt; |
385 | 1 | dsfmt_init_gen_rand(&dsfmt, 0); |
386 | 101 | for (i = 0; i < 5 * 5 * 4; i++100 ) |
387 | 100 | x_tensor->data.f32[i] = dsfmt_genrand_open_close(&dsfmt); |
388 | 1 | ccv_nnc_tensor_t* x0 = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 5, 5, 4), 0); |
389 | 1 | ccv_nnc_tensor_t* x1 = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 5, 5, 4), 0); |
390 | 1 | memcpy(x0->data.f32, x_tensor->data.f32, sizeof(float) * 5 * 5 * 4); |
391 | 1 | memcpy(x1->data.f32, x_tensor->data.f32, sizeof(float) * 5 * 5 * 4); |
392 | 145 | for (i = 0; i < 4 * 3 * 3 * 4; i++144 ) |
393 | 144 | w_tensor->data.f32[i] = dsfmt_genrand_open_close(&dsfmt) / (4 * 3 * 3); |
394 | 5 | for (i = 0; i < 4; i++4 ) |
395 | 4 | b_tensor->data.f32[i] = 0.1; |
396 | 101 | for (i = 0; i < 5 * 5 * 4; i++100 ) |
397 | 100 | y_tensor->data.f32[i] = 1; |
398 | 1 | REQUIRE(y_tensor->data.f32 != x_tensor->data.f32, "y tensor and x tensor should point to different data"); |
399 | 1 | ccv_nnc_tensor_t* y1 = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 5, 5, 4), 0); |
400 | 6 | for (i = 0; i < 5; i++5 ) |
401 | 5 | { |
402 | 5 | ccv_nnc_cmd_exec(CMD_CONVOLUTION_FORWARD(1, 4, 3, 3, 4), HINT((1, 1), (1, 1)), 0, TENSOR_LIST(x1, w_tensor, b_tensor), TENSOR_LIST(y1), 0); |
403 | 5 | memcpy(x1->data.f32, y1->data.f32, sizeof(float) * 5 * 5 * 4); |
404 | 5 | } |
405 | 101 | for (i = 0; i < 5 * 5 * 4; i++100 ) |
406 | 100 | x0->data.f32[i] += y1->data.f32[i]; |
407 | 1 | ccv_nnc_tensor_t z0 = ccv_nnc_tensor(x0->data.f32, CPU_TENSOR_NHWC(32F, 5 * 5 * 4), 0); |
408 | 1 | ccv_nnc_graph_autotune(graph, 0, 0, TRAVERSE_FULL); |
409 | 1 | ccv_nnc_graph_run(graph, 0, TRAVERSE_FULL, 0, 0); |
410 | 1 | REQUIRE_MATRIX_EQ(&z0, z_tensor, "5x5x4 matrix should be exactly the same"); |
411 | 1 | ccv_nnc_tensor_free(x0); |
412 | 1 | ccv_nnc_tensor_free(x1); |
413 | 1 | ccv_nnc_tensor_free(y1); |
414 | 1 | ccv_nnc_symbolic_graph_free(symbolic_graph); |
415 | 1 | ccv_nnc_graph_exec_arena_free(graph_exec_arena); |
416 | 1 | ccv_nnc_tensor_arena_free(tensor_arena); |
417 | 1 | ccv_nnc_graph_free(graph); |
418 | 1 | } |
419 | | |
420 | | TEST_CASE("symbolic graph for a while loop to compute (x = conv(x, w, b) 5 times, z = x0 + x (x <- z)) 5 times") |
421 | 1 | { |
422 | 1 | ccv_nnc_symbolic_graph_t* symbolic_graph = ccv_nnc_symbolic_graph_new(); |
423 | 1 | ccv_nnc_symbolic_graph_t* while_graph = ccv_nnc_symbolic_graph_new(); |
424 | 1 | ccv_nnc_symbolic_graph_t* sub_while_graph = ccv_nnc_symbolic_graph_new(); |
425 | 1 | ccv_nnc_symbolic_graph_while(symbolic_graph, CCV_NNC_GRAPH_FORWARD, while_graph, "while 1..5"); |
426 | 1 | ccv_nnc_graph_exec_symbol_t sub_while = ccv_nnc_symbolic_graph_while(while_graph, CCV_NNC_GRAPH_FORWARD, sub_while_graph, "while 1..5"); |
427 | 1 | ccv_nnc_tensor_symbol_t x = ccv_nnc_tensor_symbol_new(while_graph, CPU_TENSOR_NHWC(32F, 5, 5, 4), "x"); |
428 | 1 | ccv_nnc_tensor_symbol_t w = ccv_nnc_tensor_symbol_new(sub_while_graph, CPU_TENSOR_NHWC(32F, 4, 3, 3, 4), "w"); |
429 | 1 | ccv_nnc_tensor_symbol_t b = ccv_nnc_tensor_symbol_new(sub_while_graph, CPU_TENSOR_NHWC(32F, 4), "b"); |
430 | 1 | ccv_nnc_tensor_symbol_t y = ccv_nnc_tensor_symbol_new(while_graph, CPU_TENSOR_NHWC(32F, 5, 5, 4), "y"); |
431 | 1 | ccv_nnc_graph_exec_symbol_t sub_noop = ccv_nnc_graph_exec_symbol_new(sub_while_graph, CMD_NOOP(), 0, 0, 0, 0, "noop"); |
432 | 1 | ccv_nnc_graph_exec_symbol_t conv = ccv_nnc_graph_exec_symbol_new(sub_while_graph, CMD_CONVOLUTION_FORWARD(1, 4, 3, 3, 4), TENSOR_SYMBOL_LIST(x, w, b), TENSOR_SYMBOL_LIST(y), "conv"); |
433 | 1 | ccv_nnc_graph_exec_symbol_concat(sub_while_graph, sub_noop, conv); |
434 | 1 | ccv_nnc_tensor_symbol_t xz = ccv_nnc_tensor_symbol_alias_new(while_graph, x, ccv_nnc_no_ofs, DIM_ALLOC(1), CPU_TENSOR_NHWC(32F, 5 * 5 * 4), "x0"); |
435 | 1 | ccv_nnc_tensor_symbol_t yz = ccv_nnc_tensor_symbol_alias_new(while_graph, y, ccv_nnc_no_ofs, DIM_ALLOC(1), CPU_TENSOR_NHWC(32F, 5 * 5 * 4), "y0"); |
436 | 1 | ccv_nnc_tensor_symbol_t z = ccv_nnc_tensor_symbol_new(while_graph, CPU_TENSOR_NHWC(32F, 5, 5, 4), "z"); |
437 | 1 | ccv_nnc_tensor_symbol_t zz = ccv_nnc_tensor_symbol_alias_new(while_graph, z, ccv_nnc_no_ofs, DIM_ALLOC(1), CPU_TENSOR_NHWC(32F, 5 * 5 * 4), "z0"); |
438 | 1 | ccv_nnc_graph_exec_symbol_t sum = ccv_nnc_graph_exec_symbol_new(while_graph, CMD_EWSUM_FORWARD(), TENSOR_SYMBOL_LIST(xz, yz), TENSOR_SYMBOL_LIST(zz), "sum"); |
439 | 1 | ccv_nnc_symbolic_graph_set_while_expr(sub_while_graph, while_5, 0, TENSOR_SYMBOL_LIST(ccv_nnc_tensor_symbol_for_while_count(sub_while_graph), ccv_nnc_tensor_symbol_for_while_count(while_graph)), GRAPH_EXEC_SYMBOL_LIST(sub_noop)); |
440 | 1 | ccv_nnc_symbolic_graph_set_carry_overs(sub_while_graph, TENSOR_SYMBOL_MAP(KV(y, x))); |
441 | 1 | ccv_nnc_symbolic_graph_set_sources(sub_while_graph, GRAPH_EXEC_SYMBOL_LIST(sub_noop)); |
442 | 1 | ccv_nnc_symbolic_graph_set_destinations(sub_while_graph, GRAPH_EXEC_SYMBOL_LIST(conv)); |
443 | 1 | ccv_nnc_graph_exec_symbol_t noop = ccv_nnc_graph_exec_symbol_new(while_graph, CMD_NOOP(), 0, 0, 0, 0, "noop"); |
444 | 1 | ccv_nnc_graph_exec_symbol_concat(while_graph, noop, sub_while); |
445 | 1 | ccv_nnc_graph_exec_symbol_concat(while_graph, sub_while, sum); |
446 | 1 | ccv_nnc_symbolic_graph_set_while_expr(while_graph, while_5, 0, TENSOR_SYMBOL_LIST(ccv_nnc_tensor_symbol_for_while_count(while_graph)), GRAPH_EXEC_SYMBOL_LIST(noop)); |
447 | 1 | ccv_nnc_symbolic_graph_set_carry_overs(while_graph, TENSOR_SYMBOL_MAP(KV(z, x))); |
448 | 1 | ccv_nnc_symbolic_graph_set_sources(while_graph, GRAPH_EXEC_SYMBOL_LIST(noop)); |
449 | 1 | ccv_nnc_symbolic_graph_set_destinations(while_graph, GRAPH_EXEC_SYMBOL_LIST(sum)); |
450 | 1 | ccv_nnc_graph_exec_symbol_autogen(symbolic_graph, 0, 0, CCV_NNC_AUTOGEN_ALL_EXECS | CCV_NNC_AUTOGEN_SOURCES_AND_DESTINATIONS); |
451 | 1 | SYMBOLIC_GRAPH_GEN(symbolic_graph, CCV_NNC_LONG_DOT_GRAPH); |
452 | 1 | ccv_nnc_graph_t* graph = 0; |
453 | 1 | ccv_nnc_tensor_arena_t* tensor_arena = 0; |
454 | 1 | ccv_nnc_graph_exec_arena_t* graph_exec_arena = 0; |
455 | 1 | ccv_nnc_symbolic_graph_compile(symbolic_graph, ccv_nnc_default_compile_params, 0, 0, 0, 0, ccv_nnc_symbolic_graph_sources(symbolic_graph), ccv_nnc_symbolic_graph_source_size(symbolic_graph), ccv_nnc_symbolic_graph_destinations(symbolic_graph), ccv_nnc_symbolic_graph_destination_size(symbolic_graph), &graph, &tensor_arena, &graph_exec_arena); |
456 | 1 | GRAPH_GEN(graph, CCV_NNC_LONG_DOT_GRAPH); |
457 | 1 | ccv_nnc_tensor_t* x_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, x); |
458 | 1 | ccv_nnc_tensor_t* w_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, w); |
459 | 1 | ccv_nnc_tensor_t* b_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, b); |
460 | 1 | ccv_nnc_tensor_t* y_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, y); |
461 | 1 | ccv_nnc_tensor_t* z_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, z); |
462 | 1 | int i, j; |
463 | 1 | dsfmt_t dsfmt; |
464 | 1 | dsfmt_init_gen_rand(&dsfmt, 0); |
465 | 101 | for (i = 0; i < 5 * 5 * 4; i++100 ) |
466 | 100 | x_tensor->data.f32[i] = dsfmt_genrand_open_close(&dsfmt); |
467 | 1 | ccv_nnc_tensor_t* x0 = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 5, 5, 4), 0); |
468 | 1 | ccv_nnc_tensor_t* x1 = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 5, 5, 4), 0); |
469 | 1 | memcpy(x0->data.f32, x_tensor->data.f32, sizeof(float) * 5 * 5 * 4); |
470 | 145 | for (i = 0; i < 4 * 3 * 3 * 4; i++144 ) |
471 | 144 | w_tensor->data.f32[i] = dsfmt_genrand_open_close(&dsfmt) / (4 * 3 * 3); |
472 | 5 | for (i = 0; i < 4; i++4 ) |
473 | 4 | b_tensor->data.f32[i] = 0.1; |
474 | 101 | for (i = 0; i < 5 * 5 * 4; i++100 ) |
475 | 100 | y_tensor->data.f32[i] = 1; |
476 | 1 | REQUIRE(y_tensor->data.f32 != x_tensor->data.f32, "y tensor and x tensor should point to different data"); |
477 | 1 | ccv_nnc_tensor_t* y1 = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 5, 5, 4), 0); |
478 | 6 | for (i = 0; i < 5; i++5 ) |
479 | 5 | { |
480 | 5 | memcpy(x1->data.f32, x0->data.f32, sizeof(float) * 5 * 5 * 4); |
481 | 30 | for (j = 0; j < 5; j++25 ) |
482 | 25 | { |
483 | 25 | ccv_nnc_cmd_exec(CMD_CONVOLUTION_FORWARD(1, 4, 3, 3, 4), HINT((1, 1), (1, 1)), 0, TENSOR_LIST(x1, w_tensor, b_tensor), TENSOR_LIST(y1), 0); |
484 | 25 | memcpy(x1->data.f32, y1->data.f32, sizeof(float) * 5 * 5 * 4); |
485 | 25 | } |
486 | 505 | for (j = 0; j < 5 * 5 * 4; j++500 ) |
487 | 500 | x0->data.f32[j] += y1->data.f32[j]; |
488 | 5 | } |
489 | 1 | ccv_nnc_graph_autotune(graph, 0, 0, TRAVERSE_FULL); |
490 | 1 | ccv_nnc_graph_run(graph, 0, TRAVERSE_FULL, 0, 0); |
491 | 1 | REQUIRE_MATRIX_EQ(x0, z_tensor, "5x5x4 matrix should be exactly the same"); |
492 | 1 | ccv_nnc_tensor_free(x0); |
493 | 1 | ccv_nnc_tensor_free(x1); |
494 | 1 | ccv_nnc_tensor_free(y1); |
495 | 1 | ccv_nnc_graph_exec_arena_free(graph_exec_arena); |
496 | 1 | ccv_nnc_tensor_arena_free(tensor_arena); |
497 | 1 | ccv_nnc_graph_free(graph); |
498 | 1 | ccv_nnc_symbolic_graph_free(symbolic_graph); |
499 | 1 | } |
500 | | |
501 | | TEST_CASE("symbolic graph for a while loop to compute y = conv(x1, w, b), x2 = x0 + y 5 times, (x0 <- x1, x1 <- x2)") |
502 | 1 | { |
503 | 1 | ccv_nnc_symbolic_graph_t* symbolic_graph = ccv_nnc_symbolic_graph_new(); |
504 | 1 | ccv_nnc_symbolic_graph_t* while_graph = ccv_nnc_symbolic_graph_new(); |
505 | 1 | ccv_nnc_symbolic_graph_while(symbolic_graph, CCV_NNC_GRAPH_FORWARD, while_graph, "while 1..5"); |
506 | 1 | ccv_nnc_tensor_symbol_t x1 = ccv_nnc_tensor_symbol_new(symbolic_graph, CPU_TENSOR_NHWC(32F, 5, 5, 4), "x1"); |
507 | 1 | ccv_nnc_tensor_symbol_t x0 = ccv_nnc_tensor_symbol_new(while_graph, CPU_TENSOR_NHWC(32F, 5, 5, 4), "x0"); |
508 | 1 | ccv_nnc_tensor_symbol_t w = ccv_nnc_tensor_symbol_new(while_graph, CPU_TENSOR_NHWC(32F, 4, 3, 3, 4), "w"); |
509 | 1 | ccv_nnc_tensor_symbol_t b = ccv_nnc_tensor_symbol_new(while_graph, CPU_TENSOR_NHWC(32F, 4), "b"); |
510 | 1 | ccv_nnc_tensor_symbol_t y = ccv_nnc_tensor_symbol_new(while_graph, CPU_TENSOR_NHWC(32F, 5, 5, 4), "y"); |
511 | 1 | ccv_nnc_graph_exec_symbol_t noop = ccv_nnc_graph_exec_symbol_new(while_graph, CMD_NOOP(), 0, 0, 0, 0, "noop"); |
512 | 1 | ccv_nnc_graph_exec_symbol_t conv = ccv_nnc_graph_exec_symbol_new(while_graph, CMD_CONVOLUTION_FORWARD(1, 4, 3, 3, 4), TENSOR_SYMBOL_LIST(x1, w, b), TENSOR_SYMBOL_LIST(y), "conv"); |
513 | 1 | ccv_nnc_graph_exec_symbol_concat(while_graph, noop, conv); |
514 | 1 | ccv_nnc_tensor_symbol_t x0z = ccv_nnc_tensor_symbol_alias_new(while_graph, x0, ccv_nnc_no_ofs, DIM_ALLOC(1), CPU_TENSOR_NHWC(32F, 5 * 5 * 4), "x0"); |
515 | 1 | ccv_nnc_tensor_symbol_t yz = ccv_nnc_tensor_symbol_alias_new(while_graph, y, ccv_nnc_no_ofs, DIM_ALLOC(1), CPU_TENSOR_NHWC(32F, 5 * 5 * 4), "y"); |
516 | 1 | ccv_nnc_tensor_symbol_t x2 = ccv_nnc_tensor_symbol_new(while_graph, CPU_TENSOR_NHWC(32F, 5, 5, 4), "x2"); |
517 | 1 | ccv_nnc_tensor_symbol_t x2z = ccv_nnc_tensor_symbol_alias_new(while_graph, x2, ccv_nnc_no_ofs, DIM_ALLOC(1), CPU_TENSOR_NHWC(32F, 5 * 5 * 4), "x2"); |
518 | 1 | ccv_nnc_graph_exec_symbol_new(while_graph, CMD_EWSUM_FORWARD(), TENSOR_SYMBOL_LIST(x0z, yz), TENSOR_SYMBOL_LIST(x2z), "sum"); |
519 | 1 | ccv_nnc_symbolic_graph_set_while_expr(while_graph, while_5, 0, TENSOR_SYMBOL_LIST(ccv_nnc_tensor_symbol_for_while_count(while_graph)), GRAPH_EXEC_SYMBOL_LIST(noop)); |
520 | 1 | ccv_nnc_symbolic_graph_set_carry_overs(while_graph, TENSOR_SYMBOL_MAP(KV(x2, x1), KV(x1, x0))); |
521 | 1 | ccv_nnc_symbolic_graph_set_sources(while_graph, GRAPH_EXEC_SYMBOL_LIST(noop)); |
522 | 1 | ccv_nnc_symbolic_graph_set_destinations(while_graph, GRAPH_EXEC_SYMBOL_LIST(conv)); |
523 | 1 | ccv_nnc_graph_t* graph = 0; |
524 | 1 | ccv_nnc_tensor_arena_t* tensor_arena = 0; |
525 | 1 | ccv_nnc_graph_exec_arena_t* graph_exec_arena = 0; |
526 | 1 | ccv_nnc_graph_exec_symbol_autogen(symbolic_graph, 0, 0, CCV_NNC_AUTOGEN_ALL_EXECS | CCV_NNC_AUTOGEN_SOURCES_AND_DESTINATIONS); |
527 | 1 | SYMBOLIC_GRAPH_GEN(symbolic_graph, CCV_NNC_LONG_DOT_GRAPH); |
528 | 1 | ccv_nnc_symbolic_graph_compile(symbolic_graph, ccv_nnc_default_compile_params, 0, 0, 0, 0, ccv_nnc_symbolic_graph_sources(symbolic_graph), ccv_nnc_symbolic_graph_source_size(symbolic_graph), ccv_nnc_symbolic_graph_destinations(symbolic_graph), ccv_nnc_symbolic_graph_destination_size(symbolic_graph), &graph, &tensor_arena, &graph_exec_arena); |
529 | 1 | GRAPH_GEN(graph, CCV_NNC_LONG_DOT_GRAPH); |
530 | 1 | ccv_nnc_tensor_t* x0_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, x0); |
531 | 1 | ccv_nnc_tensor_t* x1_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, x1); |
532 | 1 | ccv_nnc_tensor_t* w_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, w); |
533 | 1 | ccv_nnc_tensor_t* b_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, b); |
534 | 1 | ccv_nnc_tensor_t* y_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, y); |
535 | 1 | int i, j; |
536 | 1 | memset(x0_tensor->data.f32, 0, sizeof(float) * 5 * 5 * 4); |
537 | 1 | dsfmt_t dsfmt; |
538 | 1 | dsfmt_init_gen_rand(&dsfmt, 0); |
539 | 101 | for (i = 0; i < 5 * 5 * 4; i++100 ) |
540 | 100 | x1_tensor->data.f32[i] = dsfmt_genrand_open_close(&dsfmt); |
541 | 145 | for (i = 0; i < 4 * 3 * 3 * 4; i++144 ) |
542 | 144 | w_tensor->data.f32[i] = dsfmt_genrand_open_close(&dsfmt) / (4 * 3 * 3); |
543 | 5 | for (i = 0; i < 4; i++4 ) |
544 | 4 | b_tensor->data.f32[i] = 0.1; |
545 | 101 | for (i = 0; i < 5 * 5 * 4; i++100 ) |
546 | 100 | y_tensor->data.f32[i] = 1; |
547 | 1 | ccv_nnc_tensor_t* x0t = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 5, 5, 4), 0); |
548 | 1 | memset(x0t->data.f32, 0, sizeof(float) * 5 * 5 * 4); |
549 | 1 | ccv_nnc_tensor_t* x1t = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 5, 5, 4), 0); |
550 | 1 | memcpy(x1t->data.f32, x1_tensor->data.f32, sizeof(float) * 5 * 5 * 4); |
551 | 1 | ccv_nnc_tensor_t* x2t = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 5, 5, 4), 0); |
552 | 6 | for (i = 0; i < 5; i++5 ) |
553 | 5 | { |
554 | 5 | ccv_nnc_cmd_exec(CMD_CONVOLUTION_FORWARD(1, 4, 3, 3, 4), HINT((1, 1), (1, 1)), 0, TENSOR_LIST(x1t, w_tensor, b_tensor), TENSOR_LIST(x2t), 0); |
555 | 505 | for (j = 0; j < 5 * 5 * 4; j++500 ) |
556 | 500 | x2t->data.f32[j] += x0t->data.f32[j]; |
557 | 5 | memcpy(x0t->data.f32, x1t->data.f32, sizeof(float) * 5 * 5 * 4); |
558 | 5 | memcpy(x1t->data.f32, x2t->data.f32, sizeof(float) * 5 * 5 * 4); |
559 | 5 | } |
560 | 1 | ccv_nnc_graph_autotune(graph, 0, 0, TRAVERSE_FULL); |
561 | 1 | ccv_nnc_graph_run(graph, 0, TRAVERSE_FULL, 0, 0); |
562 | 1 | ccv_nnc_tensor_t* x2_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, x2); |
563 | 1 | REQUIRE_MATRIX_EQ(x2t, x2_tensor, "5x5x4 matrix should be exactly the same"); |
564 | 1 | ccv_nnc_tensor_free(x0t); |
565 | 1 | ccv_nnc_tensor_free(x1t); |
566 | 1 | ccv_nnc_tensor_free(x2t); |
567 | 1 | ccv_nnc_symbolic_graph_free(symbolic_graph); |
568 | 1 | ccv_nnc_graph_exec_arena_free(graph_exec_arena); |
569 | 1 | ccv_nnc_tensor_arena_free(tensor_arena); |
570 | 1 | ccv_nnc_graph_free(graph); |
571 | 1 | } |
572 | | |
573 | | TEST_CASE("a while loop to compute y = conv(x1, w, b), y1 = 1.2 * y, x3 = x0 + y1 5 times, then z = y + x3 + x2 + x1 + x0, (x0 <- x1, x1 <- x2, x2 <- x3)") |
574 | 1 | { |
575 | 1 | ccv_nnc_symbolic_graph_t* symbolic_graph = ccv_nnc_symbolic_graph_new(); |
576 | 1 | ccv_nnc_symbolic_graph_t* while_graph = ccv_nnc_symbolic_graph_new(); |
577 | 1 | ccv_nnc_symbolic_graph_while(symbolic_graph, CCV_NNC_GRAPH_FORWARD, while_graph, "while 1..5"); |
578 | 1 | ccv_nnc_tensor_symbol_t x1 = ccv_nnc_tensor_symbol_new(symbolic_graph, CPU_TENSOR_NHWC(32F, 5, 5, 4), "x1"); |
579 | 1 | ccv_nnc_tensor_symbol_t y0 = ccv_nnc_tensor_symbol_new(symbolic_graph, CPU_TENSOR_NHWC(32F, 5 * 5 * 4), "y0"); |
580 | 1 | ccv_nnc_tensor_symbol_t x0 = ccv_nnc_tensor_symbol_new(while_graph, CPU_TENSOR_NHWC(32F, 5, 5, 4), "x0"); |
581 | 1 | ccv_nnc_tensor_symbol_t w = ccv_nnc_tensor_symbol_new(while_graph, CPU_TENSOR_NHWC(32F, 4, 3, 3, 4), "w"); |
582 | 1 | ccv_nnc_tensor_symbol_t b = ccv_nnc_tensor_symbol_new(while_graph, CPU_TENSOR_NHWC(32F, 4), "b"); |
583 | 1 | ccv_nnc_tensor_symbol_t y = ccv_nnc_tensor_symbol_new(while_graph, CPU_TENSOR_NHWC(32F, 5, 5, 4), "y"); |
584 | 1 | ccv_nnc_tensor_symbol_t y1 = ccv_nnc_tensor_symbol_new(while_graph, CPU_TENSOR_NHWC(32F, 5 * 5 * 4), "y1"); |
585 | 1 | ccv_nnc_graph_exec_symbol_t noop = ccv_nnc_graph_exec_symbol_new(while_graph, CMD_NOOP(), 0, 0, 0, 0, "noop"); |
586 | 1 | ccv_nnc_graph_exec_symbol_t conv = ccv_nnc_graph_exec_symbol_new(while_graph, CMD_CONVOLUTION_FORWARD(1, 4, 3, 3, 4), TENSOR_SYMBOL_LIST(x1, w, b), TENSOR_SYMBOL_LIST(y), "conv"); |
587 | 1 | ccv_nnc_graph_exec_symbol_concat(while_graph, noop, conv); |
588 | 1 | ccv_nnc_tensor_symbol_t x0z = ccv_nnc_tensor_symbol_alias_new(while_graph, x0, ccv_nnc_no_ofs, DIM_ALLOC(1), CPU_TENSOR_NHWC(32F, 5 * 5 * 4), "x0"); |
589 | 1 | ccv_nnc_tensor_symbol_t yz = ccv_nnc_tensor_symbol_alias_new(while_graph, y, ccv_nnc_no_ofs, DIM_ALLOC(1), CPU_TENSOR_NHWC(32F, 5 * 5 * 4), "y"); |
590 | 1 | ccv_nnc_graph_exec_symbol_new(while_graph, CMD_EWPROD_FORWARD(), TENSOR_SYMBOL_LIST(yz, y0), TENSOR_SYMBOL_LIST(y1), "prod"); |
591 | 1 | ccv_nnc_tensor_symbol_t x2 = ccv_nnc_tensor_symbol_new(while_graph, CPU_TENSOR_NHWC(32F, 5, 5, 4), "x2"); |
592 | 1 | ccv_nnc_tensor_symbol_t x2z = ccv_nnc_tensor_symbol_alias_new(while_graph, x2, ccv_nnc_no_ofs, DIM_ALLOC(1), CPU_TENSOR_NHWC(32F, 5 * 5 * 4), "x2"); |
593 | 1 | ccv_nnc_tensor_symbol_t x3 = ccv_nnc_tensor_symbol_new(while_graph, CPU_TENSOR_NHWC(32F, 5, 5, 4), "x3"); |
594 | 1 | ccv_nnc_tensor_symbol_t x3z = ccv_nnc_tensor_symbol_alias_new(while_graph, x3, ccv_nnc_no_ofs, DIM_ALLOC(1), CPU_TENSOR_NHWC(32F, 5 * 5 * 4), "x2"); |
595 | 1 | ccv_nnc_graph_exec_symbol_new(while_graph, CMD_EWSUM_FORWARD(), TENSOR_SYMBOL_LIST(x0z, y1), TENSOR_SYMBOL_LIST(x3z), "sum"); |
596 | 1 | ccv_nnc_tensor_symbol_t x1s = ccv_nnc_tensor_symbol_resolve(while_graph, x1); |
597 | 1 | ccv_nnc_tensor_symbol_t x1z = ccv_nnc_tensor_symbol_alias_new(while_graph, x1s, ccv_nnc_no_ofs, DIM_ALLOC(1), CPU_TENSOR_NHWC(32F, 5 * 5 * 4), "x1"); |
598 | 1 | ccv_nnc_symbolic_graph_set_while_expr(while_graph, while_5, 0, TENSOR_SYMBOL_LIST(ccv_nnc_tensor_symbol_for_while_count(while_graph)), GRAPH_EXEC_SYMBOL_LIST(noop)); |
599 | 1 | ccv_nnc_symbolic_graph_set_carry_overs(while_graph, TENSOR_SYMBOL_MAP(KV(x3, x2), KV(x2, x1), KV(x1, x0))); |
600 | 1 | ccv_nnc_symbolic_graph_set_sources(while_graph, GRAPH_EXEC_SYMBOL_LIST(noop)); |
601 | 1 | ccv_nnc_symbolic_graph_set_destinations(while_graph, GRAPH_EXEC_SYMBOL_LIST(conv)); |
602 | 1 | ccv_nnc_tensor_symbol_t z = ccv_nnc_tensor_symbol_new(symbolic_graph, CPU_TENSOR_NHWC(32F, 5 * 5 * 4), "z"); |
603 | 1 | ccv_nnc_graph_exec_symbol_new(symbolic_graph, CMD_EWSUM_FORWARD(), TENSOR_SYMBOL_LIST(yz, x0z, x1z, x2z, x3z), TENSOR_SYMBOL_LIST(z), "sum1"); |
604 | 1 | ccv_nnc_graph_t* graph = 0; |
605 | 1 | ccv_nnc_tensor_arena_t* tensor_arena = 0; |
606 | 1 | ccv_nnc_graph_exec_arena_t* graph_exec_arena = 0; |
607 | 1 | ccv_nnc_graph_exec_symbol_autogen(symbolic_graph, 0, 0, CCV_NNC_AUTOGEN_ALL_EXECS | CCV_NNC_AUTOGEN_SOURCES_AND_DESTINATIONS); |
608 | 1 | SYMBOLIC_GRAPH_GEN(symbolic_graph, CCV_NNC_LONG_DOT_GRAPH); |
609 | 1 | ccv_nnc_symbolic_graph_compile(symbolic_graph, ccv_nnc_default_compile_params, 0, 0, 0, 0, ccv_nnc_symbolic_graph_sources(symbolic_graph), ccv_nnc_symbolic_graph_source_size(symbolic_graph), ccv_nnc_symbolic_graph_destinations(symbolic_graph), ccv_nnc_symbolic_graph_destination_size(symbolic_graph), &graph, &tensor_arena, &graph_exec_arena); |
610 | 1 | GRAPH_GEN(graph, CCV_NNC_LONG_DOT_GRAPH); |
611 | 1 | ccv_nnc_tensor_t* x0_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, x0); |
612 | 1 | ccv_nnc_tensor_t* x1_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, x1); |
613 | 1 | ccv_nnc_tensor_t* w_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, w); |
614 | 1 | ccv_nnc_tensor_t* b_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, b); |
615 | 1 | ccv_nnc_tensor_t* y_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, y); |
616 | 1 | ccv_nnc_tensor_t* y0_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, y0); |
617 | 1 | int i, j; |
618 | 1 | memset(x0_tensor->data.f32, 0, sizeof(float) * 5 * 5 * 4); |
619 | 1 | dsfmt_t dsfmt; |
620 | 1 | dsfmt_init_gen_rand(&dsfmt, 0); |
621 | 101 | for (i = 0; i < 5 * 5 * 4; i++100 ) |
622 | 100 | x1_tensor->data.f32[i] = dsfmt_genrand_open_close(&dsfmt); |
623 | 145 | for (i = 0; i < 4 * 3 * 3 * 4; i++144 ) |
624 | 144 | w_tensor->data.f32[i] = dsfmt_genrand_open_close(&dsfmt) / (4 * 3 * 3); |
625 | 5 | for (i = 0; i < 4; i++4 ) |
626 | 4 | b_tensor->data.f32[i] = 0.1; |
627 | 101 | for (i = 0; i < 5 * 5 * 4; i++100 ) |
628 | 100 | y_tensor->data.f32[i] = 1; |
629 | 101 | for (i = 0; i < 5 * 5 * 4; i++100 ) |
630 | 100 | y0_tensor->data.f32[i] = 1.2; |
631 | 1 | ccv_nnc_tensor_t* yt = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 5, 5, 4), 0); |
632 | 1 | ccv_nnc_tensor_t* x0t = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 5, 5, 4), 0); |
633 | 1 | memset(x0t->data.f32, 0, sizeof(float) * 5 * 5 * 4); |
634 | 1 | ccv_nnc_tensor_t* x1t = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 5, 5, 4), 0); |
635 | 1 | memcpy(x1t->data.f32, x1_tensor->data.f32, sizeof(float) * 5 * 5 * 4); |
636 | 1 | ccv_nnc_tensor_t* x2t = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 5, 5, 4), 0); |
637 | 1 | ccv_nnc_tensor_t* x3t = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 5, 5, 4), 0); |
638 | 6 | for (i = 0; i < 5; i++5 ) |
639 | 5 | { |
640 | 5 | ccv_nnc_cmd_exec(CMD_CONVOLUTION_FORWARD(1, 4, 3, 3, 4), HINT((1, 1), (1, 1)), 0, TENSOR_LIST(x1t, w_tensor, b_tensor), TENSOR_LIST(yt), 0); |
641 | 505 | for (j = 0; j < 5 * 5 * 4; j++500 ) |
642 | 500 | x3t->data.f32[j] = 1.2 * yt->data.f32[j] + x0t->data.f32[j]; |
643 | 5 | memcpy(x0t->data.f32, x1t->data.f32, sizeof(float) * 5 * 5 * 4); |
644 | 5 | memcpy(x1t->data.f32, x2t->data.f32, sizeof(float) * 5 * 5 * 4); |
645 | 5 | memcpy(x2t->data.f32, x3t->data.f32, sizeof(float) * 5 * 5 * 4); |
646 | 5 | } |
647 | 101 | for (j = 0; j < 5 * 5 * 4; j++100 ) |
648 | 100 | x3t->data.f32[j] += yt->data.f32[j] + x2t->data.f32[j] + x1t->data.f32[j] + x0t->data.f32[j]; |
649 | 1 | ccv_nnc_tensor_t zt = ccv_nnc_tensor(x3t->data.f32, CPU_TENSOR_NHWC(32F, 5 * 5 * 4), 0); |
650 | 1 | ccv_nnc_graph_autotune(graph, 0, 0, TRAVERSE_FULL); |
651 | 1 | ccv_nnc_graph_run(graph, 0, TRAVERSE_FULL, 0, 0); |
652 | 1 | ccv_nnc_tensor_t* z_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, z); |
653 | 1 | REQUIRE_MATRIX_EQ(&zt, z_tensor, "100 vector should be exactly the same"); |
654 | 1 | ccv_nnc_tensor_free(yt); |
655 | 1 | ccv_nnc_tensor_free(x0t); |
656 | 1 | ccv_nnc_tensor_free(x1t); |
657 | 1 | ccv_nnc_tensor_free(x2t); |
658 | 1 | ccv_nnc_tensor_free(x3t); |
659 | 1 | ccv_nnc_symbolic_graph_free(symbolic_graph); |
660 | 1 | ccv_nnc_graph_exec_arena_free(graph_exec_arena); |
661 | 1 | ccv_nnc_tensor_arena_free(tensor_arena); |
662 | 1 | ccv_nnc_graph_free(graph); |
663 | 1 | } |
664 | | |
665 | | #include "case_main.h" |