1 | /* Copyright 2022 The TensorFlow Authors. All Rights Reserved. |
2 | |
3 | Licensed under the Apache License, Version 2.0 (the "License"); |
4 | you may not use this file except in compliance with the License. |
5 | You may obtain a copy of the License at |
6 | |
7 | http://www.apache.org/licenses/LICENSE-2.0 |
8 | |
9 | Unless required by applicable law or agreed to in writing, software |
10 | distributed under the License is distributed on an "AS IS" BASIS, |
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | See the License for the specific language governing permissions and |
13 | limitations 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`. |
31 | typedef 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'. |
75 | inline 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. |
100 | TfLiteStatus 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. |
108 | TfLiteStatus 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. |
117 | TfLiteStatus 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. |
124 | int64_t TfLiteDelegateGetFlagsInternal(TfLiteDelegate* delegate); |
125 | |
126 | #endif // TENSORFLOW_LITE_C_COMMON_INTERNAL_H_ |
127 | |