Skip to content

✨ Implement getInputQubits()/getOutputQubits()#1474

Merged
burgholzer merged 10 commits intomainfrom
taminob/mlir-qco-add-qubit-range-getter
Feb 2, 2026
Merged

✨ Implement getInputQubits()/getOutputQubits()#1474
burgholzer merged 10 commits intomainfrom
taminob/mlir-qco-add-qubit-range-getter

Conversation

@taminob
Copy link
Collaborator

@taminob taminob commented Jan 21, 2026

Description

Introduce getInputQubits() and getOutputQubits() which is especially required for a smooth interaction with CtrlOp through UnitaryOpInterface.

Checklist:

  • The pull request only contains commits that are focused and relevant to this change.
  • I have added appropriate tests that cover the new/changed functionality.
  • I have updated the documentation to reflect these changes.
  • I have added entries to the changelog for any noteworthy additions, changes, fixes, or removals.
  • I have added migration instructions to the upgrade guide (if needed).
  • The changes follow the project's style guidelines and introduce no new warnings.
  • The changes are fully tested and pass the CI checks.
  • I have reviewed my own code changes.

@taminob taminob self-assigned this Jan 21, 2026
@taminob taminob added enhancement Improvement of existing feature c++ Anything related to C++ code MLIR Anything related to MLIR labels Jan 21, 2026
@codecov
Copy link

codecov bot commented Jan 22, 2026

Codecov Report

❌ Patch coverage is 0% with 9 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
mlir/lib/Dialect/QCO/IR/Modifiers/CtrlOp.cpp 0.0% 4 Missing ⚠️
mlir/include/mlir/Dialect/QCO/IR/QCODialect.h 0.0% 3 Missing ⚠️
...lect/QCO/IR/Operations/StandardGates/BarrierOp.cpp 0.0% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

@taminob taminob force-pushed the taminob/mlir-qco-add-qubit-range-getter branch from 92f0867 to 9cf79c3 Compare January 24, 2026 17:35
@taminob taminob marked this pull request as ready for review January 24, 2026 17:35
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 24, 2026

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added bulk input/output qubit accessors across unitary, barrier, and control operations for range-based qubit handling.
  • Bug Fixes

    • Control operation qubit handling corrected to consistently use the new input/output ranges for non-control qubits.
  • Documentation

    • Added a grouping comment to clarify unitary matrix helper methods.
  • Chores

    • Updated Unreleased changelog entry with the new PR reference.

Walkthrough

Adds bulk accessor methods getInputQubits() and getOutputQubits() across QCO traits, interfaces, and ops; updates CtrlOp single‑qubit resolution to read non‑control qubits directly from targets and implements the new range accessors.

Changes

