Analysis report block based filtering for profiling (#566)

* Analysis report block based filtering for profiling

* Profiling mode changes

- `-b` option now additionally accepts metric id(s), similar to `-b` option in analyze mode (e.g. 6, 6.2, 6.23)
    - Only counters mentioned in the selected analysis report blocks will be collected
        - Add parsing logic to identify hardware counters from analysis report blocks
        - Add filtering logic to only write filtered counters in perfmon files
        - Log not collected counters in one line
- `--list-metrics` option added in profile mode to list possible metric id(s) similar to analyze mode
- Write arguments provided during profiling in profiling_configuration.yaml file

* Analysis mode changes

- During analysis mode, only show report blocks selected during profiling
    - If `-b` option is provided in analysis mode, then follow provided filters
- Do not show empty tables in analysis report

* Miscellaneous changes

- Update CHANGELOG
- Add test cases
    - Instruction mix report block filter
    - Instruction mix and Memory chart report block filter
    - Instruction mix report block filter and CPC hardware block filter
    - TA hardware block filter
    - --list-metrics in profile mode should work
- Move binary handler fixtures to conftest.py to avoid importing
  fixtures
- cmake file in tests directory has been updated to compile sample/vmem.hip for testing

* Public documentation changes

- Use the term "Hardware report block" instead of "Hardware block"
- Add documentation for "--list-metrics" option in profile mode
- Add example of filtering by hardware report block such as instruction
  mix and wavefront launch statistics
- Add deprecation warning for hardware component (sq, tcc) based filtering
Αυτή η υποβολή περιλαμβάνεται σε:
vedithal-amd
2025-03-10 14:42:56 -04:00
υποβλήθηκε από GitHub
γονέας 0aefd15b7b
υποβολή 55cf0e237e
27 αρχεία άλλαξαν με 748 προσθήκες και 199 διαγραφές
+60 -9
Προβολή Αρχείου
@@ -24,14 +24,15 @@
import argparse
import os
import re
import shutil
from pathlib import Path
def print_avail_arch(avail_arch: list):
ret_str = "\t\tList all available metrics for analysis on specified arch:"
ret_str = "\t\t\tList all available metrics for analysis on specified arch:"
for arch in avail_arch:
ret_str += "\n\t\t {}".format(arch)
ret_str += "\n\t\t\t {}".format(arch)
return ret_str
@@ -114,7 +115,6 @@ Examples:
type=str,
metavar="",
dest="name",
required=True,
help="\t\t\tAssign a name to workload.",
)
profile_group.add_argument("--target", type=str, default=None, help=argparse.SUPPRESS)
@@ -154,7 +154,7 @@ Examples:
default=False,
action="store_true",
help=argparse.SUPPRESS,
#help="\t\t\tKokkos trace, traces Kokkos API calls.",
# help="\t\t\tKokkos trace, traces Kokkos API calls.",
)
profile_group.add_argument(
"-k",
@@ -177,16 +177,67 @@ Examples:
required=False,
help="\t\t\tDispatch ID filtering.",
)
class AggregateDict(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
aggregated_dict = getattr(namespace, self.dest, {})
if aggregated_dict is None:
aggregated_dict = {}
for key, value in values:
aggregated_dict[key] = value
setattr(namespace, self.dest, aggregated_dict)
def validate_block(value):
# Metric id regex, for example, 10, 4, 4.3, 4.32
# Dont allow more than two digits after decimal point
metric_id_pattern = re.compile(r"^\d+$|^\d\.\d$|^\d+\.\d\d$")
# Allow only the following hardware blocks
hardware_block_pattern = re.compile(r"^(SQ|SQC|TA|TD|TCP|TCC|SPI|CPC|CPF)$")
if metric_id_pattern.match(value):
return (str(value), "metric_id")
if hardware_block_pattern.match(value):
return (str(value), "hardware_block")
raise argparse.ArgumentTypeError(f"Invalid hardware block or metric id: {value}")
profile_group.add_argument(
"-b",
"--block",
type=str,
dest="ipblocks",
type=validate_block,
action=AggregateDict,
dest="filter_blocks",
metavar="",
nargs="+",
required=False,
choices=["SQ", "SQC", "TA", "TD", "TCP", "TCC", "SPI", "CPC", "CPF"],
help="\t\t\tHardware block filtering:\n\t\t\t SQ\n\t\t\t SQC\n\t\t\t TA\n\t\t\t TD\n\t\t\t TCP\n\t\t\t TCC\n\t\t\t SPI\n\t\t\t CPC\n\t\t\t CPF",
default={},
help="""\t\t\tSpecify metric id(s) from --list-metrics for filtering (e.g. 10, 4, 4.3).
\t\t\tCan provide multiple space separated arguments.
\t\t\tCan also accept Hardware blocks.
\t\t\tHardware block filtering (to be deprecated soon):
\t\t\t SQ
\t\t\t SQC
\t\t\t TA
\t\t\t TD
\t\t\t TCP
\t\t\t TCC
\t\t\t SPI
\t\t\t CPC
\t\t\t CPF""",
)
profile_group.add_argument(
"--list-metrics",
metavar="",
nargs="?",
const="",
# Argument to --list-metrics is optional
choices=[""] + list(supported_archs.keys()), # ["gfx906", "gfx908", "gfx90a"],
help=print_avail_arch(supported_archs.keys()),
)
profile_group.add_argument(
"--config-dir",
dest="config_dir",
metavar="",
help="\t\t\tSpecify the directory of customized report section configs.",
default=rocprof_compute_home.joinpath("rocprof_compute_soc/analysis_configs/"),
)
result = shutil.which("rocscope")
@@ -487,7 +538,7 @@ Examples:
dest="filter_metrics",
metavar="",
nargs="+",
help="\t\tSpecify hardware block/metric id(s) from --list-metrics for filtering.",
help="\t\tSpecify metric id(s) from --list-metrics for filtering.",
)
analyze_group.add_argument(
"--gpu-id",