You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

gen_tablegen.py 5.7 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. import argparse
  4. import collections
  5. import textwrap
  6. import os
  7. import hashlib
  8. import struct
  9. import io
  10. from gen_param_defs import member_defs, ParamDef, IndentWriterBase
  11. # FIXME: move supportToString flag definition into the param def source file
  12. ENUM_TO_STRING_SPECIAL_RULES = [
  13. ("Elemwise", "Mode"),
  14. ("ElemwiseMultiType", "Mode")
  15. ]
  16. class ConverterWriter(IndentWriterBase):
  17. _skip_current_param = False
  18. _last_param = None
  19. _current_tparams = None
  20. _packed = None
  21. _const = None
  22. def __call__(self, fout, defs):
  23. super().__call__(fout)
  24. self._write("// %s", self._get_header())
  25. self._write("#ifndef MGB_PARAM")
  26. self._write("#define MGB_PARAM")
  27. self._process(defs)
  28. self._write("#endif // MGB_PARAM")
  29. def _ctype2attr(self, ctype, value):
  30. if ctype == 'uint32_t':
  31. return 'MgbUI32Attr', value
  32. if ctype == 'uint64_t':
  33. return 'MgbUI64Attr', value
  34. if ctype == 'int32_t':
  35. return 'MgbI32Attr', value
  36. if ctype == 'float':
  37. return 'MgbF32Attr', value
  38. if ctype == 'double':
  39. return 'MgbF64Attr', value
  40. if ctype == 'bool':
  41. return 'MgbBoolAttr', value
  42. if ctype == 'DTypeEnum':
  43. self._packed = False
  44. return 'MgbDTypeAttr', 'megdnn::DType::from_enum(megdnn::{})'.format(value)
  45. raise RuntimeError("unknown ctype")
  46. def _on_param_begin(self, p):
  47. self._last_param = p
  48. if p.is_legacy:
  49. self._skip_current_param = True
  50. return
  51. self._packed = True
  52. self._current_tparams = []
  53. self._const = set()
  54. def _on_param_end(self, p):
  55. if self._skip_current_param:
  56. self._skip_current_param = False
  57. return
  58. if self._packed:
  59. self._write("class {0}ParamBase<string accessor> : MgbPackedParamBase<\"{0}\", accessor> {{".format(p.name), indent=1)
  60. else:
  61. self._write("def {0}Param: MgbParamBase<\"{0}\"> {{".format(p.name), indent=1)
  62. self._write("let fields = (ins", indent=1)
  63. self._write(",\n{}".format(self._cur_indent).join(self._current_tparams))
  64. self._write(");", indent=-1)
  65. self._write("}\n", indent=-1)
  66. if self._packed:
  67. self._write("def {0}Param : {0}ParamBase<\"param\">;\n".format(p.name))
  68. self._current_tparams = None
  69. self._packed = None
  70. self._const = None
  71. def _wrapped_with_default_value(self, attr, default):
  72. return 'MgbDefaultValuedAttr<{}, \"{}\">'.format(attr, default)
  73. def _on_member_enum(self, e):
  74. p = self._last_param
  75. # Note: always generate llvm Record def for enum attribute even it was not
  76. # directly used by any operator, or other enum couldn't alias to this enum
  77. td_class = "{}{}".format(p.name, e.name)
  78. fullname = "::megdnn::param::{}".format(p.name)
  79. enum_def = "MgbEnumAttr<\"{}\", \"{}\", [".format(fullname, e.name)
  80. def format(v):
  81. return '\"{}\"'.format(str(v))
  82. enum_def += ','.join(format(i) for i in e.members)
  83. enum_def += "]"
  84. if ENUM_TO_STRING_SPECIAL_RULES.count((p.name, e.name)):
  85. enum_def += ", 1" # whether generate ToStringTrait
  86. enum_def += ">"
  87. self._write("def {} : {};".format(td_class, enum_def))
  88. if self._skip_current_param:
  89. return
  90. # wrapped with default value
  91. default_val = "static_cast<{}::{}>({})".format(fullname, e.name, e.default)
  92. wrapped = self._wrapped_with_default_value(td_class, default_val)
  93. self._current_tparams.append("{}:${}".format(wrapped, e.name_field))
  94. def _on_member_enum_alias(self, e):
  95. p = self._last_param
  96. if self._skip_current_param:
  97. return
  98. # write enum attr def
  99. td_class = "{}{}".format(p.name, e.name)
  100. fullname = "::megdnn::param::{}".format(p.name)
  101. base_td_class = "{}{}".format(e.src_class, e.src_name)
  102. enum_def = "MgbEnumAliasAttr<\"{}\", \"{}\", {}>".format(fullname, e.name, base_td_class)
  103. self._write("def {} : {};".format(td_class, enum_def))
  104. # wrapped with default value
  105. default_val = "static_cast<{}::{}>({})".format(fullname, e.name, e.get_default())
  106. wrapped = self._wrapped_with_default_value(td_class, default_val)
  107. self._current_tparams.append("{}:${}".format(wrapped, e.name_field))
  108. def _on_member_field(self, f):
  109. if self._skip_current_param:
  110. return
  111. attr, value = self._ctype2attr(f.dtype.cname, str(f.default))
  112. if str(value) in self._const:
  113. value = '::megdnn::param::{}::{}'.format(self._last_param.name, value)
  114. wrapped = self._wrapped_with_default_value(attr, value)
  115. self._current_tparams.append("{}:${}".format(wrapped, f.name))
  116. def _on_const_field(self, f):
  117. self._const.add(str(f.name))
  118. def main():
  119. parser = argparse.ArgumentParser('generate op param tablegen file')
  120. parser.add_argument('input')
  121. parser.add_argument('output')
  122. args = parser.parse_args()
  123. with open(args.input) as fin:
  124. inputs = fin.read()
  125. exec(inputs, {'pdef': ParamDef, 'Doc': member_defs.Doc})
  126. input_hash = hashlib.sha256()
  127. input_hash.update(inputs.encode(encoding='UTF-8'))
  128. input_hash = input_hash.hexdigest()
  129. writer = ConverterWriter()
  130. with open(args.output, 'w') as fout:
  131. writer.set_input_hash(input_hash)(fout, ParamDef.all_param_defs)
  132. if __name__ == "__main__":
  133. main()

MegEngine 安装包中集成了使用 GPU 运行代码所需的 CUDA 环境,不用区分 CPU 和 GPU 版。 如果想要运行 GPU 程序,请确保机器本身配有 GPU 硬件设备并安装好驱动。 如果你想体验在云端 GPU 算力平台进行深度学习开发的感觉,欢迎访问 MegStudio 平台