Этот коммит содержится в:
Evgeny
2019-01-28 20:53:55 -06:00
родитель 180b5271b4
Коммит 5e685fb9d7
3 изменённых файлов: 109 добавлений и 41 удалений
+6 -6
Просмотреть файл
@@ -1,11 +1,11 @@
#!/usr/bin/python
from sqlitedb import SQLiteDB
def post_process_data(db, table_name, outfile = ''):
def post_process_data(db, table_name, start_ns, outfile = ''):
# db.add_data_column('A', 'DispDurNs', 'INTEGER', 'BeginNs - DispatchNs')
# db.add_data_column('A', 'ComplDurNs', 'INTEGER', 'CompleteNs - EndNs')
# db.add_data_column('A', 'TotalDurNs', 'INTEGER', 'CompleteNs - DispatchNs')
# db.add_data_column('A', 'TimeNs', 'INTEGER', 'BeginNs - (select BeginNs from A limit 1)')
# db.add_data_column(table_name, 'TimeNs', 'INTEGER', 'BeginNs - %d' % start_ns)
db.add_data_column(table_name, 'DurationNs', 'INTEGER', 'EndNs - BeginNs')
if outfile != '': db.dump_csv(table_name, outfile)
@@ -19,13 +19,13 @@ def gen_table_bins(db, table, outfile, name_var, dur_ns_var):
gen_data_bins(db, outfile)
db.execute('DROP VIEW B')
def gen_api_json_trace(db, table, outfile):
db.execute('create view B as select Name as name, (BeginNs/1000) as ts, (DurationNs/1000) as dur from %s order by ts asc;' % table);
def gen_api_json_trace(db, table, start_ns, outfile):
db.execute('create view B as select "Index", Name as name, pid, tid, (BeginNs/1000 - %d/1000) as ts, (DurationNs/1000) as dur from %s order by ts asc;' % (start_ns, table));
db.dump_json('B', table, outfile)
db.execute('DROP VIEW B')
def gen_kernel_json_trace(db, table, outfile):
db.execute('create view B as select (KernelName) as name, ("gpu-id") as pid, (0) as tid, (BeginNs/1000) as ts, (DurationNs/1000) as dur from %s order by ts asc;' % table);
def gen_kernel_json_trace(db, table, base_pid, start_ns, outfile):
db.execute('create view B as select "Index", KernelName as name, ("gpu-id" + %d) as pid, (0) as tid, (BeginNs/1000 - %d/1000) as ts, (DurationNs/1000) as dur from %s order by ts asc;' % (base_pid, start_ns, table));
db.dump_json('B', table, outfile)
db.execute('DROP VIEW B')
##############################################################################################
+20 -14
Просмотреть файл
@@ -71,6 +71,12 @@ class SQLiteDB:
def _get_raws(self, table_name):
cursor = self.connection.execute('SELECT * FROM ' + table_name)
return cursor.fetchall()
def _get_raw_by_id(self, table_name, req_id):
cursor = self.connection.execute('SELECT * FROM ' + table_name + ' WHERE "Index"=?', (req_id,))
raws = cursor.fetchall()
if len(raws) != 1:
raise Exception('Index is not unique, table "' + table_name + '"')
return list(raws[0])
# dump CSV table
def dump_csv(self, table_name, file_name):
@@ -78,12 +84,10 @@ class SQLiteDB:
raise Exception('wrong output file type: "' + file_name + '"' )
fields = self._get_fields(table_name)
stm = 'select ' + ','.join(fields) + ' from ' + table_name
with open(file_name, mode='w') as fd:
fd.write(','.join(fields) + '\n')
for values in self.connection.execute(stm):
fd.write(reduce(lambda a, b: str(a) + ',' + str(b), values) + '\n')
for raw in self._get_raws(table_name):
fd.write(reduce(lambda a, b: str(a) + ',' + str(b), raw) + '\n')
# dump JSON trace
def open_json(self, file_name):
@@ -104,15 +108,17 @@ class SQLiteDB:
with open(file_name, mode='a') as fd:
fd.write(',{"args":{"name":"%s"},"ph":"M","pid":%s,"name":"process_name"}\n' %(label, pid));
def flow_json(self, from_pid, from_list, to_pid, to_dict, file_name):
def flow_json(self, base_id, from_pid, from_tid, from_us_list, to_pid, to_us_dict, start_us, file_name):
if not re.search(r'\.json$', file_name):
raise Exception('wrong output file type: "' + file_name + '"' )
with open(file_name, mode='a') as fd:
for ind in range(len(from_list)):
from_ts = from_list[ind]
to_ts = to_dict[str(ind)]
fd.write(',{"ts":%s,"ph":"s","cat":"DataFlow","id":%s,"pid":%s,"tid":0,"name":"dep"}\n' % (from_ts, str(ind), str(from_pid)))
fd.write(',{"ts":%s,"ph":"t","cat":"DataFlow","id":%s,"pid":%s,"tid":0,"name":"dep"}\n' % (to_ts, str(ind), str(to_pid)))
dep_id = base_id
for ind in range(len(from_tid)):
from_ts = from_us_list[ind] - start_us
to_ts = to_us_dict[ind] - start_us
fd.write(',{"ts":%d,"ph":"s","cat":"DataFlow","id":%d,"pid":%s,"tid":%d,"name":"dep"}\n' % (from_ts, dep_id, str(from_pid), from_tid[ind]))
fd.write(',{"ts":%d,"ph":"t","cat":"DataFlow","id":%d,"pid":%s,"tid":0,"name":"dep"}\n' % (to_ts, dep_id, str(to_pid)))
dep_id += 1
def dump_json(self, table_name, data_name, file_name):
if not re.search(r'\.json$', file_name):
@@ -124,20 +130,20 @@ class SQLiteDB:
table_fields = self._get_fields(table_name)
table_raws = self._get_raws(table_name)
data_fields = self._get_fields(data_name)
data_raws = self._get_raws(data_name)
with open(file_name, mode='a') as fd:
for raw_index in range(len(table_raws)):
values = list(table_raws[raw_index])
data = list(data_raws[raw_index])
vals_list = []
raw_id = 0;
for value_index in range(len(values)):
label = table_fields[value_index]
value = values[value_index]
if name_ptrn.search(label): value = sub_ptrn.sub(r'', value)
vals_list.append('%s:"%s"' % (label, value))
if label == '"Index"': raw_id = value
else: vals_list.append('%s:"%s"' % (label, value))
data = self._get_raw_by_id(data_name, raw_id)
args_list = []
for value_index in range(len(data)):
label = data_fields[value_index]
+83 -21
Просмотреть файл
@@ -36,8 +36,11 @@ COPY_PID = 0
HSA_PID = 1
GPU_BASE_PID = 2
max_gpu_id = 0
dep_from_list = []
dep_to_dict = {}
START_NS = 0
# dependencies dictionary
dep_dict = {}
kern_dep_list = []
# global vars
table_descr = [
@@ -84,6 +87,10 @@ def parse_res(infile):
'Index': dispatch_number,
'KernelName': "\"" + m.group(3) + "\""
}
gpu_id = 0
disp_tid = 0
kernel_properties = m.group(2)
for prop in kernel_properties.split(', '):
m = prop_pattern.match(prop)
@@ -92,8 +99,10 @@ def parse_res(infile):
val = m.group(2)
var_table[dispatch_number][var] = val
if not var in var_list: var_list.append(var);
if re.search(r'gpu-id', var):
if var == 'gpu-id':
if (val > max_gpu_id): max_gpu_id = val
gpu_id = val
if var == 'tid': disp_tid = int(val)
else: fatal('wrong kernel property "' + prop + '" in "'+ kernel_properties + '"')
m = ts_pattern.search(record)
if m:
@@ -101,6 +110,21 @@ def parse_res(infile):
var_table[dispatch_number]['BeginNs'] = m.group(2)
var_table[dispatch_number]['EndNs'] = m.group(3)
var_table[dispatch_number]['CompleteNs'] = m.group(4)
else: fatal('bad kernel record "' + record + '"')
gpu_pid = GPU_BASE_PID + int(gpu_id)
if not gpu_pid in dep_dict: dep_dict[gpu_pid] = {}
dep_str = dep_dict[gpu_pid]
if not 'tid' in dep_str: dep_str['tid'] = []
if not 'from' in dep_str: dep_str['from'] = []
if not 'to' in dep_str: dep_str['to'] = {}
to_id = len(dep_str['tid'])
from_us = int(m.group(1)) / 1000
to_us = int(m.group(2)) / 1000
dep_str['to'][to_id] = to_us
dep_str['from'].append(from_us)
dep_str['tid'].append(disp_tid)
kern_dep_list.append((disp_tid, from_us))
inp.close()
#############################################################
@@ -155,14 +179,27 @@ def fill_kernel_db(table_name, db):
# fill HSA DB
hsa_table_descr = [
['BeginNs', 'EndNs', 'pid', 'tid', 'Name', 'args'],
{'Name':'TEXT', 'args':'TEXT', 'BeginNs':'INTEGER', 'EndNs':'INTEGER', 'pid':'INTEGER', 'tid':'INTEGER'}
['BeginNs', 'EndNs', 'pid', 'tid', 'Name', 'args', 'Index'],
{'Index':'INTEGER', 'Name':'TEXT', 'args':'TEXT', 'BeginNs':'INTEGER', 'EndNs':'INTEGER', 'pid':'INTEGER', 'tid':'INTEGER'}
]
def fill_hsa_db(table_name, db, indir):
global START_NS
file_name = indir + '/' + 'hsa_api_trace.txt'
ptrn_val = re.compile(r'(\d+):(\d+) (\d+):(\d+) ([^\(]+)(\(.*)$')
ptrn_ac = re.compile(r'hsa_amd_memory_async_copy')
if not COPY_PID in dep_dict: dep_dict[COPY_PID] = {}
dep_tid_list = []
dep_from_us_list = []
with open(file_name, mode='r') as fd:
line = fd.readline()
record = line[:-1]
m = ptrn_val.match(record)
if m: START_NS = int(m.group(1))
START_NS = 0
record_id = 0
table_handle = db.add_table(table_name, hsa_table_descr)
with open(file_name, mode='r') as fd:
for line in fd.readlines():
@@ -171,24 +208,40 @@ def fill_hsa_db(table_name, db, indir):
if m:
rec_vals = []
for ind in range(1,7):
if hsa_table_descr[0][ind - 1] == 'pid':
rec_vals.append(HSA_PID)
else:
rec_vals.append(m.group(ind))
rec_vals.append(m.group(ind))
rec_vals[2] = HSA_PID
rec_vals.append(record_id)
db.insert_entry(table_handle, rec_vals)
if ptrn_ac.search(rec_vals[4]): dep_from_list.append(rec_vals[1])
if ptrn_ac.search(rec_vals[4]):
beg_ns = int(rec_vals[0])
end_ns = int(rec_vals[1])
from_us = (beg_ns / 1000) + ((end_ns - beg_ns) / 1000)
dep_from_us_list.append(from_us)
dep_tid_list.append(int(rec_vals[3]))
record_id += 1
else: fatal("hsa bad record")
for (tid, from_us) in kern_dep_list:
db.insert_entry(table_handle, [((from_us - 1) * 1000), from_us * 1000, HSA_PID, tid, 'hsa_dispatch', '', record_id])
record_id += 1
dep_dict[COPY_PID]['tid'] = dep_tid_list
dep_dict[COPY_PID]['from'] = dep_from_us_list
#############################################################
# fill COPY DB
copy_table_descr = [
['BeginNs', 'EndNs', 'Name', 'pid', 'tid'],
{'Name':'TEXT', 'args':'TEXT', 'BeginNs':'INTEGER', 'EndNs':'INTEGER', 'pid':'INTEGER', 'tid':'INTEGER'}
['BeginNs', 'EndNs', 'Name', 'pid', 'tid', 'Index'],
{'Index':'INTEGER', 'Name':'TEXT', 'args':'TEXT', 'BeginNs':'INTEGER', 'EndNs':'INTEGER', 'pid':'INTEGER', 'tid':'INTEGER'}
]
def fill_copy_db(table_name, db, indir):
file_name = indir + '/' + 'async_copy_trace.txt'
ptrn_val = re.compile(r'(\d+):(\d+) (.*)$')
ptrn_id = re.compile(r'^async-copy(\d+)$')
if not COPY_PID in dep_dict: dep_dict[COPY_PID] = {}
dep_to_us_dict = {}
table_handle = db.add_table(table_name, copy_table_descr)
with open(file_name, mode='r') as fd:
for line in fd.readlines():
@@ -199,11 +252,14 @@ def fill_copy_db(table_name, db, indir):
for ind in range(1,4): rec_vals.append(m.group(ind))
rec_vals.append(COPY_PID)
rec_vals.append(0)
db.insert_entry(table_handle, rec_vals)
m = ptrn_id.match(rec_vals[2])
if m: dep_to_dict[m.group(1)] = rec_vals[0]
if m: dep_to_us_dict[int(m.group(1))] = int(rec_vals[0]) / 1000
else: fatal("async-copy bad name")
rec_vals.append(m.group(1))
db.insert_entry(table_handle, rec_vals)
else: fatal("async-copy bad record")
dep_dict[COPY_PID]['to'] = dep_to_us_dict
#############################################################
# main
if (len(sys.argv) < 3): fatal("Usage: " + sys.argv[0] + " <output CSV file> <input result files list>")
@@ -247,21 +303,27 @@ else:
for ind in range(0, int(max_gpu_id) + 1): db.label_json(int(ind) + int(GPU_BASE_PID), "GPU" + str(ind), jsonfile)
if 'BeginNs' in var_list:
dform.post_process_data(db, 'A', csvfile)
dform.post_process_data(db, 'A', START_NS, csvfile)
dform.gen_table_bins(db, 'A', statfile, 'KernelName', 'DurationNs')
dform.gen_kernel_json_trace(db, 'A', jsonfile)
dform.gen_kernel_json_trace(db, 'A', GPU_BASE_PID, START_NS, jsonfile)
else:
db.dump_csv('A', csvfile)
statfile = re.sub(r'stats', r'hsa_stats', statfile)
dform.post_process_data(db, 'HSA')
dform.post_process_data(db, 'HSA', START_NS)
dform.gen_table_bins(db, 'HSA', statfile, 'Name', 'DurationNs')
dform.gen_api_json_trace(db, 'HSA', jsonfile)
dform.gen_api_json_trace(db, 'HSA', START_NS, jsonfile)
dform.post_process_data(db, 'COPY')
dform.gen_api_json_trace(db, 'COPY', jsonfile)
dform.post_process_data(db, 'COPY', START_NS)
dform.gen_api_json_trace(db, 'COPY', START_NS, jsonfile)
db.flow_json(HSA_PID, dep_from_list, COPY_PID, dep_to_dict, jsonfile)
dep_id = 0
for (to_pid, dep_str) in dep_dict.items():
tid_list = dep_str['tid']
from_us_list = dep_str['from']
to_us_dict = dep_str['to']
db.flow_json(dep_id, HSA_PID, tid_list, from_us_list, to_pid, to_us_dict, (START_NS / 1000), jsonfile)
dep_id += len(tid_list)
db.close_json(jsonfile);
db.close()