Skip to content

Commit 00a9838

Browse files
update constructing a decoder from a Stim DEM string
Signed-off-by: vedika-saravanan <vsaravanan@nvidia.com>
1 parent 200804a commit 00a9838

1 file changed

Lines changed: 35 additions & 26 deletions

File tree

libs/qec/python/bindings/py_decoder.cpp

Lines changed: 35 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -735,10 +735,41 @@ void bindDecoder(nb::module_ &mod) {
735735
});
736736
});
737737

738+
// Shared implementation for constructing a decoder from a Stim DEM string,
739+
// used by both get_decoder overload paths and the (deprecated)
740+
// get_decoder_from_stim_dem entry point.
741+
auto get_decoder_from_dem_text = [](const std::string &name,
742+
const std::string &dem_text,
743+
nb::kwargs options)
744+
-> std::variant<nb::object, std::unique_ptr<decoder>> {
745+
if (PyDecoderRegistry::contains(name)) {
746+
auto dem = dem_from_stim_text(dem_text);
747+
748+
// Keep in sync with make_pcm_decoder in decoder.h.
749+
auto defaults = dem_defaults_for_missing_keys(
750+
[&](const std::string &key) { return options.contains(key); }, dem);
751+
if (defaults.O)
752+
options["O"] = toPyArray(*defaults.O);
753+
if (defaults.error_rate_vec)
754+
options["error_rate_vec"] = toPyArray(*defaults.error_rate_vec);
755+
756+
nb::object H_obj = toPyArray(dem.detector_error_matrix);
757+
return PyDecoderRegistry::get_decoder(name, H_obj, options);
758+
}
759+
760+
return get_decoder(name, decoder_init{dem_text}, hetMapFromKwargs(options));
761+
};
762+
738763
qecmod.def(
739764
"get_decoder",
740-
[](const std::string &name, nb::object H, nb::kwargs options)
765+
[get_decoder_from_dem_text](const std::string &name, nb::object H,
766+
nb::kwargs options)
741767
-> std::variant<nb::object, std::unique_ptr<decoder>> {
768+
if (nb::isinstance<nb::str>(H)) {
769+
return get_decoder_from_dem_text(name, nb::cast<std::string>(H),
770+
options);
771+
}
772+
742773
if (PyDecoderRegistry::contains(name)) {
743774
return PyDecoderRegistry::get_decoder(name, H, options);
744775
}
@@ -779,6 +810,9 @@ void bindDecoder(nb::module_ &mod) {
779810
builds ``sparse_binary_matrix`` directly (no dense tensor for ``H``),
780811
allowing native C++ decoders like ``pymatching`` to be constructed
781812
from very large parity-check matrices.
813+
- A Stim detector error model string: native C++ decoders receive the
814+
raw DEM text via ``decoder_init``; Python-registered decoders receive
815+
the DEM-derived PCM plus ``O`` and ``error_rate_vec`` defaults.
782816
783817
For Python-registered decoders (``cudaq.qec.decoder`` decorator), ``H``
784818
is passed through to ``__init__`` unchanged (NumPy array or sparse dict).
@@ -787,31 +821,6 @@ void bindDecoder(nb::module_ &mod) {
787821
allocation.
788822
)pbdoc");
789823

790-
// Shared implementation for constructing a decoder from a Stim DEM string,
791-
// used by both the get_decoder(str) overload and the (deprecated)
792-
// get_decoder_from_stim_dem entry point.
793-
auto get_decoder_from_dem_text = [](const std::string &name,
794-
const std::string &dem_text,
795-
nb::kwargs options)
796-
-> std::variant<nb::object, std::unique_ptr<decoder>> {
797-
if (PyDecoderRegistry::contains(name)) {
798-
auto dem = dem_from_stim_text(dem_text);
799-
800-
// Keep in sync with make_pcm_decoder in decoder.h.
801-
auto defaults = dem_defaults_for_missing_keys(
802-
[&](const std::string &key) { return options.contains(key); }, dem);
803-
if (defaults.O)
804-
options["O"] = toPyArray(*defaults.O);
805-
if (defaults.error_rate_vec)
806-
options["error_rate_vec"] = toPyArray(*defaults.error_rate_vec);
807-
808-
nb::object H_obj = toPyArray(dem.detector_error_matrix);
809-
return PyDecoderRegistry::get_decoder(name, H_obj, options);
810-
}
811-
812-
return get_decoder(name, decoder_init{dem_text}, hetMapFromKwargs(options));
813-
};
814-
815824
// Unified entry point: get_decoder also accepts a Stim DEM string. nanobind
816825
// resolves this overload when the second argument is a str rather than a
817826
// numpy array.

0 commit comments

Comments
 (0)