CoolFace
Apppublic

Aluode/PerceptionLabPortable

sourceHugging Faceupdated 9mo agoView on Hugging Face
0likes
generate_lower_listing.py170 linesDownload Raw Back to scripts
1"""
2Generate documentation for all registered implementation for lowering
3using reStructured text.
4"""
5
6
7from subprocess import check_output
8
9import os.path
10try:
11    from StringIO import StringIO       # py2
12except ImportError:
13    from io import StringIO
14from collections import defaultdict
15import inspect
16from functools import partial
17
18import numba
19from numba.core.registry import cpu_target
20
21
22def git_hash():
23    out = check_output(['git', 'log', "--pretty=format:'%H'", '-n', '1'])
24    return out.decode('ascii').strip("'\"")
25
26
27def get_func_name(fn):
28    return getattr(fn, '__qualname__', fn.__name__)
29
30
31def gather_function_info(backend):
32    fninfos = defaultdict(list)
33    basepath = os.path.dirname(os.path.dirname(numba.__file__))
34    for fn, osel in backend._defns.items():
35        for sig, impl in osel.versions:
36            info = {}
37            fninfos[fn].append(info)
38            info['fn'] = fn
39            info['sig'] = sig
40            code, firstlineno = inspect.getsourcelines(impl)
41            path = inspect.getsourcefile(impl)
42            info['impl'] = {
43                'name': get_func_name(impl),
44                'filename': os.path.relpath(path, start=basepath),
45                'lines': (firstlineno, firstlineno + len(code) - 1),
46                'docstring': impl.__doc__
47            }
48
49    return fninfos
50
51
52def bind_file_to_print(fobj):
53    return partial(print, file=fobj)
54
55
56def format_signature(sig):
57    def fmt(c):
58        try:
59            return c.__name__
60        except AttributeError:
61            return repr(c).strip('\'"')
62    out = tuple(map(fmt, sig))
63    return '`({0})`'.format(', '.join(out))
64
65
66github_url = ('https://github.com/numba/numba/blob/'
67              '{commit}/{path}#L{firstline}-L{lastline}')
68
69description = """
70This lists all lowering definition registered to the CPU target.
71Each subsection corresponds to a Python function that is supported by numba
72nopython mode. These functions have one or more lower implementation with
73different signatures. The compiler chooses the most specific implementation
74from all overloads.
75"""
76
77
78def format_function_infos(fninfos):
79    buf = StringIO()
80    try:
81        print = bind_file_to_print(buf)
82
83        title_line = "Lowering Listing"
84        print(title_line)
85        print('=' * len(title_line))
86
87        print(description)
88
89        commit = git_hash()
90
91        def format_fname(fn):
92            try:
93                fname = "{0}.{1}".format(fn.__module__, get_func_name(fn))
94            except AttributeError:
95                fname = repr(fn)
96            return fn, fname
97
98        for fn, fname in sorted(map(format_fname, fninfos), key=lambda x: x[1]):
99            impinfos = fninfos[fn]
100            header_line = "``{0}``".format(fname)
101            print(header_line)
102            print('-' * len(header_line))
103            print()
104
105            formatted_sigs = map(
106                lambda x: format_signature(x['sig']), impinfos)
107            sorted_impinfos = sorted(zip(formatted_sigs, impinfos),
108                                     key=lambda x: x[0])
109
110            col_signatures = ['Signature']
111            col_urls = ['Definition']
112
113            for fmtsig, info in sorted_impinfos:
114                impl = info['impl']
115
116                filename = impl['filename']
117                lines = impl['lines']
118                fname = impl['name']
119
120                source = '{0} lines {1}-{2}'.format(filename, *lines)
121                link = github_url.format(commit=commit, path=filename,
122                                         firstline=lines[0], lastline=lines[1])
123                url = '``{0}`` `{1} <{2}>`_'.format(fname, source, link)
124
125                col_signatures.append(fmtsig)
126                col_urls.append(url)
127
128            # table formatting
129            max_width_col_sig = max(map(len, col_signatures))
130            max_width_col_url = max(map(len, col_urls))
131            padding = 2
132            width_col_sig = padding * 2 + max_width_col_sig
133            width_col_url = padding * 2 + max_width_col_url
134            line_format = "{{0:^{0}}}  {{1:^{1}}}".format(width_col_sig,
135                                                          width_col_url)
136            print(line_format.format('=' * width_col_sig, '=' * width_col_url))
137            print(line_format.format(col_signatures[0], col_urls[0]))
138            print(line_format.format('=' * width_col_sig, '=' * width_col_url))
139            for sig, url in zip(col_signatures[1:], col_urls[1:]):
140                print(line_format.format(sig, url))
141            print(line_format.format('=' * width_col_sig, '=' * width_col_url))
142            print()
143
144        return buf.getvalue()
145    finally:
146        buf.close()
147
148
149# Main routine for this module:
150
151def gen_lower_listing(path=None):
152    """
153    Generate lowering listing to ``path`` or (if None) to stdout.
154    """
155    cpu_backend = cpu_target.target_context
156    cpu_backend.refresh()
157
158    fninfos = gather_function_info(cpu_backend)
159    out = format_function_infos(fninfos)
160
161    if path is None:
162        print(out)
163    else:
164        with open(path, 'w') as fobj:
165            print(out, file=fobj)
166
167
168if __name__ == '__main__':
169    gen_lower_listing()
170 
Aluode/PerceptionLabPortable · CoolFace