В настоящее время я добавляю поддержку новой аппаратной цели (процессоры LEON 3 на базе Sparc V8) в инфраструктуру TensorFlow Lite Micro.Когда я собираю и запускаю встроенные тесты для этой цели, они все проходят.Однако я не могу заставить ни один из включенных примеров выполнить новую цель без сбоев во время вывода.
Я сделал действительно простую игрушечную модель, которая представляет собой полностью связанный слой 20x10, встроенный в TensorFlow Lite Micro работает нормально, но когда я собираю и запускаю его для LEON 3, он вылетает с доступом к данным.исключение »на этапе вывода.Мне удалось отследить сбой до вызова для оценки на полностью подключенном слое, который является единственным оператором в TensorFlow Lite Model.Я сделал это, добавив отладочные отпечатки в метод MicroInterpreter :: Invoke (), чтобы определить, где в этом методе произошел сбой.
Вот исходный код main.cc для моего игрушечного примера.Этот код сборки и прекрасно выполняется для собственной цели linux_x86_64.
#include <stdio.h>
#include "tensorflow/lite/experimental/micro/examples/toy_model/model/tiny_model_data.h"
#include "tensorflow/lite/experimental/micro/kernels/all_ops_resolver.h"
#include "tensorflow/lite/experimental/micro/micro_error_reporter.h"
#include "tensorflow/lite/experimental/micro/micro_interpreter.h"
#include "tensorflow/lite/schema/schema_generated.h"
#include "tensorflow/lite/version.h"
int main(int argc, char* argv[]) {
// Set up logging.
tflite::MicroErrorReporter micro_error_reporter;
tflite::ErrorReporter* error_reporter = µ_error_reporter;
printf("Parsing model FlatBuffer.\n");
// Map the model into a usable data structure. This doesn't involve any
// copying or parsing, it's a very lightweight operation.
const tflite::Model* model =
::tflite::GetModel(tiny_tflite);
if (model->version() != TFLITE_SCHEMA_VERSION) {
error_reporter->Report(
"Model provided is schema version %d not equal "
"to supported version %d.\n",
model->version(), TFLITE_SCHEMA_VERSION);
return 1;
}
printf("Model parsed.\n");
// This pulls in all the operation implementations we need.
printf("Pull in operation implementations.");
tflite::ops::micro::AllOpsResolver resolver;
printf("Done.\n");
// Create an area of memory to use for input, output, and intermediate arrays.
// The size of this will depend on the model you're using, and may need to be
// determined by experimentation.
printf("Allocate memory buffer.\n");
const int tensor_arena_size = 200 * 1024;
uint8_t tensor_arena[tensor_arena_size];
tflite::SimpleTensorAllocator tensor_allocator(tensor_arena,
tensor_arena_size);
printf("Done.\n");
// Build an interpreter to run the model with.
printf("Build interpreter.\n");
tflite::MicroInterpreter interpreter(model, resolver, &tensor_allocator,
error_reporter);
printf("Done.\n");
printf("Setting input data.\n");
TfLiteTensor* model_input = interpreter.input(0);
for (int d=0; d<20; ++d)
model_input->data.f[d] = d / 20.0;
printf("Done.\n");
// perform inference
printf("Perform inference.\n");
TfLiteStatus invoke_status = interpreter.Invoke();
if (invoke_status != kTfLiteOk) {
printf("Invoke failed.\n");
return 1;
}
printf("Done.\n");
TfLiteTensor* model_output = interpreter.output(0);
printf("Output tensor values:\n");
for (int d=0; d<10; ++d)
printf("[%d] %f\n", d, model_output->data.f[d]);
return 0;
}
Вот вывод при успешном выполнении собственной сборки:
Parsing model FlatBuffer.
Model parsed.
Pull in operation implementations.Done.
Allocate memory buffer.
Done.
Build interpreter.
Done.
Details of input tensors 0 :
Rank 2, type [Float32], shape [1, 20]
Setting input data.
Done.
Perform inference.
Entered Invoke()
init was okay.
get opcodes.
Starting operator [0]
Starting operator [0] 1
Starting operator [0] 2
Starting operator [0] 3
Starting operator [0] 4
Starting operator [0] 5
Starting operator [0] 6
Starting operator [0] 7
Starting operator [0] 8
Starting operator [0] 9
Starting operator [0] 10
Starting operator [0] 11
Starting operator [0] 12
Node FULLY_CONNECTED (number 0)
Starting operator [0] 13
Starting operator [0] 14
Done.
Details of output tensors 0 :
Rank 2, type [Float32], shape [1, 10]
Output tensor values:
[0] -0.085346
[1] -0.071581
[2] 0.195880
[3] -0.198830
[4] -0.255614
[5] -0.350692
[6] 0.053310
[7] -0.011272
[8] -0.107219
[9] 0.037424
И вывод при выполнении сборки LEON, которыйне удается.
tsim> run
starting at 0x40000000
Parsing model FlatBuffer.
Model parsed.
Pull in operation implementations.Done.
Allocate memory buffer.
Done.
Build interpreter.
Done.
Details of input tensors 0 :
Rank 2, type [Float32], shape [1, 20]
Setting input data.
Done.
Perform inference.
Entered Invoke()
init was okay.
get opcodes.
Starting operator [0]
Starting operator [0] 1
Starting operator [0] 2
Starting operator [0] 3
Starting operator [0] 4
Starting operator [0] 5
Starting operator [0] 6
Starting operator [0] 7
Starting operator [0] 8
Starting operator [0] 9
Starting operator [0] 10
Starting operator [0] 11
Starting operator [0] 12
Node FULLY_CONNECTED (number 0)
IU in error mode (tt=0x80, trap instruction)
(In trap table for tt=0x09, data access exception)
162855 40000090 91d02000 ta 0x0
Интересно, что когда я запускаю нативный код через valgrind с подробным выводом (-v), я получаю два предупреждения REDIR, приведенные ниже, именно в той точке, где происходит сбой версии LEON3.
Starting operator [0]
Starting operator [0] 1
Starting operator [0] 2
Starting operator [0] 3
Starting operator [0] 4
Starting operator [0] 5
Starting operator [0] 6
Starting operator [0] 7
Starting operator [0] 8
Starting operator [0] 9
Starting operator [0] 10
Starting operator [0] 11
Starting operator [0] 12
Node FULLY_CONNECTED (number 0)
--4540-- REDIR: 0x55593f0 (libc.so.6:memcpy@@GLIBC_2.14) redirected to 0x4a286f0 (_vgnU_ifunc_wrapper)
--4540-- REDIR: 0x5612ea0 (libc.so.6:__memcpy_avx_unaligned) redirected to 0x4c324a0 (memcpy@@GLIBC_2.14)
Starting operator [0] 13
Starting operator [0] 14
Done.
Если кто-либо из TensorFlow Lite Micro Team или пользователей имеет какое-либо представление о том, что является причиной этого, или какие-либо возможные недостатки в реализации цели LIBC, тогда я действительно буду признателен за любые идеи.
Спасибо.