## Coverage Report

#### Created: 2026-04-18 18:15

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

    /home/liu/actions-runner/_work/ccv/ccv/lib/nnc/ccv_nnc_micro_interpret.c

    Line
    Count
    Source
    1
    #include "ccv_nnc.h"
    2
    #include "ccv_nnc_easy.h"
    3
    #include "ccv_nnc_internal.h"
    4
    #include "ccv_internal.h"
    5
    #include "_ccv_nnc_micro.h"
    6
    7
    // MARK - Level-1 API
    8
    9
    static int _ccv_nnc_micro_index_interpret(const ccv_nnc_micro_loop_index_term_t index, const int* const loop_counter, const int* const shapes, const ccv_nnc_micro_scalar_t* const values, const int parameter_size)
    10
    40.3k
    {
    11
    40.3k
      switch (index.type)
    12
    40.3k
      {
    13
    5.32k
        case CCV_NNC_MICRO_LOOP_INDEX_TYPE_VAL:
    14
    5.32k
          return index.immediate_value;
    15
    30.6k
        case CCV_NNC_MICRO_LOOP_INDEX_TYPE_ID:
    16
    30.6k
          switch (index.id.type)
    17
    30.6k
          {
    18
    955
            case CCV_NNC_MICRO_AXIS_SIZE_ID:
    19
    955
              return shapes[index.id.id * CCV_NNC_MAX_DIM_ALLOC + index.id.d];
    20
    29.6k
            case CCV_NNC_MICRO_LOOP_ID:
    21
    29.6k
              return loop_counter[index.id.id];
    22
    20
            case CCV_NNC_MICRO_SCALAR_ID:
    23
    20
              switch (values[index.id.id].type)
    24
    20
              {
    25
    0
                case CCV_8U:
    26
    0
                  return values[index.id.id].u8;
    27
    20
                case CCV_32S:
    28
    20
                  return values[index.id.id].i32;
    29
    0
                case CCV_64S:
    30
    0
                  return (int)values[index.id.id].i64;
    31
    20
              }
    32
    0
              break;
    33
    30.6k
          }
    34
    0
          break;
    35
    4.35k
        case CCV_NNC_MICRO_LOOP_INDEX_TYPE_BINARY: {
    36
    4.35k
          const int left = _ccv_nnc_micro_index_interpret(index.binary->left, loop_counter, shapes, values, parameter_size);
    37
    4.35k
          const int right = _ccv_nnc_micro_index_interpret(index.binary->right, loop_counter, shapes, values, parameter_size);
    38
    4.35k
          switch (index.binary->op)
    39
    4.35k
          {
    40
    4.33k
            case CCV_NNC_MICRO_BINARY_OP_PLUS:
    41
    4.33k
              return left + right;
    42
    16
            case CCV_NNC_MICRO_BINARY_OP_MINUS:
    43
    16
              return left - right;
    44
    0
            case CCV_NNC_MICRO_BINARY_OP_MUL:
    45
    0
              return left * right;
    46
    0
            case CCV_NNC_MICRO_BINARY_OP_DIV:
    47
    0
              return left / right;
    48
    0
            case CCV_NNC_MICRO_BINARY_OP_MAX:
    49
    0
              return ccv_max(left, right);
    50
    0
            case CCV_NNC_MICRO_BINARY_OP_MIN:
    51
    0
              return ccv_min(left, right);
    52
    4.35k
          }
    53
    0
          break;
    54
    4.35k
        }
    55
    40.3k
      }
    56
    0
      return 0;
    57
    40.3k
    }
    58
    59
    static float _ccv_nnc_micro_expression_interpret(const ccv_nnc_micro_loop_expression_t* const expression, const int* const loop_counter, const ccv_nnc_micro_scalar_t* const carrieds, const int carried_count, float* const* const vars_mem, const int* const shapes, const ccv_nnc_micro_scalar_t* const values, const int parameter_size, int* const out_of_bound_ref)
    60
    7.15k
    {
    61
    7.15k
      int i;
    62
    7.15k
      switch (expression->type)
    63
    7.15k
      {
    64
    28
        case CCV_NNC_MICRO_LOOP_EXPR_TYPE_ID: {
    65
    28
          assert(expression->id.type == CCV_NNC_MICRO_LOOP_CARRIED_ID);
    66
    28
          return carrieds[expression->id.id].f32;
    67
    28
        }
    68
    354
        case CCV_NNC_MICRO_LOOP_EXPR_TYPE_VAL: {
    69
    354
          return expression->immediate_value.f32;
    70
    28
        }
    71
    4.53k
        case CCV_NNC_MICRO_LOOP_EXPR_TYPE_VAR: {
    72
    4.53k
          const ccv_nnc_micro_loop_variable_t variable = expression->variable;
    73
    4.53k
          assert(variable.id.type == CCV_NNC_MICRO_TENSOR_ID);
    74
    4.53k
          float* ptr = vars_mem[variable.id.id];
    75
    4.53k
          size_t size = 1;
    76
    4.53k
          int out_of_bound = 0;
    77
    26.6k
          for (i = variable.index_count - 1; !out_of_bound && i >= 0; i--22.1k)
    78
    22.1k
          {
    79
    22.1k
            const int index = _ccv_nnc_micro_index_interpret(variable.index[i], loop_counter, shapes, values, parameter_size);
    80
    22.1k
            if (!variable.no_check_bound[i] &&
    81
    22.1k
              (2.88kindex < 02.88k || index >= shapes[variable.id.id * 2.88kCCV_NNC_MAX_DIM_ALLOC2.88k + i]))
    82
    0
              out_of_bound = 1;
    83
    22.1k
            ptr += index * size;
    84
    22.1k
            size *= shapes[variable.id.id * CCV_NNC_MAX_DIM_ALLOC + i];
    85
    22.1k
          }
    86
    4.53k
          if (out_of_bound)
    87
    0
          {
    88
    0
            *out_of_bound_ref = 1;
    89
    0
            return 0;
    90
    0
          }
    91
    4.53k
          return ptr[0];
    92
    4.53k
        }
    93
    0
        case CCV_NNC_MICRO_LOOP_EXPR_TYPE_UNARY: {
    94
    0
          const float left = _ccv_nnc_micro_expression_interpret(expression->unary.x, loop_counter, carrieds, carried_count, vars_mem, shapes, values, parameter_size, out_of_bound_ref);
    95
    0
          if (*out_of_bound_ref)
    96
    0
            return 0;
    97
    0
          switch (expression->unary.unary_op)
    98
    0
          {
    99
    0
            case CCV_NNC_MICRO_UNARY_OP_EXP:
    100
    0
              return exp(left);
    101
    0
            case CCV_NNC_MICRO_UNARY_OP_LOG:
    102
    0
              return log(left);
    103
    0
          }
    104
    0
          break;
    105
    0
        }
    106
    2.23k
        case CCV_NNC_MICRO_LOOP_EXPR_TYPE_BINARY: {
    107
    2.23k
          const float left = _ccv_nnc_micro_expression_interpret(expression->binary.left, loop_counter, carrieds, carried_count, vars_mem, shapes, values, parameter_size, out_of_bound_ref);
    108
    2.23k
          if (*out_of_bound_ref)
    109
    0
            return 0;
    110
    2.23k
          const float right = _ccv_nnc_micro_expression_interpret(expression->binary.right, loop_counter, carrieds, carried_count, vars_mem, shapes, values, parameter_size, out_of_bound_ref);
    111
    2.23k
          if (*out_of_bound_ref)
    112
    0
            return 0;
    113
    2.23k
          switch (expression->binary.binary_op)
    114
    2.23k
          {
    115
    0
            case CCV_NNC_MICRO_BINARY_OP_PLUS:
    116
    0
              return left + right;
    117
    0
            case CCV_NNC_MICRO_BINARY_OP_MINUS:
    118
    0
              return left - right;
    119
    2.23k
            case CCV_NNC_MICRO_BINARY_OP_MUL:
    120
    2.23k
              return left * right;
    121
    0
            case CCV_NNC_MICRO_BINARY_OP_DIV:
    122
    0
              return left / right;
    123
    0
            case CCV_NNC_MICRO_BINARY_OP_MAX:
    124
    0
              return ccv_max(left, right);
    125
    0
            case CCV_NNC_MICRO_BINARY_OP_MIN:
    126
    0
              return ccv_min(left, right);
    127
    2.23k
          }
    128
    0
          break;
    129
    2.23k
        }
    130
    7.15k
      }
    131
    0
      return 0;
    132
    7.15k
    }
    133
    134
    static void _ccv_nnc_micro_statement_interpret(const ccv_nnc_micro_loop_statement_t statement, const int* const loop_counter, ccv_nnc_micro_scalar_t* const carrieds, const int carried_count, float* const* const vars_mem, const int* const shapes, const ccv_nnc_micro_scalar_t* const values, const int parameter_size)
    135
    2.68k
    {
    136
    2.68k
      int i;
    137
    2.68k
      switch (statement.type)
    138
    2.68k
      {
    139
    454
        case CCV_NNC_MICRO_LOOP_STATEMENT_TYPE_ASSIGNMENT: {
    140
    454
          assert(statement.assignment.lvalue.id.type == CCV_NNC_MICRO_TENSOR_ID);
    141
    454
          const ccv_nnc_micro_loop_variable_t variable = statement.assignment.lvalue;
    142
    454
          float* ptr = vars_mem[variable.id.id];
    143
    454
          size_t size = 1;
    144
    454
          int out_of_bound = 0;
    145
    2.20k
          for (i = variable.index_count - 1; !out_of_bound && i >= 0; i--1.75k)
    146
    1.75k
          {
    147
    1.75k
            const int index = _ccv_nnc_micro_index_interpret(variable.index[i], loop_counter, shapes, values, parameter_size);
    148
    1.75k
            if (!variable.no_check_bound[i] &&
    149
    1.75k
              (0index < 00 || index >= shapes[variable.id.id * 0CCV_NNC_MAX_DIM_ALLOC0 + i]))
    150
    0
              out_of_bound = 1;
    151
    1.75k
            ptr += index * size;
    152
    1.75k
            size *= shapes[variable.id.id * CCV_NNC_MAX_DIM_ALLOC + i];
    153
    1.75k
          }
    154
    454
          if (out_of_bound)
    155
    0
            return;
    156
    454
          const float val = _ccv_nnc_micro_expression_interpret(&statement.assignment.rvalue, loop_counter, carrieds, carried_count, vars_mem, shapes, values, parameter_size, &out_of_bound);
    157
    454
          if (out_of_bound)
    158
    0
            return;
    159
    454
          ptr[0] = val;
    160
    454
          break;
    161
    454
        }
    162
    2.23k
        case CCV_NNC_MICRO_LOOP_STATEMENT_TYPE_COMPOUND_ASSIGNMENT: {
    163
    2.23k
          int out_of_bound = 0;
    164
    2.23k
          const float rvalue = _ccv_nnc_micro_expression_interpret(&statement.compound_assignment.rvalue, loop_counter, carrieds, carried_count, vars_mem, shapes, values, parameter_size, &out_of_bound);
    165
    2.23k
          if (out_of_bound)
    166
    0
            return;
    167
    2.23k
          switch (statement.compound_assignment.lvalue.type)
    168
    2.23k
          {
    169
    744
            case CCV_NNC_MICRO_LOOP_EXPR_TYPE_ID: {
    170
    744
              assert(statement.compound_assignment.lvalue.id.type == CCV_NNC_MICRO_LOOP_CARRIED_ID);
    171
    744
              switch (statement.compound_assignment.lvalue.id.d)
    172
    744
              {
    173
    0
                case CCV_NNC_MICRO_REDUCE_OP_MAX:
    174
    0
                  carrieds[statement.compound_assignment.lvalue.id.id].f32 = ccv_max(carrieds[statement.compound_assignment.lvalue.id.id].f32, rvalue);
    175
    0
                  break;
    176
    0
                case CCV_NNC_MICRO_REDUCE_OP_MIN:
    177
    0
                  carrieds[statement.compound_assignment.lvalue.id.id].f32 = ccv_min(carrieds[statement.compound_assignment.lvalue.id.id].f32, rvalue);
    178
    0
                  break;
    179
    0
                case CCV_NNC_MICRO_REDUCE_OP_ARGMAX:
    180
    0
                  assert(0);
    181
    0
                  break;
    182
    0
                case CCV_NNC_MICRO_REDUCE_OP_ARGMIN:
    183
    0
                  assert(0);
    184
    0
                  break;
    185
    0
                case CCV_NNC_MICRO_REDUCE_OP_MEAN:
    186
    0
                  carrieds[statement.compound_assignment.lvalue.id.id].f32 += rvalue;
    187
    0
                  break;
    188
    744
                case CCV_NNC_MICRO_REDUCE_OP_SUM:
    189
    744
                  carrieds[statement.compound_assignment.lvalue.id.id].f32 += rvalue;
    190
    744
                  break;
    191
    0
                case CCV_NNC_MICRO_REDUCE_OP_PROD:
    192
    0
                  carrieds[statement.compound_assignment.lvalue.id.id].f32 *= rvalue;
    193
    0
                  break;
    194
    744
              }
    195
    744
              break;
    196
    744
            }
    197
    1.48k
            case CCV_NNC_MICRO_LOOP_EXPR_TYPE_VAR: {
    198
    1.48k
              assert(statement.compound_assignment.lvalue.id.type == CCV_NNC_MICRO_TENSOR_ID);
    199
    1.48k
              const ccv_nnc_micro_loop_variable_t variable = statement.compound_assignment.lvalue.variable;
    200
    1.48k
              float* ptr = vars_mem[variable.id.id];
    201
    1.48k
              size_t size = 1;
    202
    7.34k
              for (i = variable.index_count - 1; !out_of_bound && i >= 0; i--5.85k)
    203
    5.85k
              {
    204
    5.85k
                const int index = _ccv_nnc_micro_index_interpret(variable.index[i], loop_counter, shapes, values, parameter_size);
    205
    5.85k
                if (!variable.no_check_bound[i] &&
    206
    5.85k
                  (1.44kindex < 01.44k || index >= shapes[variable.id.id * 1.44kCCV_NNC_MAX_DIM_ALLOC1.44k + i]))
    207
    0
                  out_of_bound = 1;
    208
    5.85k
                ptr += index * size;
    209
    5.85k
                size *= shapes[variable.id.id * CCV_NNC_MAX_DIM_ALLOC + i];
    210
    5.85k
              }
    211
    1.48k
              if (out_of_bound)
    212
    0
                return;
    213
    1.48k
              ptr[0] += rvalue;
    214
    1.48k
              break;
    215
    1.48k
            }
    216
    2.23k
          }
    217
    2.23k
          break;
    218
    2.23k
        }
    219
    2.68k
      }
    220
    2.68k
    }
    221
    222
    static void _ccv_nnc_micro_loop_interpret(const ccv_nnc_micro_loop_t* const loops, const int loop_count, const int index, int* const loop_counter, ccv_nnc_micro_scalar_t* const carrieds, const int carried_count, float* const* const vars_mem, const int* const shapes, const ccv_nnc_micro_scalar_t* const values, const int parameter_size)
    223
    2.78k
    {
    224
    2.78k
      if (index >= loop_count)
    225
    1.91k
        return;
    226
    871
      const int start_index = _ccv_nnc_micro_index_interpret(loops[index].start_index, loop_counter, shapes, values, parameter_size);
    227
    871
      const int end_index = _ccv_nnc_micro_index_interpret(loops[index].end_index, loop_counter, shapes, values, parameter_size);
    228
    871
      int i, j;
    229
    871
      const ccv_nnc_micro_loop_statement_t* const statements = loops[index].statements;
    230
    871
      const int statement_count = loops[index].statement_count;
    231
    871
      const ccv_nnc_micro_loop_carried_t* const carried_refs = loops[index].carrieds;
    232
    871
      const int carried_ref_count = loops[index].carried_count;
    233
    3.64k
      for (i = start_index; i < end_index; i++2.77k)
    234
    2.77k
      {
    235
    2.77k
        loop_counter[loops[index].id.id] = i;
    236
    2.79k
        for (j = 0; j < carried_ref_count; j++28)
    237
    28
        {
    238
    28
          assert(carried_refs[j].id.type == CCV_NNC_MICRO_LOOP_CARRIED_ID);
    239
    28
          assert(carried_refs[j].id.id < carried_count);
    240
    28
          switch (carried_refs[j].id.d)
    241
    28
          {
    242
    0
            case CCV_NNC_MICRO_REDUCE_OP_MAX:
    243
    0
              carrieds[carried_refs[j].id.id].f32 = -FLT_MAX;
    244
    0
              break;
    245
    0
            case CCV_NNC_MICRO_REDUCE_OP_MIN:
    246
    0
              carrieds[carried_refs[j].id.id].f32 = FLT_MAX;
    247
    0
              break;
    248
    0
            case CCV_NNC_MICRO_REDUCE_OP_ARGMAX:
    249
    0
              carrieds[carried_refs[j].id.id].i32 = -1;
    250
    0
              break;
    251
    0
            case CCV_NNC_MICRO_REDUCE_OP_ARGMIN:
    252
    0
              carrieds[carried_refs[j].id.id].i32 = -1;
    253
    0
              break;
    254
    0
            case CCV_NNC_MICRO_REDUCE_OP_MEAN:
    255
    0
              carrieds[carried_refs[j].id.id].f32 = 0;
    256
    0
              break;
    257
    28
            case CCV_NNC_MICRO_REDUCE_OP_SUM:
    258
    28
              carrieds[carried_refs[j].id.id].f32 = 0;
    259
    28
              break;
    260
    0
            case CCV_NNC_MICRO_REDUCE_OP_PROD:
    261
    0
              carrieds[carried_refs[j].id.id].f32 = 1;
    262
    0
              break;
    263
    28
          }
    264
    28
        }
    265
    2.77k
        _ccv_nnc_micro_loop_interpret(loops, loop_count, index + 1, loop_counter, carrieds, carried_count, vars_mem, shapes, values, parameter_size);
    266
    5.45k
        for (j = 0; j < statement_count; j++2.68k)
    267
    2.68k
          _ccv_nnc_micro_statement_interpret(statements[j], loop_counter, carrieds, carried_count, vars_mem, shapes, values, parameter_size);
    268
    2.77k
      }
    269
    871
    }
    270
    271
    void ccv_nnc_micro_combine_interpret(ccv_nnc_micro_combine_t* const combine, const uint32_t cmd, ccv_nnc_tensor_t* const* const inputs, const int input_size, const ccv_nnc_micro_scalar_t* const values, const int parameter_size, ccv_nnc_tensor_t* const* const outputs, const int output_size)
    272
    6
    {
    273
      // We haven't optimized for emit_grad at the moment yet.
    274
    6
      assert(cmd == CCV_NNC_CUSTOM_FORWARD || cmd == CCV_NNC_CUSTOM_BACKWARD);
    275
    6
      int i, j;
    276
    6
      const ccv_nnc_micro_program_t* const program = cmd == CCV_NNC_CUSTOM_FORWARD ? &combine->forward3 : &combine->backward3;
    277
    6
      const int var_count = program->var_count;
    278
    6
      assert(input_size == program->input_size);
    279
    6
      assert(output_size == program->output_size);
    280
    6
      assert(parameter_size == combine->parameter_size);
    281
    6
      int* const shapes = (int*)cccalloc(var_count, sizeof(int) * CCV_NNC_MAX_DIM_ALLOC);
    282
    6
      ccv_nnc_micro_tensor_t* const vars = program->vars;
    283
    21
      for (i = 0; i < input_size; i++15)
    284
    15
        memcpy(shapes + program->inputs[i] * CCV_NNC_MAX_DIM_ALLOC, &inputs[i]->info.dim, sizeof(int) * CCV_NNC_MAX_DIM_ALLOC);
    285
    6
      int loop_counter[CCV_NNC_MAX_DIM_ALLOC];
    286
    60
      for (i = 0; i < var_count; i++54)
    287
    54
      {
    288
    54
        int flag = 0;
    289
    186
        for (j = 0; !flag && j < input_size171; j++132)
    290
    132
          flag = (program->inputs[j] == i);
    291
    54
        if (flag)
    292
    15
          continue;
    293
    39
        if (vars[i].shape)
    294
    18
        {
    295
    120
          for (j = 0; j < vars[i].dimensions; j++102)
    296
    102
            shapes[i * CCV_NNC_MAX_DIM_ALLOC + j] = _ccv_nnc_micro_index_interpret(vars[i].shape[j], loop_counter, shapes, values, parameter_size);
    297
    18
        } else
    298
    21
          memcpy(shapes + i * CCV_NNC_MAX_DIM_ALLOC, shapes + vars[i].input * CCV_NNC_MAX_DIM_ALLOC, sizeof(int) * CCV_NNC_MAX_DIM_ALLOC);
    299
    39
      }
    300
    6
      const ccv_array_t* const equal_assertions = combine->equal_assertions;
    301
    14
      for (i = 0; i < equal_assertions->rnum; i++8)
    302
    8
      {
    303
    8
        ccv_nnc_micro_id_equal_assertion_t* const equal_assertion = ccv_array_get(equal_assertions, i);
    304
    8
        assert(shapes[equal_assertion->left.id * CCV_NNC_MAX_DIM_ALLOC + equal_assertion->left.d] == shapes[equal_assertion->right.id * CCV_NNC_MAX_DIM_ALLOC + equal_assertion->right.d]);
    305
    8
      }
    306
    6
      size_t total_size = 0;
    307
    60
      for (i = 0; i < var_count; i++54)
    308
    54
      {
    309
    54
        int flag = 0;
    310
    186
        for (j = 0; !flag && j < input_size171; j++132)
    311
    132
          flag = (program->inputs[j] == i);
    312
    117
        for (j = 0; !flag && j < output_size93; j++63)
    313
    63
          flag = (program->outputs[j] == i);
    314
    54
        if (flag)
    315
    24
          continue;
    316
    30
        if (vars[i].no_alloc) // This is skipped.
    317
    27
          continue;
    318
        // allocating memory for these.
    319
    3
        size_t size = 1;
    320
    12
        for (j = 0; j < vars[i].dimensions; j++9)
    321
    9
          size *= shapes[i * CCV_NNC_MAX_DIM_ALLOC + j];
    322
    3
        total_size += size;
    323
    3
      }
    324
    6
      float** const vars_mem = (float**)ccmalloc(sizeof(float*) * var_count + sizeof(float) * total_size);
    325
    6
      float* ptr = (float*)(vars_mem + var_count);
    326
      // Assuming these are not tensor_view_t.
    327
    15
      for (i = 0; i < output_size; i++9)
    328
    9
      {
    329
    9
        assert(CCV_IS_TENSOR_CONTIGUOUS(outputs[i]));
    330
    9
        vars_mem[program->outputs[i]] = outputs[i]->data.f32;
    331
    9
      }
    332
    60
      for (i = 0; 6i < var_count; i++54)
    333
    54
      {
    334
    54
        int flag = 0;
    335
    186
        for (j = 0; !flag && j < input_size171; j++132)
    336
    132
          flag = (program->inputs[j] == i);
    337
    117
        for (j = 0; !flag && j < output_size93; j++63)
    338
    63
          flag = (program->outputs[j] == i);
    339
    54
        if (flag)
    340
    24
          continue;
    341
    30
        if (vars[i].no_alloc) // This is skipped.
    342
    27
        {
    343
    27
          vars_mem[i] = 0;
    344
    27
          continue;
    345
    27
        }
    346
        // allocating memory for these.
    347
    3
        size_t size = 1;
    348
    12
        for (j = 0; j < vars[i].dimensions; j++9)
    349
    9
          size *= shapes[i * CCV_NNC_MAX_DIM_ALLOC + j];
    350
    3
        vars_mem[i] = ptr;
    351
    3
        ptr += size;
    352
    3
      }
    353
    21
      for (i = 0; i < input_size; i++15)
    354
    15
      {
    355
    15
        assert(CCV_IS_TENSOR_CONTIGUOUS(inputs[i]));
    356
    15
        vars_mem[program->inputs[i]] = inputs[i]->data.f32;
    357
    15
      }
    358
    6
      ccv_nnc_micro_function_t* const functions = program->functions;
    359
    6
      const int function_count = program->function_count;
    360
    6
      int max_carried_count = 0;
    361
    12
      for (i = 0; i < function_count; i++6)
    362
    6
      {
    363
    6
        const int block_count = functions[i].block_count;
    364
    6
        ccv_nnc_micro_loop_block_t* const blocks = block_count == 1 ? &functions[i].one_block2 : functions[i].blocks4;
    365
    21
        for (j = 0; j < block_count; j++15)
    366
    15
          max_carried_count = ccv_max(max_carried_count, blocks[j].carried_count);
    367
    6
      }
    368
    6
      ccv_nnc_micro_scalar_t* const carrieds = max_carried_count > 0 ? (ccv_nnc_micro_scalar_t*)ccmalloc(sizeof(ccv_nnc_micro_scalar_t) * max_carried_count) : 00;
    369
    12
      for (i = 0; i < function_count; i++6)
    370
    6
      {
    371
    6
        const int block_count = functions[i].block_count;
    372
    6
        ccv_nnc_micro_loop_block_t* const blocks = block_count == 1 ? &functions[i].one_block2 : functions[i].blocks4;
    373
    21
        for (j = 0; j < block_count; j++15)
    374
    15
          _ccv_nnc_micro_loop_interpret(blocks[j].loops, blocks[j].loop_count, 0, loop_counter, carrieds, blocks[j].carried_count, vars_mem, shapes, values, parameter_size);
    375
    6
      }
    376
    6
      if (carrieds)
    377
    6
        ccfree(carrieds);
    378
    6
      ccfree(vars_mem);
    379
    6
      ccfree(shapes);
    380
    6
    }