| File: | nnc/ccv_nnc_micro_interpret.c |
| Warning: | line 47, column 18 Division by zero |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 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 | { | ||||
| 11 | switch (index.type) | ||||
| 12 | { | ||||
| 13 | case CCV_NNC_MICRO_LOOP_INDEX_TYPE_VAL: | ||||
| 14 | return index.immediate_value; | ||||
| 15 | case CCV_NNC_MICRO_LOOP_INDEX_TYPE_ID: | ||||
| 16 | switch (index.id.type) | ||||
| 17 | { | ||||
| 18 | case CCV_NNC_MICRO_AXIS_SIZE_ID: | ||||
| 19 | return shapes[index.id.id * CCV_NNC_MAX_DIM_ALLOC(12) + index.id.d]; | ||||
| 20 | case CCV_NNC_MICRO_LOOP_ID: | ||||
| 21 | return loop_counter[index.id.id]; | ||||
| 22 | case CCV_NNC_MICRO_SCALAR_ID: | ||||
| 23 | switch (values[index.id.id].type) | ||||
| 24 | { | ||||
| 25 | case CCV_8U: | ||||
| 26 | return values[index.id.id].u8; | ||||
| 27 | case CCV_32S: | ||||
| 28 | return values[index.id.id].i32; | ||||
| 29 | case CCV_64S: | ||||
| 30 | return (int)values[index.id.id].i64; | ||||
| 31 | } | ||||
| 32 | break; | ||||
| 33 | } | ||||
| 34 | break; | ||||
| 35 | case CCV_NNC_MICRO_LOOP_INDEX_TYPE_BINARY: { | ||||
| 36 | const int left = _ccv_nnc_micro_index_interpret(index.binary->left, loop_counter, shapes, values, parameter_size); | ||||
| 37 | const int right = _ccv_nnc_micro_index_interpret(index.binary->right, loop_counter, shapes, values, parameter_size); | ||||
| 38 | switch (index.binary->op) | ||||
| 39 | { | ||||
| 40 | case CCV_NNC_MICRO_BINARY_OP_PLUS: | ||||
| 41 | return left + right; | ||||
| 42 | case CCV_NNC_MICRO_BINARY_OP_MINUS: | ||||
| 43 | return left - right; | ||||
| 44 | case CCV_NNC_MICRO_BINARY_OP_MUL: | ||||
| 45 | return left * right; | ||||
| 46 | case CCV_NNC_MICRO_BINARY_OP_DIV: | ||||
| 47 | return left / right; | ||||
| |||||
| 48 | case CCV_NNC_MICRO_BINARY_OP_MAX: | ||||
| 49 | return ccv_max(left, right)({ typeof (left) _a = (left); typeof (right) _b = (right); (_a > _b) ? _a : _b; }); | ||||
| 50 | case CCV_NNC_MICRO_BINARY_OP_MIN: | ||||
| 51 | return ccv_min(left, right)({ typeof (left) _a = (left); typeof (right) _b = (right); (_a < _b) ? _a : _b; }); | ||||
| 52 | } | ||||
| 53 | break; | ||||
| 54 | } | ||||
| 55 | } | ||||
| 56 | return 0; | ||||
| 57 | } | ||||
| 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 | { | ||||
| 61 | int i; | ||||
| 62 | switch (expression->type) | ||||
| 63 | { | ||||
| 64 | case CCV_NNC_MICRO_LOOP_EXPR_TYPE_ID: { | ||||
| 65 | assert(expression->id.type == CCV_NNC_MICRO_LOOP_CARRIED_ID)((void) sizeof ((expression->id.type == CCV_NNC_MICRO_LOOP_CARRIED_ID ) ? 1 : 0), __extension__ ({ if (expression->id.type == CCV_NNC_MICRO_LOOP_CARRIED_ID ) ; else __assert_fail ("expression->id.type == CCV_NNC_MICRO_LOOP_CARRIED_ID" , "ccv_nnc_micro_interpret.c", 65, __extension__ __PRETTY_FUNCTION__ ); })); | ||||
| 66 | return carrieds[expression->id.id].f32; | ||||
| 67 | } | ||||
| 68 | case CCV_NNC_MICRO_LOOP_EXPR_TYPE_VAL: { | ||||
| 69 | return expression->immediate_value.f32; | ||||
| 70 | } | ||||
| 71 | case CCV_NNC_MICRO_LOOP_EXPR_TYPE_VAR: { | ||||
| 72 | const ccv_nnc_micro_loop_variable_t variable = expression->variable; | ||||
| 73 | assert(variable.id.type == CCV_NNC_MICRO_TENSOR_ID)((void) sizeof ((variable.id.type == CCV_NNC_MICRO_TENSOR_ID) ? 1 : 0), __extension__ ({ if (variable.id.type == CCV_NNC_MICRO_TENSOR_ID ) ; else __assert_fail ("variable.id.type == CCV_NNC_MICRO_TENSOR_ID" , "ccv_nnc_micro_interpret.c", 73, __extension__ __PRETTY_FUNCTION__ ); })); | ||||
| 74 | float* ptr = vars_mem[variable.id.id]; | ||||
| 75 | size_t size = 1; | ||||
| 76 | int out_of_bound = 0; | ||||
| 77 | for (i = variable.index_count - 1; !out_of_bound && i >= 0; i--) | ||||
| 78 | { | ||||
| 79 | const int index = _ccv_nnc_micro_index_interpret(variable.index[i], loop_counter, shapes, values, parameter_size); | ||||
| 80 | if (!variable.no_check_bound[i] && | ||||
| 81 | (index < 0 || index >= shapes[variable.id.id * CCV_NNC_MAX_DIM_ALLOC(12) + i])) | ||||
| 82 | out_of_bound = 1; | ||||
| 83 | ptr += index * size; | ||||
| 84 | size *= shapes[variable.id.id * CCV_NNC_MAX_DIM_ALLOC(12) + i]; | ||||
| 85 | } | ||||
| 86 | if (out_of_bound) | ||||
| 87 | { | ||||
| 88 | *out_of_bound_ref = 1; | ||||
| 89 | return 0; | ||||
| 90 | } | ||||
| 91 | return ptr[0]; | ||||
| 92 | } | ||||
| 93 | case CCV_NNC_MICRO_LOOP_EXPR_TYPE_UNARY: { | ||||
| 94 | 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 | if (*out_of_bound_ref) | ||||
| 96 | return 0; | ||||
| 97 | switch (expression->unary.unary_op) | ||||
| 98 | { | ||||
| 99 | case CCV_NNC_MICRO_UNARY_OP_EXP: | ||||
| 100 | return exp(left); | ||||
| 101 | case CCV_NNC_MICRO_UNARY_OP_LOG: | ||||
| 102 | return log(left); | ||||
| 103 | } | ||||
| 104 | break; | ||||
| 105 | } | ||||
| 106 | case CCV_NNC_MICRO_LOOP_EXPR_TYPE_BINARY: { | ||||
| 107 | 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 | if (*out_of_bound_ref) | ||||
| 109 | return 0; | ||||
| 110 | 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 | if (*out_of_bound_ref) | ||||
| 112 | return 0; | ||||
| 113 | switch (expression->binary.binary_op) | ||||
| 114 | { | ||||
| 115 | case CCV_NNC_MICRO_BINARY_OP_PLUS: | ||||
| 116 | return left + right; | ||||
| 117 | case CCV_NNC_MICRO_BINARY_OP_MINUS: | ||||
| 118 | return left - right; | ||||
| 119 | case CCV_NNC_MICRO_BINARY_OP_MUL: | ||||
| 120 | return left * right; | ||||
| 121 | case CCV_NNC_MICRO_BINARY_OP_DIV: | ||||
| 122 | return left / right; | ||||
| 123 | case CCV_NNC_MICRO_BINARY_OP_MAX: | ||||
| 124 | return ccv_max(left, right)({ typeof (left) _a = (left); typeof (right) _b = (right); (_a > _b) ? _a : _b; }); | ||||
| 125 | case CCV_NNC_MICRO_BINARY_OP_MIN: | ||||
| 126 | return ccv_min(left, right)({ typeof (left) _a = (left); typeof (right) _b = (right); (_a < _b) ? _a : _b; }); | ||||
| 127 | } | ||||
| 128 | break; | ||||
| 129 | } | ||||
| 130 | } | ||||
| 131 | return 0; | ||||
| 132 | } | ||||
| 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 | { | ||||
| 136 | int i; | ||||
| 137 | switch (statement.type) | ||||
| 138 | { | ||||
| 139 | case CCV_NNC_MICRO_LOOP_STATEMENT_TYPE_ASSIGNMENT: { | ||||
| 140 | assert(statement.assignment.lvalue.id.type == CCV_NNC_MICRO_TENSOR_ID)((void) sizeof ((statement.assignment.lvalue.id.type == CCV_NNC_MICRO_TENSOR_ID ) ? 1 : 0), __extension__ ({ if (statement.assignment.lvalue. id.type == CCV_NNC_MICRO_TENSOR_ID) ; else __assert_fail ("statement.assignment.lvalue.id.type == CCV_NNC_MICRO_TENSOR_ID" , "ccv_nnc_micro_interpret.c", 140, __extension__ __PRETTY_FUNCTION__ ); })); | ||||
| 141 | const ccv_nnc_micro_loop_variable_t variable = statement.assignment.lvalue; | ||||
| 142 | float* ptr = vars_mem[variable.id.id]; | ||||
| 143 | size_t size = 1; | ||||
| 144 | int out_of_bound = 0; | ||||
| 145 | for (i = variable.index_count - 1; !out_of_bound && i >= 0; i--) | ||||
| 146 | { | ||||
| 147 | const int index = _ccv_nnc_micro_index_interpret(variable.index[i], loop_counter, shapes, values, parameter_size); | ||||
| 148 | if (!variable.no_check_bound[i] && | ||||
| 149 | (index < 0 || index >= shapes[variable.id.id * CCV_NNC_MAX_DIM_ALLOC(12) + i])) | ||||
| 150 | out_of_bound = 1; | ||||
| 151 | ptr += index * size; | ||||
| 152 | size *= shapes[variable.id.id * CCV_NNC_MAX_DIM_ALLOC(12) + i]; | ||||
| 153 | } | ||||
| 154 | if (out_of_bound) | ||||
| 155 | return; | ||||
| 156 | 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 | if (out_of_bound) | ||||
| 158 | return; | ||||
| 159 | ptr[0] = val; | ||||
| 160 | break; | ||||
| 161 | } | ||||
| 162 | case CCV_NNC_MICRO_LOOP_STATEMENT_TYPE_COMPOUND_ASSIGNMENT: { | ||||
| 163 | int out_of_bound = 0; | ||||
| 164 | 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 | if (out_of_bound) | ||||
| 166 | return; | ||||
| 167 | switch (statement.compound_assignment.lvalue.type) | ||||
| 168 | { | ||||
| 169 | case CCV_NNC_MICRO_LOOP_EXPR_TYPE_ID: { | ||||
| 170 | assert(statement.compound_assignment.lvalue.id.type == CCV_NNC_MICRO_LOOP_CARRIED_ID)((void) sizeof ((statement.compound_assignment.lvalue.id.type == CCV_NNC_MICRO_LOOP_CARRIED_ID) ? 1 : 0), __extension__ ({ if (statement.compound_assignment.lvalue.id.type == CCV_NNC_MICRO_LOOP_CARRIED_ID ) ; else __assert_fail ("statement.compound_assignment.lvalue.id.type == CCV_NNC_MICRO_LOOP_CARRIED_ID" , "ccv_nnc_micro_interpret.c", 170, __extension__ __PRETTY_FUNCTION__ ); })); | ||||
| 171 | switch (statement.compound_assignment.lvalue.id.d) | ||||
| 172 | { | ||||
| 173 | case CCV_NNC_MICRO_REDUCE_OP_MAX: | ||||
| 174 | carrieds[statement.compound_assignment.lvalue.id.id].f32 = ccv_max(carrieds[statement.compound_assignment.lvalue.id.id].f32, rvalue)({ typeof (carrieds[statement.compound_assignment.lvalue.id.id ].f32) _a = (carrieds[statement.compound_assignment.lvalue.id .id].f32); typeof (rvalue) _b = (rvalue); (_a > _b) ? _a : _b; }); | ||||
| 175 | break; | ||||
| 176 | case CCV_NNC_MICRO_REDUCE_OP_MIN: | ||||
| 177 | carrieds[statement.compound_assignment.lvalue.id.id].f32 = ccv_min(carrieds[statement.compound_assignment.lvalue.id.id].f32, rvalue)({ typeof (carrieds[statement.compound_assignment.lvalue.id.id ].f32) _a = (carrieds[statement.compound_assignment.lvalue.id .id].f32); typeof (rvalue) _b = (rvalue); (_a < _b) ? _a : _b; }); | ||||
| 178 | break; | ||||
| 179 | case CCV_NNC_MICRO_REDUCE_OP_ARGMAX: | ||||
| 180 | assert(0)((void) sizeof ((0) ? 1 : 0), __extension__ ({ if (0) ; else __assert_fail ("0", "ccv_nnc_micro_interpret.c", 180, __extension__ __PRETTY_FUNCTION__ ); })); | ||||
| 181 | break; | ||||
| 182 | case CCV_NNC_MICRO_REDUCE_OP_ARGMIN: | ||||
| 183 | assert(0)((void) sizeof ((0) ? 1 : 0), __extension__ ({ if (0) ; else __assert_fail ("0", "ccv_nnc_micro_interpret.c", 183, __extension__ __PRETTY_FUNCTION__ ); })); | ||||
| 184 | break; | ||||
| 185 | case CCV_NNC_MICRO_REDUCE_OP_MEAN: | ||||
| 186 | carrieds[statement.compound_assignment.lvalue.id.id].f32 += rvalue; | ||||
| 187 | break; | ||||
| 188 | case CCV_NNC_MICRO_REDUCE_OP_SUM: | ||||
| 189 | carrieds[statement.compound_assignment.lvalue.id.id].f32 += rvalue; | ||||
| 190 | break; | ||||
| 191 | case CCV_NNC_MICRO_REDUCE_OP_PROD: | ||||
| 192 | carrieds[statement.compound_assignment.lvalue.id.id].f32 *= rvalue; | ||||
| 193 | break; | ||||
| 194 | } | ||||
| 195 | break; | ||||
| 196 | } | ||||
| 197 | case CCV_NNC_MICRO_LOOP_EXPR_TYPE_VAR: { | ||||
| 198 | assert(statement.compound_assignment.lvalue.id.type == CCV_NNC_MICRO_TENSOR_ID)((void) sizeof ((statement.compound_assignment.lvalue.id.type == CCV_NNC_MICRO_TENSOR_ID) ? 1 : 0), __extension__ ({ if (statement .compound_assignment.lvalue.id.type == CCV_NNC_MICRO_TENSOR_ID ) ; else __assert_fail ("statement.compound_assignment.lvalue.id.type == CCV_NNC_MICRO_TENSOR_ID" , "ccv_nnc_micro_interpret.c", 198, __extension__ __PRETTY_FUNCTION__ ); })); | ||||
| 199 | const ccv_nnc_micro_loop_variable_t variable = statement.compound_assignment.lvalue.variable; | ||||
| 200 | float* ptr = vars_mem[variable.id.id]; | ||||
| 201 | size_t size = 1; | ||||
| 202 | for (i = variable.index_count - 1; !out_of_bound && i >= 0; i--) | ||||
| 203 | { | ||||
| 204 | const int index = _ccv_nnc_micro_index_interpret(variable.index[i], loop_counter, shapes, values, parameter_size); | ||||
| 205 | if (!variable.no_check_bound[i] && | ||||
| 206 | (index < 0 || index >= shapes[variable.id.id * CCV_NNC_MAX_DIM_ALLOC(12) + i])) | ||||
| 207 | out_of_bound = 1; | ||||
| 208 | ptr += index * size; | ||||
| 209 | size *= shapes[variable.id.id * CCV_NNC_MAX_DIM_ALLOC(12) + i]; | ||||
| 210 | } | ||||
| 211 | if (out_of_bound) | ||||
| 212 | return; | ||||
| 213 | ptr[0] += rvalue; | ||||
| 214 | break; | ||||
| 215 | } | ||||
| 216 | } | ||||
| 217 | break; | ||||
| 218 | } | ||||
| 219 | } | ||||
| 220 | } | ||||
| 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 | { | ||||
| 224 | if (index >= loop_count) | ||||
| 225 | return; | ||||
| 226 | const int start_index = _ccv_nnc_micro_index_interpret(loops[index].start_index, loop_counter, shapes, values, parameter_size); | ||||
| 227 | const int end_index = _ccv_nnc_micro_index_interpret(loops[index].end_index, loop_counter, shapes, values, parameter_size); | ||||
| 228 | int i, j; | ||||
| 229 | const ccv_nnc_micro_loop_statement_t* const statements = loops[index].statements; | ||||
| 230 | const int statement_count = loops[index].statement_count; | ||||
| 231 | const ccv_nnc_micro_loop_carried_t* const carried_refs = loops[index].carrieds; | ||||
| 232 | const int carried_ref_count = loops[index].carried_count; | ||||
| 233 | for (i = start_index; i < end_index; i++) | ||||
| 234 | { | ||||
| 235 | loop_counter[loops[index].id.id] = i; | ||||
| 236 | for (j = 0; j < carried_ref_count; j++) | ||||
| 237 | { | ||||
| 238 | assert(carried_refs[j].id.type == CCV_NNC_MICRO_LOOP_CARRIED_ID)((void) sizeof ((carried_refs[j].id.type == CCV_NNC_MICRO_LOOP_CARRIED_ID ) ? 1 : 0), __extension__ ({ if (carried_refs[j].id.type == CCV_NNC_MICRO_LOOP_CARRIED_ID ) ; else __assert_fail ("carried_refs[j].id.type == CCV_NNC_MICRO_LOOP_CARRIED_ID" , "ccv_nnc_micro_interpret.c", 238, __extension__ __PRETTY_FUNCTION__ ); })); | ||||
| 239 | assert(carried_refs[j].id.id < carried_count)((void) sizeof ((carried_refs[j].id.id < carried_count) ? 1 : 0), __extension__ ({ if (carried_refs[j].id.id < carried_count ) ; else __assert_fail ("carried_refs[j].id.id < carried_count" , "ccv_nnc_micro_interpret.c", 239, __extension__ __PRETTY_FUNCTION__ ); })); | ||||
| 240 | switch (carried_refs[j].id.d) | ||||
| 241 | { | ||||
| 242 | case CCV_NNC_MICRO_REDUCE_OP_MAX: | ||||
| 243 | carrieds[carried_refs[j].id.id].f32 = -FLT_MAX3.40282347e+38F; | ||||
| 244 | break; | ||||
| 245 | case CCV_NNC_MICRO_REDUCE_OP_MIN: | ||||
| 246 | carrieds[carried_refs[j].id.id].f32 = FLT_MAX3.40282347e+38F; | ||||
| 247 | break; | ||||
| 248 | case CCV_NNC_MICRO_REDUCE_OP_ARGMAX: | ||||
| 249 | carrieds[carried_refs[j].id.id].i32 = -1; | ||||
| 250 | break; | ||||
| 251 | case CCV_NNC_MICRO_REDUCE_OP_ARGMIN: | ||||
| 252 | carrieds[carried_refs[j].id.id].i32 = -1; | ||||
| 253 | break; | ||||
| 254 | case CCV_NNC_MICRO_REDUCE_OP_MEAN: | ||||
| 255 | carrieds[carried_refs[j].id.id].f32 = 0; | ||||
| 256 | break; | ||||
| 257 | case CCV_NNC_MICRO_REDUCE_OP_SUM: | ||||
| 258 | carrieds[carried_refs[j].id.id].f32 = 0; | ||||
| 259 | break; | ||||
| 260 | case CCV_NNC_MICRO_REDUCE_OP_PROD: | ||||
| 261 | carrieds[carried_refs[j].id.id].f32 = 1; | ||||
| 262 | break; | ||||
| 263 | } | ||||
| 264 | } | ||||
| 265 | _ccv_nnc_micro_loop_interpret(loops, loop_count, index + 1, loop_counter, carrieds, carried_count, vars_mem, shapes, values, parameter_size); | ||||
| 266 | for (j = 0; j < statement_count; j++) | ||||
| 267 | _ccv_nnc_micro_statement_interpret(statements[j], loop_counter, carrieds, carried_count, vars_mem, shapes, values, parameter_size); | ||||
| 268 | } | ||||
| 269 | } | ||||
| 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 | { | ||||
| 273 | // We haven't optimized for emit_grad at the moment yet. | ||||
| 274 | assert(cmd == CCV_NNC_CUSTOM_FORWARD || cmd == CCV_NNC_CUSTOM_BACKWARD)((void) sizeof ((cmd == CCV_NNC_CUSTOM_FORWARD || cmd == CCV_NNC_CUSTOM_BACKWARD ) ? 1 : 0), __extension__ ({ if (cmd == CCV_NNC_CUSTOM_FORWARD || cmd == CCV_NNC_CUSTOM_BACKWARD) ; else __assert_fail ("cmd == CCV_NNC_CUSTOM_FORWARD || cmd == CCV_NNC_CUSTOM_BACKWARD" , "ccv_nnc_micro_interpret.c", 274, __extension__ __PRETTY_FUNCTION__ ); })); | ||||
| |||||
| 275 | int i, j; | ||||
| 276 | const ccv_nnc_micro_program_t* const program = cmd
| ||||
| 277 | const int var_count = program->var_count; | ||||
| 278 | assert(input_size == program->input_size)((void) sizeof ((input_size == program->input_size) ? 1 : 0 ), __extension__ ({ if (input_size == program->input_size) ; else __assert_fail ("input_size == program->input_size" , "ccv_nnc_micro_interpret.c", 278, __extension__ __PRETTY_FUNCTION__ ); })); | ||||
| 279 | assert(output_size == program->output_size)((void) sizeof ((output_size == program->output_size) ? 1 : 0), __extension__ ({ if (output_size == program->output_size ) ; else __assert_fail ("output_size == program->output_size" , "ccv_nnc_micro_interpret.c", 279, __extension__ __PRETTY_FUNCTION__ ); })); | ||||
| 280 | assert(parameter_size == combine->parameter_size)((void) sizeof ((parameter_size == combine->parameter_size ) ? 1 : 0), __extension__ ({ if (parameter_size == combine-> parameter_size) ; else __assert_fail ("parameter_size == combine->parameter_size" , "ccv_nnc_micro_interpret.c", 280, __extension__ __PRETTY_FUNCTION__ ); })); | ||||
| 281 | int* const shapes = (int*)cccalloccalloc(var_count, sizeof(int) * CCV_NNC_MAX_DIM_ALLOC(12)); | ||||
| 282 | ccv_nnc_micro_tensor_t* const vars = program->vars; | ||||
| 283 | for (i = 0; i < input_size; i++) | ||||
| 284 | memcpy(shapes + program->inputs[i] * CCV_NNC_MAX_DIM_ALLOC(12), &inputs[i]->info.dim, sizeof(int) * CCV_NNC_MAX_DIM_ALLOC(12)); | ||||
| 285 | int loop_counter[CCV_NNC_MAX_DIM_ALLOC(12)]; | ||||
| 286 | for (i = 0; i < var_count; i++) | ||||
| 287 | { | ||||
| 288 | int flag = 0; | ||||
| 289 | for (j = 0; !flag
| ||||
| 290 | flag = (program->inputs[j] == i); | ||||
| 291 | if (flag
| ||||
| 292 | continue; | ||||
| 293 | if (vars[i].shape) | ||||
| 294 | { | ||||
| 295 | for (j = 0; j < vars[i].dimensions; j++) | ||||
| 296 | shapes[i * CCV_NNC_MAX_DIM_ALLOC(12) + j] = _ccv_nnc_micro_index_interpret(vars[i].shape[j], loop_counter, shapes, values, parameter_size); | ||||
| 297 | } else | ||||
| 298 | memcpy(shapes + i * CCV_NNC_MAX_DIM_ALLOC(12), shapes + vars[i].input * CCV_NNC_MAX_DIM_ALLOC(12), sizeof(int) * CCV_NNC_MAX_DIM_ALLOC(12)); | ||||
| 299 | } | ||||
| 300 | const ccv_array_t* const equal_assertions = combine->equal_assertions; | ||||
| 301 | for (i = 0; i < equal_assertions->rnum; i++) | ||||
| 302 | { | ||||
| 303 | ccv_nnc_micro_id_equal_assertion_t* const equal_assertion = ccv_array_get(equal_assertions, i)((void*)(((char*)((equal_assertions)->data)) + (size_t)(equal_assertions )->rsize * (size_t)(i))); | ||||
| 304 | 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])((void) sizeof ((shapes[equal_assertion->left.id * (12) + equal_assertion ->left.d] == shapes[equal_assertion->right.id * (12) + equal_assertion ->right.d]) ? 1 : 0), __extension__ ({ if (shapes[equal_assertion ->left.id * (12) + equal_assertion->left.d] == shapes[equal_assertion ->right.id * (12) + equal_assertion->right.d]) ; else __assert_fail ("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]" , "ccv_nnc_micro_interpret.c", 304, __extension__ __PRETTY_FUNCTION__ ); })); | ||||
| 305 | } | ||||
| 306 | size_t total_size = 0; | ||||
| 307 | for (i = 0; i < var_count; i++) | ||||
| 308 | { | ||||
| 309 | int flag = 0; | ||||
| 310 | for (j = 0; !flag && j < input_size; j++) | ||||
| 311 | flag = (program->inputs[j] == i); | ||||
| 312 | for (j = 0; !flag && j < output_size; j++) | ||||
| 313 | flag = (program->outputs[j] == i); | ||||
| 314 | if (flag) | ||||
| 315 | continue; | ||||
| 316 | if (vars[i].no_alloc) // This is skipped. | ||||
| 317 | continue; | ||||
| 318 | // allocating memory for these. | ||||
| 319 | size_t size = 1; | ||||
| 320 | for (j = 0; j < vars[i].dimensions; j++) | ||||
| 321 | size *= shapes[i * CCV_NNC_MAX_DIM_ALLOC(12) + j]; | ||||
| 322 | total_size += size; | ||||
| 323 | } | ||||
| 324 | float** const vars_mem = (float**)ccmallocmalloc(sizeof(float*) * var_count + sizeof(float) * total_size); | ||||
| 325 | float* ptr = (float*)(vars_mem + var_count); | ||||
| 326 | // Assuming these are not tensor_view_t. | ||||
| 327 | for (i = 0; i < output_size; i++) | ||||
| 328 | { | ||||
| 329 | assert(CCV_IS_TENSOR_CONTIGUOUS(outputs[i]))((void) sizeof (((!((*(int*)(outputs[i])) & CCV_TENSOR_VIEW ) || (((ccv_nnc_tensor_view_t*)outputs[i])->contiguous == 1 ))) ? 1 : 0), __extension__ ({ if ((!((*(int*)(outputs[i])) & CCV_TENSOR_VIEW) || (((ccv_nnc_tensor_view_t*)outputs[i])-> contiguous == 1))) ; else __assert_fail ("CCV_IS_TENSOR_CONTIGUOUS(outputs[i])" , "ccv_nnc_micro_interpret.c", 329, __extension__ __PRETTY_FUNCTION__ ); })); | ||||
| 330 | vars_mem[program->outputs[i]] = outputs[i]->data.f32; | ||||
| 331 | } | ||||
| 332 | for (i = 0; i < var_count; i++) | ||||
| 333 | { | ||||
| 334 | int flag = 0; | ||||
| 335 | for (j = 0; !flag && j < input_size; j++) | ||||
| 336 | flag = (program->inputs[j] == i); | ||||
| 337 | for (j = 0; !flag && j < output_size; j++) | ||||
| 338 | flag = (program->outputs[j] == i); | ||||
| 339 | if (flag) | ||||
| 340 | continue; | ||||
| 341 | if (vars[i].no_alloc) // This is skipped. | ||||
| 342 | { | ||||
| 343 | vars_mem[i] = 0; | ||||
| 344 | continue; | ||||
| 345 | } | ||||
| 346 | // allocating memory for these. | ||||
| 347 | size_t size = 1; | ||||
| 348 | for (j = 0; j < vars[i].dimensions; j++) | ||||
| 349 | size *= shapes[i * CCV_NNC_MAX_DIM_ALLOC(12) + j]; | ||||
| 350 | vars_mem[i] = ptr; | ||||
| 351 | ptr += size; | ||||
| 352 | } | ||||
| 353 | for (i = 0; i < input_size; i++) | ||||
| 354 | { | ||||
| 355 | assert(CCV_IS_TENSOR_CONTIGUOUS(inputs[i]))((void) sizeof (((!((*(int*)(inputs[i])) & CCV_TENSOR_VIEW ) || (((ccv_nnc_tensor_view_t*)inputs[i])->contiguous == 1 ))) ? 1 : 0), __extension__ ({ if ((!((*(int*)(inputs[i])) & CCV_TENSOR_VIEW) || (((ccv_nnc_tensor_view_t*)inputs[i])-> contiguous == 1))) ; else __assert_fail ("CCV_IS_TENSOR_CONTIGUOUS(inputs[i])" , "ccv_nnc_micro_interpret.c", 355, __extension__ __PRETTY_FUNCTION__ ); })); | ||||
| 356 | vars_mem[program->inputs[i]] = inputs[i]->data.f32; | ||||
| 357 | } | ||||
| 358 | ccv_nnc_micro_function_t* const functions = program->functions; | ||||
| 359 | const int function_count = program->function_count; | ||||
| 360 | int max_carried_count = 0; | ||||
| 361 | for (i = 0; i < function_count; i++) | ||||
| 362 | { | ||||
| 363 | const int block_count = functions[i].block_count; | ||||
| 364 | ccv_nnc_micro_loop_block_t* const blocks = block_count == 1 ? &functions[i].one_block : functions[i].blocks; | ||||
| 365 | for (j = 0; j < block_count; j++) | ||||
| 366 | max_carried_count = ccv_max(max_carried_count, blocks[j].carried_count)({ typeof (max_carried_count) _a = (max_carried_count); typeof (blocks[j].carried_count) _b = (blocks[j].carried_count); (_a > _b) ? _a : _b; }); | ||||
| 367 | } | ||||
| 368 | ccv_nnc_micro_scalar_t* const carrieds = max_carried_count > 0 ? (ccv_nnc_micro_scalar_t*)ccmallocmalloc(sizeof(ccv_nnc_micro_scalar_t) * max_carried_count) : 0; | ||||
| 369 | for (i = 0; i < function_count; i++) | ||||
| 370 | { | ||||
| 371 | const int block_count = functions[i].block_count; | ||||
| 372 | ccv_nnc_micro_loop_block_t* const blocks = block_count == 1 ? &functions[i].one_block : functions[i].blocks; | ||||
| 373 | for (j = 0; j < block_count; j++) | ||||
| 374 | _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 | } | ||||
| 376 | if (carrieds) | ||||
| 377 | ccfreefree(carrieds); | ||||
| 378 | ccfreefree(vars_mem); | ||||
| 379 | ccfreefree(shapes); | ||||
| 380 | } |