## Coverage Report

#### Created: 2026-05-04 15:30

next uncovered line (L), next uncovered region (R), next uncovered branch (B)

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