Minimal TfLite program generates Valgrind "still reachable" messages
Hi @misterBart 

The TFLite includes the TFLite logger options which can be used to set the logging severity levels.

https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/logger.h


https://github.com/tensorflow/tensorflow/blob/2f1a31a27ea0a21e421e77a957cfd573973f2a65/tensorflow/lite/logger.h#L31-L32

Does this help in your use case?

thanks. No, this does not help at all.
I posted about a memory bug in TfLite.
The TfLite logger options pertain to output logging, which is completely unrelated to memory bugs. Changing the logger option will not make a memory bug disappear. Hi @alankelly, can you take a look? Thanks. More than a month passed. Any news?
Meanwhile I tested the example program in my opening post with TfLite **2.13**, and it gives the same Valgrind messages. So it seems that also in TfLite 2.13, the function `xnn_deinitialize` is never called. I can't re-produce this from the latest commit in tensorflow.

`bazel build -c dbg leak`

```
==2088258== Memcheck, a memory error detector
==2088258== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==2088258== Using Valgrind-3.19.0 and LibVEX; rerun with -h for copyright info
==2088258== Command: ../../bazel-bin/tensorflow/lite/leak
==2088258== 
INFO: Initialized TensorFlow Lite runtime.
INFO: Applying 1 TensorFlow Lite delegate(s) lazily.
INFO: Created TensorFlow Lite XNNPACK delegate for CPU.
VERBOSE: Replacing 88 out of 119 node(s) with delegate (TfLiteXNNPackDelegate) node, yielding 42 partitions for the whole graph.
INFO: Successfully applied the default TensorFlow Lite delegate indexed at 0.
 *NOTE*: because a delegate has been applied, the precision of computations should be unchanged, but the exact output tensor values may have changed. If such output values are checked in your code, like in your tests etc., please consider increasing error tolerance for the check.
==2088258== 
==2088258== HEAP SUMMARY:
==2088258==     in use at exit: 2,224 bytes in 10 blocks
==2088258==   total heap usage: 4,853 allocs, 4,843 frees, 5,656,799 bytes allocated
==2088258== 
==2088258== LEAK SUMMARY:
==2088258==    definitely lost: 0 bytes in 0 blocks
==2088258==    indirectly lost: 0 bytes in 0 blocks
==2088258==      possibly lost: 0 bytes in 0 blocks
==2088258==    still reachable: 2,224 bytes in 10 blocks
==2088258==         suppressed: 0 bytes in 0 blocks
==2088258== Rerun with --leak-check=full to see details of leaked memory
==2088258== 
==2088258== For lists of detected and suppressed errors, rerun with: -s
==2088258== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

```

It is not an issue with `xnn_deinitialize` - this function simply returns xnn_status_success: https://github.com/google/XNNPACK/blob/645035286fe31d47eeb07900450f4f6540b75c2c/src/init.c#L83

Perhaps the issue only appears with your model. Have you tried with multiple models? Hi @misterBart, let us know if you have tried multiple models to help us look into the problem further. @alankelly 
But you are reproducing my issue, your log also mentions
`still reachable: 2,224 bytes in 10 blocks`

From https://github.com/google/XNNPACK/blob/master/include/xnnpack.h
"To avoid memory and resource leaks, users must call xnn_deinitialize once for each successful xnn_initialize call."
If `xnn_deinitialize` does nothing, then the above statement is probably outdated.
```
$ git clone https://github.com/tensorflow/tensorflow tensorflow_src
$ grep -r 'xnn_deinitialize' tensorflow_src/
tensorflow_src/tensorflow/lite/delegates/xnnpack/xnnpack_delegate.cc:  xnn_deinitialize();
$
```
The function is never called.

I also tested my issue with the master branch and the .tflite model from https://www.tensorflow.org/lite/examples/segmentation/overview Then `valgrind --leak-check=full ./app` still displays `still reachable: 704 bytes in 11 blocks`

But if I disable the XNNPACK delegate, by replacing
`const tflite::ops::builtin::BuiltinOpResolver op_resolver`
with 
`const tflite::ops::builtin::BuiltinOpResolverWithoutDefaultDelegates op_resolver;`
Recompile the program, and then run `valgrind --leak-check=full ./app`, then I obtain:
```
$ valgrind --leak-check=full ./app
==924== Memcheck, a memory error detector
==924== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==924== Using Valgrind-3.19.0 and LibVEX; rerun with -h for copyright info
==924== Command: ./app
==924==
==924== error calling PR_SET_PTRACER, vgdb might block
==924==
==924== HEAP SUMMARY:
==924==     in use at exit: 0 bytes in 0 blocks
==924==   total heap usage: 1,875 allocs, 1,875 frees, 6,714,008 bytes allocated
==924==
==924== All heap blocks were freed -- no leaks are possible
==924==
==924== For lists of detected and suppressed errors, rerun with: -s
==924== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
```
Then it is correct: `All heap blocks were freed -- no leaks are possible`. All `still reachable` messages have disappeared.

Concludingly, TfLite + XNNPACK delegate allocates memory at the start but does not deallocate this memory.

Minimal-working example:
```
#include <tensorflow/lite/model.h>
#include <tensorflow/lite/kernels/register.h>
#include <tensorflow/lite/interpreter.h>

using namespace tflite;
using namespace std;

int main() {
	unique_ptr<tflite::FlatBufferModel> model = tflite::FlatBufferModel::BuildFromFile("lite-model_deeplabv3_1_metadata_2.tflite");  //This line generates one "still reachable" message
	//const tflite::ops::builtin::BuiltinOpResolver op_resolver;  //Use XNNPACK delegate
	const tflite::ops::builtin::BuiltinOpResolverWithoutDefaultDelegates op_resolver;
	tflite::InterpreterBuilder interpreter_builder(*model, op_resolver);
	interpreter_builder.SetNumThreads(1);

	unique_ptr<tflite::Interpreter> interpreter;
	interpreter_builder(&interpreter);
	interpreter->AllocateTensors();  //This line generates many "still reachable" messages if XNNPACK is used

	delete model->error_reporter();  //This will get rid off the first "still reachable" message
	return EXIT_SUCCESS;
}
```
 @alankelly Have you looked at the matter again after my above reply? Several weeks have passed. It would be nice if we could resolve this issue. Yes you're right I did reproduce the issue. Sorry for the late reply, I was on holidays.

Today xnn_deinitialize does nothing but someday it may be required to free memory so documenting that it should be called may prevent problems for users of XNNPACK down the road.

This stack overflow answer gives a good explanation of different types of memory leak, especially what still reachable means: https://stackoverflow.com/a/3857638

Let's look at the still reachable blocks in your report:

tflite::DefaultErrorReporter:  This is a static object which is allocated once per instance. The memory is cleaned up when the program is terminated. This looks like it is working as intended.
https://github.com/tensorflow/tensorflow/blob/48043f5993743a9bba3a7b4adc9155cb66bbe6b2/tensorflow/lite/stderr_reporter.cc#L30

The others come from cpuinfo: https://github.com/pytorch/cpuinfo/blob/959002f82d7962a473d8bf301845f2af720e0aa4/src/x86/linux/init.c#L181

Looking at the code we see that these functions are only ever called once and the allocated memory lives for the program lifetime: https://github.com/pytorch/cpuinfo/blob/959002f82d7962a473d8bf301845f2af720e0aa4/src/init.c#L24

This again is working as intended. Valgrind correctly identifies that the memory is not freed but still accessible. 



 Are you satisfied with the resolution of your issue?
<a href="https://docs.google.com/forms/d/e/1FAIpQLSfaP12TRhd9xSxjXZjcZFNXPGk4kc1-qMdv3gc6bEP90vY1ew/viewform?entry.85265664=Yes&entry.2137816233=https://github.com/tensorflow/tensorflow/issues/60787">Yes</a>
<a href="https://docs.google.com/forms/d/e/1FAIpQLSfaP12TRhd9xSxjXZjcZFNXPGk4kc1-qMdv3gc6bEP90vY1ew/viewform?entry.85265664=No&entry.2137816233=https://github.com/tensorflow/tensorflow/issues/60787">No</a>
 Ok, we all do need a holiday :) Thanks for the code review. Still (perhaps from purist perspective), many developers try to keep a clean Valgrind report, which precludes them from checking that these "still reachable bytes" come from TfLite/cpuinfo and are not something they introduced themselves.

