0

I am working on a TfLite program that loads a model and should output a list of floats. Unlike typical examples online, I am not inferring on an image but on an input vector/list of floats (the model contains a MLP type of architecture).

The program is able to load the model and create the interpreter as well as allocate the input buffer.

However, i am struggling to resize the interpreter's input tensor and pass the input buffer to it. The resizing part seems to work but copying the buffer data fails without much of an error message.

The program compiles and run until the buffer copying step. I'm not sure what is the issue here. Any ideas?

So far I got this:

// structure for output prediction
struct filedata
{
  void *data;
  size_t size;
};


// input data
float in_data[] = {x, y, z, a, b, c};  // variables previously declared as float

// load model
TfLiteModel* model = TfLiteModelCreateFromFile(modelPath);

// create interpreter
TfLiteInterpreter* interpreter = TfLiteInterpreterCreate(model, NULL);

// allocate tensors
if(TfLiteInterpreterAllocateTensors(interpreter)!= kTfLiteOk)
{
  return -1;
}

// resize input tensor
int inputTensorSize = 6;
const int* inputDims[2] = {1, inputTensorSize}

if(TfLiteInterpreterResizeInputTensor(interpreter, 0, inputDims, 2)!= kTfLiteOk)
{
  return -1;
}

// re-allocate tensors
TfLiteInterpreterAllocateTensors(interpreter);

// input buffer to input tensor
TfLiteTensor* inputTensor = TfLiteInterpreterGetInputTensor(interpreter, 0);

if(TfLiteTensorCopyFromBuffer(inputTensor, in_data, 
inputTensorSize * sizeof(float))!= kTfLiteOk) // <-- This is where it fails
{
  return -1;
}

// invoke interpreter
if(TfLiteInterpreterInvoke(interpreter) != kTfLiteOk)
{
  return -1;
}

// get prediction from output tensor
int num_of_output = 10; // the output is a list of 10 floats

struct filedata pred;

float **list_pred = malloc(sizeof(float *) * num_of_output);

pred.data = (void *)list_pred;
pred.size = num_of_output;

// Extract the output tensor data.
const TfLiteTensor* output_tensor = TfLiteInterpreterGetOutputTensor(interpreter, 0);

TfLiteTensorCopyToBuffer(output_tensor, pred.data, pred.size * sizeof(float));

// data from both output tensors
list_pred = (float **)&pred.data;

for (int i=0; i<num_of_output; i++)
{
  printf("%f ", list_pred[i]);
}
printf("\n");

EDIT: code update to fix the issue and improve on @Some programmer dude comments.

// input data
float in_data[] = {x, y, z, a, b, c};  // variables previously declared as float

// load model
TfLiteModel* model = TfLiteModelCreateFromFile(modelPath);

// create interpreter
TfLiteInterpreter* interpreter = TfLiteInterpreterCreate(model, NULL);

// allocate tensors
if(TfLiteInterpreterAllocateTensors(interpreter)!= kTfLiteOk)
{
  return -1;
}

// resize input tensor
int inputTensorSize = 6;
int inputDims[2] = {1, inputTensorSize}

if(TfLiteInterpreterResizeInputTensor(interpreter, 0, inputDims, 2)!= kTfLiteOk)
{
  return -1;
}

// re-allocate tensors
TfLiteInterpreterAllocateTensors(interpreter);

// input buffer to input tensor
TfLiteTensor* inputTensor = TfLiteInterpreterGetInputTensor(interpreter, 0);

if(TfLiteTensorCopyFromBuffer(inputTensor, in_data, 
inputTensorSize * sizeof(float))!= kTfLiteOk)
{
  return -1;
}

// invoke interpreter
if(TfLiteInterpreterInvoke(interpreter) != kTfLiteOk)
{
  return -1;
}

// get prediction from output tensor
int num_of_output = 10; // the output is a list of 10 floats

float list_pred[10];

// Extract the output tensor data.
const TfLiteTensor* output_tensor = TfLiteInterpreterGetOutputTensor(interpreter, 0);

TfLiteTensorCopyToBuffer(output_tensor, list_pred, num_of_output * sizeof(float));

for (int i=0; i<num_of_output; i++)
{
  printf("%f ", list_pred[i]);
}
printf("\n");
davipeix
  • 55
  • 7
  • 1
    `const int* inputDims[2] = {1, inputTensorSize}` makes no sense. Why would you define `inputDims` as an array of *pointers*, and then initialize it with plain `int` values? Any decent compiler should issue warning about that, and if it doesn't then you need to enable more warnings (and treat them as errors). – Some programmer dude Aug 30 '22 at 09:07
  • And with the assignment `list_pred = (float **)&pred.data` you loose the original pointer returned by `malloc`, so you can never pass it to `free`, leading to a memory leak. – Some programmer dude Aug 30 '22 at 09:09
  • There are also plenty of other things that just doesn't make much sense, or are at least very suspect. Turn up the warning level of your compiler and trust in what it says. And perhaps take a few steps back and refresh some of the basics of C in regards to arrays and pointers. – Some programmer dude Aug 30 '22 at 09:13
  • Your first tip on the `inputDims` solved the issue. Post it as answer to accept it. Thanks! – davipeix Aug 30 '22 at 09:44

0 Answers0