google-coral / edgetpu

Coral issue tracker (and legacy Edge TPU API source)
https://coral.ai
Apache License 2.0
422 stars 124 forks source link

edgeTPU model inference not working on coralmicro #819

Open Perugius opened 8 months ago

Perugius commented 8 months ago

Description

Hello, I'm trying to run inference on a edgeTPU compiled model. I changed the tflm_hello_world example for this purpose. Other models that are not compiled for the edgeTPU work fine, quantized and not quantized.

The code compiles and flashes fine, but trying to open the serial monitor I just get a blank terminal.

Thanks in advance

// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <cstdio>
#include <chrono>
#include "examples/tflm_hello_world/hello_world_model.h"
#include "libs/base/led.h"
#include "libs/base/timer.h"
#include <climits>
#include <ctime>
#include <stdint.h>
#include "libs/tpu/edgetpu_manager.h"
#include "libs/tpu/edgetpu_op.h"
#include "third_party/freertos_kernel/include/FreeRTOS.h"
#include "third_party/freertos_kernel/include/task.h"
#include "third_party/tflite-micro/tensorflow/lite/micro/all_ops_resolver.h"
#include "third_party/tflite-micro/tensorflow/lite/micro/micro_error_reporter.h"
#include "third_party/tflite-micro/tensorflow/lite/micro/micro_interpreter.h"

// Runs a tiny TFLM model on the M7 core, NOT on the Edge TPU, which simply
// outputs sine wave values over time in the serial console.
//
// For more information about this model, see:
// https://github.com/tensorflow/tflite-micro/tree/main/tensorflow/lite/micro/examples
//
// To build and flash from coralmicro root:
//    bash build.sh
//    python3 scripts/flashtool.py -e tflm_hello_world

extern "C" void vApplicationStackOverflowHook(TaskHandle_t xTask,
                                              char* pcTaskName) {
  printf("Stack overflow in %s\r\n", pcTaskName);
}

const int test_data[] = { 
4,4,9,3,6,8,0,8,7,4,8,2,0,6,6,7,1,2,6,1,9,0,6,8,6,8,8,7,1,3,5,8,9,9,8,6,4,6,1,7,3,2,6,5,5,8,7,6,6,7,3,9,2,5,2,1,5,1,3,8,7,6,9,6,2,2,7,4,0,9,2,4,5,8,7,5,8,7,0,8,8,3,0,1,3,0,2,7,9,6,5,4,3,9,2,0,1,8,0,3,5,2,5,9,4,4,7,4,2,6,7,5,7,3,7,6,8,9,2,7,1,3,9,7,1,0,3,8,0,5,3,2,9,2,3,2,1,1,2,1,0,1,8,7,4,0,4,9,1,5,4,3,8,0,7,5,3,2,0,2,3,1,6,2,5,7,0,9,3,3,2,2,8,6,5,6,2,6,1,2,4,7,8,8,3,3,8,9,0,7,5,6,9,1,5,0,6,1,3,0,8,3,9,2,9,9,7,7,7,1,9,1,5,3,8,0,5,1,9,2,0,0,6,9,4,2,9,2,7,2,1,1,3,4,0,5,8,8,7,3,
};

