Coverage Report

Created: 2021-09-21 23:33

/home/liu/buildslave/linux-x64-runtests/build/lib/nnc/_ccv_nnc_graph.h
Line
Count
Source (jump to first uncovered line)
1
/**********************************************************
2
 * C-based/Cached/Core Computer Vision Library
3
 * Liu Liu, 2010-02-01
4
 **********************************************************/
5
6
/**********************************************************
7
 * CCV - Neural Network Collection
8
 **********************************************************/
9
10
#ifndef GUARD_ccv_nnc_graph_internal_h
11
#define GUARD_ccv_nnc_graph_internal_h
12
13
#include "ccv_nnc.h"
14
15
#include "_ccv_nnc_stream.h"
16
#include "3rdparty/khash/khash.h"
17
18
typedef struct {
19
  int update_required;
20
  int count;
21
  int index;
22
  ccv_nnc_tensor_t* tensors[1];
23
} ccv_nnc_graph_tensor_wrap_t;
24
25
typedef struct {
26
  int size;
27
  ccv_nnc_graph_tensor_wrap_t* tensor_wraps[1];
28
} ccv_nnc_graph_tensor_wrap_array_t;
29
30
typedef struct {
31
  int stream_size; // This controls the size of both _heap_signals and _heap_streams. When this is <= 1, we don't have _heap variant.
32
  union {
33
    int _inline_signals[1];
34
    int* _heap_signals;
35
  };
36
  union {
37
    int _inline_streams[1]; // The assigned stream for this to be executed.
38
    int* _heap_streams;
39
  };
40
  int wait_size;
41
  int* waits;
42
} ccv_nnc_graph_exec_schedule_t;
43
44
struct ccv_nnc_graph_static_schedule_s {
45
  int exec_info_size;
46
  int psort_size;
47
  int wait_size;
48
  int stream_0;
49
  int stream_1_size;
50
  int* stream_1s; // The default stream will begin these signals on start.
51
  int* waits; // The default stream will wait on these signals to be done.
52
  int* psort; // If the graph is not topsorted, I will re-index it. Only applicable for partial scheduling.
53
  ccv_nnc_stream_signal_t* begin; // This signal is created so that internal stream_1s can sync with stream_0.
54
  ccv_nnc_stream_signal_t* end; // This signal is created so that outside provided stream can be synced with the stream_0.
55
  ccv_nnc_graph_exec_schedule_t exec_info[1];
56
};
57
58
typedef struct {
59
  int input_size;
60
  int output_size;
61
  int flags;
62
  int pair_ref; // Reference to its pair. Starts at 1.
63
  int graph_ref_size;
64
  int update_size;
65
  int tensor_wraps_ref; // Reference to the tensor_wraps in the graph. Starts at 1.
66
  ccv_nnc_tensor_t** inputs;
67
  int* input_flags;
68
  ccv_nnc_tensor_t** outputs;
69
  int* output_flags;
70
  ccv_array_t* outgoings; // outgoing nodes
71
  intptr_t alias_ref; // Link to some reference data.
72
  ccv_nnc_cmd_t cmd;
73
  ccv_nnc_hint_t hint;
74
  // These correlates to tensors that need to be unwrapped, but not in either inputs / outputs (thus, only relevant if this graph exec symbol points to a sub-graph.)
75
  ccv_nnc_tensor_t** updates;
76
  // Below are only relevant to sub-graph nodes (case_of, while).
77
  int _inline_graph_ref[2]; // Reference to the sub-graph. Starts at 1.
78
  int* _heap_graph_ref;
79
  union {
80
    struct {
81
      ccv_nnc_graph_case_of_f expr;
82
      const void* data;
83
      int offset;
84
    } case_of;
85
    struct {
86
      ccv_nnc_graph_while_f expr;
87
      const void* data;
88
      ccv_nnc_tensor_t** inputs;
89
      int input_size;
90
      int tensor_wraps_ref;
91
    } p_while;
92
  };
93
} ccv_nnc_graph_exec_info_t;
94
95
310k
#define SCHEDULE_SIGNALS(node) ((node).stream_size <= 1 ? 
(node)._inline_signals295k
:
(node)._heap_signals15.1k
)
96
816k
#define SCHEDULE_STREAMS(node) ((node).stream_size <= 1 ? 
(node)._inline_streams749k
:
(node)._heap_streams67.2k
)
97
98
// This struct is used to move pointers from "from" to "to". This is used to bridge between the current loop
99
// and the next one. These tensor trees wraps / unwraps follow the conventional tree_execs, but of a graph.
100
// At the end of an iteration, before rewrap, the pointer from "from" tensor will be moved to transit. At the
101
// beginning of the next iteration, after unwrap, the pointer from transit will be moved to "to" tensor.
102
typedef struct {
103
  ccv_nnc_graph_tensor_wrap_t* to;
104
  ccv_numeric_data_t transit;
105
  ccv_nnc_graph_tensor_wrap_t* from;
106
} ccv_nnc_graph_tensor_carry_over_t;
107
108
typedef struct {
109
  int d;
110
  ccv_nnc_graph_t* graph;
111
} ccv_nnc_graph_tensor_wraps_ref_t;
112
113
struct ccv_nnc_graph_s {
114
  int p_idx; // Reference to the index in its parent graph's sub-graph array, Starts at 1.
115
  int exec_idx; // Reference to the index in its parent graph's exec (the graph exec), Starts at 1.
116
  int topsorted; // Whether this graph is ordered sequentially.
117
  int breakpoint_offset; // If the graph is sorted, offset denotes the first node that is the breakpoint.
118
  int breakpoint_size;
119
  int stream_size;
120
  int signal_size;
121
  int buffer_size;
122
  ccv_array_t* exec_info; // deferred exec info
123
  // I think that I can be more explicit about which are sources and which are destinations.
124
  // These are int types.
125
  ccv_array_t* sources;
126
  ccv_array_t* destinations;
127
  // streams, signals, and waits are used to coordinate multi-stream graph run (several nodes can execute
128
  // concurrently).
129
  ccv_nnc_stream_context_t** streams; // Preallocated several streams for use, Default stream will be stream 0.
130
  co_routine_t** block_stream_tasks; // Used to keep list of tasks that blocked current stream.
131
  ccv_nnc_stream_signal_t** signals; // Preallocated several signals for use.
132
  ccv_nnc_graph_static_schedule_t* default_schedule; // The schedule for the whole graph.
133
  // Buffer that can be used during graph run, in steady state when run graph (with topsorted), it won't have
134
  // any heap allocations (the usage of buffer first will, but subsequent runs won't).
135
  void* buffer;
136
  // Extra information for all tensors that need to be unwrapped.
137
  ccv_array_t* tensor_wraps; // It contains a ccv_nnc_graph_tensor_wrap_array_t struct.
138
  ccv_array_t* tensor_wraps_refs; // It contains a ccv_nnc_graph_tensor_wrap_ref_t struct that references to all tensor wraps need to be unwrapped (including all sub-graphs).
139
  // Some extra information piggy-back on graph struct.
140
  struct ccv_nnc_graph_s* p; // The parent graph (if current one is a sub-graph).
141
  struct ccv_nnc_graph_s* pair; // The pair graph (only useful for backward prop graph).
142
  ccv_array_t* sub_graphs; // A list of its sub-graphs (for while loop).
143
  // Why some of these I choose to be flat * array, some of these I choose to be ccv_array_t?
144
  // for flat * array, these are not going to be modified until next time call ccv_nnc_symbolic_graph_backward
145
  // for ccv_array_t, we can continue to modify what's inside.
146
  int64_t while_count;
147
  ccv_nnc_graph_exec_t* breakpoints;
148
  // End of while loop handling.
149
  // Extra metadata, useful when we don't want extra memory allocation.
150
  ccv_array_t* carry_overs; // The array of tensor carry_overs.
151
};
152
153
inline static int ccv_array_find_int(ccv_array_t* ints, const int idx)
154
429
{
155
429
  int i;
156
1.27k
  for (i = 0; i < ints->rnum; 
i++850
)
157
850
    if (*(int*)ccv_array_get(ints, i) == idx)
158
0
      return 1;
159
429
  return 0;
160
429
}
Unexecuted instantiation: while.backward.tests.c:ccv_array_find_int
Unexecuted instantiation: tape.tests.c:ccv_array_find_int
ccv_nnc_graph.c:ccv_array_find_int
Line
Count
Source
154
429
{
155
429
  int i;
156
1.27k
  for (i = 0; i < ints->rnum; 
i++850
)
157
850
    if (*(int*)ccv_array_get(ints, i) == idx)
158
0
      return 1;
159
429
  return 0;
160
429
}
Unexecuted instantiation: ccv_nnc_symbolic_graph_compile.c:ccv_array_find_int
Unexecuted instantiation: ccv_nnc_graph_while.c:ccv_array_find_int
Unexecuted instantiation: ccv_nnc_tensor_tape.c:ccv_array_find_int
Unexecuted instantiation: ccv_nnc_graph_case_of.c:ccv_array_find_int
Unexecuted instantiation: ccv_nnc_graph_run.c:ccv_array_find_int
161
162
inline static int ccv_array_find_uint(ccv_array_t* ints, const uint32_t idx)
163
146
{
164
146
  int i;
165
444
  for (i = 0; i < ints->rnum; 
i++298
)
166
370
    if (*(uint32_t*)ccv_array_get(ints, i) == idx)
167
72
      return 1;
168
146
  
return 074
;
169
146
}
Unexecuted instantiation: while.backward.tests.c:ccv_array_find_uint
Unexecuted instantiation: tape.tests.c:ccv_array_find_uint
ccv_nnc_graph.c:ccv_array_find_uint
Line
Count
Source
163
146
{
164
146
  int i;
165
444
  for (i = 0; i < ints->rnum; 
i++298
)
166
370
    if (*(uint32_t*)ccv_array_get(ints, i) == idx)
167
72
      return 1;
168
146
  
return 074
;
169
146
}
Unexecuted instantiation: ccv_nnc_symbolic_graph_compile.c:ccv_array_find_uint
Unexecuted instantiation: ccv_nnc_graph_while.c:ccv_array_find_uint
Unexecuted instantiation: ccv_nnc_tensor_tape.c:ccv_array_find_uint
Unexecuted instantiation: ccv_nnc_graph_case_of.c:ccv_array_find_uint
Unexecuted instantiation: ccv_nnc_graph_run.c:ccv_array_find_uint
170
171
inline static int ccv_nnc_tensors_have_wraps(ccv_nnc_tensor_t* const* const tensors, const int tensor_size)
172
96.3k
{
173
96.3k
  int i;
174
236k
  for (i = 0; i < tensor_size; 
i++139k
)
175
139k
    if (tensors[i] &&
176
139k
      
CCV_IS_TENSOR_MULTIVIEW108k
(tensors[i]) &&
177
139k
      
((ccv_nnc_tensor_multiview_t*)tensors[i])->anchor != 71
CCV_NNC_MULTIVIEW_PHI71
)
178
139k
      
return 162
;
179
96.3k
  
return 096.2k
;
180
96.3k
}
Unexecuted instantiation: while.backward.tests.c:ccv_nnc_tensors_have_wraps
Unexecuted instantiation: tape.tests.c:ccv_nnc_tensors_have_wraps
ccv_nnc_graph.c:ccv_nnc_tensors_have_wraps
Line
Count
Source
172
96.3k
{
173
96.3k
  int i;
174
235k
  for (i = 0; i < tensor_size; 
i++139k
)
175
139k
    if (tensors[i] &&
176
139k
      
CCV_IS_TENSOR_MULTIVIEW108k
(tensors[i]) &&
177
139k
      
((ccv_nnc_tensor_multiview_t*)tensors[i])->anchor != 70
CCV_NNC_MULTIVIEW_PHI70
)
178
139k
      
return 161
;
179
96.3k
  
return 096.2k
;
180
96.3k
}
Unexecuted instantiation: ccv_nnc_symbolic_graph_compile.c:ccv_nnc_tensors_have_wraps
ccv_nnc_graph_while.c:ccv_nnc_tensors_have_wraps
Line
Count
Source
172
23
{
173
23
  int i;
174
48
  for (i = 0; i < tensor_size; 
i++25
)
175
26
    if (tensors[i] &&
176
26
      CCV_IS_TENSOR_MULTIVIEW(tensors[i]) &&
177
26
      
((ccv_nnc_tensor_multiview_t*)tensors[i])->anchor != 1
CCV_NNC_MULTIVIEW_PHI1
)
178
26
      
return 11
;
179
23
  
return 022
;
180
23
}
Unexecuted instantiation: ccv_nnc_tensor_tape.c:ccv_nnc_tensors_have_wraps
Unexecuted instantiation: ccv_nnc_graph_case_of.c:ccv_nnc_tensors_have_wraps
Unexecuted instantiation: ccv_nnc_graph_run.c:ccv_nnc_tensors_have_wraps
181
182
CCV_WARN_UNUSED(void*) ccv_nnc_graph_buffer(ccv_nnc_graph_t* const graph, int size);
183
CCV_WARN_UNUSED(ccv_nnc_graph_tensor_wrap_array_t*) ccv_nnc_get_tensor_wrap_array(ccv_nnc_graph_t* const graph, const int tensor_wrap_size, int* const tensor_wraps_ref);
184
void ccv_nnc_set_tensor_wraps(ccv_nnc_graph_tensor_wrap_t** const tensor_wraps, ccv_nnc_tensor_t* const* const tensors, const int tensor_size);
185
void ccv_nnc_graph_register_tensor_wraps(ccv_nnc_graph_t* graph, const int tensor_wraps_ref_d);
186
187
#endif