1/* Copyright 2022 The TensorFlow Authors. All Rights Reserved.
2
3Licensed under the Apache License, Version 2.0 (the "License");
4you may not use this file except in compliance with the License.
5You may obtain a copy of the License at
6
7 http://www.apache.org/licenses/LICENSE-2.0
8
9Unless required by applicable law or agreed to in writing, software
10distributed under the License is distributed on an "AS IS" BASIS,
11WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12See the License for the specific language governing permissions and
13limitations under the License.
14==============================================================================*/
15#ifndef TENSORFLOW_LITE_C_COMMON_INTERNAL_H_
16#define TENSORFLOW_LITE_C_COMMON_INTERNAL_H_
17
18#include "tensorflow/lite/c/c_api_types.h"
19#include "tensorflow/lite/c/common.h"
20
21// Internal structures and subroutines used by the C API. These are likely to
22// change and should not be depended on directly by any C API clients.
23//
24// NOTE: This header does not follow C conventions and does not define a C API.
25// It is effectively an (internal) implementation detail of the C API.
26
27// `TfLiteRegistrationExternal` is an external version of `TfLiteRegistration`
28// for C API which doesn't use internal types (such as `TfLiteContext`) but only
29// uses stable API types (such as `TfLiteOpaqueContext`). The purpose of each
30// field is the exactly the same as with `TfLiteRegistration`.
31typedef struct TfLiteRegistrationExternal {
32 // Custom op name. This should be non-null iff the op is a custom op,
33 // i.e. iff builtin_code is kTfLiteBuiltinCustom.
34 const char* custom_name;
35
36 // The version of the op. The version should be higher than 0.
37 int version;
38
39 // Initializes the op from serialized data.
40 void* (*init)(void* data, TfLiteOpaqueContext* context, const char* buffer,
41 size_t length);
42 // The pointer `buffer` is the data previously returned by an init invocation.
43 void (*free)(void* data, TfLiteOpaqueContext* context, void* buffer);
44
45 // Called when the inputs that this node depends on have been resized.
46 TfLiteStatus (*prepare)(void* data, TfLiteOpaqueContext* context,
47 TfLiteOpaqueNode* node);
48
49 // Called when the node is executed. (should read node->inputs and output to
50 // node->outputs).
51 TfLiteStatus (*invoke)(void* data, TfLiteOpaqueContext* context,
52 TfLiteOpaqueNode* node);
53
54 // Builtin op code.
55 // The values stored in this field should be enum constants from the
56 // TfLiteBuiltinOperator enum.
57 // For custom ops, this should be the value kTfLiteBuiltinCustom.
58 int32_t builtin_code;
59 // Opaque data, meant to be supplied as the 'data' argument when 'init' is
60 // invoked.
61 void* init_data;
62 // Opaque data, meant to be supplied as the 'data' argument when 'free' is
63 // invoked.
64 void* free_data;
65 // Opaque data, meant to be supplied as the 'data' argument when 'prepare' is
66 // invoked.
67 void* prepare_data;
68 // Opaque data, meant to be supplied as the 'data' argument when 'invoke' is
69 // invoked.
70 void* invoke_data;
71} TfLiteRegistrationExternal;
72
73// Returns true iff it's safe to dereference
74// 'delegate->opaque_delegate_builder'.
75inline bool TfLiteDelegateHasValidOpaqueDelegateBuilder(
76 const TfLiteDelegate* delegate) {
77 // We want to give precedence to the delegate's `opaque_delegate_builder`
78 // field when it is available. In an ideal setting, where all client code
79 // properly initializes the delegate, we could simply check if the
80 // `opaque_delegate_builder` contains a non-zero address. However, in
81 // practice this breaks code that doesn't adhere to these best practices.
82 //
83 // We can avoid this problem by checking the `Prepare` field contained in the
84 // `TfliteDelegate` (not to be confused with the `Prepare` field contained in
85 // `TfLiteOpaqueDelegateBuilder` struct). In order to tell if we should use
86 // the `opaque_delegate_builder` field we check that the `TfLiteDelegate`'s
87 // `Prepare` member is null. This should be true for every delegate that
88 // adopts the `TfLiteOpaqueDelegateBuilder` interface and should not be true
89 // for any delegate implementation that is using `TfLiteDelegate` directly.
90 //
91 // TODO(b/245730811): Consider signalling to clients if the delegate is not
92 // initialized cleanly.
93 return delegate->Prepare == nullptr &&
94 delegate->opaque_delegate_builder != nullptr;
95}
96
97// Invokes 'Prepare' on the provided 'delegate', giving the 'delegate' a view
98// of the current graph through the provided 'context'. Returns the delegate's
99// 'Prepare' return value.
100TfLiteStatus TfLiteDelegatePrepareInternal(TfLiteContext* context,
101 TfLiteDelegate* delegate);
102
103// Invokes 'CopyFromBufferHandle' on the provided 'delegate', supplying the
104// provided 'buffer_handle' and 'tensor' as arguments. The provided
105// 'buffer_handle' must have a non-null buffer handle value (i.e., not
106// 'kTfLiteNullBufferHandle'). Returns the delegate's 'CopyFromBufferHandle'
107// return value.
108TfLiteStatus TfLiteDelegateCopyFromBufferHandleInternal(
109 TfLiteContext* context, TfLiteDelegate* delegate,
110 TfLiteBufferHandle buffer_handle, TfLiteTensor* tensor);
111
112// Invokes 'FreeBufferHandle' on the provided 'delegate', supplying the provided
113// 'buffer_handle' as an argument. The '*buffer_handle' must have a non-null
114// buffer handle value (i.e., not 'kTfLiteNullBufferHandle'). Returns
115// 'kTfLiteOk' if 'FreeBufferHandle' was called, or 'kTfLiteError' if the
116// callback is not available.
117TfLiteStatus TfLiteDelegateFreeBufferHandleInternal(
118 TfLiteContext* context, TfLiteDelegate* delegate,
119 TfLiteBufferHandle* buffer_handle);
120
121// Returns the 'delegate' flags value. Note, if the delegate contains a valid
122// opaque_delegate_builder field, then the flags of the delegate external are
123// returned. Otherwise, the flags field inside `TfLiteDelegate` is returned.
124int64_t TfLiteDelegateGetFlagsInternal(TfLiteDelegate* delegate);
125
126#endif // TENSORFLOW_LITE_C_COMMON_INTERNAL_H_
127