Skip to content

Add chromobius decoder to the decoder plugins#546

Open
wsttiger wants to merge 7 commits into
NVIDIA:mainfrom
wsttiger:add_chromobius_decoder
Open

Add chromobius decoder to the decoder plugins#546
wsttiger wants to merge 7 commits into
NVIDIA:mainfrom
wsttiger:add_chromobius_decoder

Conversation

@wsttiger

Copy link
Copy Markdown
Collaborator

Summary

Adds a CUDA-QX QEC decoder plugin for Chromobius and wires it into the existing decoder factory/plugin flow.

The wrapper accepts a Stim detector error model through decoder params, compiles a Chromobius decoder from that DEM, packs detector syndromes into Chromobius’ expected bit-packed format, and returns predicted observable flips directly.

Changes

  • Add chromobius decoder plugin under libs/qec/lib/decoders/plugins/chromobius
  • Wire the plugin into the QEC library build
  • Fetch/build Chromobius as an internal plugin dependency
  • Support DEM input via dem, dem_str, or dem_path
  • Expose Chromobius decoder options through CUDA-QX decoder params
  • Return observable predictions directly and configure observable plumbing accordingly
  • Add C++ unit tests for construction, decode behavior, DEM path loading, and validation failures
  • Add small upstream-derived Chromobius reference data
  • Add C++ and Python correctness tests for single-shot and batched decode paths
  • Fix plugin registration to use CUDAQ_EXT_PT_REGISTER_TYPE
  • Fix a PyMatching pointer access issue found while building the plugin
  • Keep the GCC 12 GTest workaround private so it does not leak into CUDA test builds

Testing

  • ninja -j16
  • ninja install
  • ninja test_chromobius_correctness
  • ctest -R Chromobius --output-on-failure
  • ctest -R ChromobiusCorrectness --output-on-failure
  • PYTHONPATH=/usr/local/cudaq:/scratch/cudaqx-realtime/build/python pytest -q ../libs/qec/python/tests/test_chromobius.py

wsttiger added 3 commits May 2, 2026 22:55
Add a QEC decoder plugin wrapping Chromobius through the existing decoder
factory API. The wrapper accepts a Stim DEM via params, packs detector
syndromes for Chromobius, and returns predicted observable flips.

Also add Chromobius plugin build wiring and focused unit tests covering
construction, decoding, DEM path loading, and validation failures.

Fix a PyMatching pointer member access that broke the plugin build.

Signed-off-by: Scott Thornton <wsttiger@gmail.com>
- Register the Chromobius decoder with the CUDA-QX extension-point macro
- Add small upstream-derived DEM/reference shot data for observable predictions
- Add C++ and Python tests that validate single-shot and batched Chromobius decode results
- Keep the GCC 12 GTest workaround private so it does not leak into CUDA test builds
- Apply minor formatting cleanups in touched tests/headers

Signed-off-by: Scott Thornton <wsttiger@gmail.com>
@wsttiger wsttiger requested review from bmhowe23, kvmto and melody-ren May 15, 2026 22:15
Signed-off-by: Scott Thornton <wsttiger@gmail.com>
@wsttiger wsttiger force-pushed the add_chromobius_decoder branch from fc04644 to 5587a30 Compare May 18, 2026 04:22
std::string get_dem_text(const cudaqx::heterogeneous_map &params) {
if (params.contains("dem"))
return params.get<std::string>("dem");
if (params.contains("dem_str"))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dem_str is a functional duplicate of dem — same getstd::string lookup, same return, no transformation, and dem wins if both are passed.

Grepping the repo turns up zero callers of dem_stras a parameter key: neither test_chromobius.cpp nor test_chromobius.py exercises it, and there are no examples or docs that pass it.

Suggest dropping dem_str from get_dem_text and keeping just dem / dem_path

}

TEST(ChromobiusDecoder, checkDemPath) {
const std::string dem_path = "/tmp/cudaq_qec_chromobius_test.dem";

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm generally wary of hardcoded path

@@ -0,0 +1,8 @@
# Reference case from quantumlib/chromobius:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this mean that this file and the .tsv are both straight from the quantumlib/chromobius repo? If so, I think we need to add a readme or a license file/header. @bmhowe23 What's the general rule of thumb on this?

std::fill(packed_detection_events.begin(), packed_detection_events.end(),
uint8_t{0});
for (std::size_t i = 0; i < syndrome.size(); ++i) {
if (syndrome[i] >= 0.5)

@melody-ren melody-ren May 19, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we are doing the comparison directly. I think in the base class header decoder.h, we have helpers that does this. (call cudaq::qec::convert_vec_soft_to_hard(syndrome, hard_buf)). Using the helper will prevent future drift and match the pattern that both the sliding_window and the nv-qldpc decoder use.

I'm aware that there are other instances in our repo currently that still do this manual comparison. I'll make a new issue to track those.

Signed-off-by: Scott Thornton <wsttiger@gmail.com>
chromobius(const cudaqx::tensor<uint8_t> &H,
const cudaqx::heterogeneous_map &params)
: decoder(H), dem(get_dem_text(params)) {
auto H_shape = H.shape();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is H actually used anywhere?

FetchContent_Declare(
chromobius
GIT_REPOSITORY https://github.com/quantumlib/chromobius.git
GIT_TAG efae0325e4a8fc13be981434d38e499aa06b989f # v1.1.1

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please make sure to file the OSRB paperwork for this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants