LiteRT in Google Play services Interpreter C and C++ APIs

LiteRT in Google Play services runtime lets you run machine learning (ML) models without statically bundling LiteRT libraries into your app. This guide provide instructions on how to use the C or C++ Interpreter APIs for Google Play services.

Before working with the LiteRT in Google Play services C API or C++ API, make sure you have the CMake build tool installed.

Update your build configuration

(1) Add the Google Play services LiteRT dependency to your app's build.gradle file to access the Play services API for LiteRT:

implementation "com.google.android.gms:play-services-litert:17.0.0"

(2) Then, enable the Prefab feature to access the C and C++ APIs from your CMake script by updating the android block of your module's build.gradle file:

buildFeatures {
  prefab = true
}

(3) Configure your CMake script (CMakeLists.txt) to import the native SDKs from the Prefab packages:

C

find_package(tensorflowlite_jni_gms_client REQUIRED CONFIG)

# Set up C/C++ compiler flags to enable use of LiteRT in Play services
# (rather than regular LiteRT bundled with the app).
add_compile_definitions(TFLITE_IN_GMSCORE)
add_compile_definitions(TFLITE_WITH_STABLE_ABI)

target_link_libraries(tflite-jni # your JNI lib target
        tensorflowlite_jni_gms_client::tensorflowlite_jni_gms_client
        android # other deps for your target
        log)
      

C++

# Fetch Abseil and FlatBuffers targets required by the C++ SDK.
include(FetchContent)
FetchContent_Declare(
        flatbuffers
        URL https://github.com/google/flatbuffers/archive/refs/tags/v25.12.19.zip
)
FetchContent_Declare(
        absl
        URL https://github.com/abseil/abseil-cpp/archive/refs/tags/20260817.0.zip
)
set(FLATBUFFERS_BUILD_FLATC OFF)
set(FLATBUFFERS_BUILD_TESTS OFF)
set(FLATBUFFERS_INSTALL OFF)
set(ABSL_ENABLE_INSTALL ON)
FetchContent_MakeAvailable(flatbuffers)
FetchContent_MakeAvailable(absl)

add_library(flatbuffers::flatbuffers ALIAS flatbuffers)

# Set up LiteRT in Play services C API (tensorflowlite_jni_gms_client) dependency.
find_package(tensorflowlite_jni_gms_client REQUIRED CONFIG)

# Set up LiteRT in Play services C++ API (tflite_cc_api) dependency.
get_target_property(tflite_cc_api_dir
        tensorflowlite_jni_gms_client::tensorflowlite_jni_gms_client
        INTERFACE_INCLUDE_DIRECTORIES)
add_subdirectory(${tflite_cc_api_dir}/cc_sdk tflite_cc_api_build)

# Set up C/C++ compiler flags to enable use of LiteRT in Play services
# (rather than regular LiteRT bundled with the app).
add_compile_definitions(TFLITE_IN_GMSCORE)
add_compile_definitions(TFLITE_WITH_STABLE_ABI)

target_link_libraries(tflite-jni # your JNI lib target
        tflite_cc_api::tflite_cc_api
        tensorflowlite_jni_gms_client::tensorflowlite_jni_gms_client
        android # other deps for your target
        log)
      

Migrating from play-services-tflite-java (C++ SDK)

In previous releases of play-services-tflite-java (v16.5.0 and earlier), the C++ SDK was extracted using a custom Gradle script (tflite-java-extract-cpp-sdk.gradle) and imported with a custom CMake module (Findtflite_cc_api.cmake). In play-services-litert (v17.0.0 and later), the C++ SDK is built directly from the Prefab packages in the library.

To migrate an existing C++ project:

  1. Update your dependency in build.gradle from com.google.android.gms:play-services-tflite-java:16.5.0 to com.google.android.gms:play-services-litert:17.0.0. Keep prefab = true.
  2. Remove apply from: 'tflite-java-extract-cpp-sdk.gradle' from your build.gradle file, and delete tflite-java-extract-cpp-sdk.gradle from your project.
  3. In your CMake project, remove the Modules directory (containing Findtflite_cc_api.cmake), and remove list(PREPEND CMAKE_MODULE_PATH ...) and find_package(tflite_cc_api REQUIRED MODULE) from your CMakeLists.txt.
  4. Make the Abseil and FlatBuffers CMake targets available in your project, for example with FetchContent.
  5. Import the SDK from the Prefab packages:

    • For the Interpreter C++ API: Import from the tensorflowlite_jni_gms_client Prefab package:

      find_package(tensorflowlite_jni_gms_client REQUIRED CONFIG)
      get_target_property(tflite_cc_api_dir
              tensorflowlite_jni_gms_client::tensorflowlite_jni_gms_client
              INTERFACE_INCLUDE_DIRECTORIES)
      add_subdirectory(${tflite_cc_api_dir}/cc_sdk tflite_cc_api_build)
      target_link_libraries(sample_app tflite_cc_api::tflite_cc_api)
      

Initialize the LiteRT runtime

Before calling the LiteRT C or C++ API you must initialize the TfLiteNative runtime in your Java or Kotlin code.

Java

Task tfLiteInitializeTask = TfLiteNative.initialize(context);
      

Kotlin

val tfLiteInitializeTask: Task = TfLiteNative.initialize(context)
        

