Coverage Report

Created: 2024-08-19 11:27

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