SWDEV-393541: Added occupancy info.
Change-Id: Ib716b571210d35e1e5ffff29f8b0cced92607ff6
[ROCm/rocprofiler commit: 3170849fe1]
This commit is contained in:
کامیت شده توسط
Giovanni Baraldi
والد
4628770498
کامیت
6375a3049d
@@ -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()
|
||||
|
||||
مرجع در شماره جدید
Block a user