diff --git a/tensorflow_lite_support/acceleration/configuration/BUILD b/tensorflow_lite_support/acceleration/configuration/BUILD index e48a288f9..7709ea9a8 100644 --- a/tensorflow_lite_support/acceleration/configuration/BUILD +++ b/tensorflow_lite_support/acceleration/configuration/BUILD @@ -31,6 +31,18 @@ cc_library( alwayslink = 1, # For registration to always run. ) +cc_library( + name = "coreml_plugin", + hdrs = ["coreml_plugin.h"], + visibility = [ + "//visibility:public", + ], + deps = [ + "@org_tensorflow//tensorflow/lite/experimental/acceleration/configuration:coreml_plugin", + ], + alwayslink = 1, # For registration to always run. +) + cc_library( name = "hexagon_plugin", visibility = [ diff --git a/tensorflow_lite_support/acceleration/configuration/coreml_plugin.h b/tensorflow_lite_support/acceleration/configuration/coreml_plugin.h new file mode 100644 index 000000000..4b4d14fe5 --- /dev/null +++ b/tensorflow_lite_support/acceleration/configuration/coreml_plugin.h @@ -0,0 +1,27 @@ +/* Copyright 2020 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ +#ifndef TENSORFLOW_LITE_SUPPORT_ACCELERATION_CONFIGURATION_COREML_PLUGIN_H_ +#define TENSORFLOW_LITE_SUPPORT_ACCELERATION_CONFIGURATION_COREML_PLUGIN_H_ + +namespace tflite { +namespace delegates { +// This function can be called to force link the coreml plugin. +void register_new(); + +} // namespace delegates +} // namespace tflite + + +#endif // TENSORFLOW_LITE_SUPPORT_ACCELERATION_CONFIGURATION_COREML_PLUGIN_H_ diff --git a/tensorflow_lite_support/c/task/vision/image_classifier.cc b/tensorflow_lite_support/c/task/vision/image_classifier.cc index 52e215116..37abe8182 100644 --- a/tensorflow_lite_support/c/task/vision/image_classifier.cc +++ b/tensorflow_lite_support/c/task/vision/image_classifier.cc @@ -88,6 +88,17 @@ StatusOr CreateImageClassifierCppOptionsFromCOptions( cpp_options.set_score_threshold( c_options->classification_options.score_threshold); + cpp_options.mutable_base_options() + ->mutable_compute_settings() + ->mutable_tflite_settings() + ->set_delegate(tflite::proto::Delegate::CORE_ML); + + cpp_options.mutable_base_options() + ->mutable_compute_settings() + ->mutable_tflite_settings() + ->mutable_coreml_settings() + ->set_enabled_devices(tflite::proto::CoreMLSettings::DEVICES_ALL); + return cpp_options; } } // namespace diff --git a/tensorflow_lite_support/cc/port/default/BUILD b/tensorflow_lite_support/cc/port/default/BUILD index f506a7c35..547b66325 100644 --- a/tensorflow_lite_support/cc/port/default/BUILD +++ b/tensorflow_lite_support/cc/port/default/BUILD @@ -41,6 +41,7 @@ cc_library( "@org_tensorflow//tensorflow/lite:minimal_logging", "@org_tensorflow//tensorflow/lite/c:common", "@org_tensorflow//tensorflow/lite/experimental/acceleration/configuration:nnapi_plugin", + "//tensorflow_lite_support/acceleration/configuration:coreml_plugin", "@org_tensorflow//tensorflow/lite/delegates:interpreter_utils", "@org_tensorflow//tensorflow/lite/experimental/acceleration/configuration:configuration_cc_proto", "@org_tensorflow//tensorflow/lite/experimental/acceleration/configuration:delegate_registry", diff --git a/tensorflow_lite_support/cc/port/default/tflite_wrapper.cc b/tensorflow_lite_support/cc/port/default/tflite_wrapper.cc index d47c1ce7e..4c2bd1e33 100644 --- a/tensorflow_lite_support/cc/port/default/tflite_wrapper.cc +++ b/tensorflow_lite_support/cc/port/default/tflite_wrapper.cc @@ -23,6 +23,7 @@ limitations under the License. #include "tensorflow/lite/experimental/acceleration/configuration/proto_to_flatbuffer.h" #include "tensorflow/lite/minimal_logging.h" #include "tensorflow_lite_support/cc/port/status_macros.h" +#include "tensorflow/lite/experimental/acceleration/configuration/coreml_plugin.h" namespace tflite { namespace support { @@ -318,6 +319,10 @@ void TfLiteInterpreterWrapper::SetTfLiteCancellation() { absl::Status TfLiteInterpreterWrapper::LoadDelegatePlugin( const std::string& name, const tflite::TFLiteSettings& tflite_settings) { + + // Calling this function from coreml_plugin to force linking of core ml plugin for device builds. + tflite::delegates::register_new(); + delegate_plugin_ = DelegatePluginRegistry::CreateByName( absl::StrFormat("%sPlugin", name), tflite_settings); diff --git a/tensorflow_lite_support/ios/BUILD b/tensorflow_lite_support/ios/BUILD index b2a13352d..d3a60ee8b 100644 --- a/tensorflow_lite_support/ios/BUILD +++ b/tensorflow_lite_support/ios/BUILD @@ -9,6 +9,7 @@ load( load( "//tensorflow_lite_support/ios:ios.bzl", "TFL_TASK_MINIMUM_OS_VERSION", + "TFL_TASK_COREML_MINIMUM_OS_VERSION", "strip_api_include_path_prefix", ) @@ -142,6 +143,12 @@ objc_library( ], ) +# Xcode 12 does not support ios fat libraries. Frameworks built for multiple +# architectures should be compiled into a .xcframework inside. Bazel currently +# does not support building .xcframework. You have to build the framework +# for the architecture you decide to test on. +# Use the below command to build for arm64 which lets you test the library on +# iOS devices. # bazel build -c opt --config=ios_arm64 //tensorflow_lite_support/ios:TensorFlowLiteTaskVision_framework ios_static_framework( name = "TensorFlowLiteTaskVision_framework", @@ -159,12 +166,12 @@ ios_static_framework( ":GMLImage.h", ], bundle_name = "TensorFlowLiteTaskVision", - minimum_os_version = TFL_TASK_MINIMUM_OS_VERSION, + minimum_os_version = TFL_TASK_COREML_MINIMUM_OS_VERSION, deps = [ "//tensorflow_lite_support/ios/task/vision:TFLImageClassifier", "//tensorflow_lite_support/ios/task/vision:TFLObjectDetector", "//tensorflow_lite_support/ios/task/vision:TFLImageSegmenter", - ], + ], ) ios_static_framework( @@ -182,4 +189,3 @@ ios_static_framework( "//tensorflow_lite_support/ios/task/text/qa:TFLBertQuestionAnswerer", ], ) - diff --git a/tensorflow_lite_support/ios/ios.bzl b/tensorflow_lite_support/ios/ios.bzl index e943823d4..1a2d307a7 100644 --- a/tensorflow_lite_support/ios/ios.bzl +++ b/tensorflow_lite_support/ios/ios.bzl @@ -1,14 +1,14 @@ """TensorFlow Lite Support Library Helper Rules for iOS""" +TFL_TASK_MINIMUM_OS_VERSION = "10.0" +TFL_TASK_COREML_MINIMUM_OS_VERSION = "12.0" + # When the static framework is built with bazel, the all header files are moved # to the "Headers" directory with no header path prefixes. This auxiliary rule # is used for stripping the path prefix to the C/iOS API header files included by # other C/iOS API header files. # In case of C header files includes start with a keyword of "#include'. # Imports in iOS header files start with a keyword of '#import'. - -TFL_TASK_MINIMUM_OS_VERSION = "10.0" - def strip_api_include_path_prefix(name, hdr_labels, prefix = ""): """Create modified header files with the import path stripped out. @@ -20,8 +20,9 @@ def strip_api_include_path_prefix(name, hdr_labels, prefix = ""): """ for hdr_label in hdr_labels: hdr_filename = hdr_label.split(":")[-1] - # The last path component of iOS header files can be sources/some_file.h - # or Sources/some_file.h. Hence it wiill contain a '/'. So the string + + # The last path component of iOS header files can be sources/some_file.h + # or Sources/some_file.h. Hence it wiill contain a '/'. So the string # can be split at '/' to get the header file name. if "/" in hdr_filename: hdr_filename = hdr_filename.split("/")[-1] @@ -37,4 +38,3 @@ def strip_api_include_path_prefix(name, hdr_labels, prefix = ""): > "$@" """.format(prefix, hdr_label), ) - diff --git a/tensorflow_lite_support/ios/test/task/vision/image_classifier/BUILD b/tensorflow_lite_support/ios/test/task/vision/image_classifier/BUILD index 06da0ea6b..ca4753646 100644 --- a/tensorflow_lite_support/ios/test/task/vision/image_classifier/BUILD +++ b/tensorflow_lite_support/ios/test/task/vision/image_classifier/BUILD @@ -73,6 +73,7 @@ objc_library( "//tensorflow_lite_support/ios/task/vision/utils:GMLImageUtils", "@org_tensorflow//tensorflow/lite/experimental/acceleration/configuration:coreml_plugin", ], + copts = ["-std=c++14"], ) ios_unit_test( diff --git a/tensorflow_lite_support/ios/test/task/vision/image_classifier/TFLImageClassifierCoreMLDelegateTest.mm b/tensorflow_lite_support/ios/test/task/vision/image_classifier/TFLImageClassifierCoreMLDelegateTest.mm index 698387707..3921baca5 100644 --- a/tensorflow_lite_support/ios/test/task/vision/image_classifier/TFLImageClassifierCoreMLDelegateTest.mm +++ b/tensorflow_lite_support/ios/test/task/vision/image_classifier/TFLImageClassifierCoreMLDelegateTest.mm @@ -14,10 +14,10 @@ ==============================================================================*/ #import -#import "third_party/tensorflow_lite_support/ios/task/vision/utils/sources/GMLImage+Utils.h" +#import "tensorflow_lite_support/ios/task/vision/utils/sources/GMLImage+Utils.h" -#include "third_party/tensorflow_lite_support/c/task/vision/utils/frame_buffer_cpp_c_utils.h" -#include "third_party/tensorflow_lite_support/cc/task/vision/image_classifier.h" +#include "tensorflow_lite_support/c/task/vision/utils/frame_buffer_cpp_c_utils.h" +#include "tensorflow_lite_support/cc/task/vision/image_classifier.h" using ImageClassifier = ::tflite::task::vision::ImageClassifier; using ImageClassifierOptions = ::tflite::task::vision::ImageClassifierOptions; @@ -47,12 +47,12 @@ - (void)testCoreMLDelegateCreationFailsWithNeuralEngine { options.mutable_base_options() ->mutable_compute_settings() ->mutable_tflite_settings() - ->set_delegate(::acceleration::Delegate::CORE_ML); + ->set_delegate(tflite::proto::Delegate::CORE_ML); options.mutable_base_options() ->mutable_compute_settings() ->mutable_tflite_settings() ->mutable_coreml_settings() - ->set_enabled_devices(::acceleration::CoreMLDelegateSettings::DEVICES_ALL); + ->set_enabled_devices(tflite::proto::CoreMLSettings::DEVICES_ALL); // Creates the classifier. tflite::support::StatusOr> image_classifier_status =