I checked TfLite for `cpuinfo_deinitialize()`:
```
personau@desktop1:~/Temp/tensorflow_src/tensorflow/lite$ grep -r 'cpuinfo_deinitialize' .
./kernels/fully_connected.cc:  // paths we can take. Note the we do not call `cpuinfo_deinitialize` in
./kernels/cpu_backend_context.cc:    cpuinfo_deinitialize();
```
In ./kernels/fully_connected.cc I read:
```
// We ensure that cpuinfo is initialized to correctly detect the optimized
// paths we can take. Note the we do not call `cpuinfo_deinitialize` in
// `Free`: that operation is currently a no-op AND we want to avoid
// deinitializing cpuinfo for other parts of the program that could need it
// after we free the op if it ever does perform something.
```
The rationale is not entirely clear to me, but it at least explains you intentionally do not deallocate cpuinfo memory.
In ./kernels/cpu_backend_context.cc I read;
```
CpuBackendContext::CpuInfo::~CpuInfo() {
  if (init_status_ == InitStatus::kInitialized) {
    cpuinfo_deinitialize();
  }
}
```
So it seems possible to call `cpuinfo_deinitialize()`.
My final question, before letting this issue rest, is: How can I call this `CpuBackendContext::CpuInfo::~CpuInfo()` in my minimal TfLite program?

<details><summary>Click to expand!</summary> 
 
 ### Issue Type

Bug

### Have you reproduced the bug with TF nightly?

No

### Source

source

### Tensorflow Version

2.10

### Custom Code

No

### OS Platform and Distribution

Linux64 Ubuntu 22.10

### Mobile device

_No response_

### Python version

3.10.7 (irrelevant for the problem)

### Bazel version

_No response_

### GCC/Compiler version

gcc 12.2.0

### CUDA/cuDNN version

_No response_

### GPU model and memory

_No response_

### Current Behaviour?

Minimal TfLite (2.10) program generates Valgrind "still reachable" message. See accompanied code and Valgrind log. The network cannot be shared (company intellectual property), but this should not matter to reproduce the problem.

You can get rid off the "still reachable" message from `BuildFromFile` by using:
`delete model->error_reporter();`
Still, shouldn't TfLite take care of this? The use of smart pointers suggests that the user does not need to manage TfLite's memory.

My question:
How to get rid off the "still reachable" messages from `AllocateTensors`?

What I tried (but which does _not_ get rid off the "still reachable" messages):
Manually delete the model and interpreter at the end:
`interpreter.reset(nullptr);`
`model.reset(nullptr);`
Clear two vectors of `BuiltinOpResolver`:
`op_resolver.GetDelegateCreators().clear();`
`op_resolver.GetOpaqueDelegateCreators().clear();`

What I also tried is replace `BuiltinOpResolver` with `BuiltinOpResolverWithoutDefaultDelegates`. Then you _do_ get rid off "still reachable" messages from `AllocateTensors`. With `BuiltinOpResolverWithoutDefaultDelegates` the XNNPACK backend is not employed, so seemingly the "still reachable" messages have to do with XNNPACK.
XNNPACK documentation says: "To avoid memory and resource leaks, users must call xnn_deinitialize once for each successful xnn_initialize call." `xnn_deinitialize` is called in function `TfLiteXNNPackWeightsCacheDelete` (tensorflow/lite/delegates/xnnpack/xnnpack_delegate.cc). But `TfLiteXNNPackWeightsCacheDelete` is never called. I believe this causes the memory problem, TfLite never seems to call `xnn_deinitialize`.

My company always keeps a clean Valgrind report for their software, so even if these Valgrind messages are not harmful, I still would like to get rid off them.

### Standalone code to reproduce the issue

