/home/liu/actions-runner/_work/ccv/ccv/test/unit/nnc/tape.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 <nnc/_ccv_nnc_graph.h> |
8 | | #include <3rdparty/dsfmt/dSFMT.h> |
9 | | |
10 | | TEST_SETUP() |
11 | | { |
12 | | ccv_nnc_init(); |
13 | | } |
14 | | |
15 | | TEST_CASE("new tape from a graph") |
16 | 1 | { |
17 | 1 | ccv_nnc_symbolic_graph_t* symbolic_graph = ccv_nnc_symbolic_graph_new(); |
18 | 1 | ccv_nnc_tensor_symbol_t x = ccv_nnc_tensor_symbol_new(symbolic_graph, CPU_TENSOR_NHWC(32F, 1), "x"); |
19 | 1 | ccv_nnc_tensor_symbol_t y = ccv_nnc_tensor_symbol_new(symbolic_graph, CPU_TENSOR_NHWC(32F, 1), "y"); |
20 | 1 | ccv_nnc_tensor_symbol_t z0 = ccv_nnc_tensor_symbol_new(symbolic_graph, CPU_TENSOR_NHWC(32F, 1), "z0"); |
21 | 1 | ccv_nnc_symbolic_graph_t* while_symbolic_graph = ccv_nnc_symbolic_graph_new(); |
22 | 1 | ccv_nnc_graph_exec_symbol_t while_symbol = ccv_nnc_symbolic_graph_while(symbolic_graph, CCV_NNC_GRAPH_FORWARD, while_symbolic_graph, "for 1..5"); |
23 | 1 | ccv_nnc_tensor_symbol_t z1 = ccv_nnc_tensor_symbol_new(while_symbolic_graph, CPU_TENSOR_NHWC(32F, 1), "z1"); |
24 | 1 | ccv_nnc_graph_exec_symbol_t noop = ccv_nnc_graph_exec_symbol_new(while_symbolic_graph, CMD_NOOP(), 0, 0, 0, 0, "noop"); |
25 | 1 | ccv_nnc_graph_exec_symbol_t prod0 = ccv_nnc_graph_exec_symbol_new(while_symbolic_graph, CMD_EWPROD_FORWARD(), TENSOR_SYMBOL_LIST(z0, x), TENSOR_SYMBOL_LIST(z1), "prod0"); |
26 | 1 | ccv_nnc_graph_exec_symbol_concat(while_symbolic_graph, noop, prod0); |
27 | 1 | ccv_nnc_tensor_symbol_t z2 = ccv_nnc_tensor_symbol_new(symbolic_graph, CPU_TENSOR_NHWC(32F, 1), "z2"); |
28 | 1 | ccv_nnc_tensor_symbol_t z3 = ccv_nnc_tensor_symbol_new(symbolic_graph, CPU_TENSOR_NHWC(32F, 1), "z3"); |
29 | 1 | ccv_nnc_graph_exec_symbol_new(symbolic_graph, CMD_EWPROD_FORWARD(), TENSOR_SYMBOL_LIST(z1, y), TENSOR_SYMBOL_LIST(z2), "prod1"); |
30 | 1 | ccv_nnc_graph_exec_symbol_new(symbolic_graph, CMD_EWSUM_FORWARD(), TENSOR_SYMBOL_LIST(z2, z0), TENSOR_SYMBOL_LIST(z3), "sum"); |
31 | 1 | ccv_nnc_graph_exec_symbol_autogen(symbolic_graph, 0, 0, CCV_NNC_AUTOGEN_ALL_EXECS | CCV_NNC_AUTOGEN_SOURCES_AND_DESTINATIONS); |
32 | 1 | ccv_nnc_symbolic_graph_set_while_expr(while_symbolic_graph, NOOP_GRAPH_WHILE_EXPR, 0, 0, 0, GRAPH_EXEC_SYMBOL_LIST(noop)); |
33 | 1 | ccv_nnc_symbolic_graph_set_carry_overs(while_symbolic_graph, TENSOR_SYMBOL_MAP(KV(z1, z0))); |
34 | 1 | ccv_nnc_symbolic_graph_set_sources(while_symbolic_graph, GRAPH_EXEC_SYMBOL_LIST(noop)); |
35 | 1 | ccv_nnc_symbolic_graph_set_destinations(while_symbolic_graph, GRAPH_EXEC_SYMBOL_LIST(prod0)); |
36 | 1 | ccv_nnc_graph_t* graph = 0; |
37 | 1 | ccv_nnc_tensor_arena_t* tensor_arena = 0; |
38 | 1 | ccv_nnc_graph_exec_arena_t* graph_exec_arena = 0; |
39 | 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); |
40 | 1 | SYMBOLIC_GRAPH_GEN(symbolic_graph, CCV_NNC_LONG_DOT_GRAPH); |
41 | 1 | GRAPH_GEN(graph, CCV_NNC_LONG_DOT_GRAPH); |
42 | 1 | ccv_nnc_symbolic_graph_free(symbolic_graph); |
43 | 1 | ccv_nnc_graph_exec_t while_exec = ccv_nnc_graph_exec_from_symbol(graph_exec_arena, while_symbol); |
44 | 1 | ccv_nnc_graph_t* while_graph = ccv_nnc_graph_from_while_exec(graph, while_exec); |
45 | 1 | ccv_nnc_graph_t* sub_while_graph = ccv_nnc_graph_new(); |
46 | 1 | ccv_nnc_graph_exec_t sub_while_exec = ccv_nnc_graph_while(while_graph, CCV_NNC_GRAPH_FORWARD, sub_while_graph); |
47 | 1 | ccv_nnc_graph_exec_t noop_exec = ccv_nnc_graph_exec_from_symbol(graph_exec_arena, noop); |
48 | 1 | ccv_nnc_graph_exec_concat(while_graph, noop_exec, sub_while_exec); |
49 | 1 | ccv_nnc_tensor_tape_t* tape = ccv_nnc_tensor_tape_new(); |
50 | 1 | ccv_nnc_tensor_t* tensor = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 1), 0); |
51 | 1 | ccv_numeric_data_t data = tensor->data; // Preserve the data field. |
52 | 1 | tensor->type |= CCV_TAPE_ALLOC; |
53 | 1 | ccv_nnc_tensor_tape_io(tape, while_graph, 0, TENSOR_LIST(), 0, TENSOR_LIST(tensor)); |
54 | 1 | REQUIRE(tensor->data.u8 != data.u8, "Tensor should assigned a different memory region with (0, 0)."); |
55 | 1 | tensor->data.f32[0] = 0.32; |
56 | 1 | while_graph->while_count = 2; |
57 | 1 | ccv_nnc_tensor_tape_io(tape, while_graph, 0, TENSOR_LIST(), 0, TENSOR_LIST(tensor)); |
58 | 1 | REQUIRE(tensor->data.u8 != data.u8, "Tensor should assigned a different memory region with (0, 2)."); |
59 | 1 | tensor->data.f32[0] = 0.11; |
60 | 1 | graph->while_count = 1; |
61 | 1 | while_graph->while_count = 1; |
62 | 1 | ccv_nnc_tensor_tape_io(tape, while_graph, 0, TENSOR_LIST(), 0, TENSOR_LIST(tensor)); |
63 | 1 | REQUIRE(tensor->data.u8 != data.u8, "Tensor should assigned a different memory region with (1, 1)."); |
64 | 1 | tensor->data.f32[0] = 0.58; |
65 | 1 | while_graph->while_count = 2; |
66 | 1 | ccv_nnc_tensor_tape_io(tape, while_graph, 0, TENSOR_LIST(), 0, TENSOR_LIST(tensor)); |
67 | 1 | REQUIRE(tensor->data.u8 != data.u8, "Tensor should assigned a different memory region with (1, 2)."); |
68 | 1 | tensor->data.f32[0] = 0.18; |
69 | 1 | graph->while_count = 2; |
70 | 1 | while_graph->while_count = 3; |
71 | 1 | ccv_nnc_tensor_tape_io(tape, while_graph, 0, TENSOR_LIST(), 0, TENSOR_LIST(tensor)); |
72 | 1 | REQUIRE(tensor->data.u8 != data.u8, "Tensor should assigned a different memory region with (2, 3)."); |
73 | 1 | tensor->data.f32[0] = 1.29; |
74 | 1 | while_graph->while_count = 2; |
75 | 1 | ccv_nnc_tensor_tape_io(tape, while_graph, 0, TENSOR_LIST(), 0, TENSOR_LIST(tensor)); |
76 | 1 | REQUIRE(tensor->data.u8 != data.u8, "Tensor should assigned a different memory region with (2, 2)."); |
77 | 1 | tensor->data.f32[0] = 0.02; |
78 | 1 | graph->while_count = 0; |
79 | 1 | while_graph->while_count = 2; |
80 | 1 | ccv_nnc_tensor_tape_io(tape, while_graph, 0, TENSOR_LIST(tensor), 0, TENSOR_LIST()); |
81 | 1 | REQUIRE_EQ_WITH_TOLERANCE(tensor->data.f32[0], 0.11, 1e-5, "Tensor should retain 0.11 with (0, 2)."); |
82 | 1 | graph->while_count = 1; |
83 | 1 | while_graph->while_count = 1; |
84 | 1 | ccv_nnc_tensor_tape_io(tape, while_graph, 0, TENSOR_LIST(tensor), 0, TENSOR_LIST()); |
85 | 1 | REQUIRE_EQ_WITH_TOLERANCE(tensor->data.f32[0], 0.58, 1e-5, "Tensor should retain 0.58 with (1, 1)."); |
86 | 1 | graph->while_count = 0; |
87 | 1 | while_graph->while_count = 0; |
88 | 1 | ccv_nnc_tensor_tape_io(tape, while_graph, 0, TENSOR_LIST(tensor), 0, TENSOR_LIST()); |
89 | 1 | REQUIRE_EQ_WITH_TOLERANCE(tensor->data.f32[0], 0.32, 1e-5, "Tensor should retain 0.32 with (0, 0)."); |
90 | 1 | graph->while_count = 2; |
91 | 1 | while_graph->while_count = 3; |
92 | 1 | ccv_nnc_tensor_tape_io(tape, while_graph, 0, TENSOR_LIST(tensor), 0, TENSOR_LIST()); |
93 | 1 | REQUIRE_EQ_WITH_TOLERANCE(tensor->data.f32[0], 1.29, 1e-5, "Tensor should retain 1.29 with (2, 3)."); |
94 | 1 | graph->while_count = 2; |
95 | 1 | while_graph->while_count = 2; |
96 | 1 | ccv_nnc_tensor_tape_io(tape, while_graph, 0, TENSOR_LIST(tensor), 0, TENSOR_LIST()); |
97 | 1 | REQUIRE_EQ_WITH_TOLERANCE(tensor->data.f32[0], 0.02, 1e-5, "Tensor should retain 0.02 with (2, 2)."); |
98 | 1 | graph->while_count = 1; |
99 | 1 | while_graph->while_count = 2; |
100 | 1 | ccv_nnc_tensor_tape_io(tape, while_graph, 0, TENSOR_LIST(tensor), 0, TENSOR_LIST()); |
101 | 1 | REQUIRE_EQ_WITH_TOLERANCE(tensor->data.f32[0], 0.18, 1e-5, "Tensor should retain 0.02 with (1, 2)."); |
102 | 1 | tensor->data = data; |
103 | | // Verify while count |
104 | 1 | while_graph->while_count = 0; |
105 | 1 | ccv_nnc_tensor_tape_set_numbering(tape, graph, while_exec, 0); |
106 | 1 | while_graph->while_count = 1; |
107 | 1 | ccv_nnc_tensor_tape_set_numbering(tape, graph, while_exec, 1); |
108 | 1 | sub_while_graph->while_count = 1; |
109 | 1 | ccv_nnc_tensor_tape_set_numbering(tape, while_graph, sub_while_exec, 1); |
110 | 1 | sub_while_graph->while_count = 2; |
111 | 1 | ccv_nnc_tensor_tape_set_numbering(tape, while_graph, sub_while_exec, 2); |
112 | 1 | while_graph->while_count = 2; |
113 | 1 | ccv_nnc_tensor_tape_set_numbering(tape, graph, while_exec, 2); |
114 | 1 | sub_while_graph->while_count = 2; |
115 | 1 | ccv_nnc_tensor_tape_set_numbering(tape, while_graph, sub_while_exec, 2); |
116 | 1 | sub_while_graph->while_count = 3; |
117 | 1 | ccv_nnc_tensor_tape_set_numbering(tape, while_graph, sub_while_exec, 3); |
118 | 1 | REQUIRE_EQ(ccv_nnc_tensor_tape_numbering(tape, graph, while_exec), 2, "First while graph should have count to 2"); |
119 | 1 | REQUIRE_EQ(ccv_nnc_tensor_tape_numbering(tape, while_graph, sub_while_exec), 3, "Second while graph should have count to 3"); |
120 | 1 | while_graph->while_count = 1; |
121 | 1 | REQUIRE_EQ(ccv_nnc_tensor_tape_numbering(tape, while_graph, sub_while_exec), 2, "Second while graph should have count to 2"); |
122 | 1 | while_graph->while_count = 3; |
123 | 1 | ccv_nnc_tensor_tape_set_numbering(tape, while_graph, sub_while_exec, 4); |
124 | 1 | REQUIRE_EQ(ccv_nnc_tensor_tape_numbering(tape, while_graph, sub_while_exec), 4, "Second while graph should have count to 4"); |
125 | 1 | ccv_nnc_tensor_tape_set_numbering(tape, graph, while_exec, 3); |
126 | 1 | REQUIRE_EQ(ccv_nnc_tensor_tape_numbering(tape, graph, while_exec), 3, "First while graph should have count to 3"); |
127 | 1 | while_graph->while_count = 2; |
128 | 1 | REQUIRE_EQ(ccv_nnc_tensor_tape_numbering(tape, while_graph, sub_while_exec), 3, "Second while graph should have count to 3"); |
129 | 1 | ccv_nnc_tensor_free(tensor); |
130 | 1 | ccv_nnc_tensor_tape_free(tape); |
131 | 1 | ccv_nnc_tensor_arena_free(tensor_arena); |
132 | 1 | ccv_nnc_graph_exec_arena_free(graph_exec_arena); |
133 | 1 | ccv_nnc_graph_free(graph); |
134 | 1 | } |
135 | | |
136 | | #include "case_main.h" |