autodetect ISA and default uarch for ISA

This commit is contained in:
JanLJL
2020-10-29 13:00:02 +01:00
parent 22e36f4870
commit bfd07a83a4
4 changed files with 61 additions and 6 deletions

View File

@@ -31,6 +31,10 @@ SUPPORTED_ARCHS = [
'N1',
'A64FX',
]
DEFAULT_ARCHS = {
'aarch64': 'A64FX',
'x86': 'ICL',
}
# Stolen from pip
@@ -85,7 +89,7 @@ def create_parser(parser=None):
'--arch',
type=str,
help='Define architecture (SNB, IVB, HSW, BDW, SKX, CSX, ICL, ZEN1, ZEN2, TX2, N1, '
'A64FX).',
'A64FX). If no architecture is given, OSACA assumes a default uarch for x86/AArch64.',
)
parser.add_argument(
'--fixed',
@@ -164,7 +168,12 @@ def check_arguments(args, parser):
"""
supported_import_files = ['ibench', 'asmbench']
if 'arch' in args and (args.arch is None or args.arch.upper() not in SUPPORTED_ARCHS):
if args.arch is None and (args.check_db or 'import_data' in args):
parser.error(
'DB check and data import cannot work with a default microarchitecture. '
'Please see --help for all valid architecture codes.'
)
elif args.arch is not None and args.arch.upper() not in SUPPORTED_ARCHS:
parser.error(
'Microarchitecture not supported. Please see --help for all valid architecture codes.'
)
@@ -241,13 +250,15 @@ def inspect(args, output_file=sys.stdout):
:param output_file: Define the stream for output, defaults to :class:`sys.stdout`
:type output_file: stream, optional
"""
arch = args.arch
# Read file
code = args.file.read()
# Detect ISA if necessary
arch = args.arch if args.arch is not None else DEFAULT_ARCHS[BaseParser.detect_ISA(code)]
isa = MachineModel.get_isa_for_arch(arch)
verbose = args.verbose
ignore_unknown = args.ignore_unknown
# Read file
code = args.file.read()
# Parse file
parser = get_asm_parser(arch)
parsed_code = parser.parse_file(code)

View File

@@ -1,6 +1,7 @@
#!/usr/bin/env python3
"""Parser superclass of specific parsers."""
import operator
import re
class BaseParser(object):
# Identifiers for operand types
@@ -18,6 +19,23 @@ class BaseParser(object):
def __init__(self):
self.construct_parser()
@staticmethod
def detect_ISA(file_content):
"""Detect the ISA of the assembly based on the used registers and return the ISA code."""
# Check for the amount of registers in the code to determine the ISA
# 1) Check for xmm, ymm, zmm, rax, rbx, rcx, and rdx registers in x86
heuristics_x86ATT = [r'%[xyz]mm[0-9]', r'%r[abcd]x[0-9]']
# 2) check for v and z vector registers and x/w general-purpose registers
heuristics_aarch64 = [r'[vz][0-9][0-9]?\.[0-9][0-9]?[bhsd]', r'[wx][0-9]']
matches = {'x86': 0, 'aarch64': 0}
for h in heuristics_x86ATT:
matches['x86'] += len(re.findall(h, file_content))
for h in heuristics_aarch64:
matches['aarch64'] += len(re.findall(h, file_content))
return max(matches.items(), key=operator.itemgetter(1))[0]
def parse_file(self, file_content, start_line=0):
"""
Parse assembly file. This includes *not* extracting of the marked kernel and

View File

@@ -18,6 +18,12 @@ class TestBaseParser(unittest.TestCase):
pass
with open(self._find_file('triad_x86_iaca.s')) as f:
self.triad_code = f.read()
with open(self._find_file('triad_arm_iaca.s')) as f:
self.triad_code_arm = f.read()
with open(self._find_file('kernel_x86.s')) as f:
self.x86_code = f.read()
with open(self._find_file('kernel_aarch64.s')) as f:
self.aarch64_code = f.read()
##################
# Test
@@ -59,6 +65,12 @@ class TestBaseParser(unittest.TestCase):
with self.assertRaises(NotImplementedError):
self.parser.normalize_imd(imd_hex_1)
def test_detect_ISA(self):
self.assertEqual(BaseParser.detect_ISA(self.triad_code), 'x86')
self.assertEqual(BaseParser.detect_ISA(self.triad_code_arm), 'aarch64')
self.assertEqual(BaseParser.detect_ISA(self.x86_code), 'x86')
self.assertEqual(BaseParser.detect_ISA(self.aarch64_code), 'aarch64')
##################
# Helper functions
##################

View File

@@ -153,6 +153,20 @@ class TestCLI(unittest.TestCase):
output = StringIO()
osaca.run(args, output_file=output)
def test_without_arch(self):
# Run test kernels without --arch flag
parser = osaca.create_parser()
# x86
kernel_x86 = 'kernel_x86.s'
args = parser.parse_args([self._find_test_file(kernel_x86)])
output = StringIO()
osaca.run(args, output_file=output)
# AArch64
kernel_aarch64 = 'kernel_aarch64.s'
args = parser.parse_args([self._find_test_file(kernel_aarch64)])
osaca.run(args, output_file=output)
##################
# Helper functions
##################