-
Notifications
You must be signed in to change notification settings - Fork 283
Description
I recently did some simple profiling with cProfile on circuits that consist mainly of single qubit rotations and CNOTs. It turned out that in my case about half (!) of the accumulated time was spend in BasicGate.__eq__().
The reason for this is that _send_qubit_pipeline() does a lot of operation comparisons when finding the gateloc. As CNOT is the controlled version of XGate() and the latter is a SelfInverseGate, which is a subclass of BasicGate, the __eq__() method of BasicGate is called a lot. Now, the problem is that BasicGate.__eq__() does a comparison of the matrices of the involved gates (!) if they both have one.
When comparing a CNOT or a XGate with another BasicGate with a matrix this is clearly extremely wasteful, as any two XGates that act on the same qubit are equal. By adding the following __eq__() method to XGate
def __eq__(self, other):
return isinstance(other, self.__class__)
I was able to reduce the total run time of my circuit from 409.136 seconds to 172.695 seconds!!!
I would directly provide a pull request that adds an __eq__() method to XGate and other similar gates, but would first like to discuss this. I think, that all gates whose matrix property is fixed (i.e., is always the same for any two instances of the respective class) should overwrite __eq__(). As there are many such gates, is is maybe worth introducing a new new subclass (called e.g., FixedMatrixGate) that implements this more efficient __eq__() and then have all those gates inherit from that class. The only downside is that if some other (possibly user-defined) BasicGate or a RotationGate happens to be by chance almost equal to, say, a XGate, then this would no longer by recognized. This however seems to be unlikely in real world code.