Skip to content

fix: unwrap qir bitcode wrappers before qir-qis conversion#161

Closed
qartik wants to merge 1 commit intomainfrom
ks-fix-qir-bitcode-wrapper
Closed

fix: unwrap qir bitcode wrappers before qir-qis conversion#161
qartik wants to merge 1 commit intomainfrom
ks-fix-qir-bitcode-wrapper

Conversation

@qartik
Copy link
Copy Markdown
Member

@qartik qartik commented Apr 21, 2026

Summary

  • unwrap wrapped QIR bitcode before passing it to qir_qis
  • preserve compatibility for plain bytes and LLVM IR text inputs
  • add Selene-side regressions for wrapped QIR and wrapped lowered-QIS inputs

Root Cause

QIRBitcodeStringKind accepted wrapper-style inputs with a .bitcode attribute, but the QIR-to-Helios step still passed the wrapper object itself into validate_qir(...) and qir_to_qis(...). That made build(BitcodeString(qir_bc)) fail even though the same artifact worked as plain bytes.

Source Of Regression

This behavior was introduced in PR #114 (feat: QIR support using QIR-QIS, commit 70ab294), which added direct QIR support together with the BitcodeString-compatible matcher and the QIR-to-Helios conversion step. The matcher unwrapped .bitcode, but the conversion step still forwarded the wrapper object itself into qir_qis.

PR #157 is related context but not the introducing change. That patch fixed QIR-vs-Helios classification for lowered qir-qis output; it did not address this wrapper-handling gap in the QIR conversion step.

Validation

  • uv run pytest selene-sim/python/tests/test_build_classification.py -q
  • uv run pytest selene-sim/python/tests/test_qir.py -q

@qartik qartik marked this pull request as ready for review April 21, 2026 14:40
@qartik qartik requested a review from jake-arkinstall as a code owner April 21, 2026 14:40
@qartik qartik requested a review from Copilot April 21, 2026 14:40
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes build failures when QIR bitcode is provided via wrapper objects (with a .bitcode attribute) by unwrapping before calling qir_qis conversion/validation, and adds regressions to cover wrapped inputs.

Changes:

  • Add a helper to unwrap .bitcode wrappers and use it in QIR bitcode kind matching and QIR→QIS conversion.
  • Ensure QIR validation/conversion receives raw bytes rather than wrapper objects.
  • Add tests to ensure wrapped QIR and wrapped lowered-QIS bitcode can be built successfully.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
selene-sim/python/tests/test_build_classification.py Adds regression tests that build from wrapped QIR and wrapped translated QIS bitcode.
selene-core/python/selene_core/build_utils/builtins/qir.py Introduces _unwrap_bitcode_resource(...) and uses it to unwrap wrappers before QIR validation/conversion.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +12 to +15
def _unwrap_bitcode_resource(resource: Any) -> bytes | None:
if hasattr(resource, "bitcode"):
resource = resource.bitcode
return resource if isinstance(resource, bytes) else None
Copy link

Copilot AI Apr 21, 2026

Choose a reason for hiding this comment

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

QIRBitcodeStringKind.matches now accepts wrapper objects with a .bitcode attribute, but not all steps that consume QIRBitcodeStringKind unwrap the resource. In particular, QIRBitcodeStringToQIRBitcodeFileStep.apply still calls out_path.write_bytes(input_artifact.resource), which will raise a TypeError if the resource is a wrapper. Consider unwrapping there as well (e.g., via _unwrap_bitcode_resource) to keep wrapper support consistent across the QIR bitcode pipeline.

Copilot uses AI. Check for mistakes.
validate_qir(input_artifact.resource)
result = qir_to_qis(input_artifact.resource)
bitcode = _unwrap_bitcode_resource(input_artifact.resource)
assert bitcode is not None, "QIR bitcode step received a non-bitcode resource"
Copy link

Copilot AI Apr 21, 2026

Choose a reason for hiding this comment

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

Avoid using assert for validating runtime inputs here. Assertions can be disabled with python -O, which would skip the check and produce a less clear downstream failure in validate_qir(...)/qir_to_qis(...). Prefer raising a regular exception (e.g., TypeError/ValueError) when _unwrap_bitcode_resource(...) returns None.

Suggested change
assert bitcode is not None, "QIR bitcode step received a non-bitcode resource"
if bitcode is None:
raise TypeError("QIR bitcode step received a non-bitcode resource")

Copilot uses AI. Check for mistakes.
@qartik qartik marked this pull request as draft April 21, 2026 15:55
@qartik
Copy link
Copy Markdown
Member Author

qartik commented Apr 21, 2026

Unneeded, there was a regression in qir-qis with the inkwell 0.9 upgrade that's resolved in Quantinuum/qir-qis#72

@qartik qartik closed this Apr 21, 2026
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