[llvm] 0e34347 - [llvm-mca] Compare multiple files

Andrea Di Biagio via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 21 04:55:50 PST 2021


For the future: if you ar committing a patch on behalf of somebody else,
you should set the ‘Author’ property using the following command:

‘git commit --amend --author’

(See https://llvm.org/docs/DeveloperPolicy.html#commit-messages)

On Tue, 21 Dec 2021 at 10:57, Djordje Todorovic via llvm-commits <
llvm-commits at lists.llvm.org> wrote:

>
> Author: Djordje Todorovic
> Date: 2021-12-21T11:56:18+01:00
> New Revision: 0e343479a7ea9cabac8c467cd24bc3ed463b8786
>
> URL:
> https://github.com/llvm/llvm-project/commit/0e343479a7ea9cabac8c467cd24bc3ed463b8786
> DIFF:
> https://github.com/llvm/llvm-project/commit/0e343479a7ea9cabac8c467cd24bc3ed463b8786.diff
>
> LOG: [llvm-mca] Compare multiple files
>
> Script (llvm-mca-compare.py) uses llvm-mca tool to print
> statistics in console for multiple files.
> Script requires specified --llvm-mca-binary option (specified
> relative path to binary of llvm-mca).
> Options: --args [="-option1=<arg> -option2=<arg> ..."], -v or -h can also
> be used.
>
> The script is used as follows:
> $ llvm-project/llvm/utils/llvm-mca-compare.py file1.s
> --llvm-mca-binary=build/bin/llvm-mca
>
> Patch by Milica Matic <Milica.Matic at syrmia.com>
>
> Differential Revision: https://reviews.llvm.org/D115138
>
> Added:
>     llvm/utils/llvm-mca-compare.py
>
> Modified:
>
>
> Removed:
>
>
>
>
> ################################################################################
> diff  --git a/llvm/utils/llvm-mca-compare.py
> b/llvm/utils/llvm-mca-compare.py
> new file mode 100755
> index 0000000000000..72c875d424422
> --- /dev/null
> +++ b/llvm/utils/llvm-mca-compare.py
> @@ -0,0 +1,279 @@
> +#!/usr/bin/env python3
> +
> +import argparse
> +import sys
> +from json import loads
> +from subprocess import Popen, PIPE
> +
> +# Holds code regions statistics.
> +class Summary:
> +    def __init__(
> +        self,
> +        name,
> +        block_rthroughput,
> +        dispatch_width,
> +        ipc,
> +        instructions,
> +        iterations,
> +        total_cycles,
> +        total_uops,
> +        uops_per_cycle,
> +        iteration_resource_pressure,
> +        name_target_info_resources,
> +    ):
> +        self.name = name
> +        self.block_rthroughput = block_rthroughput
> +        self.dispatch_width = dispatch_width
> +        self.ipc = ipc
> +        self.instructions = instructions
> +        self.iterations = iterations
> +        self.total_cycles = total_cycles
> +        self.total_uops = total_uops
> +        self.uops_per_cycle = uops_per_cycle
> +        self.iteration_resource_pressure = iteration_resource_pressure
> +        self.name_target_info_resources = name_target_info_resources
> +
> +
> +# Parse the program arguments.
> +def parse_program_args(parser):
> +    parser.add_argument(
> +        "file_names",
> +        nargs="+",
> +        type=str,
> +        help="Names of files which llvm-mca tool process.",
> +    )
> +    parser.add_argument(
> +        "--llvm-mca-binary",
> +        nargs=1,
> +        required=True,
> +        type=str,
> +        action="store",
> +        metavar="[=<path to llvm-mca>]",
> +        help="Specified relative path to binary of llvm-mca.",
> +    )
> +    parser.add_argument(
> +        "--args",
> +        nargs=1,
> +        type=str,
> +        action="store",
> +        metavar="[='-option1=<arg> -option2=<arg> ...']",
> +        default=["-"],
> +        help="Forward options to lvm-mca tool.",
> +    )
> +    parser.add_argument(
> +        "-v",
> +        action="store_true",
> +        default=False,
> +        help="More details about the running lvm-mca tool.",
> +    )
> +    return parser.parse_args()
> +
> +
> +# Returns the name of the file to be analyzed from the path it is on.
> +def get_filename_from_path(path):
> +    index_of_slash = path.rfind("/")
> +    return path[(index_of_slash + 1) : len(path)]
> +
> +
> +# Returns the results of the running llvm-mca tool for the input file.
> +def run_llvm_mca_tool(opts, file_name):
> +    # Get the path of the llvm-mca binary file.
> +    llvm_mca_cmd = opts.llvm_mca_binary[0]
> +
> +    # The statistics llvm-mca options.
> +    if opts.args[0] != "-":
> +        llvm_mca_cmd += " " + opts.args[0]
> +    llvm_mca_cmd += " -json"
> +
> +    # Set file which llvm-mca tool will process.
> +    llvm_mca_cmd += " " + file_name
> +
> +    if opts.v:
> +        print("run: $ " + llvm_mca_cmd + "\n")
> +
> +    # Generate the stats with the llvm-mca.
> +    subproc = Popen(
> +        llvm_mca_cmd.split(" "),
> +        stdin=PIPE,
> +        stdout=PIPE,
> +        stderr=PIPE,
> +        universal_newlines=True,
> +    )
> +
> +    cmd_stdout, cmd_stderr = subproc.communicate()
> +
> +    try:
> +        json_parsed = loads(cmd_stdout)
> +    except:
> +        print("error: No valid llvm-mca statistics found.")
> +        print(cmd_stderr)
> +        sys.exit(1)
> +
> +    if opts.v:
> +        print("Simulation Parameters: ")
> +        simulation_parameters = json_parsed["SimulationParameters"]
> +        for key in simulation_parameters:
> +            print(key, ":", simulation_parameters[key])
> +        print("\n")
> +
> +    code_regions_len = len(json_parsed["CodeRegions"])
> +    array_of_code_regions = [None] * code_regions_len
> +
> +    for i in range(code_regions_len):
> +        code_region_instructions_len = len(
> +            json_parsed["CodeRegions"][i]["Instructions"]
> +        )
> +        target_info_resources_len =
> len(json_parsed["TargetInfo"]["Resources"])
> +        iteration_resource_pressure = ["-" for k in
> range(target_info_resources_len)]
> +        resource_pressure_info =
> json_parsed["CodeRegions"][i]["ResourcePressureView"][
> +            "ResourcePressureInfo"
> +        ]
> +
> +        name_target_info_resources = [" "] +
> json_parsed["TargetInfo"]["Resources"]
> +
> +        for s in range(len(resource_pressure_info)):
> +            obj_of_resource_pressure_info = resource_pressure_info[s]
> +            if (
> +                obj_of_resource_pressure_info["InstructionIndex"]
> +                == code_region_instructions_len
> +            ):
> +                iteration_resource_pressure[
> +                    obj_of_resource_pressure_info["ResourceIndex"]
> +                ] =
> str(round(obj_of_resource_pressure_info["ResourceUsage"], 2))
> +
> +        array_of_code_regions[i] = Summary(
> +            file_name,
> +
> json_parsed["CodeRegions"][i]["SummaryView"]["BlockRThroughput"],
> +            json_parsed["CodeRegions"][i]["SummaryView"]["DispatchWidth"],
> +            json_parsed["CodeRegions"][i]["SummaryView"]["IPC"],
> +            json_parsed["CodeRegions"][i]["SummaryView"]["Instructions"],
> +            json_parsed["CodeRegions"][i]["SummaryView"]["Iterations"],
> +            json_parsed["CodeRegions"][i]["SummaryView"]["TotalCycles"],
> +            json_parsed["CodeRegions"][i]["SummaryView"]["TotaluOps"],
> +            json_parsed["CodeRegions"][i]["SummaryView"]["uOpsPerCycle"],
> +            iteration_resource_pressure,
> +            name_target_info_resources,
> +        )
> +
> +    return array_of_code_regions
> +
> +
> +# Print statistics in console for single file or for multiple files.
> +def console_print_results(matrix_of_code_regions, opts):
> +    try:
> +        import termtables as tt
> +    except ImportError:
> +        print("error: termtables not found.")
> +        sys.exit(1)
> +
> +    headers_names = [None] * (len(opts.file_names) + 1)
> +    headers_names[0] = " "
> +
> +    max_code_regions = 0
> +
> +    print("Input files:")
> +    for i in range(len(matrix_of_code_regions)):
> +        if max_code_regions < len(matrix_of_code_regions[i]):
> +            max_code_regions = len(matrix_of_code_regions[i])
> +        print("[f" + str(i + 1) + "]: " +
> get_filename_from_path(opts.file_names[i]))
> +        headers_names[i + 1] = "[f" + str(i + 1) + "]: "
> +
> +    print("\nITERATIONS: " + str(matrix_of_code_regions[0][0].iterations)
> + "\n")
> +
> +    for i in range(max_code_regions):
> +
> +        print(
> +            "\n-----------------------------------------\nCode region: "
> +            + str(i + 1)
> +            + "\n"
> +        )
> +
> +        table_values = [
> +            [[None] for i in range(len(matrix_of_code_regions) + 1)] for
> j in range(7)
> +        ]
> +
> +        table_values[0][0] = "Instructions: "
> +        table_values[1][0] = "Total Cycles: "
> +        table_values[2][0] = "Total uOps: "
> +        table_values[3][0] = "Dispatch Width: "
> +        table_values[4][0] = "uOps Per Cycle: "
> +        table_values[5][0] = "IPC: "
> +        table_values[6][0] = "Block RThroughput: "
> +
> +        for j in range(len(matrix_of_code_regions)):
> +            if len(matrix_of_code_regions[j]) > i:
> +                table_values[0][j + 1] =
> str(matrix_of_code_regions[j][i].instructions)
> +                table_values[1][j + 1] =
> str(matrix_of_code_regions[j][i].total_cycles)
> +                table_values[2][j + 1] =
> str(matrix_of_code_regions[j][i].total_uops)
> +                table_values[3][j + 1] = str(
> +                    matrix_of_code_regions[j][i].dispatch_width
> +                )
> +                table_values[4][j + 1] = str(
> +                    round(matrix_of_code_regions[j][i].uops_per_cycle, 2)
> +                )
> +                table_values[5][j + 1] =
> str(round(matrix_of_code_regions[j][i].ipc, 2))
> +                table_values[6][j + 1] = str(
> +                    round(matrix_of_code_regions[j][i].block_rthroughput,
> 2)
> +                )
> +            else:
> +                table_values[0][j + 1] = "-"
> +                table_values[1][j + 1] = "-"
> +                table_values[2][j + 1] = "-"
> +                table_values[3][j + 1] = "-"
> +                table_values[4][j + 1] = "-"
> +                table_values[5][j + 1] = "-"
> +                table_values[6][j + 1] = "-"
> +
> +        tt.print(
> +            table_values,
> +            header=headers_names,
> +            style=tt.styles.ascii_thin_double,
> +            padding=(0, 1),
> +        )
> +
> +        print("\nResource pressure per iteration: \n")
> +
> +        table_values = [
> +            [
> +                [None]
> +                for i in range(
> +
> len(matrix_of_code_regions[0][0].iteration_resource_pressure) + 1
> +                )
> +            ]
> +            for j in range(len(matrix_of_code_regions) + 1)
> +        ]
> +
> +        table_values[0] =
> matrix_of_code_regions[0][0].name_target_info_resources
> +
> +        for j in range(len(matrix_of_code_regions)):
> +            if len(matrix_of_code_regions[j]) > i:
> +                table_values[j + 1] = [
> +                    "[f" + str(j + 1) + "]: "
> +                ] +
> matrix_of_code_regions[j][i].iteration_resource_pressure
> +            else:
> +                table_values[j + 1] = ["[f" + str(j + 1) + "]: "] + len(
> +
> matrix_of_code_regions[0][0].iteration_resource_pressure
> +                ) * ["-"]
> +
> +        tt.print(
> +            table_values,
> +            style=tt.styles.ascii_thin_double,
> +            padding=(0, 1),
> +        )
> +        print("\n")
> +
> +
> +def Main():
> +    parser = argparse.ArgumentParser()
> +    opts = parse_program_args(parser)
> +
> +    matrix_of_code_regions = [None] * len(opts.file_names)
> +
> +    for i in range(len(opts.file_names)):
> +        matrix_of_code_regions[i] = run_llvm_mca_tool(opts,
> opts.file_names[i])
> +    console_print_results(matrix_of_code_regions, opts)
> +
> +
> +if __name__ == "__main__":
> +    Main()
> +    sys.exit(0)
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20211221/c1a9c7cc/attachment-0001.html>


More information about the llvm-commits mailing list