1#!/usr/bin/env python3 2# 3# SPDX-FileCopyrightText: Copyright 2010-2023 Arm Limited and/or its affiliates <open-source-office@arm.com> 4# 5# SPDX-License-Identifier: Apache-2.0 6# 7# Licensed under the Apache License, Version 2.0 (the License); you may 8# not use this file except in compliance with the License. 9# You may obtain a copy of the License at 10# 11# www.apache.org/licenses/LICENSE-2.0 12# 13# Unless required by applicable law or agreed to in writing, software 14# distributed under the License is distributed on an AS IS BASIS, WITHOUT 15# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16# See the License for the specific language governing permissions and 17# limitations under the License. 18# 19import os 20import sys 21import json 22import math 23import argparse 24import subprocess 25import numpy as np 26 27from packaging import version 28from abc import ABC, abstractmethod 29 30try: 31 import tensorflow as tf 32except Exception as e: 33 print(e) 34 sys.exit(1) 35 36REQUIRED_MINIMUM_TENSORFLOW_VERSION = version.parse("2.10") 37 38CLANG_FORMAT = 'clang-format-12 -i' # For formatting generated headers. 39 40INT32_MAX = 2147483647 41INT32_MIN = -2147483648 42INT64_MAX = 9223372036854775807 43INT64_MIN = -9223372036854775808 44INT16_MAX = 32767 45INT16_MIN = -32768 46INT8_MAX = 127 47INT8_MIN = -128 48 49 50def parse_args() -> argparse.Namespace: 51 parser = argparse.ArgumentParser(description="Generate input and refererence output data for unittests." 52 " It can regenerate all data, load all stored data or a combination of it.") 53 parser.add_argument('--dataset', type=str, default=None, help="Name of generated test set.") 54 parser.add_argument('--regenerate-weights', action='store_true', help="Regenerate and store new weights.") 55 parser.add_argument('--regenerate-input', action='store_true', help="Regenerate and store new input.") 56 parser.add_argument('--regenerate-biases', action='store_true', help="Regenerate and store new biases.") 57 parser.add_argument('-a', '--regenerate-all', action='store_true', help="Regenerate and store all data.") 58 parser.add_argument('-t', 59 '--testtype', 60 type=str, 61 default=None, 62 choices=[ 63 'conv', 'depthwise_conv', 'avgpool', 'maxpool', 'fully_connected', 'softmax', 'svdf', 'add', 64 'mul', 'lstm' 65 ], 66 help='Type of test. There are the operators that have unit tests.') 67 parser.add_argument('--run-all-testsets', 68 action='store_true', 69 help="Run the script for all existing test " 70 "sets. Regenerate all, partially all or no input data (output may still change, depending on" 71 " changes in script) depending on regenerate flags. If used together with the -t flag, only" 72 " tests of that type will be run.") 73 parser.add_argument('--schema-file', type=str, help="Path to schema file. This may be needed for some tests.") 74 75 args = parser.parse_args() 76 return args 77 78 79# Use interpreter from tensorflow or tflite_runtime. 80# Set this to False to use the tflite_runtime instead. 81# See README for more info. 82default_interpreter = True 83 84if default_interpreter: 85 from tensorflow.lite.python.interpreter import Interpreter 86 from tensorflow.lite.python.interpreter import OpResolverType 87else: 88 from tflite_runtime.interpreter import Interpreter 89 from tflite_runtime.interpreter import OpResolverType 90 import tflite_runtime as tfl_runtime 91 92 93class TestSettings(ABC): 94 95 # This is the generated test data used by the test cases. 96 OUTDIR = 'TestCases/TestData/' 97 98 # This is input to the data generation. If everything or something is regenerated then it is overwritten. 99 # So it always has the same data as the OUTDIR. 100 # The purpose of the pregen is primarily for debugging, as it is enabling to change a single parameter and see how 101 # output changes (or not changes), without regenerating all input data. 102 # It also convinient when testing changes in the script, to be able to run all test sets again. 103 PREGEN = 'PregeneratedData/' 104 105 def __init__(self, 106 dataset, 107 testtype, 108 regenerate_weights, 109 regenerate_input, 110 regenerate_biases, 111 schema_file, 112 in_ch, 113 out_ch, 114 x_in, 115 y_in, 116 w_x, 117 w_y, 118 stride_x=1, 119 stride_y=1, 120 pad=False, 121 randmin=INT8_MIN, 122 randmax=INT8_MAX, 123 batches=1, 124 generate_bias=True, 125 relu6=False, 126 out_activation_min=None, 127 out_activation_max=None, 128 int16xint8=False, 129 bias_min=INT32_MIN, 130 bias_max=INT32_MAX, 131 dilation_x=1, 132 dilation_y=1): 133 134 self.tensor_flow_reference_version = ( 135 "// Generated by {} using tensorflow version {} (Keras version {}).\n".format( 136 os.path.basename(__file__), tf.__version__, tf.keras.__version__)) 137 138 if 'tflite_runtime' in sys.modules: 139 revision = tfl_runtime.__git_version__ 140 version = tfl_runtime.__version__ 141 interpreter = "tflite_runtime" 142 else: 143 revision = tf.__git_version__ 144 version = tf.__version__ 145 interpreter = "tensorflow" 146 147 self.tensor_flow_reference_version += ("// Interpreter from {} version {} and revision {}.\n".format( 148 interpreter, version, revision)) 149 150 # Randomization interval 151 self.mins = randmin 152 self.maxs = randmax 153 154 self.bias_mins = bias_min 155 self.bias_maxs = bias_max 156 157 self.input_ch = in_ch 158 self.output_ch = out_ch 159 self.x_input = x_in 160 self.y_input = y_in 161 self.filter_x = w_x 162 self.filter_y = w_y 163 self.stride_x = stride_x 164 self.stride_y = stride_y 165 self.dilation_x = dilation_x 166 self.dilation_y = dilation_y 167 self.batches = batches 168 self.test_type = testtype 169 self.has_padding = pad 170 171 self.is_int16xint8 = int16xint8 172 173 if relu6: 174 self.out_activation_max = 6 175 self.out_activation_min = 0 176 else: 177 if out_activation_min is not None: 178 self.out_activation_min = out_activation_min 179 else: 180 self.out_activation_min = INT16_MIN if self.is_int16xint8 else INT8_MIN 181 if out_activation_max is not None: 182 self.out_activation_max = out_activation_max 183 else: 184 self.out_activation_max = INT16_MAX if self.is_int16xint8 else INT8_MAX 185 186 # Bias is optional. 187 self.generate_bias = generate_bias 188 189 self.generated_header_files = [] 190 self.pregenerated_data_dir = self.PREGEN 191 192 self.config_data = "config_data.h" 193 194 self.testdataset = dataset 195 196 self.kernel_table_file = self.pregenerated_data_dir + self.testdataset + '/' + 'kernel.txt' 197 self.inputs_table_file = self.pregenerated_data_dir + self.testdataset + '/' + 'input.txt' 198 self.bias_table_file = self.pregenerated_data_dir + self.testdataset + '/' + 'bias.txt' 199 200 if self.has_padding: 201 self.padding = 'SAME' 202 else: 203 self.padding = 'VALID' 204 205 self.regenerate_new_weights = regenerate_weights 206 self.regenerate_new_input = regenerate_input 207 self.regenerate_new_bias = regenerate_biases 208 self.schema_file = schema_file 209 210 self.headers_dir = self.OUTDIR + self.testdataset + '/' 211 os.makedirs(self.headers_dir, exist_ok=True) 212 213 self.model_path = "{}model_{}".format(self.headers_dir, self.testdataset) 214 self.model_path_tflite = self.model_path + '.tflite' 215 216 self.input_data_file_prefix = "input" 217 self.weight_data_file_prefix = "weights" 218 self.bias_data_file_prefix = "biases" 219 self.output_data_file_prefix = "output_ref" 220 221 def save_multiple_dim_array_in_txt(self, file, data): 222 header = ','.join(map(str, data.shape)) 223 np.savetxt(file, data.reshape(-1, data.shape[-1]), header=header, delimiter=',') 224 225 def load_multiple_dim_array_from_txt(self, file): 226 with open(file) as f: 227 shape = list(map(int, next(f)[1:].split(','))) 228 data = np.genfromtxt(f, delimiter=',').reshape(shape) 229 return data.astype(np.float32) 230 231 def convert_tensor_np(self, tensor_in, converter, *qminmax): 232 w = tensor_in.numpy() 233 shape = w.shape 234 w = w.ravel() 235 if len(qminmax) == 2: 236 fw = converter(w, qminmax[0], qminmax[1]) 237 else: 238 fw = converter(w) 239 fw.shape = shape 240 return tf.convert_to_tensor(fw) 241 242 def convert_tensor(self, tensor_in, converter, *qminmax): 243 w = tensor_in.numpy() 244 shape = w.shape 245 w = w.ravel() 246 normal = np.array(w) 247 float_normal = [] 248 249 for i in normal: 250 if len(qminmax) == 2: 251 float_normal.append(converter(i, qminmax[0], qminmax[1])) 252 else: 253 float_normal.append(converter(i)) 254 255 np_float_array = np.asarray(float_normal) 256 np_float_array.shape = shape 257 258 return tf.convert_to_tensor(np_float_array) 259 260 def get_randomized_data(self, dims, npfile, regenerate, decimals=0, minrange=None, maxrange=None): 261 if not minrange: 262 minrange = self.mins 263 if not maxrange: 264 maxrange = self.maxs 265 if not os.path.exists(npfile) or regenerate: 266 regendir = os.path.dirname(npfile) 267 os.makedirs(regendir, exist_ok=True) 268 if decimals == 0: 269 data = tf.Variable(tf.random.uniform(dims, minval=minrange, maxval=maxrange, dtype=tf.dtypes.int64)) 270 data = tf.cast(data, dtype=tf.float32) 271 else: 272 data = tf.Variable(tf.random.uniform(dims, minval=minrange, maxval=maxrange, dtype=tf.dtypes.float32)) 273 data = np.around(data.numpy(), decimals) 274 data = tf.convert_to_tensor(data) 275 276 print("Saving data to {}".format(npfile)) 277 self.save_multiple_dim_array_in_txt(npfile, data.numpy()) 278 else: 279 print("Loading data from {}".format(npfile)) 280 data = tf.convert_to_tensor(self.load_multiple_dim_array_from_txt(npfile)) 281 return data 282 283 def get_randomized_input_data(self, input_data, input_shape=None): 284 # Generate or load saved input data unless hardcoded data provided 285 if input_shape is None: 286 input_shape = [self.batches, self.y_input, self.x_input, self.input_ch] 287 if input_data is not None: 288 input_data = tf.reshape(input_data, input_shape) 289 else: 290 input_data = self.get_randomized_data(input_shape, 291 self.inputs_table_file, 292 regenerate=self.regenerate_new_input) 293 return input_data 294 295 def get_randomized_bias_data(self, biases): 296 # Generate or load saved bias data unless hardcoded data provided 297 if not self.generate_bias: 298 biases = tf.reshape(np.full([self.output_ch], 0), [self.output_ch]) 299 elif biases is not None: 300 biases = tf.reshape(biases, [self.output_ch]) 301 else: 302 biases = self.get_randomized_data([self.output_ch], 303 self.bias_table_file, 304 regenerate=self.regenerate_new_bias, 305 minrange=self.bias_mins, 306 maxrange=self.bias_maxs) 307 return biases 308 309 def format_output_file(self, file): 310 command_list = CLANG_FORMAT.split(' ') 311 command_list.append(file) 312 try: 313 process = subprocess.run(command_list) 314 if process.returncode != 0: 315 print(f"ERROR: {command_list = }") 316 sys.exit(1) 317 except Exception as e: 318 raise RuntimeError(f"{e} from: {command_list = }") 319 320 def write_c_header_wrapper(self): 321 filename = "test_data.h" 322 filepath = self.headers_dir + filename 323 324 print("Generating C header wrapper {}...".format(filepath)) 325 with open(filepath, 'w+') as f: 326 f.write(self.tensor_flow_reference_version) 327 while len(self.generated_header_files) > 0: 328 f.write('#include "{}"\n'.format(self.generated_header_files.pop())) 329 self.format_output_file(filepath) 330 331 def write_common_config(self, f, prefix): 332 """ 333 Shared by conv/depthwise_conv and pooling 334 """ 335 f.write("#define {}_FILTER_X {}\n".format(prefix, self.filter_x)) 336 f.write("#define {}_FILTER_Y {}\n".format(prefix, self.filter_y)) 337 f.write("#define {}_STRIDE_X {}\n".format(prefix, self.stride_x)) 338 f.write("#define {}_STRIDE_Y {}\n".format(prefix, self.stride_y)) 339 f.write("#define {}_PAD_X {}\n".format(prefix, self.pad_x)) 340 f.write("#define {}_PAD_Y {}\n".format(prefix, self.pad_y)) 341 f.write("#define {}_OUTPUT_W {}\n".format(prefix, self.x_output)) 342 f.write("#define {}_OUTPUT_H {}\n".format(prefix, self.y_output)) 343 344 def write_c_common_header(self, f): 345 f.write(self.tensor_flow_reference_version) 346 f.write("#pragma once\n") 347 348 def write_c_config_header(self, write_common_parameters=True) -> None: 349 filename = self.config_data 350 351 self.generated_header_files.append(filename) 352 filepath = self.headers_dir + filename 353 354 prefix = self.testdataset.upper() 355 356 print("Writing C header with config data {}...".format(filepath)) 357 with open(filepath, "w+") as f: 358 self.write_c_common_header(f) 359 if (write_common_parameters): 360 f.write("#define {}_OUT_CH {}\n".format(prefix, self.output_ch)) 361 f.write("#define {}_IN_CH {}\n".format(prefix, self.input_ch)) 362 f.write("#define {}_INPUT_W {}\n".format(prefix, self.x_input)) 363 f.write("#define {}_INPUT_H {}\n".format(prefix, self.y_input)) 364 f.write("#define {}_DST_SIZE {}\n".format(prefix, self.x_output * self.y_output * self.output_ch * 365 self.batches)) 366 f.write("#define {}_INPUT_SIZE {}\n".format(prefix, self.x_input * self.y_input * self.input_ch)) 367 f.write("#define {}_OUT_ACTIVATION_MIN {}\n".format(prefix, self.out_activation_min)) 368 f.write("#define {}_OUT_ACTIVATION_MAX {}\n".format(prefix, self.out_activation_max)) 369 f.write("#define {}_INPUT_BATCHES {}\n".format(prefix, self.batches)) 370 self.format_output_file(filepath) 371 372 def get_data_file_name_info(self, name_prefix) -> (str, str): 373 filename = name_prefix + "_data.h" 374 filepath = self.headers_dir + filename 375 return filename, filepath 376 377 def generate_c_array(self, name, array, datatype="int8_t", const="const ") -> None: 378 w = None 379 380 if type(array) is list: 381 w = array 382 size = len(array) 383 elif type(array) is np.ndarray: 384 w = array 385 w = w.ravel() 386 size = w.size 387 else: 388 w = array.numpy() 389 w = w.ravel() 390 size = tf.size(array) 391 392 filename, filepath = self.get_data_file_name_info(name) 393 self.generated_header_files.append(filename) 394 395 print("Generating C header {}...".format(filepath)) 396 with open(filepath, "w+") as f: 397 self.write_c_common_header(f) 398 f.write("#include <stdint.h>\n\n") 399 if size > 0: 400 f.write(const + datatype + " " + self.testdataset + '_' + name + "[%d] =\n{\n" % size) 401 for i in range(size - 1): 402 f.write(" %d,\n" % w[i]) 403 f.write(" %d\n" % w[size - 1]) 404 f.write("};\n") 405 else: 406 f.write(const + datatype + " *" + self.testdataset + '_' + name + " = NULL;\n") 407 self.format_output_file(filepath) 408 409 def set_output_dims_and_padding(self, output_x, output_y): 410 self.x_output = output_x 411 self.y_output = output_y 412 if self.has_padding: 413 # Take dilation into account. 414 filter_x = (self.filter_x - 1) * self.dilation_x + 1 415 filter_y = (self.filter_y - 1) * self.dilation_y + 1 416 417 pad_along_width = max((self.x_output - 1) * self.stride_x + filter_x - self.x_input, 0) 418 pad_along_height = max((self.y_output - 1) * self.stride_y + filter_y - self.y_input, 0) 419 pad_top = pad_along_height // 2 420 pad_left = pad_along_width // 2 421 self.pad_x = pad_left 422 self.pad_y = pad_top 423 else: 424 self.pad_x = 0 425 self.pad_y = 0 426 427 @abstractmethod 428 def generate_data(self, input_data=None, weights=None, biases=None) -> None: 429 ''' Must be overriden ''' 430 431 def quantize_scale(self, scale): 432 significand, shift = math.frexp(scale) 433 significand_q31 = round(significand * (1 << 31)) 434 return significand_q31, shift 435 436 def get_calib_data_func(self, n_inputs, shape): 437 438 def representative_data_gen(): 439 representative_testsets = [] 440 if n_inputs > 0: 441 for i in range(n_inputs): 442 representative_testsets.append(np.ones(shape, dtype=np.float32)) 443 yield representative_testsets 444 else: 445 raise RuntimeError("Invalid number of representative test sets: {}. Must be more than 0".format( 446 self.test_type)) 447 448 return representative_data_gen 449 450 def convert_and_interpret(self, model, inttype, input_data=None, dataset_shape=None) -> Interpreter: 451 """ 452 Compile and convert a model to Tflite format, run interpreter and allocate tensors. 453 """ 454 model.compile(loss=tf.keras.losses.categorical_crossentropy, 455 optimizer=tf.keras.optimizers.Adam(), 456 metrics=['accuracy']) 457 n_inputs = len(model.inputs) 458 459 if dataset_shape: 460 representative_dataset_shape = dataset_shape 461 else: 462 representative_dataset_shape = (self.batches, self.y_input, self.x_input, self.input_ch) 463 464 converter = tf.lite.TFLiteConverter.from_keras_model(model) 465 466 representative_dataset = self.get_calib_data_func(n_inputs, representative_dataset_shape) 467 468 converter.optimizations = [tf.lite.Optimize.DEFAULT] 469 converter.representative_dataset = representative_dataset 470 if self.is_int16xint8: 471 converter.target_spec.supported_ops = [ 472 tf.lite.OpsSet.EXPERIMENTAL_TFLITE_BUILTINS_ACTIVATIONS_INT16_WEIGHTS_INT8 473 ] 474 else: 475 converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8] 476 converter.inference_input_type = inttype 477 converter.inference_output_type = inttype 478 tflite_model = converter.convert() 479 480 os.makedirs(os.path.dirname(self.model_path_tflite), exist_ok=True) 481 with open(self.model_path_tflite, "wb") as model: 482 model.write(tflite_model) 483 484 interpreter = Interpreter(model_path=str(self.model_path_tflite), 485 experimental_op_resolver_type=OpResolverType.BUILTIN_REF) 486 interpreter.allocate_tensors() 487 488 output_details = interpreter.get_output_details() 489 (self.output_scale, self.output_zero_point) = output_details[0]['quantization'] 490 491 if input_data is not None: 492 input_details = interpreter.get_input_details() 493 (self.input_scale, self.input_zero_point) = input_details[0]['quantization'] 494 495 # Set input tensors 496 interpreter.set_tensor(input_details[0]["index"], tf.cast(input_data, inttype)) 497 498 return interpreter 499 500 def generate_json_from_template(self, 501 weights_feature_data=None, 502 weights_time_data=None, 503 bias_data=None, 504 int8_time_weights=False): 505 """ 506 Takes a json template and parameters as input and creates a new json file. 507 """ 508 generated_json_file = self.model_path + '.json' 509 510 with open(self.json_template, 'r') as in_file, open(generated_json_file, 'w') as out_file: 511 # Update shapes, scales and zero points 512 data = in_file.read() 513 for item, to_replace in self.json_replacements.items(): 514 data = data.replace(item, str(to_replace)) 515 516 data = json.loads(data) 517 518 # Update weights and bias data 519 if weights_feature_data is not None: 520 w_1_buffer_index = 1 521 data["buffers"][w_1_buffer_index]["data"] = self.to_bytes(weights_feature_data.numpy().ravel(), 1) 522 if weights_time_data is not None: 523 w_2_buffer_index = 2 524 if int8_time_weights: 525 data["buffers"][w_2_buffer_index]["data"] = self.to_bytes(weights_time_data.numpy().ravel(), 1) 526 else: 527 data["buffers"][w_2_buffer_index]["data"] = self.to_bytes(weights_time_data.numpy().ravel(), 2) 528 if bias_data is not None: 529 bias_buffer_index = 3 530 data["buffers"][bias_buffer_index]["data"] = self.to_bytes(bias_data.numpy().ravel(), 4) 531 532 json.dump(data, out_file, indent=2) 533 534 return generated_json_file 535 536 def flatc_generate_tflite(self, json_input, schema): 537 flatc = 'flatc' 538 if schema is None: 539 raise RuntimeError("A schema file is required.") 540 command = "{} -o {} -c -b {} {}".format(flatc, self.headers_dir, schema, json_input) 541 command_list = command.split(' ') 542 try: 543 process = subprocess.run(command_list) 544 if process.returncode != 0: 545 print(f"ERROR: {command = }") 546 sys.exit(1) 547 except Exception as e: 548 raise RuntimeError(f"{e} from: {command = }. Did you install flatc?") 549 550 def to_bytes(self, tensor_data, type_size) -> bytes: 551 result_bytes = [] 552 553 if type_size == 1: 554 tensor_type = np.uint8 555 elif type_size == 2: 556 tensor_type = np.uint16 557 elif type_size == 4: 558 tensor_type = np.uint32 559 else: 560 raise RuntimeError("Size not supported: {}".format(type_size)) 561 562 for val in tensor_data: 563 for byte in int(tensor_type(val)).to_bytes(type_size, 'little'): 564 result_bytes.append(byte) 565 566 return result_bytes 567 568 569class ConvSettings(TestSettings): 570 571 def __init__(self, 572 dataset, 573 testtype, 574 regenerate_weights, 575 regenerate_input, 576 regenerate_biases, 577 schema_file, 578 in_ch=1, 579 out_ch=1, 580 x_in=7, 581 y_in=7, 582 w_x=3, 583 w_y=3, 584 stride_x=2, 585 stride_y=2, 586 pad=True, 587 randmin=INT8_MIN, 588 randmax=INT8_MAX, 589 batches=1, 590 generate_bias=True, 591 relu6=False, 592 out_activation_min=None, 593 out_activation_max=None, 594 int16xint8=False, 595 bias_min=INT32_MIN, 596 bias_max=INT32_MAX, 597 dilation_x=1, 598 dilation_y=1): 599 super().__init__(dataset, 600 testtype, 601 regenerate_weights, 602 regenerate_input, 603 regenerate_biases, 604 schema_file, 605 in_ch, 606 out_ch, 607 x_in, 608 y_in, 609 w_x, 610 w_y, 611 stride_x, 612 stride_y, 613 pad, 614 randmin, 615 randmax, 616 batches, 617 generate_bias=generate_bias, 618 relu6=relu6, 619 out_activation_min=out_activation_min, 620 out_activation_max=out_activation_max, 621 int16xint8=int16xint8, 622 bias_min=bias_min, 623 bias_max=bias_max, 624 dilation_x=dilation_x, 625 dilation_y=dilation_y) 626 627 self.scaling_factors = [] 628 629 if self.test_type == 'depthwise_conv': 630 self.channel_multiplier = self.output_ch // self.input_ch 631 if self.output_ch % self.input_ch != 0: 632 raise RuntimeError("out channel ({}) is not multiple of in channel ({})".format(out_ch, in_ch)) 633 634 def write_c_config_header(self) -> None: 635 super().write_c_config_header() 636 637 filename = self.config_data 638 filepath = self.headers_dir + filename 639 prefix = self.testdataset.upper() 640 641 with open(filepath, "a") as f: 642 self.write_common_config(f, prefix) 643 if self.test_type == 'depthwise_conv': 644 f.write("#define {}_CH_MULT {}\n".format(prefix, self.channel_multiplier)) 645 f.write("#define {}_INPUT_OFFSET {}\n".format(prefix, -self.input_zero_point)) 646 f.write("#define {}_OUTPUT_OFFSET {}\n".format(prefix, self.output_zero_point)) 647 f.write("#define {}_DILATION_X {}\n".format(prefix, self.dilation_x)) 648 f.write("#define {}_DILATION_Y {}\n".format(prefix, self.dilation_y)) 649 650 def generate_quantize_per_channel_multiplier(self): 651 num_channels = self.output_ch 652 per_channel_multiplier = [] 653 per_channel_shift = [] 654 655 if len(self.scaling_factors) != num_channels: 656 raise RuntimeError("Missing scaling factors") 657 658 for i in range(num_channels): 659 effective_output_scale = self.input_scale * self.scaling_factors[i] / self.output_scale 660 (quantized_multiplier, shift) = self.quantize_scale(effective_output_scale) 661 662 per_channel_multiplier.append(quantized_multiplier) 663 per_channel_shift.append(shift) 664 665 return per_channel_multiplier, per_channel_shift 666 667 def generate_data(self, input_data=None, weights=None, biases=None) -> None: 668 if self.is_int16xint8: 669 inttype = tf.int16 670 datatype = "int16_t" 671 bias_datatype = "int64_t" 672 else: 673 inttype = tf.int8 674 datatype = "int8_t" 675 bias_datatype = "int32_t" 676 677 input_data = self.get_randomized_input_data(input_data) 678 679 if self.test_type == 'conv': 680 out_channel = self.output_ch 681 elif self.test_type == 'depthwise_conv': 682 out_channel = self.channel_multiplier 683 684 if weights is not None: 685 weights = tf.reshape(weights, [self.filter_y, self.filter_x, self.input_ch, out_channel]) 686 else: 687 weights = self.get_randomized_data([self.filter_y, self.filter_x, self.input_ch, out_channel], 688 self.kernel_table_file, 689 minrange=INT32_MIN, 690 maxrange=INT32_MAX, 691 decimals=1, 692 regenerate=self.regenerate_new_weights) 693 694 biases = self.get_randomized_bias_data(biases) 695 696 # Create a one layer Keras model. 697 model = tf.keras.models.Sequential() 698 input_shape = (self.batches, self.y_input, self.x_input, self.input_ch) 699 model.add(tf.keras.layers.InputLayer(input_shape=input_shape[1:], batch_size=self.batches)) 700 if self.test_type == 'conv': 701 conv_layer = tf.keras.layers.Conv2D(self.output_ch, 702 kernel_size=(self.filter_y, self.filter_x), 703 strides=(self.stride_y, self.stride_x), 704 padding=self.padding, 705 input_shape=input_shape[1:], 706 dilation_rate=(self.dilation_y, self.dilation_x)) 707 model.add(conv_layer) 708 conv_layer.set_weights([weights, biases]) 709 elif self.test_type == 'depthwise_conv': 710 depthwise_layer = tf.keras.layers.DepthwiseConv2D(kernel_size=(self.filter_y, self.filter_x), 711 strides=(self.stride_y, self.stride_x), 712 padding=self.padding, 713 depth_multiplier=self.channel_multiplier, 714 input_shape=input_shape[1:], 715 dilation_rate=(self.dilation_y, self.dilation_x)) 716 model.add(depthwise_layer) 717 depthwise_layer.set_weights([weights, biases]) 718 interpreter = self.convert_and_interpret(model, inttype, input_data) 719 720 all_layers_details = interpreter.get_tensor_details() 721 filter_layer = all_layers_details[2] 722 bias_layer = all_layers_details[1] 723 if weights.numpy().size != interpreter.get_tensor(filter_layer['index']).size or \ 724 (self.generate_bias and biases.numpy().size != interpreter.get_tensor(bias_layer['index']).size): 725 raise RuntimeError(f"Dimension mismatch for {self.testdataset}") 726 727 output_details = interpreter.get_output_details() 728 self.set_output_dims_and_padding(output_details[0]['shape'][2], output_details[0]['shape'][1]) 729 730 self.generate_c_array(self.input_data_file_prefix, input_data, datatype=datatype) 731 self.generate_c_array(self.weight_data_file_prefix, interpreter.get_tensor(filter_layer['index'])) 732 733 self.scaling_factors = filter_layer['quantization_parameters']['scales'] 734 per_channel_multiplier, per_channel_shift = self.generate_quantize_per_channel_multiplier() 735 self.generate_c_array("output_mult", per_channel_multiplier, datatype='int32_t') 736 self.generate_c_array("output_shift", per_channel_shift, datatype='int32_t') 737 738 self.generate_c_array(self.bias_data_file_prefix, interpreter.get_tensor(bias_layer['index']), bias_datatype) 739 740 # Generate reference 741 interpreter.invoke() 742 output_data = interpreter.get_tensor(output_details[0]["index"]) 743 self.generate_c_array(self.output_data_file_prefix, 744 np.clip(output_data, self.out_activation_min, self.out_activation_max), 745 datatype=datatype) 746 747 self.write_c_config_header() 748 self.write_c_header_wrapper() 749 750 751class PoolingSettings(TestSettings): 752 753 def __init__(self, 754 dataset, 755 testtype, 756 regenerate_weights, 757 regenerate_input, 758 regenerate_biases, 759 schema_file, 760 channels=8, 761 x_in=4, 762 y_in=4, 763 w_x=4, 764 w_y=4, 765 stride_x=1, 766 stride_y=1, 767 randmin=INT8_MIN, 768 randmax=INT8_MAX, 769 bias_min=INT32_MIN, 770 bias_max=INT32_MAX, 771 batches=1, 772 pad=False, 773 relu6=False, 774 out_activation_min=None, 775 out_activation_max=None, 776 int16xint8=False): 777 super().__init__(dataset, 778 testtype, 779 regenerate_weights, 780 regenerate_input, 781 regenerate_biases, 782 schema_file, 783 channels, 784 channels, 785 x_in, 786 y_in, 787 w_x, 788 w_y, 789 stride_x, 790 stride_y, 791 pad, 792 randmin=randmin, 793 randmax=randmax, 794 relu6=relu6, 795 out_activation_min=out_activation_min, 796 out_activation_max=out_activation_max, 797 int16xint8=int16xint8) 798 799 def generate_data(self, input_data=None) -> None: 800 if self.is_int16xint8: 801 datatype = "int16_t" 802 inttype = tf.int16 803 else: 804 datatype = "int8_t" 805 inttype = tf.int8 806 807 input_data = self.get_randomized_input_data(input_data) 808 self.generate_c_array(self.input_data_file_prefix, input_data, datatype=datatype) 809 810 input_data = tf.cast(input_data, tf.float32) 811 812 # Create a one-layer Keras model 813 model = tf.keras.models.Sequential() 814 input_shape = (self.batches, self.y_input, self.x_input, self.input_ch) 815 model.add(tf.keras.layers.InputLayer(input_shape=input_shape[1:], batch_size=self.batches)) 816 if self.test_type == 'avgpool': 817 model.add( 818 tf.keras.layers.AveragePooling2D(pool_size=(self.filter_y, self.filter_x), 819 strides=(self.stride_y, self.stride_x), 820 padding=self.padding, 821 input_shape=input_shape[1:])) 822 elif self.test_type == 'maxpool': 823 model.add( 824 tf.keras.layers.MaxPooling2D(pool_size=(self.filter_y, self.filter_x), 825 strides=(self.stride_y, self.stride_x), 826 padding=self.padding, 827 input_shape=input_shape[1:])) 828 else: 829 raise RuntimeError("Wrong test type") 830 831 interpreter = self.convert_and_interpret(model, inttype, input_data) 832 833 output_details = interpreter.get_output_details() 834 self.set_output_dims_and_padding(output_details[0]['shape'][2], output_details[0]['shape'][1]) 835 836 # Generate reference 837 interpreter.invoke() 838 output_data = interpreter.get_tensor(output_details[0]["index"]) 839 self.generate_c_array(self.output_data_file_prefix, 840 np.clip(output_data, self.out_activation_min, self.out_activation_max), 841 datatype=datatype) 842 843 self.write_c_config_header() 844 self.write_c_header_wrapper() 845 846 def write_c_config_header(self) -> None: 847 super().write_c_config_header() 848 849 filename = self.config_data 850 filepath = self.headers_dir + filename 851 prefix = self.testdataset.upper() 852 853 with open(filepath, "a") as f: 854 self.write_common_config(f, prefix) 855 856 857class FullyConnectedSettings(TestSettings): 858 859 def __init__(self, 860 dataset, 861 testtype, 862 regenerate_weights, 863 regenerate_input, 864 regenerate_biases, 865 schema_file, 866 in_ch=1, 867 out_ch=1, 868 x_in=1, 869 y_in=1, 870 w_x=1, 871 w_y=1, 872 stride_x=1, 873 stride_y=1, 874 pad=False, 875 randmin=INT8_MIN, 876 randmax=INT8_MAX, 877 batches=1, 878 generate_bias=True, 879 out_activation_min=None, 880 out_activation_max=None, 881 int16xint8=False, 882 bias_min=INT32_MIN, 883 bias_max=INT32_MAX): 884 super().__init__(dataset, 885 testtype, 886 regenerate_weights, 887 regenerate_input, 888 regenerate_biases, 889 schema_file, 890 in_ch, 891 out_ch, 892 x_in, 893 y_in, 894 x_in, 895 y_in, 896 stride_x, 897 stride_y, 898 pad, 899 randmin, 900 randmax, 901 batches, 902 generate_bias=generate_bias, 903 out_activation_min=out_activation_min, 904 out_activation_max=out_activation_max, 905 int16xint8=int16xint8, 906 bias_min=bias_min, 907 bias_max=bias_max) 908 909 def write_c_config_header(self) -> None: 910 super().write_c_config_header() 911 912 filename = self.config_data 913 filepath = self.headers_dir + filename 914 prefix = self.testdataset.upper() 915 916 with open(filepath, "a") as f: 917 f.write("#define {}_OUTPUT_MULTIPLIER {}\n".format(prefix, self.quantized_multiplier)) 918 f.write("#define {}_OUTPUT_SHIFT {}\n".format(prefix, self.quantized_shift)) 919 f.write("#define {}_ACCUMULATION_DEPTH {}\n".format(prefix, self.input_ch * self.x_input * self.y_input)) 920 f.write("#define {}_INPUT_OFFSET {}\n".format(prefix, -self.input_zero_point)) 921 f.write("#define {}_OUTPUT_OFFSET {}\n".format(prefix, self.output_zero_point)) 922 923 def quantize_multiplier(self): 924 input_product_scale = self.input_scale * self.weights_scale 925 if input_product_scale < 0: 926 raise RuntimeError("negative input product scale") 927 real_multipler = input_product_scale / self.output_scale 928 (self.quantized_multiplier, self.quantized_shift) = self.quantize_scale(real_multipler) 929 930 def generate_data(self, input_data=None, weights=None, biases=None) -> None: 931 input_data = self.get_randomized_input_data(input_data, 932 [self.batches, self.input_ch * self.x_input * self.y_input]) 933 934 if self.is_int16xint8: 935 inttype = tf.int16 936 datatype = "int16_t" 937 bias_datatype = "int64_t" 938 else: 939 inttype = tf.int8 940 datatype = "int8_t" 941 bias_datatype = "int32_t" 942 943 fc_weights_format = [self.input_ch * self.y_input * self.x_input, self.output_ch] 944 945 if weights is not None: 946 weights = tf.reshape(weights, fc_weights_format) 947 else: 948 weights = self.get_randomized_data(fc_weights_format, 949 self.kernel_table_file, 950 minrange=INT32_MIN, 951 maxrange=INT32_MAX, 952 regenerate=self.regenerate_new_weights) 953 954 biases = self.get_randomized_bias_data(biases) 955 956 # Create model with one fully_connected layer. 957 model = tf.keras.models.Sequential() 958 model.add( 959 tf.keras.layers.InputLayer(input_shape=(self.y_input * self.x_input * self.input_ch, ), 960 batch_size=self.batches)) 961 fully_connected_layer = tf.keras.layers.Dense(self.output_ch, activation=None) 962 model.add(fully_connected_layer) 963 fully_connected_layer.set_weights([weights, biases]) 964 965 interpreter = self.convert_and_interpret(model, inttype, input_data) 966 967 all_layers_details = interpreter.get_tensor_details() 968 if self.generate_bias: 969 filter_layer = all_layers_details[2] 970 bias_layer = all_layers_details[1] 971 else: 972 filter_layer = all_layers_details[1] 973 if weights.numpy().size != interpreter.get_tensor(filter_layer['index']).size or \ 974 (self.generate_bias and biases.numpy().size != interpreter.get_tensor(bias_layer['index']).size): 975 raise RuntimeError(f"Dimension mismatch for {self.testdataset}") 976 977 # The generic destination size calculation for these tests are: self.x_output * self.y_output * self.output_ch 978 # * self.batches. 979 self.x_output = 1 980 self.y_output = 1 981 output_details = interpreter.get_output_details() 982 if self.output_ch != output_details[0]['shape'][1] or self.batches != output_details[0]['shape'][0]: 983 raise RuntimeError("Fully connected out dimension mismatch") 984 985 self.weights_scale = filter_layer['quantization_parameters']['scales'][0] 986 self.quantize_multiplier() 987 988 self.generate_c_array(self.input_data_file_prefix, input_data, datatype=datatype) 989 self.generate_c_array(self.weight_data_file_prefix, interpreter.get_tensor(filter_layer['index'])) 990 991 if self.generate_bias: 992 self.generate_c_array(self.bias_data_file_prefix, interpreter.get_tensor(bias_layer['index']), 993 bias_datatype) 994 else: 995 self.generate_c_array(self.bias_data_file_prefix, biases, bias_datatype) 996 997 # Generate reference 998 interpreter.invoke() 999 output_data = interpreter.get_tensor(output_details[0]["index"]) 1000 self.generate_c_array(self.output_data_file_prefix, 1001 np.clip(output_data, self.out_activation_min, self.out_activation_max), 1002 datatype=datatype) 1003 1004 self.write_c_config_header() 1005 self.write_c_header_wrapper() 1006 1007 1008class SoftmaxSettings(TestSettings): 1009 softmax_input_integer_bits = 5 1010 1011 def __init__(self, 1012 dataset, 1013 testtype, 1014 regenerate_weights, 1015 regenerate_input, 1016 regenerate_biases, 1017 schema_file, 1018 x_in=5, 1019 y_in=1, 1020 randmin=INT8_MIN, 1021 randmax=INT8_MAX, 1022 int16xint8=False, 1023 inInt8outInt16=False, 1024 input_scale=0.003922, 1025 input_zp=-128): 1026 super().__init__(dataset, 1027 testtype, 1028 regenerate_weights, 1029 regenerate_input, 1030 regenerate_biases, 1031 schema_file, 1032 1, 1033 1, 1034 x_in, 1035 y_in, 1036 1, 1037 1, 1038 1, 1039 1, 1040 False, 1041 randmin, 1042 randmax, 1043 int16xint8=int16xint8) 1044 self.x_input = self.x_output = x_in 1045 self.y_input = self.y_output = y_in 1046 self.inInt8outInt16 = inInt8outInt16 1047 1048 if self.inInt8outInt16 and self.is_int16xint8: 1049 raise RuntimeError("Specify input as either s8 or s16") 1050 1051 if self.inInt8outInt16: 1052 self.input_scale = input_scale 1053 self.json_template = "TestCases/Common/Softmax/softmax_int8_to_int16_template.json" 1054 self.json_replacements = { 1055 "num_rows": self.y_input, 1056 "row_size": self.x_input, 1057 "input_scale": input_scale, 1058 "input_zp": input_zp 1059 } 1060 1061 def calc_softmax_params(self): 1062 if self.is_int16xint8: 1063 input_scale_beta_rescale = self.input_scale / (10.0 / 65535.0) 1064 (self.input_multiplier, self.input_left_shift) = self.quantize_scale(input_scale_beta_rescale) 1065 else: 1066 input_real_multiplier = min(self.input_scale * (1 << (31 - self.softmax_input_integer_bits)), (1 << 31) - 1) 1067 (self.input_multiplier, self.input_left_shift) = self.quantize_scale(input_real_multiplier) 1068 1069 self.diff_min = ((1 << self.softmax_input_integer_bits) - 1) * \ 1070 (1 << (31 - self.softmax_input_integer_bits)) / \ 1071 (1 << self.input_left_shift) 1072 self.diff_min = math.floor(self.diff_min) 1073 1074 def write_c_config_header(self) -> None: 1075 super().write_c_config_header(write_common_parameters=False) 1076 1077 filename = self.config_data 1078 filepath = self.headers_dir + filename 1079 prefix = self.testdataset.upper() 1080 1081 with open(filepath, "a") as f: 1082 f.write("#define {}_NUM_ROWS {}\n".format(prefix, self.y_input)) 1083 f.write("#define {}_ROW_SIZE {}\n".format(prefix, self.x_input)) 1084 f.write("#define {}_INPUT_MULT {}\n".format(prefix, self.input_multiplier)) 1085 f.write("#define {}_INPUT_LEFT_SHIFT {}\n".format(prefix, self.input_left_shift)) 1086 if not self.is_int16xint8: 1087 f.write("#define {}_DIFF_MIN {}\n".format(prefix, -self.diff_min)) 1088 f.write("#define {}_DST_SIZE {}\n".format(prefix, self.x_output * self.y_output)) 1089 1090 def get_softmax_randomized_input_data(self, input_data, input_shape): 1091 # Generate or load saved input data unless hardcoded data provided. 1092 if input_data is not None: 1093 input_data = tf.reshape(input_data, input_shape) 1094 else: 1095 input_data = self.get_randomized_data(input_shape, 1096 self.inputs_table_file, 1097 regenerate=self.regenerate_new_input) 1098 return input_data 1099 1100 def generate_data(self, input_data=None, weights=None, biases=None) -> None: 1101 input_data = self.get_softmax_randomized_input_data(input_data, [self.y_input, self.x_input]) 1102 1103 if self.is_int16xint8: 1104 inttype = tf.int16 1105 datatype = "int16_t" 1106 else: 1107 inttype = tf.int8 1108 datatype = "int8_t" 1109 1110 self.generate_c_array(self.input_data_file_prefix, input_data, datatype=datatype) 1111 1112 # Generate reference. 1113 if self.inInt8outInt16: 1114 # Output is int16. 1115 datatype = "int16_t" 1116 1117 # Keras does not support int8 input and int16 output for Softmax. 1118 # Using a template json instead. 1119 generated_json = self.generate_json_from_template() 1120 self.flatc_generate_tflite(generated_json, self.schema_file) 1121 1122 interpreter = Interpreter(model_path=str(self.model_path_tflite), 1123 experimental_op_resolver_type=OpResolverType.BUILTIN_REF) 1124 interpreter.allocate_tensors() 1125 all_layers_details = interpreter.get_tensor_details() 1126 input_layer = all_layers_details[0] 1127 output_layer = all_layers_details[1] 1128 1129 interpreter.set_tensor(input_layer["index"], tf.cast(input_data, tf.int8)) 1130 interpreter.invoke() 1131 output_data = interpreter.get_tensor(output_layer["index"]) 1132 else: 1133 # Create a one-layer Keras model. 1134 model = tf.keras.models.Sequential() 1135 input_shape = (self.y_input, self.x_input) 1136 model.add(tf.keras.layers.Softmax(input_shape=input_shape)) 1137 1138 interpreter = self.convert_and_interpret(model, inttype, tf.expand_dims(input_data, axis=0)) 1139 output_details = interpreter.get_output_details() 1140 interpreter.invoke() 1141 output_data = interpreter.get_tensor(output_details[0]["index"]) 1142 1143 self.calc_softmax_params() 1144 self.generate_c_array(self.output_data_file_prefix, output_data, datatype=datatype) 1145 1146 self.write_c_config_header() 1147 self.write_c_header_wrapper() 1148 1149 1150class SVDFSettings(TestSettings): 1151 1152 def __init__(self, 1153 dataset, 1154 testtype, 1155 regenerate_weights, 1156 regenerate_input, 1157 regenerate_biases, 1158 schema_file, 1159 batches=2, 1160 number_inputs=2, 1161 rank=8, 1162 memory_size=10, 1163 randmin=INT8_MIN, 1164 randmax=INT8_MAX, 1165 input_size=3, 1166 number_units=4, 1167 generate_bias=True, 1168 int8_time_weights=False, 1169 input_scale=0.1, 1170 input_zp=0, 1171 w_1_scale=0.005, 1172 w_1_zp=0, 1173 w_2_scale=0.005, 1174 w_2_zp=0, 1175 bias_scale=0.000001, 1176 bias_zp=0, 1177 state_scale=0.005, 1178 state_zp=0, 1179 output_scale=0.1, 1180 output_zp=0): 1181 super().__init__(dataset, 1182 testtype, 1183 regenerate_weights, 1184 regenerate_input, 1185 regenerate_biases, 1186 schema_file, 1187 1, 1188 1, 1189 1, 1190 1, 1191 1, 1192 1, 1193 1, 1194 1, 1195 False, 1196 randmin, 1197 randmax, 1198 generate_bias=generate_bias) 1199 self.batches = batches 1200 self.number_units = number_units 1201 self.input_size = input_size 1202 self.memory_size = memory_size 1203 self.rank = rank 1204 self.number_filters = self.number_units * self.rank 1205 self.time_table_file = self.pregenerated_data_dir + self.testdataset + '/' + 'time_data.txt' 1206 1207 self.number_inputs = number_inputs 1208 self.input_sequence_length = self.number_inputs * self.input_size * self.batches 1209 1210 self.in_activation_max = INT16_MAX 1211 self.in_activation_min = INT16_MIN 1212 1213 self.int8_time_weights = int8_time_weights 1214 1215 if self.int8_time_weights: 1216 self.json_template = "TestCases/Common/svdf_s8_weights_template.json" 1217 else: 1218 self.json_template = "TestCases/Common/svdf_template.json" 1219 1220 self.json_replacements = { 1221 "memory_sizeXnumber_filters": self.memory_size * self.number_filters, 1222 "batches": self.batches, 1223 "input_size": self.input_size, 1224 "number_filters": self.number_filters, 1225 "memory_size": self.memory_size, 1226 "number_units": self.number_units, 1227 "rank_value": self.rank, 1228 "input_scale": input_scale, 1229 "input_zp": input_zp, 1230 "w_1_scale": w_1_scale, 1231 "w_1_zp": w_1_zp, 1232 "w_2_scale": w_2_scale, 1233 "w_2_zp": w_2_zp, 1234 "bias_scale": bias_scale, 1235 "bias_zp": bias_zp, 1236 "state_scale": state_scale, 1237 "state_zp": state_zp, 1238 "output_scale": output_scale, 1239 "output_zp": output_zp 1240 } 1241 1242 def calc_multipliers_and_shifts(self, input_scale, weights_1_scale, weights_2_scale, state_scale, output_scale): 1243 effective_scale_1 = weights_1_scale * input_scale / state_scale 1244 effective_scale_2 = state_scale * weights_2_scale / output_scale 1245 (self.multiplier_in, self.shift_1) = self.quantize_scale(effective_scale_1) 1246 (self.multiplier_out, self.shift_2) = self.quantize_scale(effective_scale_2) 1247 1248 def write_c_config_header(self) -> None: 1249 super().write_c_config_header(write_common_parameters=False) 1250 1251 filename = self.config_data 1252 filepath = self.headers_dir + filename 1253 prefix = self.testdataset.upper() 1254 1255 with open(filepath, "a") as f: 1256 f.write("#define {}_MULTIPLIER_IN {}\n".format(prefix, self.multiplier_in)) 1257 f.write("#define {}_MULTIPLIER_OUT {}\n".format(prefix, self.multiplier_out)) 1258 f.write("#define {}_SHIFT_1 {}\n".format(prefix, self.shift_1)) 1259 f.write("#define {}_SHIFT_2 {}\n".format(prefix, self.shift_2)) 1260 f.write("#define {}_IN_ACTIVATION_MIN {}\n".format(prefix, self.in_activation_min)) 1261 f.write("#define {}_IN_ACTIVATION_MAX {}\n".format(prefix, self.in_activation_max)) 1262 f.write("#define {}_RANK {}\n".format(prefix, self.rank)) 1263 f.write("#define {}_FEATURE_BATCHES {}\n".format(prefix, self.number_filters)) 1264 f.write("#define {}_TIME_BATCHES {}\n".format(prefix, self.memory_size)) 1265 f.write("#define {}_INPUT_SIZE {}\n".format(prefix, self.input_size)) 1266 f.write("#define {}_DST_SIZE {}\n".format(prefix, self.number_units * self.batches)) 1267 f.write("#define {}_OUT_ACTIVATION_MIN {}\n".format(prefix, self.out_activation_min)) 1268 f.write("#define {}_OUT_ACTIVATION_MAX {}\n".format(prefix, self.out_activation_max)) 1269 f.write("#define {}_INPUT_BATCHES {}\n".format(prefix, self.batches)) 1270 f.write("#define {}_INPUT_OFFSET {}\n".format(prefix, self.input_zero_point)) 1271 f.write("#define {}_OUTPUT_OFFSET {}\n".format(prefix, self.output_zero_point)) 1272 1273 def generate_data(self, input_data=None, weights=None, biases=None, time_data=None, state_data=None) -> None: 1274 if input_data is not None: 1275 input_data = tf.reshape(input_data, [self.input_sequence_length]) 1276 else: 1277 input_data = self.get_randomized_data([self.input_sequence_length], 1278 self.inputs_table_file, 1279 regenerate=self.regenerate_new_input) 1280 self.generate_c_array("input_sequence", input_data) 1281 1282 if weights is not None: 1283 weights_feature_data = tf.reshape(weights, [self.number_filters, self.input_size]) 1284 else: 1285 weights_feature_data = self.get_randomized_data([self.number_filters, self.input_size], 1286 self.kernel_table_file, 1287 regenerate=self.regenerate_new_weights) 1288 1289 if time_data is not None: 1290 weights_time_data = tf.reshape(time_data, [self.number_filters, self.memory_size]) 1291 else: 1292 weights_time_data = self.get_randomized_data([self.number_filters, self.memory_size], 1293 self.time_table_file, 1294 regenerate=self.regenerate_new_weights) 1295 1296 if not self.generate_bias: 1297 biases = [0] * self.number_units 1298 if biases is not None: 1299 biases = tf.reshape(biases, [self.number_units]) 1300 else: 1301 biases = self.get_randomized_data([self.number_units], 1302 self.bias_table_file, 1303 regenerate=self.regenerate_new_weights) 1304 1305 # Generate tflite model 1306 generated_json = self.generate_json_from_template(weights_feature_data, 1307 weights_time_data, 1308 biases, 1309 self.int8_time_weights) 1310 self.flatc_generate_tflite(generated_json, self.schema_file) 1311 1312 # Run TFL interpreter 1313 interpreter = Interpreter(model_path=str(self.model_path_tflite), 1314 experimental_op_resolver_type=OpResolverType.BUILTIN_REF) 1315 interpreter.allocate_tensors() 1316 1317 # Read back scales and zero points from tflite model 1318 all_layers_details = interpreter.get_tensor_details() 1319 input_layer = all_layers_details[0] 1320 weights_1_layer = all_layers_details[1] 1321 weights_2_layer = all_layers_details[2] 1322 bias_layer = all_layers_details[3] 1323 state_layer = all_layers_details[4] 1324 output_layer = all_layers_details[5] 1325 (input_scale, self.input_zero_point) = self.get_scale_and_zp(input_layer) 1326 (weights_1_scale, zero_point) = self.get_scale_and_zp(weights_1_layer) 1327 (weights_2_scale, zero_point) = self.get_scale_and_zp(weights_2_layer) 1328 (bias_scale, zero_point) = self.get_scale_and_zp(bias_layer) 1329 (state_scale, zero_point) = self.get_scale_and_zp(state_layer) 1330 (output_scale, self.output_zero_point) = self.get_scale_and_zp(output_layer) 1331 1332 self.calc_multipliers_and_shifts(input_scale, weights_1_scale, weights_2_scale, state_scale, output_scale) 1333 1334 # Generate unit test C headers 1335 self.generate_c_array("weights_feature", interpreter.get_tensor(weights_1_layer['index'])) 1336 self.generate_c_array(self.bias_data_file_prefix, interpreter.get_tensor(bias_layer['index']), "int32_t") 1337 1338 if self.int8_time_weights: 1339 self.generate_c_array("weights_time", interpreter.get_tensor(weights_2_layer['index']), datatype='int8_t') 1340 self.generate_c_array("state", interpreter.get_tensor(state_layer['index']), "int8_t") 1341 else: 1342 self.generate_c_array("weights_time", interpreter.get_tensor(weights_2_layer['index']), datatype='int16_t') 1343 self.generate_c_array("state", interpreter.get_tensor(state_layer['index']), "int16_t") 1344 1345 # TODO: generate output reference with int8 time weights. 1346 if self.int8_time_weights: 1347 self.write_c_config_header() 1348 self.write_c_header_wrapper() 1349 return 1350 1351 # Generate reference output 1352 svdf_ref = None 1353 for i in range(self.number_inputs): 1354 start = i * self.input_size * self.batches 1355 end = i * self.input_size * self.batches + self.input_size * self.batches 1356 input_sequence = input_data[start:end] 1357 input_sequence = tf.reshape(input_sequence, [self.batches, self.input_size]) 1358 interpreter.set_tensor(input_layer["index"], tf.cast(input_sequence, tf.int8)) 1359 interpreter.invoke() 1360 svdf_ref = interpreter.get_tensor(output_layer["index"]) 1361 self.generate_c_array(self.output_data_file_prefix, svdf_ref) 1362 1363 self.write_c_config_header() 1364 self.write_c_header_wrapper() 1365 1366 def get_scale_and_zp(self, layer): 1367 return (layer['quantization_parameters']['scales'][0], layer['quantization_parameters']['zero_points'][0]) 1368 1369 1370class AddMulSettings(TestSettings): 1371 1372 def __init__(self, 1373 dataset, 1374 testtype, 1375 regenerate_weights, 1376 regenerate_input, 1377 regenerate_biases, 1378 schema_file, 1379 channels=1, 1380 x_in=4, 1381 y_in=4, 1382 decimal_input=6, 1383 randmin=INT8_MIN, 1384 randmax=INT8_MAX, 1385 out_activation_min=INT8_MIN, 1386 out_activation_max=INT8_MAX, 1387 int16xint8=False): 1388 super().__init__(dataset, 1389 testtype, 1390 regenerate_weights, 1391 regenerate_input, 1392 regenerate_biases, 1393 schema_file, 1394 in_ch=channels, 1395 out_ch=channels, 1396 x_in=x_in, 1397 y_in=y_in, 1398 w_x=1, 1399 w_y=1, 1400 stride_x=1, 1401 stride_y=1, 1402 pad=False, 1403 randmin=randmin, 1404 randmax=randmax, 1405 batches=1, 1406 generate_bias=False, 1407 relu6=False, 1408 out_activation_min=out_activation_min, 1409 out_activation_max=out_activation_max, 1410 int16xint8=int16xint8) 1411 1412 self.x_input = self.x_output = x_in 1413 self.y_input = self.y_output = y_in 1414 self.decimal_input = decimal_input 1415 1416 self.left_shift = 15 if self.is_int16xint8 else 20 1417 1418 def generate_data(self, input_data1=None, input_data2=None) -> None: 1419 input_shape = (1, self.y_input, self.x_input, self.input_ch) 1420 1421 input_data1 = self.get_randomized_data(list(input_shape), 1422 self.inputs_table_file, 1423 regenerate=self.regenerate_new_input, 1424 decimals=self.decimal_input) 1425 input_data2 = self.get_randomized_data(list(input_shape), 1426 self.kernel_table_file, 1427 regenerate=self.regenerate_new_weights, 1428 decimals=self.decimal_input) 1429 1430 if self.is_int16xint8: 1431 inttype = "int16_t" 1432 inttype_tf = tf.int16 1433 else: 1434 inttype = "int8_t" 1435 inttype_tf = tf.int8 1436 1437 # Create a one-layer functional Keras model as add/mul cannot use a sequntial Keras model. 1438 input1 = tf.keras.layers.Input(shape=input_shape[1:]) 1439 input2 = tf.keras.layers.Input(shape=input_shape[1:]) 1440 if self.test_type == 'add': 1441 layer = tf.keras.layers.Add()([input1, input2]) 1442 elif self.test_type == 'mul': 1443 layer = tf.keras.layers.Multiply()([input1, input2]) 1444 else: 1445 raise RuntimeError("Wrong test type") 1446 out = tf.keras.layers.Lambda(function=lambda x: x)(layer) 1447 model = tf.keras.models.Model(inputs=[input1, input2], outputs=out) 1448 1449 interpreter = self.convert_and_interpret(model, inttype_tf) 1450 1451 input_details = interpreter.get_input_details() 1452 interpreter.set_tensor(input_details[0]["index"], tf.cast(input_data1, inttype_tf)) 1453 interpreter.set_tensor(input_details[1]["index"], tf.cast(input_data2, inttype_tf)) 1454 1455 # Calculate multipliers, shifts and offsets. 1456 (input1_scale, self.input1_zero_point) = input_details[0]['quantization'] 1457 (input2_scale, self.input2_zero_point) = input_details[1]['quantization'] 1458 self.input1_zero_point = -self.input1_zero_point 1459 self.input2_zero_point = -self.input2_zero_point 1460 double_max_input_scale = max(input1_scale, input2_scale) * 2 1461 (self.input1_mult, self.input1_shift) = self.quantize_scale(input1_scale / double_max_input_scale) 1462 (self.input2_mult, self.input2_shift) = self.quantize_scale(input2_scale / double_max_input_scale) 1463 1464 if self.test_type == 'add': 1465 actual_output_scale = double_max_input_scale / ((1 << self.left_shift) * self.output_scale) 1466 elif self.test_type == 'mul': 1467 actual_output_scale = input1_scale * input2_scale / self.output_scale 1468 (self.output_mult, self.output_shift) = self.quantize_scale(actual_output_scale) 1469 1470 # Generate reference. 1471 interpreter.invoke() 1472 output_details = interpreter.get_output_details() 1473 output_data = interpreter.get_tensor(output_details[0]["index"]) 1474 self.generate_c_array("input1", input_data1, datatype=inttype) 1475 self.generate_c_array("input2", input_data2, datatype=inttype) 1476 self.generate_c_array(self.output_data_file_prefix, 1477 np.clip(output_data, self.out_activation_min, self.out_activation_max), 1478 datatype=inttype) 1479 1480 self.write_c_config_header() 1481 self.write_c_header_wrapper() 1482 1483 def write_c_config_header(self) -> None: 1484 super().write_c_config_header(write_common_parameters=False) 1485 1486 filename = self.config_data 1487 filepath = self.headers_dir + filename 1488 prefix = self.testdataset.upper() 1489 1490 with open(filepath, "a") as f: 1491 f.write("#define {}_DST_SIZE {}\n".format(prefix, 1492 self.batches * self.y_input * self.x_input * self.input_ch)) 1493 f.write("#define {}_OUT_ACTIVATION_MIN {}\n".format(prefix, self.out_activation_min)) 1494 f.write("#define {}_OUT_ACTIVATION_MAX {}\n".format(prefix, self.out_activation_max)) 1495 f.write("#define {}_INPUT1_OFFSET {}\n".format(prefix, self.input1_zero_point)) 1496 f.write("#define {}_INPUT2_OFFSET {}\n".format(prefix, self.input2_zero_point)) 1497 f.write("#define {}_OUTPUT_MULT {}\n".format(prefix, self.output_mult)) 1498 f.write("#define {}_OUTPUT_SHIFT {}\n".format(prefix, self.output_shift)) 1499 f.write("#define {}_OUTPUT_OFFSET {}\n".format(prefix, self.output_zero_point)) 1500 if self.test_type == 'add': 1501 f.write("#define {}_LEFT_SHIFT {}\n".format(prefix, self.left_shift)) 1502 f.write("#define {}_INPUT1_SHIFT {}\n".format(prefix, self.input1_shift)) 1503 f.write("#define {}_INPUT2_SHIFT {}\n".format(prefix, self.input2_shift)) 1504 f.write("#define {}_INPUT1_MULT {}\n".format(prefix, self.input1_mult)) 1505 f.write("#define {}_INPUT2_MULT {}\n".format(prefix, self.input2_mult)) 1506 1507 1508class LSTMSettings(TestSettings): 1509 1510 def __init__(self, 1511 dataset, 1512 testtype, 1513 regenerate_weights, 1514 regenerate_input, 1515 regenerate_biases, 1516 schema_file, 1517 batches=2, 1518 time_steps=2, 1519 number_inputs=3, 1520 number_units=4, 1521 time_major=True, 1522 randmin=INT8_MIN, 1523 randmax=INT8_MAX, 1524 generate_bias=True): 1525 super().__init__(dataset, 1526 testtype, 1527 regenerate_weights, 1528 regenerate_input, 1529 regenerate_biases, 1530 schema_file, 1531 1, 1532 1, 1533 1, 1534 1, 1535 1, 1536 1, 1537 1, 1538 1, 1539 False, 1540 randmin, 1541 randmax, 1542 generate_bias=generate_bias) 1543 1544 self.batches = batches 1545 self.time_steps = time_steps 1546 self.number_units = number_units 1547 self.number_inputs = number_inputs 1548 1549 self.kernel_hidden_table_file = self.pregenerated_data_dir + self.testdataset + '/' + 'kernel_hidden.txt' 1550 1551 self.time_major = time_major 1552 1553 self.in_activation_max = INT16_MAX 1554 self.in_activation_min = INT16_MIN 1555 1556 self.lstm_scales = [] 1557 1558 # Layer indexes. Works with tensorflow 2.10 and 2.11. 1559 self.output_gate_bias_index = 1 1560 self.cell_gate_bias_index = 2 1561 self.forget_gate_bias_index = 3 1562 self.input_gate_bias_index = 4 1563 self.recurrent_input_to_output_w_index = 5 1564 self.recurrent_input_to_cell_w_index = 6 1565 self.recurrent_input_to_forget_w_index = 7 1566 self.recurrent_input_to_input_w_index = 8 1567 self.input_to_output_w_index = 9 1568 self.input_to_cell_w_index = 10 1569 self.input_to_forget_w_index = 11 1570 self.input_to_input_w_index = 12 1571 self.output_state_index = 13 1572 self.cell_state_index = 14 1573 self.input_norm_coeff_index = 15 1574 self.forget_norm_coeff_index = 16 1575 self.cell_norm_coeff_index = 17 1576 self.output_norm_coeff_index = 18 1577 self.effective_hidden_scale_intermediate_index = 20 1578 1579 def generate_data(self, input_data=None, weights=None, hidden_weights=None, biases=None) -> None: 1580 1581 input_dims = [self.batches, self.time_steps, self.number_inputs] 1582 if input_data is not None: 1583 input_data = tf.reshape(input_data, input_dims) 1584 else: 1585 input_data = self.get_randomized_data(input_dims, 1586 self.inputs_table_file, 1587 regenerate=self.regenerate_new_input) 1588 1589 # This will be the same size when there is no projection. 1590 number_cells = self.number_units 1591 1592 # Each LSTM cell has 4 input weights, 4 hidden (recurrent or cell state) weights and 4 biases. 1593 number_w_b = 4 1594 1595 if weights is not None: 1596 weights = tf.reshape(weights, [self.number_inputs, number_cells * number_w_b]) 1597 else: 1598 weights = self.get_randomized_data([self.number_inputs, number_cells * number_w_b], 1599 self.kernel_table_file, 1600 regenerate=self.regenerate_new_weights, 1601 decimals=8, 1602 minrange=-1.0, 1603 maxrange=1.0) 1604 1605 if hidden_weights is not None: 1606 hidden_weights = tf.reshape(hidden_weights, [number_cells, number_cells * number_w_b]) 1607 else: 1608 hidden_weights = self.get_randomized_data([number_cells, number_cells * number_w_b], 1609 self.kernel_hidden_table_file, 1610 regenerate=self.regenerate_new_weights, 1611 decimals=8, 1612 minrange=-1.0, 1613 maxrange=1.0) 1614 if not self.generate_bias: 1615 biases = [0] * number_cells * number_w_b 1616 if biases is not None: 1617 biases = tf.reshape(biases, [number_cells * number_w_b]) 1618 else: 1619 biases = self.get_randomized_data([number_cells * number_w_b], 1620 self.bias_table_file, 1621 regenerate=self.regenerate_new_bias, 1622 decimals=8, 1623 minrange=-1.0, 1624 maxrange=1.0) 1625 1626 # Create a Keras based LSTM model. 1627 input_layer = tf.keras.layers.Input(shape=(self.time_steps, self.number_inputs), 1628 batch_size=self.batches, 1629 name='input') 1630 if self.time_major: 1631 input_layer_transposed = tf.transpose(input_layer, perm=[1, 0, 2]) 1632 lstm_layer = tf.keras.layers.LSTM(units=self.number_units, 1633 time_major=self.time_major, 1634 return_sequences=True)(input_layer_transposed) 1635 else: 1636 lstm_layer = tf.keras.layers.LSTM(units=self.number_units, 1637 time_major=self.time_major, 1638 return_sequences=True)(input_layer) 1639 model = tf.keras.Model(input_layer, lstm_layer, name="LSTM") 1640 1641 if self.time_major: 1642 time_major_offset = 1 1643 shape = (self.time_steps, self.batches, self.number_inputs) 1644 else: 1645 time_major_offset = 0 1646 shape = (self.batches, self.time_steps, self.number_inputs) 1647 1648 # Writing weight and bias to model. 1649 print("Updating weights", model.layers[1 + time_major_offset].weights[0].name) 1650 model.layers[1 + time_major_offset].weights[0].assign(weights) 1651 print("Updating hidden weights", model.layers[1 + time_major_offset].weights[1].name) 1652 model.layers[1 + time_major_offset].weights[1].assign(hidden_weights) 1653 print("Updating bias", model.layers[1 + time_major_offset].weights[2].name) 1654 model.layers[1 + time_major_offset].weights[2].assign(biases) 1655 1656 interpreter = self.convert_and_interpret(model, tf.int8, input_data, dataset_shape=shape) 1657 1658 all_layers_details = interpreter.get_tensor_details() 1659 1660 for i in all_layers_details: 1661 self.lstm_scales.append(i['quantization_parameters']['scales']) 1662 1663 input_data_for_index = all_layers_details[0] 1664 1665 input_gate_bias = all_layers_details[self.input_gate_bias_index + time_major_offset] 1666 forget_gate_bias = all_layers_details[self.forget_gate_bias_index + time_major_offset] 1667 cell_gate_bias = all_layers_details[self.cell_gate_bias_index + time_major_offset] 1668 output_gate_bias = all_layers_details[self.output_gate_bias_index + time_major_offset] 1669 1670 input_to_input_w = all_layers_details[self.input_to_input_w_index + time_major_offset] 1671 input_to_forget_w = all_layers_details[self.input_to_forget_w_index + time_major_offset] 1672 input_to_cell_w = all_layers_details[self.input_to_cell_w_index + time_major_offset] 1673 input_to_output_w = all_layers_details[self.input_to_output_w_index + time_major_offset] 1674 1675 recurrent_input_to_input_w = all_layers_details[self.recurrent_input_to_input_w_index + time_major_offset] 1676 recurrent_input_to_forget_w = all_layers_details[self.recurrent_input_to_forget_w_index + time_major_offset] 1677 recurrent_input_to_cell_w = all_layers_details[self.recurrent_input_to_cell_w_index + time_major_offset] 1678 recurrent_input_to_output_w = all_layers_details[self.recurrent_input_to_output_w_index + time_major_offset] 1679 1680 if self.time_major: 1681 time_major_offset = 2 1682 1683 output_state = all_layers_details[self.output_state_index + time_major_offset] 1684 cell_state = all_layers_details[self.cell_state_index + time_major_offset] 1685 1686 input_norm_coeff = all_layers_details[self.input_norm_coeff_index + time_major_offset] 1687 forget_norm_coeff = all_layers_details[self.forget_norm_coeff_index + time_major_offset] 1688 cell_norm_coeff = all_layers_details[self.cell_norm_coeff_index + time_major_offset] 1689 output_norm_coeff = all_layers_details[self.output_norm_coeff_index + time_major_offset] 1690 1691 # For scale and zero point. 1692 effective_hidden_scale_intermediate = all_layers_details[self.effective_hidden_scale_intermediate_index + 1693 time_major_offset] 1694 1695 input_details = interpreter.get_input_details() 1696 output_details = interpreter.get_output_details() 1697 actual_input_data = interpreter.get_tensor(input_details[0]["index"]) 1698 if (input_data.numpy().shape != actual_input_data.shape) or \ 1699 not ((input_data.numpy().astype(int) == actual_input_data).all().astype(int)): 1700 raise RuntimeError("Input data mismatch") 1701 1702 self.generate_c_array(self.input_data_file_prefix, interpreter.get_tensor(input_data_for_index['index'])) 1703 self.generate_c_array("input_to_input_w", interpreter.get_tensor(input_to_input_w['index'])) 1704 self.generate_c_array("input_to_forget_w", interpreter.get_tensor(input_to_forget_w['index'])) 1705 self.generate_c_array("input_to_cell_w", interpreter.get_tensor(input_to_cell_w['index'])) 1706 self.generate_c_array("input_to_output_w", interpreter.get_tensor(input_to_output_w['index'])) 1707 self.generate_c_array("recurrent_input_to_input_w", interpreter.get_tensor(recurrent_input_to_input_w['index'])) 1708 self.generate_c_array("recurrent_input_to_forget_w", 1709 interpreter.get_tensor(recurrent_input_to_forget_w['index'])) 1710 self.generate_c_array("recurrent_input_to_cell_w", interpreter.get_tensor(recurrent_input_to_cell_w['index'])) 1711 self.generate_c_array("recurrent_input_to_output_w", 1712 interpreter.get_tensor(recurrent_input_to_output_w['index'])) 1713 1714 # Peephole not supported so these are nullptrs. 1715 self.generate_c_array("cell_to_input", [], datatype='int16_t') 1716 self.generate_c_array("cell_to_forget", [], datatype='int16_t') 1717 self.generate_c_array("cell_to_output", [], datatype='int16_t') 1718 1719 self.generate_c_array("input_gate_bias", interpreter.get_tensor(input_gate_bias['index']), datatype='int32_t') 1720 self.generate_c_array("cell_gate_bias", interpreter.get_tensor(cell_gate_bias['index']), datatype='int32_t') 1721 self.generate_c_array("forget_gate_bias", interpreter.get_tensor(forget_gate_bias['index']), datatype='int32_t') 1722 self.generate_c_array("output_gate_bias", interpreter.get_tensor(output_gate_bias['index']), datatype='int32_t') 1723 1724 # Projection not supported so these are nullptrs. 1725 self.generate_c_array("projection_weights", []) 1726 self.generate_c_array("projection_bias", [], datatype='int32_t') 1727 1728 self.generate_c_array("output_state", interpreter.get_tensor(output_state['index']), const="") 1729 self.generate_c_array("cell_state", interpreter.get_tensor(cell_state['index']), datatype='int16_t', const="") 1730 1731 self.generate_c_array("input_norm_coeff", interpreter.get_tensor(input_norm_coeff['index'])) 1732 self.generate_c_array("forget_norm_coeff", interpreter.get_tensor(forget_norm_coeff['index'])) 1733 self.generate_c_array("cell_norm_coeff", interpreter.get_tensor(cell_norm_coeff['index'])) 1734 self.generate_c_array("output_norm_coeff", interpreter.get_tensor(output_norm_coeff['index'])) 1735 1736 input_scale = input_data_for_index['quantization_parameters']['scales'][0] 1737 cell_scale = cell_state['quantization_parameters']['scales'][0] 1738 output_state_scale = output_state['quantization_parameters']['scales'][0] 1739 input_zp = input_data_for_index['quantization_parameters']['zero_points'][0] 1740 output_zp = output_details[0]['quantization_parameters']['zero_points'][0] 1741 output_state_zp = output_state['quantization_parameters']['zero_points'][0] 1742 self.hidden_zp = effective_hidden_scale_intermediate['quantization_parameters']['zero_points'][0] 1743 self.output_state_offset = output_state_zp 1744 1745 tmp = math.log(cell_scale) * (1 / math.log(2)) 1746 self.cell_state_shift = int(round(tmp)) 1747 1748 self.calc_scales(input_scale, output_state_scale) 1749 1750 # Calculate effective biases. 1751 input_zp = -input_zp 1752 output_zp = -output_zp 1753 output_state_zp = -output_state_zp 1754 input_to_forget_eff_bias = self.calc_effective_bias(interpreter, input_zp, input_to_forget_w, forget_gate_bias) 1755 recurrent_to_forget_eff_bias = self.calc_effective_bias(interpreter, output_state_zp, 1756 recurrent_input_to_forget_w, None, False) 1757 input_to_cell_eff_bias = self.calc_effective_bias(interpreter, input_zp, input_to_cell_w, cell_gate_bias) 1758 recurrent_to_cell_eff_bias = self.calc_effective_bias(interpreter, output_state_zp, recurrent_input_to_cell_w, 1759 None, False) 1760 input_to_output_eff_bias = self.calc_effective_bias(interpreter, input_zp, input_to_output_w, output_gate_bias) 1761 recurrent_to_output_eff_bias = self.calc_effective_bias(interpreter, output_state_zp, 1762 recurrent_input_to_output_w, None, False) 1763 input_to_input_eff_bias = self.calc_effective_bias(interpreter, input_zp, input_to_input_w, input_gate_bias) 1764 1765 recurrent_to_input_eff_bias = self.calc_effective_bias(interpreter, output_state_zp, recurrent_input_to_input_w, 1766 None, False) 1767 1768 self.generate_c_array("input_to_input_eff_bias", input_to_input_eff_bias, datatype='int32_t') 1769 self.generate_c_array("input_to_forget_eff_bias", input_to_forget_eff_bias, datatype='int32_t') 1770 self.generate_c_array("input_to_cell_eff_bias", input_to_cell_eff_bias, datatype='int32_t') 1771 self.generate_c_array("input_to_output_eff_bias", input_to_output_eff_bias, datatype='int32_t') 1772 self.generate_c_array("recurrent_to_input_eff_bias", recurrent_to_input_eff_bias, datatype='int32_t') 1773 self.generate_c_array("recurrent_to_cell_eff_bias", recurrent_to_cell_eff_bias, datatype='int32_t') 1774 self.generate_c_array("recurrent_to_forget_eff_bias", recurrent_to_forget_eff_bias, datatype='int32_t') 1775 self.generate_c_array("recurrent_to_output_eff_bias", recurrent_to_output_eff_bias, datatype='int32_t') 1776 1777 # Generate reference 1778 interpreter.invoke() 1779 output_data = interpreter.get_tensor(output_details[0]["index"]) 1780 self.generate_c_array(self.output_data_file_prefix, output_data, datatype='int8_t') 1781 1782 self.write_c_config_header() 1783 self.write_c_header_wrapper() 1784 1785 def calc_scales(self, input_scale, output_state_scale): 1786 intermediate_scale = pow(2, -12) 1787 1788 if self.time_major: 1789 time_major_offset = 1 1790 else: 1791 time_major_offset = 0 1792 1793 self.effective_hidden_scale = pow(2, -15) / output_state_scale * pow(2, -15) 1794 1795 self.i2i_effective_scale = input_scale * self.lstm_scales[self.input_to_input_w_index + time_major_offset][0] \ 1796 / intermediate_scale 1797 self.i2f_effective_scale = input_scale * self.lstm_scales[self.input_to_forget_w_index + time_major_offset][0] \ 1798 / intermediate_scale 1799 self.i2c_effective_scale = input_scale * self.lstm_scales[self.input_to_cell_w_index + time_major_offset][0] \ 1800 / intermediate_scale 1801 self.i2o_effective_scale = input_scale * self.lstm_scales[self.input_to_output_w_index + time_major_offset][0] \ 1802 / intermediate_scale 1803 1804 self.r2i_effective_scale = output_state_scale * self.lstm_scales[self.recurrent_input_to_input_w_index + 1805 time_major_offset][0] / intermediate_scale 1806 self.r2f_effective_scale = output_state_scale * self.lstm_scales[self.recurrent_input_to_forget_w_index + 1807 time_major_offset][0] / intermediate_scale 1808 self.r2c_effective_scale = output_state_scale * self.lstm_scales[self.recurrent_input_to_cell_w_index + 1809 time_major_offset][0] / intermediate_scale 1810 self.r2o_effective_scale = output_state_scale * self.lstm_scales[self.recurrent_input_to_output_w_index + 1811 time_major_offset][0] / intermediate_scale 1812 1813 def calc_effective_bias(self, interpreter, zero_point, weight_tensor, bias_tensor, has_bias=True) -> list: 1814 1815 weights = interpreter.get_tensor(weight_tensor['index']) 1816 dims = weight_tensor['shape'] 1817 row = dims[0] 1818 col = dims[1] 1819 1820 if has_bias: 1821 bias_data = interpreter.get_tensor(bias_tensor['index']) 1822 output = bias_data 1823 else: 1824 output = np.zeros((row, ), dtype=np.int32) 1825 1826 for i_row in range(row): 1827 row_sum = 0 1828 for i_col in range(col): 1829 row_sum = row_sum + weights[i_row][i_col] 1830 output[i_row] = output[i_row] + row_sum * zero_point 1831 1832 return output 1833 1834 def write_c_config_header(self) -> None: 1835 super().write_c_config_header(write_common_parameters=False) 1836 1837 filename = self.config_data 1838 filepath = self.headers_dir + filename 1839 prefix = self.testdataset.upper() 1840 1841 with open(filepath, "a") as f: 1842 f.write("#define {}_BUFFER_SIZE {}\n".format(prefix, self.batches * self.number_units)) 1843 f.write("#define {}_INPUT_BATCHES {}\n".format(prefix, self.batches)) 1844 f.write("#define {}_DST_SIZE {}\n".format(prefix, self.batches * self.time_steps * self.number_units)) 1845 f.write("#define {}_TIME_STEPS {}\n".format(prefix, self.time_steps)) 1846 f.write("#define {}_NUMBER_UNITS {}\n".format(prefix, self.number_units)) 1847 f.write("#define {}_NUMBER_INPUTS {}\n".format(prefix, self.number_inputs)) 1848 f.write("#define {}_TIME_MAJOR {}\n".format(prefix, int(self.time_major))) 1849 f.write("#define {}_IN_ACTIVATION_MIN {}\n".format(prefix, self.in_activation_min)) 1850 f.write("#define {}_IN_ACTIVATION_MAX {}\n".format(prefix, self.in_activation_max)) 1851 1852 (multiplier, shift) = self.quantize_scale(self.i2i_effective_scale) 1853 f.write("#define {}_IN_TO_INPUT_MULTIPLIER {}\n".format(prefix, multiplier)) 1854 f.write("#define {}_IN_TO_INPUT_SHIFT {}\n".format(prefix, shift)) 1855 (multiplier, shift) = self.quantize_scale(self.i2f_effective_scale) 1856 f.write("#define {}_IN_TO_FORGET_MULTIPLIER {}\n".format(prefix, multiplier)) 1857 f.write("#define {}_IN_TO_FORGET_SHIFT {}\n".format(prefix, shift)) 1858 (multiplier, shift) = self.quantize_scale(self.i2c_effective_scale) 1859 f.write("#define {}_IN_TO_CELL_MULTIPLIER {}\n".format(prefix, multiplier)) 1860 f.write("#define {}_IN_TO_CELL_SHIFT {}\n".format(prefix, shift)) 1861 (multiplier, shift) = self.quantize_scale(self.i2o_effective_scale) 1862 f.write("#define {}_IN_TO_OUTPUT_MULTIPLIER {}\n".format(prefix, multiplier)) 1863 f.write("#define {}_IN_TO_OUTPUT_SHIFT {}\n".format(prefix, shift)) 1864 1865 (multiplier, shift) = self.quantize_scale(self.r2i_effective_scale) 1866 f.write("#define {}_RECURRENT_TO_INPUT_MULTIPLIER {}\n".format(prefix, multiplier)) 1867 f.write("#define {}_RECURRENT_TO_INPUT_SHIFT {}\n".format(prefix, shift)) 1868 (multiplier, shift) = self.quantize_scale(self.r2f_effective_scale) 1869 f.write("#define {}_RECURRENT_TO_FORGET_MULTIPLIER {}\n".format(prefix, multiplier)) 1870 f.write("#define {}_RECURRENT_TO_FORGET_SHIFT {}\n".format(prefix, shift)) 1871 (multiplier, shift) = self.quantize_scale(self.r2c_effective_scale) 1872 f.write("#define {}_RECURRENT_TO_CELL_MULTIPLIER {}\n".format(prefix, multiplier)) 1873 f.write("#define {}_RECURRENT_TO_CELL_SHIFT {}\n".format(prefix, shift)) 1874 (multiplier, shift) = self.quantize_scale(self.r2o_effective_scale) 1875 f.write("#define {}_RECURRENT_TO_OUTPUT_MULTIPLIER {}\n".format(prefix, multiplier)) 1876 f.write("#define {}_RECURRENT_TO_OUTPUT_SHIFT {}\n".format(prefix, shift)) 1877 1878 (multiplier, shift) = self.quantize_scale(self.effective_hidden_scale) 1879 f.write("#define {}_HIDDEN_MULTIPLIER {}\n".format(prefix, multiplier)) 1880 f.write("#define {}_HIDDEN_SHIFT {}\n".format(prefix, shift)) 1881 1882 f.write("#define {}_HIDDEN_OFFSET {}\n".format(prefix, self.hidden_zp)) 1883 1884 f.write("#define {}_OUTPUT_STATE_OFFSET {}\n".format(prefix, self.output_state_offset)) 1885 f.write("#define {}_CELL_STATE_SHIFT {}\n".format(prefix, self.cell_state_shift)) 1886 1887 for i in range(len(self.lstm_scales)): 1888 if len(self.lstm_scales[i]) == 0: 1889 continue 1890 (multiplier, shift) = self.quantize_scale(self.lstm_scales[i][0]) 1891 1892 1893def load_testdata_sets() -> dict: 1894 """ 1895 Add all new testdata sets here 1896 """ 1897 testdata_sets = {} 1898 1899 regenerate_input = args.regenerate_input 1900 regenerate_weights = args.regenerate_weights 1901 regenerate_biases = args.regenerate_biases 1902 1903 if args.regenerate_all: 1904 regenerate_biases = True 1905 regenerate_weights = True 1906 regenerate_input = True 1907 1908 schema_file = args.schema_file 1909 1910 type_of_test = 'conv' 1911 dataset = 'basic' 1912 testdata_sets[dataset] = ConvSettings(dataset, 1913 type_of_test, 1914 regenerate_weights, 1915 regenerate_input, 1916 regenerate_biases, 1917 schema_file, 1918 in_ch=1, 1919 out_ch=1, 1920 x_in=5, 1921 y_in=8, 1922 w_x=2, 1923 w_y=4, 1924 stride_x=1, 1925 stride_y=1, 1926 pad=False) 1927 dataset = 'stride2pad1' 1928 testdata_sets[dataset] = ConvSettings(dataset, 1929 type_of_test, 1930 regenerate_weights, 1931 regenerate_input, 1932 regenerate_biases, 1933 schema_file, 1934 in_ch=1, 1935 out_ch=1, 1936 x_in=7, 1937 y_in=7, 1938 w_x=3, 1939 w_y=3, 1940 stride_x=2, 1941 stride_y=2, 1942 pad=True) 1943 dataset = 'kernel1x1' 1944 testdata_sets[dataset] = ConvSettings(dataset, 1945 type_of_test, 1946 regenerate_weights, 1947 regenerate_input, 1948 regenerate_biases, 1949 schema_file, 1950 in_ch=19, 1951 out_ch=7, 1952 x_in=7, 1953 y_in=5, 1954 w_x=1, 1955 w_y=1, 1956 stride_x=1, 1957 stride_y=1, 1958 pad=False, 1959 bias_min=INT8_MIN, 1960 bias_max=INT8_MAX, 1961 out_activation_min=-126, 1962 out_activation_max=127, 1963 batches=2) 1964 dataset = 'kernel1x1_stride_x' 1965 testdata_sets[dataset] = ConvSettings(dataset, 1966 type_of_test, 1967 regenerate_weights, 1968 regenerate_input, 1969 regenerate_biases, 1970 schema_file, 1971 in_ch=9, 1972 out_ch=5, 1973 x_in=7, 1974 y_in=4, 1975 w_x=1, 1976 w_y=1, 1977 stride_x=3, 1978 stride_y=1, 1979 pad=False, 1980 out_activation_min=-126, 1981 out_activation_max=127, 1982 batches=2) 1983 dataset = 'kernel1x1_stride_x_y' 1984 testdata_sets[dataset] = ConvSettings(dataset, 1985 type_of_test, 1986 regenerate_weights, 1987 regenerate_input, 1988 regenerate_biases, 1989 schema_file, 1990 in_ch=23, 1991 out_ch=15, 1992 randmin=0, 1993 x_in=7, 1994 y_in=6, 1995 w_x=1, 1996 w_y=1, 1997 stride_x=2, 1998 stride_y=2, 1999 pad=False, 2000 out_activation_min=-6, 2001 out_activation_max=127, 2002 batches=3) 2003 dataset = 'kernel1x1_stride_x_y_1' 2004 testdata_sets[dataset] = ConvSettings(dataset, 2005 type_of_test, 2006 regenerate_weights, 2007 regenerate_input, 2008 regenerate_biases, 2009 schema_file, 2010 in_ch=5, 2011 out_ch=5, 2012 x_in=4, 2013 y_in=4, 2014 w_x=1, 2015 w_y=1, 2016 stride_x=2, 2017 stride_y=2, 2018 pad=False, 2019 out_activation_min=-126, 2020 out_activation_max=127, 2021 batches=2) 2022 dataset = 'kernel1x1_stride_x_y_2' 2023 testdata_sets[dataset] = ConvSettings(dataset, 2024 type_of_test, 2025 regenerate_weights, 2026 regenerate_input, 2027 regenerate_biases, 2028 schema_file, 2029 in_ch=5, 2030 out_ch=5, 2031 x_in=4, 2032 y_in=4, 2033 w_x=1, 2034 w_y=1, 2035 stride_x=3, 2036 stride_y=3, 2037 pad=False, 2038 out_activation_min=-126, 2039 out_activation_max=127, 2040 batches=2) 2041 dataset = 'conv_3' 2042 testdata_sets[dataset] = ConvSettings(dataset, 2043 type_of_test, 2044 regenerate_weights, 2045 regenerate_input, 2046 regenerate_biases, 2047 schema_file, 2048 in_ch=3, 2049 out_ch=1, 2050 x_in=10, 2051 y_in=49, 2052 w_x=4, 2053 w_y=10, 2054 stride_x=1, 2055 stride_y=2, 2056 pad=True, 2057 out_activation_min=-127, 2058 out_activation_max=127) 2059 dataset = 'conv_1_x_n_1' # left and right pad, no non-padded elements 2060 testdata_sets[dataset] = ConvSettings(dataset, 2061 type_of_test, 2062 regenerate_weights, 2063 regenerate_input, 2064 regenerate_biases, 2065 schema_file, 2066 in_ch=4, 2067 out_ch=3, 2068 x_in=2, 2069 y_in=1, 2070 w_x=3, 2071 w_y=1, 2072 stride_x=1, 2073 stride_y=1, 2074 pad=True, 2075 out_activation_min=-127, 2076 out_activation_max=127, 2077 batches=2) 2078 dataset = 'conv_1_x_n_2' # no pad 2079 testdata_sets[dataset] = ConvSettings(dataset, 2080 type_of_test, 2081 regenerate_weights, 2082 regenerate_input, 2083 regenerate_biases, 2084 schema_file, 2085 in_ch=4, 2086 out_ch=3, 2087 x_in=296, 2088 y_in=1, 2089 w_x=48, 2090 w_y=1, 2091 stride_x=2, 2092 stride_y=1, 2093 pad=False, 2094 out_activation_min=-111, 2095 out_activation_max=127) 2096 dataset = 'conv_1_x_n_3' 2097 testdata_sets[dataset] = ConvSettings(dataset, 2098 type_of_test, 2099 regenerate_weights, 2100 regenerate_input, 2101 regenerate_biases, 2102 schema_file, 2103 in_ch=4, 2104 out_ch=1, 2105 x_in=296, 2106 y_in=1, 2107 w_x=48, 2108 w_y=1, 2109 stride_x=2, 2110 stride_y=1, 2111 pad=True, 2112 out_activation_min=-111, 2113 out_activation_max=127) 2114 dataset = 'conv_1_x_n_4' # 0 left pad, 1 right pad 2115 testdata_sets[dataset] = ConvSettings(dataset, 2116 type_of_test, 2117 regenerate_weights, 2118 regenerate_input, 2119 regenerate_biases, 2120 schema_file, 2121 in_ch=4, 2122 out_ch=4, 2123 x_in=16, 2124 y_in=1, 2125 w_x=3, 2126 w_y=1, 2127 stride_x=2, 2128 stride_y=1, 2129 pad=True, 2130 out_activation_min=-88, 2131 out_activation_max=127) 2132 dataset = 'conv_1_x_n_5' 2133 testdata_sets[dataset] = ConvSettings(dataset, 2134 type_of_test, 2135 regenerate_weights, 2136 regenerate_input, 2137 regenerate_biases, 2138 schema_file, 2139 in_ch=4, 2140 out_ch=1, 2141 x_in=17, 2142 y_in=1, 2143 w_x=3, 2144 w_y=1, 2145 stride_x=3, 2146 stride_y=1, 2147 pad=True, 2148 out_activation_min=-88, 2149 out_activation_max=127) 2150 dataset = 'conv_2' 2151 testdata_sets[dataset] = ConvSettings(dataset, 2152 type_of_test, 2153 regenerate_weights, 2154 regenerate_input, 2155 regenerate_biases, 2156 schema_file, 2157 in_ch=2, 2158 out_ch=4, 2159 x_in=6, 2160 y_in=3, 2161 w_x=3, 2162 w_y=3, 2163 stride_x=1, 2164 stride_y=1, 2165 pad=True, 2166 out_activation_min=-101, 2167 out_activation_max=127) 2168 dataset = 'conv_4' # batches > 2 2169 testdata_sets[dataset] = ConvSettings(dataset, 2170 type_of_test, 2171 regenerate_weights, 2172 regenerate_input, 2173 regenerate_biases, 2174 schema_file, 2175 in_ch=3, 2176 out_ch=3, 2177 x_in=5, 2178 y_in=5, 2179 w_x=2, 2180 w_y=3, 2181 stride_x=2, 2182 stride_y=2, 2183 pad=False, 2184 out_activation_min=-109, 2185 out_activation_max=127, 2186 batches=3) 2187 dataset = 'conv_5' 2188 testdata_sets[dataset] = ConvSettings(dataset, 2189 type_of_test, 2190 regenerate_weights, 2191 regenerate_input, 2192 regenerate_biases, 2193 schema_file, 2194 in_ch=128, 2195 out_ch=1, 2196 x_in=128, 2197 y_in=1, 2198 w_x=3, 2199 w_y=3, 2200 stride_x=4, 2201 stride_y=4, 2202 pad=True, 2203 out_activation_min=-88, 2204 out_activation_max=127) 2205 dataset = 'conv_out_activation' 2206 testdata_sets[dataset] = ConvSettings(dataset, 2207 type_of_test, 2208 regenerate_weights, 2209 regenerate_input, 2210 regenerate_biases, 2211 schema_file, 2212 in_ch=4, 2213 out_ch=2, 2214 x_in=3, 2215 y_in=3, 2216 w_x=3, 2217 w_y=3, 2218 stride_x=1, 2219 stride_y=1, 2220 pad=True, 2221 out_activation_min=-61, 2222 out_activation_max=107) 2223 dataset = 'conv_dilation_golden' 2224 testdata_sets[dataset] = ConvSettings(dataset, 2225 type_of_test, 2226 regenerate_weights, 2227 regenerate_input, 2228 regenerate_biases, 2229 schema_file, 2230 in_ch=1, 2231 batches=2, 2232 out_ch=3, 2233 x_in=6, 2234 y_in=4, 2235 w_x=2, 2236 w_y=2, 2237 stride_x=1, 2238 stride_y=1, 2239 pad=True, 2240 out_activation_min=-128, 2241 out_activation_max=127, 2242 dilation_x=3, 2243 dilation_y=2) 2244 dataset = 'conv_2x2_dilation' 2245 testdata_sets[dataset] = ConvSettings(dataset, 2246 type_of_test, 2247 regenerate_weights, 2248 regenerate_input, 2249 regenerate_biases, 2250 schema_file, 2251 in_ch=2, 2252 out_ch=2, 2253 x_in=10, 2254 y_in=10, 2255 w_x=3, 2256 w_y=3, 2257 stride_x=1, 2258 stride_y=1, 2259 pad=False, 2260 out_activation_min=-61, 2261 out_activation_max=107, 2262 dilation_x=2, 2263 dilation_y=2) 2264 dataset = 'conv_2x3_dilation' 2265 testdata_sets[dataset] = ConvSettings(dataset, 2266 type_of_test, 2267 regenerate_weights, 2268 regenerate_input, 2269 regenerate_biases, 2270 schema_file, 2271 in_ch=2, 2272 out_ch=2, 2273 x_in=3, 2274 y_in=3, 2275 w_x=3, 2276 w_y=3, 2277 stride_x=1, 2278 stride_y=1, 2279 pad=True, 2280 out_activation_min=-61, 2281 out_activation_max=107, 2282 dilation_x=2, 2283 dilation_y=2) 2284 dataset = 'conv_3x2_dilation' 2285 testdata_sets[dataset] = ConvSettings(dataset, 2286 type_of_test, 2287 regenerate_weights, 2288 regenerate_input, 2289 regenerate_biases, 2290 schema_file, 2291 in_ch=2, 2292 out_ch=2, 2293 x_in=3, 2294 y_in=3, 2295 w_x=3, 2296 w_y=3, 2297 stride_x=1, 2298 stride_y=1, 2299 pad=True, 2300 out_activation_min=-61, 2301 out_activation_max=107, 2302 dilation_x=3, 2303 dilation_y=2) 2304 dataset = 'conv_2x2_dilation_5x5_input' 2305 testdata_sets[dataset] = ConvSettings(dataset, 2306 type_of_test, 2307 regenerate_weights, 2308 regenerate_input, 2309 regenerate_biases, 2310 schema_file, 2311 in_ch=2, 2312 out_ch=2, 2313 x_in=5, 2314 y_in=5, 2315 w_x=3, 2316 w_y=3, 2317 stride_x=1, 2318 stride_y=1, 2319 pad=True, 2320 out_activation_min=-61, 2321 out_activation_max=107, 2322 dilation_x=2, 2323 dilation_y=2) 2324 dataset = 'conv_3x3_dilation_5x5_input' 2325 testdata_sets[dataset] = ConvSettings(dataset, 2326 type_of_test, 2327 regenerate_weights, 2328 regenerate_input, 2329 regenerate_biases, 2330 schema_file, 2331 in_ch=2, 2332 out_ch=2, 2333 x_in=9, 2334 y_in=11, 2335 w_x=3, 2336 w_y=3, 2337 stride_x=1, 2338 stride_y=1, 2339 pad=True, 2340 out_activation_min=-61, 2341 out_activation_max=107, 2342 dilation_x=2, 2343 dilation_y=2) 2344 dataset = 'int16xint8' 2345 testdata_sets[dataset] = ConvSettings(dataset, 2346 type_of_test, 2347 regenerate_weights, 2348 regenerate_input, 2349 regenerate_biases, 2350 schema_file, 2351 in_ch=3, 2352 out_ch=4, 2353 x_in=7, 2354 y_in=8, 2355 w_x=2, 2356 w_y=4, 2357 stride_x=2, 2358 stride_y=3, 2359 pad=True, 2360 randmin=INT16_MIN, 2361 randmax=INT16_MAX, 2362 out_activation_min=-13335, 2363 out_activation_max=32767, 2364 int16xint8=True) 2365 dataset = 'requantize_s64' 2366 testdata_sets[dataset] = ConvSettings(dataset, 2367 type_of_test, 2368 regenerate_weights, 2369 regenerate_input, 2370 regenerate_biases, 2371 schema_file, 2372 in_ch=2, 2373 out_ch=2, 2374 x_in=3, 2375 y_in=2, 2376 w_x=2, 2377 w_y=2, 2378 stride_x=1, 2379 stride_y=1, 2380 pad=False, 2381 out_activation_min=INT16_MIN, 2382 out_activation_max=INT16_MAX, 2383 int16xint8=True, 2384 bias_min=-0x300, 2385 bias_max=0x9fff) 2386 dataset = 'int16xint8_dilation_1' 2387 testdata_sets[dataset] = ConvSettings(dataset, 2388 type_of_test, 2389 regenerate_weights, 2390 regenerate_input, 2391 regenerate_biases, 2392 schema_file, 2393 in_ch=2, 2394 out_ch=2, 2395 x_in=32, 2396 y_in=32, 2397 w_x=2, 2398 w_y=2, 2399 stride_x=1, 2400 stride_y=1, 2401 pad=False, 2402 out_activation_min=INT16_MIN, 2403 out_activation_max=INT16_MAX, 2404 int16xint8=True, 2405 bias_min=-0x300, 2406 dilation_x=2, 2407 dilation_y=2) 2408 dataset = 'int16xint8_dilation_2' 2409 testdata_sets[dataset] = ConvSettings(dataset, 2410 type_of_test, 2411 regenerate_weights, 2412 regenerate_input, 2413 regenerate_biases, 2414 schema_file, 2415 in_ch=3, 2416 out_ch=4, 2417 x_in=7, 2418 y_in=8, 2419 w_x=2, 2420 w_y=4, 2421 stride_x=1, 2422 stride_y=1, 2423 pad=True, 2424 randmin=INT16_MIN, 2425 randmax=INT16_MAX, 2426 out_activation_min=-13335, 2427 out_activation_max=32767, 2428 int16xint8=True, 2429 dilation_x=2, 2430 dilation_y=2) 2431 dataset = 'int16xint8_dilation_3' 2432 testdata_sets[dataset] = ConvSettings(dataset, 2433 type_of_test, 2434 regenerate_weights, 2435 regenerate_input, 2436 regenerate_biases, 2437 schema_file, 2438 in_ch=3, 2439 out_ch=4, 2440 x_in=7, 2441 y_in=8, 2442 w_x=2, 2443 w_y=4, 2444 stride_x=1, 2445 stride_y=1, 2446 pad=True, 2447 randmin=INT16_MIN, 2448 randmax=INT16_MAX, 2449 out_activation_min=-13335, 2450 out_activation_max=32767, 2451 int16xint8=True, 2452 dilation_x=2) 2453 2454 type_of_test = 'depthwise_conv' 2455 dataset = 'depthwise_2' 2456 testdata_sets[dataset] = ConvSettings(dataset, 2457 type_of_test, 2458 regenerate_weights, 2459 regenerate_input, 2460 regenerate_biases, 2461 schema_file, 2462 in_ch=3, 2463 out_ch=9, 2464 x_in=6, 2465 y_in=5, 2466 w_x=3, 2467 w_y=4, 2468 stride_x=2, 2469 stride_y=2, 2470 pad=True, 2471 out_activation_min=-73, 2472 out_activation_max=127) 2473 dataset = 'depthwise_kernel_3x3' 2474 testdata_sets[dataset] = ConvSettings(dataset, 2475 type_of_test, 2476 regenerate_weights, 2477 regenerate_input, 2478 regenerate_biases, 2479 schema_file, 2480 in_ch=5, 2481 out_ch=5, 2482 x_in=4, 2483 y_in=5, 2484 w_x=3, 2485 w_y=3, 2486 stride_x=2, 2487 stride_y=2, 2488 pad=True, 2489 bias_min=INT8_MIN, 2490 bias_max=INT8_MAX, 2491 out_activation_min=-104, 2492 out_activation_max=127) 2493 dataset = 'depthwise_kernel_3x3_null_bias' 2494 testdata_sets[dataset] = ConvSettings(dataset, 2495 type_of_test, 2496 regenerate_weights, 2497 regenerate_input, 2498 regenerate_biases, 2499 schema_file, 2500 in_ch=5, 2501 out_ch=5, 2502 x_in=4, 2503 y_in=5, 2504 w_x=3, 2505 w_y=3, 2506 stride_x=2, 2507 stride_y=2, 2508 pad=True, 2509 generate_bias=False, 2510 out_activation_min=-104, 2511 out_activation_max=127) 2512 dataset = 'depthwise_eq_in_out_ch' 2513 testdata_sets[dataset] = ConvSettings(dataset, 2514 type_of_test, 2515 regenerate_weights, 2516 regenerate_input, 2517 regenerate_biases, 2518 schema_file, 2519 in_ch=250, 2520 out_ch=250, 2521 x_in=7, 2522 y_in=5, 2523 w_x=2, 2524 w_y=2, 2525 stride_x=1, 2526 stride_y=1, 2527 pad=True) 2528 dataset = 'depthwise_sub_block' 2529 testdata_sets[dataset] = ConvSettings(dataset, 2530 type_of_test, 2531 regenerate_weights, 2532 regenerate_input, 2533 regenerate_biases, 2534 schema_file, 2535 in_ch=9, 2536 out_ch=9, 2537 x_in=7, 2538 y_in=5, 2539 w_x=2, 2540 w_y=2, 2541 stride_x=1, 2542 stride_y=1, 2543 pad=False) 2544 dataset = 'depthwise_x_stride' 2545 testdata_sets[dataset] = ConvSettings(dataset, 2546 type_of_test, 2547 regenerate_weights, 2548 regenerate_input, 2549 regenerate_biases, 2550 schema_file, 2551 in_ch=9, 2552 out_ch=9, 2553 x_in=7, 2554 y_in=5, 2555 w_x=2, 2556 w_y=2, 2557 stride_x=2, 2558 stride_y=1, 2559 pad=False) 2560 dataset = 'depthwise_out_activation' 2561 testdata_sets[dataset] = ConvSettings(dataset, 2562 type_of_test, 2563 regenerate_weights, 2564 regenerate_input, 2565 regenerate_biases, 2566 schema_file, 2567 in_ch=3, 2568 out_ch=3, 2569 x_in=6, 2570 y_in=5, 2571 w_x=3, 2572 w_y=4, 2573 pad=False, 2574 out_activation_min=-45, 2575 out_activation_max=103) 2576 dataset = 'depthwise_mult_batches' 2577 testdata_sets[dataset] = ConvSettings(dataset, 2578 type_of_test, 2579 regenerate_weights, 2580 regenerate_input, 2581 regenerate_biases, 2582 schema_file, 2583 in_ch=3, 2584 out_ch=3, 2585 x_in=3, 2586 y_in=5, 2587 w_x=2, 2588 w_y=4, 2589 stride_x=2, 2590 stride_y=2, 2591 pad=True, 2592 batches=2) 2593 dataset = 'depthwise_null_bias_0' 2594 testdata_sets[dataset] = ConvSettings(dataset, 2595 type_of_test, 2596 regenerate_weights, 2597 regenerate_input, 2598 regenerate_biases, 2599 schema_file, 2600 in_ch=2, 2601 out_ch=2, 2602 x_in=4, 2603 y_in=5, 2604 w_x=2, 2605 w_y=2, 2606 stride_x=1, 2607 stride_y=1, 2608 pad=True, 2609 generate_bias=False, 2610 batches=1) 2611 dataset = 'depthwise_null_bias_1' 2612 testdata_sets[dataset] = ConvSettings(dataset, 2613 type_of_test, 2614 regenerate_weights, 2615 regenerate_input, 2616 regenerate_biases, 2617 schema_file, 2618 in_ch=2, 2619 out_ch=16, 2620 x_in=4, 2621 y_in=5, 2622 w_x=2, 2623 w_y=2, 2624 stride_x=1, 2625 stride_y=1, 2626 pad=True, 2627 generate_bias=False, 2628 batches=1) 2629 dataset = 'depthwise_dilation' 2630 testdata_sets[dataset] = ConvSettings(dataset, 2631 type_of_test, 2632 regenerate_weights, 2633 regenerate_input, 2634 regenerate_biases, 2635 schema_file, 2636 in_ch=3, 2637 out_ch=9, 2638 x_in=6, 2639 y_in=5, 2640 w_x=3, 2641 w_y=4, 2642 stride_x=2, 2643 stride_y=2, 2644 pad=True, 2645 out_activation_min=-70, 2646 out_activation_max=127, 2647 dilation_x=2, 2648 dilation_y=3) 2649 dataset = 'dw_int16xint8' 2650 testdata_sets[dataset] = ConvSettings(dataset, 2651 type_of_test, 2652 regenerate_weights, 2653 regenerate_input, 2654 regenerate_biases, 2655 schema_file, 2656 in_ch=4, 2657 out_ch=8, 2658 x_in=9, 2659 y_in=5, 2660 w_x=3, 2661 w_y=4, 2662 stride_x=3, 2663 stride_y=2, 2664 pad=True, 2665 randmin=INT16_MIN, 2666 randmax=INT16_MAX, 2667 out_activation_min=-21111, 2668 out_activation_max=32767, 2669 int16xint8=True) 2670 dataset = 'dw_int16xint8_dilation' 2671 testdata_sets[dataset] = ConvSettings(dataset, 2672 type_of_test, 2673 regenerate_weights, 2674 regenerate_input, 2675 regenerate_biases, 2676 schema_file, 2677 in_ch=4, 2678 out_ch=8, 2679 x_in=9, 2680 y_in=5, 2681 w_x=4, 2682 w_y=4, 2683 stride_x=1, 2684 stride_y=1, 2685 pad=True, 2686 randmin=INT16_MIN, 2687 randmax=INT16_MAX, 2688 out_activation_min=-32700, 2689 dilation_x=3, 2690 dilation_y=2, 2691 out_activation_max=32767, 2692 int16xint8=True) 2693 dataset = 'dw_int16xint8_mult4' 2694 testdata_sets[dataset] = ConvSettings(dataset, 2695 type_of_test, 2696 regenerate_weights, 2697 regenerate_input, 2698 regenerate_biases, 2699 schema_file, 2700 in_ch=2, 2701 out_ch=8, 2702 x_in=4, 2703 y_in=5, 2704 w_x=3, 2705 w_y=4, 2706 stride_x=3, 2707 stride_y=2, 2708 pad=False, 2709 randmin=INT16_MIN, 2710 randmax=INT16_MAX, 2711 out_activation_min=-32767, 2712 out_activation_max=32767, 2713 int16xint8=True) 2714 dataset = 'dw_int16xint8_fast' 2715 testdata_sets[dataset] = ConvSettings(dataset, 2716 type_of_test, 2717 regenerate_weights, 2718 regenerate_input, 2719 regenerate_biases, 2720 schema_file, 2721 in_ch=8, 2722 out_ch=8, 2723 x_in=4, 2724 y_in=4, 2725 w_x=2, 2726 w_y=2, 2727 stride_x=1, 2728 stride_y=1, 2729 pad=False, 2730 randmin=INT16_MIN, 2731 randmax=INT16_MAX, 2732 out_activation_min=-17000, 2733 out_activation_max=32767, 2734 int16xint8=True) 2735 dataset = 'dw_int16xint8_fast_multiple_batches_uneven_buffers' 2736 testdata_sets[dataset] = ConvSettings(dataset, 2737 type_of_test, 2738 regenerate_weights, 2739 regenerate_input, 2740 regenerate_biases, 2741 schema_file, 2742 in_ch=8, 2743 out_ch=8, 2744 x_in=5, 2745 y_in=5, 2746 w_x=3, 2747 w_y=3, 2748 stride_x=1, 2749 stride_y=1, 2750 pad=False, 2751 randmin=INT16_MIN, 2752 randmax=INT16_MAX, 2753 out_activation_min=-17000, 2754 out_activation_max=32767, 2755 int16xint8=True, 2756 batches=3) 2757 dataset = 'dw_int16xint8_fast_multiple_batches_uneven_buffers_null_bias' 2758 testdata_sets[dataset] = ConvSettings(dataset, 2759 type_of_test, 2760 regenerate_weights, 2761 regenerate_input, 2762 regenerate_biases, 2763 schema_file, 2764 in_ch=8, 2765 out_ch=8, 2766 x_in=4, 2767 y_in=4, 2768 w_x=3, 2769 w_y=2, 2770 stride_x=1, 2771 stride_y=1, 2772 pad=False, 2773 randmin=INT16_MIN, 2774 randmax=INT16_MAX, 2775 out_activation_min=-17000, 2776 out_activation_max=32767, 2777 int16xint8=True, 2778 batches=3, 2779 generate_bias=False) 2780 2781 dataset = 'dw_int16xint8_fast_test_bias' 2782 nbr_of_out_channels = 8 2783 bias = [i for i in range(nbr_of_out_channels)] 2784 testdata_sets[dataset] = ConvSettings(dataset, 2785 type_of_test, 2786 regenerate_weights, 2787 regenerate_input, 2788 regenerate_biases, 2789 schema_file, 2790 in_ch=8, 2791 out_ch=nbr_of_out_channels, 2792 x_in=4, 2793 y_in=4, 2794 w_x=2, 2795 w_y=2, 2796 stride_x=1, 2797 stride_y=1, 2798 pad=False, 2799 randmin=INT16_MIN, 2800 randmax=INT16_MAX, 2801 out_activation_min=-17000, 2802 out_activation_max=32767, 2803 int16xint8=True, 2804 generate_bias=bias) 2805 2806 dataset = 'dw_int16xint8_fast_null_bias' 2807 testdata_sets[dataset] = ConvSettings(dataset, 2808 type_of_test, 2809 regenerate_weights, 2810 regenerate_input, 2811 regenerate_biases, 2812 schema_file, 2813 in_ch=8, 2814 out_ch=8, 2815 x_in=4, 2816 y_in=4, 2817 w_x=2, 2818 w_y=2, 2819 stride_x=1, 2820 stride_y=1, 2821 pad=False, 2822 randmin=INT16_MIN, 2823 randmax=INT16_MAX, 2824 out_activation_min=-17000, 2825 out_activation_max=32767, 2826 int16xint8=True, 2827 generate_bias=False) 2828 dataset = 'dw_int16xint8_fast_stride' 2829 testdata_sets[dataset] = ConvSettings(dataset, 2830 type_of_test, 2831 regenerate_weights, 2832 regenerate_input, 2833 regenerate_biases, 2834 schema_file, 2835 in_ch=8, 2836 out_ch=8, 2837 x_in=4, 2838 y_in=4, 2839 w_x=2, 2840 w_y=2, 2841 stride_x=2, 2842 stride_y=2, 2843 pad=True, 2844 randmin=INT16_MIN, 2845 randmax=INT16_MAX, 2846 batches=2, 2847 out_activation_min=INT16_MIN, 2848 out_activation_max=16000, 2849 int16xint8=True) 2850 dataset = 'dw_int16xint8_fast_stride_null_bias' 2851 testdata_sets[dataset] = ConvSettings(dataset, 2852 type_of_test, 2853 regenerate_weights, 2854 regenerate_input, 2855 regenerate_biases, 2856 schema_file, 2857 in_ch=8, 2858 out_ch=8, 2859 x_in=4, 2860 y_in=4, 2861 w_x=2, 2862 w_y=2, 2863 stride_x=2, 2864 stride_y=2, 2865 pad=True, 2866 randmin=INT16_MIN, 2867 randmax=INT16_MAX, 2868 batches=2, 2869 out_activation_min=INT16_MIN, 2870 out_activation_max=16000, 2871 int16xint8=True, 2872 generate_bias=False) 2873 dataset = 'dw_int16xint8_fast_spill' 2874 testdata_sets[dataset] = ConvSettings(dataset, 2875 type_of_test, 2876 regenerate_weights, 2877 regenerate_input, 2878 regenerate_biases, 2879 schema_file, 2880 in_ch=5, 2881 out_ch=5, 2882 x_in=4, 2883 y_in=4, 2884 w_x=3, 2885 w_y=3, 2886 stride_x=2, 2887 stride_y=1, 2888 pad=True, 2889 randmin=INT16_MIN, 2890 randmax=INT16_MAX, 2891 batches=3, 2892 out_activation_min=-30000, 2893 out_activation_max=32767, 2894 int16xint8=True) 2895 dataset = 'dw_int16xint8_fast_spill_null_bias' 2896 testdata_sets[dataset] = ConvSettings(dataset, 2897 type_of_test, 2898 regenerate_weights, 2899 regenerate_input, 2900 regenerate_biases, 2901 schema_file, 2902 in_ch=5, 2903 out_ch=5, 2904 x_in=4, 2905 y_in=4, 2906 w_x=3, 2907 w_y=3, 2908 stride_x=2, 2909 stride_y=1, 2910 pad=True, 2911 randmin=INT16_MIN, 2912 randmax=INT16_MAX, 2913 batches=3, 2914 out_activation_min=-30000, 2915 out_activation_max=32767, 2916 int16xint8=True, 2917 generate_bias=False) 2918 2919 type_of_test = 'fully_connected' 2920 dataset = 'fully_connected' 2921 testdata_sets[dataset] = FullyConnectedSettings(dataset, 2922 type_of_test, 2923 regenerate_weights, 2924 regenerate_input, 2925 regenerate_biases, 2926 schema_file, 2927 in_ch=10, 2928 out_ch=6, 2929 x_in=2, 2930 y_in=1, 2931 batches=3) 2932 dataset = 'fully_connected_mve_0' 2933 testdata_sets[dataset] = FullyConnectedSettings(dataset, 2934 type_of_test, 2935 regenerate_weights, 2936 regenerate_input, 2937 regenerate_biases, 2938 schema_file, 2939 in_ch=16, 2940 out_ch=9, 2941 x_in=1, 2942 y_in=1, 2943 batches=1) 2944 dataset = 'fully_connected_mve_1' 2945 testdata_sets[dataset] = FullyConnectedSettings(dataset, 2946 type_of_test, 2947 regenerate_weights, 2948 regenerate_input, 2949 regenerate_biases, 2950 schema_file, 2951 in_ch=20, 2952 out_ch=4, 2953 x_in=1, 2954 y_in=1, 2955 batches=1) 2956 dataset = 'fully_connected_null_bias_0' 2957 testdata_sets[dataset] = FullyConnectedSettings(dataset, 2958 type_of_test, 2959 regenerate_weights, 2960 regenerate_input, 2961 regenerate_biases, 2962 schema_file, 2963 in_ch=33, 2964 out_ch=5, 2965 batches=2, 2966 generate_bias=False) 2967 dataset = 'fully_connected_out_activation' 2968 testdata_sets[dataset] = FullyConnectedSettings(dataset, 2969 type_of_test, 2970 regenerate_weights, 2971 regenerate_input, 2972 regenerate_biases, 2973 schema_file, 2974 in_ch=10, 2975 out_ch=4, 2976 out_activation_min=-70, 2977 out_activation_max=100) 2978 dataset = 'fully_connected_int16' 2979 testdata_sets[dataset] = FullyConnectedSettings(dataset, 2980 type_of_test, 2981 regenerate_weights, 2982 regenerate_input, 2983 regenerate_biases, 2984 schema_file, 2985 in_ch=7, 2986 out_ch=11, 2987 x_in=3, 2988 y_in=3, 2989 batches=2, 2990 randmin=INT16_MIN, 2991 randmax=INT16_MAX, 2992 out_activation_min=-9999, 2993 out_activation_max=32767, 2994 int16xint8=True) 2995 dataset = 'fully_connected_int16_big' 2996 testdata_sets[dataset] = FullyConnectedSettings(dataset, 2997 type_of_test, 2998 regenerate_weights, 2999 regenerate_input, 3000 regenerate_biases, 3001 schema_file, 3002 in_ch=7, 3003 out_ch=11, 3004 x_in=10, 3005 y_in=10, 3006 batches=3, 3007 out_activation_min=-1444, 3008 out_activation_max=32767, 3009 int16xint8=True) 3010 dataset = 'fc_int16_slow' 3011 testdata_sets[dataset] = FullyConnectedSettings(dataset, 3012 type_of_test, 3013 regenerate_weights, 3014 regenerate_input, 3015 regenerate_biases, 3016 schema_file, 3017 in_ch=7, 3018 out_ch=11, 3019 x_in=10, 3020 y_in=8, 3021 batches=3, 3022 randmin=(INT16_MAX - 100), 3023 randmax=INT16_MAX, 3024 int16xint8=True) 3025 3026 type_of_test = 'avgpool' 3027 dataset = 'avgpooling' 3028 testdata_sets[dataset] = PoolingSettings(dataset, 3029 type_of_test, 3030 regenerate_weights, 3031 regenerate_input, 3032 regenerate_biases, 3033 schema_file, 3034 channels=20, 3035 x_in=22, 3036 y_in=12, 3037 stride_x=9, 3038 stride_y=5, 3039 w_x=6, 3040 w_y=5, 3041 pad=True) 3042 dataset = 'avgpooling_1' 3043 testdata_sets[dataset] = PoolingSettings(dataset, 3044 type_of_test, 3045 regenerate_weights, 3046 regenerate_input, 3047 regenerate_biases, 3048 schema_file, 3049 channels=3, 3050 x_in=9, 3051 y_in=5, 3052 stride_x=1, 3053 stride_y=2, 3054 w_x=9, 3055 w_y=5, 3056 pad=False) 3057 dataset = 'avgpooling_2' 3058 testdata_sets[dataset] = PoolingSettings(dataset, 3059 type_of_test, 3060 regenerate_weights, 3061 regenerate_input, 3062 regenerate_biases, 3063 schema_file, 3064 channels=5, 3065 x_in=12, 3066 y_in=1, 3067 stride_x=1, 3068 stride_y=2, 3069 w_x=3, 3070 w_y=1, 3071 pad=True) 3072 dataset = 'avgpooling_3' 3073 testdata_sets[dataset] = PoolingSettings(dataset, 3074 type_of_test, 3075 regenerate_weights, 3076 regenerate_input, 3077 regenerate_biases, 3078 schema_file, 3079 channels=2, 3080 x_in=9, 3081 y_in=1, 3082 stride_x=2, 3083 stride_y=1, 3084 w_x=1, 3085 w_y=1, 3086 pad=False) 3087 dataset = 'avgpooling_4' 3088 testdata_sets[dataset] = PoolingSettings(dataset, 3089 type_of_test, 3090 regenerate_weights, 3091 regenerate_input, 3092 regenerate_biases, 3093 schema_file, 3094 channels=2, 3095 x_in=1, 3096 y_in=20, 3097 stride_x=1, 3098 stride_y=3, 3099 w_x=1, 3100 w_y=3, 3101 pad=True) 3102 dataset = 'avgpooling_5' 3103 testdata_sets[dataset] = PoolingSettings(dataset, 3104 type_of_test, 3105 regenerate_weights, 3106 regenerate_input, 3107 regenerate_biases, 3108 schema_file, 3109 channels=1, 3110 x_in=3, 3111 y_in=3, 3112 stride_x=1, 3113 stride_y=1, 3114 w_x=1, 3115 w_y=3, 3116 pad=True, 3117 relu6=True) 3118 dataset = 'avgpooling_int16' 3119 testdata_sets[dataset] = PoolingSettings(dataset, 3120 type_of_test, 3121 regenerate_weights, 3122 regenerate_input, 3123 regenerate_biases, 3124 schema_file, 3125 channels=17, 3126 x_in=6, 3127 y_in=4, 3128 stride_x=2, 3129 stride_y=1, 3130 w_x=2, 3131 w_y=3, 3132 pad=True, 3133 randmin=INT16_MIN, 3134 randmax=INT16_MAX, 3135 int16xint8=True) 3136 dataset = 'avgpooling_int16_1' 3137 testdata_sets[dataset] = PoolingSettings(dataset, 3138 type_of_test, 3139 regenerate_weights, 3140 regenerate_input, 3141 regenerate_biases, 3142 schema_file, 3143 channels=2, 3144 x_in=9, 3145 y_in=1, 3146 stride_x=2, 3147 stride_y=1, 3148 w_x=1, 3149 w_y=1, 3150 pad=False, 3151 randmin=INT16_MIN, 3152 randmax=INT16_MAX, 3153 int16xint8=True) 3154 dataset = 'avgpooling_int16_2' 3155 testdata_sets[dataset] = PoolingSettings(dataset, 3156 type_of_test, 3157 regenerate_weights, 3158 regenerate_input, 3159 regenerate_biases, 3160 schema_file, 3161 channels=20, 3162 x_in=9, 3163 y_in=1, 3164 stride_x=2, 3165 stride_y=1, 3166 w_x=1, 3167 w_y=1, 3168 pad=False, 3169 randmin=INT16_MIN, 3170 randmax=INT16_MAX, 3171 int16xint8=True) 3172 dataset = 'avgpooling_int16_3' 3173 testdata_sets[dataset] = PoolingSettings(dataset, 3174 type_of_test, 3175 regenerate_weights, 3176 regenerate_input, 3177 regenerate_biases, 3178 schema_file, 3179 channels=21, 3180 x_in=1, 3181 y_in=20, 3182 stride_x=1, 3183 stride_y=3, 3184 w_x=1, 3185 w_y=3, 3186 pad=True, 3187 randmin=INT16_MIN, 3188 randmax=INT16_MAX, 3189 int16xint8=True) 3190 3191 type_of_test = 'maxpool' 3192 dataset = 'maxpooling' 3193 testdata_sets[dataset] = PoolingSettings(dataset, 3194 type_of_test, 3195 regenerate_weights, 3196 regenerate_input, 3197 regenerate_biases, 3198 schema_file, 3199 channels=8, 3200 x_in=22, 3201 y_in=12, 3202 stride_x=9, 3203 stride_y=5, 3204 w_x=6, 3205 w_y=5, 3206 pad=True) 3207 dataset = 'maxpooling_1' 3208 testdata_sets[dataset] = PoolingSettings(dataset, 3209 type_of_test, 3210 regenerate_weights, 3211 regenerate_input, 3212 regenerate_biases, 3213 schema_file, 3214 channels=3, 3215 x_in=9, 3216 y_in=5, 3217 stride_x=1, 3218 stride_y=2, 3219 w_x=9, 3220 w_y=5, 3221 pad=False) 3222 dataset = 'maxpooling_2' 3223 testdata_sets[dataset] = PoolingSettings(dataset, 3224 type_of_test, 3225 regenerate_weights, 3226 regenerate_input, 3227 regenerate_biases, 3228 schema_file, 3229 channels=5, 3230 x_in=12, 3231 y_in=1, 3232 stride_x=1, 3233 stride_y=2, 3234 w_x=3, 3235 w_y=1, 3236 pad=True) 3237 dataset = 'maxpooling_3' 3238 testdata_sets[dataset] = PoolingSettings(dataset, 3239 type_of_test, 3240 regenerate_weights, 3241 regenerate_input, 3242 regenerate_biases, 3243 schema_file, 3244 channels=2, 3245 x_in=9, 3246 y_in=1, 3247 stride_x=2, 3248 stride_y=1, 3249 w_x=1, 3250 w_y=1, 3251 pad=False) 3252 dataset = 'maxpooling_4' 3253 testdata_sets[dataset] = PoolingSettings(dataset, 3254 type_of_test, 3255 regenerate_weights, 3256 regenerate_input, 3257 regenerate_biases, 3258 schema_file, 3259 channels=2, 3260 x_in=1, 3261 y_in=20, 3262 stride_x=1, 3263 stride_y=3, 3264 w_x=1, 3265 w_y=3, 3266 pad=True) 3267 dataset = 'maxpooling_5' 3268 testdata_sets[dataset] = PoolingSettings(dataset, 3269 type_of_test, 3270 regenerate_weights, 3271 regenerate_input, 3272 regenerate_biases, 3273 schema_file, 3274 channels=20, 3275 x_in=1, 3276 y_in=1, 3277 stride_x=1, 3278 stride_y=1, 3279 w_x=1, 3280 w_y=1, 3281 pad=True) 3282 dataset = 'maxpooling_6' 3283 testdata_sets[dataset] = PoolingSettings(dataset, 3284 type_of_test, 3285 regenerate_weights, 3286 regenerate_input, 3287 regenerate_biases, 3288 schema_file, 3289 channels=17, 3290 x_in=1, 3291 y_in=5, 3292 stride_x=1, 3293 stride_y=3, 3294 w_x=3, 3295 w_y=4, 3296 pad=True) 3297 dataset = 'maxpooling_7' 3298 testdata_sets[dataset] = PoolingSettings(dataset, 3299 type_of_test, 3300 regenerate_weights, 3301 regenerate_input, 3302 regenerate_biases, 3303 schema_file, 3304 channels=1, 3305 x_in=4, 3306 y_in=2, 3307 stride_x=2, 3308 stride_y=2, 3309 w_x=2, 3310 w_y=2, 3311 pad=False, 3312 relu6=True) 3313 dataset = 'maxpool_int16' 3314 testdata_sets[dataset] = PoolingSettings(dataset, 3315 type_of_test, 3316 regenerate_weights, 3317 regenerate_input, 3318 regenerate_biases, 3319 schema_file, 3320 channels=2, 3321 x_in=4, 3322 y_in=3, 3323 stride_x=2, 3324 stride_y=2, 3325 w_x=2, 3326 w_y=2, 3327 pad=False, 3328 randmin=INT16_MIN, 3329 randmax=INT16_MAX, 3330 int16xint8=True) 3331 dataset = 'maxpool_int16_1' 3332 testdata_sets[dataset] = PoolingSettings(dataset, 3333 type_of_test, 3334 regenerate_weights, 3335 regenerate_input, 3336 regenerate_biases, 3337 schema_file, 3338 channels=2, 3339 x_in=4, 3340 y_in=5, 3341 stride_x=2, 3342 stride_y=1, 3343 w_x=3, 3344 w_y=3, 3345 pad=True, 3346 randmin=INT16_MIN, 3347 randmax=INT16_MAX, 3348 out_activation_min=-30000, 3349 out_activation_max=30000, 3350 int16xint8=True) 3351 dataset = 'maxpool_int16_2' 3352 testdata_sets[dataset] = PoolingSettings(dataset, 3353 type_of_test, 3354 regenerate_weights, 3355 regenerate_input, 3356 regenerate_biases, 3357 schema_file, 3358 channels=3, 3359 x_in=7, 3360 y_in=7, 3361 stride_x=1, 3362 stride_y=1, 3363 w_x=3, 3364 w_y=3, 3365 pad=False, 3366 randmin=INT16_MIN, 3367 randmax=INT16_MAX, 3368 out_activation_min=-30000, 3369 out_activation_max=30000, 3370 int16xint8=True) 3371 3372 type_of_test = 'softmax' 3373 dataset = 'softmax' 3374 testdata_sets[dataset] = SoftmaxSettings(dataset, 3375 type_of_test, 3376 regenerate_weights, 3377 regenerate_input, 3378 regenerate_biases, 3379 schema_file, 3380 x_in=5, 3381 y_in=2) 3382 dataset = 'softmax_s16' 3383 testdata_sets[dataset] = SoftmaxSettings(dataset, 3384 type_of_test, 3385 regenerate_weights, 3386 regenerate_input, 3387 regenerate_biases, 3388 schema_file, 3389 x_in=10, 3390 y_in=3, 3391 int16xint8=True, 3392 randmin=INT16_MIN, 3393 randmax=INT16_MAX) 3394 dataset = 'softmax_s8_s16' 3395 testdata_sets[dataset] = SoftmaxSettings(dataset, 3396 type_of_test, 3397 regenerate_weights, 3398 regenerate_input, 3399 regenerate_biases, 3400 schema_file, 3401 x_in=12, 3402 y_in=2, 3403 inInt8outInt16=True) 3404 3405 type_of_test = 'svdf' 3406 dataset = 'svdf' 3407 testdata_sets[dataset] = SVDFSettings(dataset, 3408 type_of_test, 3409 regenerate_weights, 3410 regenerate_input, 3411 regenerate_biases, 3412 schema_file, 3413 batches=2, 3414 number_inputs=2, 3415 rank=8, 3416 memory_size=8, 3417 input_size=3, 3418 number_units=3) 3419 dataset = 'svdf_1' 3420 testdata_sets[dataset] = SVDFSettings(dataset, 3421 type_of_test, 3422 regenerate_weights, 3423 regenerate_input, 3424 regenerate_biases, 3425 schema_file, 3426 batches=3, 3427 number_inputs=2, 3428 rank=1, 3429 memory_size=2, 3430 input_size=7, 3431 number_units=5) 3432 dataset = 'svdf_2' 3433 testdata_sets[dataset] = SVDFSettings(dataset, 3434 type_of_test, 3435 regenerate_weights, 3436 regenerate_input, 3437 regenerate_biases, 3438 schema_file, 3439 batches=3, 3440 number_inputs=2, 3441 rank=2, 3442 memory_size=2, 3443 input_size=7, 3444 number_units=5, 3445 generate_bias=False) 3446 dataset = 'svdf_3' 3447 testdata_sets[dataset] = SVDFSettings(dataset, 3448 type_of_test, 3449 regenerate_weights, 3450 regenerate_input, 3451 regenerate_biases, 3452 schema_file, 3453 batches=1, 3454 number_inputs=2, 3455 rank=1, 3456 memory_size=2, 3457 input_size=20, 3458 number_units=12, 3459 generate_bias=False) 3460 dataset = 'svdf_int8' 3461 testdata_sets[dataset] = SVDFSettings(dataset, 3462 type_of_test, 3463 regenerate_weights, 3464 regenerate_input, 3465 regenerate_biases, 3466 schema_file, 3467 batches=1, 3468 number_inputs=2, 3469 rank=1, 3470 memory_size=2, 3471 input_size=20, 3472 number_units=12, 3473 generate_bias=False, 3474 int8_time_weights=True) 3475 3476 type_of_test = 'add' 3477 dataset = 'add' 3478 testdata_sets[dataset] = AddMulSettings(dataset, 3479 type_of_test, 3480 regenerate_weights, 3481 regenerate_input, 3482 regenerate_biases, 3483 schema_file, 3484 channels=8, 3485 x_in=4, 3486 y_in=4, 3487 randmin=INT8_MIN, 3488 randmax=INT8_MAX) 3489 dataset = 'add_s16' 3490 testdata_sets[dataset] = AddMulSettings(dataset, 3491 type_of_test, 3492 regenerate_weights, 3493 regenerate_input, 3494 regenerate_biases, 3495 schema_file, 3496 channels=8, 3497 x_in=4, 3498 y_in=4, 3499 randmin=INT16_MIN, 3500 randmax=INT16_MAX, 3501 out_activation_min=INT16_MIN, 3502 out_activation_max=INT16_MAX, 3503 int16xint8=True) 3504 dataset = 'add_s16_spill' 3505 testdata_sets[dataset] = AddMulSettings(dataset, 3506 type_of_test, 3507 regenerate_weights, 3508 regenerate_input, 3509 regenerate_biases, 3510 schema_file, 3511 channels=7, 3512 x_in=5, 3513 y_in=3, 3514 randmin=INT16_MIN, 3515 randmax=INT16_MAX, 3516 out_activation_min=-2000, 3517 out_activation_max=INT16_MAX, 3518 int16xint8=True) 3519 3520 type_of_test = 'mul' 3521 dataset = 'mul' 3522 testdata_sets[dataset] = AddMulSettings(dataset, 3523 type_of_test, 3524 regenerate_weights, 3525 regenerate_input, 3526 regenerate_biases, 3527 schema_file, 3528 channels=8, 3529 x_in=4, 3530 y_in=5, 3531 randmin=INT8_MIN, 3532 randmax=INT8_MAX) 3533 dataset = 'mul_s16' 3534 testdata_sets[dataset] = AddMulSettings(dataset, 3535 type_of_test, 3536 regenerate_weights, 3537 regenerate_input, 3538 regenerate_biases, 3539 schema_file, 3540 channels=8, 3541 x_in=5, 3542 y_in=4, 3543 randmin=INT16_MIN, 3544 randmax=INT16_MAX, 3545 out_activation_min=INT16_MIN, 3546 out_activation_max=INT16_MAX, 3547 int16xint8=True) 3548 dataset = 'mul_s16_spill' 3549 testdata_sets[dataset] = AddMulSettings(dataset, 3550 type_of_test, 3551 regenerate_weights, 3552 regenerate_input, 3553 regenerate_biases, 3554 schema_file, 3555 channels=7, 3556 x_in=5, 3557 y_in=7, 3558 randmin=INT16_MIN, 3559 randmax=INT16_MAX, 3560 out_activation_min=INT16_MIN, 3561 out_activation_max=1000, 3562 int16xint8=True) 3563 3564 type_of_test = 'lstm' 3565 dataset = 'lstm_1' 3566 testdata_sets[dataset] = LSTMSettings(dataset, 3567 type_of_test, 3568 regenerate_weights, 3569 regenerate_input, 3570 regenerate_biases, 3571 schema_file, 3572 batches=1, 3573 time_steps=10, 3574 number_inputs=22, 3575 number_units=11, 3576 time_major=True) 3577 dataset = 'lstm_2' 3578 testdata_sets[dataset] = LSTMSettings(dataset, 3579 type_of_test, 3580 regenerate_weights, 3581 regenerate_input, 3582 regenerate_biases, 3583 schema_file, 3584 batches=2, 3585 time_steps=9, 3586 number_inputs=6, 3587 number_units=7, 3588 time_major=False) 3589 dataset = 'lstm_one_time_step' 3590 testdata_sets[dataset] = LSTMSettings(dataset, 3591 type_of_test, 3592 regenerate_weights, 3593 regenerate_input, 3594 regenerate_biases, 3595 schema_file, 3596 batches=3, 3597 time_steps=1, 3598 number_inputs=22, 3599 number_units=3, 3600 time_major=False) 3601 3602 return testdata_sets 3603 3604 3605if __name__ == '__main__': 3606 if version.parse(tf.__version__) < REQUIRED_MINIMUM_TENSORFLOW_VERSION: 3607 print("Unsupported tensorflow version, ", version.parse(tf.__version__)) 3608 sys.exit(0) 3609 3610 args = parse_args() 3611 3612 testdataset = args.dataset 3613 test_type = args.testtype 3614 schema_file = args.schema_file 3615 3616 testdata_sets = load_testdata_sets() 3617 3618 if args.run_all_testsets: 3619 for testset_name, testset_generator in testdata_sets.items(): 3620 if test_type and testset_generator.test_type != test_type: 3621 continue 3622 print("Generating testset {}..".format(testset_name)) 3623 testset_generator.generate_data() 3624 print() 3625 3626 # Check that all testsets have been loaded. 3627 found_test_data_sets = [] 3628 directory = 'TestCases/TestData' 3629 for dir in next(os.walk(directory))[1]: 3630 found_test_data_sets.append(dir) 3631 for testset_name in found_test_data_sets: 3632 if testset_name not in testdata_sets: 3633 print("WARNING: Testset {} in {} was not loaded".format(testset_name, directory)) 3634 elif testdataset: 3635 try: 3636 generator = testdata_sets[testdataset] 3637 except KeyError: 3638 print("WARNING: testset {} not in testset list".format(testdataset)) 3639 if test_type == 'conv' or test_type == 'depthwise_conv': 3640 generator = ConvSettings(testdataset, test_type, True, True, True, schema_file) 3641 elif test_type == 'fully_connected': 3642 generator = FullyConnectedSettings(testdataset, test_type, True, True, True, schema_file) 3643 elif test_type == 'avgpool' or test_type == 'maxpool': 3644 generator = PoolingSettings(testdataset, test_type, True, True, True, schema_file) 3645 elif test_type == 'softmax': 3646 generator = SoftmaxSettings(testdataset, test_type, True, True, True, schema_file) 3647 elif test_type == 'svdf': 3648 generator = SVDFSettings(testdataset, test_type, True, True, True, schema_file) 3649 elif test_type == 'add' or test_type == 'mul': 3650 generator = AddMulSettings(testdataset, test_type, True, True, True, schema_file) 3651 elif test_type == 'lstm': 3652 generator = LSTMSettings(testdataset, test_type, True, True, True, schema_file) 3653 else: 3654 raise RuntimeError("Please specify type of test with -t") 3655 generator.generate_data() 3656 else: 3657 raise RuntimeError("Please select testdataset or use --run-all-testsets") 3658