summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLiam Barry <liam.barry@arm.com>2023-08-03 18:21:58 +0100
committerRichard <richard.burton@arm.com>2023-08-29 12:48:06 +0000
commit677d43fa8f55a8aa52e6bd9d1884e2797650fd65 (patch)
tree154774010a306aeac14bf2eb4b4a0846dd905c1b
parentf1b28b861e301122b85ad7dc3d8ccb0720fcb584 (diff)
downloadml-embedded-evaluation-kit-677d43fa8f55a8aa52e6bd9d1884e2797650fd65.tar.gz
MLECO-4260: Replace raw C++ pointers with smart variants
Model: Added std::unique_ptr qualifier to Model.cc member and used make_unique when creating interpreter object Removed custom destructor and un-necessary memory cleanup following failed allocation DataStructures: Refactored array 2d to use a std::vector under the hood. This should preserve desired attributes including contiguous memory while removing the need for custom destructor. Original size function renamed to dimSize to avoid confusion with vector.size() Accompanying changes made to preprocessing and ASR tests. AppContext: Replaced use of raw pointers in AppContext.hpp. Previously a std::map including IAttribute pointers required individual deallocation as they were allocated using new. Signed-off-by: Liam Barry <liam.barry@arm.com> Change-Id: I1a34dce5dea6ecf4883a9ada3a20f827eb6e6d6b
-rw-r--r--source/application/api/common/include/DataStructures.hpp29
-rw-r--r--source/application/api/common/include/Model.hpp4
-rw-r--r--source/application/api/common/source/Model.cc17
-rw-r--r--source/application/api/use_case/asr/include/Wav2LetterPreprocess.hpp6
-rw-r--r--source/application/api/use_case/asr/src/Wav2LetterPreprocess.cc16
-rw-r--r--source/application/main/include/AppContext.hpp36
-rw-r--r--tests/use_case/asr/AsrFeaturesTests.cc8
7 files changed, 51 insertions, 65 deletions
diff --git a/source/application/api/common/include/DataStructures.hpp b/source/application/api/common/include/DataStructures.hpp
index 04c00e7..13bf694 100644
--- a/source/application/api/common/include/DataStructures.hpp
+++ b/source/application/api/common/include/DataStructures.hpp
@@ -1,6 +1,6 @@
/*
- * SPDX-FileCopyrightText: Copyright 2021 Arm Limited and/or its affiliates <open-source-office@arm.com>
- * SPDX-License-Identifier: Apache-2.0
+ * SPDX-FileCopyrightText: Copyright 2021, 2023 Arm Limited and/or its affiliates
+ * <open-source-office@arm.com> 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.
@@ -18,6 +18,7 @@
#define DATA_STRUCTURES_HPP
#include <iterator>
+#include <vector>
namespace arm {
namespace app {
@@ -49,21 +50,17 @@ namespace app {
{
if (rows == 0 || cols == 0) {
printf("Array2d constructor has 0 size.\n");
- m_data = nullptr;
return;
}
- m_data = new T[rows * cols];
+ m_data = std::vector<T>(rows * cols);
}
- ~Array2d()
- {
- delete[] m_data;
- }
+ ~Array2d() = default;
T& operator() (unsigned int row, unsigned int col)
{
#if defined(DEBUG)
- if (row >= m_rows || col >= m_cols || m_data == nullptr) {
+ if (row >= m_rows || col >= m_cols || m_data.empty()) {
printf_err("Array2d subscript out of bounds.\n");
}
#endif /* defined(DEBUG) */
@@ -73,7 +70,7 @@ namespace app {
T operator() (unsigned int row, unsigned int col) const
{
#if defined(DEBUG)
- if (row >= m_rows || col >= m_cols || m_data == nullptr) {
+ if (row >= m_rows || col >= m_cols || m_data.empty()) {
printf_err("const Array2d subscript out of bounds.\n");
}
#endif /* defined(DEBUG) */
@@ -84,7 +81,7 @@ namespace app {
* @brief Gets rows number of the current array2d.
* @return Number of rows.
*/
- size_t size(size_t dim)
+ size_t dimSize(size_t dim)
{
switch (dim)
{
@@ -111,15 +108,15 @@ namespace app {
using iterator=T*;
using const_iterator=T const*;
- iterator begin() { return m_data; }
- iterator end() { return m_data + totalSize(); }
- const_iterator begin() const { return m_data; }
- const_iterator end() const { return m_data + totalSize(); };
+ iterator begin() { return m_data.data(); }
+ iterator end() { return m_data.data() + totalSize(); }
+ const_iterator begin() const { return m_data.data(); }
+ const_iterator end() const { return m_data.data() + totalSize(); };
private:
size_t m_rows;
size_t m_cols;
- T* m_data;
+ std::vector<T> m_data;
};
} /* namespace app */
diff --git a/source/application/api/common/include/Model.hpp b/source/application/api/common/include/Model.hpp
index ed2b4c1..1728e1f 100644
--- a/source/application/api/common/include/Model.hpp
+++ b/source/application/api/common/include/Model.hpp
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: Copyright 2021-2022 Arm Limited and/or its affiliates <open-source-office@arm.com>
+ * SPDX-FileCopyrightText: Copyright 2021-2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -134,7 +134,7 @@ namespace app {
private:
const tflite::Model* m_pModel{nullptr}; /* Tflite model pointer. */
- tflite::MicroInterpreter* m_pInterpreter{nullptr}; /* Tflite interpreter. */
+ std::unique_ptr<tflite::MicroInterpreter> m_pInterpreter{nullptr}; /* Tflite interpreter. */
tflite::MicroAllocator* m_pAllocator{nullptr}; /* Tflite micro allocator. */
bool m_inited{false}; /* Indicates whether this object has been initialised. */
const uint8_t* m_modelAddr{nullptr}; /* Model address */
diff --git a/source/application/api/common/source/Model.cc b/source/application/api/common/source/Model.cc
index f365c89..da8f46b 100644
--- a/source/application/api/common/source/Model.cc
+++ b/source/application/api/common/source/Model.cc
@@ -18,18 +18,13 @@
#include "log_macros.h"
#include <cinttypes>
+#include <memory>
-/* Initialise the model */
-arm::app::Model::~Model()
-{
- delete this->m_pInterpreter;
- /**
- * No clean-up function available for allocator in TensorFlow Lite Micro yet.
- **/
-}
+arm::app::Model::~Model() = default;
arm::app::Model::Model() : m_inited(false), m_type(kTfLiteNoType) {}
+/* Initialise the model */
bool arm::app::Model::Init(uint8_t* tensorArenaAddr,
uint32_t tensorArenaSize,
const uint8_t* nnModelAddr,
@@ -83,8 +78,8 @@ bool arm::app::Model::Init(uint8_t* tensorArenaAddr,
debug("Using existing allocator @ 0x%p\n", this->m_pAllocator);
}
- this->m_pInterpreter =
- new ::tflite::MicroInterpreter(this->m_pModel, this->GetOpResolver(), this->m_pAllocator);
+ this->m_pInterpreter = std::make_unique<tflite::MicroInterpreter>(
+ this->m_pModel, this->GetOpResolver(), this->m_pAllocator);
if (!this->m_pInterpreter) {
printf_err("Failed to allocate interpreter\n");
@@ -97,8 +92,6 @@ bool arm::app::Model::Init(uint8_t* tensorArenaAddr,
if (allocate_status != kTfLiteOk) {
printf_err("tensor allocation failed!\n");
- delete this->m_pInterpreter;
- this->m_pInterpreter = nullptr;
return false;
}
diff --git a/source/application/api/use_case/asr/include/Wav2LetterPreprocess.hpp b/source/application/api/use_case/asr/include/Wav2LetterPreprocess.hpp
index c1fec72..2f29fb0 100644
--- a/source/application/api/use_case/asr/include/Wav2LetterPreprocess.hpp
+++ b/source/application/api/use_case/asr/include/Wav2LetterPreprocess.hpp
@@ -1,6 +1,6 @@
/*
- * SPDX-FileCopyrightText: Copyright 2021-2022 Arm Limited and/or its affiliates <open-source-office@arm.com>
- * SPDX-License-Identifier: Apache-2.0
+ * SPDX-FileCopyrightText: Copyright 2021-2023 Arm Limited and/or its affiliates
+ * <open-source-office@arm.com> 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.
@@ -124,7 +124,7 @@ namespace app {
const int quantOffset)
{
/* Check the output size will fit everything. */
- if (outputBufSz < (this->m_mfccBuf.size(0) * 3 * sizeof(T))) {
+ if (outputBufSz < (this->m_mfccBuf.dimSize(0) * 3 * sizeof(T))) {
printf_err("Tensor size too small for features\n");
return false;
}
diff --git a/source/application/api/use_case/asr/src/Wav2LetterPreprocess.cc b/source/application/api/use_case/asr/src/Wav2LetterPreprocess.cc
index 99e769c..1794894 100644
--- a/source/application/api/use_case/asr/src/Wav2LetterPreprocess.cc
+++ b/source/application/api/use_case/asr/src/Wav2LetterPreprocess.cc
@@ -1,6 +1,6 @@
/*
- * SPDX-FileCopyrightText: Copyright 2021-2022 Arm Limited and/or its affiliates <open-source-office@arm.com>
- * SPDX-License-Identifier: Apache-2.0
+ * SPDX-FileCopyrightText: Copyright 2021-2023 Arm Limited and/or its affiliates
+ * <open-source-office@arm.com> 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.
@@ -63,7 +63,7 @@ namespace app {
mfccWindow,
mfccWindow + this->m_mfccWindowLen);
auto mfcc = this->m_mfcc.MfccCompute(mfccAudioData);
- for (size_t i = 0; i < this->m_mfccBuf.size(0); ++i) {
+ for (size_t i = 0; i < this->m_mfccBuf.dimSize(0); ++i) {
this->m_mfccBuf(i, mfccBufIdx) = mfcc[i];
}
++mfccBufIdx;
@@ -126,16 +126,16 @@ namespace app {
-0.03679654, -0.04329004, -0.03679654,
-0.01731602, 0.01515152, 0.06060606};
- if (delta1.size(0) == 0 || delta2.size(0) != delta1.size(0) ||
- mfcc.size(0) == 0 || mfcc.size(1) == 0) {
+ if (delta1.dimSize(0) == 0 || delta2.dimSize(0) != delta1.dimSize(0) ||
+ mfcc.dimSize(0) == 0 || mfcc.dimSize(1) == 0) {
return false;
}
/* Get the middle index; coeff vec len should always be odd. */
const size_t coeffLen = delta1Coeffs.size();
const size_t fMidIdx = (coeffLen - 1)/2;
- const size_t numFeatures = mfcc.size(0);
- const size_t numFeatVectors = mfcc.size(1);
+ const size_t numFeatures = mfcc.dimSize(0);
+ const size_t numFeatVectors = mfcc.dimSize(1);
/* Iterate through features in MFCC vector. */
for (size_t i = 0; i < numFeatures; ++i) {
@@ -169,7 +169,7 @@ namespace app {
void AsrPreProcess::StandardizeVecF32(Array2d<float>& vec)
{
- auto mean = math::MathUtils::MeanF32(vec.begin(), vec.totalSize());
+ auto mean = math::MathUtils::MeanF32(vec.begin(), vec.totalSize());
auto stddev = math::MathUtils::StdDevF32(vec.begin(), vec.totalSize(), mean);
debug("Mean: %f, Stddev: %f\n", mean, stddev);
diff --git a/source/application/main/include/AppContext.hpp b/source/application/main/include/AppContext.hpp
index 2f028d5..aae1944 100644
--- a/source/application/main/include/AppContext.hpp
+++ b/source/application/main/include/AppContext.hpp
@@ -1,6 +1,6 @@
/*
- * SPDX-FileCopyrightText: Copyright 2021 Arm Limited and/or its affiliates <open-source-office@arm.com>
- * SPDX-License-Identifier: Apache-2.0
+ * SPDX-FileCopyrightText: Copyright 2021, 2023 Arm Limited and/or its affiliates
+ * <open-source-office@arm.com> 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.
@@ -17,9 +17,9 @@
#ifndef APP_CTX_HPP
#define APP_CTX_HPP
-#include <string>
#include <map>
-
+#include <memory>
+#include <string>
namespace arm {
namespace app {
@@ -58,13 +58,11 @@ namespace app {
template<typename T>
void Set(const std::string &name, T object)
{
- /* check if we have already the attribute allocated. */
- if( true == this->Has(name) ){
- //delete its value
- delete this->m_attributes[name];
+ /* Attribute exists; reset the smart pointer */
+ if (this->Has(name)) {
+ this->m_attributes.at(name).reset();
}
- /* allocate new value */
- this->m_attributes[name] = new Attribute<T>(object);
+ this->m_attributes[name] = std::make_unique<Attribute<T>>(object);
}
/**
@@ -73,11 +71,13 @@ namespace app {
* @param[in] name Context attribute name.
* @return Value saved in the context.
*/
- template<typename T>
- T Get(const std::string &name)
+
+ template <typename T>
+ T Get(const std::string& name)
{
- auto a = (Attribute<T>*)m_attributes[name];
- return a->Get();
+ //TODO Add logic to handle access of non-existent attribute
+ auto attributeValue = (Attribute<T>*)m_attributes.at(name).get();
+ return attributeValue->Get();
}
/**
@@ -92,14 +92,10 @@ namespace app {
ApplicationContext() = default;
- ~ApplicationContext() {
- for (auto& attribute : m_attributes)
- delete attribute.second;
+ ~ApplicationContext() = default;
- this->m_attributes.clear();
- }
private:
- std::map<std::string, IAttribute*> m_attributes;
+ std::map<std::string, std::unique_ptr<IAttribute>> m_attributes;
};
} /* namespace app */
diff --git a/tests/use_case/asr/AsrFeaturesTests.cc b/tests/use_case/asr/AsrFeaturesTests.cc
index e88d932..0518ade 100644
--- a/tests/use_case/asr/AsrFeaturesTests.cc
+++ b/tests/use_case/asr/AsrFeaturesTests.cc
@@ -1,6 +1,6 @@
/*
- * SPDX-FileCopyrightText: Copyright 2021-2022 Arm Limited and/or its affiliates <open-source-office@arm.com>
- * SPDX-License-Identifier: Apache-2.0
+ * SPDX-FileCopyrightText: Copyright 2021-2023 Arm Limited and/or its affiliates
+ * <open-source-office@arm.com> 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.
@@ -100,14 +100,14 @@ TEST_CASE("Floating point asr features calculation", "[ASR]")
/* First 4 and last 4 values are different because we pad AFTER diff calculated. */
for (size_t i = 0; i < numMfccFeats; ++i) {
const float* start_goldenDelta1Buf = goldenDelta1Buf[i].data() + 4;
- const float* start_delta1 = delta1Buf.begin() + i * delta1Buf.size(1) + 4;
+ const float* start_delta1 = delta1Buf.begin() + i * delta1Buf.dimSize(1) + 4;
std::vector<float> goldenDataDelta1(start_goldenDelta1Buf, start_goldenDelta1Buf + numFeatVectors - 8);
std::vector<float> tensorDataDelta1(start_delta1, start_delta1 + numFeatVectors - 8);
CheckOutputs<float>(goldenDataDelta1,tensorDataDelta1);
const float* start_goldenDelta2Buf = goldenDelta2Buf[i].data() + 4;
- const float* start_delta2 = delta2Buf.begin() + i * delta2Buf.size(1) + 4;
+ const float* start_delta2 = delta2Buf.begin() + i * delta2Buf.dimSize(1) + 4;
std::vector<float> goldenDataDelta2(start_goldenDelta2Buf, start_goldenDelta2Buf + numFeatVectors - 8);
std::vector<float> tensorDataDelta2(start_delta2, start_delta2 + numFeatVectors - 8);