aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Moberg <anton.moberg@arm.com>2021-07-07 11:08:17 +0200
committerFredrik Knutsson <fredrik.knutsson@arm.com>2021-07-15 09:46:02 +0000
commit07cf70b46cd2bf7db94a8d0e0d845eb44be24d1c (patch)
tree8c54c8d1785d58d2c336f695bd986350af3c0960
parent67536759dce9d6a41d42c6403edc4482623eea0b (diff)
downloadethos-u-core-software-07cf70b46cd2bf7db94a8d0e0d845eb44be24d1c.tar.gz
Improved Logging - Core Software
Logging macros: Added ethosu_logging.h as a lib, containing logging macros controlled by a parameter ETHOSU_LOG_SEVERITY set in core_software CMakeLists.txt Updated inference_process: Updated inference_process to include ethosu_logging and use the logging macros rather than printf() Updated message_process: Updated message_process to include ethosu_logging and use the logging macros rather than printf() Updated ethosu_monitor: Updated ethosu_monitor to include ethosu_logging and use the logging macros rather than printf() Updated layer_by_layer_profiler: Updated layer_by_layer_profiler to include ethosu_logging and use the logging macros rather than printf() Updated mhu_v2: Updated mhu_v2 to include ethosu_logging and use the logging macros rather than printf() Change-Id: I5d6fd80b7645b3e0af5b494eea6dbb7755f02122
-rw-r--r--CMakeLists.txt17
-rw-r--r--applications/inference_process/CMakeLists.txt5
-rw-r--r--applications/inference_process/src/inference_process.cpp115
-rw-r--r--applications/message_process/CMakeLists.txt4
-rw-r--r--applications/message_process/src/message_process.cpp58
-rw-r--r--drivers/mhu_v2/CMakeLists.txt2
-rw-r--r--drivers/mhu_v2/src/mhu_v2.cpp6
-rw-r--r--lib/CMakeLists.txt3
-rw-r--r--lib/ethosu_log/CMakeLists.txt21
-rw-r--r--lib/ethosu_log/include/ethosu_log.h80
-rw-r--r--lib/ethosu_monitor/CMakeLists.txt2
-rw-r--r--lib/ethosu_monitor/src/ethosu_monitor.cpp3
-rw-r--r--lib/layer_by_layer_profiler/CMakeLists.txt2
-rw-r--r--lib/layer_by_layer_profiler/src/layer_by_layer_profiler.cpp9
14 files changed, 227 insertions, 100 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index cc0d39e..62db31e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -42,6 +42,16 @@ set_property(CACHE CORE_SOFTWARE_ACCELERATOR PROPERTY STRINGS CPU CMSIS-NN NPU)
set(CORE_SOFTWARE_RTOS "None" CACHE STRING "Select RTOS to include. (None, MbedOS, FreeRTOS, Zephyr)")
string(TOLOWER ${CORE_SOFTWARE_RTOS} CORE_SOFTWARE_RTOS_LOWER)
+set(LOG_NAMES err warning info debug)
+set(ETHOSU_LOG_SEVERITY "warning" CACHE STRING "Driver log severity level ${LOG_NAMES} (Defaults to warning)")
+set_property(CACHE ETHOSU_LOG_SEVERITY PROPERTY STRINGS ${LOG_NAMES})
+
+# Check that ETHOSU_LOG_SEVERITY has one of the supported levels
+list(FIND LOG_NAMES ${ETHOSU_LOG_SEVERITY} LOG_SEVERITY)
+if (${LOG_SEVERITY} EQUAL -1)
+ message(FATAL_ERROR "Unsupported log level ${ETHOSU_LOG_SEVERITY}")
+endif()
+
#
# Build
#
@@ -78,3 +88,10 @@ add_subdirectory(drivers)
# Merge libraries into static library
target_link_libraries(ethosu_core INTERFACE tflu ethosu_applications ethosu_drivers)
+
+message(STATUS "*******************************************************")
+message(STATUS "PROJECT_NAME : ${PROJECT_NAME}")
+message(STATUS "CORE_SOFTWARE_RTOS : ${CORE_SOFTWARE_RTOS}")
+message(STATUS "CORE_SOFTWARE_ACCELERATOR : ${CORE_SOFTWARE_ACCELERATOR}")
+message(STATUS "ETHOSU_LOG_SEVERITY : ${ETHOSU_LOG_SEVERITY}")
+message(STATUS "*******************************************************") \ No newline at end of file
diff --git a/applications/inference_process/CMakeLists.txt b/applications/inference_process/CMakeLists.txt
index 1378181..19777fd 100644
--- a/applications/inference_process/CMakeLists.txt
+++ b/applications/inference_process/CMakeLists.txt
@@ -30,5 +30,8 @@ endif()
if (TARGET arm_profiler)
target_link_libraries(inference_process PRIVATE arm_profiler)
endif()
+if (TARGET ethosu_log)
+ target_link_libraries(inference_process PRIVATE ethosu_log)
+endif()
-target_sources(inference_process PRIVATE src/inference_process.cpp)
+target_sources(inference_process PRIVATE src/inference_process.cpp) \ No newline at end of file
diff --git a/applications/inference_process/src/inference_process.cpp b/applications/inference_process/src/inference_process.cpp
index 13cabb2..7058f9c 100644
--- a/applications/inference_process/src/inference_process.cpp
+++ b/applications/inference_process/src/inference_process.cpp
@@ -27,6 +27,7 @@
#ifdef ETHOSU
#include "layer_by_layer_profiler.hpp"
#endif
+#include "ethosu_log.h"
#include "inference_process.hpp"
@@ -39,30 +40,28 @@ using namespace std;
namespace {
void tflu_debug_log(const char *s) {
- fprintf(stderr, "%s", s);
+ LOG_DEBUG("%s", s);
}
void print_output_data(TfLiteTensor *output, size_t bytesToPrint) {
const int numBytesToPrint = min(output->bytes, bytesToPrint);
-
- int dims_size = output->dims->size;
- printf("{\n");
- printf("\"dims\": [%d,", dims_size);
+ int dims_size = output->dims->size;
+ LOG("{\n");
+ LOG("\"dims\": [%d,", dims_size);
for (int i = 0; i < output->dims->size - 1; ++i) {
- printf("%d,", output->dims->data[i]);
+ LOG("%d,", output->dims->data[i]);
}
- printf("%d],\n", output->dims->data[dims_size - 1]);
-
- printf("\"data_address\": \"%08" PRIx32 "\",\n", (uint32_t)output->data.data);
- printf("\"data\":\"");
+ LOG("%d],\n", output->dims->data[dims_size - 1]);
+ LOG("\"data_address\": \"%08" PRIx32 "\",\n", (uint32_t)output->data.data);
+ LOG("\"data\":\"");
for (int i = 0; i < numBytesToPrint - 1; ++i) {
if (i % 16 == 0 && i != 0) {
- printf("\n");
+ LOG("\n");
}
- printf("0x%02x,", output->data.uint8[i]);
+ LOG("0x%02x,", output->data.uint8[i]);
}
- printf("0x%02x\"\n", output->data.uint8[numBytesToPrint - 1]);
- printf("}");
+ LOG("0x%02x\"\n", output->data.uint8[numBytesToPrint - 1]);
+ LOG("}");
}
bool copyOutput(const TfLiteTensor &src, InferenceProcess::DataPtr &dst) {
@@ -71,7 +70,7 @@ bool copyOutput(const TfLiteTensor &src, InferenceProcess::DataPtr &dst) {
}
if (src.bytes > dst.size) {
- printf("Tensor size %d does not match output size %d.\n", src.bytes, dst.size);
+ LOG_ERR("Tensor size mismatch (bytes): actual=%d, expected%d.\n", src.bytes, dst.size);
return true;
}
@@ -181,7 +180,7 @@ bool InferenceProcess::push(const InferenceJob &job) {
}
bool InferenceProcess::runJob(InferenceJob &job) {
- printf("Running inference job: %s\n", job.name.c_str());
+ LOG_INFO("Running inference job: %s\n", job.name.c_str());
// Register debug log callback for profiling
RegisterDebugLogCallback(tflu_debug_log);
@@ -192,9 +191,9 @@ bool InferenceProcess::runJob(InferenceJob &job) {
// Get model handle and verify that the version is correct
const tflite::Model *model = ::tflite::GetModel(job.networkModel.data);
if (model->version() != TFLITE_SCHEMA_VERSION) {
- printf("Model provided is schema version %" PRIu32 " not equal to supported version %d.\n",
- model->version(),
- TFLITE_SCHEMA_VERSION);
+ LOG_ERR("Model schema version unsupported: version=%" PRIu32 ", supported=%d.\n",
+ model->version(),
+ TFLITE_SCHEMA_VERSION);
return true;
}
@@ -211,7 +210,7 @@ bool InferenceProcess::runJob(InferenceJob &job) {
// Allocate tensors
TfLiteStatus allocate_status = interpreter.AllocateTensors();
if (allocate_status != kTfLiteOk) {
- printf("AllocateTensors failed for inference job: %s\n", job.name.c_str());
+ LOG_ERR("Failed to allocate tensors for inference: job=%s\n", job.name.c_str());
return true;
}
@@ -225,9 +224,9 @@ bool InferenceProcess::runJob(InferenceJob &job) {
}
}
if (job.input.size() != inputTensors.size()) {
- printf("Number of input buffers does not match number of non empty network tensors. input=%zu, network=%zu\n",
- job.input.size(),
- inputTensors.size());
+ LOG_ERR("Number of input buffers does not match number of non empty network tensors: input=%zu, network=%zu\n",
+ job.input.size(),
+ inputTensors.size());
return true;
}
@@ -237,11 +236,11 @@ bool InferenceProcess::runJob(InferenceJob &job) {
const TfLiteTensor *tensor = inputTensors[i];
if (input.size != tensor->bytes) {
- printf("Input size does not match network size. job=%s, index=%zu, input=%zu, network=%u\n",
- job.name.c_str(),
- i,
- input.size,
- tensor->bytes);
+ LOG_ERR("Job input size does not match network input size: job=%s, index=%zu, input=%zu, network=%u\n",
+ job.name.c_str(),
+ i,
+ input.size,
+ tensor->bytes);
return true;
}
@@ -251,13 +250,13 @@ bool InferenceProcess::runJob(InferenceJob &job) {
// Run the inference
TfLiteStatus invoke_status = interpreter.Invoke();
if (invoke_status != kTfLiteOk) {
- printf("Invoke failed for inference job: %s\n", job.name.c_str());
+ LOG_ERR("Invoke failed for inference: job=%s\n", job.name.c_str());
return true;
}
- printf("%s : %zu\r\n", "arena_used_bytes", interpreter.arena_used_bytes());
+ LOG("arena_used_bytes : %zu\n", interpreter.arena_used_bytes());
- printf("Inference runtime: %u cycles\r\n", (unsigned int)profiler.GetTotalTicks());
+ LOG("Inference runtime: %u cycles\n", (unsigned int)profiler.GetTotalTicks());
if (job.pmuCycleCounterEnable != 0) {
job.pmuCycleCounterCount = profiler.GetTotalTicks();
@@ -266,7 +265,7 @@ bool InferenceProcess::runJob(InferenceJob &job) {
// Copy output data
if (job.output.size() > 0) {
if (interpreter.outputs_size() != job.output.size()) {
- printf("Number of outputs mismatch. job=%zu, network=%u\n", job.output.size(), interpreter.outputs_size());
+ LOG_ERR("Output size mismatch: job=%zu, network=%u\n", job.output.size(), interpreter.outputs_size());
return true;
}
@@ -280,28 +279,26 @@ bool InferenceProcess::runJob(InferenceJob &job) {
if (job.numBytesToPrint > 0) {
// Print all of the output data, or the first NUM_BYTES_TO_PRINT bytes,
// whichever comes first as well as the output shape.
- printf("num_of_outputs: %d\n", interpreter.outputs_size());
- printf("output_begin\n");
- printf("[\n");
-
+ LOG("num_of_outputs: %d\n", interpreter.outputs_size());
+ LOG("output_begin\n");
+ LOG("[\n");
for (unsigned int i = 0; i < interpreter.outputs_size(); i++) {
TfLiteTensor *output = interpreter.output(i);
print_output_data(output, job.numBytesToPrint);
if (i != interpreter.outputs_size() - 1) {
- printf(",\n");
+ LOG(",\n");
}
}
-
- printf("]\n");
- printf("output_end\n");
+ LOG("]\n");
+ LOG("output_end\n");
}
if (job.expectedOutput.size() > 0) {
if (job.expectedOutput.size() != interpreter.outputs_size()) {
- printf("Expected number of output tensors does not match network. job=%s, expected=%zu, network=%zu\n",
- job.name.c_str(),
- job.expectedOutput.size(),
- interpreter.outputs_size());
+ LOG_ERR("Expected number of output tensors mismatch: job=%s, expected=%zu, network=%zu\n",
+ job.name.c_str(),
+ job.expectedOutput.size(),
+ interpreter.outputs_size());
return true;
}
@@ -310,33 +307,33 @@ bool InferenceProcess::runJob(InferenceJob &job) {
const TfLiteTensor *output = interpreter.output(i);
if (expected.size != output->bytes) {
- printf("Expected tensor size does not match output size. job=%s, index=%u, expected=%zu, network=%zu\n",
- job.name.c_str(),
- i,
- expected.size,
- output->bytes);
+ LOG_ERR("Expected output tensor size mismatch: job=%s, index=%u, expected=%zu, network=%zu\n",
+ job.name.c_str(),
+ i,
+ expected.size,
+ output->bytes);
return true;
}
for (unsigned int j = 0; j < output->bytes; ++j) {
if (output->data.uint8[j] != static_cast<uint8_t *>(expected.data)[j]) {
- printf("Expected data does not match output data. job=%s, index=%u, offset=%u, "
- "expected=%02x, network=%02x\n",
- job.name.c_str(),
- i,
- j,
- static_cast<uint8_t *>(expected.data)[j],
- output->data.uint8[j]);
+ LOG_ERR("Expected output tensor data mismatch: job=%s, index=%u, offset=%u, "
+ "expected=%02x, network=%02x\n",
+ job.name.c_str(),
+ i,
+ j,
+ static_cast<uint8_t *>(expected.data)[j],
+ output->data.uint8[j]);
return true;
}
}
}
}
- printf("Finished running job: %s\n", job.name.c_str());
+ LOG_INFO("Finished running job: %s\n", job.name.c_str());
return false;
-}
+} // namespace InferenceProcess
bool InferenceProcess::run(bool exitOnEmpty) {
bool anyJobFailed = false;
@@ -348,7 +345,7 @@ bool InferenceProcess::run(bool exitOnEmpty) {
if (empty) {
if (exitOnEmpty) {
- printf("Exit from InferenceProcess::run() on empty job queue!\n");
+ LOG_INFO("Exit from InferenceProcess::run() due to empty job queue\n");
break;
}
diff --git a/applications/message_process/CMakeLists.txt b/applications/message_process/CMakeLists.txt
index 1e31d68..2122f14 100644
--- a/applications/message_process/CMakeLists.txt
+++ b/applications/message_process/CMakeLists.txt
@@ -19,7 +19,7 @@
add_library(message_process STATIC src/message_process.cpp)
target_include_directories(message_process PUBLIC include ${LINUX_DRIVER_STACK_PATH}/kernel)
-target_link_libraries(message_process PRIVATE cmsis_device inference_process ethosu_mailbox)
+target_link_libraries(message_process PRIVATE cmsis_device inference_process ethosu_mailbox ethosu_log)
if (CORE_SOFTWARE_ACCELERATOR STREQUAL "NPU")
target_link_libraries(message_process PRIVATE ethosu_core_driver)
-endif()
+endif() \ No newline at end of file
diff --git a/applications/message_process/src/message_process.cpp b/applications/message_process/src/message_process.cpp
index cdd5c35..1669d3f 100644
--- a/applications/message_process/src/message_process.cpp
+++ b/applications/message_process/src/message_process.cpp
@@ -24,6 +24,8 @@
#include "cmsis_compiler.h"
+#include "ethosu_log.h"
+
#include <cstddef>
#include <cstdio>
#include <cstring>
@@ -198,7 +200,7 @@ bool MessageProcess::handleMessage() {
return false;
}
- printf("Msg: header magic=%" PRIX32 ", type=%" PRIu32 ", length=%" PRIu32 "\n", msg.magic, msg.type, msg.length);
+ LOG_INFO("Msg: header magic=%" PRIX32 ", type=%" PRIu32 ", length=%" PRIu32 "\n", msg.magic, msg.type, msg.length);
if (msg.magic != ETHOSU_CORE_MSG_MAGIC) {
sndErrorRspAndResetQueue(ETHOSU_CORE_MSG_ERR_INVALID_MAGIC, "Invalid magic");
@@ -207,21 +209,21 @@ bool MessageProcess::handleMessage() {
switch (msg.type) {
case ETHOSU_CORE_MSG_PING:
- printf("Msg: Ping\n");
+ LOG_INFO("Msg: Ping\n");
sendPong();
break;
case ETHOSU_CORE_MSG_ERR: {
struct ethosu_core_msg_err error = {0};
if (!queueIn.read(error)) {
- printf("ERROR: Msg: Failed to receive error message\n");
+ LOG_ERR("Msg: Failed to receive error message\n");
} else {
- printf("Msg: Received an error response, type=%" PRIu32 ", msg=\"%s\"\n", error.type, error.msg);
+ LOG_INFO("Msg: Received an error response, type=%" PRIu32 ", msg=\"%s\"\n", error.type, error.msg);
}
queueIn.reset();
return false;
}
case ETHOSU_CORE_MSG_VERSION_REQ:
- printf("Msg: Version request\n");
+ LOG_INFO("Msg: Version request\n");
sendVersionRsp();
break;
case ETHOSU_CORE_MSG_CAPABILITIES_REQ: {
@@ -231,7 +233,7 @@ bool MessageProcess::handleMessage() {
return false;
}
- printf("Msg: Capability request.user_arg=0x%" PRIx64 "", req.user_arg);
+ LOG_INFO("Msg: Capability request.user_arg=0x%" PRIx64 "\n", req.user_arg);
sendCapabilityRsp(req.user_arg);
break;
@@ -244,30 +246,30 @@ bool MessageProcess::handleMessage() {
return false;
}
- printf("Msg: InferenceReq. user_arg=0x%" PRIx64 ", network={0x%" PRIx32 ", %" PRIu32 "}",
- req.user_arg,
- req.network.ptr,
- req.network.size);
+ LOG_INFO("Msg: InferenceReq. user_arg=0x%" PRIx64 ", network={0x%" PRIx32 ", %" PRIu32 "}",
+ req.user_arg,
+ req.network.ptr,
+ req.network.size);
- printf(", ifm_count=%" PRIu32 ", ifm=[", req.ifm_count);
+ LOG_DEBUG_N(", ifm_count=%" PRIu32 ", ifm=[", req.ifm_count);
for (uint32_t i = 0; i < req.ifm_count; ++i) {
if (i > 0) {
- printf(", ");
+ LOG_DEBUG_N(", ");
}
- printf("{0x%" PRIx32 ", %" PRIu32 "}", req.ifm[i].ptr, req.ifm[i].size);
+ LOG_DEBUG_N("{0x%" PRIx32 ", %" PRIu32 "}", req.ifm[i].ptr, req.ifm[i].size);
}
- printf("]");
+ LOG_DEBUG_N("]");
- printf(", ofm_count=%" PRIu32 ", ofm=[", req.ofm_count);
+ LOG_DEBUG_N(", ofm_count=%" PRIu32 ", ofm=[", req.ofm_count);
for (uint32_t i = 0; i < req.ofm_count; ++i) {
if (i > 0) {
- printf(", ");
+ LOG_DEBUG_N(", ");
}
- printf("{0x%" PRIx32 ", %" PRIu32 "}", req.ofm[i].ptr, req.ofm[i].size);
+ LOG_DEBUG_N("{0x%" PRIx32 ", %" PRIu32 "}", req.ofm[i].ptr, req.ofm[i].size);
}
- printf("]\n");
+ LOG_DEBUG_N("]\n");
DataPtr networkModel(reinterpret_cast<void *>(req.network.ptr), req.network.size);
@@ -320,7 +322,7 @@ bool MessageProcess::handleMessage() {
void MessageProcess::sendPong() {
if (!queueOut.write(ETHOSU_CORE_MSG_PONG)) {
- printf("ERROR: Msg: Failed to write pong response. No mailbox message sent\n");
+ LOG_ERR("Msg: Failed to write pong response. No mailbox message sent\n");
} else {
mailbox.sendMessage();
}
@@ -335,7 +337,7 @@ void MessageProcess::sendVersionRsp() {
};
if (!queueOut.write(ETHOSU_CORE_MSG_VERSION_RSP, ver)) {
- printf("ERROR: Failed to write version response. No mailbox message sent\n");
+ LOG_ERR("Msg: Failed to write version response. No mailbox message sent\n");
} else {
mailbox.sendMessage();
}
@@ -389,7 +391,7 @@ void MessageProcess::sendCapabilityRsp(uint64_t userArg) {
#endif
if (!queueOut.write(ETHOSU_CORE_MSG_CAPABILITIES_RSP, capabilities)) {
- printf("ERROR: Failed to write capability response. No mailbox message sent\n");
+ LOG_ERR("Failed to write capability response. No mailbox message sent\n");
} else {
mailbox.sendMessage();
}
@@ -405,9 +407,9 @@ void MessageProcess::sndErrorRspAndResetQueue(ethosu_core_msg_err_type type, con
error.msg[i] = message[i];
}
}
- printf("ERROR: Msg: \"%s\"\n", message);
+ LOG_ERR("Msg: \"%s\"\n", message);
if (!queueOut.write(ETHOSU_CORE_MSG_ERR, &error)) {
- printf("ERROR: Msg: Failed to write error response. No mailbox message sent\n");
+ LOG_ERR("Msg: Failed to write error response. No mailbox message sent\n");
return;
}
queueIn.reset();
@@ -445,13 +447,13 @@ void MessageProcess::sendInferenceRsp(uint64_t userArg,
}
rsp.pmu_cycle_counter_count = pmuCycleCounterCount;
- printf("Sending inference response. userArg=0x%" PRIx64 ", ofm_count=%" PRIu32 ", status=%" PRIu32 "\n",
- rsp.user_arg,
- rsp.ofm_count,
- rsp.status);
+ LOG_INFO("Sending inference response. userArg=0x%" PRIx64 ", ofm_count=%" PRIu32 ", status=%" PRIu32 "\n",
+ rsp.user_arg,
+ rsp.ofm_count,
+ rsp.status);
if (!queueOut.write(ETHOSU_CORE_MSG_INFERENCE_RSP, rsp)) {
- printf("ERROR: Msg: Failed to write inference response. No mailbox message sent\n");
+ LOG_ERR("Msg: Failed to write inference response. No mailbox message sent\n");
} else {
mailbox.sendMessage();
}
diff --git a/drivers/mhu_v2/CMakeLists.txt b/drivers/mhu_v2/CMakeLists.txt
index 82a591a..2505901 100644
--- a/drivers/mhu_v2/CMakeLists.txt
+++ b/drivers/mhu_v2/CMakeLists.txt
@@ -20,4 +20,4 @@ add_library(ethosu_mhu_v2 STATIC)
target_include_directories(ethosu_mhu_v2 PUBLIC include)
target_sources(ethosu_mhu_v2 PRIVATE src/mhu_v2.cpp)
-target_link_libraries(ethosu_mhu_v2 PRIVATE ethosu_mailbox)
+target_link_libraries(ethosu_mhu_v2 PRIVATE ethosu_mailbox ethosu_log)
diff --git a/drivers/mhu_v2/src/mhu_v2.cpp b/drivers/mhu_v2/src/mhu_v2.cpp
index eb44a5d..3bcd256 100644
--- a/drivers/mhu_v2/src/mhu_v2.cpp
+++ b/drivers/mhu_v2/src/mhu_v2.cpp
@@ -16,6 +16,8 @@
* limitations under the License.
*/
+#include "ethosu_log.h"
+
#include <mhu_v2.hpp>
#include <cassert>
@@ -195,12 +197,12 @@ void MHUv2::printAIDR(bool tx, bool rx) {
if (tx) {
aidr = getTxAIDR();
a = reinterpret_cast<struct aidr_t *>(&aidr);
- printf("TX MHUv2 reports: Major rev: %d\nMinor rev: %d\n", a->ARCH_MAJOR_REV, a->ARCH_MINOR_REV);
+ LOG_INFO("TX MHUv2 reports: Major rev: %d, Minor rev: %d\n", a->ARCH_MAJOR_REV, a->ARCH_MINOR_REV);
}
if (rx) {
aidr = getRxAIDR();
a = reinterpret_cast<struct aidr_t *>(&aidr);
- printf("RX MHUv2 reports: Major rev: %d\nMinor rev: %d\n", a->ARCH_MAJOR_REV, a->ARCH_MINOR_REV);
+ LOG_INFO("RX MHUv2 reports: Major rev: %d, Minor rev: %d\n", a->ARCH_MAJOR_REV, a->ARCH_MINOR_REV);
}
}
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index 5536949..7e47499 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -24,3 +24,6 @@ add_subdirectory(arm_profiler)
# Build ethosu_monitor
add_subdirectory(ethosu_monitor)
+
+# Build ethosu_logging
+add_subdirectory(ethosu_log) \ No newline at end of file
diff --git a/lib/ethosu_log/CMakeLists.txt b/lib/ethosu_log/CMakeLists.txt
new file mode 100644
index 0000000..fbbed78
--- /dev/null
+++ b/lib/ethosu_log/CMakeLists.txt
@@ -0,0 +1,21 @@
+#
+# Copyright (c) 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.
+#
+
+add_library(ethosu_log INTERFACE)
+target_include_directories(ethosu_log INTERFACE include)
+target_compile_definitions(ethosu_log INTERFACE ETHOSU_LOG_SEVERITY=${LOG_SEVERITY}) \ No newline at end of file
diff --git a/lib/ethosu_log/include/ethosu_log.h b/lib/ethosu_log/include/ethosu_log.h
new file mode 100644
index 0000000..4564b98
--- /dev/null
+++ b/lib/ethosu_log/include/ethosu_log.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 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.
+ */
+
+#ifndef ETHOSU_LOG_H
+#define ETHOSU_LOG_H
+
+/******************************************************************************
+ * Includes
+ ******************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+
+/******************************************************************************
+ * Defines
+ ******************************************************************************/
+
+// Log severity levels
+#define ETHOSU_LOG_ERR 0
+#define ETHOSU_LOG_WARN 1
+#define ETHOSU_LOG_INFO 2
+#define ETHOSU_LOG_DEBUG 3
+
+// Define default log severity
+#ifndef ETHOSU_LOG_SEVERITY
+#define ETHOSU_LOG_SEVERITY ETHOSU_LOG_WARN
+#endif
+
+// Log formatting
+
+#define LOG(f, ...) fprintf(stdout, f, ##__VA_ARGS__)
+
+#if ETHOSU_LOG_SEVERITY >= ETHOSU_LOG_ERR
+#define LOG_ERR_N(f, ...) fprintf(stderr, f, ##__VA_ARGS__)
+#define LOG_ERR(f, ...) LOG_ERR_N("E: " f " (%s:%d)", ##__VA_ARGS__, strrchr("/" __FILE__, '/') + 1, __LINE__)
+#else
+#define LOG_ERR(f, ...)
+#define LOG_ERR_N(f, ...)
+#endif
+
+#if ETHOSU_LOG_SEVERITY >= ETHOSU_LOG_WARN
+#define LOG_WARN_N(f, ...) fprintf(stdout, f, ##__VA_ARGS__)
+#define LOG_WARN(f, ...) LOG_WARN_N("W: " f, ##__VA_ARGS__)
+#else
+#define LOG_WARN(f, ...)
+#define LOG_WARN_N(f, ...)
+#endif
+
+#if ETHOSU_LOG_SEVERITY >= ETHOSU_LOG_INFO
+#define LOG_INFO_N(f, ...) fprintf(stdout, f, ##__VA_ARGS__)
+#define LOG_INFO(f, ...) LOG_INFO_N("I: " f, ##__VA_ARGS__)
+#else
+#define LOG_INFO(f, ...)
+#define LOG_INFO_N(f, ...)
+#endif
+
+#if ETHOSU_LOG_SEVERITY >= ETHOSU_LOG_DEBUG
+#define LOG_DEBUG_N(f, ...) fprintf(stdout, f, ##__VA_ARGS__)
+#define LOG_DEBUG(f, ...) LOG_DEBUG_N("D: %s(): " f, __FUNCTION__, ##__VA_ARGS__)
+#else
+#define LOG_DEBUG(f, ...)
+#define LOG_DEBUG_N(f, ...)
+#endif
+
+#endif \ No newline at end of file
diff --git a/lib/ethosu_monitor/CMakeLists.txt b/lib/ethosu_monitor/CMakeLists.txt
index 50f6526..7983c48 100644
--- a/lib/ethosu_monitor/CMakeLists.txt
+++ b/lib/ethosu_monitor/CMakeLists.txt
@@ -21,6 +21,6 @@ if (NOT TARGET ethosu_core_driver)
endif()
add_library(ethosu_monitor INTERFACE)
-target_link_libraries(ethosu_monitor INTERFACE ethosu_core_driver event_recorder)
+target_link_libraries(ethosu_monitor INTERFACE ethosu_core_driver event_recorder ethosu_log)
target_include_directories(ethosu_monitor INTERFACE include)
target_sources(ethosu_monitor INTERFACE src/ethosu_monitor.cpp)
diff --git a/lib/ethosu_monitor/src/ethosu_monitor.cpp b/lib/ethosu_monitor/src/ethosu_monitor.cpp
index d5cfce9..651fc28 100644
--- a/lib/ethosu_monitor/src/ethosu_monitor.cpp
+++ b/lib/ethosu_monitor/src/ethosu_monitor.cpp
@@ -17,6 +17,7 @@
*/
#include "ethosu_monitor.hpp"
+#include "ethosu_log.h"
#include <stdio.h>
EthosUMonitor::EthosUMonitor(std::vector<int32_t> __eventRecordIds, Backend __backend) :
@@ -33,7 +34,7 @@ void EthosUMonitor::monitorSample(ethosu_driver *drv) {
break;
case PRINTF:
default:
- printf("ethosu_pmu_cntr%d : %u\n", i, eventCount[i]);
+ LOG("ethosu_pmu_cntr%d : %u\n", i, eventCount[i]);
}
}
}
diff --git a/lib/layer_by_layer_profiler/CMakeLists.txt b/lib/layer_by_layer_profiler/CMakeLists.txt
index 9774685..7a16da2 100644
--- a/lib/layer_by_layer_profiler/CMakeLists.txt
+++ b/lib/layer_by_layer_profiler/CMakeLists.txt
@@ -21,6 +21,6 @@ if (NOT TARGET ethosu_core_driver)
endif()
add_library(layer_by_layer_profiler INTERFACE)
-target_link_libraries(layer_by_layer_profiler INTERFACE ethosu_core_driver tflu event_recorder)
+target_link_libraries(layer_by_layer_profiler INTERFACE ethosu_core_driver tflu event_recorder ethosu_log)
target_include_directories(layer_by_layer_profiler INTERFACE include)
target_sources(layer_by_layer_profiler INTERFACE src/layer_by_layer_profiler.cpp)
diff --git a/lib/layer_by_layer_profiler/src/layer_by_layer_profiler.cpp b/lib/layer_by_layer_profiler/src/layer_by_layer_profiler.cpp
index f7922cb..0211414 100644
--- a/lib/layer_by_layer_profiler/src/layer_by_layer_profiler.cpp
+++ b/lib/layer_by_layer_profiler/src/layer_by_layer_profiler.cpp
@@ -23,6 +23,7 @@
#include <string.h>
+#include "ethosu_log.h"
#include "layer_by_layer_profiler.hpp"
#include <ethosu_driver.h>
#include <inttypes.h>
@@ -88,9 +89,9 @@ void LayerByLayerProfiler::EndEvent(uint32_t event_handle) {
}
if (backend_ == PRINTF) {
- printf("%s : cycle_cnt : %" PRIu64 " cycles\n",
- tags_[event_handle],
- end_ticks_[event_handle] - start_ticks_[event_handle]);
+ LOG("%s : cycle_cnt : %" PRIu64 " cycles\n",
+ tags_[event_handle],
+ end_ticks_[event_handle] - start_ticks_[event_handle]);
} else {
EventRecord2(event_id_, (int32_t)event_handle, end_ticks_[event_handle] - start_ticks_[event_handle]);
}
@@ -112,7 +113,7 @@ void LayerByLayerProfiler::Log() const {
if (backend_ == PRINTF) {
for (size_t i = 0; i < num_events_; ++i) {
uint64_t ticks = end_ticks_[i] - start_ticks_[i];
- printf("%s took %" PRIu64 " cycles\n", tags_[i], ticks);
+ LOG("%s took %" PRIu64 " cycles", tags_[i], ticks);
}
}
#endif