Open Augusto12 opened 1 week ago
Apparently, it's because they haven't implemented the q_ancillae
in add_control()
method of qiskit.circuit.add_control.py
.
def control(
operation: Gate | ControlledGate,
num_ctrl_qubits: int | None = 1,
label: str | None = None,
ctrl_state: str | int | None = None,
) -> ControlledGate:
"""Return controlled version of gate using controlled rotations. This function
first checks the name of the operation to see if it knows of a method from which
to generate a controlled version. Currently, these are ``x``, ``rx``, ``ry``, and ``rz``.
If a method is not directly known, it calls the unroller to convert to `u1`, `u3`,
and `cx` gates.
Args:
operation: The gate used to create the ControlledGate.
num_ctrl_qubits: The number of controls to add to gate (default=1).
label: An optional gate label.
ctrl_state: The control state in decimal or as
a bitstring (e.g. '111'). If specified as a bitstring the length
must equal num_ctrl_qubits, MSB on left. If None, use
2**num_ctrl_qubits-1.
Returns:
Controlled version of gate.
Raises:
CircuitError: gate contains non-gate in definition
"""
from math import pi
# pylint: disable=cyclic-import
from qiskit.circuit import controlledgate
ctrl_state = _ctrl_state_to_int(ctrl_state, num_ctrl_qubits)
q_control = QuantumRegister(num_ctrl_qubits, name="control")
q_target = QuantumRegister(operation.num_qubits, name="target")
q_ancillae = None # TODO: add
Which causes the q_ancillae
to be []
when mcry
is called. Since it's empty, the length of it is 0, which means that
if mode is None:
# if enough ancillary qubits are provided, use the 'v-chain' method
additional_vchain = MCXGate.get_num_ancilla_qubits(len(control_qubits), "v-chain")
if len(ancillary_qubits) >= additional_vchain:
mode = "basic"
else:
mode = "noancilla"
Will always choose "noancilla" given MCXGate.get_num_ancilla_qubits(4, "v-chain")
will evaluate to 2. So, the method uses "noancilla" and because you have 4 control qubits:
elif mode == "noancilla":
n_c = len(control_qubits)
if n_c == 1: # cu
_apply_cu(
self, theta, 0, 0, control_qubits[0], target_qubit, use_basis_gates=use_basis_gates
)
elif n_c < 4:
theta_step = theta * (1 / (2 ** (n_c - 1)))
_apply_mcu_graycode(
self,
theta_step,
0,
0,
control_qubits,
target_qubit,
use_basis_gates=use_basis_gates,
)
else:
if isinstance(theta, ParameterExpression):
raise QiskitError(f"Cannot synthesize MCRY with unbound parameter: {theta}.")
cgate = _mcsu2_real_diagonal(
RYGate(theta).to_matrix(),
num_controls=len(control_qubits),
use_basis_gates=use_basis_gates,
)
self.compose(cgate, control_qubits + [target_qubit], inplace=True)
It will go to the else
block, and since you're using a ParameterExpression
it raises the error. I think you have to wait until they finish adding the TODO
part.
Indeed, we currently do not have methods to transpile parameterized MCRY gates with unbound parameters, regardless of the number of ancillas, @Cryoris and @ShellyGarion please correct me if I am wrong. For instance, the function __mcsu2_realdiagonal, used in the code snippet above, requires all of the parameters to be floats and does not work with general parameter expressions.
What you can do it to call _assignparameters prior to transpilation (this was recently added in #12869), e.g. the following code does work:
from qiskit.compiler import transpile
from qiskit.circuit import QuantumCircuit, ParameterVector
p = ParameterVector('p',4)
pqc = QuantumCircuit(4)
for i in range(4):
pqc.ry(p[i],i)
pqc = pqc.control(4,0,annotated=True)
pqc = pqc.assign_parameters([1, 2, 3, 4]) # <------ BINDING PARAMETERS
pqc = transpile(pqc, basis_gates=['u1', 'u2', 'u3', 'cx'], optimization_level=3)
Also note that by default assign_parameters
returns a new circuit, but you can also (alternatively) use
pqc.assign_parameters([1, 2, 3, 4], inplace=True)
Environment
What is happening?
I can't transpile a parameterized circuit with more than 3 controls
How can we reproduce the issue?
What should happen?
I got the error: QiskitError: 'Cannot synthesize MCRY with unbound parameter: p[0].'
Any suggestions?
No response