SWDEV-393541: Added occupancy info.

Change-Id: Ib716b571210d35e1e5ffff29f8b0cced92607ff6


[ROCm/rocprofiler commit: 3170849fe1]
This commit is contained in:
Giovanni LB
2023-04-06 16:55:30 -03:00
کامیت شده توسط Giovanni Baraldi
والد 4628770498
کامیت 6375a3049d
2فایلهای تغییر یافته به همراه51 افزوده شده و 27 حذف شده
@@ -122,7 +122,9 @@ class ReturnInfo(ctypes.Structure):
_fields_ = [('num_waves', ctypes.c_uint64),
('wavedata', POINTER(Wave)),
('num_events', ctypes.c_uint64),
('perfevents', POINTER(PerfEvent))]
('perfevents', POINTER(PerfEvent)),
('occupancy', POINTER(ctypes.c_uint64)),
('num_occupancy', ctypes.c_uint64)]
rocprofv2_att_lib = os.getenv('ROCPROFV2_ATT_LIB_PATH')
try: # For build dir
@@ -178,12 +180,20 @@ def getWaves(filename, target_cu, verbose):
waves = [info.wavedata[k] for k in range(info.num_waves)]
events = [deepcopy(info.perfevents[k]) for k in range(info.num_events)]
occupancy = [int(info.occupancy[k]) for k in range(int(info.num_occupancy))]
'''occupancy = np.asarray([f for f in occupancy if (f&0xFF) == 3])
print(occupancy.size, occupancy.dtype)
token_time = occupancy >> 16
value = (occupancy >> 8) & 0xFF
plt.plot(token_time, value); plt.show()
quit()'''
for wave in waves:
wave.timeline = deepcopy(wave.timeline_string.decode("utf-8"))
wave.instructions = deepcopy(wave.instructions_string.decode("utf-8"))
return waves, events
return waves, events, occupancy
def persist(trace_file, SIMD):
@@ -307,6 +317,7 @@ def get_delta_time(events):
return 1
def draw_wave_metrics(selections, normalize):
global TIMELINES
global EVENTS
global EVENT_NAMES
@@ -317,6 +328,9 @@ def draw_wave_metrics(selections, normalize):
delta_step = 8
quad_delta_time = max(delta_step,int(0.5+np.min([get_delta_time(events) for events in EVENTS])))
maxtime = np.max([np.max([e.time for e in events]) for events in EVENTS])/quad_delta_time+1
event_timeline = np.zeros((16, maxtime), dtype=np.int32)
print('Delta:', quad_delta_time)
print('Max_cycles:', maxtime)
if maxtime*delta_step >= COUNTERS_MAX_CAPTURES:
delta_step = 1
@@ -362,7 +376,7 @@ def draw_wave_metrics(selections, normalize):
figure_bytes = BytesIO()
plt.savefig(figure_bytes, dpi=150)
return response, FileBytesIO(figure_bytes)
return response, FileBytesIO(figure_bytes), TIMELINES, EVENTS
def draw_wave_states(selections, normalize):
@@ -403,7 +417,7 @@ def draw_wave_states(selections, normalize):
figure_bytes = BytesIO()
plt.savefig(figure_bytes, dpi=150)
response = Readable({"counters": STATES})
return response, FileBytesIO(figure_bytes)
return response, FileBytesIO(figure_bytes), TIMELINES, []
def GeneratePIC(selections=[True for k in range(16)], normalize=True, bScounter=True):
@@ -491,16 +505,18 @@ if __name__ == "__main__":
global EVENTS
TIMELINES = [np.zeros(int(1E4),dtype=np.int32) for k in range(5)]
EVENTS = []
OCCUPANCY = []
analysed_filenames = []
for name in filenames:
SIMD, perfevents = getWaves(name, args.target_cu, False)
SIMD, perfevents, occupancy = getWaves(name, args.target_cu, False)
if len(SIMD) == 0:
print("Error parsing ", name)
continue
analysed_filenames.append(name)
EVENTS.append(perfevents)
DBFILES.append( persist(name, SIMD) )
OCCUPANCY.append( occupancy )
for wave in SIMD:
time_acc = 0
tuples1 = wave.timeline.split('(')
@@ -521,7 +537,7 @@ if __name__ == "__main__":
time_acc += state[1]
if args.genasm and len(args.genasm) > 0:
flight_count = view_trace(args, 0, code, jumps, DBFILES, analysed_filenames, True, None)
flight_count = view_trace(args, 0, code, jumps, DBFILES, analysed_filenames, True, None, OCCUPANCY)
with open(args.assembly_code, 'r') as file:
lines = file.readlines()
@@ -533,4 +549,4 @@ if __name__ == "__main__":
for k in keys:
file.write(assembly_code[k]+'\n')
else:
view_trace(args, 0, code, jumps, DBFILES, analysed_filenames, False, GeneratePIC)
view_trace(args, 0, code, jumps, DBFILES, analysed_filenames, False, GeneratePIC, OCCUPANCY)
@@ -21,6 +21,7 @@ from multiprocessing import Process, Manager
import numpy as np
from copy import deepcopy
from http import HTTPStatus
from io import BytesIO
class Readable:
def __init__(self, jsonstring) -> None:
@@ -41,6 +42,8 @@ class Readable:
def __len__(self):
return len(self.jsonstr)
MAX_STITCHED_TOKENS = 3000000
MAX_FAILED_STITCHES = 256
STACK_SIZE_LIMIT = 64
SMEM = 1
@@ -114,14 +117,12 @@ class RegisterWatchList:
self.registers[reg].append(deepcopy(self.labels[label_dest]))
def swappc(self, line, line_num):
#print('swappc pc:', line)
tokens = self.tokenize(line)
dst = tokens[1]
src = tokens[2]
#print('swap to', self.registers[self.range(src)[0]])
self.registers[self.range(dst)[0]].append(line_num+1)
popped = self.registers[self.range(src)[0]][-1]
self.registers[self.range(src)[0]] = self.registers[self.range(src)[0]][:-1]
self.registers[self.range(dst)[0]].append(line_num+1)
return popped
def setpc(self, line):
@@ -221,14 +222,13 @@ def stitch(insts, raw_code, jumps):
watchlist = RegisterWatchList(labels=labels)
num_failed_stitches = 0
MAX_FAILED_STITCHES = 128
loops = 0
maxline = 0
while i < N:
#print('L', line)
loops += 1
if line >= len(code) or loops > 100000 or num_failed_stitches >= MAX_FAILED_STITCHES:
if line >= len(code) or loops > MAX_STITCHED_TOKENS or num_failed_stitches > MAX_FAILED_STITCHES:
break
maxline = max(reverse_map[line], maxline)
@@ -442,7 +442,6 @@ def extract_waves(waves):
return result
def extract_data(df, se_number, code, jumps):
if len(df['id']) == 0 or len(df['instructions']) == 0 or len(df['timeline']) == 0:
return None
@@ -458,6 +457,7 @@ def extract_data(df, se_number, code, jumps):
for wave_id in df['id']:
if non_stitched[df['simd'][wave_id]][df['wave_slot'][wave_id]] == 0:
continue
print(f"Parsing :{se_number}-{df['simd'][wave_id]}-{df['wave_slot'][wave_id]}")
insts, timeline = [], []
if len(df['instructions'][wave_id]) == 0 or len(df['timeline'][wave_id]) == 0:
continue
@@ -475,8 +475,8 @@ def extract_data(df, se_number, code, jumps):
maxgrade[df['simd'][wave_id]][df['wave_slot'][wave_id]] = srate
non_stitched[df['simd'][wave_id]][df['wave_slot'][wave_id]] = len(insts) - len(stitched)
flight_count.append(count)
wave_entry = {
wave_entry = {
"id": int(df['id'][wave_id]),
"simd": int(df['simd'][wave_id]),
"slot": int(df['wave_slot'][wave_id]),
@@ -524,24 +524,28 @@ class NoCacheHTTPRequestHandler(http.server.SimpleHTTPRequestHandler):
global PICTURE_CALLBACK
if 'timeline.png?' in self.path:
selections = [int(s)!=0 for s in self.path.split('timeline.png?')[1]]
counters_json, imagebytes = PICTURE_CALLBACK(selections[1:], selections[0])
counters_json, imagebytes, _, _ = PICTURE_CALLBACK(selections[1:], selections[0])
JSON_GLOBAL_DICTIONARY['counters.json'] = counters_json
JSON_GLOBAL_DICTIONARY[self.path.split('/')[-1]] = imagebytes
if '.json' in self.path or 'timeline.png' in self.path:
if '.json' in self.path or 'timeline.png' in self.path or 'wstates' in self.path:
try:
response_file = JSON_GLOBAL_DICTIONARY[self.path.split('/')[-1]]
#print(response_file)
except:
print('Invalid json request:', self.path)
self.send_error(HTTPStatus.NOT_FOUND, "File not found")
#print(JSON_GLOBAL_DICTIONARY.keys())
print(JSON_GLOBAL_DICTIONARY.keys())
return
self.send_response(HTTPStatus.OK)
if 'timeline.png' in self.path:
self.send_header("Content-Length", str(len(response_file)))
if '.b' in self.path:
self.send_header("Content-type", 'application/octet-stream')
response_file = BytesIO(response_file)
elif 'timeline.png' in self.path:
self.send_header("Content-type", 'image/png')
else:
self.send_header("Content-type", 'application/json')
self.send_header("Content-Length", str(len(response_file)))
self.send_header("Last-Modified", self.date_time_string(time.time()))
self.end_headers()
self.copyfile(response_file, self.wfile)
@@ -615,16 +619,20 @@ def assign_ports(ports):
def call_picture_callback(return_dict):
global PICTURE_CALLBACK
response, imagebytes = PICTURE_CALLBACK()
return_dict[0] = response
return_dict[1] = imagebytes
response, imagebytes, wstates, counter_events = PICTURE_CALLBACK()
return_dict['counters.json'] = response
return_dict['timeline.png'] = imagebytes
for n, m in enumerate(wstates):
return_dict['wstates'+str(n)+'.json'] = Readable({"data": [int(n) for n in list(np.asarray(m))]})
for n, e in enumerate(counter_events):
return_dict['se'+str(n)+'_perfcounter.json'] = Readable({"data": [v.toTuple() for v in e]})
def view_trace(args, wait, code, jumps, dbnames, att_filenames, bReturnLoc, pic_callback):
def view_trace(args, wait, code, jumps, dbnames, att_filenames, bReturnLoc, pic_callback, OCCUPANCY):
global PICTURE_CALLBACK
PICTURE_CALLBACK = pic_callback
manager = Manager()
return_dict = manager.dict()
JSON_GLOBAL_DICTIONARY['occupancy.json'] = Readable({str(k): OCCUPANCY[k] for k in range(len(OCCUPANCY))})
pic_thread = Process(target=call_picture_callback, args=(return_dict,))
pic_thread.start()
@@ -678,8 +686,8 @@ def view_trace(args, wait, code, jumps, dbnames, att_filenames, bReturnLoc, pic_
PROCS = [Process(target=run_server), Process(target=run_websocket)]
if pic_thread is not None:
pic_thread.join()
JSON_GLOBAL_DICTIONARY['counters.json'] = return_dict[0]
JSON_GLOBAL_DICTIONARY['timeline.png'] = return_dict[1]
for k, v in return_dict.items():
JSON_GLOBAL_DICTIONARY[k] = v
for p in PROCS:
p.start()