## 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/lib/nnc/ccv_nnc_symbolic_graph_minimize.c

    Line
    Count
    Source
    1
    #include "ccv_nnc.h"
    2
    #include "ccv_nnc_easy.h"
    3
    #include "ccv_nnc_internal.h"
    4
    #include "ccv_internal.h"
    5
    #include "_ccv_nnc_symbolic_graph.h"
    6
    7
    // MARK - Level-3.5 API
    8
    9
    int ccv_nnc_minimizer_saved_aux_size(const ccv_nnc_cmd_t minimizer)
    10
    12.4k
    {
    11
    12.4k
      int i, aux_size = -1;
    12
    12.4k
      uint64_t input_bitmask = 0x1;
    13
    12.4k
      uint64_t output_bitmask = 0x0;
    14
    37.0k
      for (i = 0; i < 62 && aux_size < 0; i++24.6k)
    15
    24.6k
      {
    16
    24.6k
        input_bitmask |= ((uint64_t)1 << (i + 1));
    17
    24.6k
        output_bitmask |= ((uint64_t)1 << i);
    18
    24.6k
        if (ccv_nnc_cmd_bitmask(minimizer, i + 2, i + 1, &input_bitmask, 1, &output_bitmask, 1))
    19
    12.4k
          aux_size = i;
    20
    24.6k
      }
    21
    12.4k
      return aux_size;
    22
    12.4k
    }
    23
    24
    void ccv_nnc_symbolic_graph_minimize(ccv_nnc_symbolic_graph_t* const graph, const ccv_nnc_cmd_t minimizer, const ccv_nnc_tensor_symbol_t* const losses, const int loss_size, const ccv_nnc_tensor_symbol_t* const parameters, const int parameter_size, const ccv_nnc_tensor_symbol_t* const inputs, const int input_size, const ccv_nnc_graph_exec_symbol_t* const sources, const int source_size, const ccv_nnc_graph_exec_symbol_t* const destinations, const int destination_size, ccv_nnc_tensor_symbol_t* const gradients, ccv_nnc_tensor_symbol_t* const updated_parameters, ccv_nnc_tensor_symbol_map_t* const saved_aux, ccv_nnc_graph_exec_symbol_t* const graph_exec_symbols)
    25
    3.25k
    {
    26
    3.25k
      assert(parameter_size >= 0);
    27
    3.25k
      assert(loss_size > 0);
    28
    3.25k
      assert((inputs && input_size > 0) || (inputs == 0 && input_size <= 0));
    29
    3.25k
      int i, j;
    30
      // First, compute gradient.
    31
    3.25k
      if (inputs)
    32
    2.23k
      {
    33
    2.23k
        ccv_nnc_tensor_symbol_t* const ingrads = gradients ? gradients : ccmalloc0(sizeof(ccv_nnc_tensor_symbol_t) * (parameter_size + input_size))0;
    34
    2.23k
        if (parameter_size > 0)
    35
    2.23k
          memcpy(ingrads, parameters, sizeof(ccv_nnc_tensor_symbol_t) * parameter_size);
    36
    2.23k
        memcpy(ingrads + parameter_size, inputs, sizeof(ccv_nnc_tensor_symbol_t) * input_size);
    37
        // Parameters wont, but inputs might be zero length.
    38
    4.49k
        for (i = parameter_size; i < parameter_size + input_size; i++2.25k)
    39
    2.25k
          if (ingrads[i].d >= 0)
    40
    2.25k
          {
    41
    2.25k
            const ccv_nnc_tensor_param_t params = ccv_nnc_tensor_symbol_params(graph, ingrads[i]);
    42
    2.25k
            if (params.dim[0] == 0)
    43
    0
              ingrads[i] = NO_TENSOR_SYMBOL;
    44
    2.25k
          }
    45
    2.23k
        ccv_nnc_symbolic_graph_backward(graph, losses, loss_size, ingrads, parameter_size + input_size, sources, source_size, destinations, destination_size);
    46
    2.23k
        if (ingrads != gradients)
    47
    0
          ccfree(ingrads);
    48
    2.23k
      } else if (1.02kparameter_size > 01.02k)
    49
    1.02k
        ccv_nnc_symbolic_graph_backward(graph, losses, loss_size, parameters, parameter_size, sources, source_size, destinations, destination_size);
    50
      // At most the minimizer accepts 62 additional parameters.
    51
    3.25k
      const int aux_size = ccv_nnc_minimizer_saved_aux_size(minimizer);
    52
    3.25k
      assert(aux_size >= 0);
    53
    3.25k
      ccv_nnc_tensor_symbol_t update_inputs[aux_size + 2];
    54
    3.25k
      ccv_nnc_tensor_symbol_t update_outputs[aux_size + 1];
    55
    6.95k
      for (i = 0; i < parameter_size; i++3.69k)
    56
    3.69k
        if (parameters[i].d >= 0)
    57
    3.68k
        {
    58
    3.68k
          const ccv_nnc_tensor_symbol_t gradient = ccv_nnc_tensor_symbol_for_backward(graph, parameters[i]);
    59
    3.68k
          if (gradients)
    60
    2.67k
            gradients[i] = gradient;
    61
    3.68k
          const ccv_nnc_graph_exec_symbol_t graph_exec = ccv_nnc_graph_exec_symbol_for_backward(graph, gradient);
    62
    3.68k
          update_inputs[0] = gradient;
    63
    3.68k
          update_inputs[1] = parameters[i];
    64
    3.68k
          const ccv_nnc_tensor_param_t info = ccv_nnc_tensor_symbol_params(graph, update_inputs[1]);
    65
    3.68k
          update_outputs[0] = updated_parameters[i] = ccv_nnc_tensor_symbol_new(graph, info, 0);
    66
    7.28k
          for (j = 0; j < aux_size; j++3.60k)
    67
    3.60k
          {
    68
    3.60k
            update_inputs[2 + j] = saved_aux[i * aux_size + j].source = ccv_nnc_tensor_symbol_new(graph, info, 0);
    69
    3.60k
            update_outputs[1 + j] = saved_aux[i * aux_size + j].destination = ccv_nnc_tensor_symbol_new(graph, info, 0);
    70
    3.60k
          }
    71
    3.68k
          const ccv_nnc_graph_exec_symbol_t minimize = ccv_nnc_graph_exec_symbol_new(graph, minimizer, update_inputs, aux_size + 2, update_outputs, aux_size + 1, 0);
    72
    3.68k
          ccv_nnc_graph_exec_symbol_concat(graph, graph_exec, minimize);
    73
    3.68k
          graph_exec_symbols[i] = minimize;
    74
    3.68k
        } else {
    75
    7
          if (gradients)
    76
    7
            gradients[i] = NO_TENSOR_SYMBOL;
    77
    7
          updated_parameters[i] = NO_TENSOR_SYMBOL;
    78
    12
          for (j = 0; j < aux_size; j++5)
    79
    5
          {
    80
    5
            saved_aux[i * aux_size + j].source = NO_TENSOR_SYMBOL;
    81
    5
            saved_aux[i * aux_size + j].destination = NO_TENSOR_SYMBOL;
    82
    5
          }
    83
    7
          graph_exec_symbols[i] = (ccv_nnc_graph_exec_symbol_t){
    84
    7
            .d = -1,
    85
    7
            .graph = 0,
    86
    7
          };
    87
    7
        }
    88
    3.25k
      if (gradients)
    89
    4.51k
        for (i = 0; 2.25ki < input_size; i++2.25k)
    90
    2.25k
        {
    91
    2.25k
          const ccv_nnc_tensor_param_t params = ccv_nnc_tensor_symbol_params(graph, inputs[i]);
    92
    2.25k
          if (params.dim[0] == 0)
    93
    0
            gradients[i + parameter_size] = NO_TENSOR_SYMBOL;
    94
    2.25k
          else
    95
    2.25k
            gradients[i + parameter_size] = ccv_nnc_tensor_symbol_for_backward(graph, inputs[i]);
    96
    2.25k
        }
    97
    3.25k
    }