diff --git a/osaca/osaca.py b/osaca/osaca.py index 27a6575..5f6634d 100755 --- a/osaca/osaca.py +++ b/osaca/osaca.py @@ -22,6 +22,7 @@ class Osaca(object): srcCode = None df = None instr_forms = None + file_output = '' # Variables for checking lines numSeps = 0 indentChar = '' @@ -41,10 +42,11 @@ class Osaca(object): + r'((,[ \t]*103[ \t]*((,[ \t]*144)|(\n\s*\.byte[ \t]+144)))|(\n\s*\.byte' + r'[ \t]+103[ \t]*((,[ \t]*144)|(\n\s*\.byte[ \t]+144))))') - def __init__(self, _arch, _filepath): + def __init__(self, _arch, _filepath, output=sys.stdout): self.arch = _arch self.filepath = _filepath self.instr_forms = [] + self.file_output = output # -----------------main functions depending on arguments-------------------- def include_ibench(self): @@ -63,7 +65,7 @@ class Osaca(object): self.df = self.read_csv() # Create sequence of numbers and their reciprokals for validate the measurements cyc_list, reci_list = self.create_sequences() - print('Everything seems fine! Let\'s start!') + print('Everything seems fine! Let\'s start!', file=self.file_output) new_data = [] added_vals = 0 for line in self.srcCode: @@ -113,10 +115,10 @@ class Osaca(object): if(not new and abs((val/np.float64(clk_cyc))-1) > 0.05): print('Different measurement for {} ({}): {}(old) vs. '.format(instr, clmn, val) + '{}(new)\nPlease check for correctness '.format(clk_cyc) - + '(no changes were made).') + + '(no changes were made).', file=self.file_output) txt_output = True if(txt_output): - print() + print('', file=self.file_output) txt_output = False # Now merge the DataFrames and write new csv file self.df = self.df.append(pd.DataFrame(new_data, columns=['instr', 'TP', 'LT', 'ports']), @@ -124,8 +126,8 @@ class Osaca(object): csv = self.df.to_csv(index=False) self.write_csv(csv) print('ibench output {} '.format(self.filepath.split('/')[-1]) - + 'successfully in database included.') - print('{} values were added.'.format(added_vals)) + + 'successfully in database included.', file=self.file_output) + print('{} values were added.'.format(added_vals), file=self.file_output) def inspect_binary(self): """ @@ -141,14 +143,14 @@ class Osaca(object): # Finally check for database for the chosen architecture self.read_csv() - print('Everything seems fine! Let\'s start checking!') + print('Everything seems fine! Let\'s start checking!', file=self.file_output) for i, line in enumerate(self.srcCode): if(i == 0): self.check_line(line, True) else: self.check_line(line) output = self.create_output() - print(output) + print(output, file=self.file_output) def inspect_with_iaca(self): """ @@ -173,13 +175,13 @@ class Osaca(object): # Finally check for database for the chosen architecture self.read_csv() - print('Everything seems fine! Let\'s start checking!') + print('Everything seems fine! Let\'s start checking!', file=self.file_output) if(binary_file): self.iaca_bin() else: self.iaca_asm() output = self.create_output() - print(output) + print(output, file=self.file_output) # -------------------------------------------------------------------------- @@ -262,7 +264,7 @@ class Osaca(object): try: f = open(self.filepath, 'r') except IOError: - print('IOError: file \'{}\' not found'.format(self.filepath)) + print('IOError: file \'{}\' not found'.format(self.filepath), file=self.file_output) self.srcCode = '' for line in f: self.srcCode += line @@ -296,7 +298,8 @@ class Osaca(object): try: f = open('data/'+self.arch.lower()+'_data.csv', 'w') except IOError: - print('IOError: file \'{}\' not found in ./data'.format(self.arch.lower()+'_data.csv')) + print('IOError: file \'{}\' not found in ./data'.format(self.arch.lower()+'_data.csv'), + file=self.file_output) f.write(csv) f.close() @@ -366,8 +369,8 @@ class Osaca(object): # No value close to an integer or its reciprocal found, we assume the # measurement is incorrect print('Your measurement for {} ({}) is probably wrong. '.format(instr, clmn) - + 'Please inspect your benchmark!') - print('The program will continue with the given value') + + 'Please inspect your benchmark!', file=self.file_output) + print('The program will continue with the given value', file=self.file_output) return clk_cyc def check_line(self, line, first_appearance=False): @@ -687,7 +690,7 @@ class Osaca(object): tp = self.df[self.df.instr == elem[0] + '-' + operands].TP.values[0] except IndexError: # Something went wrong - print('Error while fetching data from database') + print('Error while fetching data from database', file=self.file_output) continue # Did not found the exact instruction form. # Try to find the instruction form for register operands only @@ -703,9 +706,8 @@ class Osaca(object): op_ext_regs.append(False) if(True not in op_ext_regs): # No register in whole instr form. How can I find out what regsize we need? - print('test') - print('Feature not included yet: ', end='') - print(elem[0]+' for '+operands) + print('Feature not included yet: ', end='', file=self.file_output) + print(elem[0]+' for '+operands, file=self.file_output) tp = 0 not_found = True warning = True @@ -742,7 +744,7 @@ class Osaca(object): tp = self.df[self.df.instr == elem[0]+'-'+operands].TP.values[0] except IndexError: # Something went wrong - print('Error while fetching data from database') + print('Error while fetching data from database', file=self.file_output) continue # Did not found the register instruction form. Set warning and go on with # throughput 0 diff --git a/tests/all_tests.py b/tests/all_tests.py new file mode 100755 index 0000000..7666878 --- /dev/null +++ b/tests/all_tests.py @@ -0,0 +1,16 @@ +#!/usr//bin/env python + +import sys + +import unittest + + +sys.path[0:0] = ['.', '..'] +suite = unittest.TestLoader().loadTestsFromNames( + [ + 'test_osaca' + ] +) + +testresult = unittest.TextTestRunner(verbosity=2).run(suite) +sys.exit(0 if testresult.wasSuccessful() else 1) diff --git a/tests/test_osaca.py b/tests/test_osaca.py new file mode 100755 index 0000000..1662be7 --- /dev/null +++ b/tests/test_osaca.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python3 + +import sys +from io import StringIO +import os + +import unittest + +sys.path.insert(0, '..') +from osaca.osaca import Osaca + +class TestOsaca(unittest.TestCase): + def testIACABinary(self): + out = StringIO() + curr_dir = '/'.join(os.path.realpath(__file__).split('/')[:-1]) + osa = Osaca('IVB', curr_dir+'/testfiles/taxCalc-ivb-iaca', out) + osa.inspect_with_iaca() + result = out.getvalue() + result = '\n'.join(result.split('\n')[-27:]) + with open(curr_dir+'/test_osaca_iaca.out', encoding='utf-8') as f: + assertion = f.read() + self.assertEqual(result, assertion) diff --git a/tests/test_osaca_iaca.out b/tests/test_osaca_iaca.out new file mode 100644 index 0000000..61a832f --- /dev/null +++ b/tests/test_osaca_iaca.out @@ -0,0 +1,26 @@ +Port Binding in Cycles Per Iteration: +---------------------------------------------- +| Port | 0 | 1 | 2 | 3 | 4 | 5 | +---------------------------------------------- +| Cycles | 4.0 | 5.0 | 3.0 | 3.0 | 2.0 | 2.0 | +---------------------------------------------- + + + Ports Pressure in cycles +| 0 | 1 | 2 | 3 | 4 | 5 | +------------------------------------------- +| | | 1.00 | 1.00 | | | lea 0x1(%rax,%rax,1),%edx +| 0.50 | 1.00 | | | | 0.50 | vcvtsi2ss %edx,%xmm2,%xmm2 +| 1.00 | | | | | | vmulss %xmm2,%xmm0,%xmm3 +| | | 1.00 | 1.00 | | | lea 0x2(%rax,%rax,1),%ecx +| | 1.00 | | | | | vaddss %xmm3,%xmm1,%xmm4 +| 0.33 | 0.33 | | | | 0.33 | vxorps %xmm1,%xmm1,%xmm1 +| 0.50 | 1.00 | | | | 0.50 | vcvtsi2ss %ecx,%xmm1,%xmm1 +| 1.00 | | | | | | vmulss %xmm1,%xmm0,%xmm5 +| | | 0.50 | 0.50 | 1.00 | | vmovss %xmm4,0x4(%rsp,%rax,8) +| | 1.00 | | | | | vaddss %xmm5,%xmm4,%xmm1 +| | | 0.50 | 0.50 | 1.00 | | vmovss %xmm1,0x8(%rsp,%rax,8) +| 0.33 | 0.33 | | | | 0.33 | inc %rax +| 0.33 | 0.33 | | | | 0.33 | cmp $0x1f3,%rax +| | | | | | | jb 400bc2 +Total number of estimated throughput: 5.0 diff --git a/tests/testfiles/taxCalc-ivb-iaca b/tests/testfiles/taxCalc-ivb-iaca new file mode 100755 index 0000000..5d7f82e Binary files /dev/null and b/tests/testfiles/taxCalc-ivb-iaca differ diff --git a/tox.ini b/tox.ini index cac3bec..0fc572b 100644 --- a/tox.ini +++ b/tox.ini @@ -2,5 +2,7 @@ envlist = py35 [testenv] commands= - osaca --arch ivb --iaca examples/taxCalc-ivb-iaca - osaca --arch ivb --iaca examples/taxCalc-ivb-iaca.S + python tests/all_tests.py +# osaca --arch ivb --iaca examples/taxCalc-ivb-iaca +# osaca --arch ivb --iaca examples/taxCalc-ivb-iaca.S +# osaca --arch ivb examples/taxCalc-ivb