summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKshitij Sisodia <kshitij.sisodia@arm.com>2024-07-03 09:57:10 +0100
committerKshitij Sisodia <kshitij.sisodia@arm.com>2024-07-05 08:03:51 +0000
commit9747853052f8e9edc51b33813fe41b6334cac2e5 (patch)
tree08e7a50f0cd2f5a2813cf2d22d5f6494ecc8c98f
parent4b10eef739b40c87d373b816d22fa847cf5c6fdf (diff)
downloadml-embedded-evaluation-kit-9747853052f8e9edc51b33813fe41b6334cac2e5.tar.gz
MLECO-5117: Improving auto-generation of test files
The tests expected all the data types across input and output tensors to be same. These were also limited to 8-bit signed/unsigned values. This patch make it possible to have the test vectors be of different types while being able to get a generic (void) pointer to arrays from the generated getter functions. Change-Id: Id6d8b13803cd2f2ed66fee52eaed86af194b995d Signed-off-by: Kshitij Sisodia <kshitij.sisodia@arm.com>
-rw-r--r--scripts/py/gen_test_data_cpp.py98
-rw-r--r--scripts/py/templates/TestData.cc.template19
-rw-r--r--scripts/py/templates/TestData.hpp.template35
-rw-r--r--tests/use_case/ad/InferenceTestAD.cc9
-rw-r--r--tests/use_case/asr/InferenceTestWav2Letter.cc9
-rw-r--r--tests/use_case/img_class/InferenceTestMobilenetV2.cc6
-rw-r--r--tests/use_case/kws/InferenceTestMicroNetKws.cc7
-rw-r--r--tests/use_case/kws_asr/InferenceTestMicroNetKws.cc6
-rw-r--r--tests/use_case/kws_asr/InferenceTestWav2Letter.cc7
-rw-r--r--tests/use_case/vww/InferenceVisualWakeWordModelTests.cc7
10 files changed, 109 insertions, 94 deletions
diff --git a/scripts/py/gen_test_data_cpp.py b/scripts/py/gen_test_data_cpp.py
index 1ee55ff..35e0149 100644
--- a/scripts/py/gen_test_data_cpp.py
+++ b/scripts/py/gen_test_data_cpp.py
@@ -1,4 +1,5 @@
-# SPDX-FileCopyrightText: Copyright 2021-2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
+# SPDX-FileCopyrightText: Copyright 2021-2024 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");
@@ -82,6 +83,14 @@ env = Environment(loader=FileSystemLoader(Path(__file__).parent / 'templates'),
trim_blocks=True,
lstrip_blocks=True)
+@dataclass
+class IofmParams:
+ """
+ Parameters representing a single tensor (feature map) configuration.
+ """
+ var_name: str
+ size: int
+ data_type: str
# pylint: enable=duplicate-code
@dataclass
@@ -91,20 +100,34 @@ class TestDataParams:
"""
ifm_count: int
ofm_count: int
- ifm_var_names: typing.List[str]
- ifm_var_sizes: typing.List[int]
- ofm_var_names: typing.List[str]
- ofm_var_sizes: typing.List[int]
- data_type: str
+ ifm_params: typing.List[IofmParams]
+ ofm_params: typing.List[IofmParams]
-@dataclass
-class IofmParams:
+def get_data_type_str(filename: Path) -> str:
"""
- Template params for iofmdata.cc
+ Gets the C data type string from a numpy array file path.
+ @param filename: File path to the numpy file.
+ @return String representing C data type.
"""
- var_name: str
- data_type: str
+
+ dtype = np.load(Path(parsed_args.data_folder_path) / filename).dtype
+
+ data_type = None
+ if dtype == np.int8:
+ data_type = 'int8_t'
+ elif dtype == np.uint8:
+ data_type = 'uint8_t'
+ elif dtype == np.int16:
+ data_type = 'int16_t'
+ elif dtype == np.int32:
+ data_type = 'int32_t'
+ elif dtype == np.float32:
+ data_type = 'float'
+ elif data_type is None:
+ raise ValueError(f'Numpy type {dtype} is not supported.')
+
+ return data_type
def write_hpp_file(
@@ -130,11 +153,8 @@ def write_hpp_file(
.stream(common_template_header=hdr,
ifm_count=template_params.ifm_count,
ofm_count=template_params.ofm_count,
- ifm_var_names=template_params.ifm_var_names,
- ifm_var_sizes=template_params.ifm_var_sizes,
- ofm_var_names=template_params.ofm_var_names,
- ofm_var_sizes=template_params.ofm_var_sizes,
- data_type=template_params.data_type,
+ ifm_params=template_params.ifm_params,
+ ofm_params=template_params.ofm_params,
namespaces=parsed_args.namespaces) \
.dump(str(header_file_path))
@@ -142,9 +162,8 @@ def write_hpp_file(
.get_template('TestData.cc.template') \
.stream(common_template_header=hdr,
include_h=header_filename,
- ifm_var_names=template_params.ifm_var_names,
- ofm_var_names=template_params.ofm_var_names,
- data_type=template_params.data_type,
+ ifm_params=template_params.ifm_params,
+ ofm_params=template_params.ofm_params,
namespaces=parsed_args.namespaces) \
.dump(str(cc_file_path))
@@ -169,8 +188,9 @@ def write_individual_cc_file(
hdr = GenUtils.gen_header(env, header_template_file, filename)
# Convert the image and write it to the cc file
- fm_data = (np.load(Path(parsed_args.data_folder_path) / filename)).flatten()
- type(fm_data.dtype)
+ npy_filepath = Path(parsed_args.data_folder_path) / filename
+ fm_data = (np.load(npy_filepath)).flatten()
+
hex_line_generator = (', '.join(map(hex, sub_arr))
for sub_arr in np.array_split(fm_data, math.ceil(len(fm_data) / 20)))
@@ -197,19 +217,17 @@ def get_npy_vec_size(filename: str) -> int:
return data.size * data.dtype.itemsize
-def write_cc_files(args, count, iofm_data_type, add_usecase_fname, prefix):
+def write_cc_files(args, count, add_usecase_fname, prefix) -> typing.List[IofmParams]:
"""
Write all cc files
@param args: User-provided args
@param count: File count
- @param iofm_data_type: Data type
@param add_usecase_fname: Use case suffix
@param prefix: Prefix (ifm/ofm)
@return: Names and sizes of generated C++ arrays
"""
- array_names = []
- sizes = []
+ fm_params_list = []
header_filename = get_header_filename(add_usecase_fname)
@@ -223,19 +241,20 @@ def write_cc_files(args, count, iofm_data_type, add_usecase_fname, prefix):
filename = base_name + ".npy"
array_name = base_name + add_usecase_fname
cc_filename = Path(args.source_folder_path) / (array_name + ".cc")
- array_names.append(array_name)
template_params = IofmParams(
var_name=array_name,
- data_type=iofm_data_type,
+ size=get_npy_vec_size(filename),
+ data_type=get_data_type_str(filename)
)
write_individual_cc_file(
template_params, header_filename, filename, cc_filename, args.license_template
)
- sizes.append(get_npy_vec_size(filename))
- return array_names, sizes
+ fm_params_list.append(template_params)
+
+ return fm_params_list
def get_header_filename(use_case_filename):
@@ -272,18 +291,12 @@ def main(args):
ifms_count = int(len(list(Path(args.data_folder_path).glob('ifm*.npy'))))
ofms_count = int(len(list(Path(args.data_folder_path).glob('ofm*.npy'))))
- iofm_data_type = "int8_t"
- if ifms_count > 0:
- iofm_data_type = "int8_t" \
- if (np.load(str(Path(args.data_folder_path) / "ifm0.npy")).dtype == np.int8) \
- else "uint8_t"
-
- ifm_array_names, ifm_sizes = write_cc_files(
- args, ifms_count, iofm_data_type, add_usecase_fname, prefix="ifm"
+ ifm_params = write_cc_files(
+ args, ifms_count, add_usecase_fname, prefix="ifm"
)
- ofm_array_names, ofm_sizes = write_cc_files(
- args, ofms_count, iofm_data_type, add_usecase_fname, prefix="ofm"
+ ofm_params = write_cc_files(
+ args, ofms_count, add_usecase_fname, prefix="ofm"
)
common_cc_filepath = Path(args.source_folder_path) / common_cc_filename
@@ -291,11 +304,8 @@ def main(args):
template_params = TestDataParams(
ifm_count=ifms_count,
ofm_count=ofms_count,
- ifm_var_names=ifm_array_names,
- ifm_var_sizes=ifm_sizes,
- ofm_var_names=ofm_array_names,
- ofm_var_sizes=ofm_sizes,
- data_type=iofm_data_type,
+ ifm_params=ifm_params,
+ ofm_params=ofm_params
)
write_hpp_file(
diff --git a/scripts/py/templates/TestData.cc.template b/scripts/py/templates/TestData.cc.template
index f07879f..741b510 100644
--- a/scripts/py/templates/TestData.cc.template
+++ b/scripts/py/templates/TestData.cc.template
@@ -1,5 +1,6 @@
{#
- SPDX-FileCopyrightText: Copyright 2021 Arm Limited and/or its affiliates <open-source-office@arm.com>
+ SPDX-FileCopyrightText: Copyright 2021, 2024 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");
@@ -22,15 +23,19 @@
namespace {{namespace}} {
{% endfor %}
-static const {{data_type}} *ifmArrays[] = {
- {{ ifm_var_names|join(',\n ') }}
+static const void *ifmArrays[] = {
+{% for param in ifm_params %}
+ reinterpret_cast<const void*>({{ param.var_name }}),
+{% endfor %}
};
-static const {{data_type}} *ofmArrays[] = {
- {{ ofm_var_names|join(',\n ') }}
+static const void *ofmArrays[] = {
+{% for param in ofm_params %}
+ reinterpret_cast<const void*>({{ param.var_name }}),
+{% endfor %}
};
-const {{data_type}}* GetIfmDataArray(const uint32_t idx)
+const void* GetIfmDataArray(const uint32_t idx)
{
if (idx < NUMBER_OF_IFM_FILES) {
return ifmArrays[idx];
@@ -38,7 +43,7 @@ const {{data_type}}* GetIfmDataArray(const uint32_t idx)
return nullptr;
}
-const {{data_type}}* GetOfmDataArray(const uint32_t idx)
+const void* GetOfmDataArray(const uint32_t idx)
{
if (idx < NUMBER_OF_OFM_FILES) {
return ofmArrays[idx];
diff --git a/scripts/py/templates/TestData.hpp.template b/scripts/py/templates/TestData.hpp.template
index bd56f9f..5a398c7 100644
--- a/scripts/py/templates/TestData.hpp.template
+++ b/scripts/py/templates/TestData.hpp.template
@@ -1,5 +1,6 @@
{#
- SPDX-FileCopyrightText: Copyright 2021 Arm Limited and/or its affiliates <open-source-office@arm.com>
+ SPDX-FileCopyrightText: Copyright 2021, 2024 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");
@@ -16,8 +17,8 @@
#}
{{common_template_header}}
-#ifndef GENERATED_TEST_DATA_H
-#define GENERATED_TEST_DATA_H
+#ifndef GENERATED_TEST_DATA_HPP
+#define GENERATED_TEST_DATA_HPP
#include <cstdint>
@@ -27,19 +28,21 @@ namespace {{namespace}} {
#define NUMBER_OF_IFM_FILES ({{ifm_count}}U)
#define NUMBER_OF_OFM_FILES ({{ofm_count}}U)
-{% for ifm_size in ifm_var_sizes %}
-#define IFM_{{loop.index0}}_DATA_SIZE ({{ifm_size}}U)
-{% endfor %}
-{% for ofm_size in ofm_var_sizes %}
-#define OFM_{{loop.index0}}_DATA_SIZE ({{ofm_size}}U)
-{% endfor %}
-{% for ifm_var_name in ifm_var_names %}
-extern const {{data_type}} {{ifm_var_name}}[IFM_{{loop.index0}}_DATA_SIZE];
+/** Inputs */
+{% for ifm_param in ifm_params %}
+#define IFM_{{loop.index0}}_DATA_SIZE ({{ifm_param.size}}U)
+#define IFM_{{loop.index0}}_DATA_TYPE {{ifm_param.data_type}}
+extern const IFM_{{loop.index0}}_DATA_TYPE {{ifm_param.var_name}}[IFM_{{loop.index0}}_DATA_SIZE];
+
{% endfor %}
-{% for ofm_var_name in ofm_var_names %}
-extern const {{data_type}} {{ofm_var_name}}[OFM_{{loop.index0}}_DATA_SIZE];
+/** Outputs */
+{% for ofm_param in ofm_params %}
+#define OFM_{{loop.index0}}_DATA_SIZE ({{ofm_param.size}}U)
+#define OFM_{{loop.index0}}_DATA_TYPE {{ofm_param.data_type}}
+extern const OFM_{{loop.index0}}_DATA_TYPE {{ofm_param.var_name}}[OFM_{{loop.index0}}_DATA_SIZE];
+
{% endfor %}
/**
@@ -47,17 +50,17 @@ extern const {{data_type}} {{ofm_var_name}}[OFM_{{loop.index0}}_DATA_SIZE];
* @param[in] idx Index of the input.
* @return Pointer to IFM.
**/
-const {{data_type}}* GetIfmDataArray(const uint32_t idx);
+const void* GetIfmDataArray(const uint32_t idx);
/**
* @brief Gets the pointer to output feature map (OFM).
* @param[in] idx Index of the output.
* @return Pointer to OFM.
**/
-const {{data_type}}* GetOfmDataArray(const uint32_t idx);
+const void* GetOfmDataArray(const uint32_t idx);
{% for namespace in namespaces %}
} /* namespace {{namespace}} */
{% endfor %}
-#endif /* GENERATED_TEST_DATA_H */
+#endif /* GENERATED_TEST_DATA_HPP */
diff --git a/tests/use_case/ad/InferenceTestAD.cc b/tests/use_case/ad/InferenceTestAD.cc
index 4991a30..b1184d7 100644
--- a/tests/use_case/ad/InferenceTestAD.cc
+++ b/tests/use_case/ad/InferenceTestAD.cc
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: Copyright 2021 Arm Limited and/or its affiliates
+ * SPDX-FileCopyrightText: Copyright 2021, 2024 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");
@@ -107,9 +107,10 @@ TEST_CASE("Running golden vector inference with TensorFlow Lite Micro and AdMode
{
REQUIRE(NUMBER_OF_IFM_FILES == NUMBER_OF_IFM_FILES);
for (uint32_t i = 0; i < NUMBER_OF_IFM_FILES; ++i) {
- auto input_goldenFV = GetIfmDataArray(i);
- ;
- auto output_goldenFV = GetOfmDataArray(i);
+ auto input_goldenFV = reinterpret_cast<const int8_t*>(
+ GetIfmDataArray(i));
+ auto output_goldenFV = reinterpret_cast<const int8_t*>(
+ GetOfmDataArray(i));
DYNAMIC_SECTION("Executing inference with re-init")
{
diff --git a/tests/use_case/asr/InferenceTestWav2Letter.cc b/tests/use_case/asr/InferenceTestWav2Letter.cc
index 991617c..591c22a 100644
--- a/tests/use_case/asr/InferenceTestWav2Letter.cc
+++ b/tests/use_case/asr/InferenceTestWav2Letter.cc
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: Copyright 2021 Arm Limited and/or its affiliates
+ * SPDX-FileCopyrightText: Copyright 2021, 2024 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");
@@ -99,11 +99,10 @@ void TestInference(const T* input_goldenFV, const T* output_goldenFV, arm::app::
TEST_CASE("Running inference with Tflu and Wav2LetterModel Int8", "[Wav2Letter]")
{
- REQUIRE(NUMBER_OF_IFM_FILES == NUMBER_OF_IFM_FILES);
+ REQUIRE(NUMBER_OF_IFM_FILES == NUMBER_OF_OFM_FILES);
for (uint32_t i = 0; i < NUMBER_OF_IFM_FILES; ++i) {
- auto input_goldenFV = GetIfmDataArray(i);
- ;
- auto output_goldenFV = GetOfmDataArray(i);
+ auto input_goldenFV = reinterpret_cast<const int8_t *>(GetIfmDataArray(i));
+ auto output_goldenFV = reinterpret_cast<const int8_t *>(GetOfmDataArray(i));
DYNAMIC_SECTION("Executing inference with re-init")
{
diff --git a/tests/use_case/img_class/InferenceTestMobilenetV2.cc b/tests/use_case/img_class/InferenceTestMobilenetV2.cc
index 09eba00..7e22cdd 100644
--- a/tests/use_case/img_class/InferenceTestMobilenetV2.cc
+++ b/tests/use_case/img_class/InferenceTestMobilenetV2.cc
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: Copyright 2021-2022 Arm Limited and/or its affiliates
+ * SPDX-FileCopyrightText: Copyright 2021-2022, 2024 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");
@@ -53,8 +53,8 @@ bool RunInference(arm::app::Model& model, const int8_t imageData[])
template <typename T>
void TestInference(int imageIdx, arm::app::Model& model, T tolerance)
{
- auto image = GetIfmDataArray(imageIdx);
- auto goldenFV = GetOfmDataArray(imageIdx);
+ auto image = reinterpret_cast<const IFM_0_DATA_TYPE *>(GetIfmDataArray(imageIdx));
+ auto goldenFV = reinterpret_cast<const OFM_0_DATA_TYPE *>(GetOfmDataArray(imageIdx));
REQUIRE(RunInference(model, image));
diff --git a/tests/use_case/kws/InferenceTestMicroNetKws.cc b/tests/use_case/kws/InferenceTestMicroNetKws.cc
index ace6684..a286e10 100644
--- a/tests/use_case/kws/InferenceTestMicroNetKws.cc
+++ b/tests/use_case/kws/InferenceTestMicroNetKws.cc
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: Copyright 2021 Arm Limited and/or its affiliates
+ * SPDX-FileCopyrightText: Copyright 2021, 2024 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");
@@ -100,9 +100,8 @@ TEST_CASE("Running inference with TensorFlow Lite Micro and MicroNetKwsModel int
{
REQUIRE(NUMBER_OF_IFM_FILES == NUMBER_OF_OFM_FILES);
for (uint32_t i = 0; i < NUMBER_OF_IFM_FILES; ++i) {
- const int8_t* input_goldenFV = GetIfmDataArray(i);
- ;
- const int8_t* output_goldenFV = GetOfmDataArray(i);
+ auto input_goldenFV = reinterpret_cast<const int8_t *>(GetIfmDataArray(i));
+ auto output_goldenFV = reinterpret_cast<const int8_t *>(GetOfmDataArray(i));
DYNAMIC_SECTION("Executing inference with re-init " << i)
{
diff --git a/tests/use_case/kws_asr/InferenceTestMicroNetKws.cc b/tests/use_case/kws_asr/InferenceTestMicroNetKws.cc
index 4cfd784..14e4ce2 100644
--- a/tests/use_case/kws_asr/InferenceTestMicroNetKws.cc
+++ b/tests/use_case/kws_asr/InferenceTestMicroNetKws.cc
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: Copyright 2021 Arm Limited and/or its affiliates
+ * SPDX-FileCopyrightText: Copyright 2021, 2024 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");
@@ -100,8 +100,8 @@ namespace kws {
{
REQUIRE(NUMBER_OF_IFM_FILES == NUMBER_OF_OFM_FILES);
for (uint32_t i = 0; i < NUMBER_OF_IFM_FILES; ++i) {
- const int8_t* input_goldenFV = GetIfmDataArray(i);
- const int8_t* output_goldenFV = GetOfmDataArray(i);
+ auto input_goldenFV = reinterpret_cast<const int8_t *>(GetIfmDataArray(i));
+ auto output_goldenFV = reinterpret_cast<const int8_t *>(GetOfmDataArray(i));
DYNAMIC_SECTION("Executing inference with re-init")
{
diff --git a/tests/use_case/kws_asr/InferenceTestWav2Letter.cc b/tests/use_case/kws_asr/InferenceTestWav2Letter.cc
index b49b886..29e04eb 100644
--- a/tests/use_case/kws_asr/InferenceTestWav2Letter.cc
+++ b/tests/use_case/kws_asr/InferenceTestWav2Letter.cc
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: Copyright 2021 Arm Limited and/or its affiliates
+ * SPDX-FileCopyrightText: Copyright 2021, 2024 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");
@@ -101,9 +101,8 @@ namespace asr {
{
REQUIRE(NUMBER_OF_IFM_FILES == NUMBER_OF_OFM_FILES);
for (uint32_t i = 0; i < NUMBER_OF_IFM_FILES; ++i) {
- auto input_goldenFV = GetIfmDataArray(i);
- ;
- auto output_goldenFV = GetOfmDataArray(i);
+ auto input_goldenFV = reinterpret_cast<const int8_t *>(GetIfmDataArray(i));
+ auto output_goldenFV = reinterpret_cast<const int8_t *>(GetOfmDataArray(i));
DYNAMIC_SECTION("Executing inference with re-init")
{
diff --git a/tests/use_case/vww/InferenceVisualWakeWordModelTests.cc b/tests/use_case/vww/InferenceVisualWakeWordModelTests.cc
index 82bffc6..4c9703c 100644
--- a/tests/use_case/vww/InferenceVisualWakeWordModelTests.cc
+++ b/tests/use_case/vww/InferenceVisualWakeWordModelTests.cc
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: Copyright 2021-2022 Arm Limited and/or its affiliates
+ * SPDX-FileCopyrightText: Copyright 2021-2022, 2024 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");
@@ -42,9 +42,8 @@ bool RunInference(arm::app::Model& model, const int8_t* imageData)
template <typename T>
void TestInference(int imageIdx, arm::app::Model& model)
{
-
- auto image = test::GetIfmDataArray(imageIdx);
- auto goldenFV = test::GetOfmDataArray(imageIdx);
+ auto image = reinterpret_cast<const int8_t *>(test::GetIfmDataArray(imageIdx));
+ auto goldenFV = reinterpret_cast<const int8_t *>(test::GetOfmDataArray(imageIdx));
REQUIRE(RunInference(model, image));