1#!/usr/bin/which python 2# Command line tool to load an oplib module and dump all of the operations 3# it contains in some format. 4"""Loads one or more modules containing op definitions and dumps them. 5 6The dump format can be: 7 8* `--dump_format=yaml` (default) 9* `--dump_format=repr` 10 11Positional arguments are interpreted as module names (optionally, relative to 12this module). Loose module files can be specified via `--file <filepath>`. 13 14Sample usage: 15 # Dump the YAML op definitions for the core named ops (as in the dialect 16 # source tree). 17 python -m mlir.dialects.linalg.opdsl.dump_oplib .ops.core_named_ops 18 19Note: YAML output is emitted in "document list" format with each operation 20as its own "document". Practically, this means that each operation (or group 21of composite ops) is emitted with a "---" preceding it, which can be useful 22for testing. 23""" 24 25import argparse 26import importlib 27 28from .lang import * 29from .lang.config import * 30from .lang.yaml_helper import * 31 32 33def create_arg_parser() -> argparse.ArgumentParser: 34 p = argparse.ArgumentParser(description="Dump an oplib in various formats") 35 p.add_argument( 36 "modules", metavar="M", type=str, nargs="*", help="Op module to dump" 37 ) 38 p.add_argument( 39 "--file", metavar="F", type=str, nargs="*", help="Python op file to dump" 40 ) 41 p.add_argument( 42 "--format", 43 type=str, 44 dest="format", 45 default="yaml", 46 choices=("yaml", "repr"), 47 help="Format in which to dump", 48 ) 49 return p 50 51 52def load_module_from_file(module_name, file_path): 53 spec = importlib.util.spec_from_file_location(module_name, file_path) 54 m = importlib.util.module_from_spec(spec) 55 spec.loader.exec_module(m) 56 return m 57 58 59def main(args): 60 # Load all configs. 61 configs = [] 62 modules = [] 63 for module_name in args.modules: 64 modules.append( 65 importlib.import_module(module_name, package="mlir.dialects.linalg.opdsl") 66 ) 67 for i, file_path in enumerate(args.file or []): 68 modules.append(load_module_from_file(f"_mlir_eval_oplib{i}", file_path)) 69 for m in modules: 70 for attr_name, value in m.__dict__.items(): 71 # TODO: This class layering is awkward. 72 if isinstance(value, DefinedOpCallable): 73 try: 74 linalg_config = LinalgOpConfig.from_linalg_op_def(value.op_def) 75 except Exception as e: 76 raise ValueError( 77 f"Could not create LinalgOpConfig from {value.op_def}" 78 ) from e 79 configs.extend(linalg_config) 80 81 # Print. 82 if args.format == "yaml": 83 print(yaml_dump_all(configs)) 84 elif args.format == "repr": 85 for config in configs: 86 print(repr(config)) 87 88 89if __name__ == "__main__": 90 main(create_arg_parser().parse_args()) 91