blob: becfc93b8f25dad81be659488f6c3bf2f3faeaa8 [file] [log] [blame]
alexander3c798932021-03-26 21:42:19 +00001/*
2 * Copyright (c) 2021 Arm Limited. All rights reserved.
3 * SPDX-License-Identifier: Apache-2.0
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17#include "UseCaseCommonUtils.hpp"
alexander3c798932021-03-26 21:42:19 +000018#include "InputFiles.hpp"
Kshitij Sisodiaf9c19ea2021-05-07 16:08:14 +010019#include <inttypes.h>
20
Éanna Ó Catháin8f958872021-09-15 09:32:30 +010021
22void DisplayCommonMenu()
23{
24 printf("\n\n");
25 printf("User input required\n");
26 printf("Enter option number from:\n\n");
27 printf(" %u. Classify next ifm\n", common::MENU_OPT_RUN_INF_NEXT);
28 printf(" %u. Classify ifm at chosen index\n", common::MENU_OPT_RUN_INF_CHOSEN);
29 printf(" %u. Run classification on all ifm\n", common::MENU_OPT_RUN_INF_ALL);
30 printf(" %u. Show NN model info\n", common::MENU_OPT_SHOW_MODEL_INFO);
31 printf(" %u. List ifm\n\n", common::MENU_OPT_LIST_IFM);
32 printf(" Choice: ");
33 fflush(stdout);
34}
35
36void image::ConvertImgToInt8(void* data, const size_t kMaxImageSize)
37{
Isabella Gottardi79d41542021-10-20 15:52:32 +010038 auto* tmp_req_data = static_cast<uint8_t *>(data);
39 auto* tmp_signed_req_data = static_cast<int8_t *>(data);
Éanna Ó Catháin8f958872021-09-15 09:32:30 +010040
41 for (size_t i = 0; i < kMaxImageSize; i++) {
42 tmp_signed_req_data[i] = (int8_t) (
43 (int32_t) (tmp_req_data[i]) - 128);
44 }
45}
46
47bool image::PresentInferenceResult(hal_platform& platform,
48 const std::vector<arm::app::ClassificationResult>& results)
49{
50 return PresentInferenceResult(platform, results, false);
51}
52
53bool image::PresentInferenceResult(hal_platform &platform,
54 const std::vector<arm::app::ClassificationResult> &results,
55 const time_t infTimeMs)
56{
57 return PresentInferenceResult(platform, results, true, infTimeMs);
58}
59
60
Kshitij Sisodiab48b5b62021-12-29 14:32:58 +000061bool image::PresentInferenceResult(
62 hal_platform &platform,
63 const std::vector<arm::app::ClassificationResult> &results,
64 bool profilingEnabled,
65 const time_t infTimeMs)
Éanna Ó Catháin8f958872021-09-15 09:32:30 +010066{
67 constexpr uint32_t dataPsnTxtStartX1 = 150;
68 constexpr uint32_t dataPsnTxtStartY1 = 30;
69
70 constexpr uint32_t dataPsnTxtStartX2 = 10;
71 constexpr uint32_t dataPsnTxtStartY2 = 150;
72
73 constexpr uint32_t dataPsnTxtYIncr = 16; /* Row index increment. */
74
Kshitij Sisodiab48b5b62021-12-29 14:32:58 +000075 if (profilingEnabled) {
Éanna Ó Catháin8f958872021-09-15 09:32:30 +010076 platform.data_psn->set_text_color(COLOR_YELLOW);
77
78 /* If profiling is enabled, and the time is valid. */
79 info("Final results:\n");
80 info("Total number of inferences: 1\n");
Kshitij Sisodiab48b5b62021-12-29 14:32:58 +000081 if (infTimeMs) {
Éanna Ó Catháin8f958872021-09-15 09:32:30 +010082 std::string strInf =
83 std::string{"Inference: "} +
84 std::to_string(infTimeMs) +
85 std::string{"ms"};
86 platform.data_psn->present_data_text(
87 strInf.c_str(), strInf.size(),
88 dataPsnTxtStartX1, dataPsnTxtStartY1, 0);
89 }
90 }
91 platform.data_psn->set_text_color(COLOR_GREEN);
92
93 /* Display each result. */
94 uint32_t rowIdx1 = dataPsnTxtStartY1 + 2 * dataPsnTxtYIncr;
95 uint32_t rowIdx2 = dataPsnTxtStartY2;
96
Kshitij Sisodiab48b5b62021-12-29 14:32:58 +000097 if (!profilingEnabled) {
Éanna Ó Catháin8f958872021-09-15 09:32:30 +010098 info("Final results:\n");
99 info("Total number of inferences: 1\n");
100 }
101
102 for (uint32_t i = 0; i < results.size(); ++i) {
103 std::string resultStr =
104 std::to_string(i + 1) + ") " +
105 std::to_string(results[i].m_labelIdx) +
106 " (" + std::to_string(results[i].m_normalisedVal) + ")";
107
108 platform.data_psn->present_data_text(
109 resultStr.c_str(), resultStr.size(),
110 dataPsnTxtStartX1, rowIdx1, 0);
111 rowIdx1 += dataPsnTxtYIncr;
112
113 resultStr = std::to_string(i + 1) + ") " + results[i].m_label;
114 platform.data_psn->present_data_text(
115 resultStr.c_str(), resultStr.size(),
116 dataPsnTxtStartX2, rowIdx2, 0);
117 rowIdx2 += dataPsnTxtYIncr;
118
Richard Burton9b8d67a2021-12-10 12:32:51 +0000119 info("%" PRIu32 ") %" PRIu32 " (%f) -> %s\n", i,
120 results[i].m_labelIdx, results[i].m_normalisedVal,
121 results[i].m_label.c_str());
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100122 }
123
124 return true;
125}
126
127void IncrementAppCtxIfmIdx(arm::app::ApplicationContext& ctx, std::string useCase)
128{
Kshitij Sisodiaaa5e1f62021-09-24 14:42:08 +0100129#if NUMBER_OF_FILES > 0
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100130 auto curImIdx = ctx.Get<uint32_t>(useCase);
131
132 if (curImIdx + 1 >= NUMBER_OF_FILES) {
133 ctx.Set<uint32_t>(useCase, 0);
134 return;
135 }
136 ++curImIdx;
137 ctx.Set<uint32_t>(useCase, curImIdx);
Kshitij Sisodiaaa5e1f62021-09-24 14:42:08 +0100138#else /* NUMBER_OF_FILES > 0 */
139 UNUSED(ctx);
140 UNUSED(useCase);
141#endif /* NUMBER_OF_FILES > 0 */
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100142}
143
144bool SetAppCtxIfmIdx(arm::app::ApplicationContext& ctx, uint32_t idx, std::string ctxIfmName)
145{
Kshitij Sisodiaaa5e1f62021-09-24 14:42:08 +0100146#if NUMBER_OF_FILES > 0
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100147 if (idx >= NUMBER_OF_FILES) {
148 printf_err("Invalid idx %" PRIu32 " (expected less than %u)\n",
149 idx, NUMBER_OF_FILES);
150 return false;
151 }
152 ctx.Set<uint32_t>(ctxIfmName, idx);
153 return true;
Kshitij Sisodiaaa5e1f62021-09-24 14:42:08 +0100154#else /* NUMBER_OF_FILES > 0 */
155 UNUSED(ctx);
156 UNUSED(idx);
157 UNUSED(ctxIfmName);
158 return false;
159#endif /* NUMBER_OF_FILES > 0 */
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100160}
161
alexander3c798932021-03-26 21:42:19 +0000162namespace arm {
163namespace app {
164
alexander3c798932021-03-26 21:42:19 +0000165
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100166bool RunInference(arm::app::Model& model, Profiler& profiler)
167{
168 profiler.StartProfiling("Inference");
169 bool runInf = model.RunInference();
170 profiler.StopProfiling();
171
172 return runInf;
173}
174
175int ReadUserInputAsInt(hal_platform& platform)
176{
177 char chInput[128];
178 memset(chInput, 0, sizeof(chInput));
179
180 platform.data_acq->get_input(chInput, sizeof(chInput));
181 return atoi(chInput);
182}
183
184void DumpTensorData(const uint8_t* tensorData,
185 size_t size,
186 size_t lineBreakForNumElements)
187{
188 char strhex[8];
189 std::string strdump;
190
191 for (size_t i = 0; i < size; ++i) {
192 if (0 == i % lineBreakForNumElements) {
193 printf("%s\n\t", strdump.c_str());
194 strdump.clear();
195 }
196 snprintf(strhex, sizeof(strhex) - 1,
197 "0x%02x, ", tensorData[i]);
198 strdump += std::string(strhex);
alexander3c798932021-03-26 21:42:19 +0000199 }
200
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100201 if (!strdump.empty()) {
202 printf("%s\n", strdump.c_str());
203 }
204}
alexander3c798932021-03-26 21:42:19 +0000205
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100206void DumpTensor(const TfLiteTensor* tensor, const size_t lineBreakForNumElements)
207{
208 if (!tensor) {
209 printf_err("invalid tensor\n");
210 return;
alexander3c798932021-03-26 21:42:19 +0000211 }
212
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100213 const uint32_t tensorSz = tensor->bytes;
214 const uint8_t* tensorData = tflite::GetTensorData<uint8_t>(tensor);
alexander3c798932021-03-26 21:42:19 +0000215
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100216 DumpTensorData(tensorData, tensorSz, lineBreakForNumElements);
217}
alexander80eecfb2021-07-06 19:47:59 +0100218
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100219bool ListFilesHandler(ApplicationContext& ctx)
220{
221 auto& model = ctx.Get<Model&>("model");
222 auto& platform = ctx.Get<hal_platform&>("platform");
alexander80eecfb2021-07-06 19:47:59 +0100223
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100224 constexpr uint32_t dataPsnTxtStartX = 20;
225 constexpr uint32_t dataPsnTxtStartY = 40;
alexander3c798932021-03-26 21:42:19 +0000226
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100227 if (!model.IsInited()) {
228 printf_err("Model is not initialised! Terminating processing.\n");
229 return false;
alexander3c798932021-03-26 21:42:19 +0000230 }
231
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100232 /* Clear the LCD */
233 platform.data_psn->clear(COLOR_BLACK);
alexander3c798932021-03-26 21:42:19 +0000234
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100235 /* Show the total number of embedded files. */
236 std::string strNumFiles = std::string{"Total Number of Files: "} +
237 std::to_string(NUMBER_OF_FILES);
238 platform.data_psn->present_data_text(strNumFiles.c_str(),
239 strNumFiles.size(),
240 dataPsnTxtStartX,
241 dataPsnTxtStartY,
242 false);
alexander3c798932021-03-26 21:42:19 +0000243
244#if NUMBER_OF_FILES > 0
245 constexpr uint32_t dataPsnTxtYIncr = 16;
246 info("List of Files:\n");
247 uint32_t yVal = dataPsnTxtStartY + dataPsnTxtYIncr;
248 for (uint32_t i = 0; i < NUMBER_OF_FILES; ++i, yVal += dataPsnTxtYIncr) {
249
250 std::string currentFilename{get_filename(i)};
251 platform.data_psn->present_data_text(currentFilename.c_str(),
252 currentFilename.size(),
alexander80eecfb2021-07-06 19:47:59 +0100253 dataPsnTxtStartX, yVal, false);
alexander3c798932021-03-26 21:42:19 +0000254
Kshitij Sisodiaf9c19ea2021-05-07 16:08:14 +0100255 info("\t%" PRIu32 " => %s\n", i, currentFilename.c_str());
alexander3c798932021-03-26 21:42:19 +0000256 }
257#endif /* NUMBER_OF_FILES > 0 */
258
259 return true;
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100260}
alexander3c798932021-03-26 21:42:19 +0000261
262} /* namespace app */
263} /* namespace arm */