Bug Summary

File:.cache/bazel/_bazel_alan/39be661231df2a680c9b74265384c13c/execroot/org_tensorflow/tensorflow/lite/python/interpreter_wrapper/interpreter_wrapper.cc
Warning:line 140, column 28
PyObject ownership leak with reference count of 1

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name interpreter_wrapper.cc -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -analyzer-output=html -analyzer-checker=python -analyzer-disable-checker=deadcode -analyzer-config prune-paths=true,suppress-c++-stdlib=true,suppress-null-return-paths=false,crosscheck-with-z3=true,model-path=/opt/pyrefcon/lib/pyrefcon/models/models -analyzer-config experimental-enable-naive-ctu-analysis=true,ctu-dir=/tmp/pyrefcon/tensorflow/csa-scan,ctu-index-name=/tmp/pyrefcon/tensorflow/csa-scan/externalDefMap.txt,ctu-invocation-list=/tmp/pyrefcon/tensorflow/csa-scan/invocations.yaml,display-ctu-progress=false -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/home/pyrefcon/.cache/bazel/_bazel_alan/39be661231df2a680c9b74265384c13c/execroot/org_tensorflow -resource-dir /opt/pyrefcon/lib/clang/13.0.0 -iquote . -iquote bazel-out/k8-opt/bin -iquote external/local_config_python -iquote bazel-out/k8-opt/bin/external/local_config_python -iquote external/flatbuffers -iquote bazel-out/k8-opt/bin/external/flatbuffers -iquote external/ruy -iquote bazel-out/k8-opt/bin/external/ruy -iquote external/cpuinfo -iquote bazel-out/k8-opt/bin/external/cpuinfo -iquote external/clog -iquote bazel-out/k8-opt/bin/external/clog -iquote external/gemmlowp -iquote bazel-out/k8-opt/bin/external/gemmlowp -iquote external/arm_neon_2_x86_sse -iquote bazel-out/k8-opt/bin/external/arm_neon_2_x86_sse -iquote external/eigen_archive -iquote bazel-out/k8-opt/bin/external/eigen_archive -iquote external/fft2d -iquote bazel-out/k8-opt/bin/external/fft2d -iquote external/farmhash_archive -iquote bazel-out/k8-opt/bin/external/farmhash_archive -iquote external/com_google_absl -iquote bazel-out/k8-opt/bin/external/com_google_absl -isystem external/local_config_python/numpy_include -isystem bazel-out/k8-opt/bin/external/local_config_python/numpy_include -isystem /opt/pyrefcon/lib/pyrefcon/models/python3.8 -isystem /opt/pyrefcon/lib/pyrefcon/models/python3.8 -isystem tensorflow/lite/schema -isystem bazel-out/k8-opt/bin/tensorflow/lite/schema -isystem third_party/eigen3/mkl_include -isystem bazel-out/k8-opt/bin/third_party/eigen3/mkl_include -isystem external/eigen_archive -isystem bazel-out/k8-opt/bin/external/eigen_archive -isystem external/farmhash_archive/src -isystem bazel-out/k8-opt/bin/external/farmhash_archive/src -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=1 -D NDEBUG -D EIGEN_MPL2_ONLY -D EIGEN_MAX_ALIGN_BYTES=64 -D EIGEN_ALTIVEC_USE_CUSTOM_PACK=0 -I bazel-out/k8-opt/bin/external/flatbuffers/_virtual_includes/runtime_cc -I bazel-out/k8-opt/bin/external/flatbuffers/_virtual_includes/flatbuffers -I bazel-out/k8-opt/bin/external/flatbuffers/src/_virtual_includes/flatbuffers -I bazel-out/k8-opt/bin/external/cpuinfo/_virtual_includes/cpuinfo -I bazel-out/k8-opt/bin/external/clog/_virtual_includes/clog -D AUTOLOAD_DYNAMIC_KERNELS -D __DATE__="redacted" -D __TIMESTAMP__="redacted" -D __TIME__="redacted" -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/x86_64-linux-gnu/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/backward -internal-isystem /opt/pyrefcon/lib/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wall -Wunused-but-set-parameter -Wno-free-nonheap-object -Wno-builtin-macro-redefined -w -std=c++14 -fdeprecated-macro -fdebug-compilation-dir=/home/pyrefcon/.cache/bazel/_bazel_alan/39be661231df2a680c9b74265384c13c/execroot/org_tensorflow -ferror-limit 19 -stack-protector 1 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -vectorize-loops -vectorize-slp -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/pyrefcon/tensorflow/csa-scan/reports -x c++ tensorflow/lite/python/interpreter_wrapper/interpreter_wrapper.cc

tensorflow/lite/python/interpreter_wrapper/interpreter_wrapper.cc

