diff --git a/python/tvm/contrib/mxcc.py b/python/tvm/contrib/mxcc.py index c5ad9eca5969..880f499b5f3c 100644 --- a/python/tvm/contrib/mxcc.py +++ b/python/tvm/contrib/mxcc.py @@ -19,6 +19,7 @@ import re import os +import shlex import subprocess import warnings from typing import Tuple @@ -31,6 +32,26 @@ from . import utils +def _format_mxcc_error(cmd, compiler_output, code): + """Format an mxcc failure with enough context for reproduction.""" + command_text = shlex.join([str(part) for part in cmd]) + if isinstance(compiler_output, bytes): + compiler_text = compiler_output.decode("utf-8", errors="replace") + else: + compiler_text = py_str(compiler_output) + return "\n".join( + [ + "MACA compilation failed.", + "Command:", + command_text, + "Compiler output:", + compiler_text, + "Source:", + code, + ] + ) + + def compile_maca( code, target_format="mcbin", arch=None, options=None, path_target=None ): # pylint: disable=unused-argument @@ -108,10 +129,7 @@ def compile_maca( (out, _) = proc.communicate() if proc.returncode != 0: - msg = code - msg += "\nCompilation error:\n" - msg += py_str(out) - raise RuntimeError(msg) + raise RuntimeError(_format_mxcc_error(cmd, out, code)) with open(file_target, "rb") as f: data = bytearray(f.read()) diff --git a/tests/python/contrib/test_mxcc_error_message.py b/tests/python/contrib/test_mxcc_error_message.py new file mode 100644 index 000000000000..8e518039a017 --- /dev/null +++ b/tests/python/contrib/test_mxcc_error_message.py @@ -0,0 +1,21 @@ +from pathlib import Path + +from tvm.contrib import mxcc + + +def test_error_message_includes_reproducible_command(): + cmd = ["mxcc", "-device-obj", "-o", Path("/tmp/out.mcbin"), "/tmp/in.maca"] + source = 'extern "C" __global__ void broken() {}' + message = mxcc._format_mxcc_error(cmd, b"syntax error", source) + + assert "MACA compilation failed." in message + assert "mxcc -device-obj -o /tmp/out.mcbin /tmp/in.maca" in message + assert "syntax error" in message + assert source in message + + +def test_error_message_replaces_non_utf8_output(): + message = mxcc._format_mxcc_error(["mxcc"], b"\xff", "__kernel") + + assert "Compiler output:" in message + assert "\ufffd" in message