blob: f1cb30f76c99980af6ba22c03d7f3309d5d67990 [file] [log] [blame]
Isabella Gottardic64f5062022-01-21 15:27:13 +00001# Copyright (c) 2021 - 2022 Arm Limited. All rights reserved.
alexander3c798932021-03-26 21:42:19 +00002# SPDX-License-Identifier: Apache-2.0
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16"""
17Utility script to convert a set of pairs of npy files in a given location into
18corresponding cpp files and a single hpp file referencing the vectors
19from the cpp files.
20"""
21import datetime
22import math
23import os
24import numpy as np
Richard Burton00553462021-11-10 16:27:14 +000025from pathlib import Path
alexander3c798932021-03-26 21:42:19 +000026
27from argparse import ArgumentParser
28from jinja2 import Environment, FileSystemLoader
29
30parser = ArgumentParser()
31parser.add_argument("--data_folder_path", type=str, help="path to ifm-ofm npy folder to convert.")
32parser.add_argument("--source_folder_path", type=str, help="path to source folder to be generated.")
33parser.add_argument("--header_folder_path", type=str, help="path to header folder to be generated.")
34parser.add_argument("--usecase", type=str, default="", help="Test data file suffix.")
35parser.add_argument("--namespaces", action='append', default=[])
36parser.add_argument("--license_template", type=str, help="Header template file",
37 default="header_template.txt")
38parser.add_argument("-v", "--verbosity", action="store_true")
39
40args = parser.parse_args()
41
Richard Burton17069622022-03-17 10:54:26 +000042env = Environment(loader=FileSystemLoader(Path(__file__).parent / 'templates'),
alexander3c798932021-03-26 21:42:19 +000043 trim_blocks=True,
44 lstrip_blocks=True)
45
46
Richard Burton00553462021-11-10 16:27:14 +000047def write_hpp_file(header_filename, cc_file_path, header_template_file, num_ifms, num_ofms,
48 ifm_array_names, ifm_sizes, ofm_array_names, ofm_sizes, iofm_data_type):
Richard Burton17069622022-03-17 10:54:26 +000049 header_file_path = Path(args.header_folder_path) / header_filename
alexander3c798932021-03-26 21:42:19 +000050
51 print(f"++ Generating {header_file_path}")
52 header_template = env.get_template(header_template_file)
Richard Burton17069622022-03-17 10:54:26 +000053 hdr = header_template.render(script_name=Path(__file__).name,
alexander3c798932021-03-26 21:42:19 +000054 gen_time=datetime.datetime.now(),
55 year=datetime.datetime.now().year)
56 env.get_template('TestData.hpp.template').stream(common_template_header=hdr,
Richard Burton00553462021-11-10 16:27:14 +000057 ifm_count=num_ifms,
58 ofm_count=num_ofms,
alexander3c798932021-03-26 21:42:19 +000059 ifm_var_names=ifm_array_names,
Richard Burton00553462021-11-10 16:27:14 +000060 ifm_var_sizes=ifm_sizes,
alexander3c798932021-03-26 21:42:19 +000061 ofm_var_names=ofm_array_names,
Richard Burton00553462021-11-10 16:27:14 +000062 ofm_var_sizes=ofm_sizes,
alexander3c798932021-03-26 21:42:19 +000063 data_type=iofm_data_type,
64 namespaces=args.namespaces) \
65 .dump(str(header_file_path))
66
67 env.get_template('TestData.cc.template').stream(common_template_header=hdr,
68 include_h=header_filename,
69 ifm_var_names=ifm_array_names,
70 ofm_var_names=ofm_array_names,
71 data_type=iofm_data_type,
72 namespaces=args.namespaces) \
73 .dump(str(cc_file_path))
74
75
76def write_individual_cc_file(filename, cc_filename, header_filename, header_template_file, array_name, iofm_data_type):
Richard Burton17069622022-03-17 10:54:26 +000077 print(f"++ Converting {filename} to {cc_filename.name}")
alexander3c798932021-03-26 21:42:19 +000078 header_template = env.get_template(header_template_file)
Richard Burton17069622022-03-17 10:54:26 +000079 hdr = header_template.render(script_name=Path(__file__).name,
alexander3c798932021-03-26 21:42:19 +000080 gen_time=datetime.datetime.now(),
Richard Burton17069622022-03-17 10:54:26 +000081 file_name=filename,
alexander3c798932021-03-26 21:42:19 +000082 year=datetime.datetime.now().year)
83
84 # Convert the image and write it to the cc file
Richard Burton17069622022-03-17 10:54:26 +000085 fm_data = (np.load(Path(args.data_folder_path) / filename)).flatten()
alexander3c798932021-03-26 21:42:19 +000086 type(fm_data.dtype)
87 hex_line_generator = (', '.join(map(hex, sub_arr))
88 for sub_arr in np.array_split(fm_data, math.ceil(len(fm_data) / 20)))
89
Isabella Gottardi5cbcd9e2021-10-15 10:17:33 +010090 env.get_template('iofmdata.cc.template').stream(common_template_header=hdr,
alexander3c798932021-03-26 21:42:19 +000091 include_h=header_filename,
92 var_name=array_name,
93 fm_data=hex_line_generator,
94 data_type=iofm_data_type,
95 namespaces=args.namespaces) \
96 .dump(str(cc_filename))
97
98
99def get_npy_vec_size(filename: str) -> int:
100 """
101 Gets the size of the array in the npy file
102 Args:
103 filename: npy file path.
104 Return:
105 size in bytes
106 """
Richard Burton17069622022-03-17 10:54:26 +0000107 data = np.load(Path(args.data_folder_path) / filename)
108 return data.size * data.dtype.itemsize
alexander3c798932021-03-26 21:42:19 +0000109
110
111def main(args):
112 # Keep the count of the images converted
113 ifm_array_names = []
114 ofm_array_names = []
115
Kshitij Sisodiab178b282022-01-04 13:37:53 +0000116 add_usecase_fname = ("_" + args.usecase) if (args.usecase != "") else ""
alexander3c798932021-03-26 21:42:19 +0000117 header_filename = "TestData" + add_usecase_fname + ".hpp"
118 common_cc_filename = "TestData" + add_usecase_fname + ".cc"
119
120 # In the data_folder_path there should be pairs of ifm-ofm
Richard Burton00553462021-11-10 16:27:14 +0000121 # It's assumed the ifm-ofm naming convention: ifm0.npy-ofm0.npy, ifm1.npy-ofm1.npy
122 ifms_count = int(len(list(Path(args.data_folder_path).glob('ifm*.npy'))))
123 ofms_count = int(len(list(Path(args.data_folder_path).glob('ofm*.npy'))))
124
125 #i_ofms_count = int(len([name for name in os.listdir(os.path.join(args.data_folder_path)) if name.lower().endswith('.npy')]) / 2)
alexander3c798932021-03-26 21:42:19 +0000126
127 iofm_data_type = "int8_t"
Richard Burton00553462021-11-10 16:27:14 +0000128 if ifms_count > 0:
Richard Burton17069622022-03-17 10:54:26 +0000129 iofm_data_type = "int8_t" if (np.load(Path(args.data_folder_path) / "ifm0.npy").dtype == np.int8) else "uint8_t"
alexander3c798932021-03-26 21:42:19 +0000130
Richard Burton00553462021-11-10 16:27:14 +0000131 ifm_sizes = []
132 ofm_sizes = []
alexander3c798932021-03-26 21:42:19 +0000133
Richard Burton00553462021-11-10 16:27:14 +0000134 for idx in range(ifms_count):
alexander3c798932021-03-26 21:42:19 +0000135 # Save the fm cc file
136 base_name = "ifm" + str(idx)
137 filename = base_name+".npy"
138 array_name = base_name + add_usecase_fname
Richard Burton17069622022-03-17 10:54:26 +0000139 cc_filename = Path(args.source_folder_path) / (array_name + ".cc")
alexander3c798932021-03-26 21:42:19 +0000140 ifm_array_names.append(array_name)
141 write_individual_cc_file(filename, cc_filename, header_filename, args.license_template, array_name, iofm_data_type)
Richard Burton00553462021-11-10 16:27:14 +0000142 ifm_sizes.append(get_npy_vec_size(filename))
alexander3c798932021-03-26 21:42:19 +0000143
Richard Burton00553462021-11-10 16:27:14 +0000144 for idx in range(ofms_count):
alexander3c798932021-03-26 21:42:19 +0000145 # Save the fm cc file
146 base_name = "ofm" + str(idx)
147 filename = base_name+".npy"
148 array_name = base_name + add_usecase_fname
Richard Burton17069622022-03-17 10:54:26 +0000149 cc_filename = Path(args.source_folder_path) / (array_name + ".cc")
alexander3c798932021-03-26 21:42:19 +0000150 ofm_array_names.append(array_name)
151 write_individual_cc_file(filename, cc_filename, header_filename, args.license_template, array_name, iofm_data_type)
Richard Burton00553462021-11-10 16:27:14 +0000152 ofm_sizes.append(get_npy_vec_size(filename))
alexander3c798932021-03-26 21:42:19 +0000153
Richard Burton17069622022-03-17 10:54:26 +0000154 common_cc_filepath = Path(args.source_folder_path) / common_cc_filename
alexander3c798932021-03-26 21:42:19 +0000155 write_hpp_file(header_filename, common_cc_filepath, args.license_template,
Richard Burton00553462021-11-10 16:27:14 +0000156 ifms_count, ofms_count, ifm_array_names, ifm_sizes, ofm_array_names, ofm_sizes, iofm_data_type)
alexander3c798932021-03-26 21:42:19 +0000157
158
159if __name__ == '__main__':
160 if args.verbosity:
161 print("Running gen_test_data_cpp with args: "+str(args))
162 main(args)