@@ -216,11 +216,11 @@ install(PROGRAMS src/omniperf TYPE BIN)
|
||||
install(FILES src/parser.py TYPE BIN)
|
||||
install(FILES src/common.py TYPE BIN)
|
||||
install(FILES VERSION VERSION.sha DESTINATION ${CMAKE_INSTALL_PREFIX})
|
||||
# src/omniperf_cli
|
||||
# src/omniperf_analyze
|
||||
install(
|
||||
DIRECTORY src/omniperf_cli
|
||||
DIRECTORY src/omniperf_analyze
|
||||
TYPE BIN
|
||||
PATTERN src/omniperf_cli/tests EXCLUDE
|
||||
PATTERN src/omniperf_analyze/tests EXCLUDE
|
||||
PATTERN "__pycache__" EXCLUDE)
|
||||
# src/utils
|
||||
install(
|
||||
@@ -228,9 +228,11 @@ install(
|
||||
TYPE BIN
|
||||
PATTERN "rooflines*" EXCLUDE)
|
||||
# src/utils/rooflines
|
||||
install(PROGRAMS src/utils/rooflines/roofline-rhel8-mi200-rocm5
|
||||
src/utils/rooflines/roofline-sle15sp3-mi200-rocm5
|
||||
DESTINATION ${CMAKE_INSTALL_BINDIR}/utils/rooflines)
|
||||
install(
|
||||
PROGRAMS src/utils/rooflines/roofline-rhel8-mi200-rocm5
|
||||
src/utils/rooflines/roofline-sle15sp3-mi200-rocm5
|
||||
src/utils/rooflines/roofline-ubuntu20_04-mi200-rocm5
|
||||
DESTINATION ${CMAKE_INSTALL_BINDIR}/utils/rooflines)
|
||||
# src/perfmon_pub
|
||||
install(
|
||||
DIRECTORY src/perfmon_pub
|
||||
|
||||
@@ -13,19 +13,19 @@
|
||||
"author": "Audacious Software Group",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@grafana/data": "latest",
|
||||
"@grafana/toolkit": "latest",
|
||||
"@grafana/ui": "latest",
|
||||
"emotion": "10.0.27"
|
||||
"emotion": "10.0.27",
|
||||
"react-monaco-editor": "^0.44.0",
|
||||
"tslib": "^2.3.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"dependencies": {
|
||||
"@grafana/runtime": "^8.1.1",
|
||||
"@svgdotjs/svg.js": "^3.1.1",
|
||||
"react-monaco-editor": "^0.44.0",
|
||||
"tslib": "^2.3.1"
|
||||
"@grafana/runtime": "9.1.2",
|
||||
"@grafana/data": "9.1.2",
|
||||
"@grafana/ui": "9.1.2",
|
||||
"@svgdotjs/svg.js": "^3.1.1"
|
||||
},
|
||||
"_comments": "Dependencies are not included as part of Omniperf. It's the user's responsibility to accept any licensing implications before building the project."
|
||||
}
|
||||
|
||||
@@ -31,5 +31,5 @@ pythonpath = [
|
||||
".",
|
||||
"src",
|
||||
"src/utils",
|
||||
"src/omniperf_cli/utils"
|
||||
"src/omniperf_analyze/utils"
|
||||
]
|
||||
|
||||
@@ -52,6 +52,8 @@ extensions = [
|
||||
"myst_parser",
|
||||
]
|
||||
|
||||
myst_heading_anchors = 2
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ["_templates"]
|
||||
|
||||
|
||||
@@ -69,7 +69,9 @@ Modes change the fundamental behavior of the Omniperf command line tool. Dependi
|
||||
|
||||
- **Database**: Our detailed Grafana GUI is built on a MongoDB database. `--import` profiling results to the DB to interact with the workload in Grafana or `--remove` the workload from the DB.
|
||||
|
||||
Connection options will need to be specified. See the [*Omniperf Performance Analysis*](performance_analysis.md#omniperf-grafana-gui-import) section for more details on this.
|
||||
Connection options will need to be specified. See the [*Grafana
|
||||
Analysis*](grafana_analyzer.md#grafana-gui-import) import section
|
||||
for more details on this.
|
||||
|
||||
```shell
|
||||
$ omniperf database --help
|
||||
|
||||
@@ -68,6 +68,11 @@ The uniform color coding is applied to most visualizations (bars, table, diagram
|
||||
## Grafana GUI Import
|
||||
The omniperf database `--import` option imports the raw profiling data to Grafana's backend MongoDB database. This step is only required for Grafana GUI based performance analysis.
|
||||
|
||||
Default username and password for MongoDB (to be used in database mode) are as follows:
|
||||
|
||||
- Username: **temp**
|
||||
- Password: **temp123**
|
||||
|
||||
Each workload is imported to a separate database with the following naming convention:
|
||||
|
||||
omniperf_<team>_<database>_<soc>
|
||||
|
||||
@@ -180,7 +180,7 @@ $ sudo docker-compose up -d
|
||||
> Note that TCP ports for Grafana (4000) and MongoDB (27017) in the docker container are mapped to 14000 and 27018, respectively, on the host side.
|
||||
|
||||
### Setup Grafana Instance
|
||||
Once you've launced your docker container you should be able to reach Grafana at **http://\<host-ip>:1400**. The default login credentials for the first-time Grafana setup are:
|
||||
Once you've launced your docker container you should be able to reach Grafana at **http://\<host-ip>:14000**. The default login credentials for the first-time Grafana setup are:
|
||||
|
||||
- Username: **admin**
|
||||
- Password: **admin**
|
||||
|
||||
@@ -41,7 +41,7 @@ Analyze
|
||||
|
||||
Dash is running on http://0.0.0.0:8050/
|
||||
|
||||
* Serving Flask app 'omniperf_cli.omniperf_cli' (lazy loading)
|
||||
* Serving Flask app 'omniperf_analyze.omniperf_analyze' (lazy loading)
|
||||
* Environment: production
|
||||
WARNING: This is a development server. Do not use it in a production deployment.
|
||||
Use a production WSGI server instead.
|
||||
|
||||
@@ -30,6 +30,7 @@ import glob
|
||||
import pandas as pd
|
||||
from datetime import datetime
|
||||
from pathlib import Path as path
|
||||
import warnings
|
||||
|
||||
from parser import parse
|
||||
from utils import specs
|
||||
@@ -37,7 +38,7 @@ from utils.perfagg import perfmon_filter, pmc_filter
|
||||
from utils import remove_workload
|
||||
from utils import csv_converter # Import workload
|
||||
from utils import plot_roofline # standalone roofline
|
||||
from omniperf_cli.omniperf_cli import omniperf_cli # CLI analysis
|
||||
from omniperf_analyze.omniperf_analyze import analyze # CLI analysis
|
||||
|
||||
from common import (
|
||||
OMNIPERF_HOME,
|
||||
@@ -51,6 +52,12 @@ from common import getVersion
|
||||
################################################
|
||||
# Helper Functions
|
||||
################################################
|
||||
def run_subprocess(cmd):
|
||||
subprocess.run(
|
||||
cmd,
|
||||
check=True
|
||||
)
|
||||
|
||||
def resolve_rocprof():
|
||||
# ROCPROF INFO
|
||||
global rocprof_cmd
|
||||
@@ -71,6 +78,7 @@ def resolve_rocprof():
|
||||
|
||||
print("ROC Profiler: ", rocprof_path.stdout.decode("utf-8"))
|
||||
|
||||
|
||||
def get_soc():
|
||||
mspec = specs.get_machine_specs(0)
|
||||
|
||||
@@ -108,20 +116,24 @@ def isWorkloadEmpty(my_parser, path):
|
||||
|
||||
def replace_timestamps(workload_dir):
|
||||
df_stamps = pd.read_csv(workload_dir + "/timestamps.csv")
|
||||
df_pmc_perf = pd.read_csv(workload_dir + "/pmc_perf.csv")
|
||||
if "BeginNs" in df_stamps.columns and "EndNs" in df_stamps.columns:
|
||||
df_pmc_perf = pd.read_csv(workload_dir + "/pmc_perf.csv")
|
||||
|
||||
df_pmc_perf["BeginNs"] = df_stamps["BeginNs"]
|
||||
df_pmc_perf["EndNs"] = df_stamps["EndNs"]
|
||||
df_pmc_perf.to_csv(workload_dir + "/pmc_perf.csv", index=False)
|
||||
df_pmc_perf["BeginNs"] = df_stamps["BeginNs"]
|
||||
df_pmc_perf["EndNs"] = df_stamps["EndNs"]
|
||||
df_pmc_perf.to_csv(workload_dir + "/pmc_perf.csv", index=False)
|
||||
else:
|
||||
warnings.warn("WARNING: Incomplete profiling data detected. Unable to update timestamps.")
|
||||
|
||||
|
||||
def gen_sysinfo(workload_name, workload_dir, ip_blocks, skip_roof):
|
||||
def gen_sysinfo(workload_name, workload_dir, ip_blocks, app_cmd, skip_roof):
|
||||
# Record system information
|
||||
mspec = specs.get_machine_specs(0)
|
||||
sysinfo = open(workload_dir + "/" + "sysinfo.csv", "w")
|
||||
|
||||
# write header
|
||||
header = "workload_name,"
|
||||
header += "command,"
|
||||
header += "host_name,host_cpu,host_distro,host_kernel,host_rocmver,date,"
|
||||
header += "gpu_soc,numSE,numCU,numSIMD,waveSize,maxWavesPerCU,maxWorkgroupSize,"
|
||||
header += "L1,L2,sclk,mclk,cur_sclk,cur_mclk,L2Banks,name,numSQC,hbmBW,"
|
||||
@@ -136,6 +148,7 @@ def gen_sysinfo(workload_name, workload_dir, ip_blocks, skip_roof):
|
||||
timestamp = now.strftime("%c") + " (" + local_tzname + ")"
|
||||
# host info
|
||||
param = [workload_name]
|
||||
param += [app_cmd]
|
||||
param += [
|
||||
mspec.hostname,
|
||||
mspec.cpu,
|
||||
@@ -195,10 +208,12 @@ def mongo_import(args, profileAndImport):
|
||||
csv_converter.convert_folder(connectionInfo, Extractionlvl)
|
||||
print("-- Complete! --")
|
||||
|
||||
|
||||
################################################
|
||||
# Roofline Helpers
|
||||
################################################
|
||||
|
||||
|
||||
def detect_roofline():
|
||||
mspec = specs.get_machine_specs(0)
|
||||
rocm_ver = mspec.rocmversion[:1]
|
||||
@@ -212,7 +227,7 @@ def detect_roofline():
|
||||
rooflineBinary = os.environ["ROOFLINE_BIN"]
|
||||
if os.path.exists(rooflineBinary):
|
||||
print("Detected user-supplied binary")
|
||||
return {"rocm_ver":"override", "distro":"override", "path":rooflineBinary}
|
||||
return {"rocm_ver": "override", "distro": "override", "path": rooflineBinary}
|
||||
else:
|
||||
print("ROOFLINE ERROR: user-supplied path to binary not accessible")
|
||||
print("--> ROOFLINE_BIN = %s\n" % target_binary)
|
||||
@@ -230,26 +245,34 @@ def detect_roofline():
|
||||
print("ROOFLINE ERROR: Cannot find a valid binary for your operating system")
|
||||
sys.exit(1)
|
||||
|
||||
target_binary = { "rocm_ver":rocm_ver, "distro":distro }
|
||||
target_binary = {"rocm_ver": rocm_ver, "distro": distro}
|
||||
return target_binary
|
||||
|
||||
|
||||
def mibench(args):
|
||||
print("No roofline data found. Generating...")
|
||||
|
||||
|
||||
target_binary = detect_roofline()
|
||||
if target_binary["rocm_ver"] == "override":
|
||||
path_to_binary = target_binary["path"]
|
||||
else:
|
||||
path_to_binary = str(OMNIPERF_HOME) + "/utils/rooflines/roofline" + "-" + DISTRO_MAP[target_binary["distro"]] + "-" + args.target.lower() + "-rocm" + target_binary["rocm_ver"]
|
||||
path_to_binary = (
|
||||
str(OMNIPERF_HOME)
|
||||
+ "/utils/rooflines/roofline"
|
||||
+ "-"
|
||||
+ DISTRO_MAP[target_binary["distro"]]
|
||||
+ "-"
|
||||
+ args.target.lower()
|
||||
+ "-rocm"
|
||||
+ target_binary["rocm_ver"]
|
||||
)
|
||||
|
||||
# Distro is valid but cant find rocm ver
|
||||
if not os.path.exists(path_to_binary):
|
||||
print(
|
||||
"ROOFLINE ERROR: ROCm version not supported."
|
||||
)
|
||||
print("ROOFLINE ERROR: Unable to locate expected binary (%s)." % path_to_binary)
|
||||
sys.exit(1)
|
||||
|
||||
subprocess.run(
|
||||
run_subprocess(
|
||||
[
|
||||
path_to_binary,
|
||||
"-o",
|
||||
@@ -276,6 +299,7 @@ def characterize_app(path, cmd, verbose):
|
||||
print(fname)
|
||||
run_prof(fname, workload_dir, perfmon_dir, app_cmd, verbose)
|
||||
|
||||
|
||||
################################################
|
||||
# Profiling Helpers
|
||||
################################################
|
||||
@@ -290,13 +314,11 @@ def run_prof(fname, workload_dir, perfmon_dir, cmd, verbose):
|
||||
print("pmc file:", os.path.basename(fname))
|
||||
|
||||
# profile the app
|
||||
subprocess.run(
|
||||
run_subprocess(
|
||||
[
|
||||
rocprof_cmd,
|
||||
"-i",
|
||||
fname,
|
||||
"-m",
|
||||
perfmon_dir + "/" + "metrics.xml",
|
||||
"--timestamp",
|
||||
"on",
|
||||
"-o",
|
||||
@@ -306,7 +328,7 @@ def run_prof(fname, workload_dir, perfmon_dir, cmd, verbose):
|
||||
)
|
||||
|
||||
|
||||
def omniperf_profile(args,VER):
|
||||
def omniperf_profile(args, VER):
|
||||
# Verify valid target
|
||||
if args.target not in SOC_LIST:
|
||||
parse.print_help(sys.stderr)
|
||||
@@ -335,7 +357,7 @@ def omniperf_profile(args,VER):
|
||||
for fname in glob.glob(workload_dir + "/perfmon/*.txt"):
|
||||
# Kernel filtering (in-place replacement)
|
||||
if not args.kernel == None:
|
||||
subprocess.run(
|
||||
run_subprocess(
|
||||
[
|
||||
"sed",
|
||||
"-i",
|
||||
@@ -347,7 +369,7 @@ def omniperf_profile(args,VER):
|
||||
|
||||
# Dispatch filtering (inplace replacement)
|
||||
if not args.dispatch == None:
|
||||
subprocess.run(
|
||||
run_subprocess(
|
||||
[
|
||||
"sed",
|
||||
"-i",
|
||||
@@ -359,7 +381,7 @@ def omniperf_profile(args,VER):
|
||||
run_prof(fname, workload_dir, perfmon_dir, args.remaining, args.verbose)
|
||||
|
||||
# run again with timestamps
|
||||
subprocess.run(
|
||||
run_subprocess(
|
||||
[
|
||||
rocprof_cmd,
|
||||
# "-i", fname,
|
||||
@@ -376,7 +398,7 @@ def omniperf_profile(args,VER):
|
||||
replace_timestamps(workload_dir)
|
||||
|
||||
# Generate sysinfo
|
||||
gen_sysinfo(args.name, workload_dir, args.ipblocks, args.no_roof)
|
||||
gen_sysinfo(args.name, workload_dir, args.ipblocks, args.remaining, args.no_roof)
|
||||
|
||||
# Add tracing & roofline metrics (mi200 only)
|
||||
if args.target.lower() == "mi200":
|
||||
@@ -386,15 +408,25 @@ def omniperf_profile(args,VER):
|
||||
if target_binary["rocm_ver"] == "override":
|
||||
path_to_binary = target_binary["path"]
|
||||
else:
|
||||
path_to_binary = str(OMNIPERF_HOME) + "/utils/rooflines/roofline" + "-" + DISTRO_MAP[target_binary["distro"]] + "-" + args.target.lower() + "-rocm" + target_binary["rocm_ver"]
|
||||
# Distro is valid but cant find rocm ver
|
||||
path_to_binary = (
|
||||
str(OMNIPERF_HOME)
|
||||
+ "/utils/rooflines/roofline"
|
||||
+ "-"
|
||||
+ DISTRO_MAP[target_binary["distro"]]
|
||||
+ "-"
|
||||
+ args.target.lower()
|
||||
+ "-rocm"
|
||||
+ target_binary["rocm_ver"]
|
||||
)
|
||||
# Distro is valid but cant find valid binary
|
||||
if not os.path.exists(path_to_binary):
|
||||
print(
|
||||
"ROOFLINE ERROR: ROCm version not supported."
|
||||
"ROOFLINE ERROR: Unable to locate expected binary (%s))."
|
||||
% path_to_binary
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
subprocess.run(
|
||||
run_subprocess(
|
||||
[
|
||||
path_to_binary,
|
||||
"-o",
|
||||
@@ -404,6 +436,7 @@ def omniperf_profile(args,VER):
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
################################################
|
||||
# MAIN
|
||||
################################################
|
||||
@@ -422,7 +455,7 @@ def main():
|
||||
args = my_parser.parse_args()
|
||||
|
||||
vData = getVersion()
|
||||
VER = vData['version']
|
||||
VER = vData["version"]
|
||||
|
||||
if args.mode == None:
|
||||
throw_parse_error(
|
||||
@@ -498,7 +531,7 @@ def main():
|
||||
sysinfo_exists = os.path.isfile(sysinfo_path)
|
||||
if not sysinfo_exists:
|
||||
print("sysinfo not found")
|
||||
gen_sysinfo(args.name, args.path, [], False)
|
||||
gen_sysinfo(args.name, args.path, [], args.remaining, False)
|
||||
|
||||
# does app data exist?
|
||||
print("Checking for pmc_perf.csv in ", args.path)
|
||||
@@ -512,7 +545,7 @@ def main():
|
||||
if not args.remaining:
|
||||
throw_parse_error(
|
||||
my_parser,
|
||||
"Cannot find existing application data.\nAttempting to generate application data from -c.\n--cmd option is required to generate application data.",
|
||||
"Cannot find existing application data.\nAttempting to generate application data from -- <app_cmd>.\n-- <app_cmd> option is required to generate application data.",
|
||||
)
|
||||
else:
|
||||
characterize_app(args.path, args.remaining, args.verbose)
|
||||
@@ -522,7 +555,7 @@ def main():
|
||||
# Profile only
|
||||
else:
|
||||
print("\n-------------\nProfile only\n-------------\n")
|
||||
omniperf_profile(args,VER)
|
||||
omniperf_profile(args, VER)
|
||||
|
||||
##############
|
||||
# DATABASE MODE
|
||||
@@ -583,7 +616,7 @@ def main():
|
||||
##############
|
||||
if args.mode == "analyze":
|
||||
if args.list_metrics:
|
||||
omniperf_cli(args)
|
||||
analyze(args)
|
||||
else:
|
||||
if args.path:
|
||||
if ".." in str(args.path):
|
||||
@@ -607,7 +640,7 @@ def main():
|
||||
my_parser, dir[0]
|
||||
) # Verify workload is valid before analyzing
|
||||
|
||||
omniperf_cli(args)
|
||||
analyze(args)
|
||||
else:
|
||||
throw_parse_error(
|
||||
my_parser,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Description
|
||||
|
||||
omniperf_cli.py is a post-processing profiling tool with the raw data collected from omniperf.
|
||||
omniperf_analyze.py is a post-processing profiling tool with the raw data collected from omniperf.
|
||||
|
||||
## Features
|
||||
|
||||
|
قبل از عرض: | ارتفاع: | اندازه: 197 KiB پس از عرض: | ارتفاع: | اندازه: 197 KiB |
|
قبل از عرض: | ارتفاع: | اندازه: 3.5 KiB پس از عرض: | ارتفاع: | اندازه: 3.5 KiB |
|
قبل از عرض: | ارتفاع: | اندازه: 187 KiB پس از عرض: | ارتفاع: | اندازه: 187 KiB |
|
قبل از عرض: | ارتفاع: | اندازه: 282 KiB پس از عرض: | ارتفاع: | اندازه: 282 KiB |
|
قبل از عرض: | ارتفاع: | اندازه: 182 KiB پس از عرض: | ارتفاع: | اندازه: 182 KiB |
|
قبل از عرض: | ارتفاع: | اندازه: 116 KiB پس از عرض: | ارتفاع: | اندازه: 116 KiB |
|
قبل از عرض: | ارتفاع: | اندازه: 118 KiB پس از عرض: | ارتفاع: | اندازه: 118 KiB |
|
قبل از عرض: | ارتفاع: | اندازه: 116 KiB پس از عرض: | ارتفاع: | اندازه: 116 KiB |
|
قبل از عرض: | ارتفاع: | اندازه: 118 KiB پس از عرض: | ارتفاع: | اندازه: 118 KiB |
|
قبل از عرض: | ارتفاع: | اندازه: 120 KiB پس از عرض: | ارتفاع: | اندازه: 120 KiB |
|
قبل از عرض: | ارتفاع: | اندازه: 114 KiB پس از عرض: | ارتفاع: | اندازه: 114 KiB |
|
قبل از عرض: | ارتفاع: | اندازه: 120 KiB پس از عرض: | ارتفاع: | اندازه: 120 KiB |
|
قبل از عرض: | ارتفاع: | اندازه: 117 KiB پس از عرض: | ارتفاع: | اندازه: 117 KiB |