1/* Copyright 2018 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#include "tensorflow/lite/python/interpreter_wrapper/interpreter_wrapper.h"
16
17#include <stdarg.h>
18
19#include <cstring>
20#include <functional>
21#include <memory>
22#include <sstream>
23#include <string>
24
25#include "absl/memory/memory.h"
26#include "absl/strings/str_format.h"
27#include "tensorflow/lite/c/common.h"
28#include "tensorflow/lite/core/api/error_reporter.h"
29#include "tensorflow/lite/core/api/op_resolver.h"
30#include "tensorflow/lite/interpreter.h"
31#include "tensorflow/lite/kernels/internal/compatibility.h"
32#include "tensorflow/lite/kernels/register.h"
33#include "tensorflow/lite/kernels/register_ref.h"
34#include "tensorflow/lite/model.h"
35#include "tensorflow/lite/mutable_op_resolver.h"
36#include "tensorflow/lite/python/interpreter_wrapper/numpy.h"
37#include "tensorflow/lite/python/interpreter_wrapper/python_error_reporter.h"
38#include "tensorflow/lite/python/interpreter_wrapper/python_utils.h"
39#include "tensorflow/lite/shared_library.h"
40#include "tensorflow/lite/string_util.h"
41#include "tensorflow/lite/util.h"
42
43#define TFLITE_PY_CHECK(x)if ((x) != kTfLiteOk) { return error_reporter_->exception(
); }
\
44 if ((x) != kTfLiteOk) { \
45 return error_reporter_->exception(); \
46 }
47
48#define TFLITE_PY_TENSOR_BOUNDS_CHECK(i)if (i >= interpreter_->tensors_size() || i < 0) { PyErr_Format
(PyExc_ValueError, "Invalid tensor index %d exceeds max tensor index %lu"
, i, interpreter_->tensors_size()); return nullptr; }
\
49 if (i >= interpreter_->tensors_size() || i < 0) { \
50 PyErr_Format(PyExc_ValueError, \
51 "Invalid tensor index %d exceeds max tensor index %lu", i, \
52 interpreter_->tensors_size()); \
53 return nullptr; \
54 }
55
56#define TFLITE_PY_SUBGRAPH_TENSOR_BOUNDS_CHECK(i, subgraph_index)if (i >= interpreter_->subgraph(subgraph_index)->tensors_size
() || i < 0) { PyErr_Format(PyExc_ValueError, "Invalid tensor index %d exceeds max tensor index %lu"
, i, interpreter_->subgraph(subgraph_index)->tensors_size
()); return nullptr; }
\
57 if (i >= interpreter_->subgraph(subgraph_index)->tensors_size() || i < 0) { \
58 PyErr_Format(PyExc_ValueError, \
59 "Invalid tensor index %d exceeds max tensor index %lu", i, \
60 interpreter_->subgraph(subgraph_index)->tensors_size()); \
61 return nullptr; \
62 }
63
64#define TFLITE_PY_SUBGRAPH_BOUNDS_CHECK(i)if (i >= interpreter_->subgraphs_size() || i < 0) { PyErr_Format
(PyExc_ValueError, "Invalid subgraph index %d exceeds max subgraph index %lu"
, i, interpreter_->subgraphs_size()); return nullptr; }
\
65 if (i >= interpreter_->subgraphs_size() || i < 0) { \
66 PyErr_Format(PyExc_ValueError, \
67 "Invalid subgraph index %d exceeds max subgraph index %lu", \
68 i, interpreter_->subgraphs_size()); \
69 return nullptr; \
70 }
71
72#define TFLITE_PY_NODES_BOUNDS_CHECK(i)if (i >= interpreter_->nodes_size() || i < 0) { PyErr_Format
(PyExc_ValueError, "Invalid node index"); return nullptr; }
\
73 if (i >= interpreter_->nodes_size() || i < 0) { \
74 PyErr_Format(PyExc_ValueError, "Invalid node index"); \
75 return nullptr; \
76 }
77
78#define TFLITE_PY_ENSURE_VALID_INTERPRETER()if (!interpreter_) { PyErr_SetString(PyExc_ValueError, "Interpreter was not initialized."
); return nullptr; }
\
79 if (!interpreter_) { \
80 PyErr_SetString(PyExc_ValueError, "Interpreter was not initialized."); \
81 return nullptr; \
82 }
83
84namespace tflite {
85namespace interpreter_wrapper {
86
87namespace {
88
89using python_utils::PyDecrefDeleter;
90
91std::unique_ptr<Interpreter> CreateInterpreter(
92 const InterpreterWrapper::Model* model,
93 const tflite::MutableOpResolver& resolver, bool preserve_all_tensors) {
94 if (!model) {
95 return nullptr;
96 }
97
98 ::tflite::python::ImportNumpy();
99
100 std::unique_ptr<Interpreter> interpreter;
101 InterpreterBuilder builder(*model, resolver);
102 if (preserve_all_tensors) builder.PreserveAllTensorsExperimental();
103 if (builder(&interpreter) != kTfLiteOk) {
104 return nullptr;
105 }
106 return interpreter;
107}
108
109PyObject* PyArrayFromFloatVector(const float* data, npy_intp size) {
110 void* pydata = malloc(size * sizeof(float));
111 memcpy(pydata, data, size * sizeof(float));
112 PyObject* obj = PyArray_SimpleNewFromData(1, &size, NPY_FLOAT32, pydata)(*(PyObject * (*)(PyTypeObject *, int, npy_intp const *, int,
npy_intp const *, void *, int, int, PyObject *)) _tflite_numpy_api
[93])(&(*(PyTypeObject *)_tflite_numpy_api[2]), 1, &size
, NPY_FLOAT, __null, pydata, 0, (0x0001 | (0x0100 | 0x0400)),
__null)
;
113 PyArray_ENABLEFLAGS(reinterpret_cast<PyArrayObject*>(obj), NPY_ARRAY_OWNDATA0x0004);
114 return obj;
115}
116
117PyObject* PyArrayFromIntVector(const int* data, npy_intp size) {
118 void* pydata = malloc(size * sizeof(int));
119 memcpy(pydata, data, size * sizeof(int));
120 PyObject* obj = PyArray_SimpleNewFromData(1, &size, NPY_INT32, pydata)(*(PyObject * (*)(PyTypeObject *, int, npy_intp const *, int,
npy_intp const *, void *, int, int, PyObject *)) _tflite_numpy_api
[93])(&(*(PyTypeObject *)_tflite_numpy_api[2]), 1, &size
, NPY_INT, __null, pydata, 0, (0x0001 | (0x0100 | 0x0400)), __null
)
;
121 PyArray_ENABLEFLAGS(reinterpret_cast<PyArrayObject*>(obj), NPY_ARRAY_OWNDATA0x0004);
122 return obj;
123}
124
125PyObject* PyTupleFromQuantizationParam(const TfLiteQuantizationParams& param) {
126 PyObject* result = PyTuple_New(2);
127 PyTuple_SET_ITEM(result, 0, PyFloat_FromDouble(param.scale))PyTuple_SetItem(result, 0, PyFloat_FromDouble(param.scale));
128 PyTuple_SET_ITEM(result, 1, PyLong_FromLong(param.zero_point))PyTuple_SetItem(result, 1, PyLong_FromLong(param.zero_point));
129 return result;
130}
131
132PyObject* PyDictFromSparsityParam(const TfLiteSparsity& param) {
133 PyObject* result = PyDict_New();
134 PyDict_SetItemString(result, "traversal_order",
135 PyArrayFromIntVector(param.traversal_order->data,
136 param.traversal_order->size));
137 PyDict_SetItemString(
138 result, "block_map",
139 PyArrayFromIntVector(param.block_map->data, param.block_map->size));
140 PyObject* dim_metadata = PyList_New(param.dim_metadata_size);
8
Calling 'PyList_New'
10
Returning from 'PyList_New'
13
PyObject ownership leak with reference count of 1
141 for (int i = 0; i < param.dim_metadata_size; i++) {
11
Assuming 'i' is >= field 'dim_metadata_size'
12
Loop condition is false. Execution continues on line 160
142 PyObject* dim_metadata_i = PyDict_New();
143 if (param.dim_metadata[i].format == kTfLiteDimDense) {
144 PyDict_SetItemString(dim_metadata_i, "format", PyLong_FromSize_t(0));
145 PyDict_SetItemString(dim_metadata_i, "dense_size",
146 PyLong_FromSize_t(param.dim_metadata[i].dense_size));
147 } else {
148 PyDict_SetItemString(dim_metadata_i, "format", PyLong_FromSize_t(1));
149 const auto* array_segments = param.dim_metadata[i].array_segments;
150 const auto* array_indices = param.dim_metadata[i].array_indices;
151 PyDict_SetItemString(
152 dim_metadata_i, "array_segments",
153 PyArrayFromIntVector(array_segments->data, array_segments->size));
154 PyDict_SetItemString(
155 dim_metadata_i, "array_indices",
156 PyArrayFromIntVector(array_indices->data, array_indices->size));
157 }
158 PyList_SetItem(dim_metadata, i, dim_metadata_i);
159 }
160 PyDict_SetItemString(result, "dim_metadata", dim_metadata);
161 return result;
162}
163
164bool RegisterCustomOpByName(const char* registerer_name,
165 tflite::MutableOpResolver* resolver,
166 std::string* error_msg) {
167 // Registerer functions take a pointer to a BuiltinOpResolver as an input
168 // parameter and return void.
169 // TODO(b/137576229): We should implement this functionality in a more
170 // principled way.
171 typedef void (*RegistererFunctionType)(tflite::MutableOpResolver*);
172
173 // Look for the Registerer function by name.
174 RegistererFunctionType registerer = reinterpret_cast<RegistererFunctionType>(
175 SharedLibrary::GetSymbol(registerer_name));
176
177 // Fail in an informative way if the function was not found.
178 if (registerer == nullptr) {
179 *error_msg =
180 absl::StrFormat("Looking up symbol '%s' failed with error '%s'.",
181 registerer_name, SharedLibrary::GetError());
182 return false;
183 }
184
185 // Call the registerer with the resolver.
186 registerer(resolver);
187 return true;
188}
189
190} // namespace
191
192static constexpr int kBuiltinOpResolver = 1;
193static constexpr int kBuiltinRefOpResolver = 2;
194static constexpr int kBuiltinOpResolverWithoutDefaultDelegates = 3;
195
196InterpreterWrapper* InterpreterWrapper::CreateInterpreterWrapper(
197 std::unique_ptr<InterpreterWrapper::Model> model, int op_resolver_id,
198 std::unique_ptr<PythonErrorReporter> error_reporter,
199 const std::vector<std::string>& registerers_by_name,
200 const std::vector<std::function<void(uintptr_t)>>& registerers_by_func,
201 std::string* error_msg, bool preserve_all_tensors) {
202 if (!model) {
203 *error_msg = error_reporter->message();
204 return nullptr;
205 }
206
207 std::unique_ptr<tflite::MutableOpResolver> resolver;
208 switch (op_resolver_id) {
209 case kBuiltinOpResolver:
210 resolver = absl::make_unique<tflite::ops::builtin::BuiltinOpResolver>();
211 break;
212 case kBuiltinRefOpResolver:
213 resolver =
214 absl::make_unique<tflite::ops::builtin::BuiltinRefOpResolver>();
215 break;
216 case kBuiltinOpResolverWithoutDefaultDelegates:
217 resolver = absl::make_unique<
218 tflite::ops::builtin::BuiltinOpResolverWithoutDefaultDelegates>();
219 break;
220 default:
221 // This should not never happen because the eventual caller in
222 // interpreter.py should have passed a valid id here.
223 TFLITE_DCHECK(false)(false) ? (void)0 : (static_cast<void>(0));
224 return nullptr;
225 }
226
227 for (const auto& registerer : registerers_by_name) {
228 if (!RegisterCustomOpByName(registerer.c_str(), resolver.get(), error_msg))
229 return nullptr;
230 }
231 for (const auto& registerer : registerers_by_func) {
232 registerer(reinterpret_cast<uintptr_t>(resolver.get()));
233 }
234 auto interpreter =
235 CreateInterpreter(model.get(), *resolver, preserve_all_tensors);
236 if (!interpreter) {
237 *error_msg = error_reporter->message();
238 return nullptr;
239 }
240
241 InterpreterWrapper* wrapper =
242 new InterpreterWrapper(std::move(model), std::move(error_reporter),
243 std::move(resolver), std::move(interpreter));
244 return wrapper;
245}
246
247InterpreterWrapper::InterpreterWrapper(
248 std::unique_ptr<InterpreterWrapper::Model> model,
249 std::unique_ptr<PythonErrorReporter> error_reporter,
250 std::unique_ptr<tflite::MutableOpResolver> resolver,
251 std::unique_ptr<Interpreter> interpreter)
252 : model_(std::move(model)),
253 error_reporter_(std::move(error_reporter)),
254 resolver_(std::move(resolver)),
255 interpreter_(std::move(interpreter)) {}
256
257InterpreterWrapper::~InterpreterWrapper() {}
258
259PyObject* InterpreterWrapper::AllocateTensors(int subgraph_index) {
260 TFLITE_PY_ENSURE_VALID_INTERPRETER()if (!interpreter_) { PyErr_SetString(PyExc_ValueError, "Interpreter was not initialized."
); return nullptr; }
;
261 TFLITE_PY_SUBGRAPH_BOUNDS_CHECK(subgraph_index)if (subgraph_index >= interpreter_->subgraphs_size() ||
subgraph_index < 0) { PyErr_Format(PyExc_ValueError, "Invalid subgraph index %d exceeds max subgraph index %lu"
, subgraph_index, interpreter_->subgraphs_size()); return nullptr
; }
;
262 TFLITE_PY_CHECK(interpreter_->subgraph(subgraph_index)->AllocateTensors())if ((interpreter_->subgraph(subgraph_index)->AllocateTensors
()) != kTfLiteOk) { return error_reporter_->exception(); }
;
263 Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (&
_Py_NoneStruct)
;
264}
265
266PyObject* InterpreterWrapper::Invoke(int subgraph_index) {
267 TFLITE_PY_ENSURE_VALID_INTERPRETER()if (!interpreter_) { PyErr_SetString(PyExc_ValueError, "Interpreter was not initialized."
); return nullptr; }
;
268 TFLITE_PY_SUBGRAPH_BOUNDS_CHECK(subgraph_index)if (subgraph_index >= interpreter_->subgraphs_size() ||
subgraph_index < 0) { PyErr_Format(PyExc_ValueError, "Invalid subgraph index %d exceeds max subgraph index %lu"
, subgraph_index, interpreter_->subgraphs_size()); return nullptr
; }
;
269
270 // Release the GIL so that we can run multiple interpreters in parallel
271 TfLiteStatus status_code = kTfLiteOk;
272 Py_BEGIN_ALLOW_THREADS{ PyThreadState *_save; _save = PyEval_SaveThread();; // To return can happen between this and end!
273 tflite::Subgraph* subgraph = interpreter_->subgraph(subgraph_index);
274 status_code = subgraph->Invoke();
275
276 if (!interpreter_->allow_buffer_handle_output_) {
277 for (int tensor_index : subgraph->outputs()) {
278 subgraph->EnsureTensorDataIsReadable(tensor_index);
279 }
280 }
281 Py_END_ALLOW_THREADSPyEval_RestoreThread(_save); };
282
283 TFLITE_PY_CHECK(if ((status_code) != kTfLiteOk) { return error_reporter_->
exception(); }
284 status_code)if ((status_code) != kTfLiteOk) { return error_reporter_->
exception(); }
; // don't move this into the Py_BEGIN/Py_End block
285
286 Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (&
_Py_NoneStruct)
;
287}
288
289PyObject* InterpreterWrapper::InputIndices() const {
290 TFLITE_PY_ENSURE_VALID_INTERPRETER()if (!interpreter_) { PyErr_SetString(PyExc_ValueError, "Interpreter was not initialized."
); return nullptr; }
;
291 PyObject* np_array = PyArrayFromIntVector(interpreter_->inputs().data(),
292 interpreter_->inputs().size());
293
294 return PyArray_Return(*(PyObject * (*)(PyArrayObject *)) _tflite_numpy_api[76])(reinterpret_cast<PyArrayObject*>(np_array));
295}
296
297PyObject* InterpreterWrapper::OutputIndices() const {
298 PyObject* np_array = PyArrayFromIntVector(interpreter_->outputs().data(),
299 interpreter_->outputs().size());
300
301 return PyArray_Return(*(PyObject * (*)(PyArrayObject *)) _tflite_numpy_api[76])(reinterpret_cast<PyArrayObject*>(np_array));
302}
303
304PyObject* InterpreterWrapper::ResizeInputTensorImpl(int i, PyObject* value) {
305 TFLITE_PY_ENSURE_VALID_INTERPRETER()if (!interpreter_) { PyErr_SetString(PyExc_ValueError, "Interpreter was not initialized."
); return nullptr; }
;
306
307 std::unique_ptr<PyObject, PyDecrefDeleter> array_safe(
308 PyArray_FromAny(*(PyObject * (*)(PyObject *, PyArray_Descr *, int, int, int,
PyObject *)) _tflite_numpy_api[69])
(value, nullptr, 0, 0, NPY_ARRAY_CARRAY(0x0001 | (0x0100 | 0x0400)), nullptr));
309 if (!array_safe) {
310 PyErr_SetString(PyExc_ValueError,
311 "Failed to convert numpy value into readable tensor.");
312 return nullptr;
313 }
314
315 PyArrayObject* array = reinterpret_cast<PyArrayObject*>(array_safe.get());
316
317 if (PyArray_NDIM(array) != 1) {
318 PyErr_Format(PyExc_ValueError, "Shape should be 1D instead of %d.",
319 PyArray_NDIM(array));
320 return nullptr;
321 }
322
323 if (PyArray_TYPE(array) != NPY_INT32NPY_INT) {
324 PyErr_Format(PyExc_ValueError, "Shape must be type int32 (was %d).",
325 PyArray_TYPE(array));
326 return nullptr;
327 }
328
329 PyArray_ENABLEFLAGS(reinterpret_cast<PyArrayObject*>(array),
330 NPY_ARRAY_OWNDATA0x0004);
331 return PyArray_Return(*(PyObject * (*)(PyArrayObject *)) _tflite_numpy_api[76])(reinterpret_cast<PyArrayObject*>(array));
332}
333
334PyObject* InterpreterWrapper::ResizeInputTensor(int i, PyObject* value,
335 bool strict,
336 int subgraph_index) {
337 TFLITE_PY_ENSURE_VALID_INTERPRETER()if (!interpreter_) { PyErr_SetString(PyExc_ValueError, "Interpreter was not initialized."
); return nullptr; }
;
338 TFLITE_PY_SUBGRAPH_BOUNDS_CHECK(subgraph_index)if (subgraph_index >= interpreter_->subgraphs_size() ||
subgraph_index < 0) { PyErr_Format(PyExc_ValueError, "Invalid subgraph index %d exceeds max subgraph index %lu"
, subgraph_index, interpreter_->subgraphs_size()); return nullptr
; }
;
339
340 PyArrayObject* array =
341 reinterpret_cast<PyArrayObject*>(ResizeInputTensorImpl(i, value));
342 if (array == nullptr) {
343 return nullptr;
344 }
345
346 std::vector<int> dims(PyArray_SHAPE(array)[0]);
347 memcpy(dims.data(), PyArray_BYTES(array), dims.size() * sizeof(int));
348
349 if (strict) {
350 TFLITE_PY_CHECK(interpreter_->subgraph(subgraph_index)if ((interpreter_->subgraph(subgraph_index) ->ResizeInputTensorStrict
(i, dims)) != kTfLiteOk) { return error_reporter_->exception
(); }
351 ->ResizeInputTensorStrict(i, dims))if ((interpreter_->subgraph(subgraph_index) ->ResizeInputTensorStrict
(i, dims)) != kTfLiteOk) { return error_reporter_->exception
(); }
;
352 } else {
353 TFLITE_PY_CHECK(if ((interpreter_->subgraph(subgraph_index)->ResizeInputTensor
(i, dims)) != kTfLiteOk) { return error_reporter_->exception
(); }
354 interpreter_->subgraph(subgraph_index)->ResizeInputTensor(i, dims))if ((interpreter_->subgraph(subgraph_index)->ResizeInputTensor
(i, dims)) != kTfLiteOk) { return error_reporter_->exception
(); }
;
355 }
356 Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (&
_Py_NoneStruct)
;
357}
358
359int InterpreterWrapper::NumTensors() const {
360 if (!interpreter_) {
361 return 0;
362 }
363 return interpreter_->tensors_size();
364}
365
366std::string InterpreterWrapper::TensorName(int i) const {
367 if (!interpreter_ || i >= interpreter_->tensors_size() || i < 0) {
368 return "";
369 }
370
371 const TfLiteTensor* tensor = interpreter_->tensor(i);
372 return tensor->name ? tensor->name : "";
373}
374
375PyObject* InterpreterWrapper::TensorType(int i) const {
376 TFLITE_PY_ENSURE_VALID_INTERPRETER()if (!interpreter_) { PyErr_SetString(PyExc_ValueError, "Interpreter was not initialized."
); return nullptr; }
;
377 TFLITE_PY_TENSOR_BOUNDS_CHECK(i)if (i >= interpreter_->tensors_size() || i < 0) { PyErr_Format
(PyExc_ValueError, "Invalid tensor index %d exceeds max tensor index %lu"
, i, interpreter_->tensors_size()); return nullptr; }
;
378
379 const TfLiteTensor* tensor = interpreter_->tensor(i);
380 if (tensor->type == kTfLiteNoType) {
381 PyErr_Format(PyExc_ValueError, "Tensor with no type found.");
382 return nullptr;
383 }
384
385 int code = python_utils::TfLiteTypeToPyArrayType(tensor->type);
386 if (code == -1) {
387 PyErr_Format(PyExc_ValueError, "Invalid tflite type code %d", code);
388 return nullptr;
389 }
390 return PyArray_TypeObjectFromType(*(PyObject * (*)(int)) _tflite_numpy_api[46])(code);
391}
392
393PyObject* InterpreterWrapper::TensorSize(int i) const {
394 TFLITE_PY_ENSURE_VALID_INTERPRETER()if (!interpreter_) { PyErr_SetString(PyExc_ValueError, "Interpreter was not initialized."
); return nullptr; }
;
395 TFLITE_PY_TENSOR_BOUNDS_CHECK(i)if (i >= interpreter_->tensors_size() || i < 0) { PyErr_Format
(PyExc_ValueError, "Invalid tensor index %d exceeds max tensor index %lu"
, i, interpreter_->tensors_size()); return nullptr; }
;
396
397 const TfLiteTensor* tensor = interpreter_->tensor(i);
398 if (tensor->dims == nullptr) {
399 PyErr_Format(PyExc_ValueError, "Tensor with no shape found.");
400 return nullptr;
401 }
402 PyObject* np_array =
403 PyArrayFromIntVector(tensor->dims->data, tensor->dims->size);
404
405 return PyArray_Return(*(PyObject * (*)(PyArrayObject *)) _tflite_numpy_api[76])(reinterpret_cast<PyArrayObject*>(np_array));
406}
407
408PyObject* InterpreterWrapper::TensorSizeSignature(int i) const {
409 TFLITE_PY_ENSURE_VALID_INTERPRETER()if (!interpreter_) { PyErr_SetString(PyExc_ValueError, "Interpreter was not initialized."
); return nullptr; }
;
410 TFLITE_PY_TENSOR_BOUNDS_CHECK(i)if (i >= interpreter_->tensors_size() || i < 0) { PyErr_Format
(PyExc_ValueError, "Invalid tensor index %d exceeds max tensor index %lu"
, i, interpreter_->tensors_size()); return nullptr; }
;
411
412 const TfLiteTensor* tensor = interpreter_->tensor(i);
413 const int32_t* size_signature_data = nullptr;
414 int32_t size_signature_size = 0;
415 if (tensor->dims_signature != nullptr && tensor->dims_signature->size != 0) {
416 size_signature_data = tensor->dims_signature->data;
417 size_signature_size = tensor->dims_signature->size;
418 } else {
419 size_signature_data = tensor->dims->data;
420 size_signature_size = tensor->dims->size;
421 }
422 PyObject* np_array =
423 PyArrayFromIntVector(size_signature_data, size_signature_size);
424
425 return PyArray_Return(*(PyObject * (*)(PyArrayObject *)) _tflite_numpy_api[76])(reinterpret_cast<PyArrayObject*>(np_array));
426}
427
428PyObject* InterpreterWrapper::TensorSparsityParameters(int i) const {
429 TFLITE_PY_ENSURE_VALID_INTERPRETER()if (!interpreter_) { PyErr_SetString(PyExc_ValueError, "Interpreter was not initialized."
); return nullptr; }
;
1
Taking false branch
430 TFLITE_PY_TENSOR_BOUNDS_CHECK(i)if (i >= interpreter_->tensors_size() || i < 0) { PyErr_Format
(PyExc_ValueError, "Invalid tensor index %d exceeds max tensor index %lu"
, i, interpreter_->tensors_size()); return nullptr; }
;
2
Assuming the condition is false
3
Assuming 'i' is >= 0
4
Taking false branch
431 const TfLiteTensor* tensor = interpreter_->tensor(i);
432 if (tensor->sparsity == nullptr) {
5
Assuming the condition is false
6
Taking false branch
433 return PyDict_New();
434 }
435
436 return PyDictFromSparsityParam(*tensor->sparsity);
7
Calling 'PyDictFromSparsityParam'
437}
438
439PyObject* InterpreterWrapper::TensorQuantization(int i) const {
440 TFLITE_PY_ENSURE_VALID_INTERPRETER()if (!interpreter_) { PyErr_SetString(PyExc_ValueError, "Interpreter was not initialized."
); return nullptr; }
;
441 TFLITE_PY_TENSOR_BOUNDS_CHECK(i)if (i >= interpreter_->tensors_size() || i < 0) { PyErr_Format
(PyExc_ValueError, "Invalid tensor index %d exceeds max tensor index %lu"
, i, interpreter_->tensors_size()); return nullptr; }
;
442 const TfLiteTensor* tensor = interpreter_->tensor(i);
443 return PyTupleFromQuantizationParam(tensor->params);
444}
445
446PyObject* InterpreterWrapper::TensorQuantizationParameters(int i) const {
447 TFLITE_PY_ENSURE_VALID_INTERPRETER()if (!interpreter_) { PyErr_SetString(PyExc_ValueError, "Interpreter was not initialized."
); return nullptr; }
;
448 TFLITE_PY_TENSOR_BOUNDS_CHECK(i)if (i >= interpreter_->tensors_size() || i < 0) { PyErr_Format
(PyExc_ValueError, "Invalid tensor index %d exceeds max tensor index %lu"
, i, interpreter_->tensors_size()); return nullptr; }
;
449 const TfLiteTensor* tensor = interpreter_->tensor(i);
450 const TfLiteQuantization quantization = tensor->quantization;
451 float* scales_data = nullptr;
452 int32_t* zero_points_data = nullptr;
453 int32_t scales_size = 0;
454 int32_t zero_points_size = 0;
455 int32_t quantized_dimension = 0;
456 if (quantization.type == kTfLiteAffineQuantization) {
457 const TfLiteAffineQuantization* q_params =
458 reinterpret_cast<const TfLiteAffineQuantization*>(quantization.params);
459 if (q_params->scale) {
460 scales_data = q_params->scale->data;
461 scales_size = q_params->scale->size;
462 }
463 if (q_params->zero_point) {
464 zero_points_data = q_params->zero_point->data;
465 zero_points_size = q_params->zero_point->size;
466 }
467 quantized_dimension = q_params->quantized_dimension;
468 }
469 PyObject* scales_array = PyArrayFromFloatVector(scales_data, scales_size);
470 PyObject* zero_points_array =
471 PyArrayFromIntVector(zero_points_data, zero_points_size);
472
473 PyObject* result = PyTuple_New(3);
474 PyTuple_SET_ITEM(result, 0, scales_array)PyTuple_SetItem(result, 0, scales_array);
475 PyTuple_SET_ITEM(result, 1, zero_points_array)PyTuple_SetItem(result, 1, zero_points_array);
476 PyTuple_SET_ITEM(result, 2, PyLong_FromLong(quantized_dimension))PyTuple_SetItem(result, 2, PyLong_FromLong(quantized_dimension
))
;
477 return result;
478}
479
480PyObject* InterpreterWrapper::SetTensor(int i, PyObject* value,
481 int subgraph_index) {
482 TFLITE_PY_ENSURE_VALID_INTERPRETER()if (!interpreter_) { PyErr_SetString(PyExc_ValueError, "Interpreter was not initialized."
); return nullptr; }
;
483 TFLITE_PY_SUBGRAPH_BOUNDS_CHECK(subgraph_index)if (subgraph_index >= interpreter_->subgraphs_size() ||
subgraph_index < 0) { PyErr_Format(PyExc_ValueError, "Invalid subgraph index %d exceeds max subgraph index %lu"
, subgraph_index, interpreter_->subgraphs_size()); return nullptr
; }
;
484 TFLITE_PY_SUBGRAPH_TENSOR_BOUNDS_CHECK(i, subgraph_index)if (i >= interpreter_->subgraph(subgraph_index)->tensors_size
() || i < 0) { PyErr_Format(PyExc_ValueError, "Invalid tensor index %d exceeds max tensor index %lu"
, i, interpreter_->subgraph(subgraph_index)->tensors_size
()); return nullptr; }
;
485
486 std::unique_ptr<PyObject, PyDecrefDeleter> array_safe(
487 PyArray_FromAny(*(PyObject * (*)(PyObject *, PyArray_Descr *, int, int, int,
PyObject *)) _tflite_numpy_api[69])
(value, nullptr, 0, 0, NPY_ARRAY_CARRAY(0x0001 | (0x0100 | 0x0400)), nullptr));
488 if (!array_safe) {
489 PyErr_SetString(PyExc_ValueError,
490 "Failed to convert value into readable tensor.");
491 return nullptr;
492 }
493
494 PyArrayObject* array = reinterpret_cast<PyArrayObject*>(array_safe.get());
495 TfLiteTensor* tensor = interpreter_->subgraph(subgraph_index)->tensor(i);
496
497 if (python_utils::TfLiteTypeFromPyArray(array) != tensor->type) {
498 PyErr_Format(PyExc_ValueError,
499 "Cannot set tensor:"
500 " Got value of type %s"
501 " but expected type %s for input %d, name: %s ",
502 TfLiteTypeGetName(python_utils::TfLiteTypeFromPyArray(array)),
503 TfLiteTypeGetName(tensor->type), i, tensor->name);
504 return nullptr;
505 }
506
507 if (PyArray_NDIM(array) != tensor->dims->size) {
508 PyErr_Format(PyExc_ValueError,
509 "Cannot set tensor: Dimension mismatch."
510 " Got %d"
511 " but expected %d for input %d.",
512 PyArray_NDIM(array), tensor->dims->size, i);
513 return nullptr;
514 }
515
516 for (int j = 0; j < PyArray_NDIM(array); j++) {
517 if (tensor->dims->data[j] != PyArray_SHAPE(array)[j]) {
518 PyErr_Format(PyExc_ValueError,
519 "Cannot set tensor: Dimension mismatch."
520 " Got %ld"
521 " but expected %d for dimension %d of input %d.",
522 PyArray_SHAPE(array)[j], tensor->dims->data[j], j, i);
523 return nullptr;
524 }
525 }
526
527 if (tensor->type != kTfLiteString) {
528 if (tensor->data.raw == nullptr) {
529 PyErr_Format(PyExc_ValueError,
530 "Cannot set tensor:"
531 " Tensor is unallocated. Try calling allocate_tensors()"
532 " first");
533 return nullptr;
534 }
535
536 size_t size = PyArray_NBYTES(array)(PyArray_ITEMSIZE(array) * (*(npy_intp (*)(npy_intp const *, int
)) _tflite_numpy_api[158])(PyArray_DIMS(array), PyArray_NDIM(
array)))
;
537 if (size != tensor->bytes) {
538 PyErr_Format(PyExc_ValueError,
539 "numpy array had %zu bytes but expected %zu bytes.", size,
540 tensor->bytes);
541 return nullptr;
542 }
543 memcpy(tensor->data.raw, PyArray_DATA(array), size);
544 } else {
545 DynamicBuffer dynamic_buffer;
546 if (!python_utils::FillStringBufferWithPyArray(value, &dynamic_buffer)) {
547 return nullptr;
548 }
549 dynamic_buffer.WriteToTensor(tensor, nullptr);
550 }
551 Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (&
_Py_NoneStruct)
;
552}
553
554int InterpreterWrapper::NumNodes() const {
555 if (!interpreter_) {
556 return 0;
557 }
558 return interpreter_->nodes_size();
559}
560
561PyObject* InterpreterWrapper::NodeInputs(int i) const {
562 TFLITE_PY_ENSURE_VALID_INTERPRETER()if (!interpreter_) { PyErr_SetString(PyExc_ValueError, "Interpreter was not initialized."
); return nullptr; }
;
563 TFLITE_PY_NODES_BOUNDS_CHECK(i)if (i >= interpreter_->nodes_size() || i < 0) { PyErr_Format
(PyExc_ValueError, "Invalid node index"); return nullptr; }
;
564
565 const TfLiteNode* node = &(interpreter_->node_and_registration(i)->first);
566 PyObject* inputs =
567 PyArrayFromIntVector(node->inputs->data, node->inputs->size);
568 return inputs;
569}
570
571PyObject* InterpreterWrapper::NodeOutputs(int i) const {
572 TFLITE_PY_ENSURE_VALID_INTERPRETER()if (!interpreter_) { PyErr_SetString(PyExc_ValueError, "Interpreter was not initialized."
); return nullptr; }
;
573 TFLITE_PY_NODES_BOUNDS_CHECK(i)if (i >= interpreter_->nodes_size() || i < 0) { PyErr_Format
(PyExc_ValueError, "Invalid node index"); return nullptr; }
;
574
575 const TfLiteNode* node = &(interpreter_->node_and_registration(i)->first);
576 PyObject* outputs =
577 PyArrayFromIntVector(node->outputs->data, node->outputs->size);
578 return outputs;
579}
580
581std::string InterpreterWrapper::NodeName(int i) const {
582 if (!interpreter_ || i >= interpreter_->nodes_size() || i < 0) {
583 return "";
584 }
585 // Get op name from registration
586 const TfLiteRegistration* node_registration =
587 &(interpreter_->node_and_registration(i)->second);
588 int32_t op_code = node_registration->builtin_code;
589 std::string op_name;
590 if (op_code == tflite::BuiltinOperator_CUSTOM) {
591 const char* custom_name = node_registration->custom_name;
592 op_name = custom_name ? custom_name : "UnknownCustomOp";
593 } else {
594 op_name = tflite::EnumNamesBuiltinOperator()[op_code];
595 }
596 std::string op_name_str(op_name);
597 return op_name_str;
598}
599
600namespace {
601
602// Checks to see if a tensor access can succeed (returns nullptr on error).
603// Otherwise returns Py_None.
604PyObject* CheckGetTensorArgs(Interpreter* interpreter_, int tensor_index,
605 TfLiteTensor** tensor, int* type_num,
606 int subgraph_index) {
607 TFLITE_PY_ENSURE_VALID_INTERPRETER()if (!interpreter_) { PyErr_SetString(PyExc_ValueError, "Interpreter was not initialized."
); return nullptr; }
;
608 TFLITE_PY_SUBGRAPH_BOUNDS_CHECK(subgraph_index)if (subgraph_index >= interpreter_->subgraphs_size() ||
subgraph_index < 0) { PyErr_Format(PyExc_ValueError, "Invalid subgraph index %d exceeds max subgraph index %lu"
, subgraph_index, interpreter_->subgraphs_size()); return nullptr
; }
;
609 TFLITE_PY_SUBGRAPH_TENSOR_BOUNDS_CHECK(tensor_index, subgraph_index)if (tensor_index >= interpreter_->subgraph(subgraph_index
)->tensors_size() || tensor_index < 0) { PyErr_Format(PyExc_ValueError
, "Invalid tensor index %d exceeds max tensor index %lu", tensor_index
, interpreter_->subgraph(subgraph_index)->tensors_size(
)); return nullptr; }
;
610
611 *tensor = interpreter_->subgraph(subgraph_index)->tensor(tensor_index);
612 if ((*tensor)->bytes == 0) {
613 PyErr_SetString(PyExc_ValueError, "Invalid tensor size.");
614 return nullptr;
615 }
616
617 *type_num = python_utils::TfLiteTypeToPyArrayType((*tensor)->type);
618 if (*type_num == -1) {
619 PyErr_SetString(PyExc_ValueError, "Unknown tensor type.");
620 return nullptr;
621 }
622
623 if (!(*tensor)->data.raw) {
624 PyErr_SetString(PyExc_ValueError,
625 "Tensor data is null."
626 " Run allocate_tensors() first");
627 return nullptr;
628 }
629
630 Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (&
_Py_NoneStruct)
;
631}
632
633} // namespace
634
635PyObject* InterpreterWrapper::GetSignatureDefs() const {
636 PyObject* result = PyDict_New();
637 for (const auto& sig_key : interpreter_->signature_keys()) {
638 PyObject* signature_def = PyDict_New();
639 PyObject* inputs = PyDict_New();
640 PyObject* outputs = PyDict_New();
641 const auto& signature_def_inputs =
642 interpreter_->signature_inputs(sig_key->c_str());
643 const auto& signature_def_outputs =
644 interpreter_->signature_outputs(sig_key->c_str());
645 for (const auto& input : signature_def_inputs) {
646 PyDict_SetItemString(inputs, input.first.c_str(),
647 PyLong_FromLong(input.second));
648 }
649 for (const auto& output : signature_def_outputs) {
650 PyDict_SetItemString(outputs, output.first.c_str(),
651 PyLong_FromLong(output.second));
652 }
653
654 PyDict_SetItemString(signature_def, "inputs", inputs);
655 PyDict_SetItemString(signature_def, "outputs", outputs);
656 PyDict_SetItemString(result, sig_key->c_str(), signature_def);
657 }
658 return result;
659}
660
661PyObject* InterpreterWrapper::GetSubgraphIndexFromSignature(
662 const char* signature_key) {
663 TFLITE_PY_ENSURE_VALID_INTERPRETER()if (!interpreter_) { PyErr_SetString(PyExc_ValueError, "Interpreter was not initialized."
); return nullptr; }
;
664
665 int32_t subgraph_index =
666 interpreter_->GetSubgraphIndexFromSignature(signature_key);
667
668 if (subgraph_index < 0) {
669 PyErr_SetString(PyExc_ValueError, "No matching signature.");
670 return nullptr;
671 }
672 return PyLong_FromLong(static_cast<int64_t>(subgraph_index));
673}
674
675PyObject* InterpreterWrapper::GetTensor(int i, int subgraph_index) const {
676 // Sanity check accessor
677 TfLiteTensor* tensor = nullptr;
678 int type_num = 0;
679
680 PyObject* check_result = CheckGetTensorArgs(interpreter_.get(), i, &tensor,
681 &type_num, subgraph_index);
682 if (check_result == nullptr) return check_result;
683 Py_XDECREF(check_result)_Py_XDECREF(((PyObject*)(check_result)));
684
685 std::vector<npy_intp> dims(tensor->dims->data,
686 tensor->dims->data + tensor->dims->size);
687 if (tensor->type != kTfLiteString && tensor->type != kTfLiteResource &&
688 tensor->type != kTfLiteVariant) {
689 // Make a buffer copy but we must tell Numpy It owns that data or else
690 // it will leak.
691 void* data = malloc(tensor->bytes);
692 if (!data) {
693 PyErr_SetString(PyExc_ValueError, "Malloc to copy tensor failed.");
694 return nullptr;
695 }
696 memcpy(data, tensor->data.raw, tensor->bytes);
697 PyObject* np_array;
698 if (tensor->sparsity == nullptr) {
699 np_array =
700 PyArray_SimpleNewFromData(dims.size(), dims.data(), type_num, data)(*(PyObject * (*)(PyTypeObject *, int, npy_intp const *, int,
npy_intp const *, void *, int, int, PyObject *)) _tflite_numpy_api
[93])(&(*(PyTypeObject *)_tflite_numpy_api[2]), dims.size
(), dims.data(), type_num, __null, data, 0, (0x0001 | (0x0100
| 0x0400)), __null)
;
701 } else {
702 std::vector<npy_intp> sparse_buffer_dims(1);
703 size_t size_of_type;
704 if (GetSizeOfType(nullptr, tensor->type, &size_of_type) != kTfLiteOk) {
705 PyErr_SetString(PyExc_ValueError, "Unknown tensor type.");
706 free(data);
707 return nullptr;
708 }
709 sparse_buffer_dims[0] = tensor->bytes / size_of_type;
710 np_array = PyArray_SimpleNewFromData((*(PyObject * (*)(PyTypeObject *, int, npy_intp const *, int,
npy_intp const *, void *, int, int, PyObject *)) _tflite_numpy_api
[93])(&(*(PyTypeObject *)_tflite_numpy_api[2]), sparse_buffer_dims
.size(), sparse_buffer_dims.data(), type_num, __null, data, 0
, (0x0001 | (0x0100 | 0x0400)), __null)
711 sparse_buffer_dims.size(), sparse_buffer_dims.data(), type_num, data)(*(PyObject * (*)(PyTypeObject *, int, npy_intp const *, int,
npy_intp const *, void *, int, int, PyObject *)) _tflite_numpy_api
[93])(&(*(PyTypeObject *)_tflite_numpy_api[2]), sparse_buffer_dims
.size(), sparse_buffer_dims.data(), type_num, __null, data, 0
, (0x0001 | (0x0100 | 0x0400)), __null)
;
712 }
713 PyArray_ENABLEFLAGS(reinterpret_cast<PyArrayObject*>(np_array),
714 NPY_ARRAY_OWNDATA0x0004);
715 return PyArray_Return(*(PyObject * (*)(PyArrayObject *)) _tflite_numpy_api[76])(reinterpret_cast<PyArrayObject*>(np_array));
716 } else {
717 // Create a C-order array so the data is contiguous in memory.
718 const int32_t kCOrder = 0;
719 PyObject* py_object =
720 PyArray_EMPTY(dims.size(), dims.data(), NPY_OBJECT, kCOrder)(*(PyObject * (*)(int, npy_intp const *, PyArray_Descr *, int
)) _tflite_numpy_api[184])(dims.size(), dims.data(), (*(PyArray_Descr
* (*)(int)) _tflite_numpy_api[45])(NPY_OBJECT), kCOrder)
;
721
722 if (py_object == nullptr) {
723 PyErr_SetString(PyExc_MemoryError, "Failed to allocate PyArray.");
724 return nullptr;
725 }
726
727 PyArrayObject* py_array = reinterpret_cast<PyArrayObject*>(py_object);
728 PyObject** data = reinterpret_cast<PyObject**>(PyArray_DATA(py_array));
729 auto num_strings = GetStringCount(tensor);
730 for (int j = 0; j < num_strings; ++j) {
731 auto ref = GetString(tensor, j);
732
733 PyObject* bytes = PyBytes_FromStringAndSize(ref.str, ref.len);
734 if (bytes == nullptr) {
735 Py_DECREF(py_object)_Py_DECREF(((PyObject*)(py_object)));
736 PyErr_Format(PyExc_ValueError,
737 "Could not create PyBytes from string %d of input %d.", j,
738 i);
739 return nullptr;
740 }
741 // PyArray_EMPTY produces an array full of Py_None, which we must decref.
742 Py_DECREF(data[j])_Py_DECREF(((PyObject*)(data[j])));
743 data[j] = bytes;
744 }
745 return py_object;
746 }
747}
748
749PyObject* InterpreterWrapper::tensor(PyObject* base_object, int tensor_index,
750 int subgraph_index) {
751 // Sanity check accessor
752 TfLiteTensor* tensor = nullptr;
753 int type_num = 0;
754
755 PyObject* check_result = CheckGetTensorArgs(
756 interpreter_.get(), tensor_index, &tensor, &type_num, subgraph_index);
757 if (check_result == nullptr) return check_result;
758 Py_XDECREF(check_result)_Py_XDECREF(((PyObject*)(check_result)));
759
760 std::vector<npy_intp> dims(tensor->dims->data,
761 tensor->dims->data + tensor->dims->size);
762 PyArrayObject* np_array =
763 reinterpret_cast<PyArrayObject*>(PyArray_SimpleNewFromData((*(PyObject * (*)(PyTypeObject *, int, npy_intp const *, int,
npy_intp const *, void *, int, int, PyObject *)) _tflite_numpy_api
[93])(&(*(PyTypeObject *)_tflite_numpy_api[2]), dims.size
(), dims.data(), type_num, __null, tensor->data.raw, 0, (0x0001
| (0x0100 | 0x0400)), __null)
764 dims.size(), dims.data(), type_num, tensor->data.raw)(*(PyObject * (*)(PyTypeObject *, int, npy_intp const *, int,
npy_intp const *, void *, int, int, PyObject *)) _tflite_numpy_api
[93])(&(*(PyTypeObject *)_tflite_numpy_api[2]), dims.size
(), dims.data(), type_num, __null, tensor->data.raw, 0, (0x0001
| (0x0100 | 0x0400)), __null)
);
765 Py_INCREF(base_object)_Py_INCREF(((PyObject*)(base_object))); // SetBaseObject steals, so we need to add.
766 PyArray_SetBaseObject(*(int (*)(PyArrayObject *, PyObject *)) _tflite_numpy_api[282
])
(np_array, base_object);
767 return PyArray_Return(*(PyObject * (*)(PyArrayObject *)) _tflite_numpy_api[76])(np_array);
768}
769
770InterpreterWrapper* InterpreterWrapper::CreateWrapperCPPFromFile(
771 const char* model_path, int op_resolver_id,
772 const std::vector<std::string>& registerers_by_name,
773 const std::vector<std::function<void(uintptr_t)>>& registerers_by_func,
774 std::string* error_msg, bool preserve_all_tensors) {
775 std::unique_ptr<PythonErrorReporter> error_reporter(new PythonErrorReporter);
776 std::unique_ptr<InterpreterWrapper::Model> model =
777 Model::BuildFromFile(model_path, error_reporter.get());
778 return CreateInterpreterWrapper(std::move(model), op_resolver_id,
779 std::move(error_reporter),
780 registerers_by_name, registerers_by_func,
781 error_msg, preserve_all_tensors);
782}
783
784InterpreterWrapper* InterpreterWrapper::CreateWrapperCPPFromFile(
785 const char* model_path, int op_resolver_id,
786 const std::vector<std::string>& registerers, std::string* error_msg,
787 bool preserve_all_tensors) {
788 return CreateWrapperCPPFromFile(model_path, op_resolver_id, registerers,
789 {} /*registerers_by_func*/, error_msg,
790 preserve_all_tensors);
791}
792
793InterpreterWrapper* InterpreterWrapper::CreateWrapperCPPFromBuffer(
794 PyObject* data, int op_resolver_id,
795 const std::vector<std::string>& registerers_by_name,
796 const std::vector<std::function<void(uintptr_t)>>& registerers_by_func,
797 std::string* error_msg, bool preserve_all_tensors) {
798 char* buf = nullptr;
799 Py_ssize_t length;
800 std::unique_ptr<PythonErrorReporter> error_reporter(new PythonErrorReporter);
801
802 if (python_utils::ConvertFromPyString(data, &buf, &length) == -1) {
803 return nullptr;
804 }
805 std::unique_ptr<InterpreterWrapper::Model> model =
806 Model::BuildFromBuffer(buf, length, error_reporter.get());
807 return CreateInterpreterWrapper(std::move(model), op_resolver_id,
808 std::move(error_reporter),
809 registerers_by_name, registerers_by_func,
810 error_msg, preserve_all_tensors);
811}
812
813InterpreterWrapper* InterpreterWrapper::CreateWrapperCPPFromBuffer(
814 PyObject* data, int op_resolver_id,
815 const std::vector<std::string>& registerers, std::string* error_msg,
816 bool preserve_all_tensors) {
817 return CreateWrapperCPPFromBuffer(data, op_resolver_id, registerers, {},
818 error_msg, preserve_all_tensors);
819}
820
821PyObject* InterpreterWrapper::ResetVariableTensors() {
822 TFLITE_PY_ENSURE_VALID_INTERPRETER()if (!interpreter_) { PyErr_SetString(PyExc_ValueError, "Interpreter was not initialized."
); return nullptr; }
;
823 TFLITE_PY_CHECK(interpreter_->ResetVariableTensors())if ((interpreter_->ResetVariableTensors()) != kTfLiteOk) {
return error_reporter_->exception(); }
;
824 Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (&
_Py_NoneStruct)
;
825}
826
827PyObject* InterpreterWrapper::SetNumThreads(int num_threads) {
828 TFLITE_PY_ENSURE_VALID_INTERPRETER()if (!interpreter_) { PyErr_SetString(PyExc_ValueError, "Interpreter was not initialized."
); return nullptr; }
;
829 interpreter_->SetNumThreads(num_threads);
830 Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (&
_Py_NoneStruct)
;
831}
832
833PyObject* InterpreterWrapper::ModifyGraphWithDelegate(
834 TfLiteDelegate* delegate) {
835 TFLITE_PY_ENSURE_VALID_INTERPRETER()if (!interpreter_) { PyErr_SetString(PyExc_ValueError, "Interpreter was not initialized."
); return nullptr; }
;
836 TFLITE_PY_CHECK(interpreter_->ModifyGraphWithDelegate(delegate))if ((interpreter_->ModifyGraphWithDelegate(delegate)) != kTfLiteOk
) { return error_reporter_->exception(); }
;
837 Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (&
_Py_NoneStruct)
;
838}
839
840} // namespace interpreter_wrapper
841} // namespace tflite

/opt/pyrefcon/lib/pyrefcon/models/models/PyList_New.model

1#ifndef PyList_New
2struct _object;
3typedef struct _object PyObject;
4PyObject* clang_analyzer_PyObject_New_Reference();
5PyObject* PyList_New(Py_ssize_t len) {
6 return clang_analyzer_PyObject_New_Reference();
9
Setting reference count to 1
7}
8#else
9#warning "API PyList_New is defined as a macro."
10#endif