xref: /aosp_15_r20/external/XNNPACK/tools/generate-enum-strings.py (revision 4bdc94577ba0e567308109d787f7fec7b531ce36)
1#!/usr/bin/env python
2# Copyright 2022 Google LLC
3#
4# This source code is licensed under the BSD-style license found in the
5# LICENSE file in the root directory of this source tree.
6
7import argparse
8import codecs
9import math
10import os
11import re
12import sys
13import yaml
14
15sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
16import xngen
17import xnncommon
18
19parser = argparse.ArgumentParser(
20    description="Generates operator-strings code.")
21parser.add_argument(
22    "-s",
23    "--spec",
24    metavar="FILE",
25    required=True,
26    help="Specification (YAML) file")
27parser.add_argument(
28    "-o",
29    "--output",
30    metavar="FILE",
31    required=True,
32    help="Output (C source) file")
33parser.add_argument(
34    "-e",
35    "--enum",
36    metavar="FILE",
37    required=True,
38    help="Enum to generate")
39parser.set_defaults(defines=list())
40
41
42def main(args):
43  options = parser.parse_args(args)
44
45  with codecs.open(options.spec, "r", encoding="utf-8") as spec_file:
46    spec_yaml = yaml.safe_load(spec_file)
47    if not isinstance(spec_yaml, list):
48      raise ValueError("expected a list of operators in the spec")
49
50    output = """\
51// Copyright 2022 Google LLC
52//
53// This source code is licensed under the BSD-style license found in the
54// LICENSE file in the root directory of this source tree.
55//
56// Auto-generated file. Do not edit!
57//   Specification: {specification}
58//   Generator: {generator}
59
60
61#include <assert.h>
62#include <stdint.h>
63
64#include <xnnpack/{enum}-type.h>
65
66""".format(
67    specification=options.spec, generator=sys.argv[0], enum=options.enum)
68
69    all_strings = ''
70    pos = 0
71    offset = "static const uint16_t offset[] = {";
72    last_member = ""
73    for ukernel_spec in spec_yaml:
74      name = ukernel_spec["name"]
75      string = ukernel_spec["string"]
76
77      all_strings +=  '    "' + string + '\\0"\n'
78
79      offset += str(pos) + ","
80      pos += len(string) + 1
81      last_member = name
82
83    offset = offset[:-1] + "};"
84    output += offset + '\n\n';
85    output += """static const char *data =
86{all_strings};
87""".format(all_strings=all_strings)
88
89    output += """
90const char* xnn_{enum}_type_to_string(enum xnn_{enum}_type type) {{
91  assert(type <= {last_member});
92  return &data[offset[type]];
93}}""".format(last_member=last_member, enum=options.enum)
94
95    txt_changed = True
96    if os.path.exists(options.output):
97      with codecs.open(options.output, "r", encoding="utf-8") as output_file:
98        txt_changed = output_file.read() != output
99
100    if txt_changed:
101      with codecs.open(options.output, "w", encoding="utf-8") as output_file:
102        output_file.write(output)
103
104
105if __name__ == "__main__":
106  main(sys.argv[1:])
107