GateError: expected 1 parameters, was given 2
Quil 0.16.0
This error occurs when trying to get the unitary of an FSIM gate. I suspect that FSIM may not be know to quil, but it seems here that two-parameter gates may generally be unsupported.
import numpy as np
from quil.instructions import Gate, Qubit
from quil.expression import Expression
gate = Gate(name="FSIM", parameters=[Expression.from_number(complex(np.pi/3)), Expression.from_number(complex(np.pi/12))], qubits=[Qubit.from_fixed(0), Qubit.from_fixed(1)], modifiers=[])
gate.to_unitary_mut(2)
Thank you for opening this issue. It's true that we don't support $\mathbf{FSIM}$, so this error message really should reflect that instead. That alone is not quite a bug in its own right, but it needs improvement. The current flow essentially assumes you're providing more parameters than expected for a well-known gate:
>>> Program("RX(PI, PI) 0").instructions[0].to_unitary_mut(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
quil.GateError: expected 1 parameters, was given 2
As you guessed, the message you see is due to the incidental fact that none of the parameterized gates we currently support require more than one parameter, but as mentioned in #465, we should at least support $\mathbf{CAN}\left(\alpha, \beta, \gamma\right)$. When we add it, it will be a good time to improve this flow and return a more informative error message.
FSIM is included in pyquil (see https://github.com/rigetti/pyquil/blob/master/pyquil/simulation/matrices.py#L233 and https://github.com/rigetti/pyquil/blob/master/pyquil/gates.py#L551). I believe we should have a single source of truth for the default gate set. Most sensible this would live in quil-rs.
We definitely want to support the standard gates from the Quil spec, and we can include other well-known gates with consensus on a definition. Also, right now, it's a bit hard for users to discover what gates are "well-known", simply as a consequence of how it's coded. We should improve on that.
Even in Pyquil, FSIM is not provided as a Quil gate definition; it's provided as a matrix (that you could use to build a DEFGATE) and as a convenience function for constructing references to it (that require a DEFGATE FSIM in the program). This sounds like a better task for a Quil standard library; we could absolutely maintain (in another repo, I think) such a thing. Lots of Quil programs want
DEFGATE FSIM AS MATRIX: …
DEFGATE PHASEDFSIM AS MATRIX: …
and so on; providing those as a standard Quil library – and probably also a Python library you can install to get it with quil_stdlib.new_program_with_stdlib() or similar – seems like a very useful artifact. However, nothing about it needs to interact with quil-rs.
pyquil.gates has an FSIM gate as well.
If quil-rs is going to provide the unitary associated with gate, it needs to be aware of the standard definitions. Alternatively, we could require that programs always include defgates, but this would be a significant change.
pyquil.gateshas an FSIM gate as well.
That's the "convenience function for constructing references to it" I mentioned – if you use that without a DEFGATE, none of quilc, the QVM, quil-rs, or Rigetti's own translators will understand it and you'll get an error. The current state of the world is that you need a DEFGATE to use any gates that aren't listed in the Quil spec – with the exception, as you reported in #465, of XY and CAN, which is a bug in quil-rs that we will fix.
I'd also add that this is probably more convenient in practice – updating the Quil spec and/or quil-rs is slow and more fraught. If you work with Quil DEFGATEs, you can add new gates as you need to much more fluidly.
The translator requires only a DEFCAL, I think. It's not in the qvm, quilc, or the quil-spec, but I'm happy to make the MR there if it helps.