/home/liu/actions-runner/_work/ccv/ccv/test/int/nnc/dense.net.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 <inc/ccv_convnet_internal.h> |
8 | | |
9 | | TEST_SETUP() |
10 | | { |
11 | | ccv_nnc_init(); |
12 | | } |
13 | | |
14 | | TEST_CASE("dense net with GEMM as the core") |
15 | 1 | { |
16 | 1 | ccv_nnc_symbolic_graph_t* symbolic_graph = ccv_nnc_symbolic_graph_new(); |
17 | 1 | ccv_nnc_tensor_symbol_t x = ccv_nnc_tensor_symbol_new(symbolic_graph, CPU_TENSOR_NHWC(32F, 1, 4), "x"); |
18 | 1 | ccv_nnc_tensor_symbol_t x1 = ccv_nnc_tensor_symbol_alias_new(symbolic_graph, x, ccv_nnc_no_ofs, DIM_ALLOC(4, 1), CPU_TENSOR_NHWC(32F, 1, 1), "x1"); |
19 | 1 | ccv_nnc_tensor_symbol_t w1 = ccv_nnc_tensor_symbol_new(symbolic_graph, CPU_TENSOR_NHWC(32F, 1, 1), "w1"); |
20 | 1 | ccv_nnc_tensor_symbol_t b1 = ccv_nnc_tensor_symbol_new(symbolic_graph, CPU_TENSOR_NHWC(32F, 1), "b1"); |
21 | 1 | ccv_nnc_tensor_symbol_t x11 = ccv_nnc_tensor_symbol_alias_new(symbolic_graph, x, DIM_ALLOC(0, 1), DIM_ALLOC(4, 1), CPU_TENSOR_NHWC(32F, 1, 1), "x11"); |
22 | 1 | ccv_nnc_graph_exec_symbol_t e1 = ccv_nnc_graph_exec_symbol_new(symbolic_graph, CMD_GEMM_FORWARD(NO_TRANSPOSE, TRANSPOSE(0, 1)), TENSOR_SYMBOL_LIST(x1, w1, b1), TENSOR_SYMBOL_LIST(x11), "e1"); |
23 | 1 | ccv_nnc_tensor_symbol_t x2 = ccv_nnc_tensor_symbol_alias_new(symbolic_graph, x, ccv_nnc_no_ofs, DIM_ALLOC(4, 1), CPU_TENSOR_NHWC(32F, 1, 2), "x2"); |
24 | 1 | ccv_nnc_tensor_symbol_t w2 = ccv_nnc_tensor_symbol_new(symbolic_graph, CPU_TENSOR_NHWC(32F, 1, 2), "w2"); |
25 | 1 | ccv_nnc_tensor_symbol_t b2 = ccv_nnc_tensor_symbol_new(symbolic_graph, CPU_TENSOR_NHWC(32F, 1), "b2"); |
26 | 1 | ccv_nnc_tensor_symbol_t x21 = ccv_nnc_tensor_symbol_alias_new(symbolic_graph, x, DIM_ALLOC(0, 2), DIM_ALLOC(4, 1), CPU_TENSOR_NHWC(32F, 1, 1), "x21"); |
27 | 1 | ccv_nnc_graph_exec_symbol_new(symbolic_graph, CMD_GEMM_FORWARD(NO_TRANSPOSE, TRANSPOSE(0, 1)), TENSOR_SYMBOL_LIST(x2, w2, b2), TENSOR_SYMBOL_LIST(x21), "e2"); |
28 | 1 | ccv_nnc_tensor_symbol_t x3 = ccv_nnc_tensor_symbol_alias_new(symbolic_graph, x, ccv_nnc_no_ofs, DIM_ALLOC(4, 1), CPU_TENSOR_NHWC(32F, 1, 3), "x3"); |
29 | 1 | ccv_nnc_tensor_symbol_t w3 = ccv_nnc_tensor_symbol_new(symbolic_graph, CPU_TENSOR_NHWC(32F, 1, 3), "w3"); |
30 | 1 | ccv_nnc_tensor_symbol_t b3 = ccv_nnc_tensor_symbol_new(symbolic_graph, CPU_TENSOR_NHWC(32F, 1), "b3"); |
31 | 1 | ccv_nnc_tensor_symbol_t x31 = ccv_nnc_tensor_symbol_alias_new(symbolic_graph, x, DIM_ALLOC(0, 3), DIM_ALLOC(4, 1), CPU_TENSOR_NHWC(32F, 1, 1), "x31"); |
32 | 1 | ccv_nnc_graph_exec_symbol_t e3 = ccv_nnc_graph_exec_symbol_new(symbolic_graph, CMD_GEMM_FORWARD(NO_TRANSPOSE, TRANSPOSE(0, 1)), TENSOR_SYMBOL_LIST(x3, w3, b3), TENSOR_SYMBOL_LIST(x31), "e3"); |
33 | 1 | ccv_nnc_graph_exec_symbol_autogen(symbolic_graph, 0, 0, CCV_NNC_AUTOGEN_ALL_EXECS); |
34 | 1 | SYMBOLIC_GRAPH_GEN(symbolic_graph, CCV_NNC_LONG_DOT_GRAPH); |
35 | 1 | ccv_nnc_graph_t* graph = 0; |
36 | 1 | ccv_nnc_tensor_arena_t* tensor_arena = 0; |
37 | 1 | ccv_nnc_graph_exec_arena_t* graph_exec_arena = 0; |
38 | 1 | ccv_nnc_symbolic_graph_compile(symbolic_graph, ccv_nnc_default_compile_params, 0, 0, 0, 0, GRAPH_EXEC_SYMBOL_LIST(e1), GRAPH_EXEC_SYMBOL_LIST(e3), &graph, &tensor_arena, &graph_exec_arena); |
39 | 1 | GRAPH_GEN(graph, CCV_NNC_LONG_DOT_GRAPH); |
40 | 1 | ccv_nnc_tensor_t* x_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, x); |
41 | 1 | ccv_nnc_tensor_t* x1_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, x1); |
42 | 1 | x1_tensor->data.f32[0] = 0.472; |
43 | 1 | ccv_nnc_tensor_t* w1_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, w1); |
44 | 1 | w1_tensor->data.f32[0] = 0.234; |
45 | 1 | ccv_nnc_tensor_t* w2_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, w2); |
46 | 1 | w2_tensor->data.f32[0] = 0.374; |
47 | 1 | w2_tensor->data.f32[1] = 0.886; |
48 | 1 | ccv_nnc_tensor_t* w3_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, w3); |
49 | 1 | w3_tensor->data.f32[0] = 0.484; |
50 | 1 | w3_tensor->data.f32[1] = 0.912; |
51 | 1 | w3_tensor->data.f32[2] = 0.235; |
52 | 1 | ccv_nnc_tensor_t* b1_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, b1); |
53 | 1 | b1_tensor->data.f32[0] = 0.1; |
54 | 1 | ccv_nnc_tensor_t* b2_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, b2); |
55 | 1 | b2_tensor->data.f32[0] = 0.2; |
56 | 1 | ccv_nnc_tensor_t* b3_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, b3); |
57 | 1 | b3_tensor->data.f32[0] = 0.3; |
58 | 1 | ccv_nnc_graph_run(graph, 0, GRAPH_EXEC_LIST(ccv_nnc_graph_exec_source(graph_exec_arena)), GRAPH_EXEC_LIST(ccv_nnc_graph_exec_destination(graph_exec_arena)), 0, 0); |
59 | 1 | ccv_nnc_graph_free(graph); |
60 | 1 | ccv_nnc_tensor_t* xt = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 1, 4), 0); |
61 | 1 | xt->data.f32[0] = 0.472; |
62 | 1 | xt->data.f32[1] = xt->data.f32[0] * 0.234 + 0.1; |
63 | 1 | xt->data.f32[2] = xt->data.f32[0] * 0.374 + xt->data.f32[1] * 0.886 + 0.2; |
64 | 1 | xt->data.f32[3] = xt->data.f32[0] * 0.484 + xt->data.f32[1] * 0.912 + xt->data.f32[2] * 0.235 + 0.3; |
65 | 1 | REQUIRE_MATRIX_EQ(x_tensor, xt, "1x4 matrix should be exactly the same"); |
66 | 1 | ccv_nnc_tensor_free(xt); |
67 | 1 | ccv_nnc_tensor_arena_free(tensor_arena); |
68 | 1 | ccv_nnc_graph_exec_arena_free(graph_exec_arena); |
69 | 1 | ccv_nnc_symbolic_graph_free(symbolic_graph); |
70 | 1 | } |
71 | | |
72 | | TEST_CASE("dense net with GEMM as the core and autograd") |
73 | 1 | { |
74 | 1 | ccv_nnc_symbolic_graph_t* symbolic_graph = ccv_nnc_symbolic_graph_new(); |
75 | 1 | ccv_nnc_tensor_symbol_t x = ccv_nnc_tensor_symbol_new(symbolic_graph, CPU_TENSOR_NHWC(32F, 1, 4), "x"); |
76 | 1 | ccv_nnc_tensor_symbol_t x1 = ccv_nnc_tensor_symbol_alias_new(symbolic_graph, x, ccv_nnc_no_ofs, DIM_ALLOC(4, 1), CPU_TENSOR_NHWC(32F, 1, 1), "x1"); |
77 | 1 | ccv_nnc_tensor_symbol_t w1 = ccv_nnc_tensor_symbol_new(symbolic_graph, CPU_TENSOR_NHWC(32F, 1, 1), "w1"); |
78 | 1 | ccv_nnc_tensor_symbol_t b1 = ccv_nnc_tensor_symbol_new(symbolic_graph, CPU_TENSOR_NHWC(32F, 1), "b1"); |
79 | 1 | ccv_nnc_tensor_symbol_t x11 = ccv_nnc_tensor_symbol_alias_new(symbolic_graph, x, DIM_ALLOC(0, 1), DIM_ALLOC(4, 1), CPU_TENSOR_NHWC(32F, 1, 1), "x11"); |
80 | 1 | ccv_nnc_graph_exec_symbol_t e1 = ccv_nnc_graph_exec_symbol_new(symbolic_graph, CMD_GEMM_FORWARD(NO_TRANSPOSE, TRANSPOSE(0, 1)), TENSOR_SYMBOL_LIST(x1, w1, b1), TENSOR_SYMBOL_LIST(x11), "e1"); |
81 | 1 | ccv_nnc_tensor_symbol_t x2 = ccv_nnc_tensor_symbol_alias_new(symbolic_graph, x, ccv_nnc_no_ofs, DIM_ALLOC(4, 1), CPU_TENSOR_NHWC(32F, 1, 2), "x2"); |
82 | 1 | ccv_nnc_tensor_symbol_t w2 = ccv_nnc_tensor_symbol_new(symbolic_graph, CPU_TENSOR_NHWC(32F, 1, 2), "w2"); |
83 | 1 | ccv_nnc_tensor_symbol_t b2 = ccv_nnc_tensor_symbol_new(symbolic_graph, CPU_TENSOR_NHWC(32F, 1), "b2"); |
84 | 1 | ccv_nnc_tensor_symbol_t x21 = ccv_nnc_tensor_symbol_alias_new(symbolic_graph, x, DIM_ALLOC(0, 2), DIM_ALLOC(4, 1), CPU_TENSOR_NHWC(32F, 1, 1), "x21"); |
85 | 1 | ccv_nnc_graph_exec_symbol_new(symbolic_graph, CMD_GEMM_FORWARD(NO_TRANSPOSE, TRANSPOSE(0, 1)), TENSOR_SYMBOL_LIST(x2, w2, b2), TENSOR_SYMBOL_LIST(x21), "e2"); |
86 | 1 | ccv_nnc_tensor_symbol_t x3 = ccv_nnc_tensor_symbol_alias_new(symbolic_graph, x, ccv_nnc_no_ofs, DIM_ALLOC(4, 1), CPU_TENSOR_NHWC(32F, 1, 3), "x3"); |
87 | 1 | ccv_nnc_tensor_symbol_t w3 = ccv_nnc_tensor_symbol_new(symbolic_graph, CPU_TENSOR_NHWC(32F, 1, 3), "w3"); |
88 | 1 | ccv_nnc_tensor_symbol_t b3 = ccv_nnc_tensor_symbol_new(symbolic_graph, CPU_TENSOR_NHWC(32F, 1), "b3"); |
89 | 1 | ccv_nnc_tensor_symbol_t x31 = ccv_nnc_tensor_symbol_alias_new(symbolic_graph, x, DIM_ALLOC(0, 3), DIM_ALLOC(4, 1), CPU_TENSOR_NHWC(32F, 1, 1), "x31"); |
90 | 1 | ccv_nnc_tensor_symbol_t y = ccv_nnc_tensor_symbol_new(symbolic_graph, CPU_TENSOR_NHWC(32F, 1, 1), "y"); |
91 | 1 | ccv_nnc_graph_exec_symbol_new(symbolic_graph, CMD_GEMM_FORWARD(NO_TRANSPOSE, TRANSPOSE(0, 1)), TENSOR_SYMBOL_LIST(x3, w3, b3), TENSOR_SYMBOL_LIST(x31), "e3"); |
92 | 1 | ccv_nnc_graph_exec_symbol_t e4 = ccv_nnc_graph_exec_symbol_new(symbolic_graph, CMD_DATA_TRANSFER_FORWARD(), TENSOR_SYMBOL_LIST(x31), TENSOR_SYMBOL_LIST(y), "e4"); |
93 | 1 | ccv_nnc_graph_exec_symbol_autogen(symbolic_graph, 0, 0, CCV_NNC_AUTOGEN_ALL_EXECS); |
94 | 1 | ccv_nnc_symbolic_graph_backward(symbolic_graph, TENSOR_SYMBOL_LIST(y), TENSOR_SYMBOL_LIST(w1), GRAPH_EXEC_SYMBOL_LIST(e1), GRAPH_EXEC_SYMBOL_LIST(e4)); |
95 | 1 | ccv_nnc_tensor_symbol_t dw1 = ccv_nnc_tensor_symbol_for_backward(symbolic_graph, w1); |
96 | 1 | ccv_nnc_graph_exec_symbol_t de1 = ccv_nnc_graph_exec_symbol_for_backward(symbolic_graph, dw1); |
97 | 1 | ccv_nnc_symbolic_graph_simplify(symbolic_graph, |
98 | 1 | SYMBOLIC_GRAPH_PASSES(CCV_NNC_SIMPLIFY_COMMON_SUBEXPRESSION_ELIMINATION, CCV_NNC_SIMPLIFY_GRAPH_PRUNING), |
99 | 1 | 0, 0, |
100 | 1 | TENSOR_SYMBOL_LIST(dw1), GRAPH_EXEC_SYMBOL_LIST(e1), GRAPH_EXEC_SYMBOL_LIST(de1)); |
101 | 1 | ccv_nnc_graph_exec_symbol_autogen(symbolic_graph, 0, 0, CCV_NNC_AUTOGEN_SOURCES_AND_DESTINATIONS); |
102 | 1 | SYMBOLIC_GRAPH_GEN(symbolic_graph, CCV_NNC_LONG_DOT_GRAPH); |
103 | 1 | ccv_nnc_graph_t* graph = 0; |
104 | 1 | ccv_nnc_tensor_arena_t* tensor_arena = 0; |
105 | 1 | ccv_nnc_graph_exec_arena_t* graph_exec_arena = 0; |
106 | 1 | ccv_nnc_tensor_symbol_t dy = ccv_nnc_tensor_symbol_for_backward(symbolic_graph, y); |
107 | 1 | ccv_nnc_tensor_t* dy_tensor = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 1), 0); |
108 | 1 | dy_tensor->data.f32[0] = 1; |
109 | 1 | ccv_nnc_symbolic_graph_compile(symbolic_graph, ccv_nnc_default_compile_params, TENSOR_BIND_MAP(KV(dy, dy_tensor)), 0, 0, GRAPH_EXEC_SYMBOL_LIST(e1), GRAPH_EXEC_SYMBOL_LIST(de1), &graph, &tensor_arena, &graph_exec_arena); |
110 | 1 | GRAPH_GEN(graph, CCV_NNC_LONG_DOT_GRAPH); |
111 | 1 | ccv_nnc_tensor_t* x1_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, x1); |
112 | 1 | x1_tensor->data.f32[0] = 0.472; |
113 | 1 | ccv_nnc_tensor_t* w1_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, w1); |
114 | 1 | w1_tensor->data.f32[0] = 0.234; |
115 | 1 | ccv_nnc_tensor_t* w2_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, w2); |
116 | 1 | w2_tensor->data.f32[0] = 0.374; |
117 | 1 | w2_tensor->data.f32[1] = 0.886; |
118 | 1 | ccv_nnc_tensor_t* w3_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, w3); |
119 | 1 | w3_tensor->data.f32[0] = 0.484; |
120 | 1 | w3_tensor->data.f32[1] = 0.912; |
121 | 1 | w3_tensor->data.f32[2] = 0.235; |
122 | 1 | ccv_nnc_tensor_t* b1_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, b1); |
123 | 1 | b1_tensor->data.f32[0] = 0.1; |
124 | 1 | ccv_nnc_tensor_t* b2_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, b2); |
125 | 1 | b2_tensor->data.f32[0] = 0.2; |
126 | 1 | ccv_nnc_tensor_t* b3_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, b3); |
127 | 1 | b3_tensor->data.f32[0] = 0.3; |
128 | 1 | ccv_nnc_graph_run(graph, 0, GRAPH_EXEC_LIST(ccv_nnc_graph_exec_source(graph_exec_arena)), GRAPH_EXEC_LIST(ccv_nnc_graph_exec_destination(graph_exec_arena)), 0, 0); |
129 | 1 | ccv_nnc_graph_free(graph); |
130 | 1 | ccv_nnc_tensor_t* dw1_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, dw1); |
131 | 1 | REQUIRE_EQ_WITH_TOLERANCE((0.235 * 0.886 + 0.912) * 0.472, dw1_tensor->data.f32[0], 1e-5, "the gradient should be equal to a complicated result"); |
132 | 1 | ccv_nnc_tensor_free(dy_tensor); |
133 | 1 | ccv_nnc_tensor_arena_free(tensor_arena); |
134 | 1 | ccv_nnc_graph_exec_arena_free(graph_exec_arena); |
135 | 1 | ccv_nnc_symbolic_graph_free(symbolic_graph); |
136 | 1 | } |
137 | | |
138 | | #include "case_main.h" |