Skip to content

✨ Add OpenQASM-to-QC translation#1780

Merged
denialhaag merged 54 commits into
mainfrom
open-qasm
Jun 18, 2026
Merged

✨ Add OpenQASM-to-QC translation#1780
denialhaag merged 54 commits into
mainfrom
open-qasm

Conversation

@denialhaag

@denialhaag denialhaag commented Jun 11, 2026

Copy link
Copy Markdown
Member

Description

This is a rebased version of #1671 after #1671 was automatically closed when #1751 was merged.

Original description by @J4MMlE:

Description

This PR adds a direct OpenQASM-to-QC translation that bypasses the qc::QuantumComputation.

The new flow reuses the existing parser and walks the AST directly to emit QC dialect ops. Skipping QuantumComputation removes an intermediate step and enables previously unsupported QASM3 features, such as gate modifiers, classical computations, and control flow structures.

What works

  • All standard gates plus Qiskit-style MCX variants
  • Gate modifiers: ctrl @, negctrl @, inv @, nested combinations
  • Register declarations, qubit/bit allocation
  • Measure, reset, barrier
  • if/else over quantum statements
  • Hardware qubits convert to qc.static
  • Broadcasting (register-width gate calls)

Current limitations

  • Gate parameters must be compile-time constants
  • pow modifier is unsupported (but will/should be once #1603 is merged)
  • Layout pragmas are unsupported (they have no equivalent in QC)

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.

@denialhaag denialhaag self-assigned this Jun 11, 2026
@denialhaag denialhaag added feature New feature or request MLIR Anything related to MLIR labels Jun 11, 2026
@denialhaag denialhaag added this to the MLIR Support milestone Jun 11, 2026
@codecov

codecov Bot commented Jun 11, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 81.62839% with 88 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
.../lib/Dialect/QC/Translation/TranslateQASM3ToQC.cpp 81.6% 88 Missing ⚠️

📢 Thoughts on this report? Let us know!

@denialhaag

Copy link
Copy Markdown
Member Author

A thought that came up while reviewing this: how much is the current architecture of the parser and the visitor implementation limiting us in terms of expanding the capabilities?
There are quite a few things from the OQ3 spec that we would want to support (loops being one of the most prominent ones).
Would it be interesting to define our own OpenQASM3 dialect (inspired by the qe-compiler one) that can directly parse in QASM files. And then we would write a conversion to MLIR standard dialects plus QC. Does that make sense? Is that overkill? To me it feels like this could generally make sense. What do you think?

I will think about this a bit and respond tomorrow!

@denialhaag denialhaag requested a review from burgholzer June 18, 2026 00:19
@denialhaag

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@mlir/include/mlir/Dialect/QC/Translation/TranslateQASM3ToQC.h`:
- Around line 13-26: The function translateQASM3ToQC uses OwningOpRef<ModuleOp>
as its return type but the header does not directly include the definition of
OwningOpRef, relying instead on transitive includes from BuiltinOps.h. Add
`#include` <mlir/IR/OwningOpRef.h> to the include section at the top of the file
along with the other mlir includes to make this header self-contained and
explicit about its dependencies.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4b5a8e6b-daab-46b3-96dc-c6efd737f14b

📥 Commits

Reviewing files that changed from the base of the PR and between 40e31f7 and 86bbf4b.

📒 Files selected for processing (7)
  • mlir/include/mlir/Dialect/QC/Translation/TranslateQASM3ToQC.h
  • mlir/lib/Dialect/QC/Translation/TranslateQASM3ToQC.cpp
  • mlir/tools/mqt-cc/CMakeLists.txt
  • mlir/tools/mqt-cc/mqt-cc.cpp
  • mlir/unittests/Dialect/QC/Translation/test_qasm3_translation.cpp
  • mlir/unittests/programs/qasm_programs.cpp
  • mlir/unittests/programs/qasm_programs.h
💤 Files with no reviewable changes (1)
  • mlir/tools/mqt-cc/CMakeLists.txt

Comment thread mlir/include/mlir/Dialect/QC/Translation/TranslateQASM3ToQC.h Outdated

@burgholzer burgholzer left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is very close to being mergable 🙂

Comment thread mlir/tools/mqt-cc/CMakeLists.txt
@denialhaag denialhaag requested a review from burgholzer June 18, 2026 08:51
@denialhaag denialhaag merged commit 5a12960 into main Jun 18, 2026
32 of 33 checks passed
@denialhaag denialhaag deleted the open-qasm branch June 18, 2026 16:14
@denialhaag

Copy link
Copy Markdown
Member Author

Thanks a lot for getting this started, @J4MMlE! Your initial version was a great foundation! 🙂

@denialhaag

Copy link
Copy Markdown
Member Author

A thought that came up while reviewing this: how much is the current architecture of the parser and the visitor implementation limiting us in terms of expanding the capabilities? There are quite a few things from the OQ3 spec that we would want to support (loops being one of the most prominent ones).

The current implementation is certainly limiting. It's probably not wise to keep updating MQT Core's qasm3 package if are anyway transition away from the ir package.

Would it be interesting to define our own OpenQASM3 dialect (inspired by the qe-compiler one) that can directly parse in QASM files. And then we would write a conversion to MLIR standard dialects plus QC. Does that make sense? Is that overkill? To me it feels like this could generally make sense. What do you think?

I also like the sound of the idea, but I'm not sure if we are unnecessarily creating additional work for ourselves. If such an OpenQASM 3 dialect has a chance of becoming established, I see the point in going for it. However, if it were to be an internal "tool" only, I feel like we'd be creating another hoop to jump through. For example, in my opinion, the current translation from OpenQASM 3 to QC benefits from the QCProgramBuilder. If we were to define the translation to a new OpenQASM 3 dialect instead, do we also want an OpenQASM3ProgramBuilder? If yes, any infrastructure changes would need to be implemented in two additional locations (OpenQASM3ProgramBuilder and conversion from the OpenQASM 3 dialect to QC). Thought differently, if we were to define an OpenQASM 3 dialect with a builder, do we still want or need the QC dialect and its builder? Could we not just convert directly from OpenQASM 3 to QCO and QIR? The QC dialect would be losing its position as the input (i.e., translation) dialect anyway. Also, if we define an OpenQASM 3 dialect, should we also define a Qiskit dialect to ease the translation from Qiskit? (I'll admit that I'm playing devil's advocate here. The questions are more nuanced than that.)

In short, if we plan to establish the OpenQASM 3 dialect as a standard used by others (much like jeff-mlir), I like the idea. If not, I think we'd end up with one dialect (either OpenQASM 3 or QC) that would be a potentially pointless hoop in the pipeline.

Let me know what you think! One way or another, we need to ensure that we can translate arbitrary OpenQASM 3 programs into mqt-cc.

@burgholzer

Copy link
Copy Markdown
Member

A thought that came up while reviewing this: how much is the current architecture of the parser and the visitor implementation limiting us in terms of expanding the capabilities? There are quite a few things from the OQ3 spec that we would want to support (loops being one of the most prominent ones).

The current implementation is certainly limiting. It's probably not wise to keep updating MQT Core's qasm3 package if are anyway transition away from the ir package.

Yeah, I figured as much. The current parser implementation still ties quite heavily to the ir package and it is also shaped by quite a few of the limitations of the legacy MQT Core IR. Support for loops as well as general classical computation would be really nice to have and should actually match quite naturally to concept in MLIR.

Would it be interesting to define our own OpenQASM3 dialect (inspired by the qe-compiler one) that can directly parse in QASM files. And then we would write a conversion to MLIR standard dialects plus QC. Does that make sense? Is that overkill? To me it feels like this could generally make sense. What do you think?

I also like the sound of the idea, but I'm not sure if we are unnecessarily creating additional work for ourselves. If such an OpenQASM 3 dialect has a chance of becoming established, I see the point in going for it. However, if it were to be an internal "tool" only, I feel like we'd be creating another hoop to jump through. For example, in my opinion, the current translation from OpenQASM 3 to QC benefits from the QCProgramBuilder. If we were to define the translation to a new OpenQASM 3 dialect instead, do we also want an OpenQASM3ProgramBuilder? If yes, any infrastructure changes would need to be implemented in two additional locations (OpenQASM3ProgramBuilder and conversion from the OpenQASM 3 dialect to QC). Thought differently, if we were to define an OpenQASM 3 dialect with a builder, do we still want or need the QC dialect and its builder? Could we not just convert directly from OpenQASM 3 to QCO and QIR? The QC dialect would be losing its position as the input (i.e., translation) dialect anyway. Also, if we define an OpenQASM 3 dialect, should we also define a Qiskit dialect to ease the translation from Qiskit? (I'll admit that I'm playing devil's advocate here. The questions are more nuanced than that.)

In short, if we plan to establish the OpenQASM 3 dialect as a standard used by others (much like jeff-mlir), I like the idea. If not, I think we'd end up with one dialect (either OpenQASM 3 or QC) that would be a potentially pointless hoop in the pipeline.

Let me know what you think! One way or another, we need to ensure that we can translate arbitrary OpenQASM 3 programs into mqt-cc.

I would not like to create an OpenQASM3ProgramBuilder. On the one hand for the overhead reasons you mention. On the other hand, because OpenQASM is a well spec'd out language, where we can simply consume QASM files (or strings) as input. Furthermore, OpenQASM is one of the potential entry points into mqt-cc. It does not quite feel right to write our own "producer" for these files. That's the job of a frontend. The more frontends or program formats we connect, the less relevant the QCProgramBuilder becomes in my opinion; although it will probably remain relevant for quite some while because we will likely be able to represent and manipulate more complex hybrid program constructs in mqt-cc than we could create through translating from any frontend.

That being said, I would generally view an OpenQASM3 dialect as something fairly similar to jeff-mlir. A project that we maintain for the community and that can be consumed by the community. In the best case, we would define the dialect in a way that would allow us to directly read in OpenQASM3 programs (probably through custom parsers) and that allows us to emit an OpenQASM3 program from an MLIR module that only contains OpenQASM3 operations (probably through custom printers).
Similarly to jeff-mlir, we would provide some passes to map OQ3 constructs to standard dialects and back.
I believe this should be doable.
I am not yet quite sure whether we would want to maintain such a dialect out-of-tree (like jeff-mlir) or in-tree to keep it closer to the mqt-cc source code.

On the point whether we'd actually still need the QC dialect: I think we'd still need it. OQ3 does not define individual gates (X, Y, Z, S, etc.); it also mixes classical and quantum constructs. Translating that to clearly separated dialects (QC + Standard Dialects) seems valuable to me.

How does all of that sound?

@denialhaag

Copy link
Copy Markdown
Member Author

I would not like to create an OpenQASM3ProgramBuilder. On the one hand for the overhead reasons you mention. On the other hand, because OpenQASM is a well spec'd out language, where we can simply consume QASM files (or strings) as input. Furthermore, OpenQASM is one of the potential entry points into mqt-cc. It does not quite feel right to write our own "producer" for these files. That's the job of a frontend. The more frontends or program formats we connect, the less relevant the QCProgramBuilder becomes in my opinion; although it will probably remain relevant for quite some while because we will likely be able to represent and manipulate more complex hybrid program constructs in mqt-cc than we could create through translating from any frontend.

That being said, I would generally view an OpenQASM3 dialect as something fairly similar to jeff-mlir. A project that we maintain for the community and that can be consumed by the community. In the best case, we would define the dialect in a way that would allow us to directly read in OpenQASM3 programs (probably through custom parsers) and that allows us to emit an OpenQASM3 program from an MLIR module that only contains OpenQASM3 operations (probably through custom printers).
Similarly to jeff-mlir, we would provide some passes to map OQ3 constructs to standard dialects and back. I believe this should be doable.
I am not yet quite sure whether we would want to maintain such a dialect out-of-tree (like jeff-mlir) or in-tree to keep it closer to the mqt-cc source code.

On the point whether we'd actually still need the QC dialect: I think we'd still need it. OQ3 does not define individual gates (X, Y, Z, S, etc.); it also mixes classical and quantum constructs. Translating that to clearly separated dialects (QC + Standard Dialects) seems valuable to me.

How does all of that sound?

That all sounds good to me! I would be happy to get started on this rather soon, maybe after #1707 and potentially #1726. I don't have a super strong opinion on where the dialect should live. A repsoitory that contains the dialect, bi-directional translations, and bi-directional conversions (of everything but the gates) sounds neat, but it could also make sense within MQT Core. 🤔

@burgholzer

Copy link
Copy Markdown
Member

I would not like to create an OpenQASM3ProgramBuilder. On the one hand for the overhead reasons you mention. On the other hand, because OpenQASM is a well spec'd out language, where we can simply consume QASM files (or strings) as input. Furthermore, OpenQASM is one of the potential entry points into mqt-cc. It does not quite feel right to write our own "producer" for these files. That's the job of a frontend. The more frontends or program formats we connect, the less relevant the QCProgramBuilder becomes in my opinion; although it will probably remain relevant for quite some while because we will likely be able to represent and manipulate more complex hybrid program constructs in mqt-cc than we could create through translating from any frontend.

That being said, I would generally view an OpenQASM3 dialect as something fairly similar to jeff-mlir. A project that we maintain for the community and that can be consumed by the community. In the best case, we would define the dialect in a way that would allow us to directly read in OpenQASM3 programs (probably through custom parsers) and that allows us to emit an OpenQASM3 program from an MLIR module that only contains OpenQASM3 operations (probably through custom printers).

Similarly to jeff-mlir, we would provide some passes to map OQ3 constructs to standard dialects and back. I believe this should be doable.

I am not yet quite sure whether we would want to maintain such a dialect out-of-tree (like jeff-mlir) or in-tree to keep it closer to the mqt-cc source code.

On the point whether we'd actually still need the QC dialect: I think we'd still need it. OQ3 does not define individual gates (X, Y, Z, S, etc.); it also mixes classical and quantum constructs. Translating that to clearly separated dialects (QC + Standard Dialects) seems valuable to me.

How does all of that sound?

That all sounds good to me! I would be happy to get started on this rather soon, maybe after #1707 and potentially #1726. I don't have a super strong opinion on where the dialect should live. A repsoitory that contains the dialect, bi-directional translations, and bi-directional conversions (of everything but the gates) sounds neat, but it could also make sense within MQT Core. 🤔

Sounds like a plan to me!
It's probably best to get any internal dialect changes in before adding another intergration point that has to be updated constantly. I'd add the power modifier to the list of things that should be merged before the introduction of the dialect.

Since there is no obvious best choice for where the dialect should live, I'd argue let's keep it in MQT Core for now. We can always pull it out afterwards if that should proof beneficial.

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

Labels

feature New feature or request MLIR Anything related to MLIR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants