2023-10-31 15:11:17 -05:00
|
|
|
|
##############################################################################bl
|
|
|
|
|
|
# MIT License
|
|
|
|
|
|
#
|
2024-01-24 17:11:39 -06:00
|
|
|
|
# Copyright (c) 2021 - 2024 Advanced Micro Devices, Inc. All Rights Reserved.
|
2023-10-31 15:11:17 -05:00
|
|
|
|
#
|
|
|
|
|
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
|
|
# of this software and associated documentation files (the "Software"), to deal
|
|
|
|
|
|
# in the Software without restriction, including without limitation the rights
|
|
|
|
|
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
|
|
# copies of the Software, and to permit persons to whom the Software is
|
|
|
|
|
|
# furnished to do so, subject to the following conditions:
|
|
|
|
|
|
#
|
|
|
|
|
|
# The above copyright notice and this permission notice shall be included in all
|
|
|
|
|
|
# copies or substantial portions of the Software.
|
|
|
|
|
|
#
|
|
|
|
|
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
|
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
|
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
|
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
|
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
|
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
|
|
|
|
# SOFTWARE.
|
|
|
|
|
|
##############################################################################el
|
|
|
|
|
|
|
|
|
|
|
|
from abc import ABC, abstractmethod
|
2024-03-06 10:51:54 -06:00
|
|
|
|
from tqdm import tqdm
|
2023-10-31 15:11:17 -05:00
|
|
|
|
import glob
|
2024-03-06 10:51:54 -06:00
|
|
|
|
import logging
|
2023-10-31 15:11:17 -05:00
|
|
|
|
import sys
|
|
|
|
|
|
import os
|
2024-01-10 12:49:27 -06:00
|
|
|
|
import re
|
2024-03-04 12:57:25 -06:00
|
|
|
|
from utils.utils import (
|
|
|
|
|
|
capture_subprocess_output,
|
|
|
|
|
|
run_prof,
|
|
|
|
|
|
gen_sysinfo,
|
|
|
|
|
|
run_rocscope,
|
|
|
|
|
|
demarcate,
|
|
|
|
|
|
console_log,
|
|
|
|
|
|
console_debug,
|
|
|
|
|
|
console_error,
|
|
|
|
|
|
console_warning,
|
|
|
|
|
|
print_status,
|
|
|
|
|
|
)
|
2023-10-31 15:11:17 -05:00
|
|
|
|
import config
|
2024-01-10 12:49:27 -06:00
|
|
|
|
import pandas as pd
|
2023-10-31 15:11:17 -05:00
|
|
|
|
|
2024-02-16 15:34:28 -06:00
|
|
|
|
|
|
|
|
|
|
class OmniProfiler_Base:
|
2024-01-11 12:52:27 -06:00
|
|
|
|
def __init__(self, args, profiler_mode, soc):
|
2023-10-31 15:11:17 -05:00
|
|
|
|
self.__args = args
|
|
|
|
|
|
self.__profiler = profiler_mode
|
2024-02-16 15:34:28 -06:00
|
|
|
|
self._soc = soc # OmniSoC obj
|
|
|
|
|
|
self.__perfmon_dir = os.path.join(
|
|
|
|
|
|
str(config.omniperf_home), "omniperf_soc", "profile_configs"
|
|
|
|
|
|
)
|
2023-10-31 15:11:17 -05:00
|
|
|
|
|
|
|
|
|
|
def get_args(self):
|
|
|
|
|
|
return self.__args
|
2024-02-16 15:34:28 -06:00
|
|
|
|
|
2024-01-11 12:52:27 -06:00
|
|
|
|
def get_profiler_options(self, fname):
|
2024-02-16 15:34:28 -06:00
|
|
|
|
"""Fetch any version specific arguments required by profiler"""
|
2024-01-11 12:52:27 -06:00
|
|
|
|
# assume no SoC specific options and return empty list by default
|
|
|
|
|
|
return []
|
2024-02-16 15:34:28 -06:00
|
|
|
|
|
2024-01-10 12:49:27 -06:00
|
|
|
|
@demarcate
|
|
|
|
|
|
def pmc_perf_split(self):
|
2024-02-16 15:34:28 -06:00
|
|
|
|
"""Avoid default rocprof join utility by spliting each line into a separate input file"""
|
2024-01-10 12:49:27 -06:00
|
|
|
|
workload_perfmon_dir = os.path.join(self.__args.path, "perfmon")
|
2024-02-16 15:34:28 -06:00
|
|
|
|
lines = (
|
|
|
|
|
|
open(os.path.join(workload_perfmon_dir, "pmc_perf.txt"), "r")
|
|
|
|
|
|
.read()
|
|
|
|
|
|
.splitlines()
|
|
|
|
|
|
)
|
2024-01-10 12:49:27 -06:00
|
|
|
|
|
|
|
|
|
|
# Iterate over each line in pmc_perf.txt
|
|
|
|
|
|
mpattern = r"^pmc:(.*)"
|
|
|
|
|
|
i = 0
|
|
|
|
|
|
for line in lines:
|
|
|
|
|
|
# Verify no comments
|
|
|
|
|
|
stext = line.split("#")[0].strip()
|
|
|
|
|
|
if not stext:
|
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
|
|
# all pmc counters start with "pmc:"
|
|
|
|
|
|
m = re.match(mpattern, stext)
|
|
|
|
|
|
if m is None:
|
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
|
|
# Create separate file for each line
|
|
|
|
|
|
fd = open(workload_perfmon_dir + "/pmc_perf_" + str(i) + ".txt", "w")
|
|
|
|
|
|
fd.write(stext + "\n\n")
|
|
|
|
|
|
fd.write("gpu:\n")
|
|
|
|
|
|
fd.write("range:\n")
|
|
|
|
|
|
fd.write("kernel:\n")
|
|
|
|
|
|
fd.close()
|
|
|
|
|
|
|
|
|
|
|
|
i += 1
|
|
|
|
|
|
|
|
|
|
|
|
# Remove old pmc_perf.txt input from perfmon dir
|
|
|
|
|
|
os.remove(workload_perfmon_dir + "/pmc_perf.txt")
|
|
|
|
|
|
|
|
|
|
|
|
@demarcate
|
2024-01-19 13:46:01 -06:00
|
|
|
|
def join_prof(self, out=None):
|
2024-02-16 15:34:28 -06:00
|
|
|
|
"""Manually join separated rocprof runs"""
|
2024-01-10 12:49:27 -06:00
|
|
|
|
# Set default output directory if not specified
|
|
|
|
|
|
if type(self.__args.path) == str:
|
|
|
|
|
|
if out is None:
|
|
|
|
|
|
out = self.__args.path + "/pmc_perf.csv"
|
|
|
|
|
|
files = glob.glob(self.__args.path + "/" + "pmc_perf_*.csv")
|
|
|
|
|
|
elif type(self.__args.path) == list:
|
|
|
|
|
|
files = self.__args.path
|
|
|
|
|
|
else:
|
2024-03-04 12:57:25 -06:00
|
|
|
|
console_error(
|
|
|
|
|
|
"Invalid workload directory. Cannot resolve %s" % self.__args.path
|
|
|
|
|
|
)
|
2024-01-10 12:49:27 -06:00
|
|
|
|
|
|
|
|
|
|
df = None
|
|
|
|
|
|
for i, file in enumerate(files):
|
|
|
|
|
|
_df = pd.read_csv(file) if type(self.__args.path) == str else file
|
|
|
|
|
|
if self.__args.join_type == "kernel":
|
2024-01-19 13:46:01 -06:00
|
|
|
|
key = _df.groupby("Kernel_Name").cumcount()
|
|
|
|
|
|
_df["key"] = _df.Kernel_Name + " - " + key.astype(str)
|
2024-01-10 12:49:27 -06:00
|
|
|
|
elif self.__args.join_type == "grid":
|
2024-01-19 13:46:01 -06:00
|
|
|
|
key = _df.groupby(["Kernel_Name", "Grid_Size"]).cumcount()
|
2024-01-10 12:49:27 -06:00
|
|
|
|
_df["key"] = (
|
2024-02-16 15:34:28 -06:00
|
|
|
|
_df["Kernel_Name"]
|
|
|
|
|
|
+ " - "
|
|
|
|
|
|
+ _df["Grid_Size"].astype(str)
|
|
|
|
|
|
+ " - "
|
|
|
|
|
|
+ key.astype(str)
|
2024-01-10 12:49:27 -06:00
|
|
|
|
)
|
|
|
|
|
|
else:
|
2024-03-04 12:57:25 -06:00
|
|
|
|
console_error(
|
|
|
|
|
|
"%s is an unrecognized option for --join-type" % self.__args.join_type
|
|
|
|
|
|
)
|
2024-01-10 12:49:27 -06:00
|
|
|
|
|
|
|
|
|
|
if df is None:
|
|
|
|
|
|
df = _df
|
|
|
|
|
|
else:
|
|
|
|
|
|
# join by unique index of kernel
|
|
|
|
|
|
df = pd.merge(df, _df, how="inner", on="key", suffixes=("", f"_{i}"))
|
|
|
|
|
|
|
|
|
|
|
|
# TODO: check for any mismatch in joins
|
|
|
|
|
|
duplicate_cols = {
|
2024-01-31 12:15:56 -06:00
|
|
|
|
"GPU_ID": [col for col in df.columns if col.startswith("GPU_ID")],
|
|
|
|
|
|
"Grid_Size": [col for col in df.columns if col.startswith("Grid_Size")],
|
2024-02-16 15:34:28 -06:00
|
|
|
|
"Workgroup_Size": [
|
|
|
|
|
|
col for col in df.columns if col.startswith("Workgroup_Size")
|
|
|
|
|
|
],
|
|
|
|
|
|
"LDS_Per_Workgroup": [
|
|
|
|
|
|
col for col in df.columns if col.startswith("LDS_Per_Workgroup")
|
|
|
|
|
|
],
|
|
|
|
|
|
"Scratch_Per_Workitem": [
|
|
|
|
|
|
col for col in df.columns if col.startswith("Scratch_Per_Workitem")
|
|
|
|
|
|
],
|
2024-01-31 12:15:56 -06:00
|
|
|
|
"SGPR": [col for col in df.columns if col.startswith("SGPR")],
|
2024-01-10 12:49:27 -06:00
|
|
|
|
}
|
|
|
|
|
|
# Check for vgpr counter in ROCm < 5.3
|
|
|
|
|
|
if "vgpr" in df.columns:
|
2024-01-31 12:15:56 -06:00
|
|
|
|
duplicate_cols["vgpr"] = [col for col in df.columns if col.startswith("vgpr")]
|
2024-01-10 12:49:27 -06:00
|
|
|
|
# Check for vgpr counter in ROCm >= 5.3
|
|
|
|
|
|
else:
|
2024-02-16 15:34:28 -06:00
|
|
|
|
duplicate_cols["Arch_VGPR"] = [
|
|
|
|
|
|
col for col in df.columns if col.startswith("Arch_VGPR")
|
|
|
|
|
|
]
|
|
|
|
|
|
duplicate_cols["Accum_VGPR"] = [
|
|
|
|
|
|
col for col in df.columns if col.startswith("Accum_VGPR")
|
|
|
|
|
|
]
|
2024-01-10 12:49:27 -06:00
|
|
|
|
for key, cols in duplicate_cols.items():
|
|
|
|
|
|
_df = df[cols]
|
|
|
|
|
|
if not test_df_column_equality(_df):
|
2024-03-04 12:57:25 -06:00
|
|
|
|
msg = "Detected differing {} values while joining pmc_perf.csv".format(
|
|
|
|
|
|
key
|
2024-01-10 12:49:27 -06:00
|
|
|
|
)
|
2024-01-30 17:25:16 -06:00
|
|
|
|
console_warning(msg + "\n")
|
2024-01-10 12:49:27 -06:00
|
|
|
|
else:
|
|
|
|
|
|
msg = "Successfully joined {} in pmc_perf.csv".format(key)
|
2024-01-30 17:25:16 -06:00
|
|
|
|
console_debug(msg + "\n")
|
2024-01-10 12:49:27 -06:00
|
|
|
|
if test_df_column_equality(_df) and self.__args.verbose:
|
2024-03-11 11:15:33 -05:00
|
|
|
|
console_log("profiling", msg)
|
2024-01-10 12:49:27 -06:00
|
|
|
|
|
|
|
|
|
|
# now, we can:
|
2024-01-24 12:44:42 -06:00
|
|
|
|
# A) throw away any of the "boring" duplicates
|
2024-01-10 12:49:27 -06:00
|
|
|
|
df = df[
|
|
|
|
|
|
[
|
|
|
|
|
|
k
|
|
|
|
|
|
for k in df.keys()
|
|
|
|
|
|
if not any(
|
2024-02-06 16:12:14 -06:00
|
|
|
|
k.startswith(check)
|
2024-01-10 12:49:27 -06:00
|
|
|
|
for check in [
|
2024-02-16 15:34:28 -06:00
|
|
|
|
# rocprofv2 headers
|
2024-01-10 12:49:27 -06:00
|
|
|
|
"GPU_ID_",
|
|
|
|
|
|
"Grid_Size_",
|
|
|
|
|
|
"Workgroup_Size_",
|
|
|
|
|
|
"LDS_Per_Workgroup_",
|
|
|
|
|
|
"Scratch_Per_Workitem_",
|
|
|
|
|
|
"vgpr_",
|
|
|
|
|
|
"Arch_VGPR_",
|
|
|
|
|
|
"Accum_VGPR_",
|
|
|
|
|
|
"SGPR_",
|
|
|
|
|
|
"Dispatch_ID_",
|
|
|
|
|
|
"Queue_ID",
|
|
|
|
|
|
"Queue_Index",
|
|
|
|
|
|
"PID",
|
|
|
|
|
|
"TID",
|
|
|
|
|
|
"SIG",
|
|
|
|
|
|
"OBJ",
|
|
|
|
|
|
# rocscope specific merged counters, keep original
|
|
|
|
|
|
"dispatch_",
|
2024-01-19 13:46:01 -06:00
|
|
|
|
# extras
|
|
|
|
|
|
"sig",
|
|
|
|
|
|
"queue-id",
|
|
|
|
|
|
"queue-index",
|
|
|
|
|
|
"pid",
|
|
|
|
|
|
"tid",
|
|
|
|
|
|
"fbar",
|
2024-01-10 12:49:27 -06:00
|
|
|
|
]
|
|
|
|
|
|
)
|
|
|
|
|
|
]
|
|
|
|
|
|
]
|
|
|
|
|
|
# B) any timestamps that are _not_ the duration, which is the one we care about
|
|
|
|
|
|
df = df[
|
|
|
|
|
|
[
|
|
|
|
|
|
k
|
|
|
|
|
|
for k in df.keys()
|
|
|
|
|
|
if not any(
|
|
|
|
|
|
check in k
|
|
|
|
|
|
for check in [
|
|
|
|
|
|
"DispatchNs",
|
|
|
|
|
|
"CompleteNs",
|
|
|
|
|
|
# rocscope specific timestamp
|
|
|
|
|
|
"HostDuration",
|
|
|
|
|
|
]
|
|
|
|
|
|
)
|
|
|
|
|
|
]
|
|
|
|
|
|
]
|
|
|
|
|
|
# C) sanity check the name and key
|
2024-01-19 13:46:01 -06:00
|
|
|
|
namekeys = [k for k in df.keys() if "Kernel_Name" in k]
|
2024-01-10 12:49:27 -06:00
|
|
|
|
assert len(namekeys)
|
|
|
|
|
|
for k in namekeys[1:]:
|
|
|
|
|
|
assert (df[namekeys[0]] == df[k]).all()
|
|
|
|
|
|
df = df.drop(columns=namekeys[1:])
|
|
|
|
|
|
# now take the median of the durations
|
|
|
|
|
|
bkeys = []
|
|
|
|
|
|
ekeys = []
|
|
|
|
|
|
for k in df.keys():
|
2024-01-19 13:46:01 -06:00
|
|
|
|
if "Start_Timestamp" in k:
|
2024-01-10 12:49:27 -06:00
|
|
|
|
bkeys.append(k)
|
2024-01-19 13:46:01 -06:00
|
|
|
|
if "End_Timestamp" in k:
|
2024-01-10 12:49:27 -06:00
|
|
|
|
ekeys.append(k)
|
|
|
|
|
|
# compute mean begin and end timestamps
|
|
|
|
|
|
endNs = df[ekeys].mean(axis=1)
|
|
|
|
|
|
beginNs = df[bkeys].mean(axis=1)
|
|
|
|
|
|
# and replace
|
|
|
|
|
|
df = df.drop(columns=bkeys)
|
|
|
|
|
|
df = df.drop(columns=ekeys)
|
2024-01-19 13:46:01 -06:00
|
|
|
|
df["Start_Timestamp"] = beginNs
|
|
|
|
|
|
df["End_Timestamp"] = endNs
|
2024-01-10 12:49:27 -06:00
|
|
|
|
# finally, join the drop key
|
|
|
|
|
|
df = df.drop(columns=["key"])
|
|
|
|
|
|
# save to file and delete old file(s), skip if we're being called outside of Omniperf
|
|
|
|
|
|
if type(self.__args.path) == str:
|
|
|
|
|
|
df.to_csv(out, index=False)
|
|
|
|
|
|
if not self.__args.verbose:
|
|
|
|
|
|
for file in files:
|
|
|
|
|
|
os.remove(file)
|
|
|
|
|
|
else:
|
|
|
|
|
|
return df
|
2023-10-31 15:11:17 -05:00
|
|
|
|
|
2024-02-16 15:34:28 -06:00
|
|
|
|
# ----------------------------------------------------
|
2023-10-31 15:11:17 -05:00
|
|
|
|
# Required methods to be implemented by child classes
|
2024-02-16 15:34:28 -06:00
|
|
|
|
# ----------------------------------------------------
|
2023-10-31 15:11:17 -05:00
|
|
|
|
@abstractmethod
|
|
|
|
|
|
def pre_processing(self):
|
2024-03-04 12:57:25 -06:00
|
|
|
|
"""Perform any pre-processing steps prior to profiling."""
|
|
|
|
|
|
console_debug("profiling", "pre-processing using %s profiler" % self.__profiler)
|
|
|
|
|
|
|
2024-01-19 10:56:45 -06:00
|
|
|
|
# verify soc compatibility
|
|
|
|
|
|
if self.__profiler not in self._soc.get_compatible_profilers():
|
2024-03-04 12:57:25 -06:00
|
|
|
|
console_error(
|
|
|
|
|
|
"%s is not enabled in %s. Available profilers include: %s"
|
|
|
|
|
|
% (
|
|
|
|
|
|
self._soc.get_arch(),
|
|
|
|
|
|
self.__profiler,
|
|
|
|
|
|
self._soc.get_compatible_profilers(),
|
|
|
|
|
|
)
|
|
|
|
|
|
)
|
2023-10-31 15:11:17 -05:00
|
|
|
|
# verify not accessing parent directories
|
|
|
|
|
|
if ".." in str(self.__args.path):
|
2024-03-04 12:57:25 -06:00
|
|
|
|
console_error(
|
|
|
|
|
|
"Access denied. Cannot access parent directories in path (i.e. ../)"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2023-10-31 15:11:17 -05:00
|
|
|
|
# verify correct formatting for application binary
|
|
|
|
|
|
self.__args.remaining = self.__args.remaining[1:]
|
|
|
|
|
|
if self.__args.remaining:
|
|
|
|
|
|
if not os.path.isfile(self.__args.remaining[0]):
|
2024-03-04 12:57:25 -06:00
|
|
|
|
console_error(
|
|
|
|
|
|
"Your command %s doesn't point to a executable. Please verify."
|
|
|
|
|
|
% self.__args.remaining[0]
|
|
|
|
|
|
)
|
2023-10-31 15:11:17 -05:00
|
|
|
|
self.__args.remaining = " ".join(self.__args.remaining)
|
|
|
|
|
|
else:
|
2024-03-04 12:57:25 -06:00
|
|
|
|
console_error(
|
|
|
|
|
|
"Profiling command required. Pass application executable after -- at the end of options.\n\t\ti.e. omniperf profile -n vcopy -- ./vcopy 1048576 256"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2023-10-31 15:11:17 -05:00
|
|
|
|
# verify name meets MongoDB length requirements and no illegal chars
|
|
|
|
|
|
if len(self.__args.name) > 35:
|
2024-01-30 17:25:16 -06:00
|
|
|
|
console_error("-n/--name exceeds 35 character limit. Try again.")
|
2023-10-31 15:11:17 -05:00
|
|
|
|
if self.__args.name.find(".") != -1 or self.__args.name.find("-") != -1:
|
2024-01-30 17:25:16 -06:00
|
|
|
|
console_error("'-' and '.' are not permitted in -n/--name")
|
2023-10-31 15:11:17 -05:00
|
|
|
|
|
|
|
|
|
|
@abstractmethod
|
2024-03-04 12:57:25 -06:00
|
|
|
|
def run_profiling(self, version: str, prog: str):
|
|
|
|
|
|
"""Run profiling."""
|
2024-01-30 17:25:16 -06:00
|
|
|
|
console_debug(
|
2024-03-04 12:57:25 -06:00
|
|
|
|
"profiling", "performing profiling using %s profiler" % self.__profiler
|
2024-02-16 15:34:28 -06:00
|
|
|
|
)
|
2024-03-04 12:57:25 -06:00
|
|
|
|
|
2023-10-31 15:11:17 -05:00
|
|
|
|
# log basic info
|
2024-03-08 15:10:53 -06:00
|
|
|
|
console_log(str(prog).title() + " version: " + str(version))
|
|
|
|
|
|
console_log("Profiler choice: %s" % self.__profiler)
|
2024-01-30 17:25:16 -06:00
|
|
|
|
console_log("Path: " + str(os.path.abspath(self.__args.path)))
|
2024-03-05 15:10:08 -06:00
|
|
|
|
console_log("Target: " + str(self._soc._mspec.gpu_model))
|
2024-01-30 17:25:16 -06:00
|
|
|
|
console_log("Command: " + str(self.__args.remaining))
|
|
|
|
|
|
console_log("Kernel Selection: " + str(self.__args.kernel))
|
|
|
|
|
|
console_log("Dispatch Selection: " + str(self.__args.dispatch))
|
2023-10-31 15:11:17 -05:00
|
|
|
|
if self.__args.ipblocks == None:
|
2024-01-30 17:25:16 -06:00
|
|
|
|
console_log("IP Blocks: All")
|
2023-10-31 15:11:17 -05:00
|
|
|
|
else:
|
2024-03-04 12:57:25 -06:00
|
|
|
|
console_log("IP Blocks: " + str(self.__args.ipblocks))
|
2023-10-31 15:11:17 -05:00
|
|
|
|
if self.__args.kernel_verbose > 5:
|
2024-01-30 17:25:16 -06:00
|
|
|
|
console_log("KernelName verbose: DISABLED")
|
2023-10-31 15:11:17 -05:00
|
|
|
|
else:
|
2024-01-30 17:25:16 -06:00
|
|
|
|
console_log("KernelName verbose: " + str(self.__args.kernel_verbose))
|
2023-10-31 15:11:17 -05:00
|
|
|
|
|
2024-01-30 17:25:16 -06:00
|
|
|
|
print_status("Collecting Performance Counters")
|
|
|
|
|
|
|
2024-03-06 10:51:54 -06:00
|
|
|
|
# show status bar in error-only mode
|
|
|
|
|
|
disable_tqdm = True
|
2024-03-08 10:46:10 -06:00
|
|
|
|
if self.__args.loglevel >= logging.ERROR:
|
2024-03-06 10:51:54 -06:00
|
|
|
|
disable_tqdm = False
|
|
|
|
|
|
|
2024-01-30 17:25:16 -06:00
|
|
|
|
# Run profiling on each input file
|
2024-03-06 17:05:24 -06:00
|
|
|
|
input_files = glob.glob(self.get_args().path + "/perfmon/*.txt")
|
|
|
|
|
|
input_files.sort()
|
2024-03-06 10:51:54 -06:00
|
|
|
|
|
2024-03-08 17:37:23 -06:00
|
|
|
|
for fname in tqdm(input_files, disable=disable_tqdm):
|
2023-10-31 15:11:17 -05:00
|
|
|
|
# Kernel filtering (in-place replacement)
|
|
|
|
|
|
if not self.__args.kernel == None:
|
|
|
|
|
|
success, output = capture_subprocess_output(
|
|
|
|
|
|
[
|
|
|
|
|
|
"sed",
|
|
|
|
|
|
"-i",
|
|
|
|
|
|
"-r",
|
2024-02-16 15:34:28 -06:00
|
|
|
|
"s%^(kernel:).*%"
|
|
|
|
|
|
+ "kernel: "
|
|
|
|
|
|
+ ",".join(self.__args.kernel)
|
|
|
|
|
|
+ "%g",
|
2023-10-31 15:11:17 -05:00
|
|
|
|
fname,
|
|
|
|
|
|
]
|
|
|
|
|
|
)
|
|
|
|
|
|
# log output from profile filtering
|
|
|
|
|
|
if not success:
|
2024-01-30 17:25:16 -06:00
|
|
|
|
console_error(output)
|
2023-10-31 15:11:17 -05:00
|
|
|
|
else:
|
2024-01-30 17:25:16 -06:00
|
|
|
|
console_error(output)
|
2023-10-31 15:11:17 -05:00
|
|
|
|
|
|
|
|
|
|
# Dispatch filtering (inplace replacement)
|
|
|
|
|
|
if not self.__args.dispatch == None:
|
|
|
|
|
|
success, output = capture_subprocess_output(
|
|
|
|
|
|
[
|
|
|
|
|
|
"sed",
|
|
|
|
|
|
"-i",
|
|
|
|
|
|
"-r",
|
2024-02-16 15:34:28 -06:00
|
|
|
|
"s%^(range:).*%"
|
|
|
|
|
|
+ "range: "
|
|
|
|
|
|
+ " ".join(self.__args.dispatch)
|
|
|
|
|
|
+ "%g",
|
2023-10-31 15:11:17 -05:00
|
|
|
|
fname,
|
|
|
|
|
|
]
|
|
|
|
|
|
)
|
|
|
|
|
|
# log output from profile filtering
|
|
|
|
|
|
if not success:
|
2024-01-30 17:25:16 -06:00
|
|
|
|
console_error(output)
|
2023-10-31 15:11:17 -05:00
|
|
|
|
else:
|
2024-01-30 17:25:16 -06:00
|
|
|
|
console_debug(output)
|
2024-03-04 12:57:25 -06:00
|
|
|
|
console_log("profile", "Current input file: %s" % fname)
|
|
|
|
|
|
|
2024-01-11 16:30:46 -06:00
|
|
|
|
# Fetch any SoC/profiler specific profiling options
|
|
|
|
|
|
options = self._soc.get_profiler_options()
|
|
|
|
|
|
options += self.get_profiler_options(fname)
|
2024-01-11 12:52:27 -06:00
|
|
|
|
if self.__profiler == "rocprofv1" or self.__profiler == "rocprofv2":
|
|
|
|
|
|
run_prof(
|
2024-03-01 11:52:31 -06:00
|
|
|
|
fname=fname,
|
2024-01-19 10:56:45 -06:00
|
|
|
|
profiler_options=options,
|
2024-02-16 15:34:28 -06:00
|
|
|
|
workload_dir=self.get_args().path,
|
2024-02-20 13:34:56 -06:00
|
|
|
|
mspec=self._soc._mspec,
|
2024-03-07 08:46:34 -06:00
|
|
|
|
loglevel=self.get_args().loglevel,
|
2024-01-11 12:52:27 -06:00
|
|
|
|
)
|
2023-10-31 15:11:17 -05:00
|
|
|
|
|
|
|
|
|
|
elif self.__profiler == "rocscope":
|
|
|
|
|
|
run_rocscope(self.__args, fname)
|
|
|
|
|
|
else:
|
2024-03-04 12:57:25 -06:00
|
|
|
|
# TODO: Finish logic
|
2024-01-30 17:25:16 -06:00
|
|
|
|
console_error("Profiler not supported")
|
2023-10-31 15:11:17 -05:00
|
|
|
|
|
|
|
|
|
|
@abstractmethod
|
|
|
|
|
|
def post_processing(self):
|
2024-03-04 12:57:25 -06:00
|
|
|
|
"""Perform any post-processing steps prior to profiling."""
|
2024-01-30 17:25:16 -06:00
|
|
|
|
console_debug(
|
2024-03-04 12:57:25 -06:00
|
|
|
|
"profiling", "performing post-processing using %s profiler" % self.__profiler
|
2024-02-16 15:34:28 -06:00
|
|
|
|
)
|
2024-01-30 17:25:16 -06:00
|
|
|
|
|
2024-01-23 12:56:59 -06:00
|
|
|
|
gen_sysinfo(
|
2024-02-16 15:34:28 -06:00
|
|
|
|
workload_name=self.__args.name,
|
|
|
|
|
|
workload_dir=self.get_args().path,
|
|
|
|
|
|
ip_blocks=self.__args.ipblocks,
|
|
|
|
|
|
app_cmd=self.__args.remaining,
|
|
|
|
|
|
skip_roof=self.__args.no_roof,
|
2024-01-23 12:56:59 -06:00
|
|
|
|
roof_only=self.__args.roof_only,
|
2024-02-20 13:34:56 -06:00
|
|
|
|
mspec=self._soc._mspec,
|
2024-03-01 14:28:11 -06:00
|
|
|
|
soc=self._soc,
|
2024-01-10 12:49:27 -06:00
|
|
|
|
)
|
|
|
|
|
|
|
2024-02-16 15:34:28 -06:00
|
|
|
|
|
2024-01-10 12:49:27 -06:00
|
|
|
|
def test_df_column_equality(df):
|
|
|
|
|
|
return df.eq(df.iloc[:, 0], axis=0).all(1).all()
|