2025-07-25 14:01:34 -04:00
# NOTES
#
# Read utils/unified_config.yaml and split it into per gfx architecture per panel config files
# WARNING: This script will overwrite existing files under per gfx architecture folders under src/rocprof_compute_soc/analysis_configs
#
# Read utils/unified_config.yaml and split it into metric tables per documentation section
# WARNING: This script will overwrite existing docs/data/metrics_description.yaml
2025-07-31 08:20:49 -06:00
import copy
2025-07-25 14:01:34 -04:00
import hashlib
import re
from pathlib import Path
import yaml
# Get root directory of the project
ROOT_DIR = Path ( __file__ ) . parent . parent
SOURCE_DIR = ROOT_DIR . joinpath ( "utils" )
TARGET_DIR = ROOT_DIR . joinpath ( "src" , "rocprof_compute_soc" , "analysis_configs" )
DOC_TARGET_DIR = ROOT_DIR . joinpath ( "docs" , "data" )
AUTOGEN_TEXT = "# AUTOGENERATED FILE. Only edit for testing purposes, not for development. Generated from utils/unified_config.yaml. Generated by utils/split_config.py \n "
HASH_FILE = ROOT_DIR . joinpath ( "utils" , "autogen_hash.yaml" )
HASH_FILE_MAP = {}
GFX_VERSIONS = [ "gfx908" , "gfx90a" , "gfx940" , "gfx941" , "gfx942" , "gfx950" ]
def update_analysis_config ():
# Read the unified config file
with open ( SOURCE_DIR . joinpath ( "unified_config.yaml" )) as file :
unified_config = yaml . safe_load ( file )
# Create per panel config file
for panel_config in unified_config [ "panels" ]:
new_panel_config = { "Panel Config" : {}}
new_panel_config [ "Panel Config" ][ "id" ] = panel_config [ "id" ]
new_panel_config [ "Panel Config" ][ "title" ] = panel_config [ "title" ]
2025-07-31 08:20:49 -06:00
new_panel_config [ "Panel Config" ][ "metrics_description" ] = {
key : value [ "plain" ]
for key , value in panel_config . get ( "metrics_description" , {}) . items ()
}
2025-07-25 14:01:34 -04:00
# Convert int into str with 4 digits
panel_id = str ( panel_config [ "id" ]) . zfill ( 4 )
# Replace parentehsis, hyphen, slash and space with underscore
# Remove duplicate underscore
# Convert to lower case
panel_title = re . sub ( r "[()\-/ ]+" , "_" , panel_config [ "title" ])
panel_title = "_" . join ( filter ( None , panel_title . split ( "_" )))
panel_title = panel_title . lower ()
for gfx_version in GFX_VERSIONS :
# Create per gfx architecture folder
gfx_dir = TARGET_DIR . joinpath ( gfx_version )
# Create directory if it doesn't exist
if not gfx_dir . exists ():
gfx_dir . mkdir ()
print ( f "Created directory: { gfx_dir } " )
# Select metrics from current gfx arch
new_panel_config [ "Panel Config" ][ "data source" ] = []
for data_source_config in panel_config [ "data source" ]:
data_source_config = copy . deepcopy ( data_source_config )
if "metric_table" in data_source_config :
2025-07-31 08:20:49 -06:00
data_source_config [ "metric_table" ][ "metric" ] = data_source_config [
"metric_table"
][ "metric" ][ gfx_version ]
2025-07-25 14:01:34 -04:00
new_panel_config [ "Panel Config" ][ "data source" ] . append ( data_source_config )
# Write panel config to file
filename = Path (
TARGET_DIR . joinpath ( gfx_version , f " { panel_id } _ { panel_title } .yaml" )
)
with open ( filename , "w" ) as file :
file . write ( AUTOGEN_TEXT )
yaml . dump ( new_panel_config , file , sort_keys = False )
print ( f "File write: { filename } " )
# Calculate hash of filename
HASH_FILE_MAP [ str ( filename . relative_to ( ROOT_DIR ))] = hashlib . sha256 (
filename . read_bytes ()
) . hexdigest ()
def update_documentation ():
# Documentation sections
section_panel_map = {
"Wavefront launch stats" : 701 ,
"Wavefront runtime stats" : 702 ,
"Overall instruction mix" : 1001 ,
"VALU arithmetic instruction mix" : 1002 ,
"MFMA instruction mix" : 1004 ,
"Compute Speed-of-Light" : 1101 ,
"Pipeline statistics" : 1102 ,
"Arithmetic operations" : 1103 ,
"LDS Speed-of-Light" : 1201 ,
"LDS Statistics" : 1202 ,
"vL1D Speed-of-Light" : 1601 ,
"Busy / stall metrics" : 1501 ,
"Instruction counts" : 1502 ,
"Spill / stack metrics" : 1503 ,
"L1 Unified Translation Cache (UTCL1)" : 1605 ,
"vL1D cache stall metrics" : 1602 ,
"vL1D cache access metrics" : 1603 ,
"Vector L1 data-return path or Texture Data (TD)" : 1504 ,
"L2 Speed-of-Light" : 1701 ,
"L2 cache accesses" : 1703 ,
"L2-Fabric interface metrics" : 1702 ,
"L2 - Fabric interface detailed metrics" : 1706 ,
"L2 - Fabric Interface stalls" : 1705 ,
"Scalar L1D Speed-of-Light" : 1401 ,
"Scalar L1D cache accesses" : 1402 ,
"Scalar L1D Cache - L2 Interface" : 1403 ,
"L1I Speed-of-Light" : 1301 ,
"L1I cache accesses" : 1302 ,
"L1I <-> L2 interface" : 1303 ,
"Workgroup manager utilizations" : 601 ,
"Workgroup Manager - Resource Allocation" : 602 ,
"Command processor fetcher (CPF)" : 501 ,
"Command processor packet processor (CPC)" : 502 ,
"System Speed-of-Light" : 201 ,
}
# Read the unified config file
with open ( SOURCE_DIR . joinpath ( "unified_config.yaml" )) as file :
unified_config = yaml . safe_load ( file )
panel_metric_map = {}
for panel_config in unified_config [ "panels" ]:
for data_source in panel_config [ "data source" ]:
if "metric_table" in data_source :
metrics_info = {}
for key in panel_config [ "metrics_description" ]:
metrics_info [ key ] = {
"rst" : panel_config [ "metrics_description" ][ key ][ "rst" ],
"unit" : panel_config [ "metrics_description" ][ key ][ "unit" ],
}
2025-07-31 08:20:49 -06:00
panel_metric_map [ data_source [ "metric_table" ][ "id" ]] = metrics_info
2025-07-25 14:01:34 -04:00
# Merge panel_metric_map with section_panel_map
section_metric_map = {}
for section , panel_id in section_panel_map . items ():
if panel_id in panel_metric_map :
section_metric_map [ section ] = panel_metric_map [ panel_id ]
# Write documentation metrics description file
filename = Path ( DOC_TARGET_DIR . joinpath ( "metrics_description.yaml" ))
with open ( filename , "w" ) as file :
file . write ( AUTOGEN_TEXT )
yaml . dump ( section_metric_map , file , sort_keys = False )
print ( f "File write: { filename } " )
# Calculate hash of filename
HASH_FILE_MAP [ str ( filename . relative_to ( ROOT_DIR ))] = hashlib . sha256 (
filename . read_bytes ()
) . hexdigest ()
def update_hash ():
# Write hash file
with open ( HASH_FILE , "w" ) as file :
file . write ( AUTOGEN_TEXT )
yaml . dump ( HASH_FILE_MAP , file , sort_keys = False )
print ( f "File write: { HASH_FILE } " )
if __name__ == "__main__" :
update_analysis_config ()
update_documentation ()
update_hash ()