| 151 | } |
| 152 | |
| 153 | TfLiteStatus MicroInterpreter::Invoke() { |
| 154 | if (initialization_status_ != kTfLiteOk) { |
| 155 | error_reporter_->Report("Invoke() called after initialization failed\n"); |
| 156 | return kTfLiteError; |
| 157 | } |
| 158 | |
| 159 | // Ensure tensors are allocated before the interpreter is invoked to avoid |
| 160 | // difficult to debug segfaults. |
| 161 | if (!tensors_allocated_) { |
| 162 | AllocateTensors(); |
| 163 | } |
| 164 | TfLiteStatus status = kTfLiteOk; |
| 165 | auto opcodes = model_->operator_codes(); |
| 166 | for (size_t i = 0; i < operators_->size(); ++i) { |
| 167 | const auto* op = operators_->Get(i); |
| 168 | size_t index = op->opcode_index(); |
| 169 | if (index < 0 || index >= opcodes->size()) { |
| 170 | error_reporter_->Report("Missing registration for opcode_index %d\n", |
| 171 | index); |
| 172 | return kTfLiteError; |
| 173 | } |
| 174 | auto opcode = (*opcodes)[index]; |
| 175 | const TfLiteRegistration* registration = nullptr; |
| 176 | status = GetRegistrationFromOpCode(opcode, op_resolver_, error_reporter_, |
| 177 | ®istration); |
| 178 | if (status != kTfLiteOk) { |
| 179 | return status; |
| 180 | } |
| 181 | if (registration == nullptr) { |
| 182 | error_reporter_->Report("Skipping op for opcode_index %d\n", index); |
| 183 | return kTfLiteError; |
| 184 | } |
| 185 | BuiltinOperator op_type = |
| 186 | static_cast<BuiltinOperator>(registration->builtin_code); |
| 187 | |
| 188 | if (op_type != BuiltinOperator_CUSTOM && op->custom_options()) { |
| 189 | error_reporter_->Report( |
| 190 | "Unsupported behavior: found builtin operator %s with custom " |
| 191 | "options.\n", |
| 192 | EnumNameBuiltinOperator(op_type)); |
| 193 | return kTfLiteError; |
| 194 | } |
| 195 | StackDataAllocator stack_data_allocator; |
| 196 | const char* custom_data = nullptr; |
| 197 | size_t custom_data_size = 0; |
| 198 | unsigned char* builtin_data = nullptr; |
| 199 | if (op->custom_options()) { |
| 200 | custom_data = reinterpret_cast<const char*>(op->custom_options()->data()); |
| 201 | custom_data_size = op->custom_options()->size(); |
| 202 | } else { |
| 203 | TF_LITE_ENSURE_STATUS(ParseOpData(op, op_type, error_reporter_, |
| 204 | &stack_data_allocator, |
| 205 | (void**)(&builtin_data))); |
| 206 | } |
| 207 | |
| 208 | const char* init_data; |
| 209 | size_t init_data_size; |
| 210 | if (registration->builtin_code == BuiltinOperator_CUSTOM) { |