From 563051aaebbb80da3d453cacf3e1f9782d3077fb Mon Sep 17 00:00:00 2001 From: Sayed Adel Date: Tue, 23 Nov 2021 03:51:21 +0200 Subject: DOC, SIMD: Improve the auto-generated tables of CPU features --- doc/source/reference/simd/simd-optimizations.py | 190 ------------------------ 1 file changed, 190 deletions(-) delete mode 100644 doc/source/reference/simd/simd-optimizations.py (limited to 'doc/source/reference/simd/simd-optimizations.py') diff --git a/doc/source/reference/simd/simd-optimizations.py b/doc/source/reference/simd/simd-optimizations.py deleted file mode 100644 index a78302db5..000000000 --- a/doc/source/reference/simd/simd-optimizations.py +++ /dev/null @@ -1,190 +0,0 @@ -""" -Generate CPU features tables from CCompilerOpt -""" -from os import sys, path -gen_path = path.dirname(path.realpath(__file__)) -#sys.path.append(path.abspath(path.join(gen_path, *([".."]*4), "numpy", "distutils"))) -#from ccompiler_opt import CCompilerOpt -from numpy.distutils.ccompiler_opt import CCompilerOpt - -class FakeCCompilerOpt(CCompilerOpt): - fake_info = ("arch", "compiler", "extra_args") - # disable caching no need for it - conf_nocache = True - def __init__(self, *args, **kwargs): - no_cc = None - CCompilerOpt.__init__(self, no_cc, **kwargs) - def dist_compile(self, sources, flags, **kwargs): - return sources - def dist_info(self): - return FakeCCompilerOpt.fake_info - @staticmethod - def dist_log(*args, stderr=False): - # avoid printing - pass - def feature_test(self, name, force_flags=None): - # To speed up - return True - - def gen_features_table(self, features, ignore_groups=True, - field_names=["Name", "Implies"], - fstyle=None, fstyle_implies=None, **kwargs): - rows = [] - if fstyle is None: - fstyle = lambda ft: f'``{ft}``' - if fstyle_implies is None: - fstyle_implies = lambda origin, ft: fstyle(ft) - for f in self.feature_sorted(features): - is_group = "group" in self.feature_supported.get(f, {}) - if ignore_groups and is_group: - continue - implies = self.feature_sorted(self.feature_implies(f)) - implies = ' '.join([fstyle_implies(f, i) for i in implies]) - rows.append([fstyle(f), implies]) - if rows: - return self.gen_rst_table(field_names, rows, **kwargs) - - def gen_gfeatures_table(self, features, - field_names=["Name", "Gather", "Implies"], - fstyle=None, fstyle_implies=None, **kwargs): - rows = [] - if fstyle is None: - fstyle = lambda ft: f'``{ft}``' - if fstyle_implies is None: - fstyle_implies = lambda origin, ft: fstyle(ft) - for f in self.feature_sorted(features): - gather = self.feature_supported.get(f, {}).get("group", None) - if not gather: - continue - implies = self.feature_sorted(self.feature_implies(f)) - implies = ' '.join([fstyle_implies(f, i) for i in implies]) - gather = ' '.join([fstyle_implies(f, i) for i in gather]) - rows.append([fstyle(f), gather, implies]) - if rows: - return self.gen_rst_table(field_names, rows, **kwargs) - - def gen_rst_table(self, field_names, rows, tab_size=4): - assert(not rows or len(field_names) == len(rows[0])) - rows.append(field_names) - fld_len = len(field_names) - cls_len = [max(len(c[i]) for c in rows) for i in range(fld_len)] - del rows[-1] - cformat = ' '.join('{:<%d}' % i for i in cls_len) - border = cformat.format(*['='*i for i in cls_len]) - - rows = [cformat.format(*row) for row in rows] - # header - rows = [border, cformat.format(*field_names), border] + rows - # footer - rows += [border] - # add left margin - rows = [(' ' * tab_size) + r for r in rows] - return '\n'.join(rows) - -def features_table_sections(name, ftable=None, gtable=None, tab_size=4): - tab = ' '*tab_size - content = '' - if ftable: - title = f"{name} - CPU feature names" - content = ( - f"{title}\n{'~'*len(title)}" - f"\n.. table::\n{tab}:align: left\n\n" - f"{ftable}\n\n" - ) - if gtable: - title = f"{name} - Group names" - content += ( - f"{title}\n{'~'*len(title)}" - f"\n.. table::\n{tab}:align: left\n\n" - f"{gtable}\n\n" - ) - return content - -def features_table(arch, cc="gcc", pretty_name=None, **kwargs): - FakeCCompilerOpt.fake_info = (arch, cc, '') - ccopt = FakeCCompilerOpt(cpu_baseline="max") - features = ccopt.cpu_baseline_names() - ftable = ccopt.gen_features_table(features, **kwargs) - gtable = ccopt.gen_gfeatures_table(features, **kwargs) - - if not pretty_name: - pretty_name = arch + '/' + cc - return features_table_sections(pretty_name, ftable, gtable, **kwargs) - -def features_table_diff(arch, cc, cc_vs="gcc", pretty_name=None, **kwargs): - FakeCCompilerOpt.fake_info = (arch, cc, '') - ccopt = FakeCCompilerOpt(cpu_baseline="max") - fnames = ccopt.cpu_baseline_names() - features = {f:ccopt.feature_implies(f) for f in fnames} - - FakeCCompilerOpt.fake_info = (arch, cc_vs, '') - ccopt_vs = FakeCCompilerOpt(cpu_baseline="max") - fnames_vs = ccopt_vs.cpu_baseline_names() - features_vs = {f:ccopt_vs.feature_implies(f) for f in fnames_vs} - - common = set(fnames).intersection(fnames_vs) - extra_avl = set(fnames).difference(fnames_vs) - not_avl = set(fnames_vs).difference(fnames) - diff_impl_f = {f:features[f].difference(features_vs[f]) for f in common} - diff_impl = {k for k, v in diff_impl_f.items() if v} - - fbold = lambda ft: f'**{ft}**' if ft in extra_avl else f'``{ft}``' - fbold_implies = lambda origin, ft: ( - f'**{ft}**' if ft in diff_impl_f.get(origin, {}) else f'``{ft}``' - ) - diff_all = diff_impl.union(extra_avl) - ftable = ccopt.gen_features_table( - diff_all, fstyle=fbold, fstyle_implies=fbold_implies, **kwargs - ) - gtable = ccopt.gen_gfeatures_table( - diff_all, fstyle=fbold, fstyle_implies=fbold_implies, **kwargs - ) - if not pretty_name: - pretty_name = arch + '/' + cc - content = features_table_sections(pretty_name, ftable, gtable, **kwargs) - - if not_avl: - not_avl = ccopt_vs.feature_sorted(not_avl) - not_avl = ' '.join(not_avl) - content += ( - ".. note::\n" - f" The following features aren't supported by {pretty_name}:\n" - f" **{not_avl}**\n\n" - ) - return content - -if __name__ == '__main__': - pretty_names = { - "PPC64": "IBM/POWER big-endian", - "PPC64LE": "IBM/POWER little-endian", - "ARMHF": "ARMv7/A32", - "AARCH64": "ARMv8/A64", - "ICC": "Intel Compiler", - # "ICCW": "Intel Compiler msvc-like", - "MSVC": "Microsoft Visual C/C++" - } - with open(path.join(gen_path, 'simd-optimizations-tables.inc'), 'wt') as fd: - fd.write(f'.. generated via {__file__}\n\n') - for arch in ( - ("x86", "PPC64", "PPC64LE", "ARMHF", "AARCH64") - ): - pretty_name = pretty_names.get(arch, arch) - table = features_table(arch=arch, pretty_name=pretty_name) - assert(table) - fd.write(table) - - with open(path.join(gen_path, 'simd-optimizations-tables-diff.inc'), 'wt') as fd: - fd.write(f'.. generated via {__file__}\n\n') - for arch, cc_names in ( - ("x86", ("clang", "ICC", "MSVC")), - ("PPC64", ("clang",)), - ("PPC64LE", ("clang",)), - ("ARMHF", ("clang",)), - ("AARCH64", ("clang",)) - ): - arch_pname = pretty_names.get(arch, arch) - for cc in cc_names: - pretty_name = f"{arch_pname}::{pretty_names.get(cc, cc)}" - table = features_table_diff(arch=arch, cc=cc, pretty_name=pretty_name) - if table: - fd.write(table) -- cgit v1.2.1