// const float test_data[] = { 
// 0.22768896476796524,0.2047959025298774,0.21628123544932484,0.2037094521185783,0.2047959025298774,0.193388173211237,0.17049511097314915,0.18190284029178955,0.1590097780537017,0.1590097780537017,0.1590097780537017,0.16940866056185008,0.13619431941642093,0.09040819494024523,0.0,0.3295048890268508,0.5228930622380878,0.7723110352320348,0.6476020487350613,0.5114077293186404,0.39702002172900824,0.4199130839670961,0.3741269594909204,0.3741269594909204,0.35239795126493867,0.2952040974701226,0.28379636815148224,0.2494179729939469,0.2151171814372187,0.21628123544932484,0.2390966940866056,0.26198975632469346,0.28379636815148224,0.32841843861555176,0.3409902219462983,0.4210771379792022,0.5,0.5904081949402452,0.7047959025298773,0.8054477727766568,0.9313208132857365,1.0,0.8741269594909203,0.7379326400744994,0.7150395778364116,0.6578457240415956,0.3752910135030265,0.12470898649697346,0.0,0.011485332919447462,0.03321434114542915,0.06751513270215738,0.07900046562160484,0.06751513270215738,0.09149464535154431,0.06867918671426354,0.056107403383516996,0.056107403383516996,0.07900046562160484,0.10189352785969269,0.8333965844402277,0.8333965844402277,0.8473434535104364,0.8195445920303606,0.8333965844402277,0.8329222011385199,0.8333965844402277,0.8329222011385199,0.8333965844402277,0.8329222011385199,0.8467741935483871,0.8467741935483871,0.8752371916508539,0.8752371916508539,0.9443074003795067,0.9860531309297913,1.0,0.7637571157495257,0.27751423149905124,0.04127134724857685,0.0,0.19392789373814043,0.22229601518026565,0.15265654648956356,0.12485768500948767,0.11091081593927894,0.11091081593927894,0.09743833017077799,0.08358633776091082,0.11091081593927894,0.13870967741935483,0.1666034155597723,0.18055028462998102,0.1944022770398482,0.18055028462998102,0.22229601518026565,0.3057874762808349,0.4306451612903226,0.47239089184060723,0.444022770398482,0.6663187855787476,0.8195445920303606,0.9164136622390892,0.9860531309297913,0.9994307400379506,0.9722011385199241,0.930360531309298,0.902561669829222,0.8891840607210626,0.9031309297912713,0.902561669829222,0.8752371916508539,0.8886148007590133,0.8746679316888045,0.8886148007590133,0.8886148007590133,0.8746679316888045,0.8607210626185958,0.8473434535104364,0.8467741935483871,0.7136757350250091,0.695498353055996,0.7157496645114066,0.7067219714529706,0.9636452360619739,0.9818226180309869,0.9839575454434549,0.9657801634744418,0.9546175430035378,0.7954129559594973,0.7339270464804196,0.7409418079785287,0.7045870440405027,0.679455898499451,0.7954129559594973,0.34982310601439554,0.18854458948395755,0.24094180797852874,0.14316213248749543,0.0,0.15225082347200194,0.2318531169940222,0.22276442600951568,0.4365011589605953,0.5453824569964622,0.5272050750274491,0.5544711479809686,0.4637062339880444,0.4476027815054288,0.4385140905209223,0.3931316335244602,0.4022203245089667,0.42039770647797975,0.4294863974624863,0.4385140905209223,0.4476027815054288,0.5705136025375137,0.6543247529583994,0.6976332804684641,0.4476027815054288,0.7681468830059778,0.8861778699524216,0.9909113090154935,0.9364401610345249,0.8589727949249726,0.9022203245089667,1.0,0.9113090154934732,0.7863242649749909,0.6976332804684641,0.6613395144565085,0.6885445894839576,0.6613395144565085,0.7136757350250091,0.8044406490179334,0.7772355739904844,0.6976332804684641,0.679455898499451,0.6976332804684641,0.6976332804684641,0.03571894784935709,0.0494093074864565,0.05774753606161478,0.05774753606161478,0.12463285686312904,0.1337543241302787,0.1497454474251028,0.1406076626852033,0.13146987794530382,0.08057568043861367,0.07600678806866393,0.06608576463677306,0.015175249657333072,0.0,0.10488871483584622,0.17175771816461066,0.29492200248025585,0.40813262841851056,0.4841557339599243,0.5373180601788395,0.5570458847333725,0.5844755564258207,0.5927648325827296,0.5904803863977547,0.5707525618432218,0.5973337249526793,0.5904803863977547,0.5098883884863912,0.5107368970693819,0.5410384439657986,0.5844755564258207,0.6527804973565694,0.6962339272893414,0.7333888127406827,0.750815873637491,0.780546308987664,0.8002578160694471,0.8337086352065792,0.7728118269042491,0.7045232034462502,0.8314078715488545,0.9303407088310163,1.0,0.943182559885125,0.7393773252398669,0.5510410547614385,0.3069806148423732,0.29182168265778996,0.28349977155538153,0.274361986815482,0.20063964493179295,0.16720514326741073,0.14436068141766203,0.15431433979505255,0.19607075256184323,0.1983551987468181,0.16035180471248614,0.14892957378761176,0.14207623523268717,0.14517655505515306,
// };

uint64_t startTime;
uint64_t endTime;
uint64_t inferenceTime;
TickType_t startTick;
TickType_t endTick;
TickType_t inferenceTick;