Using the Google Play services Task API, TfLiteNative.initialize asynchronously loads the LiteRT runtime from Google Play services into your application's runtime process. Use addOnSuccessListener() to make sure the TfLite.initialize() task completes before executing code that accesses LiteRT APIs. Once the task has completed successfully, you can invoke all the available LiteRT Native APIs.

Native code implementation

To use LiteRT in Google Play services with your C/C++ code, you can do one (or both) of the following:

  • declare new JNI functions to call C or C++ functions from your Java code
  • call the LiteRT Native API from your existing C or C++ code.

JNI functions

You can declare new JNI functions to make the LiteRT runtime declared in C/C++ code accessible to your Java/Kotlin code as follow:

Java

package com.google.samples.gms.tflite.c;

public class TfLiteJni {
  static {
    System.loadLibrary("tflite-jni");
  }
  public TfLiteJni() { /**/ };
  public native void loadModel(AssetManager assetManager, String assetName);
  public native float[] runInference(float[] input);  // For example.
}
      

Kotlin

package com.google.samples.gms.tflite.c

class TfLiteJni() {
  companion object {
    init {
      System.loadLibrary("tflite-jni")
    }
  }
  external fun loadModel(assetManager: AssetManager, assetName: String)
  external fun runInference(input: FloatArray): FloatArray  // For example.
}
        

Matching the following loadModel and runInference C or C++ functions:

#ifdef __cplusplus
extern "C" {
#endif

void Java_com_google_samples_gms_tflite_c_loadModel(
  JNIEnv *env, jobject tflite_jni, jobject asset_manager, jstring asset_name){
  //...
}

jfloatArray Java_com_google_samples_gms_tflite_c_TfLiteJni_runInference(
  JNIEnv* env, jobject tfliteJni, jfloatArray input) {
  //...
}

#ifdef __cplusplus
}  // extern "C".
#endif

You can then call your C/C++ functions from your Java/Kotlin code:

Java

tfLiteHandleTask.onSuccessTask(unused -> {
    TfLiteJni jni = new TfLiteJni();
    jni.loadModel(getAssets(), "add.bin");
    //...
});
    

Kotlin

tfLiteHandleTask.onSuccessTask {
    val jni = TfLiteJni()
    jni.loadModel(assets, "add.bin")
    // ...
}
      

LiteRT in native code

Include the appropriate API header file to include the LiteRT with Google Play services API:

C

#include "tensorflow/lite/c/c_api.h"
      

C++

#include "tensorflow/lite/interpreter.h"
#include "tensorflow/lite/model_builder.h"
      

You can then use the regular LiteRT C or C++ API:

C

TfLiteModel* model = TfLiteModelCreate(model_asset, model_asset_length);
// ...
TfLiteInterpreterOptions* options = TfLiteInterpreterOptionsCreate();
// ...
TfLiteInterpreter* interpreter = TfLiteInterpreterCreate(model, options);
      

C++

  // Load the model.
  auto model = tflite::FlatBufferModel::VerifyAndBuildFromBuffer(
      model_asset, model_asset_length);
  ...
  // Initialize the interpreter.
  BuiltinOpResolver op_resolver;
  InterpreterBuilder interpreter_builder(*model, op_resolver);
  interpreter_builder(&interpreter);
  std::unique_ptr<Interpreter>` interpreter;
  interpreter_builder(&interpreter);
      

Supported APIs

C

The LiteRT with Google Play services C API headers provide the same API as the regular LiteRT C API, excluding features that are deprecated or experimental. For now the functions and types from the following headers are available.

TensorFlow Lite APIs for loading and executing models:

tensorflow/lite/c/c_api.h
tensorflow/lite/c/c_api_types.h
      

TensorFlow Lite Extension APIs for defining custom ops and delegates (e.g. for hardware acceleration):

tensorflow/lite/c/c_api_opaque.h
tensorflow/lite/c/common.h
tensorflow/lite/c/builtin_op_data.h
tensorflow/lite/builtin_ops.h
      

Delegate plug-in APIs for using existing delegates:

tensorflow/lite/acceleration/configuration/c/gpu_plugin.h
tensorflow/lite/acceleration/configuration/c/xnnpack_plugin.h
      

Please note that functions from the c_api_experimental.h header are not supported.

You can use functions specific to LiteRT with Google Play services by including the following header:

tensorflow/lite/abi/tflite.h
.

C++

The LiteRT with Google Play services C++ API headers provide the same API as the regular LiteRT C++ API, excluding features that are deprecated or experimental, and with a few minor exceptions noted later in this section. The functionality from the following headers is available:

tensorflow/lite/model_builder.h
tensorflow/lite/interpreter_builder.h
tensorflow/lite/interpreter.h
tensorflow/lite/signature_runner.h
tensorflow/lite/acceleration/configuration/delegate_registry.h
tensorflow/lite/kernels/builtin_op_kernels.h
tensorflow/lite/kernels/register.h
tensorflow/lite/tools/verifier.h
      

For tensorflow/lite/interpreter.h, the supported API with Play services excludes a few members of tflite::Interpreter for which LiteRT does not offer a stable ABI:

Interpreter::variables()
Interpreter::nodes_size()
Interpreter::node_and_registration(int node_index)
Interpreter::kTensorsReservedCapacity
Interpreter::kTensorsCapacityHeadroom
Interpreter::OpProfilingString(const TfLiteRegistration&, const TfLiteNode*)
Interpreter::SetExternalContext(TfLiteExternalContextType type, TfLiteExternalContext* ctx)