diff --git a/osaca/db_interface.py b/osaca/db_interface.py index 048a1e8..12e8327 100755 --- a/osaca/db_interface.py +++ b/osaca/db_interface.py @@ -2,6 +2,7 @@ import math import os +import sys import warnings import ruamel.yaml @@ -56,17 +57,68 @@ def import_benchmark_output(arch, bench_type, filepath): if bench_type == 'ibench': db_entries = _get_ibench_output(input_data, mm.get_ISA()) elif bench_type == 'asmbench': - raise NotImplementedError + db_entries = _get_asmbench_output(input_data, mm.get_ISA()) # write entries to DB for entry in db_entries: mm.set_instruction_entry(db_entries[entry]) - print(mm.dump()) + sys.stdout.write(mm.dump()) + ################## # HELPERS IBENCH # ################## +def _get_asmbench_output(input_data, isa): + """ + Parse asmbench output in the format + + 1 MNEMONIC[-OP1[_OP2][...]] + 2 Latency: X cycles + 3 Throughput: Y cycles + 4 + + and creates per 4 lines in the input_data one entry in the database. + + :param str input_data: content of asmbench output file + :param str isa: ISA of target architecture (x86, AArch64, ...) + : return: dictionary with all new db_entries + """ + db_entries = {} + for i in range(0, len(input_data), 4): + if input_data[i + 3].strip() != '': + print('asmbench output not in the correct format! Format must be: ', file=sys.stderr) + print( + '-------------\nMNEMONIC[-OP1[_OP2][...]]\nLatency: X cycles\n' + 'Throughput: Y cycles\n\n-------------', + file=sys.stderr, + ) + print( + 'Entry {} and all further entries won\'t be added.'.format((i / 4) + 1), + file=sys.stderr, + ) + break + else: + i_form = input_data[i].strip() + mnemonic = i_form.split('-')[0] + operands = i_form.split('-')[1].split('_') + operands = [_create_db_operand(op, isa) for op in operands] + entry = { + 'name': mnemonic, + 'operands': operands, + 'throughput': _validate_measurement(float(input_data[i + 2].split()[1]), 'tp'), + 'latency': _validate_measurement(float(input_data[i + 1].split()[1]), 'lt'), + 'port_pressure': None, + } + if not entry['throughput'] or not entry['latency']: + warnings.warn( + 'Your measurement for {} looks suspicious'.format(i_form) + + ' and was not added. Please inspect your benchmark.' + ) + db_entries[i_form] = entry + return db_entries + + def _get_ibench_output(input_data, isa): db_entries = {} for line in input_data: @@ -89,14 +141,14 @@ def _get_ibench_output(input_data, isa): 'port_pressure': None, } if 'TP' in instruction: - entry['throughput'] = _validate_measurement(float(line.split()[1]), True) + entry['throughput'] = _validate_measurement(float(line.split()[1]), 'tp') if not entry['throughput']: warnings.warn( 'Your THROUGHPUT measurement for {} looks suspicious'.format(key) + ' and was not added. Please inspect your benchmark.' ) elif 'LT' in instruction: - entry['latency'] = _validate_measurement(float(line.split()[1]), False) + entry['latency'] = _validate_measurement(float(line.split()[1]), 'lt') if not entry['latency']: warnings.warn( 'Your LATENCY measurement for {} looks suspicious'.format(key) @@ -106,8 +158,8 @@ def _get_ibench_output(input_data, isa): return db_entries -def _validate_measurement(measurement, is_tp): - if not is_tp: +def _validate_measurement(measurement, mode): + if mode == 'lt': if ( math.floor(measurement) * 1.05 >= measurement or math.ceil(measurement) * 0.95 <= measurement @@ -115,7 +167,7 @@ def _validate_measurement(measurement, is_tp): # Value is probably correct, so round it to the estimated value return float(round(measurement)) # Check reciprocal only if it is a throughput value - else: + elif mode == 'tp': reciprocals = [1 / x for x in range(1, 11)] for reci in reciprocals: if reci * 0.95 <= measurement <= reci * 1.05: diff --git a/osaca/osaca.py b/osaca/osaca.py index 4ff3864..71c832e 100755 --- a/osaca/osaca.py +++ b/osaca/osaca.py @@ -130,6 +130,8 @@ def check_user_dir(): def import_data(benchmark_type, arch, filepath): if benchmark_type.lower() == 'ibench': import_benchmark_output(arch, 'ibench', filepath) + elif benchmark_type.lower() == 'asmbench': + import_benchmark_output(arch, 'asmbench', filepath) else: raise NotImplementedError('This benchmark input variant is not implemented yet.')