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

Can't simulate circuits using SamplerV2. Error: "AttributeError: '_SingletonHGate' object has no attribute 'parameters'" #12391

Closed
SrLo98 opened this issue May 12, 2024 · 8 comments
Labels
bug Something isn't working

Comments

@SrLo98
Copy link

SrLo98 commented May 12, 2024

Environment

  • Qiskit version: 1.0.2
  • Python version: 3.12.3
  • Operating system: Windows 11 / linux

What is happening?

This issue is a continuation of the #12388.
Basically, when I have a transpiled circuit and I want to simulate it using the library SamplerV2, it throws the error AttributeError: '_SingletonHGate' object has no attribute 'parameters' .

How can we reproduce the issue?

The code is the following one:

from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime import SamplerV2 as Sampler
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
from qiskit.transpiler import InstructionProperties

# Import service
service = QiskitRuntimeService()
backend = service.get_backend('ibmq_qasm_simulator')

psi = [0.6269101568208251, 0.3990782681769692, 0.32708356008043044, 0.5837264221095967]
phi = [0.2134892935266178, -0.9769454035663946]

# Quantum Circuit
q0 = QuantumRegister(1, name = 'q0')
q1 = QuantumRegister(3, name = 'q1') 
c = ClassicalRegister(1, name = 'c')
qc = QuantumCircuit(q0,q1,c, name="qc")

# States initialization
psi_state = Gate('psi', 2, psi)
phi_state = Gate('phi', 1, phi)
qc.append(psi_state, q1[0:2])
qc.append(phi_state, q1[2:3])

# swap_test
qc.h(q0[0])
qc.cswap(q0[0], q1[0], q1[2])
qc.h(q0[0])
qc.measure(q0[0],c[0])

qc.draw(output="mpl")

And the output of the circuit:
image

Then I added the instructions to the backend and transpiled the circuit:

service = QiskitRuntimeService()

backend = service.get_backend('ibmq_qasm_simulator')
backend.target.add_instruction(psi_state)
backend.target.add_instruction(phi_state)

pm = generate_preset_pass_manager(optimization_level=1, backend=backend)
qc_transpiled = pm.run(qc)

qc_transpiled.draw(output="mpl")

And the transpiled circuit look like this:

image

Nevertheless, when I try to run the circuit with SamplerV2, a new error appears:

shots = 2048
sampler = Sampler(backend=backend)
job = sampler.run(qc_transpiled, shots=shots)
job_result = job.result()
counts = job_result.get_counts()

The error is: AttributeError: 'RZGate' object has no attribute 'parameters'