namespace {
tflite::ErrorReporter* error_reporter = nullptr;
const tflite::Model* model = nullptr;
tflite::MicroInterpreter* interpreter = nullptr;
TfLiteTensor* input = nullptr;
TfLiteTensor* output = nullptr;

int inference_count = 0;
const int kInferencesPerCycle = 1000;

const int kModelArenaSize = 4096;
const int kExtraArenaSize = 4096;
const int kTensorArenaSize = 90000;
uint8_t tensor_arena[kTensorArenaSize] __attribute__((aligned(16)));

static void loop() {

  for (int i = 0; i < 240; i++) {
    input->data.f[i] = test_data[i];
  }

  vTaskDelay(pdMS_TO_TICKS(1000));

  startTime = coralmicro::TimerMicros();

  TfLiteStatus invoke_status = interpreter->Invoke();
  if (invoke_status != kTfLiteOk) {
    TF_LITE_REPORT_ERROR(error_reporter, "Invoke failed on x");
    return;
  }
  endTime = coralmicro::TimerMicros();
  inferenceTime = endTime-startTime;
  printf("inference: ");
  TF_LITE_REPORT_ERROR(error_reporter, "start time: %u", (unsigned int)startTime);
  TF_LITE_REPORT_ERROR(error_reporter, "end time: %u", (unsigned int)endTime);
  TF_LITE_REPORT_ERROR(error_reporter, "invoke duration: %u", (unsigned int)inferenceTime);

  //float y_val = output->data.f[0];

  for (int i = 0; i < 7; i++) {
    if (input->params.scale == 0 && input->params.zero_point == 0) {
      TF_LITE_REPORT_ERROR(error_reporter, "Out[%d]: %f", i, output->data.f[i]);
    } 
    else {
      float y = (output->data.int8[i] - output->params.zero_point) * output->params.scale;
      int result = y * 100;
      TF_LITE_REPORT_ERROR(error_reporter, "Out[%d]: %d", i, result);
    }
  } 

  //TF_LITE_REPORT_ERROR(error_reporter, "testtest: %f y_val: %f",
  //                     static_cast<double>(x_val), static_cast<double>(y_val));

  ++inference_count;
  if (inference_count >= kInferencesPerCycle) {
    inference_count = 0;
  }
}

[[noreturn]] void hello_task(void* param) {
  printf("Starting inference task...\r\n");
  while (true) {
    loop();
    taskYIELD();
  }
}

}  
// namespace
namespace coralmicro {
extern "C" [[noreturn]] void app_main(void* param) {
  (void)param;

  coralmicro::TimerInit();
  //turn on Edge TPU
  auto tpu_context = EdgeTpuManager::GetSingleton()->OpenDevice();
  if (!tpu_context) {
    printf("ERROR: Failed to get EdgeTpu context\r\n");
  }

  // printf("Hello Tensorflow FreeRTOS Example!\r\n");
  // Turn on Status LED to show the board is on.
  LedSet(coralmicro::Led::kStatus, true);

  static tflite::MicroErrorReporter micro_error_reporter;
  error_reporter = &micro_error_reporter;
  TF_LITE_REPORT_ERROR(error_reporter, "HelloTensorflowFreeRTOS!");

  model = tflite::GetModel(g_model);
  if (model->version() != TFLITE_SCHEMA_VERSION) {
    TF_LITE_REPORT_ERROR(error_reporter,
                         "Model schema version is %d, supported is %d",
                         model->version(), TFLITE_SCHEMA_VERSION);
    vTaskSuspend(nullptr);
  }

  //static tflite::AllOpsResolver resolver;

  static tflite::MicroMutableOpResolver<6> resolver(error_reporter);
  resolver.AddCustom(kCustomOp, RegisterCustomOp());
  resolver.AddQuantize();
  resolver.AddDequantize();
  resolver.AddReshape();
  resolver.AddSoftmax();
  resolver.AddFullyConnected();

  static tflite::MicroInterpreter static_interpreter(
      model, resolver, tensor_arena, kTensorArenaSize, error_reporter);
  interpreter = &static_interpreter;

  TfLiteStatus allocate_status = interpreter->AllocateTensors();
  if (allocate_status != kTfLiteOk) {
    TF_LITE_REPORT_ERROR(error_reporter, "AllocateTensors failed.");
    vTaskSuspend(nullptr);
  }

  input = interpreter->input(0);
  output = interpreter->output(0);

  int ret;
  // High water mark testing showed that this task consumes about 218 words.
  // Set our stack size sufficiently large to accomodate.
  ret = xTaskCreate(hello_task, "HelloTask", configMINIMAL_STACK_SIZE * 3,
                    nullptr, configMAX_PRIORITIES - 1, nullptr);
  if (ret != pdPASS) {
    printf("Failed to start HelloTask\r\n");
  }
  while (true) {
    taskYIELD();
  }
}
} // namespace coralmicro
Click to expand! ### Issue Type Support ### Operating System Ubuntu ### Coral Device Dev Board Micro ### Other Devices _No response_ ### Programming Language C++ ### Relevant Log Output _No response_
google-coral-bot[bot] commented 8 months ago

Are you satisfied with the resolution of your issue? Yes No