From cf9ac338377045dc124b35f4feac159e9c51068c Mon Sep 17 00:00:00 2001 From: mdzurick Date: Fri, 5 Jun 2026 12:23:33 +0000 Subject: [PATCH 1/2] [python] Surface dem_from_kernel errors as RuntimeError instead of aborting cudaq.dem_from_kernel runs the kernel under a dlopen'd `stim` analysis plugin. A non-Clifford gate makes Stim throw std::runtime_error from inside that plugin; on macOS the exception escapes uncaught at the binding boundary and the process aborts (SIGABRT / "Fatal Python error: Aborted"), crashing the test worker instead of raising in Python. Wrap the call in dem_from_kernel_impl and re-throw a fresh runtime_error owned by this module (with a catch-all fallback) so the error reliably surfaces as a Python RuntimeError on all platforms. Mirrors the catch-and-rethrow guard already used at other binding boundaries (e.g. runtime/cudaq/realtime.cpp). Fixes the macOS 'Python metapackage validation' failure on test_dem_from_kernel.py::test_non_clifford_raises. Signed-off-by: mdzurick --- python/runtime/cudaq/analysis/py_dem.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/python/runtime/cudaq/analysis/py_dem.cpp b/python/runtime/cudaq/analysis/py_dem.cpp index d29d34220d7..e00f08dd458 100644 --- a/python/runtime/cudaq/analysis/py_dem.cpp +++ b/python/runtime/cudaq/analysis/py_dem.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include using namespace cudaq; @@ -27,10 +28,21 @@ static std::string dem_from_kernel_impl(const std::string &kernelName, args = simplifiedValidateInputArguments(args); const cudaq::noise_model *noisePtr = noise ? &(*noise) : nullptr; - return cudaq::detail::runDemFromKernel(kernelName, platform, noisePtr, [&]() { - [[maybe_unused]] auto result = - cudaq::marshal_and_launch_module(kernelName, kernelMod, args); - }); + // Re-throw as a module-local RuntimeError; plugin exceptions otherwise + // escape uncaught on macOS and abort instead of raising in Python. + try { + return cudaq::detail::runDemFromKernel( + kernelName, platform, noisePtr, [&]() { + [[maybe_unused]] auto result = + cudaq::marshal_and_launch_module(kernelName, kernelMod, args); + }); + } catch (const std::exception &e) { + throw std::runtime_error(e.what()); + } catch (...) { + throw std::runtime_error( + "cudaq::dem_from_kernel failed: the kernel uses an operation the Stim " + "analysis backend cannot simulate (only Clifford gates are supported)."); + } } void cudaq::bindDemFromKernel(nanobind::module_ &mod) { From 906443ec13e4b1aa7edca4d1b3318c77a423edf8 Mon Sep 17 00:00:00 2001 From: mdzurick Date: Fri, 5 Jun 2026 18:29:43 +0000 Subject: [PATCH 2/2] [python] Preserve Python exceptions in dem_from_kernel error guard Review follow-up: the catch-all guard added previously also intercepted nanobind::python_error (which derives from std::runtime_error) thrown by marshal_and_launch_module during argument marshalling/launch, flattening a real Python error to a generic RuntimeError (losing its type/traceback) or mislabeling it as a Clifford error. Catch nanobind::python_error first and re-throw it unchanged so genuine Python exceptions propagate intact; only foreign C++ exceptions fall through to the RuntimeError translation. Signed-off-by: mdzurick --- python/runtime/cudaq/analysis/py_dem.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/python/runtime/cudaq/analysis/py_dem.cpp b/python/runtime/cudaq/analysis/py_dem.cpp index e00f08dd458..65538da1b11 100644 --- a/python/runtime/cudaq/analysis/py_dem.cpp +++ b/python/runtime/cudaq/analysis/py_dem.cpp @@ -36,8 +36,10 @@ static std::string dem_from_kernel_impl(const std::string &kernelName, [[maybe_unused]] auto result = cudaq::marshal_and_launch_module(kernelName, kernelMod, args); }); + } catch (nanobind::python_error &) { + throw; // keep real Python exceptions (e.g. from argument marshalling) } catch (const std::exception &e) { - throw std::runtime_error(e.what()); + throw std::runtime_error(e.what()); // dem_from_kernel reports via RuntimeError } catch (...) { throw std::runtime_error( "cudaq::dem_from_kernel failed: the kernel uses an operation the Stim "