/home/liu/actions-runner/_work/ccv/ccv/lib/nnc/_ccv_nnc_micro.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_micro_internal_h |
11 | | #define GUARD_ccv_nnc_micro_internal_h |
12 | | |
13 | | #include "ccv_nnc.h" |
14 | | |
15 | | enum { |
16 | | CCV_NNC_MICRO_LOOP_ID, |
17 | | CCV_NNC_MICRO_LOOP_CARRIED_ID, |
18 | | CCV_NNC_MICRO_AXIS_SIZE_ID, |
19 | | CCV_NNC_MICRO_TENSOR_ID, |
20 | | CCV_NNC_MICRO_SCALAR_ID, |
21 | | }; |
22 | | |
23 | | typedef struct { |
24 | | uint8_t type; |
25 | | uint8_t d; // Only used for axis_size, identify which axis for a tensor. |
26 | | int16_t id; |
27 | | } ccv_nnc_micro_id_t; |
28 | | |
29 | | typedef struct { |
30 | | ccv_nnc_micro_id_t left; |
31 | | ccv_nnc_micro_id_t right; |
32 | | } ccv_nnc_micro_id_equal_assertion_t; |
33 | | |
34 | | enum { |
35 | | CCV_NNC_MICRO_LOOP_INDEX_TYPE_NONE, |
36 | | CCV_NNC_MICRO_LOOP_INDEX_TYPE_ID, |
37 | | CCV_NNC_MICRO_LOOP_INDEX_TYPE_VAL, |
38 | | CCV_NNC_MICRO_LOOP_INDEX_TYPE_BINARY, |
39 | | CCV_NNC_MICRO_LOOP_INDEX_TYPE_UNBOUND_SCALAR, // Unbounded scalar variable, shouldn't be there after fully-evaluated. |
40 | | }; |
41 | | |
42 | | typedef struct ccv_nnc_micro_loop_index_binary_s ccv_nnc_micro_loop_index_binary_t; |
43 | | |
44 | | typedef struct { |
45 | | int type; |
46 | | union { |
47 | | char* name; // binding variable name. |
48 | | ccv_nnc_micro_id_t id; |
49 | | int immediate_value; |
50 | | ccv_nnc_micro_loop_index_binary_t* binary; |
51 | | }; |
52 | | } ccv_nnc_micro_loop_index_term_t; |
53 | | |
54 | | struct ccv_nnc_micro_loop_index_binary_s { |
55 | | int op; |
56 | | ccv_nnc_micro_loop_index_term_t left; |
57 | | ccv_nnc_micro_loop_index_term_t right; |
58 | | }; |
59 | | |
60 | | typedef struct { |
61 | | ccv_nnc_micro_id_t id; |
62 | | int index_count; |
63 | | int no_check_bound[CCV_NNC_MAX_DIM_ALLOC]; |
64 | | ccv_nnc_micro_loop_index_term_t index[CCV_NNC_MAX_DIM_ALLOC]; |
65 | | } ccv_nnc_micro_loop_variable_t; |
66 | | |
67 | | enum { |
68 | | CCV_NNC_MICRO_LOOP_EXPR_TYPE_ID, |
69 | | CCV_NNC_MICRO_LOOP_EXPR_TYPE_VAL, |
70 | | CCV_NNC_MICRO_LOOP_EXPR_TYPE_VAR, |
71 | | CCV_NNC_MICRO_LOOP_EXPR_TYPE_UNARY, |
72 | | CCV_NNC_MICRO_LOOP_EXPR_TYPE_BINARY, |
73 | | CCV_NNC_MICRO_LOOP_EXPR_TYPE_TERNAY, |
74 | | }; |
75 | | |
76 | | typedef struct ccv_nnc_micro_loop_expression_s ccv_nnc_micro_loop_expression_t; |
77 | | |
78 | | typedef struct { |
79 | | int unary_op; |
80 | | ccv_nnc_micro_loop_expression_t* x; |
81 | | } ccv_nnc_micro_loop_unary_t; |
82 | | |
83 | | typedef struct { |
84 | | int binary_op; |
85 | | ccv_nnc_micro_loop_expression_t* left; |
86 | | ccv_nnc_micro_loop_expression_t* right; |
87 | | } ccv_nnc_micro_loop_binary_t; |
88 | | |
89 | | typedef struct { |
90 | | ccv_nnc_micro_loop_expression_t* pivot; // If it is 0, choose left, otherwise choose right. |
91 | | ccv_nnc_micro_loop_expression_t* left; |
92 | | ccv_nnc_micro_loop_expression_t* right; |
93 | | } ccv_nnc_micro_loop_ternary_t; |
94 | | |
95 | | struct ccv_nnc_micro_loop_expression_s { |
96 | | int type; |
97 | | union { |
98 | | ccv_nnc_micro_id_t id; // If this is a compound assignment, the id to that. |
99 | | ccv_nnc_micro_scalar_t immediate_value; |
100 | | ccv_nnc_micro_loop_variable_t variable; |
101 | | ccv_nnc_micro_loop_unary_t unary; |
102 | | ccv_nnc_micro_loop_binary_t binary; |
103 | | ccv_nnc_micro_loop_ternary_t ternary; |
104 | | }; |
105 | | }; |
106 | | |
107 | | typedef struct { |
108 | | ccv_nnc_micro_loop_variable_t lvalue; |
109 | | ccv_nnc_micro_loop_expression_t rvalue; |
110 | | } ccv_nnc_micro_loop_assignment_t; |
111 | | |
112 | | |
113 | | typedef struct { |
114 | | int type; |
115 | | union { |
116 | | ccv_nnc_micro_id_t id; // If this is a compound assignment, the id to that. |
117 | | ccv_nnc_micro_loop_variable_t variable; // This only implies PLUS at the moment. |
118 | | }; |
119 | | } ccv_nnc_micro_loop_compound_assignment_lvalue_t; |
120 | | |
121 | | typedef struct { |
122 | | ccv_nnc_micro_loop_compound_assignment_lvalue_t lvalue; // It shouldn't be unary or binary, only id or variable. |
123 | | ccv_nnc_micro_loop_expression_t rvalue; |
124 | | } ccv_nnc_micro_loop_compound_assignment_t; |
125 | | |
126 | | enum { |
127 | | CCV_NNC_MICRO_LOOP_STATEMENT_TYPE_ASSIGNMENT, |
128 | | CCV_NNC_MICRO_LOOP_STATEMENT_TYPE_COMPOUND_ASSIGNMENT, |
129 | | }; |
130 | | |
131 | | // A generic statement within a loop. |
132 | | // For our purpose, there will be two types of generic statement: |
133 | | // an assignment statement (for tensors). |
134 | | // an compound assignment statement (for loop carry overs). |
135 | | typedef struct { |
136 | | int type; |
137 | | union { |
138 | | ccv_nnc_micro_loop_assignment_t assignment; |
139 | | ccv_nnc_micro_loop_compound_assignment_t compound_assignment; |
140 | | }; |
141 | | } ccv_nnc_micro_loop_statement_t; |
142 | | |
143 | | typedef struct { |
144 | | ccv_nnc_micro_id_t id; |
145 | | } ccv_nnc_micro_loop_carried_t; // The accumulating register. |
146 | | |
147 | | // A loop is identified with a loop counter id, some blocks inside this loop, some carry overs within |
148 | | // this loop and can be used outside of this loop. |
149 | | // If this loop has another loop nested (represented as the next one in the ccv_nnc_micro_nested_loop_t) |
150 | | // all blocks are executed after the nested loop finished. |
151 | | typedef struct { |
152 | | ccv_nnc_micro_id_t id; // Loop counter's id, this will be used for indexing. |
153 | | int carried_count; |
154 | | int statement_count; |
155 | | ccv_nnc_micro_loop_index_term_t start_index; |
156 | | ccv_nnc_micro_loop_index_term_t end_index; |
157 | | ccv_nnc_micro_loop_carried_t* carrieds; |
158 | | ccv_nnc_micro_loop_statement_t* statements; |
159 | | } ccv_nnc_micro_loop_t; |
160 | | |
161 | | // A loop block contains many loops within each other. |
162 | | typedef struct { |
163 | | int carried_count; |
164 | | int loop_count; |
165 | | ccv_nnc_micro_loop_t* loops; |
166 | | } ccv_nnc_micro_loop_block_t; |
167 | | |
168 | | typedef struct { |
169 | | int input; // The one it derives its shape from. If shape is nullptr, it has the same shape as input. -1 means it is an input. |
170 | | int sibling; // The sibling that has the same shape. |
171 | | int dimensions; |
172 | | int no_alloc; // No need to allocate this tensor. |
173 | | ccv_nnc_micro_loop_index_term_t* shape; |
174 | | } ccv_nnc_micro_tensor_t; |
175 | | |
176 | | // A function contains a list of loop blocks that will be executed serially. |
177 | | // It also contains references to its dependencies so a function knows its inputs / outputs. |
178 | | typedef struct { |
179 | | int block_count; |
180 | | union { |
181 | | ccv_nnc_micro_loop_block_t* blocks; // Heap-allocated blocks. |
182 | | ccv_nnc_micro_loop_block_t one_block; // In-place block to optimize memory allocation for one block cases. |
183 | | }; |
184 | | } ccv_nnc_micro_function_t; |
185 | | |
186 | | typedef struct { |
187 | | int input_size; // Size of inputs. |
188 | | int output_size; // Size of outputs. |
189 | | // Combined ops only have global vars, there is no local vars. All vars are tensors. |
190 | | int var_count; |
191 | | // loops are our constructs of IR ops really. It is hierarchical. |
192 | | int function_count; |
193 | | int* inputs; |
194 | | int* outputs; |
195 | | ccv_nnc_micro_tensor_t* vars; |
196 | | ccv_nnc_micro_function_t* functions; |
197 | | } ccv_nnc_micro_program_t; |
198 | | |
199 | | // A combined op is constructed with many nested loops. These loops may have data dependencies |
200 | | // between each other, but they are ordered in topological order to make sure one is finished |
201 | | // after the another. |
202 | | struct ccv_nnc_micro_combine_s { |
203 | | int parameter_size; // Size of parameters. |
204 | | ccv_nnc_micro_program_t forward; |
205 | | ccv_nnc_micro_program_t backward; |
206 | | ccv_array_t* equal_assertions; |
207 | | }; |
208 | | |
209 | | typedef uint32_t(*ccv_nnc_micro_scalar_lookup_f)(const void* const context, const char* const name); |
210 | | |
211 | | /** |
212 | | * This is the virtual table for micro op. |
213 | | */ |
214 | | struct ccv_nnc_micro_io_vtab_s { |
215 | | void (*bind_scalars)(const ccv_nnc_micro_io_t self, ccv_nnc_micro_scalar_lookup_f lookup, const void* const context); /**< Bind scalar name to a scoped id. */ |
216 | | void (*numbering)(const ccv_nnc_micro_io_t self, const int id, const int var_count); /**< Assign id to the output of this micro op. */ |
217 | | void (*equal_assertions)(const ccv_nnc_micro_io_t self, ccv_array_t* const equal_assertions); /**< Collect assertions about id equal. */ |
218 | | ccv_nnc_micro_function_t (*emit)(const ccv_nnc_micro_io_t self); /**< Emit instructions for this micro op. */ |
219 | | ccv_nnc_micro_function_t (*emit_grad)(const ccv_nnc_micro_io_t self, const int var_count); /**< Emit backward instructions for this micro op. */ |
220 | | ccv_nnc_micro_tensor_t (*return_shape)(const ccv_nnc_micro_io_t self); /**< The shape of the returned tensor. */ |
221 | | void (*deinit)(const ccv_nnc_micro_io_t self); /**< Deinit this micro io. */ |
222 | | }; |
223 | | |
224 | | extern const ccv_nnc_micro_io_vtab_t ccv_nnc_micro_io_input_isa; |
225 | | extern const ccv_nnc_micro_io_vtab_t ccv_nnc_micro_io_grad_isa; |
226 | | |
227 | 25 | #define CCV_NNC_IS_MICRO_IO_INPUT(x) ((x)->isa == &ccv_nnc_micro_io_input_isa) |
228 | 15 | #define CCV_NNC_IS_MICRO_IO_GRAD(x) ((x)->isa == &ccv_nnc_micro_io_grad_isa) |
229 | | |
230 | | static inline void ccv_nnc_micro_numbering(const ccv_nnc_micro_io_t self, const int id, const int var_count) |
231 | 33 | { |
232 | 33 | const ccv_nnc_micro_io_vtab_t* const isa = self->isa; |
233 | | // If we numbering with negative id, we really just enumerate the grad. |
234 | 33 | if (id < 0 && !15 CCV_NNC_IS_MICRO_IO_GRAD15 (self)) |
235 | 6 | return; |
236 | 27 | if (isa->numbering) |
237 | 15 | isa->numbering(self, id, var_count); |
238 | 12 | else |
239 | 12 | self->id = id; |
240 | 27 | } ccv_nnc_micro.c:ccv_nnc_micro_numbering Line | Count | Source | 231 | 33 | { | 232 | 33 | const ccv_nnc_micro_io_vtab_t* const isa = self->isa; | 233 | | // If we numbering with negative id, we really just enumerate the grad. | 234 | 33 | if (id < 0 && !15 CCV_NNC_IS_MICRO_IO_GRAD15 (self)) | 235 | 6 | return; | 236 | 27 | if (isa->numbering) | 237 | 15 | isa->numbering(self, id, var_count); | 238 | 12 | else | 239 | 12 | self->id = id; | 240 | 27 | } |
Unexecuted instantiation: ccv_nnc_micro_core.c:ccv_nnc_micro_numbering Unexecuted instantiation: ccv_nnc_micro_interpret.c:ccv_nnc_micro_numbering Unexecuted instantiation: ccv_nnc_micro_simplify.c:ccv_nnc_micro_numbering |
241 | | |
242 | | static inline void ccv_nnc_micro_equal_assertions(const ccv_nnc_micro_io_t self, ccv_array_t* const equal_assertions) |
243 | 12 | { |
244 | 12 | const ccv_nnc_micro_io_vtab_t* const isa = self->isa; |
245 | 12 | if (isa->equal_assertions) |
246 | 6 | isa->equal_assertions(self, equal_assertions); |
247 | 12 | } ccv_nnc_micro.c:ccv_nnc_micro_equal_assertions Line | Count | Source | 243 | 12 | { | 244 | 12 | const ccv_nnc_micro_io_vtab_t* const isa = self->isa; | 245 | 12 | if (isa->equal_assertions) | 246 | 6 | isa->equal_assertions(self, equal_assertions); | 247 | 12 | } |
Unexecuted instantiation: ccv_nnc_micro_core.c:ccv_nnc_micro_equal_assertions Unexecuted instantiation: ccv_nnc_micro_interpret.c:ccv_nnc_micro_equal_assertions Unexecuted instantiation: ccv_nnc_micro_simplify.c:ccv_nnc_micro_equal_assertions |
248 | | |
249 | | static inline void ccv_nnc_micro_bind_scalars(const ccv_nnc_micro_io_t self, ccv_nnc_micro_scalar_lookup_f lookup, const void* const context) |
250 | 12 | { |
251 | 12 | const ccv_nnc_micro_io_vtab_t* const isa = self->isa; |
252 | 12 | if (isa->bind_scalars) |
253 | 6 | isa->bind_scalars(self, lookup, context); |
254 | 12 | } ccv_nnc_micro.c:ccv_nnc_micro_bind_scalars Line | Count | Source | 250 | 12 | { | 251 | 12 | const ccv_nnc_micro_io_vtab_t* const isa = self->isa; | 252 | 12 | if (isa->bind_scalars) | 253 | 6 | isa->bind_scalars(self, lookup, context); | 254 | 12 | } |
Unexecuted instantiation: ccv_nnc_micro_core.c:ccv_nnc_micro_bind_scalars Unexecuted instantiation: ccv_nnc_micro_interpret.c:ccv_nnc_micro_bind_scalars Unexecuted instantiation: ccv_nnc_micro_simplify.c:ccv_nnc_micro_bind_scalars |
255 | | |
256 | | static inline void ccv_nnc_micro_deinit(const ccv_nnc_micro_io_t self) |
257 | 27 | { |
258 | 27 | const ccv_nnc_micro_io_vtab_t* const isa = self->isa; |
259 | 27 | if (isa->deinit) |
260 | 6 | isa->deinit(self); |
261 | 27 | } ccv_nnc_micro.c:ccv_nnc_micro_deinit Line | Count | Source | 257 | 27 | { | 258 | 27 | const ccv_nnc_micro_io_vtab_t* const isa = self->isa; | 259 | 27 | if (isa->deinit) | 260 | 6 | isa->deinit(self); | 261 | 27 | } |
Unexecuted instantiation: ccv_nnc_micro_core.c:ccv_nnc_micro_deinit Unexecuted instantiation: ccv_nnc_micro_interpret.c:ccv_nnc_micro_deinit Unexecuted instantiation: ccv_nnc_micro_simplify.c:ccv_nnc_micro_deinit |
262 | | |
263 | | static inline CCV_WARN_UNUSED(ccv_nnc_micro_function_t) ccv_nnc_micro_emit(const ccv_nnc_micro_io_t self) |
264 | 24 | { |
265 | 24 | const ccv_nnc_micro_io_vtab_t* const isa = self->isa; |
266 | 24 | return isa->emit(self); |
267 | 24 | } ccv_nnc_micro.c:ccv_nnc_micro_emit Line | Count | Source | 264 | 24 | { | 265 | 24 | const ccv_nnc_micro_io_vtab_t* const isa = self->isa; | 266 | 24 | return isa->emit(self); | 267 | 24 | } |
Unexecuted instantiation: ccv_nnc_micro_core.c:ccv_nnc_micro_emit Unexecuted instantiation: ccv_nnc_micro_interpret.c:ccv_nnc_micro_emit Unexecuted instantiation: ccv_nnc_micro_simplify.c:ccv_nnc_micro_emit |
268 | | |
269 | | static inline CCV_WARN_UNUSED(ccv_nnc_micro_function_t) ccv_nnc_micro_emit_grad(const ccv_nnc_micro_io_t self, const int var_count) |
270 | 12 | { |
271 | 12 | const ccv_nnc_micro_io_vtab_t* const isa = self->isa; |
272 | 12 | return isa->emit_grad(self, var_count); |
273 | 12 | } ccv_nnc_micro.c:ccv_nnc_micro_emit_grad Line | Count | Source | 270 | 12 | { | 271 | 12 | const ccv_nnc_micro_io_vtab_t* const isa = self->isa; | 272 | 12 | return isa->emit_grad(self, var_count); | 273 | 12 | } |
Unexecuted instantiation: ccv_nnc_micro_core.c:ccv_nnc_micro_emit_grad Unexecuted instantiation: ccv_nnc_micro_interpret.c:ccv_nnc_micro_emit_grad Unexecuted instantiation: ccv_nnc_micro_simplify.c:ccv_nnc_micro_emit_grad |
274 | | |
275 | | static inline CCV_WARN_UNUSED(ccv_nnc_micro_tensor_t) ccv_nnc_micro_return_shape(const ccv_nnc_micro_io_t self) |
276 | 12 | { |
277 | 12 | const ccv_nnc_micro_io_vtab_t* const isa = self->isa; |
278 | 12 | return isa->return_shape(self); |
279 | 12 | } ccv_nnc_micro.c:ccv_nnc_micro_return_shape Line | Count | Source | 276 | 12 | { | 277 | 12 | const ccv_nnc_micro_io_vtab_t* const isa = self->isa; | 278 | 12 | return isa->return_shape(self); | 279 | 12 | } |
Unexecuted instantiation: ccv_nnc_micro_core.c:ccv_nnc_micro_return_shape Unexecuted instantiation: ccv_nnc_micro_interpret.c:ccv_nnc_micro_return_shape Unexecuted instantiation: ccv_nnc_micro_simplify.c:ccv_nnc_micro_return_shape |
280 | | |
281 | | /** |
282 | | * Helpers to construct the micro IR. |
283 | | */ |
284 | | |
285 | | static inline ccv_nnc_micro_id_t ccv_nnc_micro_id_of_tensor(const int id) |
286 | 96 | { |
287 | 96 | return (ccv_nnc_micro_id_t){ |
288 | 96 | .type = CCV_NNC_MICRO_TENSOR_ID, |
289 | 96 | .id = id, |
290 | 96 | .d = 0 |
291 | 96 | }; |
292 | 96 | } Unexecuted instantiation: ccv_nnc_micro.c:ccv_nnc_micro_id_of_tensor ccv_nnc_micro_core.c:ccv_nnc_micro_id_of_tensor Line | Count | Source | 286 | 96 | { | 287 | 96 | return (ccv_nnc_micro_id_t){ | 288 | 96 | .type = CCV_NNC_MICRO_TENSOR_ID, | 289 | 96 | .id = id, | 290 | 96 | .d = 0 | 291 | 96 | }; | 292 | 96 | } |
Unexecuted instantiation: ccv_nnc_micro_interpret.c:ccv_nnc_micro_id_of_tensor Unexecuted instantiation: ccv_nnc_micro_simplify.c:ccv_nnc_micro_id_of_tensor |
293 | | |
294 | | static inline ccv_nnc_micro_loop_index_term_t ccv_nnc_micro_index_of_value(const int value) |
295 | 269 | { |
296 | 269 | return (ccv_nnc_micro_loop_index_term_t){ |
297 | 269 | .type = CCV_NNC_MICRO_LOOP_INDEX_TYPE_VAL, |
298 | 269 | .immediate_value = value |
299 | 269 | }; |
300 | 269 | } Unexecuted instantiation: ccv_nnc_micro.c:ccv_nnc_micro_index_of_value ccv_nnc_micro_core.c:ccv_nnc_micro_index_of_value Line | Count | Source | 295 | 269 | { | 296 | 269 | return (ccv_nnc_micro_loop_index_term_t){ | 297 | 269 | .type = CCV_NNC_MICRO_LOOP_INDEX_TYPE_VAL, | 298 | 269 | .immediate_value = value | 299 | 269 | }; | 300 | 269 | } |
Unexecuted instantiation: ccv_nnc_micro_interpret.c:ccv_nnc_micro_index_of_value Unexecuted instantiation: ccv_nnc_micro_simplify.c:ccv_nnc_micro_index_of_value |
301 | | |
302 | | static inline ccv_nnc_micro_loop_index_term_t ccv_nnc_micro_index_of_id(const ccv_nnc_micro_id_t id) |
303 | 81 | { |
304 | 81 | return (ccv_nnc_micro_loop_index_term_t){ |
305 | 81 | .type = CCV_NNC_MICRO_LOOP_INDEX_TYPE_ID, |
306 | 81 | .id = id |
307 | 81 | }; |
308 | 81 | } Unexecuted instantiation: ccv_nnc_micro.c:ccv_nnc_micro_index_of_id ccv_nnc_micro_core.c:ccv_nnc_micro_index_of_id Line | Count | Source | 303 | 81 | { | 304 | 81 | return (ccv_nnc_micro_loop_index_term_t){ | 305 | 81 | .type = CCV_NNC_MICRO_LOOP_INDEX_TYPE_ID, | 306 | 81 | .id = id | 307 | 81 | }; | 308 | 81 | } |
Unexecuted instantiation: ccv_nnc_micro_interpret.c:ccv_nnc_micro_index_of_id Unexecuted instantiation: ccv_nnc_micro_simplify.c:ccv_nnc_micro_index_of_id |
309 | | |
310 | | static inline ccv_nnc_micro_loop_index_term_t ccv_nnc_micro_index_of_axis_size(const int id, const int level) |
311 | 258 | { |
312 | 258 | return (ccv_nnc_micro_loop_index_term_t){ |
313 | 258 | .type = CCV_NNC_MICRO_LOOP_INDEX_TYPE_ID, |
314 | 258 | .id = { |
315 | 258 | .type = CCV_NNC_MICRO_AXIS_SIZE_ID, |
316 | 258 | .id = id, |
317 | 258 | .d = level |
318 | 258 | } |
319 | 258 | }; |
320 | 258 | } Unexecuted instantiation: ccv_nnc_micro.c:ccv_nnc_micro_index_of_axis_size ccv_nnc_micro_core.c:ccv_nnc_micro_index_of_axis_size Line | Count | Source | 311 | 258 | { | 312 | 258 | return (ccv_nnc_micro_loop_index_term_t){ | 313 | 258 | .type = CCV_NNC_MICRO_LOOP_INDEX_TYPE_ID, | 314 | 258 | .id = { | 315 | 258 | .type = CCV_NNC_MICRO_AXIS_SIZE_ID, | 316 | 258 | .id = id, | 317 | 258 | .d = level | 318 | 258 | } | 319 | 258 | }; | 320 | 258 | } |
Unexecuted instantiation: ccv_nnc_micro_interpret.c:ccv_nnc_micro_index_of_axis_size Unexecuted instantiation: ccv_nnc_micro_simplify.c:ccv_nnc_micro_index_of_axis_size |
321 | | |
322 | | static inline ccv_nnc_micro_loop_t ccv_nnc_micro_for_in(const ccv_nnc_micro_loop_index_term_t start_index, const ccv_nnc_micro_loop_index_term_t end_index, const int level) |
323 | 241 | { |
324 | 241 | return (ccv_nnc_micro_loop_t){ |
325 | 241 | .start_index = start_index, |
326 | 241 | .end_index = end_index, |
327 | 241 | .carried_count = 0, |
328 | 241 | .carrieds = 0, |
329 | 241 | .statement_count = 0, |
330 | 241 | .statements = 0, |
331 | 241 | .id = { |
332 | 241 | .type = CCV_NNC_MICRO_LOOP_ID, |
333 | 241 | .d = 0, |
334 | 241 | .id = level, |
335 | 241 | } |
336 | 241 | }; |
337 | 241 | } Unexecuted instantiation: ccv_nnc_micro.c:ccv_nnc_micro_for_in ccv_nnc_micro_core.c:ccv_nnc_micro_for_in Line | Count | Source | 323 | 241 | { | 324 | 241 | return (ccv_nnc_micro_loop_t){ | 325 | 241 | .start_index = start_index, | 326 | 241 | .end_index = end_index, | 327 | 241 | .carried_count = 0, | 328 | 241 | .carrieds = 0, | 329 | 241 | .statement_count = 0, | 330 | 241 | .statements = 0, | 331 | 241 | .id = { | 332 | 241 | .type = CCV_NNC_MICRO_LOOP_ID, | 333 | 241 | .d = 0, | 334 | 241 | .id = level, | 335 | 241 | } | 336 | 241 | }; | 337 | 241 | } |
Unexecuted instantiation: ccv_nnc_micro_interpret.c:ccv_nnc_micro_for_in Unexecuted instantiation: ccv_nnc_micro_simplify.c:ccv_nnc_micro_for_in |
338 | | |
339 | | // This is a macro because C cannot return array type. |
340 | | #define ccv_nnc_micro_index_of_loops(_loops, _loop_count) \ |
341 | 60 | (ccv_nnc_micro_loop_index_term_t [CCV_NNC_MAX_DIM_ALLOC]){ \ |
342 | 60 | { .type = CCV_NNC_MICRO_LOOP_INDEX_TYPE_ID, .id = _loop_count > 0 ? _loops[0].id : (ccv_nnc_micro_id_t){}0 }, \ |
343 | 60 | { .type = CCV_NNC_MICRO_LOOP_INDEX_TYPE_ID, .id = _loop_count > 1 ? _loops[1].id : (ccv_nnc_micro_id_t){}0 }, \ |
344 | 60 | { .type = CCV_NNC_MICRO_LOOP_INDEX_TYPE_ID, .id = _loop_count > 2 ? _loops[2].id58 : (ccv_nnc_micro_id_t){}2 }, \ |
345 | 60 | { .type = CCV_NNC_MICRO_LOOP_INDEX_TYPE_ID, .id = _loop_count > 3 ? _loops[3].id40 : (ccv_nnc_micro_id_t){}20 }, \ |
346 | 60 | { .type = CCV_NNC_MICRO_LOOP_INDEX_TYPE_ID, .id = _loop_count > 4 ? _loops[4].id36 : (ccv_nnc_micro_id_t){}24 }, \ |
347 | 60 | { .type = CCV_NNC_MICRO_LOOP_INDEX_TYPE_ID, .id = _loop_count > 5 ? _loops[5].id36 : (ccv_nnc_micro_id_t){}24 }, \ |
348 | 60 | { .type = CCV_NNC_MICRO_LOOP_INDEX_TYPE_ID, .id = _loop_count > 6 ? _loops[6].id36 : (ccv_nnc_micro_id_t){}24 }, \ |
349 | 60 | { .type = CCV_NNC_MICRO_LOOP_INDEX_TYPE_ID, .id = _loop_count > 7 ? _loops[7].id0 : (ccv_nnc_micro_id_t){} } \ |
350 | 60 | } |
351 | | |
352 | | static inline ccv_nnc_micro_loop_variable_t ccv_nnc_micro_loop_variable_of_tensor(const int id, const int index_count, const ccv_nnc_micro_loop_index_term_t* const index) |
353 | 96 | { |
354 | 96 | ccv_nnc_micro_loop_variable_t variable = { |
355 | 96 | .id = ccv_nnc_micro_id_of_tensor(id), |
356 | 96 | .index_count = index_count |
357 | 96 | }; |
358 | 96 | int i; |
359 | 584 | for (i = 0; i < index_count; i++488 ) |
360 | 488 | variable.index[i] = index[i]; |
361 | 96 | return variable; |
362 | 96 | } Unexecuted instantiation: ccv_nnc_micro.c:ccv_nnc_micro_loop_variable_of_tensor ccv_nnc_micro_core.c:ccv_nnc_micro_loop_variable_of_tensor Line | Count | Source | 353 | 96 | { | 354 | 96 | ccv_nnc_micro_loop_variable_t variable = { | 355 | 96 | .id = ccv_nnc_micro_id_of_tensor(id), | 356 | 96 | .index_count = index_count | 357 | 96 | }; | 358 | 96 | int i; | 359 | 584 | for (i = 0; i < index_count; i++488 ) | 360 | 488 | variable.index[i] = index[i]; | 361 | 96 | return variable; | 362 | 96 | } |
Unexecuted instantiation: ccv_nnc_micro_interpret.c:ccv_nnc_micro_loop_variable_of_tensor Unexecuted instantiation: ccv_nnc_micro_simplify.c:ccv_nnc_micro_loop_variable_of_tensor |
363 | | |
364 | | static inline ccv_nnc_micro_loop_expression_t ccv_nnc_micro_loop_expression_of_variable(const ccv_nnc_micro_loop_variable_t variable) |
365 | 51 | { |
366 | 51 | return (ccv_nnc_micro_loop_expression_t){ |
367 | 51 | .type = CCV_NNC_MICRO_LOOP_EXPR_TYPE_VAR, |
368 | 51 | .variable = variable |
369 | 51 | }; |
370 | 51 | } Unexecuted instantiation: ccv_nnc_micro.c:ccv_nnc_micro_loop_expression_of_variable ccv_nnc_micro_core.c:ccv_nnc_micro_loop_expression_of_variable Line | Count | Source | 365 | 51 | { | 366 | 51 | return (ccv_nnc_micro_loop_expression_t){ | 367 | 51 | .type = CCV_NNC_MICRO_LOOP_EXPR_TYPE_VAR, | 368 | 51 | .variable = variable | 369 | 51 | }; | 370 | 51 | } |
Unexecuted instantiation: ccv_nnc_micro_interpret.c:ccv_nnc_micro_loop_expression_of_variable Unexecuted instantiation: ccv_nnc_micro_simplify.c:ccv_nnc_micro_loop_expression_of_variable |
371 | | |
372 | | static inline ccv_nnc_micro_loop_expression_t ccv_nnc_micro_loop_expression_of_value(const float value) |
373 | 6 | { |
374 | 6 | return (ccv_nnc_micro_loop_expression_t){ |
375 | 6 | .type = CCV_NNC_MICRO_LOOP_EXPR_TYPE_VAL, |
376 | 6 | .immediate_value = { |
377 | 6 | .type = CCV_32F, |
378 | 6 | .f32 = value |
379 | 6 | } |
380 | 6 | }; |
381 | 6 | } Unexecuted instantiation: ccv_nnc_micro.c:ccv_nnc_micro_loop_expression_of_value ccv_nnc_micro_core.c:ccv_nnc_micro_loop_expression_of_value Line | Count | Source | 373 | 6 | { | 374 | 6 | return (ccv_nnc_micro_loop_expression_t){ | 375 | 6 | .type = CCV_NNC_MICRO_LOOP_EXPR_TYPE_VAL, | 376 | 6 | .immediate_value = { | 377 | 6 | .type = CCV_32F, | 378 | 6 | .f32 = value | 379 | 6 | } | 380 | 6 | }; | 381 | 6 | } |
Unexecuted instantiation: ccv_nnc_micro_interpret.c:ccv_nnc_micro_loop_expression_of_value Unexecuted instantiation: ccv_nnc_micro_simplify.c:ccv_nnc_micro_loop_expression_of_value |
382 | | |
383 | | static inline ccv_nnc_micro_loop_expression_t ccv_nnc_micro_loop_expression_of_id(const ccv_nnc_micro_id_t id) |
384 | 6 | { |
385 | 6 | return (ccv_nnc_micro_loop_expression_t){ |
386 | 6 | .type = CCV_NNC_MICRO_LOOP_EXPR_TYPE_ID, |
387 | 6 | .id = id |
388 | 6 | }; |
389 | 6 | } Unexecuted instantiation: ccv_nnc_micro.c:ccv_nnc_micro_loop_expression_of_id ccv_nnc_micro_core.c:ccv_nnc_micro_loop_expression_of_id Line | Count | Source | 384 | 6 | { | 385 | 6 | return (ccv_nnc_micro_loop_expression_t){ | 386 | 6 | .type = CCV_NNC_MICRO_LOOP_EXPR_TYPE_ID, | 387 | 6 | .id = id | 388 | 6 | }; | 389 | 6 | } |
Unexecuted instantiation: ccv_nnc_micro_interpret.c:ccv_nnc_micro_loop_expression_of_id Unexecuted instantiation: ccv_nnc_micro_simplify.c:ccv_nnc_micro_loop_expression_of_id |
390 | | |
391 | | static inline ccv_nnc_micro_loop_statement_t ccv_nnc_micro_loop_assignment(const ccv_nnc_micro_loop_variable_t lvalue, const ccv_nnc_micro_loop_expression_t rvalue) |
392 | 39 | { |
393 | 39 | return (ccv_nnc_micro_loop_statement_t){ |
394 | 39 | .type = CCV_NNC_MICRO_LOOP_STATEMENT_TYPE_ASSIGNMENT, |
395 | 39 | .assignment = { |
396 | 39 | .lvalue = lvalue, |
397 | 39 | .rvalue = rvalue |
398 | 39 | } |
399 | 39 | }; |
400 | 39 | } Unexecuted instantiation: ccv_nnc_micro.c:ccv_nnc_micro_loop_assignment ccv_nnc_micro_core.c:ccv_nnc_micro_loop_assignment Line | Count | Source | 392 | 39 | { | 393 | 39 | return (ccv_nnc_micro_loop_statement_t){ | 394 | 39 | .type = CCV_NNC_MICRO_LOOP_STATEMENT_TYPE_ASSIGNMENT, | 395 | 39 | .assignment = { | 396 | 39 | .lvalue = lvalue, | 397 | 39 | .rvalue = rvalue | 398 | 39 | } | 399 | 39 | }; | 400 | 39 | } |
Unexecuted instantiation: ccv_nnc_micro_interpret.c:ccv_nnc_micro_loop_assignment Unexecuted instantiation: ccv_nnc_micro_simplify.c:ccv_nnc_micro_loop_assignment |
401 | | |
402 | | static inline ccv_nnc_micro_loop_expression_t ccv_nnc_micro_loop_expression_of_unary(const int unary_op, const ccv_nnc_micro_loop_expression_t x) |
403 | 0 | { |
404 | 0 | ccv_nnc_micro_loop_expression_t expression = { |
405 | 0 | .type = CCV_NNC_MICRO_LOOP_EXPR_TYPE_BINARY |
406 | 0 | }; |
407 | 0 | expression.unary.unary_op = unary_op; |
408 | 0 | expression.unary.x = (ccv_nnc_micro_loop_expression_t*)ccmalloc(sizeof(ccv_nnc_micro_loop_expression_t)); |
409 | 0 | *expression.unary.x = x; |
410 | 0 | return expression; |
411 | 0 | } Unexecuted instantiation: ccv_nnc_micro.c:ccv_nnc_micro_loop_expression_of_unary Unexecuted instantiation: ccv_nnc_micro_core.c:ccv_nnc_micro_loop_expression_of_unary Unexecuted instantiation: ccv_nnc_micro_interpret.c:ccv_nnc_micro_loop_expression_of_unary Unexecuted instantiation: ccv_nnc_micro_simplify.c:ccv_nnc_micro_loop_expression_of_unary |
412 | | |
413 | | static inline ccv_nnc_micro_loop_expression_t ccv_nnc_micro_loop_expression_of_binary(const int binary_op, const ccv_nnc_micro_loop_expression_t left, const ccv_nnc_micro_loop_expression_t right) |
414 | 12 | { |
415 | 12 | ccv_nnc_micro_loop_expression_t expression = { |
416 | 12 | .type = CCV_NNC_MICRO_LOOP_EXPR_TYPE_BINARY |
417 | 12 | }; |
418 | 12 | expression.binary.binary_op = binary_op; |
419 | 12 | expression.binary.left = (ccv_nnc_micro_loop_expression_t*)ccmalloc(sizeof(ccv_nnc_micro_loop_expression_t)); |
420 | 12 | *expression.binary.left = left; |
421 | 12 | expression.binary.right = (ccv_nnc_micro_loop_expression_t*)ccmalloc(sizeof(ccv_nnc_micro_loop_expression_t)); |
422 | 12 | *expression.binary.right = right; |
423 | 12 | return expression; |
424 | 12 | } Unexecuted instantiation: ccv_nnc_micro.c:ccv_nnc_micro_loop_expression_of_binary ccv_nnc_micro_core.c:ccv_nnc_micro_loop_expression_of_binary Line | Count | Source | 414 | 12 | { | 415 | 12 | ccv_nnc_micro_loop_expression_t expression = { | 416 | 12 | .type = CCV_NNC_MICRO_LOOP_EXPR_TYPE_BINARY | 417 | 12 | }; | 418 | 12 | expression.binary.binary_op = binary_op; | 419 | 12 | expression.binary.left = (ccv_nnc_micro_loop_expression_t*)ccmalloc(sizeof(ccv_nnc_micro_loop_expression_t)); | 420 | 12 | *expression.binary.left = left; | 421 | 12 | expression.binary.right = (ccv_nnc_micro_loop_expression_t*)ccmalloc(sizeof(ccv_nnc_micro_loop_expression_t)); | 422 | 12 | *expression.binary.right = right; | 423 | 12 | return expression; | 424 | 12 | } |
Unexecuted instantiation: ccv_nnc_micro_interpret.c:ccv_nnc_micro_loop_expression_of_binary Unexecuted instantiation: ccv_nnc_micro_simplify.c:ccv_nnc_micro_loop_expression_of_binary |
425 | | |
426 | | static inline ccv_nnc_micro_loop_expression_t ccv_nnc_micro_loop_expression_of_ternary(const ccv_nnc_micro_loop_expression_t pivot, const ccv_nnc_micro_loop_expression_t left, const ccv_nnc_micro_loop_expression_t right) |
427 | 0 | { |
428 | 0 | ccv_nnc_micro_loop_expression_t expression = { |
429 | 0 | .type = CCV_NNC_MICRO_LOOP_EXPR_TYPE_TERNAY |
430 | 0 | }; |
431 | 0 | expression.ternary.pivot = (ccv_nnc_micro_loop_expression_t*)ccmalloc(sizeof(ccv_nnc_micro_loop_expression_t)); |
432 | 0 | *expression.ternary.pivot = pivot; |
433 | 0 | expression.ternary.left = (ccv_nnc_micro_loop_expression_t*)ccmalloc(sizeof(ccv_nnc_micro_loop_expression_t)); |
434 | 0 | *expression.ternary.left = left; |
435 | 0 | expression.ternary.right = (ccv_nnc_micro_loop_expression_t*)ccmalloc(sizeof(ccv_nnc_micro_loop_expression_t)); |
436 | 0 | *expression.ternary.right = right; |
437 | 0 | return expression; |
438 | 0 | } Unexecuted instantiation: ccv_nnc_micro.c:ccv_nnc_micro_loop_expression_of_ternary Unexecuted instantiation: ccv_nnc_micro_core.c:ccv_nnc_micro_loop_expression_of_ternary Unexecuted instantiation: ccv_nnc_micro_interpret.c:ccv_nnc_micro_loop_expression_of_ternary Unexecuted instantiation: ccv_nnc_micro_simplify.c:ccv_nnc_micro_loop_expression_of_ternary |
439 | | |
440 | | static inline ccv_nnc_micro_loop_statement_t ccv_nnc_micro_loop_compound_assignment_of_id(const ccv_nnc_micro_id_t lvalue, const ccv_nnc_micro_loop_expression_t rvalue) |
441 | 6 | { |
442 | 6 | return (ccv_nnc_micro_loop_statement_t){ |
443 | 6 | .type = CCV_NNC_MICRO_LOOP_STATEMENT_TYPE_COMPOUND_ASSIGNMENT, |
444 | 6 | .compound_assignment = { |
445 | 6 | .lvalue = { |
446 | 6 | .type = CCV_NNC_MICRO_LOOP_EXPR_TYPE_ID, |
447 | 6 | .id = lvalue |
448 | 6 | }, |
449 | 6 | .rvalue = rvalue |
450 | 6 | } |
451 | 6 | }; |
452 | 6 | } Unexecuted instantiation: ccv_nnc_micro.c:ccv_nnc_micro_loop_compound_assignment_of_id ccv_nnc_micro_core.c:ccv_nnc_micro_loop_compound_assignment_of_id Line | Count | Source | 441 | 6 | { | 442 | 6 | return (ccv_nnc_micro_loop_statement_t){ | 443 | 6 | .type = CCV_NNC_MICRO_LOOP_STATEMENT_TYPE_COMPOUND_ASSIGNMENT, | 444 | 6 | .compound_assignment = { | 445 | 6 | .lvalue = { | 446 | 6 | .type = CCV_NNC_MICRO_LOOP_EXPR_TYPE_ID, | 447 | 6 | .id = lvalue | 448 | 6 | }, | 449 | 6 | .rvalue = rvalue | 450 | 6 | } | 451 | 6 | }; | 452 | 6 | } |
Unexecuted instantiation: ccv_nnc_micro_interpret.c:ccv_nnc_micro_loop_compound_assignment_of_id Unexecuted instantiation: ccv_nnc_micro_simplify.c:ccv_nnc_micro_loop_compound_assignment_of_id |
453 | | |
454 | | static inline ccv_nnc_micro_loop_statement_t ccv_nnc_micro_loop_compound_assignment_of_tensor(const ccv_nnc_micro_loop_variable_t lvalue, const ccv_nnc_micro_loop_expression_t rvalue) |
455 | 6 | { |
456 | 6 | return (ccv_nnc_micro_loop_statement_t){ |
457 | 6 | .type = CCV_NNC_MICRO_LOOP_STATEMENT_TYPE_COMPOUND_ASSIGNMENT, |
458 | 6 | .compound_assignment = { |
459 | 6 | .lvalue = { |
460 | 6 | .type = CCV_NNC_MICRO_LOOP_EXPR_TYPE_VAR, |
461 | 6 | .variable = lvalue |
462 | 6 | }, |
463 | 6 | .rvalue = rvalue |
464 | 6 | } |
465 | 6 | }; |
466 | 6 | } Unexecuted instantiation: ccv_nnc_micro.c:ccv_nnc_micro_loop_compound_assignment_of_tensor ccv_nnc_micro_core.c:ccv_nnc_micro_loop_compound_assignment_of_tensor Line | Count | Source | 455 | 6 | { | 456 | 6 | return (ccv_nnc_micro_loop_statement_t){ | 457 | 6 | .type = CCV_NNC_MICRO_LOOP_STATEMENT_TYPE_COMPOUND_ASSIGNMENT, | 458 | 6 | .compound_assignment = { | 459 | 6 | .lvalue = { | 460 | 6 | .type = CCV_NNC_MICRO_LOOP_EXPR_TYPE_VAR, | 461 | 6 | .variable = lvalue | 462 | 6 | }, | 463 | 6 | .rvalue = rvalue | 464 | 6 | } | 465 | 6 | }; | 466 | 6 | } |
Unexecuted instantiation: ccv_nnc_micro_interpret.c:ccv_nnc_micro_loop_compound_assignment_of_tensor Unexecuted instantiation: ccv_nnc_micro_simplify.c:ccv_nnc_micro_loop_compound_assignment_of_tensor |
467 | | |
468 | | static inline ccv_nnc_micro_loop_carried_t ccv_nnc_micro_loop_carried(const uint8_t reduce_op, const int idx) |
469 | 6 | { |
470 | 6 | return (ccv_nnc_micro_loop_carried_t){ |
471 | 6 | .id = { |
472 | 6 | .type = CCV_NNC_MICRO_LOOP_CARRIED_ID, |
473 | 6 | .d = reduce_op, |
474 | 6 | .id = idx |
475 | 6 | } |
476 | 6 | }; |
477 | 6 | } Unexecuted instantiation: ccv_nnc_micro.c:ccv_nnc_micro_loop_carried ccv_nnc_micro_core.c:ccv_nnc_micro_loop_carried Line | Count | Source | 469 | 6 | { | 470 | 6 | return (ccv_nnc_micro_loop_carried_t){ | 471 | 6 | .id = { | 472 | 6 | .type = CCV_NNC_MICRO_LOOP_CARRIED_ID, | 473 | 6 | .d = reduce_op, | 474 | 6 | .id = idx | 475 | 6 | } | 476 | 6 | }; | 477 | 6 | } |
Unexecuted instantiation: ccv_nnc_micro_interpret.c:ccv_nnc_micro_loop_carried Unexecuted instantiation: ccv_nnc_micro_simplify.c:ccv_nnc_micro_loop_carried |
478 | | |
479 | | // This method has to be mutable for efficiency reasons. Hence I kept it private. |
480 | | void ccv_nnc_micro_program_simplify(ccv_nnc_micro_program_t* const program, const ccv_nnc_micro_io_t* const inputs, const int input_size, const ccv_nnc_micro_io_t* const outputs, const int output_size, const ccv_array_t* const equal_assertions); |
481 | | ccv_nnc_micro_loop_index_term_t ccv_nnc_micro_loop_index_deep_copy(const ccv_nnc_micro_loop_index_term_t* const term); |
482 | | void ccv_nnc_micro_loop_index_free(ccv_nnc_micro_loop_index_term_t* const term); |
483 | | void ccv_nnc_micro_loop_variable_free(ccv_nnc_micro_loop_variable_t* const var); |
484 | | void ccv_nnc_micro_loop_statement_free(ccv_nnc_micro_loop_statement_t* const statement); |
485 | | void ccv_nnc_micro_loop_statement_lvalue_free(ccv_nnc_micro_loop_statement_t* const statement); |
486 | | void ccv_nnc_micro_loops_free(ccv_nnc_micro_loop_t* const loops, const int loop_count); |
487 | | |
488 | | #endif |