#!/usr/bin/env python import sys import json import pprint import argparse import datetime import itertools defaults = { '--sdram-module': [ 'IS42S16160', 'IS42S16320', 'MT48LC4M16', 'MT48LC16M16', 'AS4C16M16', 'AS4C32M16', 'AS4C32M8', 'M12L64322A', 'M12L16161A', 'MT46V32M16', 'MT46H32M16', 'MT46H32M32', 'MT47H128M8', 'MT47H32M16', 'MT47H64M16', 'P3R1GE4JGF', 'MT41K64M16', 'MT41J128M16', 'MT41K128M16', 'MT41J256M16', 'MT41K256M16', 'K4B1G0446F', 'K4B2G1646F', 'H5TC4G63CFR', 'IS43TR16128B', 'MT8JTF12864', 'MT8KTF51264', # 'MT18KSF1G72HZ', # 'AS4C256M16D3A', # 'MT16KTF1G64HZ', # 'EDY4016A', # 'MT40A1G8', # 'MT40A512M16', ], '--sdram-data-width': [32], '--bist-alternating': [True, False], '--bist-length': [1, 4096], '--bist-random': [True, False], '--num-generators': [1], '--num-checkers': [1], '--access-pattern': ['access_pattern.csv'] } def convert_string_arg(args, arg, type): map_func = { bool: lambda s: {'false': False, 'true': True}[s.lower()], int: lambda s: int(s, 0), } setattr(args, arg, [map_func[type](val) if not isinstance(val, type) else val for val in getattr(args, arg)]) def generate_header(args): header = 'Auto-generated on {} by {}'.format( datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"), sys.argv[0], ) args_str = pprint.pformat(vars(args), sort_dicts=False) arg_lines = args_str.split('\n') lines = [60*'=', header, 60*'-', *arg_lines, 60*'='] return '\n'.join('# ' + line for line in lines) def main(): parser = argparse.ArgumentParser(description='Generate configuration for all possible argument combinations.', formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('--name-format', default='test_%d', help='Name format for i-th test') for name, default in defaults.items(): parser.add_argument(name, nargs='+', default=default, help='%s options' % name) args = parser.parse_args() # make sure not to write those as strings convert_string_arg(args, 'sdram_data_width', int) convert_string_arg(args, 'bist_alternating', bool) convert_string_arg(args, 'bist_length', int) convert_string_arg(args, 'bist_random', bool) convert_string_arg(args, 'num_generators', int) convert_string_arg(args, 'num_checkers', int) common_args = ('sdram_module', 'sdram_data_width', 'bist_alternating', 'num_generators', 'num_checkers') generated_pattern_args = ('bist_length', 'bist_random') custom_pattern_args = ('access_pattern', ) def generated_pattern_configuration(values): config = dict(zip(common_args + generated_pattern_args, values)) # move access pattern parameters deeper config['access_pattern'] = { 'bist_length': config.pop('bist_length'), 'bist_random': config.pop('bist_random'), } return config def custom_pattern_configuration(values): config = dict(zip(common_args + custom_pattern_args, values)) # "rename" --access-pattern to access_pattern.pattern_file due to name difference between # command line args and run_benchmarks.py configuration format config['access_pattern'] = { 'pattern_file': config.pop('access_pattern'), } return config # iterator over the product of given command line arguments def args_product(names): return itertools.product(*(getattr(args, name) for name in names)) generated_pattern_iter = zip(itertools.repeat(generated_pattern_configuration), args_product(common_args + generated_pattern_args)) custom_pattern_iter = zip(itertools.repeat(custom_pattern_configuration), args_product(common_args + custom_pattern_args)) i = 0 configurations = {} for config_generator, values in itertools.chain(generated_pattern_iter, custom_pattern_iter): config = config_generator(values) # ignore unsupported case: bist_random=True and bist_alternating=False if config['access_pattern'].get('bist_random', False) and not config['bist_alternating']: continue configurations[args.name_format % i] = config i += 1 json_str = json.dumps(configurations, indent=4) print(generate_header(args)) print(json_str) if __name__ == "__main__": main()