MCPcopy Create free account
hub / github.com/DeepRec-AI/DeepRec / Invoke

Method Invoke

tensorflow/lite/core/subgraph.cc:749–852  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

747}
748
749TfLiteStatus Subgraph::Invoke() {
750 if (!consistent_) {
751 ReportError("Invoke called on model that is not consistent.");
752 return kTfLiteError;
753 }
754
755 TfLiteStatus status = kTfLiteOk;
756 if (state_ == kStateUninvokable) {
757 ReportError("Invoke called on model that is not ready.");
758 return kTfLiteError;
759 }
760
761 // This is only needed for UseNNAPI(true);
762 if (should_apply_nnapi_delegate_ && !applied_nnapi_delegate_) {
763 TF_LITE_ENSURE_OK(&context_, ModifyGraphWithDelegate(NnApiDelegate()));
764 // only need to modify the graph once upon the first invocation.
765 applied_nnapi_delegate_ = true;
766 }
767
768 // Invocations are always done in node order.
769 // Note that calling Invoke repeatedly will cause the original memory plan to
770 // be reused, unless either ResizeInputTensor() or AllocateTensors() has been
771 // called.
772 for (int execution_plan_index = 0;
773 execution_plan_index < execution_plan_.size(); execution_plan_index++) {
774 if (execution_plan_index == next_execution_plan_index_to_prepare_) {
775 TF_LITE_ENSURE_STATUS(PrepareOpsAndTensors());
776 TF_LITE_ENSURE(&context_, next_execution_plan_index_to_prepare_ >=
777 execution_plan_index);
778 }
779 int node_index = execution_plan_[execution_plan_index];
780 TfLiteNode& node = nodes_and_registration_[node_index].first;
781 const TfLiteRegistration& registration =
782 nodes_and_registration_[node_index].second;
783 TFLITE_SCOPED_OPERATOR_PROFILE(profiler_, node_index);
784
785 // TODO(ycling): This is an extra loop through inputs to check if the data
786 // need to be copied from Delegate buffer to raw memory, which is often not
787 // needed. We may want to cache this in prepare to know if this needs to be
788 // done for a node or not.
789 for (int i = 0; i < node.inputs->size; ++i) {
790 int tensor_index = node.inputs->data[i];
791 if (tensor_index == kOptionalTensor) {
792 continue;
793 }
794 TfLiteTensor* tensor = &tensors_[tensor_index];
795 if (tensor->delegate && tensor->delegate != node.delegate &&
796 tensor->data_is_stale) {
797 TF_LITE_ENSURE_STATUS(EnsureTensorDataIsReadable(tensor_index));
798 }
799 if (tensor->data.raw == nullptr && tensor->bytes > 0) {
800 if (registration.builtin_code == kTfLiteBuiltinReshape && i == 1) {
801 // In general, having a tensor here with no buffer will be an error.
802 // However, for the reshape operator, the second input tensor is only
803 // used for the shape, not for the data. Thus, null buffer is ok.
804 continue;
805 } else {
806 // In all other cases, we need to return an error as otherwise we will

Callers 5

ExecuteTfLiteFunction · 0.45
TESTFunction · 0.45
TESTFunction · 0.45
TESTFunction · 0.45

Calls 6

HasDynamicTensorFunction · 0.85
ResetAllocationsMethod · 0.80
ReportOpErrorFunction · 0.70
ReportErrorFunction · 0.50
NnApiDelegateFunction · 0.50
sizeMethod · 0.45

Tested by 3

TESTFunction · 0.36
TESTFunction · 0.36
TESTFunction · 0.36