Merge pull request #28 from AMDResearch/dev

Landing development work in support of 1.0.4 release
Tento commit je obsažen v:
Cole Ramos
2022-11-11 15:36:35 -06:00
odevzdal GitHub
32 změnil soubory, kde provedl 832 přidání a 593 odebrání
+12
Zobrazit soubor
@@ -13,8 +13,18 @@ jobs:
env:
INSTALL_DIR: /tmp/foo1
steps:
- name: Set git sha mode
id: sha-mode
run: |
if [ "$EVENT" == 'pull_request' ]; then
echo "sha=${{github.event.pull_request.head.sha}}" >> $GITHUB_OUTPUT
else
echo "sha=$GITHUB_SHA" >> $GITHUB_OUTPUT
fi
- name: Checkout code
uses: actions/checkout@v3
with:
ref: ${{ steps.sha-mode.sha }}
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@0.11.0
- name: Install Python
@@ -73,6 +83,8 @@ jobs:
- name: Verify expected paths
run: |
test -d $INSTALL_DIR/omniperf
test -s $INSTALL_DIR/omniperf/VERSION
test -s $INSTALL_DIR/omniperf/VERSION.sha
test -d $INSTALL_DIR/omniperf/bin
test -x $INSTALL_DIR/omniperf/bin/omniperf
test -d $INSTALL_DIR/modulefiles/omniperf
+1
Zobrazit soubor
@@ -14,6 +14,7 @@ __pycache__
.coverage
saved_analysis
pmc_kernel_top.csv
VERSION.sha
# temp files
/tests/Testing
+26 -4
Zobrazit soubor
@@ -33,6 +33,17 @@ project(
include(ExternalProject)
include(GNUInstallDirs)
# version control info
find_package(Git)
if(Git_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git")
execute_process(
COMMAND git log --pretty=format:%h -n 1
OUTPUT_VARIABLE OMNIPERF_GIT_REV
OUTPUT_STRIP_TRAILING_WHITESPACE)
message(STATUS "Git revision: ${OMNIPERF_GIT_REV}")
endif()
set(CMAKE_BUILD_TYPE "Release")
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX
@@ -140,7 +151,7 @@ if(LOCALHOST MATCHES ".*\.crusher\.olcf\.ornl\.gov")
endif()
# Thera mods
if(LOCALHOST MATCHES ".*\.thera\.amd\.com")
if(LOCALHOST MATCHES "TheraS01|.*\.thera\.amd\.com|thera-hn")
list(APPEND CMAKE_MESSAGE_INDENT " ")
message(STATUS "Using thera-specific modulefile modification")
file(READ ${PROJECT_SOURCE_DIR}/cmake/modfile.thera.mod mod_additions)
@@ -151,6 +162,10 @@ if(LOCALHOST MATCHES ".*\.thera\.amd\.com")
list(POP_BACK CMAKE_MESSAGE_INDENT)
endif()
# git versioning file
configure_file(${PROJECT_SOURCE_DIR}/cmake/VERSION.sha.in
${PROJECT_SOURCE_DIR}/VERSION.sha @ONLY)
enable_testing()
add_test(
@@ -196,7 +211,7 @@ add_test(
install(PROGRAMS src/omniperf TYPE BIN)
install(FILES src/parser.py TYPE BIN)
install(FILES src/common.py TYPE BIN)
install(FILES VERSION DESTINATION ${CMAKE_INSTALL_PREFIX})
install(FILES VERSION VERSION.sha DESTINATION ${CMAKE_INSTALL_PREFIX})
# src/omniperf_cli
install(
DIRECTORY src/omniperf_cli
@@ -272,6 +287,13 @@ install(
# Source tarball
set(CPACK_SOURCE_GENERATOR "TGZ")
set(CPACK_SOURCE_PACKAGE_FILE_NAME ${CMAKE_PROJECT_NAME}-${PROJECT_VERSION})
set(CPACK_SOURCE_IGNORE_FILES ".*~$" \.git/ \.github /tests /build)
set(CPACK_SOURCE_PACKAGE_FILE_NAME ${CMAKE_PROJECT_NAME}-${FULL_VERSION_STRING})
set(CPACK_SOURCE_IGNORE_FILES
".*~$"
\.git/
\.github
\.gitmodules
\.gitignore
/tests
/build)
include(CPack)
+1 -3
Zobrazit soubor
@@ -1,6 +1,4 @@
[![Docs](https://github.com/AMDResearch/omniperf/actions/workflows/pages/pages-build-deployment/badge.svg?branch=gh-pages)](https://amdresearch.github.io/omniperf/)
<!-- [![GitHub commits since last release](https://img.shields.io/github/commits-since/AMDResearch/omniperf/latest/dev.svg)](https://github.com/AMDResearch/omniperf/compare/main...dev) -->
[![Docs](https://github.com/AMDResearch/omniperf/actions/workflows/pages/pages-build-deployment/badge.svg?branch=gh-pages)](https://amdresearch.github.io/omniperf/) [![GitHub commits since last release](https://img.shields.io/github/commits-since/AMDResearch/omniperf/latest/dev.svg)](https://github.com/AMDResearch/omniperf/compare/main...dev)
# Omniperf
+1 -1
Zobrazit soubor
@@ -1 +1 @@
1.0.3
1.0.4
+1
Zobrazit soubor
@@ -0,0 +1 @@
@OMNIPERF_GIT_REV@
+2 -2
Zobrazit soubor
@@ -24,8 +24,8 @@ services:
image: mongo
restart: always
environment:
MONGO_INITDB_ROOT_USERNAME: amd
MONGO_INITDB_ROOT_PASSWORD: amd123
MONGO_INITDB_ROOT_USERNAME: temp
MONGO_INITDB_ROOT_PASSWORD: temp123
volumes:
- grafana-mongo-db:/data/db
ports:
+2 -2
Zobrazit soubor
@@ -2,8 +2,8 @@ astunparse==1.6.2
colorlover
dash
matplotlib
numpy
pandas
numpy>=1.17.5
pandas>=1.4.3
pymongo
pyyaml
tabulate
+14 -1
Zobrazit soubor
@@ -2,6 +2,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <iostream>
using namespace std;
#define HIP_ASSERT(x) (assert((x)==hipSuccess))
@@ -19,7 +21,7 @@ __global__ void vecCopy(double *a, double *b, double *c, int n,int stride)
void usage()
{
printf("\nUsage: vcopy [n] [blocksize]\n\n");
printf("\nUsage: vcopy [n] [blocksize] {dev}\n\n");
exit(1);
return;
}
@@ -45,13 +47,24 @@ int main( int argc, char* argv[] )
double *d_c;
int stride = 1;
int devId = 0;
if(argc < 3)
usage();
if(argc > 3)
devId = atoi(argv[3]);
n = atoi(argv[1]);
blockSize = atoi(argv[2]);
int numGpuDevices;
HIP_ASSERT(hipGetDeviceCount(&numGpuDevices));
if(devId >= numGpuDevices)
devId = 0;
HIP_ASSERT(hipSetDevice(devId));
printf("vcopy testing on GCD %d\n", devId);
assert(n > 0);
assert(blockSize > 0);
+50 -7
Zobrazit soubor
@@ -22,8 +22,10 @@
import os
import sys
import io
from pathlib import Path
import subprocess
import shutil
OMNIPERF_HOME = Path(__file__).resolve().parent
@@ -31,10 +33,51 @@ OMNIPERF_HOME = Path(__file__).resolve().parent
PROG = "omniperf"
SOC_LIST = ["mi50", "mi100", "mi200"]
DISTRO_MAP = {"platform:el8": "rhel8", "15.3": "sle15sp3", "20.04": "ubuntu20_04"}
version = os.path.join(OMNIPERF_HOME.parent, "VERSION")
try:
with open(version, "r") as file:
VER = file.read().replace("\n", "")
except EnvironmentError:
print("ERROR: Cannot find VERSION file at {}".format(version))
sys.exit(1)
def getVersion():
# symantic version info
version = os.path.join(OMNIPERF_HOME.parent, "VERSION")
try:
with open(version, "r") as file:
VER = file.read().replace("\n", "")
except EnvironmentError:
print("ERROR: Cannot find VERSION file at {}".format(version))
sys.exit(1)
# git version info
gitDir = os.path.join(OMNIPERF_HOME.parent, ".git")
if (shutil.which("git") is not None) and os.path.exists(gitDir):
gitQuery = subprocess.run(
["git", "log", "--pretty=format:%h", "-n", "1"],
stdout=subprocess.PIPE,
stderr=subprocess.DEVNULL,
)
if gitQuery.returncode != 0:
SHA = "unknown"
MODE = "unknown"
else:
SHA = gitQuery.stdout.decode("utf-8")
MODE = "dev"
else:
shaFile = os.path.join(OMNIPERF_HOME.parent, "VERSION.sha")
try:
with open(shaFile, "r") as file:
SHA = file.read().replace("\n", "")
except EnvironmentError:
print("ERROR: Cannot find VERSION.sha file at {}".format(shaFile))
sys.exit(1)
MODE = "release"
versionData = {"version": VER, "sha": SHA, "mode": MODE}
return versionData
def getVersionDisplay(version, sha, mode):
buf = io.StringIO()
print("-" * 40, file=buf)
print("Omniperf version: %s (%s)" % (version, mode), file=buf)
print("Git revision: %s" % sha, file=buf)
print("-" * 40, file=buf)
return buf.getvalue()
+2 -2
Zobrazit soubor
@@ -111,8 +111,8 @@ html_static_path = ["_static"]
htmlhelp_basename = "Omniperfdoc"
html_theme_options = {
# "analytics_id": "G-1HLBBRSTT9", # Provided by Google in your dashboard
# "analytics_anonymize_ip": False,
"analytics_id": "G-C5DYLCE9ED", # Provided by Google in your dashboard
"analytics_anonymize_ip": False,
"logo_only": False,
"display_version": True,
"prev_next_buttons_location": "bottom",
+88 -1
Zobrazit soubor
@@ -1,4 +1,4 @@
# Omniperf Grafana GUI Analyzer
# Grafana-based Analysis
```eval_rst
.. toctree::
@@ -65,6 +65,93 @@ The uniform color coding is applied to most visualizations (bars, table, diagram
![Grafana GUI Global Variables](images/global_variables.png)
## 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.
Each workload is imported to a separate database with the following naming convention:
omniperf_<team>_<database>_<soc>
e.g., omniperf_asw_vcopy_mi200.
Below is the sample command to import the *vcopy* profiling data.
```shell
$ omniperf database --help
ROC Profiler: /usr/bin/rocprof
usage:
omniperf database <interaction type> [connection options]
-------------------------------------------------------------------------------
Examples:
omniperf database --import -H pavii1 -u temp -t asw -w workloads/vcopy/mi200/
omniperf database --remove -H pavii1 -u temp -w omniperf_asw_sample_mi200
-------------------------------------------------------------------------------
Help:
-h, --help show this help message and exit
General Options:
-v, --version show program's version number and exit
-V, --verbose Increase output verbosity
Interaction Type:
-i, --import Import workload to Omniperf DB
-r, --remove Remove a workload from Omniperf DB
Connection Options:
-H , --host Name or IP address of the server host.
-P , --port TCP/IP Port. (DEFAULT: 27018)
-u , --username Username for authentication.
-p , --password The user's password. (will be requested later if it's not set)
-t , --team Specify Team prefix.
-w , --workload Specify name of workload (to remove) or path to workload (to import)
-k , --kernelVerbose Specify Kernel Name verbose level 1-5.
Lower the level, shorter the kernel name. (DEFAULT: 2) (DISABLE: 5)
```
**omniperf import for vcopy:**
```shell
$ omniperf database --import -H pavii1 -u temp -t asw -w workloads/vcopy/mi200/
ROC Profiler: /usr/bin/rocprof
--------
Import Profiling Results
--------
Pulling data from /home/amd/xlu/test/workloads/vcopy/mi200
The directory exists
Found sysinfo file
KernelName shortening enabled
Kernel name verbose level: 2
Password:
Password recieved
-- Conversion & Upload in Progress --
0%| | 0/11 [00:00<?, ?it/s]/home/amd/xlu/test/workloads/vcopy/mi200/SQ_IFETCH_LEVEL.csv
9%|█████████████████▉ | 1/11 [00:00<00:01, 8.53it/s]/home/amd/xlu/test/workloads/vcopy/mi200/pmc_perf.csv
18%|███████████████████████████████████▊ | 2/11 [00:00<00:01, 6.99it/s]/home/amd/xlu/test/workloads/vcopy/mi200/SQ_INST_LEVEL_SMEM.csv
27%|█████████████████████████████████████████████████████▋ | 3/11 [00:00<00:01, 7.90it/s]/home/amd/xlu/test/workloads/vcopy/mi200/SQ_LEVEL_WAVES.csv
36%|███████████████████████████████████████████████████████████████████████▋ | 4/11 [00:00<00:00, 8.56it/s]/home/amd/xlu/test/workloads/vcopy/mi200/SQ_INST_LEVEL_LDS.csv
45%|█████████████████████████████████████████████████████████████████████████████████████████▌ | 5/11 [00:00<00:00, 9.00it/s]/home/amd/xlu/test/workloads/vcopy/mi200/SQ_INST_LEVEL_VMEM.csv
55%|███████████████████████████████████████████████████████████████████████████████████████████████████████████▍ | 6/11 [00:00<00:00, 9.24it/s]/home/amd/xlu/test/workloads/vcopy/mi200/sysinfo.csv
64%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▎ | 7/11 [00:00<00:00, 9.37it/s]/home/amd/xlu/test/workloads/vcopy/mi200/roofline.csv
82%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▏ | 9/11 [00:00<00:00, 12.60it/s]/home/amd/xlu/test/workloads/vcopy/mi200/timestamps.csv
100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 11/11 [00:00<00:00, 11.05it/s]
9 collections added.
Workload name uploaded
-- Complete! --
```
## Omniperf Panels
### Overview
+1 -1
Zobrazit soubor
@@ -1,4 +1,4 @@
# Omniperf High Level Design
# High Level Design
```eval_rst
.. toctree::
Binární soubor nebyl zobrazen.

Za

Šířka:  |  Výška:  |  Velikost: 47 KiB

Binární soubor nebyl zobrazen.

Za

Šířka:  |  Výška:  |  Velikost: 113 KiB

Binární soubor nebyl zobrazen.

Za

Šířka:  |  Výška:  |  Velikost: 272 KiB

Binární soubor nebyl zobrazen.

Za

Šířka:  |  Výška:  |  Velikost: 57 KiB

Binární soubor nebyl zobrazen.

Za

Šířka:  |  Výška:  |  Velikost: 253 KiB

+1
Zobrazit soubor
@@ -11,6 +11,7 @@
installation
getting_started
performance_analysis
standalone_gui_analyzer
grafana_analyzer
faq
```
+39 -4
Zobrazit soubor
@@ -1,4 +1,4 @@
# Omniperf Deployment
# Deployment
```eval_rst
.. toctree::
@@ -146,7 +146,7 @@ optional `ROCPROF` environment variable.
---
## Omniperf Server Setup
## Server-side Setup
Note: Server-side setup is not required to profile or analyze
performance data from the CLI. It is provided as an additional mechanism to import performance
@@ -157,10 +157,10 @@ use the provided Docker file to build the Grafana and MongoDB
instance.
### Install MongoDB Utils
Omniperf uses [mongoimport](https://www.mongodb.com/docs/database-tools/mongoimport/) to upload data to Grafana's backend database
Omniperf uses [mongoimport](https://www.mongodb.com/docs/database-tools/mongoimport/) to upload data to Grafana's backend database. Install for Ubuntu 20.04 is as follows:
```bash
$ wget https://fastdl.mongodb.org/tools/db/mongodb-database-tools-ubuntu2004-x86_64-100.6.1.deb
$ sudo apt intall ./mongodb-database-tools-ubuntu2004-x86_64-100.6.1.deb
$ sudo apt install ./mongodb-database-tools-ubuntu2004-x86_64-100.6.1.deb
```
> Find install for alternative distros [here](https://www.mongodb.com/download-center/database-tools/releases/archive)
@@ -177,3 +177,38 @@ $ sudo docker volume create --driver local --opt type=none --opt device=/usr/loc
$ sudo docker-compose build
$ 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:
- Username: **admin**
- Password: **admin**
![Grafana Welcome Page](images/grafana_welcome.png)
MongoDB Datasource Configuration
The MongoDB Datasource shall be configured prior to the first-time use. Navigate to Grafana's Configuration page (shown below) to add the **Omniperf Data** connection.
![Omniperf Datasource Config](images/datasource_config.png)
Configure the following fields in the datasource:
- HTTP URL: set to *http://localhost:3333*
- MongoDB URL: set to *mongodb://temp:temp123@\<host-ip>:27018/admin?authSource=admin*
- Database Name: set to *admin*
After properly configuring these fields click **Save & Test** to make sure your connection is successful.
> Note to avoid potential DNS issue, one may need to use the actual IP address for the host node in the MongoDB URL.
![Datasource Settings](images/datasource_settings.png)
Omniperf Dashboard Import
From *Create* → *Import*, (as seen below) upload the dashboard file, `/dashboards/Omniperf_v{__VERSION__}_pub.json`, from the Omniperf tarball.
Edit both the Dashboard Name and the Unique Identifier (UID) to uniquely identify the dashboard he/she will use. Click Import to finish the process.
![Import Dashboard](images/import_dashboard.png)
+1 -88
Zobrazit soubor
@@ -1,4 +1,4 @@
# Omniperf Performance Analysis
# Performance Profiling
```eval_rst
.. toctree::
@@ -348,90 +348,3 @@ Dispatch Selection: ['0']
IP Blocks: All
... ...
```
## Omniperf 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.
Each workload is imported to a separate database with the following naming convention:
omniperf_<team>_<database>_<soc>
e.g., omniperf_asw_vcopy_mi200.
Below is the sample command to import the *vcopy* profiling data.
```shell
$ omniperf database --help
ROC Profiler: /usr/bin/rocprof
usage:
omniperf database <interaction type> [connection options]
-------------------------------------------------------------------------------
Examples:
omniperf database --import -H pavii1 -u amd -t asw -w workloads/vcopy/mi200/
omniperf database --remove -H pavii1 -u amd -w omniperf_asw_sample_mi200
-------------------------------------------------------------------------------
Help:
-h, --help show this help message and exit
General Options:
-v, --version show program's version number and exit
-V, --verbose Increase output verbosity
Interaction Type:
-i, --import Import workload to Omniperf DB
-r, --remove Remove a workload from Omniperf DB
Connection Options:
-H , --host Name or IP address of the server host.
-P , --port TCP/IP Port. (DEFAULT: 27018)
-u , --username Username for authentication.
-p , --password The user's password. (will be requested later if it's not set)
-t , --team Specify Team prefix.
-w , --workload Specify name of workload (to remove) or path to workload (to import)
-k , --kernelVerbose Specify Kernel Name verbose level 1-5.
Lower the level, shorter the kernel name. (DEFAULT: 2) (DISABLE: 5)
```
**omniperf import for vcopy:**
```shell
$ omniperf database --import -H pavii1 -u amd -t asw -w workloads/vcopy/mi200/
ROC Profiler: /usr/bin/rocprof
--------
Import Profiling Results
--------
Pulling data from /home/amd/xlu/test/workloads/vcopy/mi200
The directory exists
Found sysinfo file
KernelName shortening enabled
Kernel name verbose level: 2
Password:
Password recieved
-- Conversion & Upload in Progress --
0%| | 0/11 [00:00<?, ?it/s]/home/amd/xlu/test/workloads/vcopy/mi200/SQ_IFETCH_LEVEL.csv
9%|█████████████████▉ | 1/11 [00:00<00:01, 8.53it/s]/home/amd/xlu/test/workloads/vcopy/mi200/pmc_perf.csv
18%|███████████████████████████████████▊ | 2/11 [00:00<00:01, 6.99it/s]/home/amd/xlu/test/workloads/vcopy/mi200/SQ_INST_LEVEL_SMEM.csv
27%|█████████████████████████████████████████████████████▋ | 3/11 [00:00<00:01, 7.90it/s]/home/amd/xlu/test/workloads/vcopy/mi200/SQ_LEVEL_WAVES.csv
36%|███████████████████████████████████████████████████████████████████████▋ | 4/11 [00:00<00:00, 8.56it/s]/home/amd/xlu/test/workloads/vcopy/mi200/SQ_INST_LEVEL_LDS.csv
45%|█████████████████████████████████████████████████████████████████████████████████████████▌ | 5/11 [00:00<00:00, 9.00it/s]/home/amd/xlu/test/workloads/vcopy/mi200/SQ_INST_LEVEL_VMEM.csv
55%|███████████████████████████████████████████████████████████████████████████████████████████████████████████▍ | 6/11 [00:00<00:00, 9.24it/s]/home/amd/xlu/test/workloads/vcopy/mi200/sysinfo.csv
64%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▎ | 7/11 [00:00<00:00, 9.37it/s]/home/amd/xlu/test/workloads/vcopy/mi200/roofline.csv
82%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▏ | 9/11 [00:00<00:00, 12.60it/s]/home/amd/xlu/test/workloads/vcopy/mi200/timestamps.csv
100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 11/11 [00:00<00:00, 11.05it/s]
9 collections added.
Workload name uploaded
-- Complete! --
```
+85
Zobrazit soubor
@@ -0,0 +1,85 @@
# Web-based GUI Analysis
```eval_rst
.. toctree::
:glob:
:maxdepth: 4
```
## Features
Omniperf's standalone GUI analyzer is a lightweight web page that can
be generated directly from the command-line. This option is provided
as an alternative for users wanting to explore profiling results
graphically, but without the additional setup requirements or
server-side overhead of Omniperf's detailed [Grafana
interface](https://amdresearch.github.io/omniperf/grafana_analyzer.html#)
option. The standalone GUI analyzer is provided as simple
[Flask](https://flask.palletsprojects.com/en/2.2.x/) application
allowing users to view results from within a web browser.
```{admonition} Port forwarding
Note that the standalone GUI analyzer publishes a web interface on port 8050 by default.
On production HPC systems where profiling jobs run
under the auspices of a resource manager, additional ssh tunneling
between the desired web browser host (e.g. login node or remote workstation) and compute host may be
required. Alternatively, users may find it more convenient to download
profiled workloads to perform analysis on their local system.
```
## Usage
To launch the standalone GUI, include the `--gui` flag with your desired analysis command. For example:
```bash
$ omniperf analyze -p workloads/vcopy/mi200/ --gui
--------
Analyze
--------
Dash is running on http://0.0.0.0:8050/
* Serving Flask app 'omniperf_cli.omniperf_cli' (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on all addresses (0.0.0.0)
WARNING: This is a development server. Do not use it in a production deployment.
* Running on http://127.0.0.1:8050
* Running on http://10.228.32.139:8050 (Press CTRL+C to quit)
```
At this point, users can then launch their web browser of choice and
go to http://localhost:8050/ to see an analysis page.
![Standalone GUI Homepage](images/standalone_gui.png)
```{tip}
To launch the web application on a port other than 8050, include an optional port argument:
`--gui <desired port>`
```
When no filters are applied, users will see five basic sections derived from their application's profiling data:
1. Memory Chart Analysis
2. Empirical Roofline Analysis
3. Top Stats (Top Kernel Statistics)
4. System Info
5. System Speed-of-Light
To dive deeper, use the top drop down menus to isolate particular
kernel(s) or dispatch(s). You will then see the web page update with
metrics specific to the filter you've applied.
Once you have applied a filter, you will also see several additional
sections become available with detailed metrics specific to that area
of AMD hardware. These detailed sections mirror the data displayed in
Omniperf's [Grafana
interface](https://amdresearch.github.io/omniperf/grafana_analyzer.html#).
+10 -4
Zobrazit soubor
@@ -43,10 +43,11 @@ from common import (
OMNIPERF_HOME,
PROG,
SOC_LIST,
VER,
DISTRO_MAP,
) # Import global variables
from common import getVersion
################################################
# Helper Functions
################################################
@@ -305,7 +306,7 @@ def run_prof(fname, workload_dir, perfmon_dir, cmd, verbose):
)
def omniperf_profile(args):
def omniperf_profile(args,VER):
# Verify valid target
if args.target not in SOC_LIST:
parse.print_help(sys.stderr)
@@ -398,6 +399,8 @@ def omniperf_profile(args):
path_to_binary,
"-o",
workload_dir + "/" + "roofline.csv",
"-d",
str(args.device),
]
)
@@ -418,6 +421,9 @@ def main():
parse(my_parser)
args = my_parser.parse_args()
vData = getVersion()
VER = vData['version']
if args.mode == None:
throw_parse_error(
my_parser,
@@ -515,8 +521,8 @@ def main():
# Profile only
else:
print("\n--------\nProfile only\n--------\n")
omniperf_profile(args)
print("\n-------------\nProfile only\n-------------\n")
omniperf_profile(args,VER)
##############
# DATABASE MODE
+2 -4
Zobrazit soubor
@@ -175,9 +175,7 @@ def omniperf_cli(args):
args.path[0][0]
) # create mega df
is_gui = False
# parser.load_table_data(
# runs[args.path[0][0]], args.path[0][0], is_gui, args.g
# ) # create the loaded table
parser.load_kernel_top(runs[args.path[0][0]], args.path[0][0])
input_filters = {
"kernel": runs[args.path[0][0]].filter_kernel_ids,
@@ -217,7 +215,7 @@ def omniperf_cli(args):
runs[d[0]].raw_pmc = file_io.create_df_pmc(d[0]) # creates mega dataframe
is_gui = False
parser.load_table_data(
runs[d[0]], d[0], is_gui, args.g
runs[d[0]], d[0], is_gui, args.g, args.verbose
) # create the loaded table
if args.list_kernels:
tty.show_kernels(runs, archConfigs["gfx90a"], output, args.decimal)
+34 -9
Zobrazit soubor
@@ -29,6 +29,7 @@ from dash.dash_table import FormatTemplate
from dash.dash_table.Format import Format, Scheme, Symbol
from dash import html, dash_table
from dash.dependencies import Input, Output, State
import dash_bootstrap_components as dbc
from dash import dcc
import plotly.express as px
@@ -307,9 +308,7 @@ def build_layout(
Build gui layout
"""
comparable_columns = parser.build_comparable_columns(time_unit)
base_run, base_data = next(iter(runs.items()))
app.layout = html.Div(style={"backgroundColor": "rgb(50, 50, 50)" if IS_DARK else ""})
filt_kernel_names = []
@@ -319,8 +318,17 @@ def build_layout(
app.layout.children = html.Div(
children=[
get_header(runs[path_to_dir].raw_pmc, input_filters, filt_kernel_names),
html.Div(id="container", children=[]),
dbc.Spinner(
children=[
get_header(
runs[path_to_dir].raw_pmc, input_filters, filt_kernel_names
),
html.Div(id="container", children=[]),
],
fullscreen=True,
color="primary",
spinner_style={"width": "6rem", "height": "6rem"},
)
]
)
@@ -333,12 +341,13 @@ def build_layout(
)
def generate_from_filter(disp_filt, kernel_filter, gcd_filter, div_children):
runs[path_to_dir].dfs = copy.deepcopy(archConfigs.dfs) # reset the equations
panel_configs = copy.deepcopy(archConfigs.panel_configs)
# Generate original raw df
runs[path_to_dir].raw_pmc = file_io.create_df_pmc(path_to_dir)
if verbose:
if verbose >= 1:
print("disp-filter is ", disp_filt)
print("kernel-filter is ", kernel_filter)
print("gpu-filter is ", gcd_filter)
print("gpu-filter is ", gcd_filter, "\n")
runs[path_to_dir].filter_kernel_ids = kernel_filter
runs[path_to_dir].filter_gpu_ids = gcd_filter
runs[path_to_dir].filter_dispatch_ids = disp_filt
@@ -351,11 +360,27 @@ def build_layout(
time_unit,
num_results,
)
# Evaluate metrics and table data from the raw df
is_gui = True
# Only display basic metrics if no filters are applied
if not (disp_filt or kernel_filter or gcd_filter):
temp = {}
keep = [1, 201, 101, 1901]
for key in runs[path_to_dir].dfs:
if keep.count(key) != 0:
temp[key] = runs[path_to_dir].dfs[key]
runs[path_to_dir].dfs = temp
temp = {}
keep = [0, 100, 200, 1900]
for key in panel_configs:
if keep.count(key) != 0:
temp[key] = panel_configs[key]
panel_configs = temp
parser.load_table_data(
runs[path_to_dir], path_to_dir, True, debug
runs[path_to_dir], path_to_dir, True, debug, verbose
) # Note: All the filtering happens in this function
div_children = []
div_children.append(
get_memchart(archConfigs.panel_configs[1900]["data source"], base_data)
@@ -369,7 +394,7 @@ def build_layout(
)
)
# Iterate over each section as defined in panel configs
for panel_id, panel in archConfigs.panel_configs.items():
for panel_id, panel in panel_configs.items():
title = str(panel_id // 100) + ". " + panel["title"]
section_title = (
panel["title"]
+1 -1
Zobrazit soubor
@@ -183,7 +183,7 @@ def get_roofline(path_to_dir, ret_df, verbose):
# Generate roofline plots
print("Path: ", path_to_dir)
ai_data = roofline_calc.plot_application("kernels", ret_df, verbose)
if verbose:
if verbose >= 1:
# print AI data for each mem level
for i in ai_data:
print(i, "->", ai_data[i])
+13 -10
Zobrazit soubor
@@ -650,7 +650,6 @@ def apply_filters(workload, is_gui, debug):
# NB: support ignoring the 1st n dispatched execution by '> n'
# The better way may be parsing python slice string
for d in workload.filter_dispatch_ids:
print("len of ret_df is ", len(ret_df))
if int(d) > len(ret_df) - 2: # subtract 2 bc of the two header rows
print("{} is an invalid dispatch id.".format(d))
sys.exit(1)
@@ -674,12 +673,7 @@ def apply_filters(workload, is_gui, debug):
return ret_df
def load_table_data(workload, dir, is_gui, debug):
"""
Load data for all "raw_csv_table".
Calculate mertric value for all "metric_table".
"""
def load_kernel_top(workload, dir):
# NB:
# - Do pmc_kernel_top.csv loading before eval_metric because we need the kernel names.
# - There might be a better way/timing to load raw_csv_table.
@@ -698,9 +692,16 @@ def load_table_data(workload, dir, is_gui, debug):
# All transposed columns should be marked with a general header,
# so tty could detect them and show them correctly in comparison.
tmp[id].columns = ["Info"]
workload.dfs.update(tmp)
def load_table_data(workload, dir, is_gui, debug, verbose):
"""
Load data for all "raw_csv_table".
Calculate mertric value for all "metric_table".
"""
load_kernel_top(workload, dir)
eval_metric(
workload.dfs,
workload.dfs_type,
@@ -715,9 +716,11 @@ def load_table_data(workload, dir, is_gui, debug):
out_path = os.path.join(dir, name)
try:
os.mkdir(out_path)
print("Created a Saved Analysis folder")
if verbose >= 1:
print("Created a Saved Analysis folder")
except OSError as error:
print("Saved Analysis folder exists")
if verbose >= 1:
print("Saved Analysis folder exists")
for id, df in workload.dfs.items():
if "coll_level" in list(df.columns):
df = df.drop(["coll_level", "Tips"], axis=1)
+8 -8
Zobrazit soubor
@@ -239,7 +239,7 @@ def plot_application(sortType, ret_df, verbose):
avgDuration / calls,
)
)
if verbose:
if verbose >= 2:
print(
"Just added {} to AI_Data at index {}. # of calls: {}".format(
kernelName, index, calls
@@ -299,7 +299,7 @@ def plot_application(sortType, ret_df, verbose):
+ (row["SQ_INSTS_VALU_MFMA_MOPS_F64"] * 512)
)
except KeyError:
if verbose:
if verbose >= 2:
print("Skipped total_flops at index {}".format(index))
pass
try:
@@ -327,7 +327,7 @@ def plot_application(sortType, ret_df, verbose):
)
)
except KeyError:
if verbose:
if verbose >= 2:
print("Skipped valu_flops at index {}".format(index))
pass
@@ -338,7 +338,7 @@ def plot_application(sortType, ret_df, verbose):
mfma_flops_f64 += row["SQ_INSTS_VALU_MFMA_MOPS_F64"] * 512
mfma_iops_i8 += row["SQ_INSTS_VALU_MFMA_MOPS_I8"] * 512
except KeyError:
if verbose:
if verbose >= 2:
print("Skipped mfma ops at index {}".format(index))
pass
@@ -347,14 +347,14 @@ def plot_application(sortType, ret_df, verbose):
(row["SQ_LDS_IDX_ACTIVE"] - row["SQ_LDS_BANK_CONFLICT"]) * 4 * L2_BANKS
) # L2_BANKS = 32 (since assuming mi200)
except KeyError:
if verbose:
if verbose >= 2:
print("Skipped lds_data at index {}".format(index))
pass
try:
L1cache_data += row["TCP_TOTAL_CACHE_ACCESSES_sum"] * 64
except KeyError:
if verbose:
if verbose >= 2:
print("Skipped L1cache_data at index {}".format(index))
pass
@@ -366,7 +366,7 @@ def plot_application(sortType, ret_df, verbose):
+ row["TCP_TCC_READ_REQ_sum"] * 64
)
except KeyError:
if verbose:
if verbose >= 2:
print("Skipped L2cache_data at index {}".format(index))
pass
try:
@@ -377,7 +377,7 @@ def plot_application(sortType, ret_df, verbose):
+ ((row["TCC_EA_WRREQ_sum"] - row["TCC_EA_WRREQ_64B_sum"]) * 32)
)
except KeyError:
if verbose:
if verbose >= 2:
print("Skipped hbm_data at index {}".format(index))
pass
+15 -19
Zobrazit soubor
@@ -26,11 +26,16 @@ from common import (
OMNIPERF_HOME,
PROG,
SOC_LIST,
VER,
) # Import global variables
from common import getVersion, getVersionDisplay
def parse(my_parser):
# versioning info
vData = getVersion()
versionString = getVersionDisplay(vData["version"], vData["sha"], vData["mode"])
# -----------------------------------------
# Parse arguments (dependent on mode)
# -----------------------------------------
@@ -40,9 +45,7 @@ def parse(my_parser):
general_group = my_parser.add_argument_group("General Options")
my_parser._positionals.title = "Modes"
my_parser._optionals.title = "Help"
general_group.add_argument(
"-v", "--version", action="version", version=PROG + " (" + VER + ")"
)
general_group.add_argument("-v", "--version", action="version", version=versionString)
subparsers = my_parser.add_subparsers(
dest="mode", help="Select mode of interaction with the target application:"
@@ -76,13 +79,10 @@ def parse(my_parser):
profile_group = profile_parser.add_argument_group("Profile Options")
roofline_group = profile_parser.add_argument_group("Standalone Roofline Options")
general_group.add_argument("-v", "--version", action="version", version=versionString)
general_group.add_argument(
"-v", "--version", action="version", version="%(PROG)s (" + VER + ")"
"-V", "--verbose", help="Increase output verbosity", action="count", default=0
)
general_group.add_argument(
"-V", "--verbose", help="Increase output verbosity", action="store_true"
)
profile_group.add_argument(
"-n",
"--name",
@@ -211,8 +211,8 @@ def parse(my_parser):
\n\n-------------------------------------------------------------------------------
\nExamples:
\n\tomniperf database --import -H pavii1 -u amd -t asw -w workloads/vcopy/mi200/
\n\tomniperf database --remove -H pavii1 -u amd -w omniperf_asw_sample_mi200
\n\tomniperf database --import -H pavii1 -u temp -t asw -w workloads/vcopy/mi200/
\n\tomniperf database --remove -H pavii1 -u temp -w omniperf_asw_sample_mi200
\n-------------------------------------------------------------------------------\n
""",
prog="tool",
@@ -227,11 +227,9 @@ def parse(my_parser):
interaction_group = db_parser.add_argument_group("Interaction Type")
connection_group = db_parser.add_argument_group("Connection Options")
general_group.add_argument("-v", "--version", action="version", version=versionString)
general_group.add_argument(
"-v", "--version", action="version", version="%(PROG)s (" + VER + ")"
)
general_group.add_argument(
"-V", "--verbose", help="Increase output verbosity", action="store_true"
"-V", "--verbose", help="Increase output verbosity", action="count", default=0
)
interaction_group.add_argument(
@@ -327,11 +325,9 @@ def parse(my_parser):
general_group = analyze_parser.add_argument_group("General Options")
analyze_group = analyze_parser.add_argument_group("Analyze Options")
general_group.add_argument("-v", "--version", action="version", version=versionString)
general_group.add_argument(
"-v", "--version", action="version", version="%(PROG)s (" + VER + ")"
)
general_group.add_argument(
"-V", "--verbose", help="Increase output verbosity", action="store_true"
"-V", "--verbose", help="Increase output verbosity", action="count", default=0
)
analyze_group.add_argument(
+8 -8
Zobrazit soubor
@@ -294,7 +294,7 @@ def plot_application(inputs, verbose):
avgDuration / calls,
)
)
if verbose:
if verbose >= 2:
print(
"Just added {} to AI_Data at index {}. # of calls: {}".format(
kernelName, index, calls
@@ -354,7 +354,7 @@ def plot_application(inputs, verbose):
+ (row["SQ_INSTS_VALU_MFMA_MOPS_F64"] * 512)
)
except KeyError:
if verbose:
if verbose >= 2:
print("Skipped total_flops at index {}".format(index))
pass
try:
@@ -382,7 +382,7 @@ def plot_application(inputs, verbose):
)
)
except KeyError:
if verbose:
if verbose >= 2:
print("Skipped valu_flops at index {}".format(index))
pass
@@ -393,7 +393,7 @@ def plot_application(inputs, verbose):
mfma_flops_f64 += row["SQ_INSTS_VALU_MFMA_MOPS_F64"] * 512
mfma_iops_i8 += row["SQ_INSTS_VALU_MFMA_MOPS_I8"] * 512
except KeyError:
if verbose:
if verbose >= 2:
print("Skipped mfma ops at index {}".format(index))
pass
@@ -402,14 +402,14 @@ def plot_application(inputs, verbose):
(row["SQ_LDS_IDX_ACTIVE"] - row["SQ_LDS_BANK_CONFLICT"]) * 4 * L2_BANKS
) # L2_BANKS = 32 (since assuming mi200)
except KeyError:
if verbose:
if verbose >= 2:
print("Skipped lds_data at index {}".format(index))
pass
try:
L1cache_data += row["TCP_TOTAL_CACHE_ACCESSES_sum"] * 64
except KeyError:
if verbose:
if verbose >= 2:
print("Skipped L1cache_data at index {}".format(index))
pass
@@ -421,7 +421,7 @@ def plot_application(inputs, verbose):
+ row["TCP_TCC_READ_REQ_sum"] * 64
)
except KeyError:
if verbose:
if verbose >= 2:
print("Skipped L2cache_data at index {}".format(index))
pass
try:
@@ -432,7 +432,7 @@ def plot_application(inputs, verbose):
+ ((row["TCC_EA_WRREQ_sum"] - row["TCC_EA_WRREQ_64B_sum"]) * 32)
)
except KeyError:
if verbose:
if verbose >= 2:
print("Skipped hbm_data at index {}".format(index))
pass
+2 -2
Zobrazit soubor
@@ -35,7 +35,7 @@ if __name__ == "__main__":
test = (
"\n\ndef test_import_"
+ workload_name
+ "_mi100():\n with patch('sys.argv',['omniperf', 'database', '--import', '-H', 'localhost', '-u', 'amd', '-p', 'amd123', '-t', 'asw', '-w', '"
+ "_mi100():\n with patch('sys.argv',['omniperf', 'database', '--import', '-H', 'localhost', '-u', 'temp', '-p', 'temp123', '-t', 'asw', '-w', '"
+ workload
+ "/mi100']): omniperf.main()"
)
@@ -65,7 +65,7 @@ if __name__ == "__main__":
test = (
"\n\ndef test_"
+ workload_name
+ "_mi100():\n with patch('sys.argv',['omniperf', 'database', '--import', '-H', 'localhost', '-u', '-p', 'amd123', 'amd', '-t', 'asw', '-w', '"
+ "_mi100():\n with patch('sys.argv',['omniperf', 'database', '--import', '-H', 'localhost', '-u', 'temp', '-p', 'temp123', '-t', 'asw', '-w', '"
+ workload
+ "/mi100']): omniperf.main()"
)
Rozdílový obsah nebyl zobrazen, protože je příliš veliký Načíst rozdílové porovnání