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