Skip to content

Commit 34d1f26

Browse files
committed
Upstream eim.cpp
1 parent 7950c4c commit 34d1f26

File tree

1 file changed

+82
-0
lines changed

1 file changed

+82
-0
lines changed

source/eim.cpp

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,38 @@
1+
/* The Clear BSD License
2+
*
3+
* Copyright (c) 2025 EdgeImpulse Inc.
4+
* All rights reserved.
5+
*
6+
* Redistribution and use in source and binary forms, with or without
7+
* modification, are permitted (subject to the limitations in the disclaimer
8+
* below) provided that the following conditions are met:
9+
*
10+
* * Redistributions of source code must retain the above copyright notice,
11+
* this list of conditions and the following disclaimer.
12+
*
13+
* * Redistributions in binary form must reproduce the above copyright
14+
* notice, this list of conditions and the following disclaimer in the
15+
* documentation and/or other materials provided with the distribution.
16+
*
17+
* * Neither the name of the copyright holder nor the names of its
18+
* contributors may be used to endorse or promote products derived from this
19+
* software without specific prior written permission.
20+
*
21+
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY
22+
* THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
23+
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25+
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
26+
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27+
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28+
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
29+
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
30+
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32+
* POSSIBILITY OF SUCH DAMAGE.
33+
*/
34+
35+
/* Includes ---------------------------------------------------------------- */
136
#include <stdio.h>
237
#include <stdarg.h>
338
#include <cstring>
@@ -52,6 +87,10 @@ typedef struct {
5287
#define ALIGN(X) __align(X)
5388
#endif
5489

90+
#if EI_CLASSIFIER_FREEFORM_OUTPUT
91+
static std::vector<matrix_t> freeform_outputs;
92+
#endif
93+
5594
static char rapidjson_buffer[10 * 1024 * 1024] ALIGN(8);
5695
rapidjson::MemoryPoolAllocator<> rapidjson_allocator(rapidjson_buffer, sizeof(rapidjson_buffer));
5796

@@ -181,6 +220,17 @@ void json_send_classification_response(int id,
181220
}
182221
#endif // EI_CLASSIFIER_HAS_VISUAL_ANOMALY
183222

223+
#if EI_CLASSIFIER_FREEFORM_OUTPUT
224+
nlohmann::json freeform_res = nlohmann::json::array();
225+
for (size_t ix = 0; ix < freeform_outputs.size(); ix++) {
226+
const matrix_t& freeform_output = freeform_outputs[ix];
227+
nlohmann::json freeform_entry(
228+
std::vector<float>(freeform_output.buffer, freeform_output.buffer + (freeform_output.rows * freeform_output.cols))
229+
);
230+
freeform_res.push_back(freeform_entry);
231+
}
232+
#endif // EI_CLASSIFIER_FREEFORM_OUTPUT
233+
184234
uint64_t total_ms = ei_read_timer_ms() - json_message_handler_entry_ms;
185235

186236
nlohmann::json resp = {
@@ -205,6 +255,9 @@ void json_send_classification_response(int id,
205255
#if EI_CLASSIFIER_HAS_ANOMALY > 0
206256
{"anomaly", result.anomaly},
207257
#endif // EI_CLASSIFIER_HAS_ANOMALY == 1
258+
#if EI_CLASSIFIER_FREEFORM_OUTPUT
259+
{"freeform", freeform_res},
260+
#endif // #if EI_CLASSIFIER_FREEFORM_OUTPUT
208261
}},
209262
{"timing", {
210263
{"dsp", result.timing.dsp},
@@ -267,6 +320,26 @@ void json_message_handler(rapidjson::Document &msg, char *resp_buffer, size_t re
267320

268321
run_classifier_init();
269322

323+
#if EI_CLASSIFIER_FREEFORM_OUTPUT
324+
freeform_outputs.reserve(ei_default_impulse.impulse->freeform_outputs_size);
325+
for (size_t ix = 0; ix < ei_default_impulse.impulse->freeform_outputs_size; ++ix) {
326+
freeform_outputs.emplace_back(ei_default_impulse.impulse->freeform_outputs[ix], 1);
327+
}
328+
329+
EI_IMPULSE_ERROR set_freeform_res = ei_set_freeform_output(freeform_outputs.data(), freeform_outputs.size());
330+
if (set_freeform_res != EI_IMPULSE_OK) {
331+
char err_msg[128];
332+
snprintf(err_msg, 128, "ei_set_freeform_output() failed with code %d", set_freeform_res);
333+
nlohmann::json err = {
334+
{"id", id},
335+
{"success", false},
336+
{"error", err_msg},
337+
};
338+
snprintf(resp_buffer, resp_buffer_size, "%s\n", err.dump().c_str());
339+
return;
340+
}
341+
#endif
342+
270343
vector<std::string> engine_properties;
271344
vector<std::string> labels;
272345
for (size_t ix = 0; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) {
@@ -292,7 +365,11 @@ void json_message_handler(rapidjson::Document &msg, char *resp_buffer, size_t re
292365
const char *model_type = "object_detection";
293366
#endif // EI_CLASSIFIER_OBJECT_DETECTION_LAST_LAYER
294367
#else
368+
#if EI_CLASSIFIER_FREEFORM_OUTPUT
369+
const char *model_type = "freeform";
370+
#else
295371
const char *model_type = "classification";
372+
#endif
296373
#endif // EI_CLASSIFIER_OBJECT_DETECTION
297374

298375
// keep track of configurable thresholds
@@ -418,6 +495,11 @@ void json_message_handler(rapidjson::Document &msg, char *resp_buffer, size_t re
418495
{"model_type", model_type},
419496
{"slice_size", EI_CLASSIFIER_SLICE_SIZE},
420497
{"use_continuous_mode", EI_CLASSIFIER_SENSOR == EI_CLASSIFIER_SENSOR_MICROPHONE},
498+
#if EI_CLASSIFIER_CALIBRATION_ENABLED
499+
{"has_performance_calibration", true},
500+
#else
501+
{"has_performance_calibration", false},
502+
#endif // EI_CLASSIFIER_CALIBRATION_ENABLED
421503
{"inferencing_engine", EI_CLASSIFIER_INFERENCING_ENGINE},
422504
{"thresholds", thresholds},
423505
}},

0 commit comments

Comments
 (0)