Skip to content

added adaptive profile support for qbraid_qir#225

Merged
TheGupta2012 merged 24 commits intoqBraid:mainfrom
feelerx:Adaptive-Profile
Jun 10, 2025
Merged

added adaptive profile support for qbraid_qir#225
TheGupta2012 merged 24 commits intoqBraid:mainfrom
feelerx:Adaptive-Profile

Conversation

@feelerx
Copy link
Copy Markdown
Contributor

@feelerx feelerx commented May 28, 2025

Summary of changes

Adaptive Execution Profile
The Adaptive Execution Profile (adaptive_profile.json) enables:

  • Conditional Execution: Support for if/else statements based on measurement results
  • Qubit Reuse: Operations on qubits after measurement (with proper state tracking)
  • Advanced Output Recording: Preserves register structure and grouping
  • Measurement State Tracking: Per-qubit measurement state management

Key differences from qbraid_qir custom Profile:

  • Uses qis.* functions instead of pyqir._native.* for better adaptive support
  • Implements measurement state tracking for post-measurement qubit operations
  • Provides register-grouped output recording
  • Supports configurable barrier emission

Profile Structure
Each profile is defined as a JSON file with the following structure:

{
  "profile_name": "ProfileName",
  "version": "1.0.0",
  "description": "Profile description",
  "capabilities": {
    "feature_name": {
      "enabled": true,
      "description": "Feature description",
      "additional_options": "..."
    }
  },
  "required_functions": {
    "quantum_intrinsics": ["function_list"],
    "runtime_functions": ["function_list"]
  },
  "restrictions": {
    "restriction_category": {
      "setting": "value"
    }
  },
  "validation_rules": {
    "rule_category": {
      "rule_name": "rule_value"
    }
  },
  "compliance_checks": [
    {
      "rule_id": "PROFILE_001",
      "description": "Rule description",
      "severity": "error|warning|info",
      "check_type": "check_category"
    }
  ]
}

Compliance Issues Identified

  1. Function Usage Compliance (CRITICAL)
    Issue: Custom profile uses pyqir._native.* functions while adaptive profile requires qis.* functions.

Custom Profile

pyqir._native.mz(self._builder, src_id, tgt_id)
pyqir._native.reset(self._builder, qid) 
pyqir._native.if_result(self._builder, result, ...)
pyqir._native.barrier(self._builder)

Adaptive Profile:

qis.mz(self._builder, src_id, tgt_id)
qis.reset(self._builder, qid)
qis.if_result(self._builder, result, ...)
qis.barrier(self._builder)

Impact: Native functions don't provide the adaptive execution semantics required for conditional branching and qubit reuse.

  1. Measurement State Tracking (MEDIUM)
    Issue: Base profile doesn't track which qubits have been measured.

Adaptive Profile Addition:

self._measured_qubits: dict[int, bool] = {}  # Track measured qubits

# In measurement:
qubit_id = pyqir.qubit_id(src_id)
self._measured_qubits[qubit_id] = True

# In reset:
self._measured_qubits[qubit_id] = False

Impact: Without tracking, post-measurement operations can't be properly validated or optimized.

  1. Output Recording Structure (HIGH)
    Issue: Custom profile records output bit-by-bit, losing register structure.

Custom Profile:

for i in range(module.qasm_program.num_qubits):
    result_ref = pyqir.result(self._llvm_module.context, i)
    pyqir.rt.result_record_output(self._builder, result_ref, pyqir.Constant.null(i8p))

Adaptive Profile:

# Record array for each register
for reg_name, reg_size in self._global_creg_size_map.items():
    pyqir.rt.array_record_output(self._builder, ...)
    # Then record individual results within register
    for i in range(reg_size - 1, -1, -1):  # Inverted order
        # Record individual bits...

Impact: Register structure is lost, making it difficult for adaptive runtimes to process results correctly.

  1. Qubit Use Validation (LOW)
    Issue:Custom profile doesn't validate qubit usage patterns for adaptive execution.
    Adaptive Profile Addition:
def _check_qubit_use_after_measurement(self, qubit_ids: list[pyqir.Constant]) -> None:
    """Check if any qubits have been measured before use (adaptive profile allows this)."""
    # In adaptive profile, qubit use after measurement is allowed
    # This is a key difference from custom profile
    pass

Impact: No validation of post-measurement qubit operations, which may be restricted in some execution environments.

  1. Barrier Configuration (LOW)
    Issue: Custom profile always emits barriers when applicable.
    Adaptive Profile Addition:
def __init__(self, ..., emit_barrier_calls: bool = False):
    self._emit_barrier_calls = emit_barrier_calls

# In barrier handling:
if self._emit_barrier_calls:
    qis.barrier(self._builder)

Impact: Some adaptive runtimes may not support or need explicit barrier operations.

@ryanhill1 ryanhill1 requested a review from TheGupta2012 May 28, 2025 17:03
@ryanhill1 ryanhill1 linked an issue May 28, 2025 that may be closed by this pull request
@codecov
Copy link
Copy Markdown

codecov bot commented May 29, 2025

