Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add initial C API for circuit construction #14006

Open
wants to merge 13 commits into
base: main
Choose a base branch
from

Conversation

mtreinish
Copy link
Member

@mtreinish mtreinish commented Mar 12, 2025

Summary

Building off the infrastructure for the sparse observable added in
PR #13445 this commit adds a C FFI for building Quantum Circuits. Right
now there is a function to create an empty circuit with n qubits and m
clbits and then a function to add standard gates to a circuit and then
also get the op counts out of a circuit. This is a start of the
functionality for a C API around interacting with circuits, later PRs
will expand this so we can have a more fully featured C API in the
future.

Details and comments

Part of #13276

This PR is based on top of #13986 and will need to rebased after that merges. To see the contents of just this PR you can look at: mtreinish/qiskit-core@no-py-token-constructor-path...mtreinish:qiskit-core:c-api-circuit-rebased

TODO:

  • Add release notes

@mtreinish mtreinish added Changelog: New Feature Include in the "Added" section of the changelog Rust This PR or issue is related to Rust code in the repository mod: circuit Related to the core of the `QuantumCircuit` class or the circuit library C API Related to the C API labels Mar 12, 2025
@mtreinish mtreinish added this to the 2.1.0 milestone Mar 12, 2025
@mtreinish mtreinish requested a review from a team as a code owner March 12, 2025 16:05
@qiskit-bot
Copy link
Collaborator

One or more of the following people are relevant to this code:

  • @Qiskit/terra-core
  • @levbishop

@mtreinish mtreinish force-pushed the c-api-circuit-rebased branch from d3d226a to 590e7a8 Compare March 12, 2025 16:49
Copy link
Contributor

@Cryoris Cryoris left a comment

Choose a reason for hiding this comment

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

This looks really cool! I left some comments below 🙂

@mtreinish mtreinish force-pushed the c-api-circuit-rebased branch from 2e02dc1 to bbde5e5 Compare March 12, 2025 19:50
@coveralls
Copy link

coveralls commented Mar 12, 2025

Pull Request Test Coverage Report for Build 13924464330

Warning: This coverage report may be inaccurate.

This pull request's base commit is no longer the HEAD commit of its target branch. This means it includes changes from outside the original pull request, including, potentially, unrelated coverage changes.

Details

  • 14 of 270 (5.19%) changed or added relevant lines in 5 files are covered.
  • 6 unchanged lines in 2 files lost coverage.
  • Overall coverage decreased (-0.3%) to 87.831%

Changes Missing Coverage Covered Lines Changed/Added Lines %
crates/cext/src/pointers.rs 0 19 0.0%
crates/cext/src/circuit.rs 0 237 0.0%
Files with Coverage Reduction New Missed Lines %
crates/accelerate/src/unitary_synthesis.rs 1 94.69%
crates/qasm2/src/lex.rs 5 92.23%
Totals Coverage Status
Change from base Build 13905217637: -0.3%
Covered Lines: 72598
Relevant Lines: 82656

💛 - Coveralls

mtreinish and others added 6 commits March 14, 2025 17:25
Building off the infrastructure for the sparse observable added in
PR Qiskit#13445 this commit adds a C FFI for building Quantum Circuits. Right
now there is a function to create an empty circuit with n qubits and m
clbits and then a function to add standard gates to a circuit and then
also get the op counts out of a circuit. This is a start of the
functionality for a C API around interacting with circuits, later PRs
will expand this so we can have a more fully featured C API in the
future.

Part of Qiskit#13276
This also updates the test logic to make sure we always free even in
case of a failure.
@mtreinish mtreinish force-pushed the c-api-circuit-rebased branch from 3e62ec6 to 669695a Compare March 15, 2025 18:22
@mtreinish mtreinish changed the title [WIP] Add initial C API for circuit construction Add initial C API for circuit construction Mar 15, 2025
/// Behavior is undefined ``circuit`` is not a valid, non-null pointer to a ``QkCircuit``.
#[no_mangle]
#[cfg(feature = "cbinding")]
pub unsafe extern "C" fn qk_circuit_append_measure(
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we just call this qk_circuit_measure (same for the other directives)? The append doesn't really add any information, or what do you think?

Copy link
Member Author

Choose a reason for hiding this comment

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

I can drop append if you prefer. I named it this way because of the gate function I used append.

circuit: *mut CircuitData,
qubit: u32,
) -> ExitCode {
let circuit = unsafe { mut_ptr_as_ref(circuit) };
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm surprised cargo doesn't complain (maybe because of unsafe?) but the circuit should be declared mut if we push onto it, no? The same holds for the other methods 🙂

/// Behavior is undefined if ``inst`` is not an object returned by ``qk_circuit_get_instruction``.
#[no_mangle]
#[cfg(feature = "cbinding")]
pub unsafe extern "C" fn qk_free_circuit_instruction(inst: CInstruction) {
Copy link
Contributor

@Cryoris Cryoris Mar 18, 2025

Choose a reason for hiding this comment

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

This should be qk_circuit_instruction_free for consistency -- and should it take a pointer to a CInstruction otherwise the struct would get passed by value? Same question actually below for OpCounts 🙂

Copy link
Member Author

Choose a reason for hiding this comment

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

It does take it by value, but that's because we're freeing the pointers that are contained in the struct not the struct itself. Each CInstruction has 4 pointers to a heap allocated arrays that we need to free. If we just drop the instruction those would be leaked. We can take a pointer to CInstruction but it functionally doesn't matter in this case because the struct itself isn't what we're freeing.

mtreinish and others added 5 commits March 18, 2025 06:56
Locally I was using clang-format-19 while in CI we run with
clang-format-14. Version 14 was flagging this difference while version
19 was happy. This commit makes the change to make version 14 happy in
CI.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C API Related to the C API Changelog: New Feature Include in the "Added" section of the changelog mod: circuit Related to the core of the `QuantumCircuit` class or the circuit library priority: high Rust This PR or issue is related to Rust code in the repository
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants