## 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/unit/nnc/smooth_l1.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
    8
    TEST_SETUP()
    9
    {
    10
      ccv_nnc_init();
    11
    }
    12
    13
    TEST_CASE("compare smooth L1")
    14
    1
    {
    15
    1
      ccv_nnc_symbolic_graph_t* const graph = ccv_nnc_symbolic_graph_new();
    16
      // batch size = 2, dim = 3.
    17
    1
      const ccv_nnc_tensor_symbol_t a = ccv_nnc_tensor_symbol_new(graph, CPU_TENSOR_NHWC(32F, 2, 3), "a");
    18
    1
      const ccv_nnc_tensor_symbol_t label = ccv_nnc_tensor_symbol_new(graph, CPU_TENSOR_NHWC(32F, 2, 3), "label");
    19
    1
      const ccv_nnc_tensor_symbol_t loss0 = ccv_nnc_tensor_symbol_new(graph, ccv_nnc_tensor_auto, "loss0");
    20
    1
      ccv_nnc_graph_exec_symbol_new(graph, CMD_SMOOTH_L1_FORWARD(1), TENSOR_SYMBOL_LIST(a, label), TENSOR_SYMBOL_LIST(loss0), "smooth l1");
    21
    1
      ccv_nnc_graph_exec_symbol_autogen(graph, 0, 0, CCV_NNC_AUTOGEN_ALL_EXECS | CCV_NNC_AUTOGEN_SOURCES_AND_DESTINATIONS);
    22
    1
      ccv_nnc_symbolic_graph_backward(graph, TENSOR_SYMBOL_LIST(loss0), TENSOR_SYMBOL_LIST(a), SYMBOLIC_GRAPH_SOURCES(graph), SYMBOLIC_GRAPH_DESTINATIONS(graph));
    23
    1
      const ccv_nnc_tensor_symbol_t dloss0 = ccv_nnc_tensor_symbol_for_backward(graph, loss0);
    24
    1
      const ccv_nnc_tensor_symbol_t da0 = ccv_nnc_tensor_symbol_for_backward(graph, a);
    25
    1
      ccv_nnc_graph_exec_symbol_new(graph, CMD_SET_FORWARD(1), 0, 0, TENSOR_SYMBOL_LIST(dloss0), "set 1");
    26
    1
      ccv_nnc_graph_exec_symbol_autogen(graph, 0, 0, CCV_NNC_AUTOGEN_ALL_EXECS | CCV_NNC_AUTOGEN_SOURCES_AND_DESTINATIONS);
    27
    1
      SYMBOLIC_GRAPH_GEN(graph, CCV_NNC_LONG_DOT_GRAPH);
    28
    1
      ccv_nnc_graph_t* run_graph;
    29
    1
      ccv_nnc_tensor_arena_t* tensor_arena;
    30
    1
      ccv_nnc_graph_exec_arena_t* graph_exec_arena;
    31
    1
      ccv_nnc_symbolic_graph_compile(graph, ccv_nnc_default_compile_params,
    32
    1
        0, 0,
    33
    1
        TENSOR_SYMBOL_LIST(da0, loss0),
    34
    1
        SYMBOLIC_GRAPH_SOURCES(graph), SYMBOLIC_GRAPH_DESTINATIONS(graph),
    35
    1
        &run_graph, &tensor_arena, &graph_exec_arena);
    36
    1
      ccv_nnc_tensor_t* const a_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, a);
    37
    1
      a_tensor->data.f32[0] = -0.0001;
    38
    1
      a_tensor->data.f32[1] = 1;
    39
    1
      a_tensor->data.f32[2] = -1;
    40
    1
      a_tensor->data.f32[3] = -0.5;
    41
    1
      a_tensor->data.f32[4] = 0.4;
    42
    1
      a_tensor->data.f32[5] = 0;
    43
    1
      ccv_nnc_tensor_t* const label_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, label);
    44
    1
      label_tensor->data.f32[0] = 0;
    45
    1
      label_tensor->data.f32[1] = 0;
    46
    1
      label_tensor->data.f32[2] = 0;
    47
    1
      label_tensor->data.f32[3] = 0;
    48
    1
      label_tensor->data.f32[4] = 0;
    49
    1
      label_tensor->data.f32[5] = 0;
    50
    1
      ccv_nnc_graph_run(run_graph, 0, TRAVERSE_FULL, 0, 0);
    51
    1
      ccv_nnc_tensor_t* const da0_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, da0);
    52
    1
      ccv_nnc_tensor_t* const da1_tensor = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 2, 3), 0);
    53
    1
      da1_tensor->data.f32[0] = -1;
    54
    1
      da1_tensor->data.f32[1] = 1;
    55
    1
      da1_tensor->data.f32[2] = -1;
    56
    1
      da1_tensor->data.f32[3] = -0.5;
    57
    1
      da1_tensor->data.f32[4] = 0.4;
    58
    1
      da1_tensor->data.f32[5] = 0;
    59
    1
      REQUIRE_TENSOR_EQ(da0_tensor, da1_tensor, "two tensors from combined op and separate ops should be equal");
    60
    1
      ccv_nnc_tensor_t* const loss0_tensor = ccv_nnc_tensor_from_symbol(tensor_arena, loss0);
    61
    1
      ccv_nnc_tensor_t* const loss1_tensor = ccv_nnc_tensor_new(0, CPU_TENSOR_NHWC(32F, 2, 1), 0);
    62
    1
      loss1_tensor->data.f32[0] = 1.5001;
    63
    1
      loss1_tensor->data.f32[1] = 0.205;
    64
    1
      REQUIRE_TENSOR_EQ(loss0_tensor, loss1_tensor, "two tensors from combined op and separate ops should be equal");
    65
    1
      ccv_nnc_graph_free(run_graph);
    66
    1
      ccv_nnc_tensor_arena_free(tensor_arena);
    67
    1
      ccv_nnc_graph_exec_arena_free(graph_exec_arena);
    68
    1
      ccv_nnc_symbolic_graph_free(graph);
    69
    1
      ccv_nnc_tensor_free(da1_tensor);
    70
    1
      ccv_nnc_tensor_free(loss1_tensor);
    71
    1
    }
    72
    73
    #include "case_main.h"