Skip to content

Conversation

raynelfss
Copy link
Contributor

@raynelfss raynelfss commented Apr 25, 2025

Summary

Fixes #14241 and #14376

The following commits enable a C FFI for creation of a Rust Target.

Details and comments

As we work into expanding Qiskit into working in C, it is important to bring parts of the transpiler into this domain. One such part is the Target, which contains a lot of information about the hardware a circuit will be executed in. The following commits expose a C FFI that allows us to create and interact with a Target directly from C.

In order to achieve this we have 3 types of pointers being exposed to C:

  • QkTarget - which points to a Target in Rust.
  • QkPropsMap - which represents a mapping between Qargs : InstructionProperties, or, in C terms, this would be a mapping of uint32_t[] : QkInstructionProps.

The C FFI should allow us to:

  • Fully build a Target based on standard gates QkGate, a list of parameters double[], and an optional QkPropsMap containing the instruction properties.
  • Update any of the QkTarget instruction's properties after being added.

@raynelfss raynelfss added mod: transpiler Issues and PRs related to Transpiler C API Related to the C API labels Apr 25, 2025
@coveralls
Copy link

coveralls commented Apr 25, 2025

Pull Request Test Coverage Report for Build 15447438495

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

  • 276 of 316 (87.34%) changed or added relevant lines in 5 files are covered.
  • 18 unchanged lines in 4 files lost coverage.
  • Overall coverage increased (+0.003%) to 87.906%

Changes Missing Coverage Covered Lines Changed/Added Lines %
crates/cext/src/exit_codes.rs 6 8 75.0%
crates/transpiler/src/target/mod.rs 34 40 85.0%
crates/cext/src/transpiler/target.rs 233 265 87.92%
Files with Coverage Reduction New Missed Lines %
crates/transpiler/src/passes/unitary_synthesis.rs 1 94.57%
crates/qasm2/src/lex.rs 2 92.23%
qiskit/transpiler/passes/layout/vf2_utils.py 3 93.33%
crates/qasm2/src/parse.rs 12 96.68%
Totals Coverage Status
Change from base Build 15440870635: 0.003%
Covered Lines: 81653
Relevant Lines: 92887

💛 - Coveralls

@eliarbel eliarbel added this to the 2.1.0 milestone Apr 27, 2025
@eliarbel eliarbel linked an issue Apr 28, 2025 that may be closed by this pull request
@raynelfss raynelfss changed the title [WIP] Target C - API [WIP] Target - C API May 5, 2025
raynelfss and others added 16 commits May 5, 2025 14:05
- Add provisional `PropertyMap` to represent the mapping of `qargs : InstructionProperties` before adding it to the `Target`.
- `InstructionProperties`:
    - free.
- `Target`:
    - `update_instruction_prop`
    - `operation_names`
    - `physical_qubits`
    - `non_global_operation_names`.
    - `operation_names_for_qargs`.
    - `qargs_for_operation_names`.
    - `qargs`.
    - `instruction_supported`.
    - `contains_key`.
- Add getter methods for `InstructionProperties`.
- Add `length` method for `PropertyMap`.
- Add name maping for `PropertyMap`.
- Add `get` method to `Target`.
- Add missing methods to `PropertyMap`.
- Fix methods returning arrays to C by adding a a forget statement to prevent pointer from being destroyed.
- Add getter methods to the `C` api of target.
- Add helper function to parse qargs.
- Move `print_qargs` helper to top of module.
- Add helper method to compare arrays.
- Fix print method for qargs.
- Use correct type of pointers for outputs,
- Use IndexSet to preserve insertion order to avoid sorting in the C API.
raynelfss added 2 commits May 6, 2025 19:01
- Sort the string arrays obtained from the target in C during tests.
- Remove `Copy` from `InstructionProperties`.
- Add helper method to sort string array outputs, coming from the Target.
- Add getters for `description`, `dt` `min_length` `granularity`, `acquire_alignment`, and `pulse_alignment`.
- Add Target construction test.
Copy link
Member

@mtreinish mtreinish left a comment

Choose a reason for hiding this comment

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

I know this isn't ready for review yet, and I haven't done a full review. But I opened this up and got triggered on the first c function so left a comment there.

