Protocols#

We write bloqs so we can query properties, draw diagrams, and check the correctness of quantum algorithms. Basically: we write bloqs so we can do things with them! Each ‘thing’–or genre of thing–we want to do has an associated “protocol”. In our usage of the term, a protocol is a set of methods, functions, or procedures to structure a relevant piece of functionality.

Components of a protocol#

Specifically, a protocol is composed of:

  • A method on Bloq that takes no arguments and returns a property of interest. This is the interface

  • A method on Bloq that takes system-supplied arguments which bloq authors can override to provide information for the protocol. This is the implementation.

  • A Python module containing functions for plumbing the implementation into the interface and other additional functionality.

  • Helper functions for implementing one protocol in terms of another called fallbacks. Some protocols have a default fallback that requires no special action from the bloq author.

Summary of Qualtran protocols#

Decomposition#

You can get a decomposition of a bloq in terms of its component bloqs by calling bloq.decompose_bloq(). Additional functionality is provided by the qualtran.BloqBuilder class. To implement this protocol, bloq authors can override Bloq.build_composite_bloq(...). A fallback to use a Cirq decomposition is provided. There is no default fallback – qualtran.DecomposeNotImplementedError will be raised.

Call Graph#

You can get a directed-acyclic graph representing the hierarchical decomposition of bloqs by calling bloq.call_graph() or direct callees with bloq.bloq_counts(). Additional functionality is contained in the qualtran.resource_counting module. To implement this protocol, bloq authors can override Bloq.build_call_graph(...). The default fallback uses the decomposition protocol and build_cbloq_call_graph(...). See the full call graph protocol documentation for details.

Tensor#

You can get a tensor (i.e. vector or matrix representation) of a bloq or composite bloq by calling bloq.tensor_contract(). Additional functionality is contained in the qualtran.simulation.tensor module. To implement this protocol, bloq authors can override Bloq.add_my_tensors(...). The default fallback uses the decomposition protocol and cbloq_as_contracted_tensor(...). See the full tensor protocol documentation for details.

Classical#

You can get a bloq’s classical action on a basis state by calling bloq.call_classically(**vals). Additional functionality is contained in the qualtran.simulation.classical_sim module. To implement this protocol, bloq authors can override Bloq.on_classical_vals(...). The default fallback uses the decomposition protocol and cbloq_call_classically. An exception should be raised if a bloq acts non-classically on its data.

Other methods#

Other methods on Bloq can be called or overridden to support drawing or interoperability with Cirq.