Codecov Report

Attention: Patch coverage is 89.13043% with 30 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
qbraid_qir/qasm3/visitor.py 78.65% 19 Missing ⚠️
qbraid_qir/profiles/core.py 94.92% 7 Missing ⚠️
qbraid_qir/qasm3/convert.py 83.33% 3 Missing ⚠️
qbraid_qir/qasm3/elements.py 90.00% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

Copy link
Copy Markdown
Member

@TheGupta2012 TheGupta2012 left a comment

Choose a reason for hiding this comment

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

Hi @feelerx, thanks so much for working on this!
Your initial code looks good and I've given some comments on the overall design. Once your updates are completed, can you also add tests for the verification of adaptive profiles?

@TheGupta2012
Copy link
Copy Markdown
Member

TheGupta2012 commented Jun 2, 2025

The PR is quite close @feelerx , thanks for the great work!
Other than some minor refactoring suggestions, the only major change I'd want is adding test cases for verification.

Besides that, could you also add an entry to the CHANGELOG.md with a link to this PR?

@TheGupta2012 TheGupta2012 self-requested a review June 5, 2025 09:27
Copy link
Copy Markdown
Member

@TheGupta2012 TheGupta2012 left a comment

Choose a reason for hiding this comment

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

Changes look good, thanks for the work!

Copy link
Copy Markdown
Member

@ryanhill1 ryanhill1 left a comment

Choose a reason for hiding this comment

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

We might need to update MANIFEST.in to also include json files from qbraid_qir/qasm3/profiles

Edit: Actually maybe not. Might be fine to not include

@TheGupta2012
Copy link
Copy Markdown
Member

@ryanhill1 this lgtm, can you approve as well?

Copy link
Copy Markdown
Member

@ryanhill1 ryanhill1 left a comment

Choose a reason for hiding this comment

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

Shouldn't we put this code in a module qbraid_qir/profiles, not qbraid_qir/qasm3/profiles, since it is not unique to qasm3, and could also eventually be leveraged by the cirq module as well?

"""


# profile/__init__.py
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.

Suggested change
# profile/__init__.py

return cls._profiles[name]

@classmethod
def list_profiles(cls) -> List[str]:
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.

Suggested change
def list_profiles(cls) -> List[str]:
def list_profiles(cls) -> list[str]:

initialize_runtime: bool = True,
record_output: bool = True,
external_gates: list[str] | None = None,
external_gates: Optional[List[str]] = None,
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.

Suggested change
external_gates: Optional[List[str]] = None,
external_gates: Optional[list[str]] = None,

@feelerx
Copy link
Copy Markdown
Contributor Author

feelerx commented Jun 6, 2025

Shouldn't we put this code in a module qbraid_qir/profiles, not qbraid_qir/qasm3/profiles, since it is not unique to qasm3, and could also eventually be leveraged by the cirq module as well?

core.py in qbraid_qir/qasm3/profiles makes calls to QasmQIRVisitor and QasmQIRModule. Making it unique to qasm3.

@TheGupta2012
Copy link
Copy Markdown
Member

@ryanhill1 yeah I think that makes sense, most likely Cirq could benefit from the profiles too.

@feelerx
Copy link
Copy Markdown
Contributor Author

feelerx commented Jun 6, 2025

@ryanhill1 yeah I think that makes sense, most likely Cirq could benefit from the profiles too.

@TheGupta2012 core.py is unique to qasm3. The other 2 json files aren't. Should I move only the 2 of them?

@feelerx feelerx force-pushed the Adaptive-Profile branch from 33dea9b to 9eaf059 Compare June 6, 2025 17:35
@ryanhill1
Copy link
Copy Markdown
Member

ryanhill1 commented Jun 6, 2025

Maybe we want to create abstract QIRVisitor and QIRModule classes at the qbraid_qir top-level which the cirq and qasm3 visitor / module classes inherit from, and then have the AdaptiveProfile and BaseProfile classes reference the abstract visitor / module classes instead of the specific QasmQIRVisitor and QasmQIRModule classes?

… abstracted visitor and module classes so both cirq and qasm can use core.py
@ryanhill1 ryanhill1 requested a review from TheGupta2012 June 8, 2025 16:10
# See the License for the specific language governing permissions and
# limitations under the License.

"""
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 doesn't really have much relevance inside the profiles, let's move it to qbraid_qir/abstract.py

Copy link
Copy Markdown
Member

@ryanhill1 ryanhill1 Jun 9, 2025

Choose a reason for hiding this comment

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

Or qbraid_qir/profiles.py for more clarity

Copy link
Copy Markdown
Member

@ryanhill1 ryanhill1 left a comment

Choose a reason for hiding this comment

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

Still a few things that will need tweaking down the road, and some other organizational things that could be improved, but for now this is OK. Can address those things later. Main functionality is there, so will approve this

@TheGupta2012 TheGupta2012 merged commit e1e80ef into qBraid:main Jun 10, 2025
6 of 7 checks passed
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.

[FEATURE] QIR Adaptive Profile compliant QASM conversions

3 participants