```shell
#include <tensorflow/lite/model.h>
#include <tensorflow/lite/kernels/register.h>
#include <tensorflow/lite/interpreter.h>

using namespace tflite;
using namespace std;

int main() {
	unique_ptr<tflite::FlatBufferModel> model = tflite::FlatBufferModel::BuildFromFile("classifier.tflite");  //This line generates one "still reachable" message
	const tflite::ops::builtin::BuiltinOpResolver op_resolver;
	tflite::InterpreterBuilder interpreter_builder(*model, op_resolver);
	interpreter_builder.SetNumThreads(1);

	unique_ptr<tflite::Interpreter> interpreter;
	interpreter_builder(&interpreter);
	interpreter->AllocateTensors();  //This line generates many "still reachable" messages

	//delete model->error_reporter();  //This will get rid off the first "still reachable" message
	return EXIT_SUCCESS;
}
```


### Relevant log output

```shell
$ valgrind --leak-check=full --show-reachable=yes ./app
==988== Memcheck, a memory error detector
==988== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==988== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==988== Command: ./app
==988==
==988== error calling PR_SET_PTRACER, vgdb might block
INFO: Created TensorFlow Lite XNNPACK delegate for CPU.
==988==
==988== HEAP SUMMARY:
==988==     in use at exit: 704 bytes in 11 blocks
==988==   total heap usage: 2,144 allocs, 2,133 frees, 4,481,261 bytes allocated
==988==
==988== 8 bytes in 1 blocks are still reachable in loss record 1 of 11
==988==    at 0x4845013: operator new(unsigned long) (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==988==    by 0x1F6CF9: tflite::DefaultErrorReporter() (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x11FC7C: main (Main.cpp:9)
==988==
==988== 32 bytes in 1 blocks are still reachable in loss record 2 of 11
==988==    at 0x4849A83: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==988==    by 0x55A454: cpuinfo_x86_linux_init (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x4C28576: __pthread_once_slow (pthread_once.c:116)
==988==    by 0x5568CA: cpuinfo_initialize (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x49EB7F: xnn_initialize (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x20F1B7: TfLiteXNNPackDelegateCreate (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x1F74C0: tflite::MaybeCreateXNNPACKDelegate(int) (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x122C33: std::_Function_handler<std::unique_ptr<TfLiteDelegate, void (*)(TfLiteDelegate*)> (int), tflite::ops::builtin::BuiltinOpResolver::BuiltinOpResolver()::{lambda(int)#1}>::_M_invoke(std::_Any_data const&, int&&) (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x1E7945: tflite::Interpreter::ApplyLazyDelegateProviders() (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x1E7B2C: tflite::Interpreter::AllocateTensors() (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x11FD23: main (Main.cpp:16)
==988==
==988== 32 bytes in 1 blocks are still reachable in loss record 3 of 11
==988==    at 0x4849A83: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==988==    by 0x55A46F: cpuinfo_x86_linux_init (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x4C28576: __pthread_once_slow (pthread_once.c:116)
==988==    by 0x5568CA: cpuinfo_initialize (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x49EB7F: xnn_initialize (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x20F1B7: TfLiteXNNPackDelegateCreate (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x1F74C0: tflite::MaybeCreateXNNPACKDelegate(int) (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x122C33: std::_Function_handler<std::unique_ptr<TfLiteDelegate, void (*)(TfLiteDelegate*)> (int), tflite::ops::builtin::BuiltinOpResolver::BuiltinOpResolver()::{lambda(int)#1}>::_M_invoke(std::_Any_data const&, int&&) (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x1E7945: tflite::Interpreter::ApplyLazyDelegateProviders() (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x1E7B2C: tflite::Interpreter::AllocateTensors() (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x11FD23: main (Main.cpp:16)
==988==
==988== 32 bytes in 1 blocks are still reachable in loss record 4 of 11
==988==    at 0x4849A83: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==988==    by 0x55B06F: cpuinfo_x86_linux_init (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x4C28576: __pthread_once_slow (pthread_once.c:116)
==988==    by 0x5568CA: cpuinfo_initialize (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x49EB7F: xnn_initialize (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x20F1B7: TfLiteXNNPackDelegateCreate (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x1F74C0: tflite::MaybeCreateXNNPACKDelegate(int) (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x122C33: std::_Function_handler<std::unique_ptr<TfLiteDelegate, void (*)(TfLiteDelegate*)> (int), tflite::ops::builtin::BuiltinOpResolver::BuiltinOpResolver()::{lambda(int)#1}>::_M_invoke(std::_Any_data const&, int&&) (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x1E7945: tflite::Interpreter::ApplyLazyDelegateProviders() (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x1E7B2C: tflite::Interpreter::AllocateTensors() (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x11FD23: main (Main.cpp:16)
==988==
==988== 32 bytes in 1 blocks are still reachable in loss record 5 of 11
==988==    at 0x4849A83: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==988==    by 0x55B017: cpuinfo_x86_linux_init (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x4C28576: __pthread_once_slow (pthread_once.c:116)
==988==    by 0x5568CA: cpuinfo_initialize (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x49EB7F: xnn_initialize (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x20F1B7: TfLiteXNNPackDelegateCreate (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x1F74C0: tflite::MaybeCreateXNNPACKDelegate(int) (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x122C33: std::_Function_handler<std::unique_ptr<TfLiteDelegate, void (*)(TfLiteDelegate*)> (int), tflite::ops::builtin::BuiltinOpResolver::BuiltinOpResolver()::{lambda(int)#1}>::_M_invoke(std::_Any_data const&, int&&) (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x1E7945: tflite::Interpreter::ApplyLazyDelegateProviders() (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x1E7B2C: tflite::Interpreter::AllocateTensors() (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x11FD23: main (Main.cpp:16)
==988==
==988== 32 bytes in 1 blocks are still reachable in loss record 6 of 11
==988==    at 0x4849A83: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==988==    by 0x55AFCF: cpuinfo_x86_linux_init (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x4C28576: __pthread_once_slow (pthread_once.c:116)
==988==    by 0x5568CA: cpuinfo_initialize (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x49EB7F: xnn_initialize (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x20F1B7: TfLiteXNNPackDelegateCreate (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x1F74C0: tflite::MaybeCreateXNNPACKDelegate(int) (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x122C33: std::_Function_handler<std::unique_ptr<TfLiteDelegate, void (*)(TfLiteDelegate*)> (int), tflite::ops::builtin::BuiltinOpResolver::BuiltinOpResolver()::{lambda(int)#1}>::_M_invoke(std::_Any_data const&, int&&) (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x1E7945: tflite::Interpreter::ApplyLazyDelegateProviders() (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x1E7B2C: tflite::Interpreter::AllocateTensors() (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x11FD23: main (Main.cpp:16)
==988==
==988== 32 bytes in 1 blocks are still reachable in loss record 7 of 11
==988==    at 0x4849A83: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==988==    by 0x55AF96: cpuinfo_x86_linux_init (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x4C28576: __pthread_once_slow (pthread_once.c:116)
==988==    by 0x5568CA: cpuinfo_initialize (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x49EB7F: xnn_initialize (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x20F1B7: TfLiteXNNPackDelegateCreate (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x1F74C0: tflite::MaybeCreateXNNPACKDelegate(int) (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x122C33: std::_Function_handler<std::unique_ptr<TfLiteDelegate, void (*)(TfLiteDelegate*)> (int), tflite::ops::builtin::BuiltinOpResolver::BuiltinOpResolver()::{lambda(int)#1}>::_M_invoke(std::_Any_data const&, int&&) (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x1E7945: tflite::Interpreter::ApplyLazyDelegateProviders() (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x1E7B2C: tflite::Interpreter::AllocateTensors() (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x11FD23: main (Main.cpp:16)
==988==
==988== 56 bytes in 1 blocks are still reachable in loss record 8 of 11
==988==    at 0x4849A83: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==988==    by 0x55A491: cpuinfo_x86_linux_init (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x4C28576: __pthread_once_slow (pthread_once.c:116)
==988==    by 0x5568CA: cpuinfo_initialize (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x49EB7F: xnn_initialize (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x20F1B7: TfLiteXNNPackDelegateCreate (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x1F74C0: tflite::MaybeCreateXNNPACKDelegate(int) (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x122C33: std::_Function_handler<std::unique_ptr<TfLiteDelegate, void (*)(TfLiteDelegate*)> (int), tflite::ops::builtin::BuiltinOpResolver::BuiltinOpResolver()::{lambda(int)#1}>::_M_invoke(std::_Any_data const&, int&&) (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x1E7945: tflite::Interpreter::ApplyLazyDelegateProviders() (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x1E7B2C: tflite::Interpreter::AllocateTensors() (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x11FD23: main (Main.cpp:16)
==988==
==988== 56 bytes in 1 blocks are still reachable in loss record 9 of 11
==988==    at 0x4849A83: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==988==    by 0x55A4B3: cpuinfo_x86_linux_init (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x4C28576: __pthread_once_slow (pthread_once.c:116)
==988==    by 0x5568CA: cpuinfo_initialize (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x49EB7F: xnn_initialize (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x20F1B7: TfLiteXNNPaeckDelegateCreate (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x1F74C0: tflite::MaybeCreateXNNPACKDelegate(int) (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x122C33: std::_Function_handler<std::unique_ptr<TfLiteDelegate, void (*)(TfLiteDelegate*)> (int), tflite::ops::builtin::BuiltinOpResolver::BuiltinOpResolver()::{lambda(int)#1}>::_M_invoke(std::_Any_data const&, int&&) (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x1E7945: tflite::Interpreter::ApplyLazyDelegateProviders() (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x1E7B2C: tflite::Interpreter::AllocateTensors() (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x11FD23: main (Main.cpp:16)
==988==
==988== 72 bytes in 1 blocks are still reachable in loss record 10 of 11
==988==    at 0x4849A83: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==988==    by 0x55A4D5: cpuinfo_x86_linux_init (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x4C28576: __pthread_once_slow (pthread_once.c:116)
==988==    by 0x5568CA: cpuinfo_initialize (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x49EB7F: xnn_initialize (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x20F1B7: TfLiteXNNPackDelegateCreate (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x1F74C0: tflite::MaybeCreateXNNPACKDelegate(int) (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x122C33: std::_Function_handler<std::unique_ptr<TfLiteDelegate, void (*)(TfLiteDelegate*)> (int), tflite::ops::builtin::BuiltinOpResolver::BuiltinOpResolver()::{lambda(int)#1}>::_M_invoke(std::_Any_data const&, int&&) (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x1E7945: tflite::Interpreter::ApplyLazyDelegateProviders() (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x1E7B2C: tflite::Interpreter::AllocateTensors() (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x11FD23: main (Main.cpp:16)
==988==
==988== 320 bytes in 1 blocks are still reachable in loss record 11 of 11
==988==    at 0x4849A83: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==988==    by 0x55A11E: cpuinfo_x86_linux_init (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x4C28576: __pthread_once_slow (pthread_once.c:116)
==988==    by 0x5568CA: cpuinfo_initialize (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x49EB7F: xnn_initialize (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x20F1B7: TfLiteXNNPackDelegateCreate (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x1F74C0: tflite::MaybeCreateXNNPACKDelegate(int) (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x122C33: std::_Function_handler<std::unique_ptr<TfLiteDelegate, void (*)(TfLiteDelegate*)> (int), tflite::ops::builtin::BuiltinOpResolver::BuiltinOpResolver()::{lambda(int)#1}>::_M_invoke(std::_Any_data const&, int&&) (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x1E7945: tflite::Interpreter::ApplyLazyDelegateProviders() (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x1E7B2C: tflite::Interpreter::AllocateTensors() (in /home/personau/SvnDnnProjects/research/DnnBackendTfLite/MyDevX64/app)
==988==    by 0x11FD23: main (Main.cpp:16)
==988==
==988== LEAK SUMMARY:
==988==    definitely lost: 0 bytes in 0 blocks
==988==    indirectly lost: 0 bytes in 0 blocks
==988==      possibly lost: 0 bytes in 0 blocks
==988==    still reachable: 704 bytes in 11 blocks
==988==         suppressed: 0 bytes in 0 blocks
==988==
==988== For lists of detected and suppressed errors, rerun with: -s
==988== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
```
</details>