## Coverage Report

#### Created: 2026-04-14 20:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)

    /home/liu/actions-runner/_work/ccv/ccv/lib/nnc/_ccv_nnc_micro.h

    Line
    Count
    Source
    1
    /**********************************************************
    2
     * C-based/Cached/Core Computer Vision Library
    3
     * Liu Liu, 2010-02-01
    4
     **********************************************************/
    5
    6
    /**********************************************************
    7
     * CCV - Neural Network Collection
    8
     **********************************************************/
    9
    10
    #ifndef GUARD_ccv_nnc_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 && !15CCV_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 && !15CCV_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