chromium/third_party/tflite/src/tensorflow/lite/delegates/serialization.h

/* Copyright 2021 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_DELEGATES_SERIALIZATION_H_
#define TENSORFLOW_LITE_DELEGATES_SERIALIZATION_H_

#include <cstdint>
#include <map>
#include <string>
#include <utility>
#include <vector>

#include "tensorflow/lite/core/c/common.h"

// This file implements a serialization utility that TFLite delegates can use to
// read/write initialization data.
//
// Example code:
//
// Initialization
// ==============
// SerializationParams params;
// // Acts as a namespace for all data entries for a given model.
// // See StrFingerprint().
// params.model_token = options->model_token;
// // Location where data is stored, should be private to the app using this.
// params.serialization_dir = options->serialization_dir;
// Serialization serialization(params);
//
// Writing data
// ============
// TfLiteContext* context = ...;
// TfLiteDelegateParams* params = ...;
// SerializationEntry kernels_entry = serialization->GetEntryForKernel(
//     "gpuv2_kernels", context, delegate_params);
//
// TfLiteStatus kernels_save_status = kernels_entry.SetData(
//     reinterpret_cast<char*>(data_ptr),
//     data_size);
// if (kernels_save_status == kTfLiteOk) {
//   //...serialization successful...
// } else if (kernels_save_status == kTfLiteDelegateDataWriteError) {
//   //...error in serializing data to disk...
// } else {
//   //...unexpected error...
// }
//
// Reading data
// ============
// std::string kernels_data;
// TfLiteStatus kernels_data_status = kernels_entry.GetData(&kernels_data);
// if (kernels_data_status == kTfLiteOk) {
//   //...serialized data found...
// } else if (kernels_data_status == kTfLiteDelegateDataNotFound) {
//   //...serialized data missing...
// } else {
//   //...unexpected error...
// }
namespace tflite {
namespace delegates {

// Helper to generate a unique string (converted from 64-bit farmhash) given
// some data. Intended for use by:
//
// 1. Delegates, to 'fingerprint' some custom data (like options),
//    and provide it as custom_key to Serialization::GetEntryForDelegate or
//    GetEntryForKernel.
// 2. TFLite clients, to fingerprint a model flatbuffer & get a unique
//    model_token.
std::string StrFingerprint(const void* data, const size_t num_bytes);

// Encapsulates a unique blob of data serialized by a delegate.
// Needs to be initialized with a Serialization instance.
// Any data set with this entry is 'keyed' by a 64-bit fingerprint unique to the
// parameters used during initialization via
// Serialization::GetEntryForDelegate/GetEntryForKernel.
//
// NOTE: TFLite cannot guarantee that the read data is always fully valid,
// especially if the directory is accessible to other applications/processes.
// It is the delegate's responsibility to validate the retrieved data.
class SerializationEntry {};

// Encapsulates all the data that clients can use to parametrize a Serialization
// interface.
SerializationParams;

// Utility to enable caching abilities for delegates.
// See documentation at the top of the file for usage details.
//
// WARNING: Experimental interface, subject to change.
class Serialization {};

// Helper for delegates to save their delegation decisions (which nodes to
// delegate) in TfLiteDelegate::Prepare().
// Internally, this uses a unique SerializationEntry based on the `context` &
// `delegate_id` to save the `node_ids`. It is recommended that `delegate_id` be
// unique to a backend/version to avoid reading back stale delegation decisions.
//
// NOTE: This implementation is platform-specific, so this method & the
// subsequent call to GetDelegatedNodes should happen on the same device.
TfLiteStatus SaveDelegatedNodes(TfLiteContext* context,
                                Serialization* serialization,
                                const std::string& delegate_id,
                                const TfLiteIntArray* node_ids);

// Retrieves list of delegated nodes that were saved earlier with
// SaveDelegatedNodes.
// Caller assumes ownership of data pointed by *nodes_ids.
//
// NOTE: This implementation is platform-specific, so SaveDelegatedNodes &
// corresponding GetDelegatedNodes should be called on the same device.
TfLiteStatus GetDelegatedNodes(TfLiteContext* context,
                               Serialization* serialization,
                               const std::string& delegate_id,
                               TfLiteIntArray** node_ids);

}  // namespace delegates
}  // namespace tflite

#endif  // TENSORFLOW_LITE_DELEGATES_SERIALIZATION_H_