From 2d30d190f4cf99def33247f9a880a22ac9e00cde Mon Sep 17 00:00:00 2001 From: JanLJL Date: Wed, 26 Feb 2020 18:40:08 +0100 Subject: [PATCH] running examples for tests --- osaca/osaca.py | 7 ++-- tests/all_tests.py | 1 + tests/test_examples.py | 55 ++++++++++++++++++++++++++++++++ tests/test_files/test_db_x86.yml | 1 - tests/test_semantics.py | 20 +++++++++--- 5 files changed, 76 insertions(+), 8 deletions(-) create mode 100755 tests/test_examples.py diff --git a/osaca/osaca.py b/osaca/osaca.py index 722ebcc..08f5ffd 100755 --- a/osaca/osaca.py +++ b/osaca/osaca.py @@ -198,12 +198,13 @@ def insert_byte_marker(args): f.write(assembly) -def inspect(args): +def inspect(args, output_file=sys.stdout): """ Does the actual throughput and critical path analysis of OSACA and prints it to the terminal. :param args: arguments given from :class:`~argparse.ArgumentParser` after parsing + :param output_file: Define the stream for output, defaults to :class:`sys.stdout` """ arch = args.arch isa = MachineModel.get_isa_for_arch(arch) @@ -233,7 +234,7 @@ def inspect(args): frontend = Frontend(args.file.name, arch=arch) print(frontend.full_analysis( kernel, kernel_graph, ignore_unknown=ignore_unknown, verbose=verbose - )) + ), file=output_file) def run(args, output_file=sys.stdout): @@ -255,7 +256,7 @@ def run(args, output_file=sys.stdout): insert_byte_marker(args) else: # Analyze kernel - inspect(args) + inspect(args, output_file=output_file) def get_asm_parser(arch) -> BaseParser: diff --git a/tests/all_tests.py b/tests/all_tests.py index c4b711f..af1d87f 100755 --- a/tests/all_tests.py +++ b/tests/all_tests.py @@ -14,6 +14,7 @@ suite = unittest.TestLoader().loadTestsFromNames( 'test_frontend', 'test_db_interface', 'test_kerncraftAPI', + 'test_examples', ] ) diff --git a/tests/test_examples.py b/tests/test_examples.py new file mode 100755 index 0000000..1eeb1ea --- /dev/null +++ b/tests/test_examples.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 +""" +Unit tests for OSACA sample kernels in examples/ +""" + +import os +import unittest +from io import StringIO + +import osaca.osaca as osaca + + +class TestExamples(unittest.TestCase): + + ########### + # Tests + ########### + + def test_examples(self): + kernels = ['add', 'copy', 'daxpy', 'j2d', 'striad', 'sum_reduction', 'triad', 'update'] + archs = ['csx', 'tx2', 'zen1'] + comps = {'csx': ['gcc', 'icc'], 'tx2': ['gcc', 'clang'], 'zen1': ['gcc']} + parser = osaca.create_parser() + # Analyze all asm files resulting out of kernels, archs and comps + for k in kernels: + for a in archs: + for c in comps[a]: + with self.subTest(kernel=k, arch=a, comp=c): + args = parser.parse_args(['--arch', a, self._find_file(k, a, c)]) + output = StringIO() + osaca.run(args, output_file=output) + self.assertTrue('WARNING' not in output.getvalue()) + + ################## + # Helper functions + ################## + + @staticmethod + def _find_file(kernel, arch, comp): + testdir = os.path.dirname(__file__) + name = os.path.join( + testdir, + '../examples', + kernel, + kernel + '.s.' + arch[:3].lower() + '.' + comp.lower() + '.s', + ) + if kernel == 'j2d' and arch.lower() == 'csx': + name = name[:-1] + 'AVX.s' + assert os.path.exists(name) + return name + + +if __name__ == '__main__': + suite = unittest.TestLoader().loadTestsFromTestCase(TestExamples) + unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/tests/test_files/test_db_x86.yml b/tests/test_files/test_db_x86.yml index 5e1ffc9..8b40fee 100644 --- a/tests/test_files/test_db_x86.yml +++ b/tests/test_files/test_db_x86.yml @@ -5,7 +5,6 @@ isa: x86 ROB_size: 224 retired_uOps_per_cycle: 4 scheduler_size: 97 -hidden_loads: false load_latency: {gpr: 4.0, mm: 4.0, xmm: 4.0, ymm: 4.0, zmm: 4.0} load_throughput: - {base: gpr, offset: ~, index: ~, scale: 1, port_pressure: [[1, '23'], [1, ['2D', '3D']]]} diff --git a/tests/test_semantics.py b/tests/test_semantics.py index 368a791..82bb44c 100755 --- a/tests/test_semantics.py +++ b/tests/test_semantics.py @@ -135,13 +135,13 @@ class TestSemanticTools(unittest.TestCase): # test get_store_tp self.assertEqual( test_mm_x86.get_store_throughput( - {'base': 'x', 'offset': None, 'index': None, 'scale': 1} + {'base': {'name': 'x'}, 'offset': None, 'index': None, 'scale': 1} ), [[2, '237'], [2, '4']], ) self.assertEqual( test_mm_x86.get_store_throughput( - {'base': 'NOT_IN_DB', 'offset': None, 'index': 'NOT_NONE', 'scale': 1} + {'base': {'prefix': 'NOT_IN_DB'}, 'offset': None, 'index': 'NOT_NONE', 'scale': 1} ), [[1, '23'], [1, '4']], ) @@ -161,13 +161,13 @@ class TestSemanticTools(unittest.TestCase): # test get_store_lt self.assertEqual( test_mm_x86.get_store_latency( - {'base': 'x', 'offset': None, 'index': None, 'scale': '1'} + {'base': {'name': 'x'}, 'offset': None, 'index': None, 'scale': '1'} ), 0, ) self.assertEqual( test_mm_arm.get_store_latency( - {'base': 'x', 'offset': None, 'index': None, 'scale': '1'} + {'base': {'prefix': 'x'}, 'offset': None, 'index': None, 'scale': '1'} ), 0, ) @@ -175,6 +175,14 @@ class TestSemanticTools(unittest.TestCase): # test has_hidden_load self.assertFalse(test_mm_x86.has_hidden_loads()) + # test default load tp + self.assertEqual( + test_mm_x86.get_load_throughput( + {'base': {'name': 'x'}, 'offset': None, 'index': None, 'scale': 1} + ), + [[1, '23'], [1, ['2D', '3D']]] + ) + # test adding port test_mm_x86.add_port('dummyPort') test_mm_arm.add_port('dummyPort') @@ -262,6 +270,8 @@ class TestSemanticTools(unittest.TestCase): self.assertEqual(len(list(dg.get_dependent_instruction_forms(line_number=8))), 0) with self.assertRaises(ValueError): dg.get_dependent_instruction_forms() + # test dot creation + dg.export_graph(filepath='/dev/null') def test_kernelDG_AArch64(self): dg = KernelDG(self.kernel_AArch64, self.parser_AArch64, self.machine_model_tx2) @@ -286,6 +296,8 @@ class TestSemanticTools(unittest.TestCase): self.assertEqual(len(list(dg.get_dependent_instruction_forms(line_number=20))), 0) with self.assertRaises(ValueError): dg.get_dependent_instruction_forms() + # test dot creation + dg.export_graph(filepath='/dev/null') def test_hidden_load(self): machine_model_hld = MachineModel(