blob: a99e05d2ffa8818aee0e9f2f46693c936804cbbb [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{
38 auto* tmp_req_data = (uint8_t*) data;
39 auto* tmp_signed_req_data = (int8_t*) data;
40
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
61bool image::PresentInferenceResult(hal_platform &platform,
62 const std::vector<arm::app::ClassificationResult> &results,
63 bool profilingEnabled,
64 const time_t infTimeMs)
65{
66 constexpr uint32_t dataPsnTxtStartX1 = 150;
67 constexpr uint32_t dataPsnTxtStartY1 = 30;
68
69 constexpr uint32_t dataPsnTxtStartX2 = 10;
70 constexpr uint32_t dataPsnTxtStartY2 = 150;
71
72 constexpr uint32_t dataPsnTxtYIncr = 16; /* Row index increment. */
73
74 if(profilingEnabled)
75 {
76 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");
81 if (infTimeMs)
82 {
83 std::string strInf =
84 std::string{"Inference: "} +
85 std::to_string(infTimeMs) +
86 std::string{"ms"};
87 platform.data_psn->present_data_text(
88 strInf.c_str(), strInf.size(),
89 dataPsnTxtStartX1, dataPsnTxtStartY1, 0);
90 }
91 }
92 platform.data_psn->set_text_color(COLOR_GREEN);
93
94 /* Display each result. */
95 uint32_t rowIdx1 = dataPsnTxtStartY1 + 2 * dataPsnTxtYIncr;
96 uint32_t rowIdx2 = dataPsnTxtStartY2;
97
98 if(!profilingEnabled)
99 {
100 info("Final results:\n");
101 info("Total number of inferences: 1\n");
102 }
103
104 for (uint32_t i = 0; i < results.size(); ++i) {
105 std::string resultStr =
106 std::to_string(i + 1) + ") " +
107 std::to_string(results[i].m_labelIdx) +
108 " (" + std::to_string(results[i].m_normalisedVal) + ")";
109
110 platform.data_psn->present_data_text(
111 resultStr.c_str(), resultStr.size(),
112 dataPsnTxtStartX1, rowIdx1, 0);
113 rowIdx1 += dataPsnTxtYIncr;
114
115 resultStr = std::to_string(i + 1) + ") " + results[i].m_label;
116 platform.data_psn->present_data_text(
117 resultStr.c_str(), resultStr.size(),
118 dataPsnTxtStartX2, rowIdx2, 0);
119 rowIdx2 += dataPsnTxtYIncr;
120
121 if(profilingEnabled)
122 {
123 info("%" PRIu32 ") %" PRIu32 " (%f) -> %s\n", i, results[i].m_labelIdx,
124 results[i].m_normalisedVal, results[i].m_label.c_str());
125 }
126 else
127 {
128 info("%" PRIu32 ") %" PRIu32 " (%f) -> %s\n", i,
129 results[i].m_labelIdx, results[i].m_normalisedVal,
130 results[i].m_label.c_str());
131 }
132 }
133
134 return true;
135}
136
137void IncrementAppCtxIfmIdx(arm::app::ApplicationContext& ctx, std::string useCase)
138{
Kshitij Sisodiaaa5e1f62021-09-24 14:42:08 +0100139#if NUMBER_OF_FILES > 0
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100140 auto curImIdx = ctx.Get<uint32_t>(useCase);
141
142 if (curImIdx + 1 >= NUMBER_OF_FILES) {
143 ctx.Set<uint32_t>(useCase, 0);
144 return;
145 }
146 ++curImIdx;
147 ctx.Set<uint32_t>(useCase, curImIdx);
Kshitij Sisodiaaa5e1f62021-09-24 14:42:08 +0100148#else /* NUMBER_OF_FILES > 0 */
149 UNUSED(ctx);
150 UNUSED(useCase);
151#endif /* NUMBER_OF_FILES > 0 */
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100152}
153
154bool SetAppCtxIfmIdx(arm::app::ApplicationContext& ctx, uint32_t idx, std::string ctxIfmName)
155{
Kshitij Sisodiaaa5e1f62021-09-24 14:42:08 +0100156#if NUMBER_OF_FILES > 0
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100157 if (idx >= NUMBER_OF_FILES) {
158 printf_err("Invalid idx %" PRIu32 " (expected less than %u)\n",
159 idx, NUMBER_OF_FILES);
160 return false;
161 }
162 ctx.Set<uint32_t>(ctxIfmName, idx);
163 return true;
Kshitij Sisodiaaa5e1f62021-09-24 14:42:08 +0100164#else /* NUMBER_OF_FILES > 0 */
165 UNUSED(ctx);
166 UNUSED(idx);
167 UNUSED(ctxIfmName);
168 return false;
169#endif /* NUMBER_OF_FILES > 0 */
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100170}
171
alexander3c798932021-03-26 21:42:19 +0000172namespace arm {
173namespace app {
174
alexander3c798932021-03-26 21:42:19 +0000175
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100176bool RunInference(arm::app::Model& model, Profiler& profiler)
177{
178 profiler.StartProfiling("Inference");
179 bool runInf = model.RunInference();
180 profiler.StopProfiling();
181
182 return runInf;
183}
184
185int ReadUserInputAsInt(hal_platform& platform)
186{
187 char chInput[128];
188 memset(chInput, 0, sizeof(chInput));
189
190 platform.data_acq->get_input(chInput, sizeof(chInput));
191 return atoi(chInput);
192}
193
194void DumpTensorData(const uint8_t* tensorData,
195 size_t size,
196 size_t lineBreakForNumElements)
197{
198 char strhex[8];
199 std::string strdump;
200
201 for (size_t i = 0; i < size; ++i) {
202 if (0 == i % lineBreakForNumElements) {
203 printf("%s\n\t", strdump.c_str());
204 strdump.clear();
205 }
206 snprintf(strhex, sizeof(strhex) - 1,
207 "0x%02x, ", tensorData[i]);
208 strdump += std::string(strhex);
alexander3c798932021-03-26 21:42:19 +0000209 }
210
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100211 if (!strdump.empty()) {
212 printf("%s\n", strdump.c_str());
213 }
214}
alexander3c798932021-03-26 21:42:19 +0000215
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100216void DumpTensor(const TfLiteTensor* tensor, const size_t lineBreakForNumElements)
217{
218 if (!tensor) {
219 printf_err("invalid tensor\n");
220 return;
alexander3c798932021-03-26 21:42:19 +0000221 }
222
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100223 const uint32_t tensorSz = tensor->bytes;
224 const uint8_t* tensorData = tflite::GetTensorData<uint8_t>(tensor);
alexander3c798932021-03-26 21:42:19 +0000225
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100226 DumpTensorData(tensorData, tensorSz, lineBreakForNumElements);
227}
alexander80eecfb2021-07-06 19:47:59 +0100228
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100229bool ListFilesHandler(ApplicationContext& ctx)
230{
231 auto& model = ctx.Get<Model&>("model");
232 auto& platform = ctx.Get<hal_platform&>("platform");
alexander80eecfb2021-07-06 19:47:59 +0100233
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100234 constexpr uint32_t dataPsnTxtStartX = 20;
235 constexpr uint32_t dataPsnTxtStartY = 40;
alexander3c798932021-03-26 21:42:19 +0000236
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100237 if (!model.IsInited()) {
238 printf_err("Model is not initialised! Terminating processing.\n");
239 return false;
alexander3c798932021-03-26 21:42:19 +0000240 }
241
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100242 /* Clear the LCD */
243 platform.data_psn->clear(COLOR_BLACK);
alexander3c798932021-03-26 21:42:19 +0000244
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100245 /* Show the total number of embedded files. */
246 std::string strNumFiles = std::string{"Total Number of Files: "} +
247 std::to_string(NUMBER_OF_FILES);
248 platform.data_psn->present_data_text(strNumFiles.c_str(),
249 strNumFiles.size(),
250 dataPsnTxtStartX,
251 dataPsnTxtStartY,
252 false);
alexander3c798932021-03-26 21:42:19 +0000253
254#if NUMBER_OF_FILES > 0
255 constexpr uint32_t dataPsnTxtYIncr = 16;
256 info("List of Files:\n");
257 uint32_t yVal = dataPsnTxtStartY + dataPsnTxtYIncr;
258 for (uint32_t i = 0; i < NUMBER_OF_FILES; ++i, yVal += dataPsnTxtYIncr) {
259
260 std::string currentFilename{get_filename(i)};
261 platform.data_psn->present_data_text(currentFilename.c_str(),
262 currentFilename.size(),
alexander80eecfb2021-07-06 19:47:59 +0100263 dataPsnTxtStartX, yVal, false);
alexander3c798932021-03-26 21:42:19 +0000264
Kshitij Sisodiaf9c19ea2021-05-07 16:08:14 +0100265 info("\t%" PRIu32 " => %s\n", i, currentFilename.c_str());
alexander3c798932021-03-26 21:42:19 +0000266 }
267#endif /* NUMBER_OF_FILES > 0 */
268
269 return true;
Éanna Ó Catháin8f958872021-09-15 09:32:30 +0100270}
alexander3c798932021-03-26 21:42:19 +0000271
272} /* namespace app */
273} /* namespace arm */