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

Failed preparing ansatz circuit using PauliEvolutionGate when 'time' is taken as a Parameter('t'). #13625

Closed
crystaldot opened this issue Jan 8, 2025 · 2 comments · Fixed by #13634
Assignees
Labels
bug Something isn't working

Comments

@crystaldot
Copy link

Environment

  • Qiskit version: 1.3.1
  • Python version: 3.12.7
  • Operating system: Linux fedora 6.11.3-200.fc40.x86_64

What is happening?

I would like to prepare an ansatz circuit using PauliEvolutionGate with a Hamiltonian of the form SparsePauliOp and time taken as Parameter (type: qiskit.circuit.parameter.Parameter). While using LieTrotter or SuzukiTrotter decomposition technique to synthesize the circuit with time as a numerical value it can synthsize with any reps and order. But with time taken as a Parameter instead of a numerical value in PauliEvolutionGate it is unable to synthesize it for some form of Hamiltonian with an error PanicException: internal error: entered unreachable code .

How can we reproduce the issue?

Code to reproduce the error:

# Import
from qiskit_nature.second_q.hamiltonians.lattices import BoundaryCondition, SquareLattice
from qiskit_nature.second_q.mappers import JordanWignerMapper
from qiskit_nature.second_q.hamiltonians import FermiHubbardModel

from qiskit.synthesis import LieTrotter, SuzukiTrotter
from qiskit.circuit.library import PauliEvolutionGate

from qiskit.circuit import Parameter
from qiskit.quantum_info import SparsePauliOp


# Prepare Hamiltonian
jw_mapper = JordanWignerMapper()
PERIODIC = BoundaryCondition.PERIODIC

rows = 2
cols = 2
square_lattice = SquareLattice(rows=rows, cols=cols, boundary_condition = PERIODIC)

t = -1  # the interaction parameter
v =  3 # the onsite potential
u = 7  # the interaction parameter u

fhm = FermiHubbardModel(
    lattice = square_lattice.uniform_parameters(uniform_interaction = t, uniform_onsite_potential = v),
    onsite_interaction = u
)
fhm_sq = fhm.second_q_op().simplify()
groups = jw_mapper.map(fhm_sq).group_commuting(qubit_wise= True) 
fhm_ham = sum(groups)                                                   # With Grouping
# fhm_ham = jw_mapper.map(fhm_sq)                                       # Without Grouping

# test_ham = SparsePauliOp(['XXXX', 'YYYY', 'ZZII','ZZZZ'],[2,3,5,7])      # Expected output is available through this 

# Prepare Ansatz
t = Parameter('t')
# t = 1.2
time_evolution_operator = PauliEvolutionGate(fhm_ham, time=t)
# time_evolution_operator = PauliEvolutionGate(test_ham, time=t)      # Expected output is available through this 


# lie_trotter_factory = LieTrotter(reps=1, insert_barriers=True, wrap = True, preserve_order= True)
# evolution_circuit = lie_trotter_factory.synthesize(time_evolution_operator)    

suzuki_trotter_factory = SuzukiTrotter(order=2, reps=1, insert_barriers=True, wrap = True, preserve_order= True)
evolution_circuit = suzuki_trotter_factory.synthesize(time_evolution_operator)

# Draw Circuit
evolution_circuit.decompose(reps = 1).draw(fold = -1)

Error genearated after running the above code:

thread '<unnamed>' panicked at crates[/circuit/src/operations.rs:2353:14](http://localhost:8888/circuit/src/operations.rs#line=2352):
internal error: entered unreachable code
---------------------------------------------------------------------------
PanicException                            Traceback (most recent call last)
Cell In[19], line 47
     40 # time_evolution_operator = PauliEvolutionGate(test_ham, time=t)
     41 
     42 
     43 # lie_trotter_factory = LieTrotter(reps=1, insert_barriers=False, wrap = True, preserve_order= True)
     44 # evolution_circuit = lie_trotter_factory.synthesize(time_evolution_operator)
     46 suzuki_trotter_factory = SuzukiTrotter(order=2, reps=1, insert_barriers=False, wrap = True, preserve_order= True)
---> 47 evolution_circuit = suzuki_trotter_factory.synthesize(time_evolution_operator)

File [~/.local/lib/python3.12/site-packages/qiskit/synthesis/evolution/product_formula.py:161](http://localhost:8888/lab/tree/qc-research/New%20Tests/HVA/~/.local/lib/python3.12/site-packages/qiskit/synthesis/evolution/product_formula.py#line=160), in ProductFormula.synthesize(self, evolution)
    156 num_qubits = evolution.num_qubits
    158 if self._wrap or self._atomic_evolution is not None:
    159     # this is the slow path, where each Pauli evolution is constructed in Rust
    160     # separately and then wrapped into a gate object
--> 161     circuit = self._custom_evolution(num_qubits, pauli_rotations)
    162 else:
    163     # this is the fast path, where the whole evolution is constructed Rust-side
    164     cx_fountain = self._cx_structure == "fountain"

File [~/.local/lib/python3.12/site-packages/qiskit/synthesis/evolution/product_formula.py:223](http://localhost:8888/lab/tree/qc-research/New%20Tests/HVA/~/.local/lib/python3.12/site-packages/qiskit/synthesis/evolution/product_formula.py#line=222), in ProductFormula._custom_evolution(self, num_qubits, pauli_rotations)
    220 local_pauli = (pauli_string, list(range(len(qubits))), coeff)
    222 # build the circuit Rust-side
--> 223 data = pauli_evolution(
    224     len(qubits),
    225     [local_pauli],
    226     False,
    227     cx_fountain,
    228 )
    229 evo = QuantumCircuit._from_circuit_data(data)
    231 # and append it to the circuit with the correct label

PanicException: internal error: entered unreachable code

What should happen?

It should prepare the ansatz circuit with time taken as a Parameter. The correct output will be visible if Hamiltonian is replaced by test_ham. Synthesized circuit should be visible through: evolution_circuit.decompose(reps = 1).draw(fold = -1) with t as a multiplied parameter in every argument of $R_z$ or $R_{zz}$ gate throughout the circuit.

Any suggestions?

No response

@crystaldot crystaldot added the bug Something isn't working label Jan 8, 2025
@Cryoris Cryoris self-assigned this Jan 8, 2025
@Cryoris
Copy link
Contributor

Cryoris commented Jan 8, 2025

This is likely due to the Rust internals trying to add a parameter expression (the time) with a float (the global phase), which would also explain why you only see it for the JW hamiltonian containing an all-identity term. If it's that it should be easy to fix 🙂

@crystaldot
Copy link
Author

Upon further testing it was found that any Hamiltonian containing an all-identity term irrespective of number of qubits will throw the same error.
Same error will always show up if any of the mapper (JordanWignerMapper, ParityMapper, BravyiKitaevMapper, BravyiKitaevSuperFastMapper) is used to prepare the Hamiltonian in our problem. As in all cases it will definitely contain an all-identity term.
Thanks for identifying the root of the bug and initiatives taken to resolve it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants