Coverage Report

Created: 2024-08-18 16:21

/home/liu/actions-runner/_work/ccv/ccv/lib/nnc/ccv_nnc_symbolic_graph_minimize.c
Line
Count
Source (jump to first uncovered line)
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.3k
{
11
12.3k
  int i, aux_size = -1;
12
12.3k
  uint64_t input_bitmask = 0x1;
13
12.3k
  uint64_t output_bitmask = 0x0;
14
36.9k
  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.3k
      aux_size = i;
20
24.6k
  }
21
12.3k
  return aux_size;
22
12.3k
}
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.22k
      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.47k
    for (i = parameter_size; i < parameter_size + input_size; 
i++2.24k
)
39
2.24k
      if (ingrads[i].d >= 0)
40
2.24k
      {
41
2.24k
        const ccv_nnc_tensor_param_t params = ccv_nnc_tensor_symbol_params(graph, ingrads[i]);
42
2.24k
        if (params.dim[0] == 0)
43
0
          ingrads[i] = NO_TENSOR_SYMBOL;
44
2.24k
      }
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.02k
parameter_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.93k
  for (i = 0; i < parameter_size; 
i++3.68k
)
56
3.68k
    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.49k
    
for (i = 0; 2.24k
i < input_size;
i++2.24k
)
90
2.24k
    {
91
2.24k
      const ccv_nnc_tensor_param_t params = ccv_nnc_tensor_symbol_params(graph, inputs[i]);
92
2.24k
      if (params.dim[0] == 0)
93
0
        gradients[i + parameter_size] = NO_TENSOR_SYMBOL;
94
2.24k
      else
95
2.24k
        gradients[i + parameter_size] = ccv_nnc_tensor_symbol_for_backward(graph, inputs[i]);
96
2.24k
    }
97
3.25k
}