Commit Graph

1 Commits

Author SHA1 Message Date
Jake Lishman bcf5ce4951
Rewrite singleton handling including `SingletonInstruction` (#11014)
* Rewrite singleton handling including `SingletonInstruction`

This is a large rewrite of the singleton gate handling, building off the
work done across the library to make the initial implementation work.

There are two main purposes to this commit:

* Make `SingletonInstruction` available in addition to `SingletonGate`,
  and have these be easy to maintain in conjunction, not need to
  duplicate overrides between them, and not require inheritors to do any
  nasty multiple inheritance or the like.

* Fix regressions in the construction time of `SingletonGate` instances.

In the end, this turned into a fairly complete rewrite that completely
switches out the method of defining the classes; it transpires that the
previous way of having the "immutable overrides" on _all_ instances of
the classes was the main source of slowdown, with `__setattr__` being a
large problem.  The previous method was far easier from an
implementation perspective, but the runtime costs ended up being too
high.

This new form takes a vastly different strategy, explained in detail in
`qiskit/circuit/singleton.py`.  The gist is that we instead make the
singleton instance a _subclass_ of the class object we're creating, and
only it contains the overrides to make itself immutable.  We get around
the instantiation problem (`__init__` isn't special and doesn't
skip the forbidden `__setattr__`) by constructing an instance of the
_base_ class, and then dynamically switching in the overrides
afterwards.  Since the overrides and the dynamic singleton type of the
instance are designed to be co-operative (including in `__slots__`
layout), this can be done safely.

* Make singleton documentation public

* Add tests of new singleton behaviour

* Fix typos

Co-authored-by: Matthew Treinish <mtreinish@kortar.org>

---------

Co-authored-by: Matthew Treinish <mtreinish@kortar.org>
2023-10-13 19:04:48 +00:00