diff --git a/doc/releases/changelog-dev.md b/doc/releases/changelog-dev.md index f35ae47c7d..88d3af4155 100644 --- a/doc/releases/changelog-dev.md +++ b/doc/releases/changelog-dev.md @@ -19,6 +19,11 @@ distribution over the branches. The counted resources are then scaled proportionally and summed. [(#3059)](https://github.com/PennyLaneAI/catalyst/pull/3059) +* Warnings and diagnostics emitted by successful Catalyst compiler subprocesses are now forwarded to + Python callers instead of being silently discarded. LLVM diagnostic colors are preserved in + interactive terminals. + [(#3080)](https://github.com/PennyLaneAI/catalyst/pull/3080) + * A new runtime transport layer for remote/local executors is introduced. [(#3043)](https://github.com/PennyLaneAI/catalyst/pull/3043) [(#3045)](https://github.com/PennyLaneAI/catalyst/pull/3045) diff --git a/frontend/catalyst/compiler.py b/frontend/catalyst/compiler.py index aa8ea8032f..621366050f 100644 --- a/frontend/catalyst/compiler.py +++ b/frontend/catalyst/compiler.py @@ -302,27 +302,37 @@ def _get_catalyst_cli_cmd(*args, stdin=None): return cmd -def _catalyst(*args, stdin=None, text=True): +def _catalyst(*args, stdin=None, text=True, stderr_return=False): """Raw interface to catalyst echo ${stdin} | catalyst *args - catalyst *args """ cmd = _get_catalyst_cli_cmd(*args, stdin=stdin) + + if sys.stderr.isatty(): + cmd.insert(1, "--color") + try: result = subprocess.run(cmd, input=stdin, check=True, capture_output=True, text=text) + + # Capture the diagnostic output from the compiler + if stderr_return and result.stderr: + stderr = result.stderr.decode() if isinstance(result.stderr, bytes) else result.stderr + print(stderr, end="", file=sys.stderr) + return result.stdout except subprocess.CalledProcessError as e: raise CompileError(f"catalyst failed with error code {e.returncode}: {e.stderr}") from e -def _quantum_opt(*args, stdin=None, text=True): +def _quantum_opt(*args, stdin=None, text=True, stderr_return=False): """Raw interface to quantum-opt echo ${stdin} | catalyst --tool=opt *args - catalyst --tool=opt *args """ - return _catalyst(("--tool", "opt"), *args, stdin=stdin, text=text) + return _catalyst(("--tool", "opt"), *args, stdin=stdin, text=text, stderr_return=stderr_return) def canonicalize(*args, stdin=None, options: Optional[CompileOptions] = None): @@ -404,6 +414,7 @@ def to_mlir_opt( options: Optional[CompileOptions] = None, using_python_compiler=False, workspace=None, + stderr_return=True, ): """echo ${input} | catalyst --tool=opt *args *opts -""" # Check if we need to use the Python interface for xDSL passes @@ -417,12 +428,12 @@ def to_mlir_opt( # These are the options that may affect compilation if not options: - return _quantum_opt(*args, stdin=stdin) + return _quantum_opt(*args, stdin=stdin, stderr_return=stderr_return) opts = _options_to_cli_flags(options) if workspace is not None: opts += [("--workspace", str(workspace))] - return _quantum_opt(*opts, *args, stdin=stdin) + return _quantum_opt(*opts, *args, stdin=stdin, stderr_return=stderr_return) class Compiler: