/home/liu/actions-runner/_work/ccv/ccv/test/unit/nnc/gelu.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 | | TEST_CASE("compare fast GELU gradient with fine-grained symbolic graph") |
15 | 1 | { |
16 | 1 | ccv_nnc_symbolic_graph_t* const symbolic_graph = ccv_nnc_symbolic_graph_new(); |
17 | 1 | const ccv_nnc_tensor_symbol_t x = ccv_nnc_tensor_symbol_new(symbolic_graph, CPU_TENSOR_NHWC(32F, 10), "x"); |
18 | 1 | const ccv_nnc_tensor_symbol_t x_sq = ccv_nnc_tensor_symbol_new(symbolic_graph, CPU_TENSOR_NHWC(32F, 10), "x_sq"); |
19 | 1 | const ccv_nnc_tensor_symbol_t x_cube = ccv_nnc_tensor_symbol_new(symbolic_graph, CPU_TENSOR_NHWC(32F, 10), "x_cube"); |
20 | 1 | const ccv_nnc_tensor_symbol_t x_sum = ccv_nnc_tensor_symbol_new(symbolic_graph, CPU_TENSOR_NHWC(32F, 10), "x_sum"); |
21 | 1 | const ccv_nnc_tensor_symbol_t beta_x_sum = ccv_nnc_tensor_symbol_new(symbolic_graph, CPU_TENSOR_NHWC(32F, 10), "beta_x_sum"); |
22 | 1 | const ccv_nnc_tensor_symbol_t one = ccv_nnc_tensor_symbol_new(symbolic_graph, CPU_TENSOR_NHWC(32F, 10), "one"); |
23 | 1 | const ccv_nnc_tensor_symbol_t tanh = ccv_nnc_tensor_symbol_new(symbolic_graph, ccv_nnc_tensor_auto, "tanh"); |
24 | 1 | const ccv_nnc_tensor_symbol_t tanh_1 = ccv_nnc_tensor_symbol_new(symbolic_graph, ccv_nnc_tensor_auto, "1_tanh"); |
25 | 1 | const ccv_nnc_tensor_symbol_t y = ccv_nnc_tensor_symbol_new(symbolic_graph, ccv_nnc_tensor_auto, "y"); |
26 | 1 | ccv_nnc_graph_exec_symbol_new(symbolic_graph, CMD_SET_FORWARD(1), TENSOR_SYMBOL_LIST(), TENSOR_SYMBOL_LIST(one), "one"); |
27 | 1 | ccv_nnc_graph_exec_symbol_new(symbolic_graph, CMD_MUL_FORWARD(1), TENSOR_SYMBOL_LIST(x, x), TENSOR_SYMBOL_LIST(x_sq), "x_sq"); |
28 | 1 | ccv_nnc_graph_exec_symbol_new(symbolic_graph, CMD_MUL_FORWARD(0.044715), TENSOR_SYMBOL_LIST(x_sq, x), TENSOR_SYMBOL_LIST(x_cube), "x_cube"); |
29 | 1 | ccv_nnc_graph_exec_symbol_new(symbolic_graph, CMD_ADD_FORWARD(1, 1), TENSOR_SYMBOL_LIST(x, x_cube), TENSOR_SYMBOL_LIST(x_sum), "x_sum"); |
30 | 1 | ccv_nnc_graph_exec_symbol_new(symbolic_graph, CMD_SCALAR_MUL_FORWARD(0.797884560802865355), TENSOR_SYMBOL_LIST(x_sum), TENSOR_SYMBOL_LIST(beta_x_sum), "beta_x_sum"); |
31 | 1 | ccv_nnc_graph_exec_symbol_new(symbolic_graph, CMD_TANH_FORWARD(), TENSOR_SYMBOL_LIST(beta_x_sum), TENSOR_SYMBOL_LIST(tanh), "tanh"); |
32 | 1 | ccv_nnc_graph_exec_symbol_new(symbolic_graph, CMD_ADD_FORWARD(1, 1), TENSOR_SYMBOL_LIST(tanh, one), TENSOR_SYMBOL_LIST(tanh_1), "tanh_1"); |
33 | 1 | ccv_nnc_graph_exec_symbol_new(symbolic_graph, CMD_MUL_FORWARD(0.5), TENSOR_SYMBOL_LIST(x, tanh_1), TENSOR_SYMBOL_LIST(y), "y"); |
34 | 1 | ccv_nnc_graph_exec_symbol_autogen(symbolic_graph, 0, 0, CCV_NNC_AUTOGEN_ALL_EXECS | CCV_NNC_AUTOGEN_SOURCES_AND_DESTINATIONS); |
35 | 1 | SYMBOLIC_GRAPH_GEN(symbolic_graph, CCV_NNC_LONG_DOT_GRAPH); |
36 | 1 | ccv_nnc_symbolic_graph_backward(symbolic_graph, TENSOR_SYMBOL_LIST(y), TENSOR_SYMBOL_LIST(x), SYMBOLIC_GRAPH_SOURCES(symbolic_graph), SYMBOLIC_GRAPH_DESTINATIONS(symbolic_graph)); |
37 | 1 | ccv_nnc_graph_exec_symbol_autogen(symbolic_graph, 0, 0, CCV_NNC_AUTOGEN_ALL_EXECS | CCV_NNC_AUTOGEN_SOURCES_AND_DESTINATIONS); |
38 | 1 | const ccv_nnc_tensor_symbol_t dx = ccv_nnc_tensor_symbol_for_backward(symbolic_graph, x); |
39 | 1 | const ccv_nnc_tensor_symbol_t dy = ccv_nnc_tensor_symbol_for_backward(symbolic_graph, y); |
40 | 1 | ccv_nnc_graph_t* graph = 0; |
41 | 1 | ccv_nnc_tensor_arena_t* tensor_arena = 0; |
42 | 1 | ccv_nnc_graph_exec_arena_t* graph_exec_arena = 0; |
43 | 1 | ccv_nnc_symbolic_graph_compile(symbolic_graph, ccv_nnc_default_compile_params, |
44 | 1 | 0, 0, TENSOR_SYMBOL_LIST(y, dx), |
45 | 1 | SYMBOLIC_GRAPH_SOURCES(symbolic_graph), SYMBOLIC_GRAPH_DESTINATIONS(symbolic_graph), |
46 | 1 | &graph, &tensor_arena, &graph_exec_arena); |
47 | 1 | GRAPH_GEN(graph, CCV_NNC_LONG_DOT_GRAPH); |
48 | 1 | ccv_nnc_tensor_t* const x_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, x); |
49 | 1 | dsfmt_t dsfmt; |
50 | 1 | int i; |
51 | 1 | dsfmt_init_gen_rand(&dsfmt, 1); |
52 | 11 | for (i = 0; i < 10; i++10 ) |
53 | 10 | x_tensor->data.f32[i] = dsfmt_genrand_open_close(&dsfmt); |
54 | 1 | ccv_nnc_symbolic_graph_t* const swish_symbolic_graph = ccv_nnc_symbolic_graph_new(); |
55 | 1 | ccv_nnc_tensor_symbol_t sx = ccv_nnc_tensor_symbol_new(swish_symbolic_graph, CPU_TENSOR_NHWC(32F, 10), "x"); |
56 | 1 | ccv_nnc_tensor_symbol_t sy = ccv_nnc_tensor_symbol_new(swish_symbolic_graph, ccv_nnc_tensor_auto, "y"); |
57 | 1 | ccv_nnc_graph_exec_symbol_new(swish_symbolic_graph, CMD_GELU_FORWARD(1), TENSOR_SYMBOL_LIST(sx), TENSOR_SYMBOL_LIST(sy), "gelu"); |
58 | 1 | ccv_nnc_graph_exec_symbol_autogen(swish_symbolic_graph, 0, 0, CCV_NNC_AUTOGEN_ALL_EXECS | CCV_NNC_AUTOGEN_SOURCES_AND_DESTINATIONS); |
59 | 1 | SYMBOLIC_GRAPH_GEN(swish_symbolic_graph, CCV_NNC_LONG_DOT_GRAPH); |
60 | 1 | ccv_nnc_symbolic_graph_backward(swish_symbolic_graph, TENSOR_SYMBOL_LIST(sy), TENSOR_SYMBOL_LIST(sx), SYMBOLIC_GRAPH_SOURCES(swish_symbolic_graph), SYMBOLIC_GRAPH_DESTINATIONS(swish_symbolic_graph)); |
61 | 1 | ccv_nnc_graph_exec_symbol_autogen(swish_symbolic_graph, 0, 0, CCV_NNC_AUTOGEN_ALL_EXECS | CCV_NNC_AUTOGEN_SOURCES_AND_DESTINATIONS); |
62 | 1 | const ccv_nnc_tensor_symbol_t sdx = ccv_nnc_tensor_symbol_for_backward(swish_symbolic_graph, sx); |
63 | 1 | const ccv_nnc_tensor_symbol_t sdy = ccv_nnc_tensor_symbol_for_backward(swish_symbolic_graph, sy); |
64 | 1 | ccv_nnc_graph_t* swish_graph = 0; |
65 | 1 | ccv_nnc_tensor_arena_t* swish_tensor_arena = 0; |
66 | 1 | ccv_nnc_graph_exec_arena_t* swish_graph_exec_arena = 0; |
67 | 1 | ccv_nnc_symbolic_graph_compile(swish_symbolic_graph, ccv_nnc_default_compile_params, |
68 | 1 | 0, 0, TENSOR_SYMBOL_LIST(sy, sdx), |
69 | 1 | SYMBOLIC_GRAPH_SOURCES(swish_symbolic_graph), SYMBOLIC_GRAPH_DESTINATIONS(swish_symbolic_graph), |
70 | 1 | &swish_graph, &swish_tensor_arena, &swish_graph_exec_arena); |
71 | 1 | ccv_nnc_tensor_t* const sx_tensor = ccv_nnc_tensor_from_symbol(swish_tensor_arena, sx); |
72 | 1 | memcpy(sx_tensor->data.f32, x_tensor->data.f32, sizeof(float) * 10); |
73 | 1 | ccv_nnc_tensor_t* const dy_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, dy); |
74 | 1 | ccv_nnc_tensor_t* const sdy_tensor = ccv_nnc_tensor_from_symbol(swish_tensor_arena, sdy); |
75 | 11 | for (i = 0; i < 10; i++10 ) |
76 | 10 | sdy_tensor->data.f32[i] = dy_tensor->data.f32[i] = dsfmt_genrand_open_close(&dsfmt) * 2 - 1; |
77 | 1 | ccv_nnc_graph_run(graph, 0, TRAVERSE_FULL, 0, 0); |
78 | 1 | ccv_nnc_graph_run(swish_graph, 0, TRAVERSE_FULL, 0, 0); |
79 | 1 | ccv_nnc_tensor_t* const y_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, y); |
80 | 1 | ccv_nnc_tensor_t* const sy_tensor = ccv_nnc_tensor_from_symbol(swish_tensor_arena, sy); |
81 | 1 | REQUIRE_TENSOR_EQ(y_tensor, sy_tensor, "graph computed result should match swish op result"); |
82 | 1 | ccv_nnc_tensor_t* const dx_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, dx); |
83 | 1 | ccv_nnc_tensor_t* const sdx_tensor = ccv_nnc_tensor_from_symbol(swish_tensor_arena, sdx); |
84 | 1 | REQUIRE_TENSOR_EQ(dx_tensor, sdx_tensor, "gradient computed result should match swish op result"); |
85 | 1 | ccv_nnc_symbolic_graph_free(symbolic_graph); |
86 | 1 | ccv_nnc_tensor_arena_free(tensor_arena); |
87 | 1 | ccv_nnc_graph_exec_arena_free(graph_exec_arena); |
88 | 1 | ccv_nnc_graph_free(graph); |
89 | 1 | ccv_nnc_symbolic_graph_free(swish_symbolic_graph); |
90 | 1 | ccv_nnc_tensor_arena_free(swish_tensor_arena); |
91 | 1 | ccv_nnc_graph_exec_arena_free(swish_graph_exec_arena); |
92 | 1 | ccv_nnc_graph_free(swish_graph); |
93 | 1 | } |
94 | | |
95 | | #include "case_main.h" |