diff options
author | Kshitij Sisodia <kshitij.sisodia@arm.com> | 2024-07-03 09:57:10 +0100 |
---|---|---|
committer | Kshitij Sisodia <kshitij.sisodia@arm.com> | 2024-07-05 08:03:51 +0000 |
commit | 9747853052f8e9edc51b33813fe41b6334cac2e5 (patch) | |
tree | 08e7a50f0cd2f5a2813cf2d22d5f6494ecc8c98f | |
parent | 4b10eef739b40c87d373b816d22fa847cf5c6fdf (diff) | |
download | ml-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.py | 98 | ||||
-rw-r--r-- | scripts/py/templates/TestData.cc.template | 19 | ||||
-rw-r--r-- | scripts/py/templates/TestData.hpp.template | 35 | ||||
-rw-r--r-- | tests/use_case/ad/InferenceTestAD.cc | 9 | ||||
-rw-r--r-- | tests/use_case/asr/InferenceTestWav2Letter.cc | 9 | ||||
-rw-r--r-- | tests/use_case/img_class/InferenceTestMobilenetV2.cc | 6 | ||||
-rw-r--r-- | tests/use_case/kws/InferenceTestMicroNetKws.cc | 7 | ||||
-rw-r--r-- | tests/use_case/kws_asr/InferenceTestMicroNetKws.cc | 6 | ||||
-rw-r--r-- | tests/use_case/kws_asr/InferenceTestWav2Letter.cc | 7 | ||||
-rw-r--r-- | tests/use_case/vww/InferenceVisualWakeWordModelTests.cc | 7 |
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)); |