/home/liu/actions-runner/_work/ccv/ccv/lib/nnc/_ccv_nnc_graph.h
Line | Count | Source |
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 | 320k | #define SCHEDULE_SIGNALS(node) ((node).stream_size <= 1 ? (node)._inline_signals305k : (node)._heap_signals15.1k ) |
96 | 841k | #define SCHEDULE_STREAMS(node) ((node).stream_size <= 1 ? (node)._inline_streams774k : (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 | | enum { |
114 | | CCV_NNC_GRAPH_STATE_IDLE = 0, |
115 | | CCV_NNC_GRAPH_STATE_RUNNING = 1, |
116 | | CCV_NNC_GRAPH_STATE_CANCEL = 2, |
117 | | }; |
118 | | |
119 | | struct ccv_nnc_graph_s { |
120 | | int p_idx; // Reference to the index in its parent graph's sub-graph array, Starts at 1. |
121 | | int exec_idx; // Reference to the index in its parent graph's exec (the graph exec), Starts at 1. |
122 | | int topsorted; // Whether this graph is ordered sequentially. |
123 | | int breakpoint_offset; // If the graph is sorted, offset denotes the first node that is the breakpoint. |
124 | | int breakpoint_size; |
125 | | int stream_size; |
126 | | int signal_size; |
127 | | int buffer_size; |
128 | | int run_state; |
129 | | ccv_array_t* exec_info; // deferred exec info |
130 | | // I think that I can be more explicit about which are sources and which are destinations. |
131 | | // These are int types. |
132 | | ccv_array_t* sources; |
133 | | ccv_array_t* destinations; |
134 | | // streams, signals, and waits are used to coordinate multi-stream graph run (several nodes can execute |
135 | | // concurrently). |
136 | | ccv_nnc_stream_context_t** streams; // Preallocated several streams for use, Default stream will be stream 0. |
137 | | co_routine_t** block_stream_tasks; // Used to keep list of tasks that blocked current stream. |
138 | | ccv_nnc_stream_signal_t** signals; // Preallocated several signals for use. |
139 | | ccv_nnc_graph_static_schedule_t* default_schedule; // The schedule for the whole graph. |
140 | | // Buffer that can be used during graph run, in steady state when run graph (with topsorted), it won't have |
141 | | // any heap allocations (the usage of buffer first will, but subsequent runs won't). |
142 | | void* buffer; |
143 | | // Extra information for all tensors that need to be unwrapped. |
144 | | ccv_array_t* tensor_wraps; // It contains a ccv_nnc_graph_tensor_wrap_array_t struct. |
145 | | 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). |
146 | | // Some extra information piggy-back on graph struct. |
147 | | struct ccv_nnc_graph_s* p; // The parent graph (if current one is a sub-graph). |
148 | | struct ccv_nnc_graph_s* pair; // The pair graph (only useful for backward prop graph). |
149 | | ccv_array_t* sub_graphs; // A list of its sub-graphs (for while loop). |
150 | | // Why some of these I choose to be flat * array, some of these I choose to be ccv_array_t? |
151 | | // for flat * array, these are not going to be modified until next time call ccv_nnc_symbolic_graph_backward |
152 | | // for ccv_array_t, we can continue to modify what's inside. |
153 | | int64_t while_count; |
154 | | ccv_nnc_graph_exec_t* breakpoints; |
155 | | // End of while loop handling. |
156 | | // Extra metadata, useful when we don't want extra memory allocation. |
157 | | ccv_array_t* carry_overs; // The array of tensor carry_overs. |
158 | | }; |
159 | | |
160 | | inline static int ccv_array_find_int(ccv_array_t* ints, const int idx) |
161 | 427 | { |
162 | 427 | int i; |
163 | 1.27k | for (i = 0; i < ints->rnum; i++849 ) |
164 | 849 | if (*(int*)ccv_array_get(ints, i) == idx) |
165 | 0 | return 1; |
166 | 427 | return 0; |
167 | 427 | } 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 | 161 | 427 | { | 162 | 427 | int i; | 163 | 1.27k | for (i = 0; i < ints->rnum; i++849 ) | 164 | 849 | if (*(int*)ccv_array_get(ints, i) == idx) | 165 | 0 | return 1; | 166 | 427 | return 0; | 167 | 427 | } |
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 Unexecuted instantiation: ccv_cnnp_model.c:ccv_array_find_int |
168 | | |
169 | | inline static int ccv_array_find_uint(ccv_array_t* ints, const uint32_t idx) |
170 | 153 | { |
171 | 153 | int i; |
172 | 355 | for (i = 0; i < ints->rnum; i++202 ) |
173 | 270 | if (*(uint32_t*)ccv_array_get(ints, i) == idx) |
174 | 68 | return 1; |
175 | 85 | return 0; |
176 | 153 | } 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 | 170 | 153 | { | 171 | 153 | int i; | 172 | 355 | for (i = 0; i < ints->rnum; i++202 ) | 173 | 270 | if (*(uint32_t*)ccv_array_get(ints, i) == idx) | 174 | 68 | return 1; | 175 | 85 | return 0; | 176 | 153 | } |
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 Unexecuted instantiation: ccv_cnnp_model.c:ccv_array_find_uint |
177 | | |
178 | | inline static int ccv_nnc_tensors_have_wraps(ccv_nnc_tensor_t* const* const tensors, const int tensor_size) |
179 | 97.5k | { |
180 | 97.5k | int i; |
181 | 238k | for (i = 0; i < tensor_size; i++141k ) |
182 | 141k | if (tensors[i] && |
183 | 141k | CCV_IS_TENSOR_MULTIVIEW105k (tensors[i]) && |
184 | 141k | ((ccv_nnc_tensor_multiview_t*)tensors[i])->anchor != 71 CCV_NNC_MULTIVIEW_PHI71 ) |
185 | 62 | return 1; |
186 | 97.4k | return 0; |
187 | 97.5k | } 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 | 179 | 97.4k | { | 180 | 97.4k | int i; | 181 | 238k | for (i = 0; i < tensor_size; i++141k ) | 182 | 141k | if (tensors[i] && | 183 | 141k | CCV_IS_TENSOR_MULTIVIEW105k (tensors[i]) && | 184 | 141k | ((ccv_nnc_tensor_multiview_t*)tensors[i])->anchor != 70 CCV_NNC_MULTIVIEW_PHI70 ) | 185 | 61 | return 1; | 186 | 97.4k | return 0; | 187 | 97.4k | } |
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 | 179 | 23 | { | 180 | 23 | int i; | 181 | 48 | for (i = 0; i < tensor_size; i++25 ) | 182 | 26 | if (tensors[i] && | 183 | 26 | CCV_IS_TENSOR_MULTIVIEW(tensors[i]) && | 184 | 26 | ((ccv_nnc_tensor_multiview_t*)tensors[i])->anchor != 1 CCV_NNC_MULTIVIEW_PHI1 ) | 185 | 1 | return 1; | 186 | 22 | return 0; | 187 | 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 Unexecuted instantiation: ccv_cnnp_model.c:ccv_nnc_tensors_have_wraps |
188 | | |
189 | | CCV_WARN_UNUSED(void*) ccv_nnc_graph_buffer(ccv_nnc_graph_t* const graph, int size); |
190 | | 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); |
191 | | 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); |
192 | | void ccv_nnc_graph_register_tensor_wraps(ccv_nnc_graph_t* graph, const int tensor_wraps_ref_d); |
193 | | |
194 | | #endif |