Cohort / File(s) Summary
Traits & Interfaces
mlir/include/mlir/Dialect/QCO/IR/QCODialect.h, mlir/include/mlir/Dialect/QCO/IR/QCOInterfaces.td, mlir/include/mlir/Dialect/QCO/IR/QCOOps.td
Added getInputQubits() and getOutputQubits() declarations to TargetAndParameterArityTrait::Impl, UnitaryOpInterface, and op extraClassDeclaration (BarrierOp, CtrlOp) to expose operand/result ranges.
CtrlOp implementation
mlir/lib/Dialect/QCO/IR/Modifiers/CtrlOp.cpp
Changed non-control single‑qubit resolution to use getTargetsIn()/getTargetsOut() instead of delegating to the body unitary; added getInputQubits() / getOutputQubits() returning operand/result ranges.
BarrierOp implementation
mlir/lib/Dialect/QCO/IR/Operations/StandardGates/BarrierOp.cpp
Implemented getInputQubits() / getOutputQubits() as wrappers returning getQubitsIn() / getQubitsOut().
Changelog
CHANGELOG.md
Added PR reference [#1474] to Unreleased "Added" and appended to "Changed" links.

Sequence Diagram(s)

sequenceDiagram
  participant Caller as Caller
  participant CtrlOp as CtrlOp
  participant Targets as Targets (operands)
  participant Body as BodyUnitary
  participant Results as Results

  Note over Caller,Results: Old flow (before this change)
  Caller->>CtrlOp: getInputQubit(i)
  CtrlOp->>Body: getInputQubit(i)  -- delegate to body unitary
  Body-->>CtrlOp: Operand (resolved)
  CtrlOp-->>Caller: Operand

  Note over Caller,Results: New flow (after this change)
  Caller->>CtrlOp: getInputQubits() / getInputQubit(i)
  CtrlOp->>Targets: read getTargetsIn() (first T operands)
  Targets-->>CtrlOp: OperandRange
  CtrlOp-->>Caller: OperandRange
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • burgholzer

Poem

🐇 I hop through circuits, soft and spry,

bundling qubits where the targets lie,
controls and targets in tidy queues,
handed in ranges for simpler views,
a nibble of code and a carrot-sized sigh.

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.88% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The description provides a clear purpose but lacks details on dependencies, testing, and documentation updates. Most checklist items remain unchecked, indicating incomplete coverage of required documentation. Expand the description with specific details about testing, documentation changes, and verification of checklist items before merging.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: implementing two new methods (getInputQubits/getOutputQubits), which aligns with the PR's core objective.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch taminob/mlir-qco-add-qubit-range-getter

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@mlir/include/mlir/Dialect/QCO/IR/QCODialect.h`:
- Around line 83-87: The assertion in getInputQubits() is off-by-one and wrongly
requires operands.size() to be greater than T; change the check to allow
equality so take_front(T) is valid when operands.size() == T. Update the assert
in ValueRange getInputQubits() (method getInputQubits of the QCODialect/op
class) from asserting T < operands.size() to asserting T <= operands.size() so
it correctly permits zero-parameter cases.

In `@mlir/lib/Dialect/QCO/IR/Modifiers/CtrlOp.cpp`:
- Around line 190-198: CtrlOp::getOutputQubits returns targets then controls,
which contradicts getOutputQubit(i) that returns controls first; swap the concat
arguments so the returned ValueRange is controls followed by targets (i.e. call
llvm::concat<Value> with ValueRange{getControlsOut()} then
ValueRange{getTargetsOut()}) to match per‑qubit accessor ordering and keep
CtrlOp::getOutputQubits consistent with getOutputQubit.
- Around line 169-177: getInputQubits() currently concatenates targets then
controls (using llvm::concat<Value>(ValueRange{getTargetsIn()},
ValueRange{getControlsIn()}), producing a different ordering than
getInputQubit(i) which returns controls first. Fix getInputQubits() to
concatenate controls then targets (i.e., use llvm::concat with
ValueRange{getControlsIn()} followed by ValueRange{getTargetsIn()}) so that
getInputQubits()[i] matches getInputQubit(i); keep using the same ValueRange
wrapping to avoid changing storage semantics.

This change will hopefully shorten debug times for optimization patterns
that introduce new gates. Especially when inserting gates with constant
parameters, caution is advised when working with circuits containing
controlled gates because the pattern will also be applied to the
operation inside the control body - potentially leading to undesired
operations in the control body. This assertion should make this easier
to spot and debug.
@taminob taminob force-pushed the taminob/mlir-qco-add-qubit-range-getter branch from 147f2d5 to 8baf49c Compare January 27, 2026 22:06
@taminob taminob requested a review from burgholzer January 27, 2026 22:06
taminob added a commit that referenced this pull request Jan 31, 2026
Signed-off-by: burgholzer <burgholzer@me.com>
Copy link
Member

@burgholzer burgholzer left a comment

Choose a reason for hiding this comment

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

Okay. After spending some more time on this, I found a way cleaner solution that should also be the most performant one.
There is no need to perform any kind of iterator concatenation here.

@taminob You may want to add this PR to the changelog list.
Once CI is green, this is ready to go from my side.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@mlir/include/mlir/Dialect/QCO/IR/QCOInterfaces.td`:
- Around line 105-118: The documentation for the bulk range accessors lacks an
ordering contract; update the docstrings for InterfaceMethod entries
getInputQubits and getOutputQubits (and the singular getOutputQubit) to state
explicitly that the ranges are ordered the same way as the per-element accessors
(e.g., getInputQubit(i) / getOutputQubit(i)), so callers can rely on consistent
index-based correspondence between the singular getters and the returned
OperandRange/ResultRange.

@taminob
Copy link
Collaborator Author

taminob commented Feb 2, 2026

Okay. After spending some more time on this, I found a way cleaner solution that should also be the most performant one. There is no need to perform any kind of iterator concatenation here.

Thanks for looking into this - I feel slightly stupid for not seeing this simple solution...
This is definitely way more elegant than my workaround.

@taminob You may want to add this PR to the changelog list. Once CI is green, this is ready to go from my side.

I will rebase the branch and add it to the changelog 👍

@burgholzer
Copy link
Member

@taminob didn't you want to add it to the changelog too? ;-)

@burgholzer burgholzer enabled auto-merge (squash) February 2, 2026 16:09
@burgholzer burgholzer merged commit 4e9f745 into main Feb 2, 2026
29 of 30 checks passed
@burgholzer burgholzer deleted the taminob/mlir-qco-add-qubit-range-getter branch February 2, 2026 16:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c++ Anything related to C++ code enhancement Improvement of existing feature MLIR Anything related to MLIR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants