Coverage Report

Created: 2021-04-07 03:47

/home/liu/buildslave/linux-x64-runtests/build/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
};
207
208
typedef uint32_t(*ccv_nnc_micro_scalar_lookup_f)(const void* const context, const char* const name);
209
210
/**
211
 * This is the virtual table for micro op.
212
 */
213
struct ccv_nnc_micro_io_vtab_s {
214
  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. */
215
  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. */
216
  void (*equal_assertions)(const ccv_nnc_micro_io_t self, ccv_array_t* const equal_assertions); /**< Collect assertions about id equal. */
217
  ccv_nnc_micro_function_t (*emit)(const ccv_nnc_micro_io_t self); /**< Emit instructions for this micro op. */
218
  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. */
219
  ccv_nnc_micro_tensor_t (*return_shape)(const ccv_nnc_micro_io_t self); /**< The shape of the returned tensor. */
220
  void (*deinit)(const ccv_nnc_micro_io_t self); /**< Deinit this micro io. */
221
};
222
223
extern const ccv_nnc_micro_io_vtab_t ccv_nnc_micro_io_input_isa;
224
extern const ccv_nnc_micro_io_vtab_t ccv_nnc_micro_io_grad_isa;
225
226
25
#define CCV_NNC_IS_MICRO_IO_INPUT(x) ((x)->isa == &ccv_nnc_micro_io_input_isa)
227
15
#define CCV_NNC_IS_MICRO_IO_GRAD(x) ((x)->isa == &ccv_nnc_micro_io_grad_isa)
228
229
static inline void ccv_nnc_micro_numbering(const ccv_nnc_micro_io_t self, const int id, const int var_count)
230
33
{
231
33
  const ccv_nnc_micro_io_vtab_t* const isa = self->isa;
232
33
  // If we numbering with negative id, we really just enumerate the grad.
233
33
  if (id < 0 && 
!15
CCV_NNC_IS_MICRO_IO_GRAD15
(self))
234
33
    
return6
;
235
27
  if (isa->numbering)
236
15
    isa->numbering(self, id, var_count);
237
12
  else
238
12
    self->id = id;
239
27
}
ccv_nnc_micro.c:ccv_nnc_micro_numbering
Line
Count
Source
230
33
{
231
33
  const ccv_nnc_micro_io_vtab_t* const isa = self->isa;
232
33
  // If we numbering with negative id, we really just enumerate the grad.
233
33
  if (id < 0 && 
!15
CCV_NNC_IS_MICRO_IO_GRAD15
(self))
234
33
    
return6
;
235
27
  if (isa->numbering)
236
15
    isa->numbering(self, id, var_count);
237
12
  else
238
12
    self->id = id;
239
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
240
241
static inline void ccv_nnc_micro_equal_assertions(const ccv_nnc_micro_io_t self, ccv_array_t* const equal_assertions)
242
12
{
243
12
  const ccv_nnc_micro_io_vtab_t* const isa = self->isa;
244
12
  if (isa->equal_assertions)
245
6
    isa->equal_assertions(self, equal_assertions);
246
12
}
ccv_nnc_micro.c:ccv_nnc_micro_equal_assertions
Line
Count
Source
242
12
{
243
12
  const ccv_nnc_micro_io_vtab_t* const isa = self->isa;
244
12
  if (isa->equal_assertions)
245
6
    isa->equal_assertions(self, equal_assertions);
246
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
247
248
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)
249
12
{
250
12
  const ccv_nnc_micro_io_vtab_t* const isa = self->isa;
251
12
  if (isa->bind_scalars)
252
6
    isa->bind_scalars(self, lookup, context);
253
12
}
ccv_nnc_micro.c:ccv_nnc_micro_bind_scalars
Line
Count
Source
249
12
{
250
12
  const ccv_nnc_micro_io_vtab_t* const isa = self->isa;
251
12
  if (isa->bind_scalars)
252
6
    isa->bind_scalars(self, lookup, context);
253
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
254
255
static inline void ccv_nnc_micro_deinit(const ccv_nnc_micro_io_t self)
256
27
{
257
27
  const ccv_nnc_micro_io_vtab_t* const isa = self->isa;
258
27
  if (isa->deinit)
259
6
    isa->deinit(self);
260
27
}
ccv_nnc_micro.c:ccv_nnc_micro_deinit
Line
Count
Source
256
27
{
257
27
  const ccv_nnc_micro_io_vtab_t* const isa = self->isa;
258
27
  if (isa->deinit)
259
6
    isa->deinit(self);
260
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
261
262
static inline CCV_WARN_UNUSED(ccv_nnc_micro_function_t) ccv_nnc_micro_emit(const ccv_nnc_micro_io_t self)
263
24
{
264
24
  const ccv_nnc_micro_io_vtab_t* const isa = self->isa;
265
24
  return isa->emit(self);
266
24
}
ccv_nnc_micro.c:ccv_nnc_micro_emit
Line
Count
Source
263
24
{
264
24
  const ccv_nnc_micro_io_vtab_t* const isa = self->isa;
265
24
  return isa->emit(self);
266
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
267
268
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)
269
12
{
270
12
  const ccv_nnc_micro_io_vtab_t* const isa = self->isa;
271
12
  return isa->emit_grad(self, var_count);
272
12
}
ccv_nnc_micro.c:ccv_nnc_micro_emit_grad
Line
Count
Source
269
12
{
270
12
  const ccv_nnc_micro_io_vtab_t* const isa = self->isa;
271
12
  return isa->emit_grad(self, var_count);
272
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
273
274
static inline CCV_WARN_UNUSED(ccv_nnc_micro_tensor_t) ccv_nnc_micro_return_shape(const ccv_nnc_micro_io_t self)
275
12
{
276
12
  const ccv_nnc_micro_io_vtab_t* const isa = self->isa;
277
12
  return isa->return_shape(self);
278
12
}
ccv_nnc_micro.c:ccv_nnc_micro_return_shape
Line
Count
Source
275
12
{
276
12
  const ccv_nnc_micro_io_vtab_t* const isa = self->isa;
277
12
  return isa->return_shape(self);
278
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
279
280
/**
281
 * Helpers to construct the micro IR.
282
 */
283
284
static inline ccv_nnc_micro_id_t ccv_nnc_micro_id_of_tensor(const int id)
285
96
{
286
96
  return (ccv_nnc_micro_id_t){
287
96
    .type = CCV_NNC_MICRO_TENSOR_ID,
288
96
    .id = id,
289
96
    .d = 0
290
96
  };
291
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
285
96
{
286
96
  return (ccv_nnc_micro_id_t){
287
96
    .type = CCV_NNC_MICRO_TENSOR_ID,
288
96
    .id = id,
289
96
    .d = 0
290
96
  };
291
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
292
293
static inline ccv_nnc_micro_loop_index_term_t ccv_nnc_micro_index_of_value(const int value)
294
269
{
295
269
  return (ccv_nnc_micro_loop_index_term_t){
296
269
    .type = CCV_NNC_MICRO_LOOP_INDEX_TYPE_VAL,
297
269
    .immediate_value = value
298
269
  };
299
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
294
269
{
295
269
  return (ccv_nnc_micro_loop_index_term_t){
296
269
    .type = CCV_NNC_MICRO_LOOP_INDEX_TYPE_VAL,
297
269
    .immediate_value = value
298
269
  };
299
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
300
301
static inline ccv_nnc_micro_loop_index_term_t ccv_nnc_micro_index_of_id(const ccv_nnc_micro_id_t id)
302
81
{
303
81
  return (ccv_nnc_micro_loop_index_term_t){
304
81
    .type = CCV_NNC_MICRO_LOOP_INDEX_TYPE_ID,
305
81
    .id = id
306
81
  };
307
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
302
81
{
303
81
  return (ccv_nnc_micro_loop_index_term_t){
304
81
    .type = CCV_NNC_MICRO_LOOP_INDEX_TYPE_ID,
305
81
    .id = id
306
81
  };
307
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
308
309
static inline ccv_nnc_micro_loop_index_term_t ccv_nnc_micro_index_of_axis_size(const int id, const int level)
310
258
{
311
258
  return (ccv_nnc_micro_loop_index_term_t){
312
258
    .type = CCV_NNC_MICRO_LOOP_INDEX_TYPE_ID,
313
258
    .id = {
314
258
      .type = CCV_NNC_MICRO_AXIS_SIZE_ID,
315
258
      .id = id,
316
258
      .d = level
317
258
    }
318
258
  };
319
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
310
258
{
311
258
  return (ccv_nnc_micro_loop_index_term_t){
312
258
    .type = CCV_NNC_MICRO_LOOP_INDEX_TYPE_ID,
313
258
    .id = {
314
258
      .type = CCV_NNC_MICRO_AXIS_SIZE_ID,
315
258
      .id = id,
316
258
      .d = level
317
258
    }
318
258
  };
319
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
320
321
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)
322
241
{
323
241
  return (ccv_nnc_micro_loop_t){
324
241
    .start_index = start_index,
325
241
    .end_index = end_index,
326
241
    .carried_count = 0,
327
241
    .carrieds = 0,
328
241
    .statement_count = 0,
329
241
    .statements = 0,
330
241
    .id = {
331
241
      .type = CCV_NNC_MICRO_LOOP_ID,
332
241
      .d = 0,
333
241
      .id = level,
334
241
    }
335
241
  };
336
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
322
241
{
323
241
  return (ccv_nnc_micro_loop_t){
324
241
    .start_index = start_index,
325
241
    .end_index = end_index,
326
241
    .carried_count = 0,
327
241
    .carrieds = 0,
328
241
    .statement_count = 0,
329
241
    .statements = 0,
330
241
    .id = {
331
241
      .type = CCV_NNC_MICRO_LOOP_ID,
332
241
      .d = 0,
333
241
      .id = level,
334
241
    }
335
241
  };
336
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
337
338
// This is a macro because C cannot return array type.
339
#define ccv_nnc_micro_index_of_loops(_loops, _loop_count) \
340
60
  (ccv_nnc_micro_loop_index_term_t [CCV_NNC_MAX_DIM_ALLOC]){ \
341
60
    { .type = CCV_NNC_MICRO_LOOP_INDEX_TYPE_ID, .id = _loop_count > 0 ? _loops[0].id : 
(ccv_nnc_micro_id_t){}0
}, \
342
60
    { .type = CCV_NNC_MICRO_LOOP_INDEX_TYPE_ID, .id = _loop_count > 1 ? _loops[1].id : 
(ccv_nnc_micro_id_t){}0
}, \
343
60
    { .type = CCV_NNC_MICRO_LOOP_INDEX_TYPE_ID, .id = _loop_count > 2 ? 
_loops[2].id58
:
(ccv_nnc_micro_id_t){}2
}, \
344
60
    { .type = CCV_NNC_MICRO_LOOP_INDEX_TYPE_ID, .id = _loop_count > 3 ? 
_loops[3].id40
:
(ccv_nnc_micro_id_t){}20
}, \
345
60
    { .type = CCV_NNC_MICRO_LOOP_INDEX_TYPE_ID, .id = _loop_count > 4 ? 
_loops[4].id36
:
(ccv_nnc_micro_id_t){}24
}, \
346
60
    { .type = CCV_NNC_MICRO_LOOP_INDEX_TYPE_ID, .id = _loop_count > 5 ? 
_loops[5].id36
:
(ccv_nnc_micro_id_t){}24
}, \
347
60
    { .type = CCV_NNC_MICRO_LOOP_INDEX_TYPE_ID, .id = _loop_count > 6 ? 
_loops[6].id36
:
(ccv_nnc_micro_id_t){}24
}, \
348
60
    { .type = CCV_NNC_MICRO_LOOP_INDEX_TYPE_ID, .id = _loop_count > 7 ? 
_loops[7].id0
: (ccv_nnc_micro_id_t){} } \
349
60
  }
350
351
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)
352
96
{
353
96
  ccv_nnc_micro_loop_variable_t variable = {
354
96
    .id = ccv_nnc_micro_id_of_tensor(id),
355
96
    .index_count = index_count
356
96
  };
357
96
  int i;
358
584
  for (i = 0; i < index_count; 
i++488
)
359
488
    variable.index[i] = index[i];
360
96
  return variable;
361
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
352
96
{
353
96
  ccv_nnc_micro_loop_variable_t variable = {
354
96
    .id = ccv_nnc_micro_id_of_tensor(id),
355
96
    .index_count = index_count
356
96
  };
357
96
  int i;
358
584
  for (i = 0; i < index_count; 
i++488
)
359
488
    variable.index[i] = index[i];
360
96
  return variable;
361
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
362
363
static inline ccv_nnc_micro_loop_expression_t ccv_nnc_micro_loop_expression_of_variable(const ccv_nnc_micro_loop_variable_t variable)
364
51
{
365
51
  return (ccv_nnc_micro_loop_expression_t){
366
51
    .type = CCV_NNC_MICRO_LOOP_EXPR_TYPE_VAR,
367
51
    .variable = variable
368
51
  };
369
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
364
51
{
365
51
  return (ccv_nnc_micro_loop_expression_t){
366
51
    .type = CCV_NNC_MICRO_LOOP_EXPR_TYPE_VAR,
367
51
    .variable = variable
368
51
  };
369
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
370
371
static inline ccv_nnc_micro_loop_expression_t ccv_nnc_micro_loop_expression_of_value(const float value)
372
6
{
373
6
  return (ccv_nnc_micro_loop_expression_t){
374
6
    .type = CCV_NNC_MICRO_LOOP_EXPR_TYPE_VAL,
375
6
    .immediate_value = {
376
6
      .type = CCV_32F,
377
6
      .f32 = value
378
6
    }
379
6
  };
380
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
372
6
{
373
6
  return (ccv_nnc_micro_loop_expression_t){
374
6
    .type = CCV_NNC_MICRO_LOOP_EXPR_TYPE_VAL,
375
6
    .immediate_value = {
376
6
      .type = CCV_32F,
377
6
      .f32 = value
378
6
    }
379
6
  };
380
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
381
382
static inline ccv_nnc_micro_loop_expression_t ccv_nnc_micro_loop_expression_of_id(const ccv_nnc_micro_id_t id)
383
6
{
384
6
  return (ccv_nnc_micro_loop_expression_t){
385
6
    .type = CCV_NNC_MICRO_LOOP_EXPR_TYPE_ID,
386
6
    .id = id
387
6
  };
388
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
383
6
{
384
6
  return (ccv_nnc_micro_loop_expression_t){
385
6
    .type = CCV_NNC_MICRO_LOOP_EXPR_TYPE_ID,
386
6
    .id = id
387
6
  };
388
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
389
390
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)
391
39
{
392
39
  return (ccv_nnc_micro_loop_statement_t){
393
39
    .type = CCV_NNC_MICRO_LOOP_STATEMENT_TYPE_ASSIGNMENT,
394
39
    .assignment = {
395
39
      .lvalue = lvalue,
396
39
      .rvalue = rvalue
397
39
    }
398
39
  };
399
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
391
39
{
392
39
  return (ccv_nnc_micro_loop_statement_t){
393
39
    .type = CCV_NNC_MICRO_LOOP_STATEMENT_TYPE_ASSIGNMENT,
394
39
    .assignment = {
395
39
      .lvalue = lvalue,
396
39
      .rvalue = rvalue
397
39
    }
398
39
  };
399
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
400
401
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)
402
0
{
403
0
  ccv_nnc_micro_loop_expression_t expression = {
404
0
    .type = CCV_NNC_MICRO_LOOP_EXPR_TYPE_BINARY
405
0
  };
406
0
  expression.unary.unary_op = unary_op;
407
0
  expression.unary.x = (ccv_nnc_micro_loop_expression_t*)ccmalloc(sizeof(ccv_nnc_micro_loop_expression_t));
408
0
  *expression.unary.x = x;
409
0
  return expression;
410
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
411
412
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)
413
12
{
414
12
  ccv_nnc_micro_loop_expression_t expression = {
415
12
    .type = CCV_NNC_MICRO_LOOP_EXPR_TYPE_BINARY
416
12
  };
417
12
  expression.binary.binary_op = binary_op;
418
12
  expression.binary.left = (ccv_nnc_micro_loop_expression_t*)ccmalloc(sizeof(ccv_nnc_micro_loop_expression_t));
419
12
  *expression.binary.left = left;
420
12
  expression.binary.right = (ccv_nnc_micro_loop_expression_t*)ccmalloc(sizeof(ccv_nnc_micro_loop_expression_t));
421
12
  *expression.binary.right = right;
422
12
  return expression;
423
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
413
12
{
414
12
  ccv_nnc_micro_loop_expression_t expression = {
415
12
    .type = CCV_NNC_MICRO_LOOP_EXPR_TYPE_BINARY
416
12
  };
417
12
  expression.binary.binary_op = binary_op;
418
12
  expression.binary.left = (ccv_nnc_micro_loop_expression_t*)ccmalloc(sizeof(ccv_nnc_micro_loop_expression_t));
419
12
  *expression.binary.left = left;
420
12
  expression.binary.right = (ccv_nnc_micro_loop_expression_t*)ccmalloc(sizeof(ccv_nnc_micro_loop_expression_t));
421
12
  *expression.binary.right = right;
422
12
  return expression;
423
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
424
425
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)
426
0
{
427
0
  ccv_nnc_micro_loop_expression_t expression = {
428
0
    .type = CCV_NNC_MICRO_LOOP_EXPR_TYPE_TERNAY
429
0
  };
430
0
  expression.ternary.pivot = (ccv_nnc_micro_loop_expression_t*)ccmalloc(sizeof(ccv_nnc_micro_loop_expression_t));
431
0
  *expression.ternary.pivot = pivot;
432
0
  expression.ternary.left = (ccv_nnc_micro_loop_expression_t*)ccmalloc(sizeof(ccv_nnc_micro_loop_expression_t));
433
0
  *expression.ternary.left = left;
434
0
  expression.ternary.right = (ccv_nnc_micro_loop_expression_t*)ccmalloc(sizeof(ccv_nnc_micro_loop_expression_t));
435
0
  *expression.ternary.right = right;
436
0
  return expression;
437
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
438
439
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)
440
6
{
441
6
  return (ccv_nnc_micro_loop_statement_t){
442
6
    .type = CCV_NNC_MICRO_LOOP_STATEMENT_TYPE_COMPOUND_ASSIGNMENT,
443
6
    .compound_assignment = {
444
6
      .lvalue = {
445
6
        .type = CCV_NNC_MICRO_LOOP_EXPR_TYPE_ID,
446
6
        .id = lvalue
447
6
      },
448
6
      .rvalue = rvalue
449
6
    }
450
6
  };
451
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
440
6
{
441
6
  return (ccv_nnc_micro_loop_statement_t){
442
6
    .type = CCV_NNC_MICRO_LOOP_STATEMENT_TYPE_COMPOUND_ASSIGNMENT,
443
6
    .compound_assignment = {
444
6
      .lvalue = {
445
6
        .type = CCV_NNC_MICRO_LOOP_EXPR_TYPE_ID,
446
6
        .id = lvalue
447
6
      },
448
6
      .rvalue = rvalue
449
6
    }
450
6
  };
451
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
452
453
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)
454
6
{
455
6
  return (ccv_nnc_micro_loop_statement_t){
456
6
    .type = CCV_NNC_MICRO_LOOP_STATEMENT_TYPE_COMPOUND_ASSIGNMENT,
457
6
    .compound_assignment = {
458
6
      .lvalue = {
459
6
        .type = CCV_NNC_MICRO_LOOP_EXPR_TYPE_VAR,
460
6
        .variable = lvalue
461
6
      },
462
6
      .rvalue = rvalue
463
6
    }
464
6
  };
465
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
454
6
{
455
6
  return (ccv_nnc_micro_loop_statement_t){
456
6
    .type = CCV_NNC_MICRO_LOOP_STATEMENT_TYPE_COMPOUND_ASSIGNMENT,
457
6
    .compound_assignment = {
458
6
      .lvalue = {
459
6
        .type = CCV_NNC_MICRO_LOOP_EXPR_TYPE_VAR,
460
6
        .variable = lvalue
461
6
      },
462
6
      .rvalue = rvalue
463
6
    }
464
6
  };
465
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
466
467
static inline ccv_nnc_micro_loop_carried_t ccv_nnc_micro_loop_carried(const uint8_t reduce_op, const int idx)
468
6
{
469
6
  return (ccv_nnc_micro_loop_carried_t){
470
6
    .id = {
471
6
      .type = CCV_NNC_MICRO_LOOP_CARRIED_ID,
472
6
      .d = reduce_op,
473
6
      .id = idx
474
6
    }
475
6
  };
476
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
468
6
{
469
6
  return (ccv_nnc_micro_loop_carried_t){
470
6
    .id = {
471
6
      .type = CCV_NNC_MICRO_LOOP_CARRIED_ID,
472
6
      .d = reduce_op,
473
6
      .id = idx
474
6
    }
475
6
  };
476
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
477
478
// This method has to be mutable for efficiency reasons. Hence I kept it private.
479
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);
480
ccv_nnc_micro_loop_index_term_t ccv_nnc_micro_loop_index_deep_copy(const ccv_nnc_micro_loop_index_term_t* const term);
481
void ccv_nnc_micro_loop_index_free(ccv_nnc_micro_loop_index_term_t* const term);
482
void ccv_nnc_micro_loop_variable_free(ccv_nnc_micro_loop_variable_t* const var);
483
void ccv_nnc_micro_loop_statement_free(ccv_nnc_micro_loop_statement_t* const statement);
484
void ccv_nnc_micro_loop_statement_lvalue_free(ccv_nnc_micro_loop_statement_t* const statement);
485
void ccv_nnc_micro_loops_free(ccv_nnc_micro_loop_t* const loops, const int loop_count);
486
487
#endif