The same happens if i choose pm = generate_preset_pass_manager(optimization_level=0, backend=backend) instead (this doesn't modify the initial circuit structure or gates). And now the error is similar but with another gate: AttributeError: '_SingletonHGate' object has no attribute 'parameters'

What should happen?

The Sampler object should be able to simulate the circuit.

Any suggestions?

No response

@SrLo98 SrLo98 added the bug Something isn't working label May 12, 2024
@t-imamichi
Copy link
Member

t-imamichi commented May 13, 2024

Sampler.run call looks wrong.
You should try job = sampler.run([qc_transpiled], shots=shots)

We have updated the error message #12031 and will be released as Qiskit 1.1 soon.

@jakelishman
Copy link
Member

I'll close this as expected/solved, but feel free to reopen if there's more to discuss.

@SrLo98
Copy link
Author

SrLo98 commented May 13, 2024

Hello, by adding the instruction job = sampler.run([qc_transpiled], shots=shots) that problem was resolved. However, when I run the sampler and I try to get the job results doing:

shots = 2048
sampler = Sampler(backend=backend)
job = sampler.run(qc_transpiled, shots=shots)
job_result = job.result()
counts = job_result.get_counts()

A new error RuntimeJobFailureError: 'Unable to retrieve job result. Instruction psi on qubits (1, 2) from the 0-th circuit not is supported by the target. appears.

I tried to transpile the circuit by doing:

pm = generate_preset_pass_manager(optimization_level=0, backend=backend)
qc_transpiled = pm.run(qc)

And also including the target:

pm = generate_preset_pass_manager(optimization_level=0, backend=backend, target=backend.target)
qc_transpiled = pm.run(qc)

But in both cases the error persists. Thanks!

@t-imamichi
Copy link
Member

You can add instructions to target. But, the resulting circuit does not work on a remote device because you cannot modify the target of the remote device.
I suggest transpiling your circuit without modify target.

@SrLo98
Copy link
Author

SrLo98 commented May 13, 2024

You can add instructions to target. But, the resulting circuit does not work on a remote device because you cannot modify the target of the remote device. I suggest transpiling your circuit without modify target.

Thank you for responding, If I don't add any instruction and then I simply transpile the circuit, I got this error: TranspilerError: "HighLevelSynthesis was unable to synthesize Instruction(name='psi', num_qubits=2, num_clbits=0, params=[0.6269101568208251, 0.3990782681769692, 0.32708356008043044, 0.5837264221095967])."

The transpilation was done like this:

service = QiskitRuntimeService()
backend = service.get_backend('ibmq_qasm_simulator')

pm = generate_preset_pass_manager(optimization_level=0, backend=backend)
qc_transpiled = pm.run(qc)

Thank you

@jakelishman
Copy link
Member

I suggest you look at the initialize or prepare_state methods to QuantumCircuit, which seems to be what you're trying to do.

At the moment you are defining some custom Gate without specifying anything about what that gate means. The transpiler is telling you that explicitly: "unable to synthesise [for the backend]", because it doesn't understand the gate you've given. If you want to make a one-off gate with a specific decomposition, you can make a circuit with only qubits and unitary operations and then call to_gate on it, or you can define a Gate subclass that specifies the definition field to be what you want. Alternatively, you can look in Qiskit's qiskit.circuit.library for pre-existing circuits/gates that might meet your needs.

@SrLo98
Copy link
Author

SrLo98 commented May 13, 2024

I suggest you look at the initialize or prepare_state methods to QuantumCircuit, which seems to be what you're trying to do.

At the moment you are defining some custom Gate without specifying anything about what that gate means. The transpiler is telling you that explicitly: "unable to synthesise [for the backend]", because it doesn't understand the gate you've given. If you want to make a one-off gate with a specific decomposition, you can make a circuit with only qubits and unitary operations and then call to_gate on it, or you can define a Gate subclass that specifies the definition field to be what you want. Alternatively, you can look in Qiskit's qiskit.circuit.library for pre-existing circuits/gates that might meet your needs.

Thank you for replying Jake,

Basically my program is using the SWAP routine to compute the inner product between two vectors A and B using amplitude encoding, using these states:
$|Ψ⟩=\frac{1}{\sqrt{2}}[|0⟩⊗|A⟩+|1⟩⊗|B⟩]$
$|𝜑⟩=\frac{1}{\sqrt{Z}}[|A||0⟩-|B||1⟩]$
Where: $Z=|A|^2+|B|^2$

Just to create the issue, I just copied directly an example of previously computed values of both states for two random A and B vectors.
As I commented in #12388, to do exactly the same with the functions transpile and assemble with older qiskit version, I had no problems.

I used instead initialize:

#States initialization
qc.initialize(psi, q1[0:2])
qc.initialize(phi, q1[2:3])

And then to simulate the circuit:

backend_QASM = Aer.get_backend('qasm_simulator')

# Number of realizations
    realizations = 2048

    # Create quantum circuit
    qc = build_QuantumCircuit_Amplitude(psi,phi)

    # Transpile the quantum circuit for the target backend
    qc_transpiled = transpile(qc, backend_QASM)

    # Assemble the transpiled quantum circuit into a Qobj
    qobj = assemble(qc_transpiled, shots=realizations)

    # Run the Qobj on the backend
    job = backend_QASM.run(qobj)

    # Get the result of the job
    job_result = job.result()

    # Get the counts from the result
    counts = job_result.get_counts()

But it's just now that I try to update the code to current Qiskit version that I'm struggling to make it work.

@jakelishman
Copy link
Member

Your working examples don't appear to be much to do with new versions of Qiskit and more because you're simply using a different backend. The Runtime ibmq_qasm_simulator may not be reporting its ability to handle reset correctly.

Aer also provides Sampler implementations (in qiskit_aer.primitives), so you might just want to use one of those. If you want to continue using backend.run, you can get the Aer object from qiskit_aer.Aer, which is identical to the one you're using. There is no need to manually call assemble - that hasn't been necessary (or desirable) for at least a few years, and is mostly just an internal detail of how IBM services used to run. You should just pass the transpiled circuit directly to backend.run.

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

No branches or pull requests

3 participants