/* * Copyright (c) 2020-2021 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * * 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 * * 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. */ /**************************************************************************** * Includes ****************************************************************************/ // FreeRTOS #include "FreeRTOS.h" #include "queue.h" #include "task.h" // Ethos-U #include "ethosu_driver.h" #include "inference_process.hpp" // System includes #include using namespace std; using namespace InferenceProcess; /**************************************************************************** * InferenceJob ****************************************************************************/ #define TENSOR_ARENA_SIZE 0xa0000 __attribute__((section(".bss.NoInit"), aligned(16))) uint8_t inferenceProcessTensorArena[TENSOR_ARENA_SIZE]; namespace { struct xInferenceJob : public InferenceJob { QueueHandle_t queue; bool status; xInferenceJob(); xInferenceJob(const string &name, const DataPtr &networkModel, const vector &input, const vector &output, const vector &expectedOutput, size_t numBytesToPrint, const vector &pmuEventConfig, const uint32_t pmuCycleCounterEnable, QueueHandle_t queue); }; xInferenceJob::xInferenceJob() : InferenceJob(), queue(nullptr), status(false) {} xInferenceJob::xInferenceJob(const std::string &_name, const DataPtr &_networkModel, const std::vector &_input, const std::vector &_output, const std::vector &_expectedOutput, size_t _numBytesToPrint, const vector &_pmuEventConfig, const uint32_t _pmuCycleCounterEnable, QueueHandle_t _queue) : InferenceJob(_name, _networkModel, _input, _output, _expectedOutput, _numBytesToPrint, _pmuEventConfig, _pmuCycleCounterEnable), queue(_queue), status(false) {} } // namespace /**************************************************************************** * Functions ****************************************************************************/ namespace { #include "model.h" #include "input.h" #include "output.h" void inferenceProcessTask(void *pvParameters) { QueueHandle_t queue = reinterpret_cast(pvParameters); class InferenceProcess inferenceProcess(inferenceProcessTensorArena, TENSOR_ARENA_SIZE); while (true) { xInferenceJob *job; // Wait for inference job xQueueReceive(queue, &job, portMAX_DELAY); printf("Received inference job. job=%p, name=%s\n", job, job->name.c_str()); bool status = inferenceProcess.runJob(*job); job->status = status; // Return inference job response xQueueSend(job->queue, &job, portMAX_DELAY); } vTaskDelete(NULL); } void inferenceJobTask(void *pvParameters) { QueueHandle_t inferenceProcessQueue = reinterpret_cast(pvParameters); // Create queue for response messages QueueHandle_t senderQueue = xQueueCreate(10, sizeof(xInferenceJob *)); // Inference job DataPtr networkModel(networkModelData, sizeof(networkModelData)); DataPtr input(inputData, sizeof(inputData)); DataPtr expected(expectedData, sizeof(expectedData)); xInferenceJob job; xInferenceJob *j = &job; job.name = "mobilenet_v2"; job.networkModel = networkModel; job.input.push_back(input); job.expectedOutput.push_back(expected); job.queue = senderQueue; // Send job printf("Sending inference job\n"); xQueueSend(inferenceProcessQueue, &j, portMAX_DELAY); // Wait for response xQueueReceive(senderQueue, &j, portMAX_DELAY); printf("Received inference job response. status=%u\n", j->status); exit(j->status); } } // namespace /* Keep the queue ouf of the stack sinde freertos resets it when the scheduler starts.*/ QueueHandle_t inferenceProcessQueue; int main() { // Inference process inferenceProcessQueue = xQueueCreate(10, sizeof(xInferenceJob *)); xTaskCreate(inferenceProcessTask, "inferenceProcess", 2 * 1024, inferenceProcessQueue, 1, nullptr); // Inference job task xTaskCreate(inferenceJobTask, "inferenceJob", 2 * 1024, inferenceProcessQueue, 2, nullptr); // Run the scheduler vTaskStartScheduler(); return 0; }