Files

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

275 baris
8.1 KiB
Python

2023-02-07 13:06:02 +05:30
#!/usr/bin/env python3
2025-09-19 10:31:12 +05:30
# Copyright © Advanced Micro Devices, Inc., or its affiliates.
# SPDX-License-Identifier: MIT
2023-02-07 13:06:02 +05:30
import sys
2023-08-21 15:08:31 +00:00
2023-02-07 13:06:02 +05:30
if sys.version_info[0] < 3:
raise Exception("Must be using Python 3")
import os
import sys
import time
import socket
from pathlib import Path
from collections import defaultdict
import http.server
import socketserver
import socket
import asyncio
import websockets
from multiprocessing import Process, Manager
import numpy as np
from http import HTTPStatus
2023-04-06 16:55:30 -03:00
from io import BytesIO
2023-06-21 19:49:00 -03:00
from drawing import Readable, GeneratePIC
from copy import deepcopy
from shutil import copy2
from glob import glob
JSON_GLOBAL_DICTIONARY = {}
def get_ip():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.settimeout(0)
try:
hostname = socket.gethostname()
IPAddr = socket.gethostbyname(hostname)
s.connect(({IPAddr}, 1))
except Exception:
2023-08-21 15:08:31 +00:00
IPAddr = "127.0.0.1"
finally:
return IPAddr
IPAddr = get_ip()
PORT, WebSocketPort = 8000, 18000
2023-08-21 15:08:31 +00:00
SP = "\u00A0"
2023-02-07 13:06:02 +05:30
2023-05-02 05:17:47 -03:00
2023-06-21 19:49:00 -03:00
def get_top_n(code):
2023-02-07 13:06:02 +05:30
TOP_N = 10
2023-06-21 19:49:00 -03:00
top_n = sorted(deepcopy(code), key=lambda x: x[-1], reverse=True)[:TOP_N]
2023-08-21 15:08:31 +00:00
return [
(line_num, hitc, 0, run_time) for _, _, _, _, line_num, _, hitc, run_time in top_n
]
2023-02-07 13:06:02 +05:30
def wave_info(df, id):
dic = {
2023-08-21 15:08:31 +00:00
"Issue": df["issued_ins"][id],
"Valu": df["valu_ins"][id],
"Valu_stall": df["valu_stalls"][id],
"Salu": df["salu_ins"][id],
"Salu_stall": df["salu_stalls"][id],
"Vmem": df["vmem_ins"][id],
"Vmem_stall": df["vmem_stalls"][id],
"Smem": df["smem_ins"][id],
"Smem_stall": df["smem_stalls"][id],
"Flat": df["flat_ins"][id],
"Flat_stall": df["flat_stalls"][id],
"Lds": df["lds_ins"][id],
"Lds_stall": df["lds_stalls"][id],
"Br": df["br_ins"][id],
"Br_stall": df["br_stalls"][id],
}
2023-08-21 15:08:31 +00:00
dic["Issue_stall"] = int(np.sum([dic[key] for key in dic.keys() if "_STALL" in key]))
return dic
2023-02-07 13:06:02 +05:30
2023-06-21 19:49:00 -03:00
def extract_data(df, se_number):
2023-08-21 15:08:31 +00:00
if len(df["id"]) == 0 or len(df["instructions"]) == 0 or len(df["timeline"]) == 0:
2023-02-07 13:06:02 +05:30
return None
wave_filenames = []
2023-02-07 13:06:02 +05:30
flight_count = []
2023-08-21 15:08:31 +00:00
wave_slot_count = [
{df["wave_slot"][wave_id]: 0 for wave_id in df["id"]} for k in range(4)
]
print("Number of waves:", len(df["id"]))
allwaves_maxline = 0
2023-02-07 13:06:02 +05:30
2023-08-21 15:08:31 +00:00
for wave_id in df["id"]:
stitched, loopCount, mem_unroll, count, maxline, num_insts = df["instructions"][
wave_id
]
timeline = df["timeline"][wave_id]
2023-02-07 13:06:02 +05:30
2024-01-05 20:17:50 -03:00
if len(stitched) == 0 or len(timeline) == 0:
2023-03-15 17:17:57 -03:00
continue
allwaves_maxline = max(allwaves_maxline, maxline)
2023-02-07 13:06:02 +05:30
flight_count.append(count)
2023-06-21 19:49:00 -03:00
wave_entry = {
2023-08-21 15:08:31 +00:00
"id": int(df["id"][wave_id]),
"simd": int(df["simd"][wave_id]),
"slot": int(df["wave_slot"][wave_id]),
"begin": int(df["begin_time"][wave_id]),
"end": int(df["end_time"][wave_id]),
2023-02-07 13:06:02 +05:30
"info": wave_info(df, wave_id),
"instructions": stitched,
"timeline": timeline,
2023-08-21 15:08:31 +00:00
"waitcnt": mem_unroll,
2023-02-07 13:06:02 +05:30
}
data_obj = {
2023-08-21 15:08:31 +00:00
"name": "SE".format(se_number),
2023-02-07 13:06:02 +05:30
"duration": sum(dur for (_, dur) in timeline),
"wave": wave_entry,
"loop_count": loopCount,
2023-06-21 19:49:00 -03:00
"top_n": [],
"num_stitched": len(stitched),
"num_insts": num_insts,
2023-02-07 13:06:02 +05:30
"websocket_port": WebSocketPort,
2023-08-21 15:08:31 +00:00
"generation_time": time.ctime(),
2023-02-07 13:06:02 +05:30
}
2023-08-21 15:08:31 +00:00
simd_id = df["simd"][wave_id]
slot_id = df["wave_slot"][wave_id]
2023-06-21 19:49:00 -03:00
slot_count = wave_slot_count[simd_id][slot_id]
wave_slot_count[simd_id][slot_id] += 1
2023-08-21 15:08:31 +00:00
OUT = (
"se"
+ str(se_number)
+ "_sm"
+ str(simd_id)
+ "_sl"
+ str(slot_id)
+ "_wv"
+ str(slot_count)
+ ".json"
)
JSON_GLOBAL_DICTIONARY[OUT] = Readable(data_obj)
2023-08-21 15:08:31 +00:00
wave_filenames.append((OUT, df["begin_time"][wave_id], df["end_time"][wave_id]))
data_obj = {
2023-08-21 15:08:31 +00:00
"name": "SE".format(se_number),
"websocket_port": WebSocketPort,
2023-08-21 15:08:31 +00:00
"generation_time": time.ctime(),
}
2023-06-21 19:49:00 -03:00
se_filename = None
if len(wave_filenames) > 0:
2023-08-21 15:08:31 +00:00
se_filename = "se" + str(se_number) + "_info.json"
JSON_GLOBAL_DICTIONARY[se_filename] = Readable(data_obj)
2023-02-07 13:06:02 +05:30
2023-06-21 19:49:00 -03:00
return flight_count, wave_filenames, se_filename, allwaves_maxline
2023-02-07 13:06:02 +05:30
2023-06-21 19:49:00 -03:00
def call_picture_callback(return_dict, drawinfo):
response, imagebytes = GeneratePIC(drawinfo)
2023-08-21 15:08:31 +00:00
return_dict["graph_options.json"] = response
2023-06-21 19:49:00 -03:00
for k, v in imagebytes.items():
return_dict[k] = v
2023-08-21 15:08:31 +00:00
for n, m in enumerate(drawinfo["TIMELINES"]):
return_dict["wstates" + str(n) + ".json"] = Readable(
{"data": [int(n) for n in list(np.asarray(m))]}
)
for n, e in enumerate(drawinfo["EVENTS"]):
return_dict["se" + str(n) + "_perfcounter.json"] = Readable(
{"data": [v.toTuple() for v in e]}
)
def view_trace(
code,
dbnames,
att_filenames,
se_time_begin,
gfxv,
2023-10-04 14:27:55 -03:00
drawinfo,
trace_instance_name
2023-08-21 15:08:31 +00:00
):
2023-06-21 19:49:00 -03:00
global JSON_GLOBAL_DICTIONARY
pic_thread = None
manager = Manager()
return_dict = manager.dict()
occ_dict = {str(k): drawinfo["OCCUPANCY"][k] for k in range(len(drawinfo["OCCUPANCY"]))}
occ_dict['dispatches'] = {}
for id, name in drawinfo['DispatchNames'].items():
occ_dict['dispatches'][id] = name
occ_dict['names'] = drawinfo['ShaderNames']
JSON_GLOBAL_DICTIONARY["occupancy.json"] = Readable(occ_dict)
pic_thread = Process(target=call_picture_callback, args=(return_dict, drawinfo))
pic_thread.start()
2023-02-07 13:06:02 +05:30
att_filenames = [Path(f).name for f in att_filenames]
2023-08-21 15:08:31 +00:00
se_numbers = [int(a.split("_se")[1].split(".att")[0]) for a in att_filenames]
2023-02-07 13:06:02 +05:30
flight_count = []
simd_wave_filenames = {}
se_filenames = []
2023-02-07 13:06:02 +05:30
2023-06-21 19:49:00 -03:00
allse_maxline = 0
2023-02-07 13:06:02 +05:30
for se_number, dbname in zip(se_numbers, dbnames):
2023-08-21 15:08:31 +00:00
if len(dbname["id"]) == 0:
2023-02-07 13:06:02 +05:30
continue
2023-06-21 19:49:00 -03:00
count, wv_filenames, se_filename, maxline = extract_data(dbname, se_number)
if se_filename is None:
continue
allse_maxline = max(allse_maxline, maxline)
se_filenames.append(se_filename)
2023-02-07 13:06:02 +05:30
if count is not None:
flight_count.append(count)
simd_wave_filenames[se_number] = wv_filenames
2024-01-05 20:17:50 -03:00
code_sel = [c[:-3]+c[-2:] for c in code]
JSON_GLOBAL_DICTIONARY['code.json'] = Readable({"code": code_sel, "top_n": get_top_n(code_sel)})
2023-06-21 19:49:00 -03:00
2023-02-07 13:06:02 +05:30
for key in simd_wave_filenames.keys():
2023-08-21 15:08:31 +00:00
wv_array = [
[
int(s[0].split("_sm")[1].split("_sl")[0]),
int(s[0].split("_sl")[1].split("_wv")[0]),
int(s[0].split("_wv")[1].split(".")[0]),
s,
]
for s in simd_wave_filenames[key]
]
2023-02-07 13:06:02 +05:30
wv_dict = {}
for wv in wv_array:
try:
2023-06-21 19:49:00 -03:00
wv_dict[wv[0]][wv[1]][wv[2]] = wv[3]
2023-02-07 13:06:02 +05:30
except:
try:
2023-06-21 19:49:00 -03:00
wv_dict[wv[0]][wv[1]] = {wv[2]: wv[3]}
2023-02-07 13:06:02 +05:30
except:
2023-06-21 19:49:00 -03:00
try:
wv_dict[wv[0]] = {wv[1]: {wv[2]: wv[3]}}
except:
pass
2023-02-07 13:06:02 +05:30
simd_wave_filenames[key] = wv_dict
JSON_GLOBAL_DICTIONARY["filenames.json"] = Readable(
{
"wave_filenames": simd_wave_filenames,
"se_filenames": se_filenames,
"global_begin_time": int(se_time_begin),
"gfxv": gfxv,
}
)
2023-02-07 13:06:02 +05:30
if pic_thread is not None:
pic_thread.join()
for k, v in return_dict.items():
JSON_GLOBAL_DICTIONARY[k] = v
2023-02-07 13:06:02 +05:30
os.makedirs(trace_instance_name + "_ui/", exist_ok=True)
JSON_GLOBAL_DICTIONARY["live.json"] = Readable({"live": 0})
ui_dir_files = glob(os.path.join(os.path.abspath(os.path.dirname(__file__)), "ui")+"/*")
for f in ui_dir_files:
copy2(f, trace_instance_name + "_ui/")
for k, v in JSON_GLOBAL_DICTIONARY.items():
with open(os.path.join(trace_instance_name+"_ui", k), "w" if ".json" in k else "wb") as f:
f.write(v.read())