diff --git a/flang/examples/flang-omp-report-plugin/yaml_summarizer.py b/flang/examples/flang-omp-report-plugin/yaml_summarizer.py new file mode 100644 --- /dev/null +++ b/flang/examples/flang-omp-report-plugin/yaml_summarizer.py @@ -0,0 +1,134 @@ +"""YAML Summariser + +This Python script generates a YAML summary from +the files generated by ``flang-omp-report``. +Currently, it only support ``ruamel.yaml``, +which can be installed with: + + ``pip3 install ruamel.yaml`` + +By default it scans the directory it is ran in +for any YAML files and outputs a summary to +stdout. It can be ran as: + + ``python3 yaml_summarizer.py`` + +Parameters: + + -d --directory Specify which directory to scan + + -l --log This option combines all yaml files into one + + -o --output Specify a directory in which to save the summary file + +Examples: + + ``python3 yaml_summarizer.py -d ~/llvm-project/build/`` + + ``python3 yaml_summarizer.py -l -o ~/examples/`` +""" + +import sys +import glob +import argparse +from pathlib import Path + +MODULE = True +try: + from ruamel.yaml import YAML +except ImportError: + MODULE = False + +parser = argparse.ArgumentParser() +parser.add_argument("-d", "--directory", help="Specify a directory to scan", + dest="dir", type=str) +parser.add_argument("-l", "--log", help="Combines the log files instead of\ + writing out a summary", dest="log") +parser.add_argument("-o", "--output", help="Writes to a file instead of\ + stdout", dest="output", type=str) + +def hasYaml(path=None, log=None, output=None): + yaml = YAML() + if path: + files_to_scan = glob.iglob(path) + else: + files_to_scan = glob.iglob('*.yaml') + + file_yaml_summary = [] # Keeps track of the total amount of constructs seen + file_yaml_log = dict() # Keeps track of constructs and the line they're on + for file in files_to_scan: + with open(file) as f: + data = yaml.load(f) + for datum in data: + items = file_yaml_log.get(datum['file'], []) + items.append({"construct" : datum['construct'], + "line" : datum['line'], + "clauses" : datum['clauses']}) + file_yaml_log[datum['file']] = items + + construct = next((item for item in file_yaml_summary + if item["construct"] == datum["construct"]), None) + clauses = [] + # Add the construct and clauses to the summary if + # they haven't been seen before + if not construct: + for i in datum['clauses']: + clauses.append({"clause" : i['clause'], + "num" : 1}) + file_yaml_summary.append({"construct" : datum['construct'], + "num" : 1, + "clauses" : clauses}) + else: + construct["num"] += 1 + + # Add clauses to the construct if they're missing + # Otherwise increment their count by one + to_check = [i['clause'] for i in construct['clauses']] + to_add = [i['clause'] for i in datum['clauses']] + clauses = construct["clauses"] + for item in to_add: + if item in to_check: + for clause in clauses: + if clause["clause"] == item: + clause["num"] += 1 + else: + clauses.append({"clause" : item, + "num" : 1}) + + if log: + if output: + with open(output, 'w') as f: + yaml.dump(file_yaml_log, f) + else: + yaml.dump(file_yaml_log, sys.stdout) + else: + if output: + with open(output, 'w') as f: + yaml.dump(file_yaml_summary, f) + else: + yaml.dump(file_yaml_summary, sys.stdout) + +def hasNotYaml(): + print("Currently this script only works with\ + ``ruamel.yaml`` installed.") + sys.exit(1) + +if __name__ == "__main__": + if MODULE: + args = parser.parse_args() + + p = None + if args.dir: + p = str(Path(args.dir).joinpath("*.yaml")) + + l = None + if args.log: + l = True + + o = None + if args.output: + o = Path(args.output).joinpath("summary.yaml") + + hasYaml(p, l, o) + else: + hasNotYaml()