mirror of
https://github.com/RRZE-HPC/OSACA.git
synced 2025-12-13 07:30:06 +01:00
173 lines
7.4 KiB
Python
Executable File
173 lines
7.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
Unit tests for OSACA Frontend
|
|
"""
|
|
|
|
import os
|
|
import unittest
|
|
|
|
from osaca.frontend import Frontend
|
|
from osaca.parser import ParserAArch64, ParserX86ATT
|
|
from osaca.semantics import ArchSemantics, KernelDG, MachineModel, reduce_to_section
|
|
|
|
|
|
class TestFrontend(unittest.TestCase):
|
|
MODULE_DATA_DIR = os.path.join(
|
|
os.path.dirname(os.path.split(os.path.abspath(__file__))[0]), "osaca/data/"
|
|
)
|
|
|
|
@classmethod
|
|
def setUpClass(self):
|
|
# set up parser and kernels
|
|
self.parser_x86 = ParserX86ATT()
|
|
self.parser_AArch64 = ParserAArch64()
|
|
with open(self._find_file("kernel_x86.s")) as f:
|
|
code_x86 = f.read()
|
|
with open(self._find_file("kernel_aarch64.s")) as f:
|
|
code_AArch64 = f.read()
|
|
self.kernel_x86 = self.parser_x86.parse_file(code_x86)
|
|
self.kernel_AArch64 = self.parser_AArch64.parse_file(code_AArch64)
|
|
|
|
# set up machine models
|
|
self.machine_model_csx = MachineModel(
|
|
path_to_yaml=os.path.join(self.MODULE_DATA_DIR, "csx.yml")
|
|
)
|
|
self.machine_model_tx2 = MachineModel(arch="tx2")
|
|
self.semantics_csx = ArchSemantics(
|
|
self.parser_x86,
|
|
self.machine_model_csx,
|
|
path_to_yaml=os.path.join(self.MODULE_DATA_DIR, "isa/x86.yml"),
|
|
)
|
|
self.semantics_tx2 = ArchSemantics(
|
|
self.parser_AArch64,
|
|
self.machine_model_tx2,
|
|
path_to_yaml=os.path.join(self.MODULE_DATA_DIR, "isa/aarch64.yml"),
|
|
)
|
|
|
|
self.semantics_csx.normalize_instruction_forms(self.kernel_x86)
|
|
self.semantics_tx2.normalize_instruction_forms(self.kernel_AArch64)
|
|
|
|
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])
|
|
for i in range(len(self.kernel_AArch64)):
|
|
self.semantics_tx2.assign_src_dst(self.kernel_AArch64[i])
|
|
self.semantics_tx2.assign_tp_lt(self.kernel_AArch64[i])
|
|
|
|
###########
|
|
# Tests
|
|
###########
|
|
|
|
def test_frontend_creation(self):
|
|
with self.assertRaises(ValueError):
|
|
Frontend()
|
|
with self.assertRaises(ValueError):
|
|
Frontend(arch="csx", path_to_yaml=os.path.join(self.MODULE_DATA_DIR, "csx.yml"))
|
|
with self.assertRaises(FileNotFoundError):
|
|
Frontend(path_to_yaml=os.path.join(self.MODULE_DATA_DIR, "THE_MACHINE.yml"))
|
|
with self.assertRaises(FileNotFoundError):
|
|
Frontend(arch="THE_MACHINE")
|
|
Frontend(arch="zen1")
|
|
|
|
def test_frontend_x86(self):
|
|
dg = KernelDG(self.kernel_x86, self.parser_x86, self.machine_model_csx, self.semantics_csx)
|
|
fe = Frontend(path_to_yaml=os.path.join(self.MODULE_DATA_DIR, "csx.yml"))
|
|
fe.throughput_analysis(self.kernel_x86, show_cmnts=False)
|
|
fe.latency_analysis(dg.get_critical_path())
|
|
# TODO compare output with checked string
|
|
|
|
def test_frontend_AArch64(self):
|
|
dg = KernelDG(
|
|
self.kernel_AArch64,
|
|
self.parser_AArch64,
|
|
self.machine_model_tx2,
|
|
self.semantics_tx2,
|
|
)
|
|
fe = Frontend(path_to_yaml=os.path.join(self.MODULE_DATA_DIR, "tx2.yml"))
|
|
fe.full_analysis(self.kernel_AArch64, dg, verbose=True)
|
|
# TODO compare output with checked string
|
|
|
|
def test_dict_output_x86(self):
|
|
dg = KernelDG(self.kernel_x86, self.parser_x86, self.machine_model_csx, self.semantics_csx)
|
|
fe = Frontend(path_to_yaml=os.path.join(self.MODULE_DATA_DIR, "csx.yml"))
|
|
analysis_dict = fe.full_analysis_dict(self.kernel_x86, dg)
|
|
self.assertEqual(len(self.kernel_x86), len(analysis_dict["Kernel"]))
|
|
self.assertEqual("csx", analysis_dict["Header"]["Architecture"])
|
|
self.assertEqual(len(analysis_dict["Warnings"]), 0)
|
|
for i, line in enumerate(self.kernel_x86):
|
|
self.assertEqual(line.throughput, analysis_dict["Kernel"][i]["Throughput"])
|
|
self.assertEqual(line.latency, analysis_dict["Kernel"][i]["Latency"])
|
|
self.assertEqual(
|
|
line.latency_wo_load, analysis_dict["Kernel"][i]["LatencyWithoutLoad"]
|
|
)
|
|
self.assertEqual(line.latency_cp, analysis_dict["Kernel"][i]["LatencyCP"])
|
|
self.assertEqual(line.mnemonic, analysis_dict["Kernel"][i]["Instruction"])
|
|
self.assertEqual(len(line.operands), len(analysis_dict["Kernel"][i]["Operands"]))
|
|
self.assertEqual(
|
|
len(line.semantic_operands["source"]),
|
|
len(analysis_dict["Kernel"][i]["SemanticOperands"]["source"]),
|
|
)
|
|
self.assertEqual(
|
|
len(line.semantic_operands["destination"]),
|
|
len(analysis_dict["Kernel"][i]["SemanticOperands"]["destination"]),
|
|
)
|
|
self.assertEqual(
|
|
len(line.semantic_operands["src_dst"]),
|
|
len(analysis_dict["Kernel"][i]["SemanticOperands"]["src_dst"]),
|
|
)
|
|
self.assertEqual(line.flags, analysis_dict["Kernel"][i]["Flags"])
|
|
self.assertEqual(line.line_number, analysis_dict["Kernel"][i]["LineNumber"])
|
|
|
|
def test_dict_output_AArch64(self):
|
|
reduced_kernel = reduce_to_section(self.kernel_AArch64, self.parser_AArch64)
|
|
dg = KernelDG(
|
|
reduced_kernel,
|
|
self.parser_AArch64,
|
|
self.machine_model_tx2,
|
|
self.semantics_tx2,
|
|
)
|
|
fe = Frontend(path_to_yaml=os.path.join(self.MODULE_DATA_DIR, "tx2.yml"))
|
|
analysis_dict = fe.full_analysis_dict(reduced_kernel, dg)
|
|
self.assertEqual(len(reduced_kernel), len(analysis_dict["Kernel"]))
|
|
self.assertEqual("tx2", analysis_dict["Header"]["Architecture"])
|
|
self.assertEqual(len(analysis_dict["Warnings"]), 0)
|
|
for i, line in enumerate(reduced_kernel):
|
|
self.assertEqual(line.throughput, analysis_dict["Kernel"][i]["Throughput"])
|
|
self.assertEqual(line.latency, analysis_dict["Kernel"][i]["Latency"])
|
|
self.assertEqual(
|
|
line.latency_wo_load, analysis_dict["Kernel"][i]["LatencyWithoutLoad"]
|
|
)
|
|
self.assertEqual(line.latency_cp, analysis_dict["Kernel"][i]["LatencyCP"])
|
|
self.assertEqual(line.mnemonic, analysis_dict["Kernel"][i]["Instruction"])
|
|
self.assertEqual(len(line.operands), len(analysis_dict["Kernel"][i]["Operands"]))
|
|
self.assertEqual(
|
|
len(line.semantic_operands["source"]),
|
|
len(analysis_dict["Kernel"][i]["SemanticOperands"]["source"]),
|
|
)
|
|
self.assertEqual(
|
|
len(line.semantic_operands["destination"]),
|
|
len(analysis_dict["Kernel"][i]["SemanticOperands"]["destination"]),
|
|
)
|
|
self.assertEqual(
|
|
len(line.semantic_operands["src_dst"]),
|
|
len(analysis_dict["Kernel"][i]["SemanticOperands"]["src_dst"]),
|
|
)
|
|
self.assertEqual(line.flags, analysis_dict["Kernel"][i]["Flags"])
|
|
self.assertEqual(line.line_number, analysis_dict["Kernel"][i]["LineNumber"])
|
|
|
|
##################
|
|
# Helper functions
|
|
##################
|
|
|
|
@staticmethod
|
|
def _find_file(name):
|
|
testdir = os.path.dirname(__file__)
|
|
name = os.path.join(testdir, "test_files", name)
|
|
assert os.path.exists(name)
|
|
return name
|
|
|
|
|
|
if __name__ == "__main__":
|
|
suite = unittest.TestLoader().loadTestsFromTestCase(TestFrontend)
|
|
unittest.TextTestRunner(verbosity=2).run(suite)
|