/// non-null pointer to a ``QkTargetEntry`` object.
#[no_mangle]
#[cfg(feature = "cbinding")]
pub unsafe extern "C" fn qk_target_entry_len(entry: *const TargetEntry) -> usize {
Copy link
Contributor

Choose a reason for hiding this comment

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

Also here, could we call it something that reflects the property better, like num_instructions or something? 🙂

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For an entry, I think the current name is valid since it is the number of both qargs and properties (we could get away with calling it qk_target_entry_num_props or something among those lines). This name, however, could work for the qk_target_len method.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Addressed in a35f1bb

raynelfss and others added 3 commits June 2, 2025 08:55
Co-authored-by: Julien Gacon <gaconju@gmail.com>
- Rename `qk_target_len` to `qk_target_num_instructions`.
- Rename `qk_target_entry_len` to `qk_target_num_properties`.
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.

I'm very happy with the code, but the docs need some more attention (and I think we can complete the reno now 🙂). I also left a comment on the tests 🙂


use crate::exit_codes::ExitCode;
use crate::pointers::{const_ptr_as_ref, mut_ptr_as_ref};
use core::f64;
Copy link
Contributor

Choose a reason for hiding this comment

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

Just a question: is this the same as std::f64? I'm surprised we need an import to use the native type 🤔

Copy link
Member

Choose a reason for hiding this comment

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

We shouldn't need to import this from core. We're not in a no-std build for rust we very explicitly rely on the stdlib in cext (and qiskit more broadly). You should just be able to use the built in f64 intrinsic. If that isn't sufficient you might want to use std::ffi::c_double but I don't think think that should be necessary.

features_transpiler:
- |
Support for creation, manipulation, and interaction of :class:`~.Target` have
been added to the Qiskit C API.
Copy link
Contributor

Choose a reason for hiding this comment

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

We are happy now I think 🙂

raynelfss and others added 2 commits June 3, 2025 14:31
- Use `u32` for `Target` length and `min_length`.

Co-authored-by: Julien Gacon <gaconju@gmail.com>
@mtreinish
Copy link
Member

#14526 should fix the CI failures

raynelfss and others added 4 commits June 4, 2025 08:50
- Fix indentation in helper function docstrings in target.rs
Co-authored-by: Julien Gacon <gaconju@gmail.com>
raynelfss and others added 2 commits June 4, 2025 11:28
- `qk_target_entry_add_property` will throw an error code if the wrong qargs number is ever provided.
- Add comparison of error codes in unittests.
Co-authored-by: Julien Gacon <gaconju@gmail.com>
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.

LGTM thanks for all the work -- I believe we're in very good shape now and have a API that works well for C space. The true test will come once users will want to build custom targets (assuming that auto-generated targets from backends will be generated in Rust) 🙂

@Cryoris Cryoris enabled auto-merge June 4, 2025 16:31
@Cryoris Cryoris added this pull request to the merge queue Jun 4, 2025
Merged via the queue into Qiskit:main with commit d3ffc29 Jun 4, 2025
26 checks passed
rahaman-quantum pushed a commit to rahaman-quantum/qiskit that referenced this pull request Jun 20, 2025
* Initial: Enable a C API to build and modify a Target

* Add: `add_instruction` function

* Add: More methods to `Target` C API
- Add provisional `PropertyMap` to represent the mapping of `qargs : InstructionProperties` before adding it to the `Target`.
- `InstructionProperties`:
    - free.
- `Target`:
    - `update_instruction_prop`
    - `operation_names`
    - `physical_qubits`
    - `non_global_operation_names`.
    - `operation_names_for_qargs`.
    - `qargs_for_operation_names`.
    - `qargs`.
    - `instruction_supported`.
    - `contains_key`.

* Add: C unit test
- Add getter methods for `InstructionProperties`.
- Add `length` method for `PropertyMap`.
- Add name maping for `PropertyMap`.

* Fix: Add `IndexMap` and `Ahash` dependencies to qiskit_cext.
- Add `get` method to `Target`.
- Add missing methods to `PropertyMap`.
- Fix methods returning arrays to C by adding a a forget statement to prevent pointer from being destroyed.
- Add getter methods to the `C` api of target.
- Add helper function to parse qargs.

* Test: Add tests to update properties and get non global names.

* Add `operation_names_for_qargs` test case.
- Move `print_qargs` helper to top of module.

* Add: `qargs_for_operation_names` test case
- Add helper method to compare arrays.
- Fix print method for qargs.

* Docs: Add first wave of docstrings.

* Fix: Incorrect typing in `test_target.c`

* Fix: Add missing docstrings.
- Use correct type of pointers for outputs,

* Lint: Fix c-format

* Fix: Remove option from `qarg_gate_map`.
- Use IndexSet to preserve insertion order to avoid sorting in the C API.

* Test: Add `qargs` test.

* FIx: Add missing docstrings for remainign tests

* Fix: Type errors in MacOS

* Fix: Undo extra changes in the target.
- Sort the string arrays obtained from the target in C during tests.
- Remove `Copy` from `InstructionProperties`.
- Add helper method to sort string array outputs, coming from the Target.

* Add: more complete constructor for `Target`.
- Add getters for `description`, `dt` `min_length` `granularity`, `acquire_alignment`, and `pulse_alignment`.
- Add Target construction test.

* Fix: Clean up pointers in `qk_target_new`
- Add setters for `QkTarget` attributes.

* Fix: Add release note

* Fix: Typos in docstring

* Lint: Fix lint for C

* Fix: Use structs for collections, specify length.
- Introduce `QkTargetQargs`, `QkTargetNameList`, and `QkTargetQargsList` to expose collections of operation names and qargs to C exposing the length of the collection.

* Fix: Use ``Target`` for docstrings.

* Fix: Use the `qiskit_transpiler` crate.

* Fix: Add "qiskit-transpiler" to cbindgen.toml
- Remove incorrect usage of pointers for `qk_target_dt`.

* Fix: Incorrect import of `PhysicalQubit` in target.rs

* Fix: Remove usage of `string` to query instructions, use `StandardGate` instead.
- Introduce `Target` specific exitcodes starting at 300.
- Change methods to use `StandardGate` instead of String.

* Fix: Remove `description` from the C API.

* FIx: Remove `InstructionProperties` from the C API
- Introduce `QkInstProperties` as a C representable variant of `InstructionProperties`.
- Move `InstructionProperties` instantiation to function calls. Now you can directly send duration or error as function arguments.
- Make `PropsMap` be either initialized or `NULL`.

* Fix: Incorrect documentation usage for `qk_target_new()`

* Fix: Use NAN in one of the examples.

* Docs: Add documentation for the `Target` C API

* Lint: Qiskit header format in docs

* Fix: Use `NaN` when `dt` is not set.

* Refactor: Remove all querrying methods from Target, PropsMap.
- Remove all helper structs.
- All removed changes will be spun off to a different PR.

* Fix: Implement `From<TargetError>` for `ErrorCode`.

* Add: Separate method to add gates with fixed params.
- Since parameters are not fully supported in C as of yet, we have to separate the methods to make a clear division between how to add a gate with/without parameters, and making additions with fixed parameters fully explicit in the Target.

* Docs: Address new changes in documentation

* Fix: Add a way of copying a Target from C.

* Fix: Address review comments

Co-authored-by: Julien Gacon <gaconju@gmail.com>

* Lint: Fix formatting

* Remove: `Target::get` method.
- Will be re-added in future updates.

* Docs: Remove volatility line from `PropsMap` docs.

* Refactor: `QkPropsMap` is now `QkTargetEntry`.
- Add rust struct `TargetEntry` to better represent adding a gate to the Target from C,
- Add `SmallVec` as a dependency.
- Remove `qk_target_add_instruction_fixed` in favor of performing the checks during the creation of the `QkTargetEntry`.
- Update documentation with newer additions.

* Docs: update documentation to clearly

* Apply suggestions from code review

Co-authored-by: Julien Gacon <gaconju@gmail.com>

* Chore: Rename len methods.
- Rename `qk_target_len` to `qk_target_num_instructions`.
- Rename `qk_target_entry_len` to `qk_target_num_properties`.

* Chore: Fix documentation further
- Use `u32` for `Target` length and `min_length`.

Co-authored-by: Julien Gacon <gaconju@gmail.com>

* Docs: Add example to release note

* Chore: Remove unused error codes

* Fix: Remove conversion in vf2 vf2_layout
- Fix indentation in helper function docstrings in target.rs

* Apply suggestions from code review

Co-authored-by: Julien Gacon <gaconju@gmail.com>

* Fix: Make `qk_target_entry_add_property` fallible.
- `qk_target_entry_add_property` will throw an error code if the wrong qargs number is ever provided.
- Add comparison of error codes in unittests.

* Update docs/cdoc/qk-target-entry.rst

Co-authored-by: Julien Gacon <gaconju@gmail.com>

* Fix: Check pointer before consuming in `qk_target_add_instruction`.

* Chore: Clean up the  target tests.

* Fix: More mistakes in tests.

---------

Co-authored-by: Julien Gacon <gaconju@gmail.com>
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 experimental Experimental feature without API stability guarantee mod: transpiler Issues and PRs related to Transpiler priority: high
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add ability to copy a Target from C Add C interface for Target construction and interaction
6 participants