Coverage Report

Created: 2024-08-19 11:27

/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