-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Add qk_transpile_stage_routing() to the C API #15358
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -6,12 +6,19 @@ features_c: | |||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| * :c:func:`qk_transpile_stage_init` | ||||||||||||||||||||||||||||||||||||||||||||||
| * :c:func:`qk_transpile_stage_layout` | ||||||||||||||||||||||||||||||||||||||||||||||
| * :c:func:`qk_transpile_stage_routing` | ||||||||||||||||||||||||||||||||||||||||||||||
| * :c:func:`qk_transpile_stage_translation` | ||||||||||||||||||||||||||||||||||||||||||||||
| * :c:func:`qk_transpile_stage_optimization` | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| run the :ref:`transpiler-preset-stage-init`, :ref:`transpiler-preset-stage-layout`, | ||||||||||||||||||||||||||||||||||||||||||||||
| :ref:`transpiler-preset-stage-routing`, | ||||||||||||||||||||||||||||||||||||||||||||||
| :ref:`transpiler-preset-stage-translation`, and | ||||||||||||||||||||||||||||||||||||||||||||||
| :ref:`transpiler-preset-stage-optimization` respectively. | ||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
6
to
16
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would it be better to turn these into a table? Sort of like this:
Suggested change
It would look like this:
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm fine either way. I went with a list because it was simpler. Either way we can always change it in the release note roundup for the final release. |
||||||||||||||||||||||||||||||||||||||||||||||
| These function are used to run these stages from the preset pass manager | ||||||||||||||||||||||||||||||||||||||||||||||
| on a ``QkDag`` object. The goal of these functions are to enable composable | ||||||||||||||||||||||||||||||||||||||||||||||
| transpilation workflows from C when combined with custom transpiler passes. | ||||||||||||||||||||||||||||||||||||||||||||||
| - | | ||||||||||||||||||||||||||||||||||||||||||||||
| Added a new function :c:func:`qk_transpile_layout_generate_from_mapping` which is | ||||||||||||||||||||||||||||||||||||||||||||||
| used to generate a custom :c:struct:`QkTranspileLayout` with an initial layout set | ||||||||||||||||||||||||||||||||||||||||||||||
| from a mapping array. The intent of this function is to enable creating a | ||||||||||||||||||||||||||||||||||||||||||||||
| layout object for custom layout transpiler passes. | ||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| // This code is part of Qiskit. | ||
| // | ||
| // (C) Copyright IBM 2025. | ||
| // | ||
| // This code is licensed under the Apache License, Version 2.0. You may | ||
| // obtain a copy of this license in the LICENSE.txt file in the root directory | ||
| // of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. | ||
| // | ||
| // Any modifications or derivative works of this code must retain this | ||
| // copyright notice, and modified files need to carry a notice indicating | ||
| // that they have been altered from the originals. | ||
|
|
||
| #include "common.h" | ||
| #include <complex.h> | ||
| #include <qiskit.h> | ||
| #include <stdbool.h> | ||
| #include <stddef.h> | ||
| #include <stdint.h> | ||
| #include <stdio.h> | ||
| #include <string.h> | ||
|
|
||
| static int test_transpile_layout_generate(void) { | ||
| int result = Ok; | ||
| QkTarget *target = qk_target_new(5); | ||
| QkDag *orig_dag = qk_dag_new(); | ||
| QkQuantumRegister *qr = qk_quantum_register_new(3, "qr"); | ||
| qk_dag_add_quantum_register(orig_dag, qr); | ||
| uint32_t layout_mapping[5] = {1, 4, 3, 2, 0}; | ||
| QkTranspileLayout *layout = | ||
| qk_transpile_layout_generate_from_mapping(orig_dag, target, layout_mapping); | ||
| if (qk_transpile_layout_num_input_qubits(layout) != 3) { | ||
| fprintf(stderr, "Number of input qubits is %u, expected 3\n", | ||
| qk_transpile_layout_num_input_qubits(layout)); | ||
| result = EqualityError; | ||
| goto cleanup; | ||
| } | ||
| if (qk_transpile_layout_num_output_qubits(layout) != 5) { | ||
| fprintf(stderr, "Number of output qubits is %u, expected 5\n", | ||
| qk_transpile_layout_num_input_qubits(layout)); | ||
| result = EqualityError; | ||
| goto cleanup; | ||
| } | ||
| bool permutation_set = qk_transpile_layout_output_permutation(layout, NULL); | ||
| if (permutation_set) { | ||
| fprintf(stderr, "Generated unexpectedly has an output permutation"); | ||
| goto cleanup; | ||
| } | ||
| uint32_t *output_mapping = malloc(sizeof(uint32_t) * 5); | ||
| bool layout_set = qk_transpile_layout_initial_layout(layout, false, output_mapping); | ||
| if (!layout_set) { | ||
| fprintf(stderr, "Generated layout doesn't have initial layout set\n"); | ||
| result = EqualityError; | ||
| goto result_cleanup; | ||
| } | ||
| for (int i = 0; i < 5; i++) { | ||
| if (output_mapping[i] != layout_mapping[i]) { | ||
| fprintf(stderr, "Element %i does not match. Result: %u, Expected: %u\n", i, | ||
| output_mapping[i], layout_mapping[i]); | ||
| result = EqualityError; | ||
| goto result_cleanup; | ||
| } | ||
| } | ||
| result_cleanup: | ||
| free(output_mapping); | ||
|
|
||
| cleanup: | ||
| qk_transpile_layout_free(layout); | ||
| qk_dag_free(orig_dag); | ||
| qk_target_free(target); | ||
| return result; | ||
| } | ||
|
|
||
| int test_transpile_layout(void) { | ||
| int num_failed = 0; | ||
| num_failed += RUN_TEST(test_transpile_layout_generate); | ||
|
|
||
| fflush(stderr); | ||
| fprintf(stderr, "=== Number of failed subtests: %i\n", num_failed); | ||
|
|
||
| return num_failed; | ||
| } |

There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One small cleanup suggestion I could think of here is that several of the new :meth:
qk_transpile_stage_*functions repeat the same pointer-conversion, options-handling, approximation-degree parsing, seed parsing, and error-reporting boilerplate. It may be worth considering internal helpers to centralize that logic and reduce duplication. This changed is not required for this PR however, as the overall functionality doesn't change. But the code reduction may improve maintainability and readability.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a fair comment, but I think since this PR is adding the last one in the series we should just finish following the pattern the other functions use. But if you want to push a PR on top of this one deduplicating the internals we can review that very easily if it makes things cleaner.