1#!/usr/bin/env python 2# Copyright 2019 Google LLC 3# 4# This source code is licensed under the BSD-style license found in the 5# LICENSE file in the root directory of this source tree. 6 7 8def _indent(text): 9 return "\n".join(map(lambda t: " " + t if t else t, text.splitlines())) 10 11 12def _remove_duplicate_newlines(text): 13 filtered_lines = list() 14 last_newline = False 15 for line in text.splitlines(): 16 is_newline = len(line.strip()) == 0 17 if not is_newline or not last_newline: 18 filtered_lines.append(line) 19 last_newline = is_newline 20 return "\n".join(filtered_lines) 21 22 23_ARCH_TO_MACRO_MAP = { 24 "aarch32": "XNN_ARCH_ARM", 25 "aarch64": "XNN_ARCH_ARM64", 26 "x86-32": "XNN_ARCH_X86", 27 "x86-64": "XNN_ARCH_X86_64", 28 "wasm": "XNN_ARCH_WASM", 29 "wasmsimd": "XNN_ARCH_WASMSIMD", 30 "wasmrelaxedsimd": "XNN_ARCH_WASMRELAXEDSIMD", 31} 32 33# Mapping from ISA extension to macro guarding build-time enabled/disabled 34# status for the ISA. Only ISAs that can be enabled/disabled have an entry. 35_ISA_TO_MACRO_MAP = { 36 "neonfp16arith": "XNN_ENABLE_ARM_FP16", 37 "neonbf16": "XNN_ENABLE_ARM_BF16", 38 "neondot": "XNN_ENABLE_ARM_DOTPROD", 39} 40 41_ISA_TO_ARCH_MAP = { 42 "armsimd32": ["aarch32"], 43 "neon": ["aarch32", "aarch64"], 44 "neonfp16": ["aarch32", "aarch64"], 45 "neonfma": ["aarch32", "aarch64"], 46 "neonv8": ["aarch32", "aarch64"], 47 "neonfp16arith": ["aarch32", "aarch64"], 48 "neonbf16": ["aarch32", "aarch64"], 49 "neondot": ["aarch32", "aarch64"], 50 "sse": ["x86-32", "x86-64"], 51 "sse2": ["x86-32", "x86-64"], 52 "ssse3": ["x86-32", "x86-64"], 53 "sse41": ["x86-32", "x86-64"], 54 "avx": ["x86-32", "x86-64"], 55 "f16c": ["x86-32", "x86-64"], 56 "xop": ["x86-32", "x86-64"], 57 "fma3": ["x86-32", "x86-64"], 58 "avx2": ["x86-32", "x86-64"], 59 "avx512f": ["x86-32", "x86-64"], 60 "avx512skx": ["x86-32", "x86-64"], 61 "wasm32": ["wasm", "wasmsimd"], 62 "wasm": ["wasm", "wasmsimd", "wasmrelaxedsimd"], 63 "wasmsimd": ["wasmsimd", "wasmrelaxedsimd"], 64 "wasmrelaxedsimd": ["wasmrelaxedsimd"], 65} 66 67_ISA_TO_CHECK_MAP = { 68 "armsimd32": "TEST_REQUIRES_ARM_SIMD32", 69 "neon": "TEST_REQUIRES_ARM_NEON", 70 "neonfp16": "TEST_REQUIRES_ARM_NEON_FP16", 71 "neonfma": "TEST_REQUIRES_ARM_NEON_FMA", 72 "neonv8": "TEST_REQUIRES_ARM_NEON_V8", 73 "neonfp16arith": "TEST_REQUIRES_ARM_NEON_FP16_ARITH", 74 "neonbf16": "TEST_REQUIRES_ARM_NEON_BF16", 75 "neondot": "TEST_REQUIRES_ARM_NEON_DOT", 76 "sse": "TEST_REQUIRES_X86_SSE", 77 "sse2": "TEST_REQUIRES_X86_SSE2", 78 "ssse3": "TEST_REQUIRES_X86_SSSE3", 79 "sse41": "TEST_REQUIRES_X86_SSE41", 80 "avx": "TEST_REQUIRES_X86_AVX", 81 "f16c": "TEST_REQUIRES_X86_F16C", 82 "xop": "TEST_REQUIRES_X86_XOP", 83 "avx2": "TEST_REQUIRES_X86_AVX2", 84 "fma3": "TEST_REQUIRES_X86_FMA3", 85 "avx512f": "TEST_REQUIRES_X86_AVX512F", 86 "avx512skx": "TEST_REQUIRES_X86_AVX512SKX", 87} 88 89 90def parse_target_name(target_name): 91 arch = list() 92 isa = None 93 for target_part in target_name.split("_"): 94 if target_part in _ARCH_TO_MACRO_MAP: 95 if target_part in _ISA_TO_ARCH_MAP: 96 arch = _ISA_TO_ARCH_MAP[target_part] 97 isa = target_part 98 else: 99 arch = [target_part] 100 elif target_part in _ISA_TO_ARCH_MAP: 101 isa = target_part 102 if isa and not arch: 103 arch = _ISA_TO_ARCH_MAP[isa] 104 105 return arch, isa 106 107 108def generate_isa_check_macro(isa): 109 return _ISA_TO_CHECK_MAP.get(isa, "") 110 111 112def arch_to_macro(arch, isa): 113 if arch == "aarch32" and isa == "neondot": 114 return _ARCH_TO_MACRO_MAP[arch] + " && !XNN_PLATFORM_IOS" 115 else: 116 return _ARCH_TO_MACRO_MAP[arch] 117 118 119def postprocess_test_case(test_case, arch, isa, assembly=False, jit=False): 120 test_case = _remove_duplicate_newlines(test_case) 121 if arch: 122 guard = " || ".join(arch_to_macro(a, isa) for a in arch) 123 if isa in _ISA_TO_MACRO_MAP: 124 if len(arch) > 1: 125 guard = "%s && (%s)" % (_ISA_TO_MACRO_MAP[isa], guard) 126 else: 127 guard = "%s && %s" % (_ISA_TO_MACRO_MAP[isa], guard) 128 if assembly: 129 guard += " && XNN_ENABLE_ASSEMBLY" 130 if jit: 131 guard += " && XNN_PLATFORM_JIT" 132 return "#if %s\n" % guard + _indent(test_case) + "\n" + \ 133 "#endif // %s\n" % guard 134 else: 135 return test_case 136