From 832af1ac0175271415f5df0685a7e77dc43b3fc1 Mon Sep 17 00:00:00 2001 From: erweiw Date: Thu, 9 Apr 2026 15:29:00 -0700 Subject: [PATCH 1/5] Replace print() calls with logging module for controllable verbosity MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Addresses #40 — compilation messages (cache hits, tiling script paths, compile-only output) now use Python's logging module instead of print(). By default the logger is set to WARNING (silent on success). Set AMD_TRITON_NPU_DEBUG=1 to restore verbose output at DEBUG level. Autotuning prints remain gated by knobs.autotuning.print. Co-Authored-By: Claude Opus 4.6 (1M context) --- amd_triton_npu/backend/driver.py | 35 ++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/amd_triton_npu/backend/driver.py b/amd_triton_npu/backend/driver.py index 7887cff..ff0eb7d 100644 --- a/amd_triton_npu/backend/driver.py +++ b/amd_triton_npu/backend/driver.py @@ -3,6 +3,7 @@ import hashlib import json +import logging import tempfile import sys import sysconfig @@ -23,6 +24,11 @@ from air.ir import * import air.passmanager +logger = logging.getLogger(__name__) +if os.getenv("AMD_TRITON_NPU_DEBUG", "0") == "1": + logging.basicConfig() + logger.setLevel(logging.DEBUG) + autotune_time = False @@ -176,10 +182,10 @@ def get_npu_device_info(): return devices except subprocess.CalledProcessError as e: - print("Failed to run xrt-smi:", e.stderr) + logger.warning("Failed to run xrt-smi: %s", e.stderr) return [] except Exception as e: - print("Unexpected error:", str(e)) + logger.warning("Unexpected error: %s", e) return [] @@ -434,7 +440,7 @@ def _get_transform_ir_string(): f"Use an absolute path or run from the directory containing the script." ) with open(custom_script_path, "r") as f: - print(f"Using custom tiling script from: {custom_script_path}") + logger.info("Using custom tiling script from: %s", custom_script_path) user_script = f.read() return _inject_transform_library(user_script) @@ -1335,28 +1341,27 @@ def launch( # Check for compile-only mode if os.getenv("AMD_TRITON_NPU_COMPILE_ONLY", "0") == "1": - print(f"Compile-only mode: binaries cached at {cache_path}") + logger.info("Compile-only mode: binaries cached at %s", cache_path) if output_format == "elf": - print(f" elf: {cache_elf_path}") + logger.info(" elf: %s", cache_elf_path) else: - print(f" xclbin: {cache_xclbin_path}") - print(f" insts: {cache_insts_path}") + logger.info(" xclbin: %s", cache_xclbin_path) + logger.info(" insts: %s", cache_insts_path) return None else: - print( - "got cache path: " - + cache_path - + " compilation is therefore skipped (delete cache path to force recompile)." + logger.info( + "got cache path: %s compilation is therefore skipped " + "(delete cache path to force recompile).", cache_path ) # Check for compile-only mode (cache hit) if os.getenv("AMD_TRITON_NPU_COMPILE_ONLY", "0") == "1": - print(f"Compile-only mode (cache hit): binaries at {cache_path}") + logger.info("Compile-only mode (cache hit): binaries at %s", cache_path) if output_format == "elf": - print(f" elf: {cache_elf_path}") + logger.info(" elf: %s", cache_elf_path) else: - print(f" xclbin: {cache_xclbin_path}") - print(f" insts: {cache_insts_path}") + logger.info(" xclbin: %s", cache_xclbin_path) + logger.info(" insts: %s", cache_insts_path) return None # Load and launch the compiled kernel. From 3cdbafc7621e236a9d56a2e278ee82c24c005a1d Mon Sep 17 00:00:00 2001 From: erweiw Date: Thu, 9 Apr 2026 15:34:35 -0700 Subject: [PATCH 2/5] Fix black formatting: trailing comma on multi-line logger.info call Co-Authored-By: Claude Opus 4.6 (1M context) --- amd_triton_npu/backend/driver.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/amd_triton_npu/backend/driver.py b/amd_triton_npu/backend/driver.py index ff0eb7d..89bbce1 100644 --- a/amd_triton_npu/backend/driver.py +++ b/amd_triton_npu/backend/driver.py @@ -1351,7 +1351,8 @@ def launch( else: logger.info( "got cache path: %s compilation is therefore skipped " - "(delete cache path to force recompile).", cache_path + "(delete cache path to force recompile).", + cache_path, ) # Check for compile-only mode (cache hit) From 9964c0b8ec2948ed4f5d503a6fca3c84761f0f4d Mon Sep 17 00:00:00 2001 From: erweiw Date: Thu, 9 Apr 2026 16:29:26 -0700 Subject: [PATCH 3/5] Address PR review: fix logger default level and avoid global side effects - Set logger default to WARNING so info/debug messages stay suppressed even when the embedding app configures root logger to INFO - Replace logging.basicConfig() with a module-local StreamHandler using a message-only formatter to avoid global side effects - Set logger.propagate = False to isolate from app logging config - Change all logger.info() to logger.debug() since these are verbose debug messages, not standard informational output Co-Authored-By: Claude Opus 4.6 (1M context) --- amd_triton_npu/backend/driver.py | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/amd_triton_npu/backend/driver.py b/amd_triton_npu/backend/driver.py index 89bbce1..3d57e07 100644 --- a/amd_triton_npu/backend/driver.py +++ b/amd_triton_npu/backend/driver.py @@ -25,9 +25,14 @@ import air.passmanager logger = logging.getLogger(__name__) +logger.setLevel(logging.WARNING) if os.getenv("AMD_TRITON_NPU_DEBUG", "0") == "1": - logging.basicConfig() logger.setLevel(logging.DEBUG) +if not logger.handlers: + _handler = logging.StreamHandler() + _handler.setFormatter(logging.Formatter("%(message)s")) + logger.addHandler(_handler) +logger.propagate = False autotune_time = False @@ -440,7 +445,7 @@ def _get_transform_ir_string(): f"Use an absolute path or run from the directory containing the script." ) with open(custom_script_path, "r") as f: - logger.info("Using custom tiling script from: %s", custom_script_path) + logger.debug("Using custom tiling script from: %s", custom_script_path) user_script = f.read() return _inject_transform_library(user_script) @@ -1341,15 +1346,15 @@ def launch( # Check for compile-only mode if os.getenv("AMD_TRITON_NPU_COMPILE_ONLY", "0") == "1": - logger.info("Compile-only mode: binaries cached at %s", cache_path) + logger.debug("Compile-only mode: binaries cached at %s", cache_path) if output_format == "elf": - logger.info(" elf: %s", cache_elf_path) + logger.debug(" elf: %s", cache_elf_path) else: - logger.info(" xclbin: %s", cache_xclbin_path) - logger.info(" insts: %s", cache_insts_path) + logger.debug(" xclbin: %s", cache_xclbin_path) + logger.debug(" insts: %s", cache_insts_path) return None else: - logger.info( + logger.debug( "got cache path: %s compilation is therefore skipped " "(delete cache path to force recompile).", cache_path, @@ -1357,12 +1362,12 @@ def launch( # Check for compile-only mode (cache hit) if os.getenv("AMD_TRITON_NPU_COMPILE_ONLY", "0") == "1": - logger.info("Compile-only mode (cache hit): binaries at %s", cache_path) + logger.debug("Compile-only mode (cache hit): binaries at %s", cache_path) if output_format == "elf": - logger.info(" elf: %s", cache_elf_path) + logger.debug(" elf: %s", cache_elf_path) else: - logger.info(" xclbin: %s", cache_xclbin_path) - logger.info(" insts: %s", cache_insts_path) + logger.debug(" xclbin: %s", cache_xclbin_path) + logger.debug(" insts: %s", cache_insts_path) return None # Load and launch the compiled kernel. From c3712fa2fcfce5043d3f1b58f5eb2e323a0e2154 Mon Sep 17 00:00:00 2001 From: erweiw Date: Thu, 9 Apr 2026 16:37:52 -0700 Subject: [PATCH 4/5] Fix black formatting: wrap long logger.debug line Co-Authored-By: Claude Opus 4.6 (1M context) --- amd_triton_npu/backend/driver.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/amd_triton_npu/backend/driver.py b/amd_triton_npu/backend/driver.py index 3d57e07..c628d49 100644 --- a/amd_triton_npu/backend/driver.py +++ b/amd_triton_npu/backend/driver.py @@ -1362,7 +1362,9 @@ def launch( # Check for compile-only mode (cache hit) if os.getenv("AMD_TRITON_NPU_COMPILE_ONLY", "0") == "1": - logger.debug("Compile-only mode (cache hit): binaries at %s", cache_path) + logger.debug( + "Compile-only mode (cache hit): binaries at %s", cache_path + ) if output_format == "elf": logger.debug(" elf: %s", cache_elf_path) else: From 742764c60962e6572d034b4e8e6ac6cda70909a4 Mon Sep 17 00:00:00 2001 From: erweiw Date: Fri, 10 Apr 2026 21:42:12 -0700 Subject: [PATCH 5/5] Address PR review: use CRITICAL default level and error/exception for failures MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Default log level → CRITICAL per reviewer request (suppress all non-critical) - xrt-smi CalledProcessError → logger.error (was warning) - Unexpected Exception → logger.exception (includes traceback) Co-Authored-By: Claude Opus 4.6 (1M context) --- amd_triton_npu/backend/driver.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/amd_triton_npu/backend/driver.py b/amd_triton_npu/backend/driver.py index c628d49..807d7d4 100644 --- a/amd_triton_npu/backend/driver.py +++ b/amd_triton_npu/backend/driver.py @@ -25,7 +25,7 @@ import air.passmanager logger = logging.getLogger(__name__) -logger.setLevel(logging.WARNING) +logger.setLevel(logging.CRITICAL) if os.getenv("AMD_TRITON_NPU_DEBUG", "0") == "1": logger.setLevel(logging.DEBUG) if not logger.handlers: @@ -187,10 +187,10 @@ def get_npu_device_info(): return devices except subprocess.CalledProcessError as e: - logger.warning("Failed to run xrt-smi: %s", e.stderr) + logger.error("Failed to run xrt-smi: %s", e.stderr) return [] except Exception as e: - logger.warning("Unexpected error: %s", e) + logger.exception("Unexpected error during NPU device detection") return []