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 6.1 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  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. if e.combined:
  84. enum_def += "], 1"
  85. else:
  86. enum_def += "], 0"
  87. if ENUM_TO_STRING_SPECIAL_RULES.count((p.name, e.name)):
  88. enum_def += ", 1" # whether generate ToStringTrait
  89. enum_def += ">"
  90. self._write("def {} : {};".format(td_class, enum_def))
  91. if self._skip_current_param:
  92. return
  93. # wrapped with default value
  94. if e.combined:
  95. default_val = "static_cast<{}::{}>({})".format(
  96. fullname, e.name, e.compose_combined_enum(e.default))
  97. else:
  98. default_val = "{}::{}::{}".format(fullname, e.name, e.members[e.default])
  99. wrapped = self._wrapped_with_default_value(td_class, default_val)
  100. self._current_tparams.append("{}:${}".format(wrapped, e.name_field))
  101. def _on_member_enum_alias(self, e):
  102. p = self._last_param
  103. if self._skip_current_param:
  104. return
  105. # write enum attr def
  106. td_class = "{}{}".format(p.name, e.name)
  107. fullname = "::megdnn::param::{}".format(p.name)
  108. base_td_class = "{}{}".format(e.src_class, e.src_name)
  109. enum_def = "MgbEnumAliasAttr<\"{}\", \"{}\", {}>".format(fullname, e.name, base_td_class)
  110. self._write("def {} : {};".format(td_class, enum_def))
  111. # wrapped with default value
  112. s = e.src_enum
  113. if s.combined:
  114. default_val = "static_cast<{}::{}>({})".format(
  115. fullname, e.name, s.compose_combined_enum(e.get_default()))
  116. else:
  117. default_val = "{}::{}::{}".format(fullname, e.name, s.members[e.get_default()])
  118. wrapped = self._wrapped_with_default_value(td_class, default_val)
  119. self._current_tparams.append("{}:${}".format(wrapped, e.name_field))
  120. def _on_member_field(self, f):
  121. if self._skip_current_param:
  122. return
  123. attr, value = self._ctype2attr(f.dtype.cname, str(f.default))
  124. if str(value) in self._const:
  125. value = '::megdnn::param::{}::{}'.format(self._last_param.name, value)
  126. wrapped = self._wrapped_with_default_value(attr, value)
  127. self._current_tparams.append("{}:${}".format(wrapped, f.name))
  128. def _on_const_field(self, f):
  129. self._const.add(str(f.name))
  130. def main():
  131. parser = argparse.ArgumentParser('generate op param tablegen file')
  132. parser.add_argument('input')
  133. parser.add_argument('output')
  134. args = parser.parse_args()
  135. with open(args.input) as fin:
  136. inputs = fin.read()
  137. exec(inputs, {'pdef': ParamDef, 'Doc': member_defs.Doc})
  138. input_hash = hashlib.sha256()
  139. input_hash.update(inputs.encode(encoding='UTF-8'))
  140. input_hash = input_hash.hexdigest()
  141. writer = ConverterWriter()
  142. with open(args.output, 'w') as fout:
  143. writer.set_input_hash(input_hash)(fout, ParamDef.all_param_defs)
  144. if __name__ == "__main__":
  145. main()

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