diff --git a/mlir_exercises/lit.site.cfg.py.in b/mlir_exercises/lit.site.cfg.py.in index a2e11168c1d..343496b20af 100755 --- a/mlir_exercises/lit.site.cfg.py.in +++ b/mlir_exercises/lit.site.cfg.py.in @@ -11,53 +11,53 @@ import sys import lit.util -config.host_triple = "@LLVM_HOST_TRIPLE@" -config.target_triple = "@TARGET_TRIPLE@" -config.llvm_src_root = "@LLVM_SOURCE_DIR@" -config.llvm_obj_root = "@LLVM_BINARY_DIR@" -config.llvm_tools_dir = "@LLVM_TOOLS_DIR@" -config.llvm_lib_dir = "@LLVM_LIBRARY_DIR@" -config.llvm_shlib_dir = "@SHLIBDIR@" -config.llvm_shlib_ext = "@SHLIBEXT@" -config.llvm_exe_ext = "@EXEEXT@" -config.peano_install_dir = "@PEANO_INSTALL_DIR@" -config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@" -config.python_executable = "@Python3_EXECUTABLE@" -config.gold_executable = "@GOLD_EXECUTABLE@" -config.ld64_executable = "@LD64_EXECUTABLE@" +config.host_triple = r"""@LLVM_HOST_TRIPLE@""" +config.target_triple = r"""@TARGET_TRIPLE@""" +config.llvm_src_root = r"""@LLVM_SOURCE_DIR@""" +config.llvm_obj_root = r"""@LLVM_BINARY_DIR@""" +config.llvm_tools_dir = r"""@LLVM_TOOLS_DIR@""" +config.llvm_lib_dir = r"""@LLVM_LIBRARY_DIR@""" +config.llvm_shlib_dir = r"""@SHLIBDIR@""" +config.llvm_shlib_ext = r"""@SHLIBEXT@""" +config.llvm_exe_ext = r"""@EXEEXT@""" +config.peano_install_dir = r"""@PEANO_INSTALL_DIR@""" +config.lit_tools_dir = r"""@LLVM_LIT_TOOLS_DIR@""" +config.python_executable = r"""@Python3_EXECUTABLE@""" +config.gold_executable = r"""@GOLD_EXECUTABLE@""" +config.ld64_executable = r"""@LD64_EXECUTABLE@""" config.enable_shared = @ENABLE_SHARED@ config.enable_assertions = @ENABLE_ASSERTIONS@ -config.targets_to_build = "@TARGETS_TO_BUILD@" -config.native_target = "@LLVM_NATIVE_ARCH@" -config.llvm_bindings = "@LLVM_BINDINGS@".split(' ') -config.host_os = "@HOST_OS@" -config.host_cc = "@HOST_CC@" -config.host_cxx = "@HOST_CXX@" -# Note: ldflags can contain double-quoted paths, so must use single quotes here. -config.host_ldflags = '@HOST_LDFLAGS@' -config.llvm_use_sanitizer = "@LLVM_USE_SANITIZER@" -config.llvm_host_triple = '@LLVM_HOST_TRIPLE@' -config.host_arch = "@HOST_ARCH@" +config.targets_to_build = r"""@TARGETS_TO_BUILD@""" +config.native_target = r"""@LLVM_NATIVE_ARCH@""" +config.llvm_bindings = r"""@LLVM_BINDINGS@""".split(' ') +config.host_os = r"""@HOST_OS@""" +config.host_cc = r"""@HOST_CC@""" +config.host_cxx = r"""@HOST_CXX@""" +# Use a raw triple-quoted string so Windows backslashes and embedded quotes survive. +config.host_ldflags = r"""@HOST_LDFLAGS@""" +config.llvm_use_sanitizer = r"""@LLVM_USE_SANITIZER@""" +config.llvm_host_triple = r"""@LLVM_HOST_TRIPLE@""" +config.host_arch = r"""@HOST_ARCH@""" -config.aie_src_root = "@AIE_SOURCE_DIR@" -config.aie_obj_root = "@AIE_BINARY_DIR@" +config.aie_src_root = r"""@AIE_SOURCE_DIR@""" +config.aie_obj_root = r"""@AIE_BINARY_DIR@""" # test_exec_root: The root path where tests should be run. -config.test_exec_root = "@CMAKE_CURRENT_BINARY_DIR@" +config.test_exec_root = r"""@CMAKE_CURRENT_BINARY_DIR@""" # pass on vitis settings config.enable_chess_tests = @CONFIG_ENABLE_CHESS_TESTS@ config.enable_board_tests = @CONFIG_ENABLE_BOARD_TESTS@ -config.vitis_root = "@VITIS_ROOT@" -config.vitis_aietools_dir = "@VITIS_AIETOOLS_DIR@" -config.vitis_sysroot = "@Sysroot@" -config.extraAieCcFlags = "@extraAieCcFlags@" -config.aieHostTarget = "@AIE_RUNTIME_TEST_TARGET@" -config.aieInstallPrefix = "@CMAKE_INSTALL_PREFIX@" +config.vitis_root = r"""@VITIS_ROOT@""" +config.vitis_aietools_dir = r"""@VITIS_AIETOOLS_DIR@""" +config.vitis_sysroot = r"""@Sysroot@""" +config.extraAieCcFlags = r"""@extraAieCcFlags@""" +config.aieHostTarget = r"""@AIE_RUNTIME_TEST_TARGET@""" +config.aieInstallPrefix = r"""@CMAKE_INSTALL_PREFIX@""" config.vitis_components = [] -if lit.util.pythonize_bool("@AIETools_AIE_FOUND@"): +if lit.util.pythonize_bool(r"""@AIETools_AIE_FOUND@"""): config.vitis_components.append("AIE") -if lit.util.pythonize_bool("@AIETools_AIE2_FOUND@"): +if lit.util.pythonize_bool(r"""@AIETools_AIE2_FOUND@"""): config.vitis_components.append("AIE2") # Support substitution of the tools_dir with user parameters. This is @@ -70,10 +70,10 @@ except KeyError: key, = e.args lit_config.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key)) -config.aie_include_integration_tests = "@AIE_INCLUDE_INTEGRATION_TESTS@" +config.aie_include_integration_tests = r"""@AIE_INCLUDE_INTEGRATION_TESTS@""" import lit.llvm lit.llvm.initialize(lit_config, config) # Let the main config do the real work. -lit_config.load_config(config, "@PROJECT_SOURCE_DIR@/lit.cfg.py") +lit_config.load_config(config, r"""@PROJECT_SOURCE_DIR@/lit.cfg.py""") diff --git a/programming_examples/lit.site.cfg.py.in b/programming_examples/lit.site.cfg.py.in index 3ba7a457f11..ca6152bd98f 100755 --- a/programming_examples/lit.site.cfg.py.in +++ b/programming_examples/lit.site.cfg.py.in @@ -11,65 +11,65 @@ import sys import lit.util -config.host_triple = "@LLVM_HOST_TRIPLE@" -config.target_triple = "@TARGET_TRIPLE@" -config.llvm_src_root = "@LLVM_SOURCE_DIR@" -config.llvm_obj_root = "@LLVM_BINARY_DIR@" -config.llvm_tools_dir = "@LLVM_TOOLS_DIR@" -config.llvm_lib_dir = "@LLVM_LIBRARY_DIR@" -config.llvm_shlib_dir = "@SHLIBDIR@" -config.llvm_shlib_ext = "@SHLIBEXT@" -config.llvm_exe_ext = "@EXEEXT@" -config.peano_install_dir = "@PEANO_INSTALL_DIR@" -config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@" -config.python_executable = "@Python3_EXECUTABLE@" -config.gold_executable = "@GOLD_EXECUTABLE@" -config.ld64_executable = "@LD64_EXECUTABLE@" +config.host_triple = r"""@LLVM_HOST_TRIPLE@""" +config.target_triple = r"""@TARGET_TRIPLE@""" +config.llvm_src_root = r"""@LLVM_SOURCE_DIR@""" +config.llvm_obj_root = r"""@LLVM_BINARY_DIR@""" +config.llvm_tools_dir = r"""@LLVM_TOOLS_DIR@""" +config.llvm_lib_dir = r"""@LLVM_LIBRARY_DIR@""" +config.llvm_shlib_dir = r"""@SHLIBDIR@""" +config.llvm_shlib_ext = r"""@SHLIBEXT@""" +config.llvm_exe_ext = r"""@EXEEXT@""" +config.peano_install_dir = r"""@PEANO_INSTALL_DIR@""" +config.lit_tools_dir = r"""@LLVM_LIT_TOOLS_DIR@""" +config.python_executable = r"""@Python3_EXECUTABLE@""" +config.gold_executable = r"""@GOLD_EXECUTABLE@""" +config.ld64_executable = r"""@LD64_EXECUTABLE@""" config.enable_shared = @ENABLE_SHARED@ config.enable_assertions = @ENABLE_ASSERTIONS@ -config.targets_to_build = "@TARGETS_TO_BUILD@" -config.native_target = "@LLVM_NATIVE_ARCH@" -config.llvm_bindings = "@LLVM_BINDINGS@".split(' ') -config.host_os = "@HOST_OS@" -config.host_cc = "@HOST_CC@" -config.host_cxx = "@HOST_CXX@" -# Note: ldflags can contain double-quoted paths, so must use single quotes here. -config.host_ldflags = '@HOST_LDFLAGS@' -config.llvm_use_sanitizer = "@LLVM_USE_SANITIZER@" -config.llvm_host_triple = '@LLVM_HOST_TRIPLE@' -config.host_arch = "@HOST_ARCH@" -config.xrt_dir = "@XRT_DIR@" -config.xrt_bin_dir = "@XRT_BIN_DIR@" -config.xrt_lib_dir = "@XRT_LIB_DIR@" -config.xrt_include_dir = "@XRT_INCLUDE_DIR@" -config.opencv_libs = "@OpenCV_LIBS@" -config.opencv_lib_dir = "@OpenCV_LIB_PATH@" -config.opencv_include_dir = "@OpenCV_INCLUDE_DIRS@" +config.targets_to_build = r"""@TARGETS_TO_BUILD@""" +config.native_target = r"""@LLVM_NATIVE_ARCH@""" +config.llvm_bindings = r"""@LLVM_BINDINGS@""".split(' ') +config.host_os = r"""@HOST_OS@""" +config.host_cc = r"""@HOST_CC@""" +config.host_cxx = r"""@HOST_CXX@""" +# Use a raw triple-quoted string so Windows backslashes and embedded quotes survive. +config.host_ldflags = r"""@HOST_LDFLAGS@""" +config.llvm_use_sanitizer = r"""@LLVM_USE_SANITIZER@""" +config.llvm_host_triple = r"""@LLVM_HOST_TRIPLE@""" +config.host_arch = r"""@HOST_ARCH@""" +config.xrt_dir = r"""@XRT_DIR@""" +config.xrt_bin_dir = r"""@XRT_BIN_DIR@""" +config.xrt_lib_dir = r"""@XRT_LIB_DIR@""" +config.xrt_include_dir = r"""@XRT_INCLUDE_DIR@""" +config.opencv_libs = r"""@OpenCV_LIBS@""" +config.opencv_lib_dir = r"""@OpenCV_LIB_PATH@""" +config.opencv_include_dir = r"""@OpenCV_INCLUDE_DIRS@""" -config.aie_src_root = "@AIE_SOURCE_DIR@" -config.aie_obj_root = "@AIE_BINARY_DIR@" +config.aie_src_root = r"""@AIE_SOURCE_DIR@""" +config.aie_obj_root = r"""@AIE_BINARY_DIR@""" # test_exec_root: The root path where tests should be run. -config.test_exec_root = "@CMAKE_CURRENT_BINARY_DIR@" +config.test_exec_root = r"""@CMAKE_CURRENT_BINARY_DIR@""" -config.hsa_dir = "@hsa-runtime64_DIR@" -config.hsa_found = lit.util.pythonize_bool("@hsa-runtime64_FOUND@") +config.hsa_dir = r"""@hsa-runtime64_DIR@""" +config.hsa_found = lit.util.pythonize_bool(r"""@hsa-runtime64_FOUND@""") # pass on vitis settings config.enable_chess_tests = @CONFIG_ENABLE_CHESS_TESTS@ config.enable_board_tests = @CONFIG_ENABLE_BOARD_TESTS@ -config.vitis_root = "@VITIS_ROOT@" -config.vitis_aietools_dir = "@VITIS_AIETOOLS_DIR@" -config.vitis_sysroot = "@Sysroot@" -config.extraAieCcFlags = "@extraAieCcFlags@" -config.aieHostTarget = "@AIE_RUNTIME_TEST_TARGET@" -config.aieInstallPrefix = "@CMAKE_INSTALL_PREFIX@" +config.vitis_root = r"""@VITIS_ROOT@""" +config.vitis_aietools_dir = r"""@VITIS_AIETOOLS_DIR@""" +config.vitis_sysroot = r"""@Sysroot@""" +config.extraAieCcFlags = r"""@extraAieCcFlags@""" +config.aieHostTarget = r"""@AIE_RUNTIME_TEST_TARGET@""" +config.aieInstallPrefix = r"""@CMAKE_INSTALL_PREFIX@""" config.vitis_components = [] -if lit.util.pythonize_bool("@AIETools_AIE_FOUND@"): +if lit.util.pythonize_bool(r"""@AIETools_AIE_FOUND@"""): config.vitis_components.append("AIE") -if lit.util.pythonize_bool("@AIETools_AIE2_FOUND@"): +if lit.util.pythonize_bool(r"""@AIETools_AIE2_FOUND@"""): config.vitis_components.append("AIE2") -if lit.util.pythonize_bool("@AIETools_AIE2P_FOUND@"): +if lit.util.pythonize_bool(r"""@AIETools_AIE2P_FOUND@"""): config.vitis_components.append("AIE2P") # Support substitution of the tools_dir with user parameters. This is @@ -82,10 +82,10 @@ except KeyError: key, = e.args lit_config.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key)) -config.aie_include_integration_tests = "@AIE_INCLUDE_INTEGRATION_TESTS@" +config.aie_include_integration_tests = r"""@AIE_INCLUDE_INTEGRATION_TESTS@""" import lit.llvm lit.llvm.initialize(lit_config, config) # Let the main config do the real work. -lit_config.load_config(config, "@PROJECT_SOURCE_DIR@/lit.cfg.py") +lit_config.load_config(config, r"""@PROJECT_SOURCE_DIR@/lit.cfg.py""") diff --git a/programming_guide/lit.site.cfg.py.in b/programming_guide/lit.site.cfg.py.in index 3ba7a457f11..ca6152bd98f 100755 --- a/programming_guide/lit.site.cfg.py.in +++ b/programming_guide/lit.site.cfg.py.in @@ -11,65 +11,65 @@ import sys import lit.util -config.host_triple = "@LLVM_HOST_TRIPLE@" -config.target_triple = "@TARGET_TRIPLE@" -config.llvm_src_root = "@LLVM_SOURCE_DIR@" -config.llvm_obj_root = "@LLVM_BINARY_DIR@" -config.llvm_tools_dir = "@LLVM_TOOLS_DIR@" -config.llvm_lib_dir = "@LLVM_LIBRARY_DIR@" -config.llvm_shlib_dir = "@SHLIBDIR@" -config.llvm_shlib_ext = "@SHLIBEXT@" -config.llvm_exe_ext = "@EXEEXT@" -config.peano_install_dir = "@PEANO_INSTALL_DIR@" -config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@" -config.python_executable = "@Python3_EXECUTABLE@" -config.gold_executable = "@GOLD_EXECUTABLE@" -config.ld64_executable = "@LD64_EXECUTABLE@" +config.host_triple = r"""@LLVM_HOST_TRIPLE@""" +config.target_triple = r"""@TARGET_TRIPLE@""" +config.llvm_src_root = r"""@LLVM_SOURCE_DIR@""" +config.llvm_obj_root = r"""@LLVM_BINARY_DIR@""" +config.llvm_tools_dir = r"""@LLVM_TOOLS_DIR@""" +config.llvm_lib_dir = r"""@LLVM_LIBRARY_DIR@""" +config.llvm_shlib_dir = r"""@SHLIBDIR@""" +config.llvm_shlib_ext = r"""@SHLIBEXT@""" +config.llvm_exe_ext = r"""@EXEEXT@""" +config.peano_install_dir = r"""@PEANO_INSTALL_DIR@""" +config.lit_tools_dir = r"""@LLVM_LIT_TOOLS_DIR@""" +config.python_executable = r"""@Python3_EXECUTABLE@""" +config.gold_executable = r"""@GOLD_EXECUTABLE@""" +config.ld64_executable = r"""@LD64_EXECUTABLE@""" config.enable_shared = @ENABLE_SHARED@ config.enable_assertions = @ENABLE_ASSERTIONS@ -config.targets_to_build = "@TARGETS_TO_BUILD@" -config.native_target = "@LLVM_NATIVE_ARCH@" -config.llvm_bindings = "@LLVM_BINDINGS@".split(' ') -config.host_os = "@HOST_OS@" -config.host_cc = "@HOST_CC@" -config.host_cxx = "@HOST_CXX@" -# Note: ldflags can contain double-quoted paths, so must use single quotes here. -config.host_ldflags = '@HOST_LDFLAGS@' -config.llvm_use_sanitizer = "@LLVM_USE_SANITIZER@" -config.llvm_host_triple = '@LLVM_HOST_TRIPLE@' -config.host_arch = "@HOST_ARCH@" -config.xrt_dir = "@XRT_DIR@" -config.xrt_bin_dir = "@XRT_BIN_DIR@" -config.xrt_lib_dir = "@XRT_LIB_DIR@" -config.xrt_include_dir = "@XRT_INCLUDE_DIR@" -config.opencv_libs = "@OpenCV_LIBS@" -config.opencv_lib_dir = "@OpenCV_LIB_PATH@" -config.opencv_include_dir = "@OpenCV_INCLUDE_DIRS@" +config.targets_to_build = r"""@TARGETS_TO_BUILD@""" +config.native_target = r"""@LLVM_NATIVE_ARCH@""" +config.llvm_bindings = r"""@LLVM_BINDINGS@""".split(' ') +config.host_os = r"""@HOST_OS@""" +config.host_cc = r"""@HOST_CC@""" +config.host_cxx = r"""@HOST_CXX@""" +# Use a raw triple-quoted string so Windows backslashes and embedded quotes survive. +config.host_ldflags = r"""@HOST_LDFLAGS@""" +config.llvm_use_sanitizer = r"""@LLVM_USE_SANITIZER@""" +config.llvm_host_triple = r"""@LLVM_HOST_TRIPLE@""" +config.host_arch = r"""@HOST_ARCH@""" +config.xrt_dir = r"""@XRT_DIR@""" +config.xrt_bin_dir = r"""@XRT_BIN_DIR@""" +config.xrt_lib_dir = r"""@XRT_LIB_DIR@""" +config.xrt_include_dir = r"""@XRT_INCLUDE_DIR@""" +config.opencv_libs = r"""@OpenCV_LIBS@""" +config.opencv_lib_dir = r"""@OpenCV_LIB_PATH@""" +config.opencv_include_dir = r"""@OpenCV_INCLUDE_DIRS@""" -config.aie_src_root = "@AIE_SOURCE_DIR@" -config.aie_obj_root = "@AIE_BINARY_DIR@" +config.aie_src_root = r"""@AIE_SOURCE_DIR@""" +config.aie_obj_root = r"""@AIE_BINARY_DIR@""" # test_exec_root: The root path where tests should be run. -config.test_exec_root = "@CMAKE_CURRENT_BINARY_DIR@" +config.test_exec_root = r"""@CMAKE_CURRENT_BINARY_DIR@""" -config.hsa_dir = "@hsa-runtime64_DIR@" -config.hsa_found = lit.util.pythonize_bool("@hsa-runtime64_FOUND@") +config.hsa_dir = r"""@hsa-runtime64_DIR@""" +config.hsa_found = lit.util.pythonize_bool(r"""@hsa-runtime64_FOUND@""") # pass on vitis settings config.enable_chess_tests = @CONFIG_ENABLE_CHESS_TESTS@ config.enable_board_tests = @CONFIG_ENABLE_BOARD_TESTS@ -config.vitis_root = "@VITIS_ROOT@" -config.vitis_aietools_dir = "@VITIS_AIETOOLS_DIR@" -config.vitis_sysroot = "@Sysroot@" -config.extraAieCcFlags = "@extraAieCcFlags@" -config.aieHostTarget = "@AIE_RUNTIME_TEST_TARGET@" -config.aieInstallPrefix = "@CMAKE_INSTALL_PREFIX@" +config.vitis_root = r"""@VITIS_ROOT@""" +config.vitis_aietools_dir = r"""@VITIS_AIETOOLS_DIR@""" +config.vitis_sysroot = r"""@Sysroot@""" +config.extraAieCcFlags = r"""@extraAieCcFlags@""" +config.aieHostTarget = r"""@AIE_RUNTIME_TEST_TARGET@""" +config.aieInstallPrefix = r"""@CMAKE_INSTALL_PREFIX@""" config.vitis_components = [] -if lit.util.pythonize_bool("@AIETools_AIE_FOUND@"): +if lit.util.pythonize_bool(r"""@AIETools_AIE_FOUND@"""): config.vitis_components.append("AIE") -if lit.util.pythonize_bool("@AIETools_AIE2_FOUND@"): +if lit.util.pythonize_bool(r"""@AIETools_AIE2_FOUND@"""): config.vitis_components.append("AIE2") -if lit.util.pythonize_bool("@AIETools_AIE2P_FOUND@"): +if lit.util.pythonize_bool(r"""@AIETools_AIE2P_FOUND@"""): config.vitis_components.append("AIE2P") # Support substitution of the tools_dir with user parameters. This is @@ -82,10 +82,10 @@ except KeyError: key, = e.args lit_config.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key)) -config.aie_include_integration_tests = "@AIE_INCLUDE_INTEGRATION_TESTS@" +config.aie_include_integration_tests = r"""@AIE_INCLUDE_INTEGRATION_TESTS@""" import lit.llvm lit.llvm.initialize(lit_config, config) # Let the main config do the real work. -lit_config.load_config(config, "@PROJECT_SOURCE_DIR@/lit.cfg.py") +lit_config.load_config(config, r"""@PROJECT_SOURCE_DIR@/lit.cfg.py""") diff --git a/python/aie_lit_utils/lit_config_helpers.py b/python/aie_lit_utils/lit_config_helpers.py index 98ab9880afb..4c7a2db9841 100644 --- a/python/aie_lit_utils/lit_config_helpers.py +++ b/python/aie_lit_utils/lit_config_helpers.py @@ -67,6 +67,75 @@ class LitConfigHelper: "npu2": ["npu4", "Strix", "npu5", "Strix Halo", "npu6", "Krackan"], } + PATH_ENV_VARS = {"PATH", "LD_LIBRARY_PATH", "DYLD_LIBRARY_PATH"} + + @staticmethod + def _prepend_env_paths(current_value: str, new_value: str) -> str: + """Prepend path entries without overwriting the existing values.""" + entries = [] + for value in (new_value, current_value): + if not value: + continue + entries.extend([entry for entry in value.split(os.path.pathsep) if entry]) + + merged = [] + seen = set() + for entry in entries: + normalized = os.path.normcase(os.path.normpath(entry)) + if normalized in seen: + continue + seen.add(normalized) + merged.append(entry) + return os.path.pathsep.join(merged) + + @staticmethod + def _quote_lit_arg(value: str) -> str: + """Quote arguments for lit's shell parser.""" + return '"' + value.replace("\\", "/").replace('"', '\\"') + '"' + + @staticmethod + def _run_on_npu_wrap(aie_src_root: str, npu_kind: str) -> str: + """Build the cross-platform run-on-NPU wrapper command.""" + wrapper = os.path.join(aie_src_root, "utils", "run_on_npu.py") + return " ".join( + [ + LitConfigHelper._quote_lit_arg(sys.executable), + LitConfigHelper._quote_lit_arg(wrapper), + LitConfigHelper._quote_lit_arg(npu_kind), + ] + ) + + @staticmethod + def _find_xrt_smi(xrt_bin_dir: str) -> Optional[str]: + """Find xrt-smi without assuming it exists under XRT_ROOT.""" + candidates = [] + if xrt_bin_dir: + candidates.extend( + [ + os.path.join(xrt_bin_dir, "xrt-smi"), + os.path.join(xrt_bin_dir, "bin", "xrt-smi"), + ] + ) + if os.name == "nt": + candidates.extend( + [ + os.path.join(xrt_bin_dir, "xrt-smi.exe"), + os.path.join(xrt_bin_dir, "bin", "xrt-smi.exe"), + ] + ) + + if os.name == "nt": + system_root = os.environ.get("SystemRoot", r"C:\Windows") + candidates.append( + os.path.join(system_root, "System32", "AMD", "xrt-smi.exe") + ) + + for candidate in candidates: + if os.path.isfile(candidate): + return candidate + + return shutil.which("xrt-smi") + @staticmethod def prepend_path(llvm_config, path: str) -> None: """ @@ -196,7 +265,7 @@ def detect_xrt( xrt_lib_dir: Path to XRT library directory xrt_include_dir: Path to XRT include directory xrt_bin_dir: Path to XRT binary directory - aie_src_root: Path to AIE source root (for run_on_npu.sh script) + aie_src_root: Path to AIE source root (for the run_on_npu wrapper) vitis_components: List of available Vitis components for feature filtering Returns: @@ -226,27 +295,50 @@ def detect_xrt( logger.info("xrt found at %s", os.path.dirname(xrt_lib_dir)) config.found = True - config.flags = f"-I{xrt_include_dir} -L{xrt_lib_dir} -luuid -lxrt_coreutil" - config.substitutions["%xrt_flags"] = config.flags - # Add XRT library directory to LD_LIBRARY_PATH for runtime linking, - # preserving any existing entries from the parent environment. - existing_ld_library_path = os.environ.get("LD_LIBRARY_PATH") - if existing_ld_library_path: - new_ld_library_path = existing_ld_library_path + os.pathsep + xrt_lib_dir + if os.name == "nt": + config.flags = f"-I{xrt_include_dir} -L{xrt_lib_dir} -lxrt_coreutil" else: - new_ld_library_path = xrt_lib_dir - config.environment["LD_LIBRARY_PATH"] = new_ld_library_path + config.flags = f"-I{xrt_include_dir} -L{xrt_lib_dir} -luuid -lxrt_coreutil" + config.substitutions["%xrt_flags"] = config.flags - # Detect NPU hardware + # Runtime library search path. Compose with the lit environment instead of + # rebuilding PATH/LD_LIBRARY_PATH from the process environment. + if os.name == "nt": + runtime_dirs = [path for path in (xrt_bin_dir, xrt_lib_dir) if path] + if runtime_dirs: + config.environment["PATH"] = os.path.pathsep.join(runtime_dirs) + elif xrt_lib_dir: + config.environment["LD_LIBRARY_PATH"] = xrt_lib_dir + + # Detect NPU hardware. XRT installation layout and xrt-smi location are + # not always the same on Windows, so probe them independently. try: - xrtsmi = os.path.join(xrt_bin_dir, "xrt-smi") + xrtsmi = LitConfigHelper._find_xrt_smi(xrt_bin_dir) + if not xrtsmi: + raise FileNotFoundError("xrt-smi") + + probe_env = os.environ.copy() + for key, value in config.environment.items(): + if key in LitConfigHelper.PATH_ENV_VARS: + probe_env[key] = LitConfigHelper._prepend_env_paths( + probe_env.get(key, ""), value + ) + else: + probe_env[key] = value + + print(f"Using xrt-smi: {xrtsmi}") result = subprocess.run( [xrtsmi, "examine"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, + env=probe_env, timeout=10, ) - output = result.stdout.decode("utf-8", errors="ignore").split("\n") + output = ( + result.stdout.decode("utf-8", errors="ignore") + + "\n" + + result.stderr.decode("utf-8", errors="ignore") + ).split("\n") # Pattern matches both old and new xrt-smi output formats: # Old: "|[0000:41:00.1] ||RyzenAI-npu1 |" @@ -272,13 +364,13 @@ def detect_xrt( logger.info("\tmodel: '%s'", model) - run_on_npu = f"{aie_src_root}/utils/run_on_npu.sh" - # Map model to NPU generation and filter by available components # Use substring matching so e.g. "Krackan" matches "Krackan 1" if any(known in model for known in LitConfigHelper.NPU_MODELS["npu1"]): if "AIE2" in vitis_components: - run_on_npu1 = run_on_npu + run_on_npu1 = LitConfigHelper._run_on_npu_wrap( + aie_src_root, "npu1" + ) config.features.extend(["ryzen_ai", "ryzen_ai_npu1"]) config.substitutions["%run_on_npu1%"] = run_on_npu1 logger.info( @@ -292,7 +384,9 @@ def detect_xrt( known in model for known in LitConfigHelper.NPU_MODELS["npu2"] ): if "AIE2P" in vitis_components: - run_on_npu2 = run_on_npu + run_on_npu2 = LitConfigHelper._run_on_npu_wrap( + aie_src_root, "npu2" + ) config.features.extend(["ryzen_ai", "ryzen_ai_npu2"]) config.substitutions["%run_on_npu2%"] = run_on_npu2 logger.info( @@ -524,7 +618,13 @@ def apply_config_to_lit(config_obj, hardware_configs: Dict[str, HardwareConfig]) # Add environment variables for key, value in hw_config.environment.items(): - config_obj.environment[key] = value + if key in LitConfigHelper.PATH_ENV_VARS: + current_value = config_obj.environment.get(key, "") + config_obj.environment[key] = LitConfigHelper._prepend_env_paths( + current_value, value + ) + else: + config_obj.environment[key] = value @staticmethod def setup_standard_environment( diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index af6449e64a4..eec7dda8ca3 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -96,6 +96,10 @@ include_directories(${PROJECT_SOURCE_DIR}/include) include_directories(${PROJECT_BINARY_DIR}/include) add_definitions(${LLVM_DEFINITIONS}) +if(WIN32) + file(TO_CMAKE_PATH "${PEANO_INSTALL_DIR}" PEANO_INSTALL_DIR) +endif() + configure_lit_site_cfg( ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg.py diff --git a/test/lit.cfg.py b/test/lit.cfg.py index cd3edd57188..b9d2a6868b7 100644 --- a/test/lit.cfg.py +++ b/test/lit.cfg.py @@ -137,17 +137,38 @@ tools = [ "aie-opt", "aie-translate", - "aiecc.py", "ld.lld", "llc", "llvm-objdump", "opt", "xchesscc_wrapper", - "txn2mlir.py", ] +if os.name != "nt": + tools.extend(["aiecc.py", "txn2mlir.py"]) + llvm_config.add_tool_substitutions(tools, tool_dirs) +if os.name == "nt": + # Lit on Windows struggles with substituting tools with a .py extension. + # Add these manually and quote them so paths with spaces survive. + config.substitutions.append( + ( + "aiecc.py", + LitConfigHelper._quote_lit_arg( + os.path.join(config.aie_tools_dir, "aiecc.py") + ), + ) + ) + config.substitutions.append( + ( + "txn2mlir.py", + LitConfigHelper._quote_lit_arg( + os.path.join(config.aie_tools_dir, "txn2mlir.py") + ), + ) + ) + if config.enable_board_tests: lit_config.parallelism_groups["board"] = 1 config.parallelism_group = "board" diff --git a/test/lit.site.cfg.py.in b/test/lit.site.cfg.py.in index 94c2c0c2161..1dd0bfccdc2 100644 --- a/test/lit.site.cfg.py.in +++ b/test/lit.site.cfg.py.in @@ -11,69 +11,69 @@ import sys import lit.util -config.host_triple = "@LLVM_HOST_TRIPLE@" -config.target_triple = "@TARGET_TRIPLE@" -config.llvm_src_root = "@LLVM_SOURCE_DIR@" -config.llvm_obj_root = "@LLVM_BINARY_DIR@" -config.llvm_tools_dir = "@LLVM_TOOLS_DIR@" -config.llvm_lib_dir = "@LLVM_LIBRARY_DIR@" -config.llvm_shlib_dir = "@SHLIBDIR@" -config.llvm_shlib_ext = "@SHLIBEXT@" -config.llvm_exe_ext = "@EXEEXT@" -config.peano_install_dir = "@PEANO_INSTALL_DIR@" -config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@" -config.python_executable = "@Python3_EXECUTABLE@" -config.gold_executable = "@GOLD_EXECUTABLE@" -config.ld64_executable = "@LD64_EXECUTABLE@" +config.host_triple = r"""@LLVM_HOST_TRIPLE@""" +config.target_triple = r"""@TARGET_TRIPLE@""" +config.llvm_src_root = r"""@LLVM_SOURCE_DIR@""" +config.llvm_obj_root = r"""@LLVM_BINARY_DIR@""" +config.llvm_tools_dir = r"""@LLVM_TOOLS_DIR@""" +config.llvm_lib_dir = r"""@LLVM_LIBRARY_DIR@""" +config.llvm_shlib_dir = r"""@SHLIBDIR@""" +config.llvm_shlib_ext = r"""@SHLIBEXT@""" +config.llvm_exe_ext = r"""@EXEEXT@""" +config.peano_install_dir = r"""@PEANO_INSTALL_DIR@""" +config.lit_tools_dir = r"""@LLVM_LIT_TOOLS_DIR@""" +config.python_executable = r"""@Python3_EXECUTABLE@""" +config.gold_executable = r"""@GOLD_EXECUTABLE@""" +config.ld64_executable = r"""@LD64_EXECUTABLE@""" config.enable_shared = @ENABLE_SHARED@ config.enable_assertions = @ENABLE_ASSERTIONS@ -config.targets_to_build = "@TARGETS_TO_BUILD@" -config.native_target = "@LLVM_NATIVE_ARCH@" -config.llvm_bindings = "@LLVM_BINDINGS@".split(' ') -config.host_os = "@HOST_OS@" -config.host_cc = "@HOST_CC@" -config.host_cxx = "@HOST_CXX@" -# Note: ldflags can contain double-quoted paths, so must use single quotes here. -config.host_ldflags = '@HOST_LDFLAGS@' -config.llvm_use_sanitizer = "@LLVM_USE_SANITIZER@" -config.llvm_host_triple = '@LLVM_HOST_TRIPLE@' -config.host_arch = "@HOST_ARCH@" -config.xrt_dir = "@XRT_DIR@" -config.xrt_bin_dir = "@XRT_BIN_DIR@" -config.xrt_lib_dir = "@XRT_LIB_DIR@" -config.xrt_include_dir = "@XRT_INCLUDE_DIR@" +config.targets_to_build = r"""@TARGETS_TO_BUILD@""" +config.native_target = r"""@LLVM_NATIVE_ARCH@""" +config.llvm_bindings = r"""@LLVM_BINDINGS@""".split(' ') +config.host_os = r"""@HOST_OS@""" +config.host_cc = r"""@HOST_CC@""" +config.host_cxx = r"""@HOST_CXX@""" +# Use a raw triple-quoted string so Windows backslashes and embedded quotes survive. +config.host_ldflags = r"""@HOST_LDFLAGS@""" +config.llvm_use_sanitizer = r"""@LLVM_USE_SANITIZER@""" +config.llvm_host_triple = r"""@LLVM_HOST_TRIPLE@""" +config.host_arch = r"""@HOST_ARCH@""" +config.xrt_dir = r"""@XRT_DIR@""" +config.xrt_bin_dir = r"""@XRT_BIN_DIR@""" +config.xrt_lib_dir = r"""@XRT_LIB_DIR@""" +config.xrt_include_dir = r"""@XRT_INCLUDE_DIR@""" -config.aie_src_root = "@AIE_SOURCE_DIR@" -config.aie_obj_root = "@AIE_BINARY_DIR@" +config.aie_src_root = r"""@AIE_SOURCE_DIR@""" +config.aie_obj_root = r"""@AIE_BINARY_DIR@""" # test_exec_root: The root path where tests should be run. -config.test_exec_root = "@CMAKE_CURRENT_BINARY_DIR@" +config.test_exec_root = r"""@CMAKE_CURRENT_BINARY_DIR@""" # Pointing to the ROCr directories -config.hsa_dir = "@hsa-runtime64_DIR@" -config.hsa_found = "@hsa-runtime64_FOUND@" +config.hsa_dir = r"""@hsa-runtime64_DIR@""" +config.hsa_found = r"""@hsa-runtime64_FOUND@""" # available features -config.enable_chess_tests = lit.util.pythonize_bool("@ENABLE_CHESS_TESTS@") -config.enable_board_tests = lit.util.pythonize_bool("@ENABLE_BOARD_TESTS@") -config.enable_python_tests = lit.util.pythonize_bool("@ENABLE_PYTHON_TESTS@") -config.python_passes = lit.util.pythonize_bool("@AIE_ENABLE_PYTHON_PASSES@") -config.xrt_python_bindings = lit.util.pythonize_bool("@AIE_ENABLE_XRT_PYTHON_BINDINGS@") -config.has_mlir_runtime_libraries = lit.util.pythonize_bool("@HAS_MLIR_RUNTIME_LIBRARIES@") +config.enable_chess_tests = lit.util.pythonize_bool(r"""@ENABLE_CHESS_TESTS@""") +config.enable_board_tests = lit.util.pythonize_bool(r"""@ENABLE_BOARD_TESTS@""") +config.enable_python_tests = lit.util.pythonize_bool(r"""@ENABLE_PYTHON_TESTS@""") +config.python_passes = lit.util.pythonize_bool(r"""@AIE_ENABLE_PYTHON_PASSES@""") +config.xrt_python_bindings = lit.util.pythonize_bool(r"""@AIE_ENABLE_XRT_PYTHON_BINDINGS@""") +config.has_mlir_runtime_libraries = lit.util.pythonize_bool(r"""@HAS_MLIR_RUNTIME_LIBRARIES@""") # pass on vitis settings -config.vitis_root = "@VITIS_ROOT@" -config.vitis_aietools_dir = "@VITIS_AIETOOLS_DIR@" -config.vitis_sysroot = "@Sysroot@" -config.extraAieCcFlags = "@extraAieCcFlags@" -config.aieHostTarget = "@AIE_RUNTIME_TEST_TARGET@" -config.aieInstallPrefix = "@CMAKE_INSTALL_PREFIX@" +config.vitis_root = r"""@VITIS_ROOT@""" +config.vitis_aietools_dir = r"""@VITIS_AIETOOLS_DIR@""" +config.vitis_sysroot = r"""@Sysroot@""" +config.extraAieCcFlags = r"""@extraAieCcFlags@""" +config.aieHostTarget = r"""@AIE_RUNTIME_TEST_TARGET@""" +config.aieInstallPrefix = r"""@CMAKE_INSTALL_PREFIX@""" config.vitis_components = [] -if lit.util.pythonize_bool("@AIETools_AIE_FOUND@"): +if lit.util.pythonize_bool(r"""@AIETools_AIE_FOUND@"""): config.vitis_components.append("AIE") -if lit.util.pythonize_bool("@AIETools_AIE2_FOUND@"): +if lit.util.pythonize_bool(r"""@AIETools_AIE2_FOUND@"""): config.vitis_components.append("AIE2") -if lit.util.pythonize_bool("@AIETools_AIE2P_FOUND@"): +if lit.util.pythonize_bool(r"""@AIETools_AIE2P_FOUND@"""): config.vitis_components.append("AIE2P") # Support substitution of the tools_dir with user parameters. This is @@ -86,10 +86,10 @@ except KeyError: key, = e.args lit_config.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key)) -config.aie_include_integration_tests = "@AIE_INCLUDE_INTEGRATION_TESTS@" +config.aie_include_integration_tests = r"""@AIE_INCLUDE_INTEGRATION_TESTS@""" import lit.llvm lit.llvm.initialize(lit_config, config) # Let the main config do the real work. -lit_config.load_config(config, "@PROJECT_SOURCE_DIR@/lit.cfg.py") +lit_config.load_config(config, r"""@PROJECT_SOURCE_DIR@/lit.cfg.py""") diff --git a/utils/run_on_npu.py b/utils/run_on_npu.py new file mode 100644 index 00000000000..7580523b672 --- /dev/null +++ b/utils/run_on_npu.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python3 + +# (c) Copyright 2023-2026 Advanced Micro Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +import os +import subprocess +import sys +import tempfile + + +def main() -> int: + if len(sys.argv) < 3: + print("usage: run_on_npu.py [args...]", file=sys.stderr) + return 2 + + # Mimic the existing %run_on_npu*% bash functionality, broadening OS support. + # "NPU kind" is currently informational only. + _npu_kind = sys.argv[1] + command = sys.argv[2:] + + if os.name == "nt": + completed = subprocess.run(command) + return completed.returncode + + xrt_dir = ( + os.environ.get("XRT_DIR") or os.environ.get("XRT_ROOT") or "/opt/xilinx/xrt" + ) + setup_script = os.path.join(xrt_dir, "setup.sh") + if not os.path.isfile(setup_script): + completed = subprocess.run(command) + return completed.returncode + + # Serialize Ryzen AI executions on POSIX runners to avoid contention. + import fcntl + + lock_path = os.path.join(tempfile.gettempdir(), "mlir_aie_run_on_npu.lock") + bash_command = [ + "bash", + "-c", + 'XRT_DIR="$1"; source "$XRT_DIR/setup.sh" >/dev/null 2>&1; shift; exec "$@"', + "run_on_npu", + xrt_dir, + *command, + ] + with open(lock_path, "w") as lock_file: + fcntl.flock(lock_file.fileno(), fcntl.LOCK_EX) + completed = subprocess.run(bash_command) + return completed.returncode + + +if __name__ == "__main__": + raise SystemExit(main())