Skip to content

Add qml_transpile: efficient parameter binding and local re-optimization for QML workflows - #7

Open
pandey-tushar wants to merge 10 commits into
haiqu-ai:mainfrom
pandey-tushar:feature/qml-transpile
Open

Add qml_transpile: efficient parameter binding and local re-optimization for QML workflows#7
pandey-tushar wants to merge 10 commits into
haiqu-ai:mainfrom
pandey-tushar:feature/qml-transpile

Conversation

@pandey-tushar

@pandey-tushar pandey-tushar commented May 31, 2025

Copy link
Copy Markdown

Fixes #4

@yuriy-haiqu

Copy link
Copy Markdown
Contributor

one of the important optimization for qml_transpile is to run passes only in place where we did the change!

so you need to

  1. detect location of parameters that you set. For example checking DAG for example
  2. cutting this part from circuit
  3. optimizing small part
  4. sticking it back to original circuit

In this way you only do necessary work

@d-bharadwaj

d-bharadwaj commented Jun 4, 2025

Copy link
Copy Markdown

@yuriy-haiqu comments have been addressed. Can you please review?

@yuriy-haiqu

Copy link
Copy Markdown
Contributor

on it

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.

this notebook do nothing.

Should it be removed?

Comment thread examples/qml_workflow/example.ipynb Outdated
"metadata": {},
"outputs": [],
"source": [
"def qml_transpile(circuit, parameter_values):\n",

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.

It would be better for notebook to use qml_transpile defined in
rivet_transpiler/functions.py

As there will be less code duplication

Comment thread rivet_transpiler/functions.py Outdated
subdag.apply_operation_back(succ.op, succ.qargs, succ.cargs)
# Optimize this small subdag
pm = PassManager([
Optimize1qGatesDecomposition(basis=['u3','u2','u1','rz','rx','ry','sx','x','y','z','h']),

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.

Will it produce gates in device_basis gateset in the end?

I think it should be better to target/backend parameter to qml_transpile. I will add coment about that in issue description

Comment thread rivet_transpiler/functions.py Outdated
# Optimize this small subdag
pm = PassManager([
Optimize1qGatesDecomposition(basis=['u3','u2','u1','rz','rx','ry','sx','x','y','z','h']),
CommutativeCancellation(),

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.

There should be much more optimisation passes that could work for our case

if you look qiskit transpilation stages

Init Stage: Customize the synthesis algorithms with hls_config, select a different initialization plugin using init_method, or adjust the unitary synthesis method with unitary_synthesis_method and unitary_synthesis_plugin_config.
Layout Stage: Modify the layout_method to change how the initial layout of qubits is selected. Options include trivial, dense, noise_adaptive, or sabre.
Routing Stage: Adjust the routing_method to influence how qubits are swapped during the circuit execution. Options include basic, lookahead, stochastic, sabre, or none.
Translation Stage: Experiment with the translation_method to determine how the circuit is converted to the backend’s native gate set, choosing between translator or synthesis.
Optimization Stage: Experiment with the approximation_degree to trade off accuracy for gate reduction. You can set it to a value between 0.0 (maximal approximation) and 1.0 (no approximation), or None to automatically match the error rate.

they do Translation Stage and Optimization Stage as iterative process many times to already routed circuit.
You could just take qiskit passmanager for transpialtion level 3

get all passes after routing and apply them here

there is nice tutorials here
https://github.com/qiskit-community/qdc-challenges-2024/blob/main/Day_2/QDC_Day_2_Track_A.ipynb
https://github.com/qiskit-community/qdc-challenges-2024/blob/main/Day_2/QDC_Day_2_Track_B.ipynb

@yuriy-haiqu

Copy link
Copy Markdown
Contributor

good work on selection subgraph

@yuriy-haiqu

Copy link
Copy Markdown
Contributor

Additional points notebook that is present do not show benchmarks different between methods.

there is big chunk of code related to classification problem. It's better to make notebook more focused on benchmarking

@d-bharadwaj

Copy link
Copy Markdown

@yuriy-haiqu We have addressed all the comments and made more changes to the notebook to make it more benchmark-focused. Apologies for the delay since we were busy this past week. Since we had already made progress on this issue, I think we have until Monday June 16th as the deadline. We hope to merge this PR by then. Thanks!

feat: address comments and add target backend to qml_transpile
@yuriy-haiqu

Copy link
Copy Markdown
Contributor

@d-bharadwaj
You are almost done. MR looks good
would close MR if do fixes

@d-bharadwaj

Copy link
Copy Markdown

@d-bharadwaj You are almost done. MR looks good would close MR if do fixes

Thanks @yuriy-haiqu ! Just to confirm—are there any remaining fixes you’d like me to make before merge? I didn’t see anything outstanding.

@yuriy-haiqu

Copy link
Copy Markdown
Contributor

@d-bharadwaj have you pushed you changes?

latest commit 2 weeks ago

@pandey-tushar

Copy link
Copy Markdown
Author

@d-bharadwaj have you pushed you changes?

latest commit 2 weeks ago

Hi,
The last commit was 2 days ago with the fixes you requested.

@yuriy-haiqu

Copy link
Copy Markdown
Contributor

Somehow pull request not updated
you could check
https://github.com/haiqu-ai/rivet/pull/7/commits

@pandey-tushar

Copy link
Copy Markdown
Author

Screenshot_20250614-142006.png

We see 10 commits, the last one is 2 days ago.

@yuriy-haiqu

Copy link
Copy Markdown
Contributor

Yes, all good. My mistake.

@yuriy-haiqu

yuriy-haiqu commented Jun 15, 2025

Copy link
Copy Markdown
Contributor

I looked at your results in [this notebook](https://github.com/pandey-tushar/rivet/blob/feature/qml-transpile/examples/qml_workflow/example.ipynb).

The reported metrics are:

Baseline (transpile once, bind later):

  • Avg transpile time: 0.12 ms
  • Avg circuit depth: 23.00
  • Avg 2-qubit gate count: 8.00

QML Transpile (bind on transpiled):

  • Avg transpile time: 1.24 ms
  • Avg circuit depth: 23.00
  • Avg 2-qubit gate count: 8.00

These results are identical in terms of circuit structure, which is a bit strange. I started debugging the logic with the following snippet:

affected_nodes = []
for node in dag.topological_op_nodes():
    print(node.op)
    print(list(
        hasattr(param, "is_parameter") and param.is_parameter 
        for param in getattr(node.op, "params", [])
    ))

    if hasattr(node.op, "params") and any(
        hasattr(param, "is_parameter") and param.is_parameter 
        for param in getattr(node.op, "params", [])
    ):
        affected_nodes.append(node)

print("affected_nodes", len(affected_nodes))

I found that affected_nodes is always empty, meaning that the logic essentially does nothing.

Do you have the same?

Also, there’s not much value in testing with a small 2-qubit circuit—transpilation time is negligible, and routing-related effects won’t be visible.

In the issue description, I suggested:

"Use a real-world QML example where the PQC is relatively small and prefixed by a large static circuit."

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.

Add qml_transpile: Efficient Parameterized Circuit Re-Optimization for QML Workflows

3 participants