mirror of
https://github.com/RRZE-HPC/OSACA.git
synced 2025-12-16 00:50:06 +01:00
more tests and bugfixes
This commit is contained in:
@@ -21,7 +21,7 @@ def add_entry_to_db(arch: str, entry):
|
||||
"""
|
||||
# load yaml
|
||||
arch = arch.lower()
|
||||
filepath = os.path.join(os.path.expanduser('~/.osaca/data/', arch + '.yml'))
|
||||
filepath = os.path.join(os.path.expanduser('~/.osaca/data/' + arch + '.yml'))
|
||||
assert os.path.exists(filepath)
|
||||
with open(filepath, 'r') as f:
|
||||
data = yaml.load(f, Loader=yaml.Loader)
|
||||
@@ -52,7 +52,7 @@ def add_entries_to_db(arch: str, entries: list) -> None:
|
||||
"""
|
||||
# load yaml
|
||||
arch = arch.lower()
|
||||
filepath = os.path.join(os.path.expanduser('~/.osaca/data/', arch + '.yml'))
|
||||
filepath = os.path.join(os.path.expanduser('~/.osaca/data/' + arch + '.yml'))
|
||||
assert os.path.exists(filepath)
|
||||
with open(filepath, 'r') as f:
|
||||
data = yaml.load(f, Loader=yaml.Loader)
|
||||
|
||||
@@ -27,9 +27,10 @@ class MachineModel(object):
|
||||
)
|
||||
elif path_to_yaml:
|
||||
try:
|
||||
assert os.path.exists(self._path)
|
||||
with open(self._path, 'r') as f:
|
||||
self._data = yaml.load(f, Loader=yaml.Loader)
|
||||
except AssertionError:
|
||||
except (AssertionError, FileNotFoundError):
|
||||
raise ValueError(
|
||||
'Cannot find specified path to YAML file. Make sure the machine file exists.'
|
||||
)
|
||||
|
||||
@@ -10,7 +10,8 @@ suite = unittest.TestLoader().loadTestsFromNames(
|
||||
'test_parser_AArch64v81',
|
||||
'test_marker_utils',
|
||||
'test_semantics',
|
||||
'test_frontend'
|
||||
'test_frontend',
|
||||
'test_db_interface',
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
113
tests/test_db_interface.py
Executable file
113
tests/test_db_interface.py
Executable file
@@ -0,0 +1,113 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Unit tests for DB interface
|
||||
"""
|
||||
|
||||
import copy
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from osaca.api import add_entries_to_db, add_entry_to_db, sanity_check
|
||||
from osaca.semantics import MachineModel
|
||||
|
||||
|
||||
class TestDBInterface(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(self):
|
||||
sample_entry = {
|
||||
'name': 'DoItRightAndDoItFast',
|
||||
'operands': [
|
||||
{'class': 'memory', 'offset': 'imd', 'base': 'gpr', 'index': 'gpr', 'scale': 8},
|
||||
{'class': 'register', 'name': 'xmm'},
|
||||
],
|
||||
'throughput': 1.25,
|
||||
'latency': 125,
|
||||
'uops': 6,
|
||||
}
|
||||
self.entry_csx = sample_entry.copy()
|
||||
self.entry_vulcan = sample_entry.copy()
|
||||
self.entry_zen1 = sample_entry.copy()
|
||||
|
||||
self.entry_csx['port_pressure'] = [1.25, 0, 1.25, 0.5, 0.5, 0.5, 0.5, 0, 1.25, 1.25, 0]
|
||||
self.entry_vulcan['port_pressure'] = [2.5, 2.5, 0, 0, 0.5, 0.5]
|
||||
del(self.entry_vulcan['operands'][1]['name'])
|
||||
self.entry_vulcan['operands'][1]['prefix'] = 'x'
|
||||
self.entry_zen1['port_pressure'] = [1, 1, 1, 1, 0, 1, 0, 0, 0, 0.5, 1, 0.5, 1]
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(self):
|
||||
if sys.exc_info() == (None, None, None):
|
||||
# Test successful, remove DB entries
|
||||
for arch in ['csx', 'vulcan', 'zen1']:
|
||||
lines = []
|
||||
with open(os.path.expanduser('~/.osaca/data/' + arch + '.yml'), 'r') as f:
|
||||
lines = f.readlines()
|
||||
with open(os.path.expanduser('~/.osaca/data/' + arch + '.yml'), 'w') as f:
|
||||
f.writelines([line for line in lines[:-24]])
|
||||
|
||||
###########
|
||||
# Tests
|
||||
###########
|
||||
|
||||
def test_add_single_entry(self):
|
||||
num_entries_csx = len(MachineModel('csx')['instruction_forms'])
|
||||
num_entries_vulcan = len(MachineModel('vulcan')['instruction_forms'])
|
||||
num_entries_zen1 = len(MachineModel('zen1')['instruction_forms'])
|
||||
|
||||
add_entry_to_db('csx', self.entry_csx)
|
||||
add_entry_to_db('vulcan', self.entry_vulcan)
|
||||
add_entry_to_db('zen1', self.entry_zen1)
|
||||
|
||||
num_entries_csx = len(MachineModel('csx')['instruction_forms']) - num_entries_csx
|
||||
num_entries_vulcan = len(MachineModel('vulcan')['instruction_forms']) - num_entries_vulcan
|
||||
num_entries_zen1 = len(MachineModel('zen1')['instruction_forms']) - num_entries_zen1
|
||||
|
||||
self.assertEqual(num_entries_csx, 1)
|
||||
self.assertEqual(num_entries_vulcan, 1)
|
||||
self.assertEqual(num_entries_zen1, 1)
|
||||
|
||||
def test_add_multiple_entries(self):
|
||||
num_entries_csx = len(MachineModel('csx')['instruction_forms'])
|
||||
num_entries_vulcan = len(MachineModel('vulcan')['instruction_forms'])
|
||||
num_entries_zen1 = len(MachineModel('zen1')['instruction_forms'])
|
||||
|
||||
entries_csx, entries_vulcan, entries_zen1 = [], [], []
|
||||
for i in range(2):
|
||||
self.entry_csx['name'] += '-'
|
||||
self.entry_vulcan['name'] += '-'
|
||||
self.entry_zen1['name'] += '-'
|
||||
entries_csx.append(copy.deepcopy(self.entry_csx))
|
||||
entries_vulcan.append(copy.deepcopy(self.entry_vulcan))
|
||||
entries_zen1.append(copy.deepcopy(self.entry_zen1))
|
||||
|
||||
add_entries_to_db('csx', entries_csx)
|
||||
add_entries_to_db('vulcan', entries_vulcan)
|
||||
add_entries_to_db('zen1', entries_zen1)
|
||||
|
||||
num_entries_csx = len(MachineModel('csx')['instruction_forms']) - num_entries_csx
|
||||
num_entries_vulcan = len(MachineModel('vulcan')['instruction_forms']) - num_entries_vulcan
|
||||
num_entries_zen1 = len(MachineModel('zen1')['instruction_forms']) - num_entries_zen1
|
||||
|
||||
self.assertEqual(num_entries_csx, 2)
|
||||
self.assertEqual(num_entries_vulcan, 2)
|
||||
self.assertEqual(num_entries_zen1, 2)
|
||||
|
||||
def test_sanity_check(self):
|
||||
# non-verbose
|
||||
sanity_check('csx', verbose=False)
|
||||
sanity_check('vulcan', verbose=False)
|
||||
sanity_check('zen1', verbose=False)
|
||||
# verbose
|
||||
sanity_check('csx', verbose=True)
|
||||
sanity_check('vulcan', verbose=True)
|
||||
sanity_check('zen1', verbose=True)
|
||||
|
||||
##################
|
||||
# Helper functions
|
||||
##################
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
suite = unittest.TestLoader().loadTestsFromTestCase(TestDBInterface)
|
||||
unittest.TextTestRunner(verbosity=2).run(suite)
|
||||
@@ -18,7 +18,8 @@ class TestFrontend(unittest.TestCase):
|
||||
os.path.dirname(os.path.split(os.path.abspath(__file__))[0]), 'osaca/data/'
|
||||
)
|
||||
|
||||
def setUp(self):
|
||||
@classmethod
|
||||
def setUpClass(self):
|
||||
# set up parser and kernels
|
||||
self.parser_x86 = ParserX86ATT()
|
||||
self.parser_AArch64 = ParserAArch64v81()
|
||||
|
||||
@@ -10,7 +10,8 @@ from osaca.parser import ParserAArch64v81, ParserX86ATT
|
||||
|
||||
|
||||
class TestMarkerUtils(unittest.TestCase):
|
||||
def setUp(self):
|
||||
@classmethod
|
||||
def setUpClass(self):
|
||||
self.parser_AArch = ParserAArch64v81()
|
||||
self.parser_x86 = ParserX86ATT()
|
||||
with open(self._find_file('triad-arm-iaca.s')) as f:
|
||||
|
||||
@@ -12,7 +12,8 @@ from osaca.parser import AttrDict, ParserAArch64v81
|
||||
|
||||
|
||||
class TestParserAArch64v81(unittest.TestCase):
|
||||
def setUp(self):
|
||||
@classmethod
|
||||
def setUpClass(self):
|
||||
self.parser = ParserAArch64v81()
|
||||
with open(self._find_file('triad-arm-iaca.s')) as f:
|
||||
self.triad_code = f.read()
|
||||
|
||||
@@ -12,7 +12,8 @@ from osaca.parser import AttrDict, ParserX86ATT
|
||||
|
||||
|
||||
class TestParserX86ATT(unittest.TestCase):
|
||||
def setUp(self):
|
||||
@classmethod
|
||||
def setUpClass(self):
|
||||
self.parser = ParserX86ATT()
|
||||
with open(self._find_file('triad-x86-iaca.s')) as f:
|
||||
self.triad_code = f.read()
|
||||
|
||||
@@ -21,7 +21,8 @@ class TestSemanticTools(unittest.TestCase):
|
||||
)
|
||||
USER_DATA_DIR = os.path.join(os.path.expanduser('~'), '.osaca/')
|
||||
|
||||
def setUp(self):
|
||||
@classmethod
|
||||
def setUpClass(self):
|
||||
# copy db files in user directory
|
||||
if not os.path.isdir(os.path.join(self.USER_DATA_DIR, 'data')):
|
||||
os.makedirs(os.path.join(self.USER_DATA_DIR, 'data'))
|
||||
@@ -50,6 +51,8 @@ class TestSemanticTools(unittest.TestCase):
|
||||
self.machine_model_tx2,
|
||||
path_to_yaml=os.path.join(self.MODULE_DATA_DIR, 'isa/aarch64.yml'),
|
||||
)
|
||||
self.machine_model_zen = MachineModel(arch='zen1')
|
||||
|
||||
for i in range(len(self.kernel_x86)):
|
||||
self.semantics_csx.assign_src_dst(self.kernel_x86[i])
|
||||
self.semantics_csx.assign_tp_lt(self.kernel_x86[i])
|
||||
@@ -85,6 +88,7 @@ class TestSemanticTools(unittest.TestCase):
|
||||
self.assertTrue('src_dst' in instruction_form['operands'])
|
||||
|
||||
def test_tp_lt_assignment_x86(self):
|
||||
self.assertTrue('ports' in self.machine_model_csx)
|
||||
port_num = len(self.machine_model_csx['ports'])
|
||||
for instruction_form in self.kernel_x86:
|
||||
with self.subTest(instruction_form=instruction_form):
|
||||
@@ -94,6 +98,7 @@ class TestSemanticTools(unittest.TestCase):
|
||||
self.assertEqual(len(instruction_form['port_pressure']), port_num)
|
||||
|
||||
def test_tp_lt_assignment_AArch64(self):
|
||||
self.assertTrue('ports' in self.machine_model_tx2)
|
||||
port_num = len(self.machine_model_tx2['ports'])
|
||||
for instruction_form in self.kernel_AArch64:
|
||||
with self.subTest(instruction_form=instruction_form):
|
||||
@@ -237,6 +242,48 @@ class TestSemanticTools(unittest.TestCase):
|
||||
self.assertTrue(dag.is_written(reg, instr_form_non_rw_1))
|
||||
self.assertTrue(dag.is_written(reg, instr_form_non_rw_1))
|
||||
|
||||
def test_invalid_MachineModel(self):
|
||||
with self.assertRaises(ValueError):
|
||||
MachineModel()
|
||||
with self.assertRaises(ValueError):
|
||||
MachineModel(arch='CSX', path_to_yaml=os.path.join(self.MODULE_DATA_DIR, 'csx.yml'))
|
||||
with self.assertRaises(ValueError):
|
||||
MachineModel(arch='THE_MACHINE')
|
||||
with self.assertRaises(ValueError):
|
||||
MachineModel(path_to_yaml=os.path.join(self.MODULE_DATA_DIR, 'THE_MACHINE.yml'))
|
||||
|
||||
def test_MachineModel_getter(self):
|
||||
sample_operands = [
|
||||
{
|
||||
'memory': {
|
||||
'offset': None,
|
||||
'base': {'name': 'r12'},
|
||||
'index': {'name': 'rcx'},
|
||||
'scale': 8,
|
||||
}
|
||||
}
|
||||
]
|
||||
self.assertIsNone(self.machine_model_csx.get_instruction('GETRESULT', sample_operands))
|
||||
self.assertIsNone(self.machine_model_tx2.get_instruction('GETRESULT', sample_operands))
|
||||
|
||||
self.assertEqual(self.machine_model_csx.get_arch(), 'CSX')
|
||||
self.assertEqual(self.machine_model_tx2.get_arch(), 'Vulcan')
|
||||
|
||||
self.assertEqual(self.machine_model_csx.get_ISA(), 'x86')
|
||||
self.assertEqual(self.machine_model_tx2.get_ISA(), 'AArch64')
|
||||
|
||||
ports_csx = ['0', '0DV', '1', '2', '2D', '3', '3D', '4', '5', '6', '7']
|
||||
data_ports_csx = ['2D', '3D']
|
||||
self.assertEqual(self.machine_model_csx.get_ports(), ports_csx)
|
||||
self.assertEqual(self.machine_model_csx.get_data_ports(), data_ports_csx)
|
||||
|
||||
self.assertFalse(self.machine_model_tx2.has_hidden_loads())
|
||||
self.assertTrue(self.machine_model_zen.has_hidden_loads())
|
||||
|
||||
self.assertEqual(MachineModel.get_isa_for_arch('CSX'), 'x86')
|
||||
self.assertEqual(MachineModel.get_isa_for_arch('VuLcAn'), 'aarch64')
|
||||
self.assertIsNone(MachineModel.get_isa_for_arch('THE_MACHINE'))
|
||||
|
||||
##################
|
||||
# Helper functions
|
||||
##################
|
||||
|
||||
Reference in New Issue
Block a user