Merge branch 'dev' of https://github.com/AMDResearch/omniperf into kernel_name_mappings

[ROCm/rocprofiler-compute commit: 76da2a9ed5]
This commit is contained in:
JoseSantosAMD
2023-08-08 14:49:59 -05:00
bovenliggende a712bcef4b 00e4558fca
commit 67971bca46
56 gewijzigde bestanden met toevoegingen van 1345 en 213 verwijderingen
Bestand-diff onderdrukt omdat een of meer regels te lang zijn
@@ -7,7 +7,7 @@ gpgkey=https://repo.radeon.com/rocm/rocm.gpg.key
[amdgpu]
name=amdgpu
baseurl=https://repo.radeon.com/amdgpu/latest/rhel/8.5/main/x86_64
baseurl=https://repo.radeon.com/amdgpu/latest/rhel/8.8/main/x86_64
enabled=1
gpgcheck=1
gpgkey=https://repo.radeon.com/rocm/rocm.gpg.key
@@ -0,0 +1,13 @@
/*
* ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️
*
* In order to extend the configuration follow the steps in
* https://grafana.github.io/plugin-tools/docs/advanced-configuration#extending-the-eslint-config
*/
{
"extends": ["@grafana/eslint-config"],
"root": true,
"rules": {
"react/prop-types": "off"
}
}
@@ -0,0 +1,16 @@
/*
* ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️
*
* In order to extend the configuration follow the steps in .config/README.md
*/
module.exports = {
"endOfLine": "auto",
"printWidth": 120,
"trailingComma": "es5",
"semi": true,
"jsxSingleQuote": false,
"singleQuote": true,
"useTabs": false,
"tabWidth": 2
};
@@ -0,0 +1,16 @@
ARG grafana_version=latest
ARG grafana_image=grafana-enterprise
FROM grafana/${grafana_image}:${grafana_version}
# Make it as simple as possible to access the grafana instance for development purposes
# Do NOT enable these settings in a public facing / production grafana instance
ENV GF_AUTH_ANONYMOUS_ORG_ROLE "Admin"
ENV GF_AUTH_ANONYMOUS_ENABLED "true"
ENV GF_AUTH_BASIC_ENABLED "false"
# Set development mode so plugins can be loaded without the need to sign
ENV GF_DEFAULT_APP_MODE "development"
# Inject livereload script into grafana index.html
USER root
RUN sed -i 's/<\/body><\/html>/<script src=\"http:\/\/localhost:35729\/livereload.js\"><\/script><\/body><\/html>/g' /usr/share/grafana/public/views/index.html
@@ -0,0 +1,164 @@
# Default build configuration by Grafana
**This is an auto-generated directory and is not intended to be changed! ⚠️**
The `.config/` directory holds basic configuration for the different tools
that are used to develop, test and build the project. In order to make it updates easier we ask you to
not edit files in this folder to extend configuration.
## How to extend the basic configs?
Bear in mind that you are doing it at your own risk, and that extending any of the basic configuration can lead
to issues around working with the project.
### Extending the ESLint config
Edit the `.eslintrc` file in the project root in order to extend the ESLint configuration.
**Example:**
```json
{
"extends": "./.config/.eslintrc",
"rules": {
"react/prop-types": "off"
}
}
```
---
### Extending the Prettier config
Edit the `.prettierrc.js` file in the project root in order to extend the Prettier configuration.
**Example:**
```javascript
module.exports = {
// Prettier configuration provided by Grafana scaffolding
...require('./.config/.prettierrc.js'),
semi: false,
};
```
---
### Extending the Jest config
There are two configuration in the project root that belong to Jest: `jest-setup.js` and `jest.config.js`.
**`jest-setup.js`:** A file that is run before each test file in the suite is executed. We are using it to
set up the Jest DOM for the testing library and to apply some polyfills. ([link to Jest docs](https://jestjs.io/docs/configuration#setupfilesafterenv-array))
**`jest.config.js`:** The main Jest configuration file that extends the Grafana recommended setup. ([link to Jest docs](https://jestjs.io/docs/configuration))
#### ESM errors with Jest
A common issue found with the current jest config involves importing an npm package which only offers an ESM build. These packages cause jest to error with `SyntaxError: Cannot use import statement outside a module`. To work around this we provide a list of known packages to pass to the `[transformIgnorePatterns](https://jestjs.io/docs/configuration#transformignorepatterns-arraystring)` jest configuration property. If need be this can be extended in the following way:
```javascript
process.env.TZ = 'UTC';
const { grafanaESModules, nodeModulesToTransform } = require('./config/jest/utils');
module.exports = {
// Jest configuration provided by Grafana
...require('./.config/jest.config'),
// Inform jest to only transform specific node_module packages.
transformIgnorePatterns: [nodeModulesToTransform([...grafanaESModules, 'packageName'])],
};
```
---
### Extending the TypeScript config
Edit the `tsconfig.json` file in the project root in order to extend the TypeScript configuration.
**Example:**
```json
{
"extends": "./.config/tsconfig.json",
"compilerOptions": {
"preserveConstEnums": true
}
}
```
---
### Extending the Webpack config
Follow these steps to extend the basic Webpack configuration that lives under `.config/`:
#### 1. Create a new Webpack configuration file
Create a new config file that is going to extend the basic one provided by Grafana.
It can live in the project root, e.g. `webpack.config.ts`.
#### 2. Merge the basic config provided by Grafana and your custom setup
We are going to use [`webpack-merge`](https://github.com/survivejs/webpack-merge) for this.
```typescript
// webpack.config.ts
import type { Configuration } from 'webpack';
import { merge } from 'webpack-merge';
import grafanaConfig from './.config/webpack/webpack.config';
const config = async (env): Promise<Configuration> => {
const baseConfig = await grafanaConfig(env);
return merge(baseConfig, {
// Add custom config here...
output: {
asyncChunks: true,
},
});
};
export default config;
```
#### 3. Update the `package.json` to use the new Webpack config
We need to update the `scripts` in the `package.json` to use the extended Webpack configuration.
**Update for `build`:**
```diff
-"build": "webpack -c ./.config/webpack/webpack.config.ts --env production",
+"build": "webpack -c ./webpack.config.ts --env production",
```
**Update for `dev`:**
```diff
-"dev": "webpack -w -c ./.config/webpack/webpack.config.ts --env development",
+"dev": "webpack -w -c ./webpack.config.ts --env development",
```
### Configure grafana image to use when running docker
By default `grafana-enterprise` will be used as the docker image for all docker related commands. If you want to override this behaviour simply alter the `docker-compose.yaml` by adding the following build arg `grafana_image`.
**Example:**
```yaml
version: '3.7'
services:
grafana:
container_name: 'myorg-basic-app'
build:
context: ./.config
args:
grafana_version: ${GRAFANA_VERSION:-9.1.2}
grafana_image: ${GRAFANA_IMAGE:-grafana}
```
In this example we are assigning the environment variable `GRAFANA_IMAGE` to the build arg `grafana_image` with a default value of `grafana`. This will give you the possibility to set the value while running the docker-compose commands which might be convinent in some scenarios.
---
@@ -0,0 +1,25 @@
/*
* ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️
*
* In order to extend the configuration follow the steps in
* https://grafana.github.io/plugin-tools/docs/advanced-configuration#extending-the-jest-config
*/
import '@testing-library/jest-dom';
// https://jestjs.io/docs/manual-mocks#mocking-methods-which-are-not-implemented-in-jsdom
Object.defineProperty(global, 'matchMedia', {
writable: true,
value: jest.fn().mockImplementation((query) => ({
matches: false,
media: query,
onchange: null,
addListener: jest.fn(), // deprecated
removeListener: jest.fn(), // deprecated
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
dispatchEvent: jest.fn(),
})),
});
HTMLCanvasElement.prototype.getContext = () => {};
@@ -0,0 +1,43 @@
/*
* ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️
*
* In order to extend the configuration follow the steps in
* https://grafana.github.io/plugin-tools/docs/advanced-configuration#extending-the-jest-config
*/
const path = require('path');
const { grafanaESModules, nodeModulesToTransform } = require('./jest/utils');
module.exports = {
moduleNameMapper: {
'\\.(css|scss|sass)$': 'identity-obj-proxy',
'react-inlinesvg': path.resolve(__dirname, 'jest', 'mocks', 'react-inlinesvg.tsx'),
},
modulePaths: ['<rootDir>/src'],
setupFilesAfterEnv: ['<rootDir>/jest-setup.js'],
testEnvironment: 'jest-environment-jsdom',
testMatch: [
'<rootDir>/src/**/__tests__/**/*.{js,jsx,ts,tsx}',
'<rootDir>/src/**/*.{spec,test,jest}.{js,jsx,ts,tsx}',
'<rootDir>/src/**/*.{spec,test,jest}.{js,jsx,ts,tsx}',
],
transform: {
'^.+\\.(t|j)sx?$': [
'@swc/jest',
{
sourceMaps: 'inline',
jsc: {
parser: {
syntax: 'typescript',
tsx: true,
decorators: false,
dynamicImport: true,
},
},
},
],
},
// Jest will throw `Cannot use import statement outside module` if it tries to load an
// ES module without it being transformed first. ./config/README.md#esm-errors-with-jest
transformIgnorePatterns: [nodeModulesToTransform(grafanaESModules)],
};
@@ -0,0 +1,25 @@
// Due to the grafana/ui Icon component making fetch requests to
// `/public/img/icon/<icon_name>.svg` we need to mock react-inlinesvg to prevent
// the failed fetch requests from displaying errors in console.
import React from 'react';
type Callback = (...args: any[]) => void;
export interface StorageItem {
content: string;
queue: Callback[];
status: string;
}
export const cacheStore: { [key: string]: StorageItem } = Object.create(null);
const SVG_FILE_NAME_REGEX = /(.+)\/(.+)\.svg$/;
const InlineSVG = ({ src }: { src: string }) => {
// testId will be the file name without extension (e.g. `public/img/icons/angle-double-down.svg` -> `angle-double-down`)
const testId = src.replace(SVG_FILE_NAME_REGEX, '$2');
return <svg xmlns="http://www.w3.org/2000/svg" data-testid={testId} viewBox="0 0 24 24" />;
};
export default InlineSVG;
@@ -0,0 +1,31 @@
/*
* ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️
*
* In order to extend the configuration follow the steps in .config/README.md
*/
/*
* This utility function is useful in combination with jest `transformIgnorePatterns` config
* to transform specific packages (e.g.ES modules) in a projects node_modules folder.
*/
const nodeModulesToTransform = (moduleNames) => `node_modules\/(?!(${moduleNames.join('|')})\/)`;
// Array of known nested grafana package dependencies that only bundle an ESM version
const grafanaESModules = [
'.pnpm', // Support using pnpm symlinked packages
'@grafana/schema',
'd3',
'd3-color',
'd3-force',
'd3-interpolate',
'd3-scale-chromatic',
'ol',
'react-colorful',
'rxjs',
'uuid',
];
module.exports = {
nodeModulesToTransform,
grafanaESModules,
};
@@ -0,0 +1,26 @@
/*
* THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY.
*
* In order to extend the configuration follow the steps in
* https://grafana.github.io/plugin-tools/docs/advanced-configuration#extending-the-typescript-config
*/
{
"compilerOptions": {
"alwaysStrict": true,
"declaration": false,
"rootDir": "../src",
"baseUrl": "../src",
"typeRoots": ["../node_modules/@types"],
"resolveJsonModule": true
},
"ts-node": {
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"esModuleInterop": true
},
"transpileOnly": true
},
"include": ["../src", "./types"],
"extends": "@grafana/tsconfig"
}
@@ -0,0 +1,37 @@
// Image declarations
declare module '*.gif' {
const src: string;
export default src;
}
declare module '*.jpg' {
const src: string;
export default src;
}
declare module '*.jpeg' {
const src: string;
export default src;
}
declare module '*.png' {
const src: string;
export default src;
}
declare module '*.webp' {
const src: string;
export default src;
}
declare module '*.svg' {
const content: string;
export default content;
}
// Font declarations
declare module '*.woff';
declare module '*.woff2';
declare module '*.eot';
declare module '*.ttf';
declare module '*.otf';
@@ -0,0 +1,2 @@
export const SOURCE_DIR = 'src';
export const DIST_DIR = 'dist';
@@ -0,0 +1,40 @@
import fs from 'fs';
import path from 'path';
import util from 'util';
import { glob } from 'glob';
import { SOURCE_DIR } from './constants';
export function getPackageJson() {
return require(path.resolve(process.cwd(), 'package.json'));
}
export function getPluginJson() {
return require(path.resolve(process.cwd(), `${SOURCE_DIR}/plugin.json`));
}
export function hasReadme() {
return fs.existsSync(path.resolve(process.cwd(), SOURCE_DIR, 'README.md'));
}
// Support bundling nested plugins by finding all plugin.json files in src directory
// then checking for a sibling module.[jt]sx? file.
export async function getEntries(): Promise<Record<string, string>> {
const pluginsJson = await glob('**/src/**/plugin.json', { absolute: true });
const plugins = await Promise.all(pluginsJson.map((pluginJson) => {
const folder = path.dirname(pluginJson);
return glob(`${folder}/module.{ts,tsx,js,jsx}`, { absolute: true });
})
);
return plugins.reduce((result, modules) => {
return modules.reduce((result, module) => {
const pluginPath = path.dirname(module);
const pluginName = path.relative(process.cwd(), pluginPath).replace(/src\/?/i, '');
const entryName = pluginName === '' ? 'module' : `${pluginName}/module`;
result[entryName] = module;
return result;
}, result);
}, {});
}
@@ -0,0 +1,201 @@
/*
* ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️
*
* In order to extend the configuration follow the steps in
* https://grafana.github.io/plugin-tools/docs/advanced-configuration#extending-the-webpack-config
*/
import CopyWebpackPlugin from 'copy-webpack-plugin';
import ESLintPlugin from 'eslint-webpack-plugin';
import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin';
import LiveReloadPlugin from 'webpack-livereload-plugin';
import path from 'path';
import ReplaceInFileWebpackPlugin from 'replace-in-file-webpack-plugin';
import { Configuration } from 'webpack';
import { getPackageJson, getPluginJson, hasReadme, getEntries } from './utils';
import { SOURCE_DIR, DIST_DIR } from './constants';
const pluginJson = getPluginJson();
const config = async (env): Promise<Configuration> => ({
cache: {
type: 'filesystem',
buildDependencies: {
config: [__filename],
},
},
context: path.join(process.cwd(), SOURCE_DIR),
devtool: env.production ? 'source-map' : 'eval-source-map',
entry: await getEntries(),
externals: [
'lodash',
'jquery',
'moment',
'slate',
'emotion',
'@emotion/react',
'@emotion/css',
'prismjs',
'slate-plain-serializer',
'@grafana/slate-react',
'react',
'react-dom',
'react-redux',
'redux',
'rxjs',
'react-router',
'react-router-dom',
'd3',
'angular',
'@grafana/ui',
'@grafana/runtime',
'@grafana/data',
// Mark legacy SDK imports as external if their name starts with the "grafana/" prefix
({ request }, callback) => {
const prefix = 'grafana/';
const hasPrefix = (request) => request.indexOf(prefix) === 0;
const stripPrefix = (request) => request.substr(prefix.length);
if (hasPrefix(request)) {
return callback(undefined, stripPrefix(request));
}
callback();
},
],
mode: env.production ? 'production' : 'development',
module: {
rules: [
{
exclude: /(node_modules)/,
test: /\.[tj]sx?$/,
use: {
loader: 'swc-loader',
options: {
jsc: {
baseUrl: './src',
target: 'es2015',
loose: false,
parser: {
syntax: 'typescript',
tsx: true,
decorators: false,
dynamicImport: true,
},
},
},
},
},
{
test: /\.css$/,
use: ["style-loader", "css-loader"]
},
{
test: /\.s[ac]ss$/,
use: ['style-loader', 'css-loader', 'sass-loader'],
},
{
test: /\.(png|jpe?g|gif|svg)$/,
type: 'asset/resource',
generator: {
// Keep publicPath relative for host.com/grafana/ deployments
publicPath: `public/plugins/${pluginJson.id}/img/`,
outputPath: 'img/',
filename: Boolean(env.production) ? '[hash][ext]' : '[name][ext]',
},
},
{
test: /\.(woff|woff2|eot|ttf|otf)(\?v=\d+\.\d+\.\d+)?$/,
type: 'asset/resource',
generator: {
// Keep publicPath relative for host.com/grafana/ deployments
publicPath: `public/plugins/${pluginJson.id}/fonts/`,
outputPath: 'fonts/',
filename: Boolean(env.production) ? '[hash][ext]' : '[name][ext]',
},
},
],
},
output: {
clean: {
keep: new RegExp(`.*?_(amd64|arm(64)?)(.exe)?`),
},
filename: '[name].js',
library: {
type: 'amd',
},
path: path.resolve(process.cwd(), DIST_DIR),
publicPath: '/',
},
plugins: [
new CopyWebpackPlugin({
patterns: [
// If src/README.md exists use it; otherwise the root README
// To `compiler.options.output`
{ from: hasReadme() ? 'README.md' : '../README.md', to: '.', force: true },
{ from: 'plugin.json', to: '.' },
{ from: '../LICENSE', to: '.' },
{ from: '../CHANGELOG.md', to: '.', force: true },
{ from: '**/*.json', to: '.' }, // TODO<Add an error for checking the basic structure of the repo>
{ from: '**/*.svg', to: '.', noErrorOnMissing: true }, // Optional
{ from: '**/*.png', to: '.', noErrorOnMissing: true }, // Optional
{ from: '**/*.html', to: '.', noErrorOnMissing: true }, // Optional
{ from: 'img/**/*', to: '.', noErrorOnMissing: true }, // Optional
{ from: 'libs/**/*', to: '.', noErrorOnMissing: true }, // Optional
{ from: 'static/**/*', to: '.', noErrorOnMissing: true }, // Optional
],
}),
// Replace certain template-variables in the README and plugin.json
new ReplaceInFileWebpackPlugin([
{
dir: DIST_DIR,
files: ['plugin.json', 'README.md'],
rules: [
{
search: /\%VERSION\%/g,
replace: getPackageJson().version,
},
{
search: /\%TODAY\%/g,
replace: new Date().toISOString().substring(0, 10),
},
{
search: /\%PLUGIN_ID\%/g,
replace: pluginJson.id,
},
],
},
]),
new ForkTsCheckerWebpackPlugin({
async: Boolean(env.development),
issue: {
include: [{ file: '**/*.{ts,tsx}' }],
},
typescript: { configFile: path.join(process.cwd(), 'tsconfig.json') },
}),
new ESLintPlugin({
extensions: ['.ts', '.tsx'],
lintDirtyModulesOnly: Boolean(env.development), // don't lint on start, only lint changed files
}),
...(env.development ? [new LiveReloadPlugin()] : []),
],
resolve: {
extensions: ['.js', '.jsx', '.ts', '.tsx'],
// handle resolving "rootDir" paths
modules: [path.resolve(process.cwd(), 'src'), 'node_modules'],
unsafeCache: true,
},
});
export default config;
@@ -0,0 +1,3 @@
{
"extends": "./.config/.eslintrc"
}
@@ -1,3 +1,4 @@
module.exports = {
...require("./node_modules/@grafana/toolkit/src/config/prettier.plugin.config.json"),
};
// Prettier configuration provided by Grafana scaffolding
...require("./.config/.prettierrc.js")
};
@@ -0,0 +1,15 @@
version: '3.0'
services:
grafana:
container_name: 'amd-custom-svg'
build:
context: ./.config
args:
grafana_image: ${GRAFANA_IMAGE:-grafana-enterprise}
grafana_version: ${GRAFANA_VERSION:-9.5.3}
ports:
- 3000:3000/tcp
volumes:
- ./dist:/var/lib/grafana/plugins/amd-custom-svg
- ./provisioning:/etc/grafana/provisioning
@@ -0,0 +1,2 @@
// Jest setup provided by Grafana scaffolding
import './.config/jest-setup';
@@ -0,0 +1,8 @@
// force timezone to UTC to allow tests to work regardless of local timezone
// generally used by snapshots, but can affect specific tests
process.env.TZ = 'UTC';
module.exports = {
// Jest configuration provided by Grafana scaffolding
...require('./.config/jest.config'),
};
@@ -3,29 +3,72 @@
"version": "1.0.0",
"description": "",
"scripts": {
"build": "grafana-toolkit plugin:build",
"test": "grafana-toolkit plugin:test",
"dev": "grafana-toolkit plugin:dev",
"watch": "grafana-toolkit plugin:dev --watch",
"sign": "grafana-toolkit plugin:sign",
"start": "yarn watch"
"build": "webpack -c ./.config/webpack/webpack.config.ts --env production",
"dev": "webpack -w -c ./.config/webpack/webpack.config.ts --env development",
"e2e": "yarn exec cypress install && yarn exec grafana-e2e run",
"e2e:update": "yarn exec cypress install && yarn exec grafana-e2e run --update-screenshots",
"lint": "eslint --cache --ignore-path ./.gitignore --ext .js,.jsx,.ts,.tsx .",
"lint:fix": "yarn run lint --fix",
"server": "docker-compose up --build",
"sign": "npx --yes @grafana/sign-plugin@latest",
"start": "yarn watch",
"test": "jest --watch --onlyChanged",
"test:ci": "jest --passWithNoTests --maxWorkers 4",
"typecheck": "tsc --noEmit"
},
"author": "Audacious Software Group",
"license": "MIT",
"devDependencies": {
"@grafana/toolkit": "latest",
"@babel/core": "^7.21.4",
"@grafana/e2e": "9.5.3",
"@grafana/e2e-selectors": "9.5.3",
"@grafana/eslint-config": "^6.0.0",
"@grafana/tsconfig": "^1.2.0-rc1",
"@swc/core": "^1.3.62",
"@swc/helpers": "^0.5.0",
"@swc/jest": "^0.2.26",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^12.1.4",
"@types/jest": "^29.5.0",
"@types/lodash": "^4.14.194",
"@types/node": "^18.15.11",
"copy-webpack-plugin": "^11.0.0",
"css-loader": "^6.7.3",
"emotion": "10.0.27",
"eslint-webpack-plugin": "^4.0.1",
"fork-ts-checker-webpack-plugin": "^8.0.0",
"glob": "^10.2.7",
"identity-obj-proxy": "3.0.0",
"jest": "^29.5.0",
"jest-environment-jsdom": "^29.5.0",
"prettier": "^2.8.7",
"react-monaco-editor": "^0.44.0",
"tslib": "^2.3.1"
"replace-in-file-webpack-plugin": "^1.0.6",
"sass": "1.63.2",
"sass-loader": "13.3.1",
"style-loader": "3.3.3",
"swc-loader": "^0.2.3",
"ts-node": "^10.9.1",
"tsconfig-paths": "^4.2.0",
"tslib": "^2.3.1",
"typescript": "4.8.4",
"webpack": "^5.86.0",
"webpack-cli": "^5.1.4",
"webpack-livereload-plugin": "^3.0.2"
},
"engines": {
"node": ">=14"
},
"dependencies": {
"@grafana/runtime": "9.1.2",
"@emotion/css": "^11.1.3",
"@grafana/data": "9.1.2",
"@grafana/runtime": "9.1.2",
"@grafana/ui": "9.1.2",
"@svgdotjs/svg.js": "^3.1.1"
"@svgdotjs/svg.js": "^3.1.1",
"react": "17.0.2",
"react-dom": "17.0.2",
"tslib": "2.5.3"
},
"_comments": "Dependencies are not included as part of Omniperf. It's the user's responsibility to accept any licensing implications before building the project."
"_comments": "Dependencies are not included as part of Omniperf. It's the user's responsibility to accept any licensing implications before building the project.",
"packageManager": "yarn@1.22.19"
}
@@ -1,11 +1,3 @@
{
"extends": "./node_modules/@grafana/toolkit/src/config/tsconfig.plugin.json",
"include": ["src", "types"],
"compilerOptions": {
"types": ["@emotion/core"],
"rootDir": "./src",
"baseUrl": "./src",
"typeRoots": ["./node_modules/@types"],
"jsx": "react"
}
}
"extends": "./.config/tsconfig.json"
}
@@ -510,23 +510,7 @@ def characterize_app(args, VER):
else:
run_prof(fname, workload_dir, perfmon_dir, app_cmd, args.target, log, args.verbose)
# run again with timestamps
success, output = capture_subprocess_output(
[
rocprof_cmd,
# "-i", fname,
# "-m", perfmon_dir + "/" + "metrics.xml",
"--timestamp",
"on",
"-o",
workload_dir + "/" + "timestamps.csv",
'"' + app_cmd + '"',
]
)
log.write(output)
# Update pmc_perf.csv timestamps
# Update timestamps
replace_timestamps(workload_dir, log)
# Manually join each pmc_perf*.csv output
@@ -747,21 +731,7 @@ def omniperf_profile(args, VER):
else:
run_prof(fname, workload_dir, perfmon_dir, args.remaining, args.target, log, args.verbose)
# run again with timestamps
success, output = capture_subprocess_output(
[
rocprof_cmd,
# "-i", fname,
# "-m", perfmon_dir + "/" + "metrics.xml",
"--timestamp",
"on",
"-o",
workload_dir + "/" + "timestamps.csv",
'"' + args.remaining + '"',
]
)
log.write(output)
# Update pmc_perf.csv timestamps
# Update timestamps
replace_timestamps(workload_dir, log)
# Manually join each pmc_perf*.csv output
@@ -11,6 +11,7 @@ Panel Config:
data source:
- metric_table:
id: 201
title: Speed-of-Light
header:
metric: Metric
value: Value
@@ -16,6 +16,9 @@ Panel Config:
count: Count
unit: Unit
tips: Tips
style:
type: simple_bar
label_txt: (# of instr + $normUnit)
metric:
VALU - Vector:
count: None # No HW module
@@ -27,7 +30,7 @@ Panel Config:
tips:
LDS:
count: AVG((SQ_INSTS_LDS / $denom))
unit: $normUnit
unit: (instr + $normUnit)
tips:
VALU - MFMA:
count: None # No HW module
@@ -58,10 +61,13 @@ Panel Config:
count: Count
unit: Unit
tips: Tips
style:
type: simple_bar
label_txt: (# of instr + $normUnit)
metric:
INT-32:
count: None # No perf counter
unit: $normUnit
unit: (instr + $normUnit)
tips:
INT-64:
count: None # No perf counter
@@ -15,6 +15,11 @@ Panel Config:
metric: Metric
value: Value
tips: Tips
style:
type: simple_bar
range_color: [1, 100]
label_txt: (%)
xrange: [0, 110]
metric:
valu_flops_pop:
value: None # No perf counter
@@ -15,6 +15,11 @@ Panel Config:
metric: Metric
value: Value
tips: Tips
style:
type: simple_bar
range_color: [1, 100]
label_txt: (%)
xrange: [0, 110]
metric:
Utilization:
value: AVG(((100 * SQ_LDS_IDX_ACTIVE) / (GRBM_GUI_ACTIVE * $numCU)))
@@ -15,6 +15,11 @@ Panel Config:
metric: Metric
value: Value
tips: Tips
style:
type: simple_bar
range_color: [1, 100]
label_txt: (%)
xrange: [0, 110]
metric:
Bandwidth:
value: AVG(((SQC_ICACHE_REQ * 100000) / (($sclk * $numSQC)
@@ -15,6 +15,11 @@ Panel Config:
mertic: Metric
value: Value
tips: Tips
style:
type: simple_bar
range_color: [1, 100]
label_txt: (%)
xrange: [0, 110]
metric:
Bandwidth:
value: AVG(((SQC_DCACHE_REQ * 100000) / (($sclk * $numSQC)
@@ -15,6 +15,11 @@ Panel Config:
metric: Metric
value: Value
tips: Tips
style:
type: simple_bar
range_color: [1, 100]
label_txt: (%)
xrange: [0, 110]
metric:
Buffer Coalescing:
value: AVG(((((TA_TOTAL_WAVEFRONTS_sum * 64) * 100) / (TCP_TOTAL_ACCESSES_sum
@@ -248,6 +253,8 @@ Panel Config:
max: Max
unit: Unit
tips: Tips
style:
type: simple_multi_bar
metric:
NC - Read:
xfer: Read
@@ -361,7 +368,7 @@ Panel Config:
mean: AVG((TCP_UTCL1_REQUEST_sum / $denom))
min: MIN((TCP_UTCL1_REQUEST_sum / $denom))
max: MAX((TCP_UTCL1_REQUEST_sum / $denom))
units: ( + $normUnit)
units: (Req + $normUnit)
tips:
Hit Ratio:
mean: AVG((((100 * TCP_UTCL1_TRANSLATION_HIT_sum) / TCP_UTCL1_REQUEST_sum) if
@@ -376,17 +383,17 @@ Panel Config:
mean: AVG((TCP_UTCL1_TRANSLATION_HIT_sum / $denom))
min: MIN((TCP_UTCL1_TRANSLATION_HIT_sum / $denom))
max: MAX((TCP_UTCL1_TRANSLATION_HIT_sum / $denom))
units: ( + $normUnit)
units: (Hits + $normUnit)
tips:
Misses (Translation):
mean: AVG((TCP_UTCL1_TRANSLATION_MISS_sum / $denom))
min: MIN((TCP_UTCL1_TRANSLATION_MISS_sum / $denom))
max: MAX((TCP_UTCL1_TRANSLATION_MISS_sum / $denom))
units: ( + $normUnit)
units: (Misses + $normUnit)
tips:
Misses (Permission):
mean: AVG((TCP_UTCL1_PERMISSION_MISS_sum / $denom))
min: MIN((TCP_UTCL1_PERMISSION_MISS_sum / $denom))
max: MAX((TCP_UTCL1_PERMISSION_MISS_sum / $denom))
units: ( + $normUnit)
units: (Misses + $normUnit)
tips:
@@ -16,6 +16,8 @@ Panel Config:
value: Value
unit: Unit
tips: Tips
style:
type: simple_bar
metric:
L2 Util:
value: AVG(((TCC_BUSY_sum * 100) / (TO_INT($L2Banks) * GRBM_GUI_ACTIVE)))
@@ -301,6 +303,8 @@ Panel Config:
max: Max
unit: Unit
tips: Tips
style:
type: simple_multi_bar
metric:
Read - Remote Socket Stall:
type: Remote Socket Stall
@@ -204,7 +204,7 @@ Panel Config:
+ TO_INT(TCC_REQ[22])) + TO_INT(TCC_REQ[23])) + TO_INT(TCC_REQ[24])) + TO_INT(TCC_REQ[25]))
+ TO_INT(TCC_REQ[26])) + TO_INT(TCC_REQ[27])) + TO_INT(TCC_REQ[28])) + TO_INT(TCC_REQ[29]))
+ TO_INT(TCC_REQ[30])) + TO_INT(TCC_REQ[31])) / 32) / $denom))
units: ( + $normUnit)
units: (Req + $normUnit)
tips:
L1 - L2 Read Req:
mean: AVG((((((((((((((((((((((((((((((((((TO_INT(TCC_READ[0]) + TO_INT(TCC_READ[1]))
@@ -247,7 +247,7 @@ Panel Config:
+ TO_INT(TCC_READ[24])) + TO_INT(TCC_READ[25])) + TO_INT(TCC_READ[26])) +
TO_INT(TCC_READ[27])) + TO_INT(TCC_READ[28])) + TO_INT(TCC_READ[29])) + TO_INT(TCC_READ[30]))
+ TO_INT(TCC_READ[31])) / 32) / $denom))
units: ( + $normUnit)
units: (Req + $normUnit)
tips:
L1 - L2 Write Req:
mean: AVG((((((((((((((((((((((((((((((((((TO_INT(TCC_WRITE[0]) + TO_INT(TCC_WRITE[1]))
@@ -294,7 +294,7 @@ Panel Config:
+ TO_INT(TCC_WRITE[24])) + TO_INT(TCC_WRITE[25])) + TO_INT(TCC_WRITE[26]))
+ TO_INT(TCC_WRITE[27])) + TO_INT(TCC_WRITE[28])) + TO_INT(TCC_WRITE[29]))
+ TO_INT(TCC_WRITE[30])) + TO_INT(TCC_WRITE[31])) / 32) / $denom))
units: ( + $normUnit)
units: (Req + $normUnit)
tips:
L1 - L2 Atomic Req:
mean: AVG((((((((((((((((((((((((((((((((((TO_INT(TCC_ATOMIC[0]) + TO_INT(TCC_ATOMIC[1]))
@@ -345,7 +345,7 @@ Panel Config:
+ TO_INT(TCC_ATOMIC[26])) + TO_INT(TCC_ATOMIC[27])) + TO_INT(TCC_ATOMIC[28]))
+ TO_INT(TCC_ATOMIC[29])) + TO_INT(TCC_ATOMIC[30])) + TO_INT(TCC_ATOMIC[31]))
/ 32) / $denom))
units: ( + $normUnit)
units: (Req + $normUnit)
tips:
L2 - EA Read Req:
mean: AVG((((((((((((((((((((((((((((((((((TO_INT(TCC_EA_RDREQ[0]) + TO_INT(TCC_EA_RDREQ[1]))
@@ -396,7 +396,7 @@ Panel Config:
+ TO_INT(TCC_EA_RDREQ[26])) + TO_INT(TCC_EA_RDREQ[27])) + TO_INT(TCC_EA_RDREQ[28]))
+ TO_INT(TCC_EA_RDREQ[29])) + TO_INT(TCC_EA_RDREQ[30])) + TO_INT(TCC_EA_RDREQ[31]))
/ 32) / $denom))
units: ( + $normUnit)
units: (Req + $normUnit)
tips:
L2 - EA Write Req:
mean: AVG((((((((((((((((((((((((((((((((((TO_INT(TCC_EA_WRREQ[0]) + TO_INT(TCC_EA_WRREQ[1]))
@@ -447,7 +447,7 @@ Panel Config:
+ TO_INT(TCC_EA_WRREQ[26])) + TO_INT(TCC_EA_WRREQ[27])) + TO_INT(TCC_EA_WRREQ[28]))
+ TO_INT(TCC_EA_WRREQ[29])) + TO_INT(TCC_EA_WRREQ[30])) + TO_INT(TCC_EA_WRREQ[31]))
/ 32) / $denom))
units: ( + $normUnit)
units: (Req + $normUnit)
tips:
L2 - EA Atomic Req:
mean: AVG((((((((((((((((((((((((((((((((((TO_INT(TCC_EA_ATOMIC[0]) + TO_INT(TCC_EA_ATOMIC[1]))
@@ -498,7 +498,7 @@ Panel Config:
+ TO_INT(TCC_EA_ATOMIC[26])) + TO_INT(TCC_EA_ATOMIC[27])) + TO_INT(TCC_EA_ATOMIC[28]))
+ TO_INT(TCC_EA_ATOMIC[29])) + TO_INT(TCC_EA_ATOMIC[30])) + TO_INT(TCC_EA_ATOMIC[31]))
/ 32) / $denom))
units: ( + $normUnit)
units: (Req + $normUnit)
tips:
L2 - EA Read Lat:
mean: AVG((((((((((((((((((((((((((((((((((TCC_EA_RDREQ_LEVEL[0] + TCC_EA_RDREQ_LEVEL[1])
@@ -11,6 +11,7 @@ Panel Config:
data source:
- metric_table:
id: 201
title: Speed-of-Light
header:
metric: Metric
value: Value
@@ -16,6 +16,9 @@ Panel Config:
count: Count
unit: Unit
tips: Tips
style:
type: simple_bar
label_txt: (# of instr + $normUnit)
metric:
VALU - Vector:
count: AVG(((SQ_INSTS_VALU - SQ_INSTS_MFMA) / $denom))
@@ -58,6 +61,9 @@ Panel Config:
count: Count
unit: Unit
tips: Tips
style:
type: simple_bar
label_txt: (# of instr + $normUnit)
metric:
INT-32:
count: None # No perf counter
@@ -15,6 +15,11 @@ Panel Config:
metric: Metric
value: Value
tips: Tips
style:
type: simple_bar
range_color: [1, 100]
label_txt: (%)
xrange: [0, 110]
metric:
valu_flops_pop:
value: None # No perf counter
@@ -15,6 +15,11 @@ Panel Config:
metric: Metric
value: Value
tips: Tips
style:
type: simple_bar
range_color: [1, 100]
label_txt: (%)
xrange: [0, 110]
metric:
Utilization:
value: AVG(((100 * SQ_LDS_IDX_ACTIVE) / (GRBM_GUI_ACTIVE * $numCU)))
@@ -15,6 +15,11 @@ Panel Config:
metric: Metric
value: Value
tips: Tips
style:
type: simple_bar
range_color: [1, 100]
label_txt: (%)
xrange: [0, 110]
metric:
Bandwidth:
value: AVG(((SQC_ICACHE_REQ * 100000) / (($sclk * $numSQC)
@@ -15,6 +15,11 @@ Panel Config:
mertic: Metric
value: Value
tips: Tips
style:
type: simple_bar
range_color: [1, 100]
label_txt: (%)
xrange: [0, 110]
metric:
Bandwidth:
value: AVG(((SQC_DCACHE_REQ * 100000) / (($sclk * $numSQC)
@@ -15,6 +15,11 @@ Panel Config:
metric: Metric
value: Value
tips: Tips
style:
type: simple_bar
range_color: [1, 100]
label_txt: (%)
xrange: [0, 110]
metric:
Buffer Coalescing:
value: AVG(((((TA_TOTAL_WAVEFRONTS_sum * 64) * 100) / (TCP_TOTAL_ACCESSES_sum
@@ -248,6 +253,8 @@ Panel Config:
max: Max
unit: Unit
tips: Tips
style:
type: simple_multi_bar
metric:
NC - Read:
xfer: Read
@@ -361,7 +368,7 @@ Panel Config:
mean: AVG((TCP_UTCL1_REQUEST_sum / $denom))
min: MIN((TCP_UTCL1_REQUEST_sum / $denom))
max: MAX((TCP_UTCL1_REQUEST_sum / $denom))
units: ( + $normUnit)
units: (Req + $normUnit)
tips:
Hit Ratio:
mean: AVG((((100 * TCP_UTCL1_TRANSLATION_HIT_sum) / TCP_UTCL1_REQUEST_sum) if
@@ -376,17 +383,17 @@ Panel Config:
mean: AVG((TCP_UTCL1_TRANSLATION_HIT_sum / $denom))
min: MIN((TCP_UTCL1_TRANSLATION_HIT_sum / $denom))
max: MAX((TCP_UTCL1_TRANSLATION_HIT_sum / $denom))
units: ( + $normUnit)
units: (Hits + $normUnit)
tips:
Misses (Translation):
mean: AVG((TCP_UTCL1_TRANSLATION_MISS_sum / $denom))
min: MIN((TCP_UTCL1_TRANSLATION_MISS_sum / $denom))
max: MAX((TCP_UTCL1_TRANSLATION_MISS_sum / $denom))
units: ( + $normUnit)
units: (Misses + $normUnit)
tips:
Misses (Permission):
mean: AVG((TCP_UTCL1_PERMISSION_MISS_sum / $denom))
min: MIN((TCP_UTCL1_PERMISSION_MISS_sum / $denom))
max: MAX((TCP_UTCL1_PERMISSION_MISS_sum / $denom))
units: ( + $normUnit)
units: (Misses + $normUnit)
tips:
@@ -16,6 +16,8 @@ Panel Config:
value: Value
unit: Unit
tips: Tips
style:
type: simple_bar
metric:
L2 Util:
value: AVG(((TCC_BUSY_sum * 100) / (TO_INT($L2Banks) * GRBM_GUI_ACTIVE)))
@@ -301,6 +303,8 @@ Panel Config:
max: Max
unit: Unit
tips: Tips
style:
type: simple_multi_bar
metric:
Read - Remote Socket Stall:
type: Remote Socket Stall
@@ -204,7 +204,7 @@ Panel Config:
+ TO_INT(TCC_REQ[22])) + TO_INT(TCC_REQ[23])) + TO_INT(TCC_REQ[24])) + TO_INT(TCC_REQ[25]))
+ TO_INT(TCC_REQ[26])) + TO_INT(TCC_REQ[27])) + TO_INT(TCC_REQ[28])) + TO_INT(TCC_REQ[29]))
+ TO_INT(TCC_REQ[30])) + TO_INT(TCC_REQ[31])) / 32) / $denom))
units: ( + $normUnit)
units: (Req + $normUnit)
tips:
L1 - L2 Read Req:
mean: AVG((((((((((((((((((((((((((((((((((TO_INT(TCC_READ[0]) + TO_INT(TCC_READ[1]))
@@ -247,7 +247,7 @@ Panel Config:
+ TO_INT(TCC_READ[24])) + TO_INT(TCC_READ[25])) + TO_INT(TCC_READ[26])) +
TO_INT(TCC_READ[27])) + TO_INT(TCC_READ[28])) + TO_INT(TCC_READ[29])) + TO_INT(TCC_READ[30]))
+ TO_INT(TCC_READ[31])) / 32) / $denom))
units: ( + $normUnit)
units: (Req + $normUnit)
tips:
L1 - L2 Write Req:
mean: AVG((((((((((((((((((((((((((((((((((TO_INT(TCC_WRITE[0]) + TO_INT(TCC_WRITE[1]))
@@ -294,7 +294,7 @@ Panel Config:
+ TO_INT(TCC_WRITE[24])) + TO_INT(TCC_WRITE[25])) + TO_INT(TCC_WRITE[26]))
+ TO_INT(TCC_WRITE[27])) + TO_INT(TCC_WRITE[28])) + TO_INT(TCC_WRITE[29]))
+ TO_INT(TCC_WRITE[30])) + TO_INT(TCC_WRITE[31])) / 32) / $denom))
units: ( + $normUnit)
units: (Req + $normUnit)
tips:
L1 - L2 Atomic Req:
mean: AVG((((((((((((((((((((((((((((((((((TO_INT(TCC_ATOMIC[0]) + TO_INT(TCC_ATOMIC[1]))
@@ -345,7 +345,7 @@ Panel Config:
+ TO_INT(TCC_ATOMIC[26])) + TO_INT(TCC_ATOMIC[27])) + TO_INT(TCC_ATOMIC[28]))
+ TO_INT(TCC_ATOMIC[29])) + TO_INT(TCC_ATOMIC[30])) + TO_INT(TCC_ATOMIC[31]))
/ 32) / $denom))
units: ( + $normUnit)
units: (Req + $normUnit)
tips:
L2 - EA Read Req:
mean: AVG((((((((((((((((((((((((((((((((((TO_INT(TCC_EA_RDREQ[0]) + TO_INT(TCC_EA_RDREQ[1]))
@@ -396,7 +396,7 @@ Panel Config:
+ TO_INT(TCC_EA_RDREQ[26])) + TO_INT(TCC_EA_RDREQ[27])) + TO_INT(TCC_EA_RDREQ[28]))
+ TO_INT(TCC_EA_RDREQ[29])) + TO_INT(TCC_EA_RDREQ[30])) + TO_INT(TCC_EA_RDREQ[31]))
/ 32) / $denom))
units: ( + $normUnit)
units: (Req + $normUnit)
tips:
L2 - EA Write Req:
mean: AVG((((((((((((((((((((((((((((((((((TO_INT(TCC_EA_WRREQ[0]) + TO_INT(TCC_EA_WRREQ[1]))
@@ -447,7 +447,7 @@ Panel Config:
+ TO_INT(TCC_EA_WRREQ[26])) + TO_INT(TCC_EA_WRREQ[27])) + TO_INT(TCC_EA_WRREQ[28]))
+ TO_INT(TCC_EA_WRREQ[29])) + TO_INT(TCC_EA_WRREQ[30])) + TO_INT(TCC_EA_WRREQ[31]))
/ 32) / $denom))
units: ( + $normUnit)
units: (Req + $normUnit)
tips:
L2 - EA Atomic Req:
mean: AVG((((((((((((((((((((((((((((((((((TO_INT(TCC_EA_ATOMIC[0]) + TO_INT(TCC_EA_ATOMIC[1]))
@@ -498,7 +498,7 @@ Panel Config:
+ TO_INT(TCC_EA_ATOMIC[26])) + TO_INT(TCC_EA_ATOMIC[27])) + TO_INT(TCC_EA_ATOMIC[28]))
+ TO_INT(TCC_EA_ATOMIC[29])) + TO_INT(TCC_EA_ATOMIC[30])) + TO_INT(TCC_EA_ATOMIC[31]))
/ 32) / $denom))
units: ( + $normUnit)
units: (Req + $normUnit)
tips:
L2 - EA Read Lat:
mean: AVG((((((((((((((((((((((((((((((((((TCC_EA_RDREQ_LEVEL[0] + TCC_EA_RDREQ_LEVEL[1])
@@ -11,6 +11,7 @@ Panel Config:
data source:
- metric_table:
id: 201
title: Speed-of-Light
header:
metric: Metric
value: Value
@@ -44,9 +45,9 @@ Panel Config:
MFMA FLOPs (BF16):
value: AVG(((SQ_INSTS_VALU_MFMA_MOPS_BF16 * 512) / (EndNs - BeginNs)))
unit: GFLOP
peak: ((($sclk * $numCU) * 512) / 1000)
peak: ((($sclk * $numCU) * 1024) / 1000)
pop: ((100 * AVG(((SQ_INSTS_VALU_MFMA_MOPS_BF16 * 512) / (EndNs - BeginNs))))
/ ((($sclk * $numCU) * 512) / 1000))
/ ((($sclk * $numCU) * 1024) / 1000))
tips:
MFMA FLOPs (F16):
value: AVG(((SQ_INSTS_VALU_MFMA_MOPS_F16 * 512) / (EndNs - BeginNs)))
@@ -16,6 +16,9 @@ Panel Config:
count: Count
unit: Unit
tips: Tips
style:
type: simple_bar
label_txt: (# of instr + $normUnit)
metric:
VALU - Vector:
count: AVG(((SQ_INSTS_VALU - SQ_INSTS_MFMA) / $denom))
@@ -58,6 +61,9 @@ Panel Config:
count: Count
unit: Unit
tips: Tips
style:
type: simple_bar
label_txt: (# of instr + $normUnit)
metric:
INT32:
count: AVG((SQ_INSTS_VALU_INT32 / $denom))
@@ -15,6 +15,11 @@ Panel Config:
metric: Metric
value: Value
tips: Tips
style:
type: simple_bar
range_color: [1, 100]
label_txt: (%)
xrange: [0, 110]
metric:
valu_flops_pop:
value: ((100 * AVG(((((64 * (((SQ_INSTS_VALU_ADD_F16 + SQ_INSTS_VALU_MUL_F16)
@@ -15,6 +15,11 @@ Panel Config:
metric: Metric
value: Value
tips: Tips
style:
type: simple_bar
range_color: [1, 100]
label_txt: (%)
xrange: [0, 110]
metric:
Utilization:
value: AVG(((100 * SQ_LDS_IDX_ACTIVE) / (GRBM_GUI_ACTIVE * $numCU)))
@@ -15,6 +15,11 @@ Panel Config:
metric: Metric
value: Value
tips: Tips
style:
type: simple_bar
range_color: [1, 100]
label_txt: (%)
xrange: [0, 110]
metric:
Bandwidth:
value: AVG(((SQC_ICACHE_REQ * 100000) / (($sclk * $numSQC)
@@ -15,6 +15,11 @@ Panel Config:
mertic: Metric
value: Value
tips: Tips
style:
type: simple_bar
range_color: [1, 100]
label_txt: (%)
xrange: [0, 110]
metric:
Bandwidth:
value: AVG(((SQC_DCACHE_REQ * 100000) / (($sclk * $numSQC)
@@ -15,6 +15,11 @@ Panel Config:
metric: Metric
value: Value
tips: Tips
style:
type: simple_bar
range_color: [1, 100]
label_txt: (%)
xrange: [0, 110]
metric:
Buffer Coalescing:
value: AVG(((((TA_TOTAL_WAVEFRONTS_sum * 64) * 100) / (TCP_TOTAL_ACCESSES_sum
@@ -248,6 +253,8 @@ Panel Config:
max: Max
unit: Unit
tips: Tips
style:
type: simple_multi_bar
metric:
NC - Read:
xfer: Read
@@ -361,7 +368,7 @@ Panel Config:
mean: AVG((TCP_UTCL1_REQUEST_sum / $denom))
min: MIN((TCP_UTCL1_REQUEST_sum / $denom))
max: MAX((TCP_UTCL1_REQUEST_sum / $denom))
units: ( + $normUnit)
units: (Req + $normUnit)
tips:
Hit Ratio:
mean: AVG((((100 * TCP_UTCL1_TRANSLATION_HIT_sum) / TCP_UTCL1_REQUEST_sum) if
@@ -376,17 +383,17 @@ Panel Config:
mean: AVG((TCP_UTCL1_TRANSLATION_HIT_sum / $denom))
min: MIN((TCP_UTCL1_TRANSLATION_HIT_sum / $denom))
max: MAX((TCP_UTCL1_TRANSLATION_HIT_sum / $denom))
units: ( + $normUnit)
units: (Hits + $normUnit)
tips:
Misses (Translation):
mean: AVG((TCP_UTCL1_TRANSLATION_MISS_sum / $denom))
min: MIN((TCP_UTCL1_TRANSLATION_MISS_sum / $denom))
max: MAX((TCP_UTCL1_TRANSLATION_MISS_sum / $denom))
units: ( + $normUnit)
units: (Misses + $normUnit)
tips:
Misses (Permission):
mean: AVG((TCP_UTCL1_PERMISSION_MISS_sum / $denom))
min: MIN((TCP_UTCL1_PERMISSION_MISS_sum / $denom))
max: MAX((TCP_UTCL1_PERMISSION_MISS_sum / $denom))
units: ( + $normUnit)
units: (Misses + $normUnit)
tips:
@@ -16,6 +16,8 @@ Panel Config:
value: Value
unit: Unit
tips: Tips
style:
type: simple_bar
metric:
L2 Util:
value: AVG(((TCC_BUSY_sum * 100) / (TO_INT($L2Banks) * GRBM_GUI_ACTIVE)))
@@ -301,6 +303,8 @@ Panel Config:
max: Max
unit: Unit
tips: Tips
style:
type: simple_multi_bar
metric:
Read - Remote Socket Stall:
type: Remote Socket Stall
@@ -204,7 +204,7 @@ Panel Config:
+ TO_INT(TCC_REQ[22])) + TO_INT(TCC_REQ[23])) + TO_INT(TCC_REQ[24])) + TO_INT(TCC_REQ[25]))
+ TO_INT(TCC_REQ[26])) + TO_INT(TCC_REQ[27])) + TO_INT(TCC_REQ[28])) + TO_INT(TCC_REQ[29]))
+ TO_INT(TCC_REQ[30])) + TO_INT(TCC_REQ[31])) / 32) / $denom))
units: ( + $normUnit)
units: (Req + $normUnit)
tips:
L1 - L2 Read Req:
mean: AVG((((((((((((((((((((((((((((((((((TO_INT(TCC_READ[0]) + TO_INT(TCC_READ[1]))
@@ -247,7 +247,7 @@ Panel Config:
+ TO_INT(TCC_READ[24])) + TO_INT(TCC_READ[25])) + TO_INT(TCC_READ[26])) +
TO_INT(TCC_READ[27])) + TO_INT(TCC_READ[28])) + TO_INT(TCC_READ[29])) + TO_INT(TCC_READ[30]))
+ TO_INT(TCC_READ[31])) / 32) / $denom))
units: ( + $normUnit)
units: (Req + $normUnit)
tips:
L1 - L2 Write Req:
mean: AVG((((((((((((((((((((((((((((((((((TO_INT(TCC_WRITE[0]) + TO_INT(TCC_WRITE[1]))
@@ -294,7 +294,7 @@ Panel Config:
+ TO_INT(TCC_WRITE[24])) + TO_INT(TCC_WRITE[25])) + TO_INT(TCC_WRITE[26]))
+ TO_INT(TCC_WRITE[27])) + TO_INT(TCC_WRITE[28])) + TO_INT(TCC_WRITE[29]))
+ TO_INT(TCC_WRITE[30])) + TO_INT(TCC_WRITE[31])) / 32) / $denom))
units: ( + $normUnit)
units: (Req + $normUnit)
tips:
L1 - L2 Atomic Req:
mean: AVG((((((((((((((((((((((((((((((((((TO_INT(TCC_ATOMIC[0]) + TO_INT(TCC_ATOMIC[1]))
@@ -345,7 +345,7 @@ Panel Config:
+ TO_INT(TCC_ATOMIC[26])) + TO_INT(TCC_ATOMIC[27])) + TO_INT(TCC_ATOMIC[28]))
+ TO_INT(TCC_ATOMIC[29])) + TO_INT(TCC_ATOMIC[30])) + TO_INT(TCC_ATOMIC[31]))
/ 32) / $denom))
units: ( + $normUnit)
units: (Req + $normUnit)
tips:
L2 - EA Read Req:
mean: AVG((((((((((((((((((((((((((((((((((TO_INT(TCC_EA_RDREQ[0]) + TO_INT(TCC_EA_RDREQ[1]))
@@ -396,7 +396,7 @@ Panel Config:
+ TO_INT(TCC_EA_RDREQ[26])) + TO_INT(TCC_EA_RDREQ[27])) + TO_INT(TCC_EA_RDREQ[28]))
+ TO_INT(TCC_EA_RDREQ[29])) + TO_INT(TCC_EA_RDREQ[30])) + TO_INT(TCC_EA_RDREQ[31]))
/ 32) / $denom))
units: ( + $normUnit)
units: (Req + $normUnit)
tips:
L2 - EA Write Req:
mean: AVG((((((((((((((((((((((((((((((((((TO_INT(TCC_EA_WRREQ[0]) + TO_INT(TCC_EA_WRREQ[1]))
@@ -447,7 +447,7 @@ Panel Config:
+ TO_INT(TCC_EA_WRREQ[26])) + TO_INT(TCC_EA_WRREQ[27])) + TO_INT(TCC_EA_WRREQ[28]))
+ TO_INT(TCC_EA_WRREQ[29])) + TO_INT(TCC_EA_WRREQ[30])) + TO_INT(TCC_EA_WRREQ[31]))
/ 32) / $denom))
units: ( + $normUnit)
units: (Req + $normUnit)
tips:
L2 - EA Atomic Req:
mean: AVG((((((((((((((((((((((((((((((((((TO_INT(TCC_EA_ATOMIC[0]) + TO_INT(TCC_EA_ATOMIC[1]))
@@ -498,7 +498,7 @@ Panel Config:
+ TO_INT(TCC_EA_ATOMIC[26])) + TO_INT(TCC_EA_ATOMIC[27])) + TO_INT(TCC_EA_ATOMIC[28]))
+ TO_INT(TCC_EA_ATOMIC[29])) + TO_INT(TCC_EA_ATOMIC[30])) + TO_INT(TCC_EA_ATOMIC[31]))
/ 32) / $denom))
units: ( + $normUnit)
units: (Req + $normUnit)
tips:
L2 - EA Read Lat:
mean: AVG((((((((((((((((((((((((((((((((((TCC_EA_RDREQ_LEVEL[0] + TCC_EA_RDREQ_LEVEL[1])
@@ -46,38 +46,45 @@ from pathlib import Path
from omniperf_analyze.utils import parser, file_io
from omniperf_analyze.utils.gui_components.roofline import get_roofline
archConfigs = {}
def initialize_run(args, normalization_filter=None):
import pandas as pd
from collections import OrderedDict
################################################
# Helper Functions
################################################
def generate_config(arch, config_dir, list_kernels, filter_metrics):
from omniperf_analyze.utils import schema
single_panel_config = file_io.is_single_panel_config(Path(config_dir))
global archConfigs
ac = schema.ArchConfig()
if list_kernels:
ac.panel_configs = file_io.top_stats_build_in_config
else:
arch_panel_config = (
config_dir if single_panel_config else config_dir.joinpath(arch)
)
ac.panel_configs = file_io.load_panel_configs(arch_panel_config)
# TODO: filter_metrics should/might be one per arch
# print(ac)
parser.build_dfs(ac, filter_metrics)
archConfigs[arch] = ac
return archConfigs # Note: This return comes in handy for rocScope which borrows generate_configs() in its rocomni plugin
def list_metrics(args):
import pandas as pd
from tabulate import tabulate
# Fixme: cur_root.parent.joinpath('soc_params')
soc_params_dir = os.path.join(os.path.dirname(__file__), "..", "soc_params")
soc_spec_df = file_io.load_soc_params(soc_params_dir)
single_panel_config = file_io.is_single_panel_config(Path(args.config_dir))
global archConfigs
archConfigs = {}
for arch in file_io.supported_arch.keys():
ac = schema.ArchConfig()
if args.list_kernels:
ac.panel_configs = file_io.top_stats_build_in_config
else:
arch_panel_config = (
args.config_dir if single_panel_config else args.config_dir.joinpath(arch)
)
ac.panel_configs = file_io.load_panel_configs(arch_panel_config)
# TODO: filter_metrics should/might be one per arch
# print(ac)
parser.build_dfs(ac, args.filter_metrics)
archConfigs[arch] = ac
if args.list_metrics in file_io.supported_arch.keys():
arch = args.list_metrics
if arch not in archConfigs.keys():
generate_config(arch, args.config_dir, args.list_kernels, args.filter_metrics)
print(
tabulate(
pd.DataFrame.from_dict(
@@ -91,7 +98,12 @@ def initialize_run(args, normalization_filter=None):
file=output,
)
sys.exit(0)
else:
print("Error: Unsupported arch")
sys.exit(-1)
def load_options(args, normalization_filter):
# Use original normalization or user input from GUI
if not normalization_filter:
for k, v in archConfigs.items():
@@ -100,10 +112,7 @@ def initialize_run(args, normalization_filter=None):
for k, v in archConfigs.items():
parser.build_metric_value_string(v.dfs, v.dfs_type, normalization_filter)
runs = OrderedDict()
# err checking for multiple runs and multiple gpu_kernel filter
# TODO: move it to util
if args.gpu_kernel and (len(args.path) != len(args.gpu_kernel)):
if len(args.gpu_kernel) == 1:
for i in range(len(args.path) - 1):
@@ -115,6 +124,31 @@ def initialize_run(args, normalization_filter=None):
)
sys.exit(-1)
################################################
# Core Functions
################################################
def initialize_run(args, normalization_filter=None):
from collections import OrderedDict
from omniperf_analyze.utils import schema
# Fixme: cur_root.parent.joinpath('soc_params')
soc_params_dir = os.path.join(os.path.dirname(__file__), "..", "soc_params")
soc_spec_df = file_io.load_soc_params(soc_params_dir)
if args.list_metrics:
list_metrics(args)
# Load required configs
for d in args.path:
sys_info = file_io.load_sys_info(Path(d[0], "sysinfo.csv"))
arch = sys_info.iloc[0]["gpu_soc"]
generate_config(arch, args.config_dir, args.list_kernels, args.filter_metrics)
load_options(args, normalization_filter)
runs = OrderedDict()
# Todo: warning single -d with multiple dirs
for d in args.path:
w = schema.Workload()
@@ -201,10 +235,21 @@ def run_cli(args, runs):
parser.load_table_data(
runs[d[0]], d[0], is_gui, args.g, args.verbose
) # create the loaded table
# TODO: In show_* functions always assume newest architecture. This way newest configs/figures are loaded
if args.list_kernels:
tty.show_kernels(args, runs, archConfigs["gfx90a"], output)
tty.show_kernels(
args,
runs,
archConfigs[runs[args.path[0][0]].sys_info.iloc[0]["gpu_soc"]],
output,
)
else:
tty.show_all(args, runs, archConfigs["gfx90a"], output)
tty.show_all(
args,
runs,
archConfigs[runs[args.path[0][0]].sys_info.iloc[0]["gpu_soc"]],
output,
)
def roofline_only(path_to_dir, dev_id, sort_type, mem_level, kernel_names, verbose):
@@ -321,6 +321,71 @@ def update_normUnit_string(equation, unit):
).capitalize()
def gen_counter_list(formula):
function_filter = {
"MIN": None,
"MAX": None,
"AVG": None,
"ROUND": None,
"TO_INT": None,
"GB": None,
"STD": None,
"GFLOP": None,
"GOP": None,
"OP": None,
"CU": None,
"NC": None,
"UC": None,
"CC": None,
"RW": None,
"GIOP": None,
"GFLOPs": None,
"CONCAT": None,
"MOD": None,
}
built_in_counter = [
"lds",
"grd",
"wgr",
"arch_vgpr",
"accum_vgpr",
"sgpr",
"scr",
"BeginNs",
"EndNs",
]
visited = False
counters = []
if not isinstance(formula, str):
return visited, counters
try:
tree = ast.parse(
formula.replace("$normUnit", "SQ_WAVES")
.replace("$denom", "SQ_WAVES")
.replace(
"$numActiveCUs",
"TO_INT(MIN((((ROUND(AVG(((4 * SQ_BUSY_CU_CYCLES) / GRBM_GUI_ACTIVE)), \
0) / $maxWavesPerCU) * 8) + MIN(MOD(ROUND(AVG(((4 * SQ_BUSY_CU_CYCLES) \
/ GRBM_GUI_ACTIVE)), 0), $maxWavesPerCU), 8)), $numCU))",
)
.replace("$", "")
)
for node in ast.walk(tree):
if isinstance(node, ast.Name):
val = str(node.id)[:-4] if str(node.id).endswith("_sum") else str(node.id)
if val.isupper() and val not in function_filter:
counters.append(val)
visited = True
if val in built_in_counter:
visited = True
except:
pass
return visited, counters
def build_dfs(archConfigs, filter_metrics):
"""
- Build dataframe for each type of data source within each panel.
@@ -338,10 +403,16 @@ def build_dfs(archConfigs, filter_metrics):
d = {}
metric_list = {}
dfs_type = {}
metric_counters = {}
for panel_id, panel in archConfigs.panel_configs.items():
panel_idx = str(panel_id // 100)
for data_source in panel["data source"]:
for type, data_cofig in data_source.items():
if type == "metric_table":
metric_list[panel_idx] = panel["title"]
table_idx = panel_idx + "." + str(data_cofig["id"] % 100)
metric_list[table_idx] = data_cofig["title"]
headers = ["Index"]
for key, tile in data_cofig["header"].items():
if key != "tips":
@@ -355,20 +426,16 @@ def build_dfs(archConfigs, filter_metrics):
i = 0
for key, entries in data_cofig["metric"].items():
data_source_idx = (
str(data_cofig["id"] // 100)
+ "."
+ str(data_cofig["id"] % 100)
)
metric_idx = data_source_idx + "." + str(i)
metric_idx = table_idx + "." + str(i)
values = []
eqn_content = []
if (
(not filter_metrics)
or (metric_idx in filter_metrics) # no filter
or # metric in filter
# the whole table in filter
(data_source_idx in filter_metrics)
(table_idx in filter_metrics)
or
# the whole IP block in filter
(str(panel_id // 100) in filter_metrics)
@@ -378,6 +445,7 @@ def build_dfs(archConfigs, filter_metrics):
for k, v in entries.items():
if k != "tips" and k != "coll_level" and k != "alias":
values.append(v)
eqn_content.append(v)
if "alias" in entries.keys():
values.append(entries["alias"])
@@ -395,7 +463,21 @@ def build_dfs(archConfigs, filter_metrics):
df = pd.concat([df, df_new_row])
# collect metric_list
metric_list[metric_idx] = key.replace(" ", "_")
metric_list[metric_idx] = key
# generate mapping of counters and metrics
filter = {}
_visited = False
for formula in eqn_content:
if formula is not None and formula != "None":
visited, counters = gen_counter_list(formula)
if visited:
_visited = True
for k in counters:
filter[k] = None
if len(filter) > 0 or _visited:
metric_counters[key] = list(filter)
i += 1
df.set_index("Index", inplace=True)
@@ -431,6 +513,7 @@ def build_dfs(archConfigs, filter_metrics):
setattr(archConfigs, "dfs", d)
setattr(archConfigs, "metric_list", metric_list)
setattr(archConfigs, "dfs_type", dfs_type)
setattr(archConfigs, "metric_counters", metric_counters)
def build_metric_value_string(dfs, dfs_type, normal_unit):
@@ -469,7 +552,12 @@ def eval_metric(dfs, dfs_type, sys_info, soc_spec, raw_pmc_df, debug):
# confirm no illogical counter values (only consider non-roofline runs)
roof_only_run = sys_info.ip_blocks == "roofline"
if not roof_only_run and (raw_pmc_df["pmc_perf"]["GRBM_GUI_ACTIVE"] == 0).any():
rocscope_run = sys_info.ip_blocks == "rocscope"
if (
not rocscope_run
and not roof_only_run
and (raw_pmc_df["pmc_perf"]["GRBM_GUI_ACTIVE"] == 0).any()
):
print("WARNING: Dectected GRBM_GUI_ACTIVE == 0\nHaulting execution.")
sys.exit(1)
@@ -711,12 +799,13 @@ def load_kernel_top(workload, dir):
workload.dfs.update(tmp)
def load_table_data(workload, dir, is_gui, debug, verbose):
def load_table_data(workload, dir, is_gui, debug, verbose, skipKernelTop=False):
"""
Load data for all "raw_csv_table".
Calculate mertric value for all "metric_table".
"""
load_kernel_top(workload, dir)
if not skipKernelTop:
load_kernel_top(workload, dir)
eval_metric(
workload.dfs,
@@ -52,6 +52,9 @@ class ArchConfig:
# [Index: Metric name] pairs
metric_list: Dict[str, str] = field(default_factory=dict)
# [Metric name: Counters] pairs
metric_counters: Dict[str, list] = field(default_factory=dict)
@dataclass
class Workload:
@@ -0,0 +1,119 @@
##############################################################################bl
# MIT License
#
# Copyright (c) 2021 - 2023 Advanced Micro Devices, Inc. All Rights Reserved.
#
# 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
import plotly.express as px
import pandas as pd
# Notes:
# This file includes implementation of a few simple but common charts in CLI.
# We try to auto-size the layout to cover most of the cases as default. If it
# doesn't work, apply style config in yaml for each dashboard.
def simple_bar(df, title: str = None, id=None, style: dict = None, orientation="h"):
"""
Plot data with simple bar chart
"""
# TODO: handle None properly
if "Metric" in df.columns and ("Count" in df.columns or "Value" in df.columns):
detected_label = "Count" if "Count" in df.columns else "Value"
df[detected_label] = [
x.astype(int) if x != "" else int(0) for x in df[detected_label]
]
else:
raise NameError("simple_bar: No Metric or Count in df columns!")
# Assign figure characteristics
range_color = style.get("range_color", None)
label_txt = style.get("label_txt", None)
xrange = style.get("xrange", None)
if label_txt is not None:
label_txt = label_txt.strip("()")
try:
label_txt = label_txt.replace("+ $normUnit", df["Unit"][0])
except KeyError:
print("No units found in df. Auto labeling.")
# Overrides for figure chatacteristics
if id == 1701.1:
label_txt = "%"
range_color = [0, 100]
xrange = [0, 110]
if id == 1701.2:
label_txt = "Gb/s"
range_color = [0, 1638]
xrange = [0, 1638]
fig = px.bar(
df,
title=title,
x=detected_label,
y="Metric",
color=detected_label,
range_color=range_color,
labels={detected_label: label_txt},
orientation=orientation,
).update_xaxes(range=xrange)
return fig
def simple_multi_bar(df, title=None, id=None):
"""
Plot data with simple multiple bar chart
"""
# TODO: handle Nan and None properly
if "Metric" in df.columns and "Avg" in df.columns:
df["Avg"] = [x.astype(int) if x != "" else int(0) for x in df["Avg"]]
else:
raise NameError("simple_multi_bar: No Metric or Count in df columns!")
dfigs = []
nested_bar = {}
df_unit = df["Unit"][0]
if id == 1604:
nested_bar = {"NC": {}, "UC": {}, "RW": {}, "CC": {}}
for index, row in df.iterrows():
nested_bar[row["Coherency"]][row["Xfer"]] = row["Avg"]
if id == 1704:
nested_bar = {"Read": {}, "Write": {}}
for index, row in df.iterrows():
nested_bar[row["Transaction"]][row["Type"]] = row["Avg"]
for group, metric in nested_bar.items():
dfigs.append(
px.bar(
title=group,
x=metric.values(),
y=metric.keys(),
labels={"x": df_unit, "y": ""},
text=metric.values(),
)
.update_xaxes(showgrid=False, rangemode="nonnegative")
.update_yaxes(showgrid=False)
)
return dfigs
@@ -95,13 +95,19 @@ def test_df_column_equality(df):
# joins disparate runs less dumbly than rocprof
def join_prof(workload_dir, join_type, log_file, verbose, out=None):
# Set default output directory if not specified
if out == None:
out = workload_dir + "/pmc_perf.csv"
files = glob.glob(workload_dir + "/" + "pmc_perf_*.csv")
df = None
if type(workload_dir) == str:
if out is None:
out = workload_dir + "/pmc_perf.csv"
files = glob.glob(workload_dir + "/" + "pmc_perf_*.csv")
elif type(workload_dir) == list:
files = workload_dir
else:
print("ERROR: Invalid workload_dir")
sys.exit(1)
df = None
for i, file in enumerate(files):
_df = pd.read_csv(file)
_df = pd.read_csv(file) if type(workload_dir) == str else file
if join_type == "kernel":
key = _df.groupby("KernelName").cumcount()
_df["key"] = _df.KernelName + " - " + key.astype(str)
@@ -127,10 +133,15 @@ def join_prof(workload_dir, join_type, log_file, verbose, out=None):
"wgr": [col for col in df.columns if "wgr" in col],
"lds": [col for col in df.columns if "lds" in col],
"scr": [col for col in df.columns if "scr" in col],
"arch_vgpr": [col for col in df.columns if "arch_vgpr" in col],
"accum_vgpr": [col for col in df.columns if "accum_vgpr" in col],
"spgr": [col for col in df.columns if "sgpr" in col],
}
# Check for vgpr counter in ROCm < 5.3
if "vgpr" in df.columns:
duplicate_cols["vgpr"] = [col for col in df.columns if "vgpr" in col]
# Check for vgpr counter in ROCm >= 5.3
else:
duplicate_cols["arch_vgpr"] = [col for col in df.columns if "arch_vgpr" in col]
duplicate_cols["accum_vgpr"] = [col for col in df.columns if "accum_vgpr" in col]
for key, cols in duplicate_cols.items():
_df = df[cols]
if not test_df_column_equality(_df):
@@ -140,10 +151,12 @@ def join_prof(workload_dir, join_type, log_file, verbose, out=None):
)
)
warnings.warn(msg)
log_file.write(msg + "\n")
if log_file:
log_file.write(msg + "\n")
else:
msg = "Successfully joined {} in pmc_perf.csv".format(key)
log_file.write(msg + "\n")
if log_file:
log_file.write(msg + "\n")
if test_df_column_equality(_df) and verbose:
print(msg)
@@ -173,6 +186,8 @@ def join_prof(workload_dir, join_type, log_file, verbose, out=None):
"fbar",
"sig",
"obj",
# rocscope specific merged counters, keep original
"dispatch_",
]
)
]
@@ -183,7 +198,15 @@ def join_prof(workload_dir, join_type, log_file, verbose, out=None):
[
k
for k in df.keys()
if not any(check in k for check in ["DispatchNs", "CompleteNs"])
if not any(
check in k
for check in [
"DispatchNs",
"CompleteNs",
# rocscope specific timestamp
"HostDuration",
]
)
]
]
#   C) sanity check the name and key
@@ -210,12 +233,14 @@ def join_prof(workload_dir, join_type, log_file, verbose, out=None):
df["EndNs"] = endNs
# finally, join the drop key
df = df.drop(columns=["key"])
# and save to file
df.to_csv(out, index=False)
# and delete old file(s)
if not verbose:
for file in files:
os.remove(file)
# save to file and delete old file(s), skip if we're being called outside of Omniperf
if type(workload_dir) == str:
df.to_csv(out, index=False)
if not verbose:
for file in files:
os.remove(file)
else:
return df
def pmc_perf_split(workload_dir):
@@ -250,7 +275,94 @@ def pmc_perf_split(workload_dir):
os.remove(workload_perfmon_dir + "/pmc_perf.txt")
def perfmon_coalesce(pmc_files_list, workload_dir, soc):
def update_pmc_bucket(
counters, save_file, soc, pmc_list=None, stext=None, workload_perfmon_dir=None
):
# Verify inputs.
# If save_file is True, we're being called internally, from perfmon_coalesce
# Else we're being called externally, from rocomni
detected_external_call = False
if save_file and (stext is None or workload_perfmon_dir is None):
raise ValueError(
"stext and workload_perfmon_dir must be specified if save_file is True"
)
if pmc_list is None:
detected_external_call = True
pmc_list = dict(
[
("SQ", []),
("GRBM", []),
("TCP", []),
("TA", []),
("TD", []),
("TCC", []),
("SPI", []),
("CPC", []),
("CPF", []),
("GDS", []),
("TCC2", {}), # per-channel TCC perfmon
]
)
for ch in range(perfmon_config[soc]["TCC_channels"]):
pmc_list["TCC2"][str(ch)] = []
if "SQ_ACCUM_PREV_HIRES" in counters and not detected_external_call:
# save all level counters separately
nindex = counters.index("SQ_ACCUM_PREV_HIRES")
level_counter = counters[nindex - 1]
if save_file:
# Save to level counter file, file name = level counter name
fd = open(workload_perfmon_dir + "/" + level_counter + ".txt", "w")
fd.write(stext + "\n\n")
fd.write("gpu:\n")
fd.write("range:\n")
fd.write("kernel:\n")
fd.close()
return pmc_list
# save normal pmc counters in matching buckets
for counter in counters:
IP_block = counter.split(sep="_")[0].upper()
# SQC and SQ belong to the IP block, coalesce them
if IP_block == "SQC":
IP_block = "SQ"
if IP_block != "TCC":
# Insert unique pmc counters into its bucket
if counter not in pmc_list[IP_block]:
pmc_list[IP_block].append(counter)
else:
# TCC counters processing
m = re.match(r"[\s\S]+\[(\d+)\]", counter)
if m is None:
# Aggregated TCC counters
if counter not in pmc_list[IP_block]:
pmc_list[IP_block].append(counter)
else:
# TCC channel ID
ch = m.group(1)
# fake IP block for per channel TCC
if str(ch) in pmc_list["TCC2"]:
# append unique counter into the channel
if counter not in pmc_list["TCC2"][str(ch)]:
pmc_list["TCC2"][str(ch)].append(counter)
else:
# initial counter in this channel
pmc_list["TCC2"][str(ch)] = [counter]
if detected_external_call:
# sort the per channel counter, so that same counter in all channels can be aligned
for ch in range(perfmon_config[soc]["TCC_channels"]):
pmc_list["TCC2"][str(ch)].sort()
return pmc_list
def perfmon_coalesce(pmc_files_list, soc, workload_dir):
workload_perfmon_dir = workload_dir + "/perfmon"
# match pattern for pmc counters
@@ -290,54 +402,20 @@ def perfmon_coalesce(pmc_files_list, workload_dir, soc):
# we have found all the counters, store them in buckets
counters = m.group(1).split()
if "SQ_ACCUM_PREV_HIRES" in counters:
# save all level counters separately
nindex = counters.index("SQ_ACCUM_PREV_HIRES")
level_counter = counters[nindex - 1]
# Utilitze helper function once a list of counters has be extracted
save_file = True
pmc_list = update_pmc_bucket(
counters, save_file, soc, pmc_list, stext, workload_perfmon_dir
)
# Save to level counter file, file name = level counter name
fd = open(workload_perfmon_dir + "/" + level_counter + ".txt", "w")
fd.write(stext + "\n\n")
fd.write("gpu:\n")
fd.write("range:\n")
fd.write("kernel:\n")
fd.close()
continue
# save normal pmc counters in matching buckets
for counter in counters:
IP_block = counter.split(sep="_")[0].upper()
# SQC and SQ belong to the IP block, coalesce them
if IP_block == "SQC":
IP_block = "SQ"
if IP_block != "TCC":
# Insert unique pmc counters into its bucket
if counter not in pmc_list[IP_block]:
pmc_list[IP_block].append(counter)
else:
# TCC counters processing
m = re.match(r"[\s\S]+\[(\d+)\]", counter)
if m is None:
# Aggregated TCC counters
if counter not in pmc_list[IP_block]:
pmc_list[IP_block].append(counter)
else:
# TCC channel ID
ch = m.group(1)
# fake IP block for per channel TCC
if str(ch) in pmc_list["TCC2"]:
# append unique counter into the channel
if counter not in pmc_list["TCC2"][str(ch)]:
pmc_list["TCC2"][str(ch)].append(counter)
else:
# initial counter in this channel
pmc_list["TCC2"][str(ch)] = [counter]
# add a timestamp file
fd = open(workload_perfmon_dir + "/timestamps.txt", "w")
fd.write("pmc:\n\n")
fd.write("gpu:\n")
fd.write("range:\n")
fd.write("kernel:\n")
fd.close()
# sort the per channel counter, so that same counter in all channels can be aligned
for ch in range(perfmon_config[soc]["TCC_channels"]):
@@ -346,9 +424,7 @@ def perfmon_coalesce(pmc_files_list, workload_dir, soc):
return pmc_list
def perfmon_emit(pmc_list, workload_dir, soc):
workload_perfmon_dir = workload_dir + "/perfmon"
def perfmon_emit(pmc_list, soc, workload_dir=None):
# Calculate the minimum number of iteration to save the pmc counters
# non-TCC counters
pmc_cnt = [
@@ -370,7 +446,11 @@ def perfmon_emit(pmc_list, workload_dir, soc):
niter = max(math.ceil(max(pmc_cnt)), math.ceil(tcc_cnt) + math.ceil(max(tcc2_cnt)))
# Emit PMC counters into pmc config file
fd = open(workload_perfmon_dir + "/pmc_perf.txt", "w")
if workload_dir:
workload_perfmon_dir = workload_dir + "/perfmon"
fd = open(workload_perfmon_dir + "/pmc_perf.txt", "w")
else:
batches = []
tcc2_index = 0
for iter in range(niter):
@@ -400,12 +480,20 @@ def perfmon_emit(pmc_list, workload_dir, soc):
# TCC aggregated counters
line = line + " " + " ".join(tcc_counters)
fd.write(line + "\n")
if workload_dir:
fd.write(line + "\n")
else:
b = line.split()
b.remove("pmc:")
batches.append(b)
fd.write("\ngpu:\n")
fd.write("range:\n")
fd.write("kernel:\n")
fd.close()
if workload_dir:
fd.write("\ngpu:\n")
fd.write("range:\n")
fd.write("kernel:\n")
fd.close()
else:
return batches
def perfmon_filter(workload_dir, perfmon_dir, args):
@@ -445,8 +533,8 @@ def perfmon_filter(workload_dir, perfmon_dir, args):
pmc_files_list = ref_pmc_files_list
# Coalesce and writeback workload specific perfmon
pmc_list = perfmon_coalesce(pmc_files_list, workload_dir, soc)
perfmon_emit(pmc_list, workload_dir, soc)
pmc_list = perfmon_coalesce(pmc_files_list, soc, workload_dir)
perfmon_emit(pmc_list, soc, workload_dir)
def pmc_filter(workload_dir, perfmon_dir, soc):
@@ -463,5 +551,5 @@ def pmc_filter(workload_dir, perfmon_dir, soc):
pmc_files_list = ref_pmc_files_list
# Coalesce and writeback workload specific perfmon
pmc_list = perfmon_coalesce(pmc_files_list, workload_dir, soc)
perfmon_emit(pmc_list, workload_dir, soc)
pmc_list = perfmon_coalesce(pmc_files_list, soc, workload_dir)
perfmon_emit(pmc_list, soc, workload_dir)