pygsti.processors.compilationrules.CliffordCompilationRules#

class CliffordCompilationRules(native_gates_processorspec, compile_type='absolute')#

Bases: CompilationRules

An collection of compilations for clifford gates.

Holds mapping between operation labels (Label objects) and circuits (Circuit objects).

A CliffordCompilationRules holds a processor specification of the “native” gates of a processor and uses it to produce compilations of many of/all Clifford operations. Currently, the native gates should all be Clifford gates, so that the processor spec’s compute_clifford_symplectic_reps method gives representations for all of its gates.

Compilations can be either “local” or “non-local”. A local compilation only uses gates that act on its target qubits. All 1-qubit gates can be local. A non-local compilation uses qubits outside the set of target qubits (e.g. a CNOT between two qubits between which there is no native CNOT). Currently, non-local compilations can only be constructed for the CNOT gate.

To speed up the creation of local compilations, a CliffordCompilationRules instance stores “template” compilations, which specify how to construct a compilation for some k-qubit gate on qubits labeled 0 to k-1. When creating a compilation for a gate, a template is used if a suitable one can be found; otherwise a new template is created and then used.

Parameters:
  • native_gates_processorspec (QubitProcessorSpec) – The processor specification of “native” Clifford gates which all compilation rules are composed from.

  • compile_type ({"absolute","paulieq"}) – The “compilation type” for this rules set. If “absolute”, then compilations must match the gate operation being compiled exactly. If “paulieq”, then compilations only need to match the desired gate operation up to a Paui operation (which is useful for compiling multi-qubit Clifford gates / stabilizer states without unneeded 1-qubit gate over-heads).

Methods

__init__(native_gates_processorspec[, ...])

add_clifford_compilation_template(gate_name, ...)

Adds a new compilation template for gate_name.

add_compilation_of(oplabel[, force, ...])

Adds a compilation of oplabel in the context of allowed_filter, if any.

add_compilation_rule(gate_name, ...[, unitary])

Add a compilation rule for a gate name, given as a circuit or function.

add_given_clifford_compilation_template(...)

Adds a specific compilation template (as opposed to searching for one) after checking its validity.

add_local_compilation_of(oplabel[, unitary, ...])

Adds a new local compilation of oplabel.

add_nonlocal_compilation_of(oplabel[, ...])

Add a potentially non-local compilation of oplabel to this library.

add_specific_compilation_rule(gate_label, ...)

Add a compilation rule for a gate at a specific location (target labels)

apply_to_circuits(circuits, **kwargs)

Use these compilation rules to convert one list of circuits into another one.

apply_to_processorspec(processor_spec[, ...])

Use these compilation rules to convert one processor specification into another one.

cast(obj)

Convert an object into compilation rules, if it isn't already.

create_aux_info()

Create auxiliary information that should be stored along with the compilation rules herein.

create_standard(base_processor_spec[, ...])

Create a common set of compilation rules based on a base processor specification.

filter_connectivity(gate_name, allowed_filter)

Compute the QubitGraph giving the available gate_name gates subject to allowed_filter.

retrieve_compilation_of(oplabel[, force, ...])

Get a compilation of oplabel in the context of allowed_filter, if any.

add_clifford_compilation_template(gate_name, nqubits, unitary, srep, available_gatelabels, available_sreps, verbosity=1, max_iterations=10)#

Adds a new compilation template for gate_name.

Parameters:
  • gate_name (str) – The gate name to create a compilation for. If it is recognized standard Clifford name (e.g. ‘H’, ‘P’, ‘X’, ‘CNOT’) then unitary and srep can be None. Otherwise, you must specify either (or both) of unitary or srep.

  • nqubits (int) – The number of qubits this gate acts upon.

  • unitary (numpy.ndarray) – The unitary action of the gate being templated. If, as is typical, you’re compiling using Clifford gates, then this unitary should correspond to a Clifford operation. If you specify unitary, you don’t need to specify srep - it is computed automatically.

  • srep (tuple, optional) – The (smatrix, svector) tuple giving the symplectic representation of the gate being templated.

  • available_glabels (list) – A list of the gate labels (Label objects) that are available for use in compilations.

  • available_sreps (dict) – A dictionary of available symplectic representations. Keys are gate labels and values are numpy arrays.

  • verbosity (int, optional) – An integer >= 0 specifying how much detail to send to stdout.

  • max_iterations (int, optional) – The maximum number of iterations for the iterative template compilation-finding algorithm.

Returns:

A tuple of the operation labels (essentially a circuit) specifying the template compilation that was generated.

Return type:

tuple

add_compilation_of(oplabel, force=False, allowed_filter=None, verbosity=1, check=True)#

Adds a compilation of oplabel in the context of allowed_filter, if any.

If allowed_filter is None then the compilation is recorded under the key oplabel. Otherwise, the compilation is recorded under the key (oplabel,`context_key`) where context_key is frozenset(allowed_filter) when allowed_filter is a set, and context_key is frozenset(allowed_filter.items()) when allowed_filter is a dict.

Parameters:
  • oplabel (Label) – The label of the gate to compile.

  • force (bool, optional) – If True, then an attempt is made to recompute a compilation even if oplabel already exists in this CompilationLibrary. Otherwise compilations are only computed when they are not present.

  • allowed_filter (dict or set, optional) – Specifies which gates are allowed to be used in this non-local compilation. If a dict, keys must be gate names (like “CNOT”) and values QubitGraph objects indicating where that gate (if it’s present in the library) may be used. If a set, then it specifies a set of qubits and any gate in the current library that is confined within that set is allowed. If None, then all gates within the library are allowed.

  • verbosity (int, optional) – An integer >= 0 specifying how much detail to send to stdout.

  • check (bool, optional) – Whether to perform internal consistency checks.

Return type:

None

add_compilation_rule(gate_name, template_circuit_or_fn, unitary=None)#

Add a compilation rule for a gate name, given as a circuit or function.

Parameters:
  • gate_name (str) – The gate name to add a rule for.

  • template_circuit_or_fn (Circuit or callable) – The rule. This can be specified as either a circuit or as a function. If a circuit is given, it must be on the gate’s local state space, assumed to be a k-qubit space (for a k-qubit gate) with qubit labels 0 to k-1. That is, the circuit must have line labels equal to 0…k-1. If a function if given, the function must take as a single argument a tuple of state space labels that specify the target labels of the gate.

  • unitary (numpy.ndarray) – The unitary corresponding to the gate. This can be left as None if gate_name names a standard or internal gate known to pyGSTi.

Return type:

None

add_given_clifford_compilation_template(gate_name, nqubits, unitary, srep, compilation, available_sreps)#

Adds a specific compilation template (as opposed to searching for one) after checking its validity.

Parameters:
  • gate_name (str) – The gate name to create a compilation for. If it is recognized standard Clifford name (e.g. ‘H’, ‘P’, ‘X’, ‘CNOT’) then unitary and srep can be None. Otherwise, you must specify either (or both) of unitary or srep.

  • nqubits (int) – The number of qubits this gate acts upon.

  • unitary (numpy.ndarray) – The unitary action of the gate being templated. If, as is typical, you’re compiling using Clifford gates, then this unitary should correspond to a Clifford operation. If you specify unitary, you don’t need to specify srep - it is computed automatically.

  • srep (tuple, optional) – The (smatrix, svector) tuple giving the symplectic representation of the gate being templated.

  • available_sreps (dict) – A dictionary of available symplectic representations. Keys are gate labels and values are numpy arrays.

  • verbosity (int, optional) – An integer >= 0 specifying how much detail to send to stdout.

Returns:

A tuple of the operation labels (essentially a circuit) specifying the template compilation that was generated.

Return type:

tuple

add_local_compilation_of(oplabel, unitary=None, srep=None, max_iterations=10, force=False, verbosity=1)#

Adds a new local compilation of oplabel.

Parameters:
  • oplabel (Label) – The label of the gate to compile. If oplabel.name is a recognized standard Clifford name (e.g. ‘H’, ‘P’, ‘X’, ‘CNOT’) then no further information is needed. Otherwise, you must specify either (or both) of unitary or srep.

  • unitary (numpy.ndarray, optional) – The unitary action of the gate being compiled. If, as is typical, you’re compiling using Clifford gates, then this unitary should correspond to a Clifford operation. If you specify unitary, you don’t need to specify srep - it is computed automatically.

  • srep (tuple, optional) – The (smatrix, svector) tuple giving the symplectic representation of the gate being compiled.

  • max_iterations (int, optional) – The maximum number of iterations for the iterative compilation algorithm.

  • force (bool, optional) – If True, then a compilation is recomputed even if oplabel already exists in this CompilationLibrary. Otherwise compilations are only computed when they are not present.

  • verbosity (int, optional) – An integer >= 0 specifying how much detail to send to stdout.

Return type:

None

add_nonlocal_compilation_of(oplabel, force=False, allowed_filter=None, verbosity=1, check=True)#

Add a potentially non-local compilation of oplabel to this library.

This method currently only generates a compilation for a non-local CNOT, up to arbitrary Pauli gates, between a pair of unconnected qubits. It converts this CNOT into a circuit of CNOT gates between connected qubits, using a fixed circuit form. This compilation is not optimal in at least some circumstances.

If allowed_filter is None then the compilation is recorded under the key oplabel. Otherwise, the compilation is recorded under the key (oplabel,`context_key`) where context_key is frozenset(allowed_filter) when allowed_filter is a set, and context_key is frozenset(allowed_filter.items()) when allowed_filter is a dict.

Parameters:
  • oplabel (Label) – The label of the gate to compile. Currently, oplabel.name must equal “CNOT”.

  • force (bool, optional) – If True, then a compilation is recomputed even if oplabel already exists in this CompilationLibrary. Otherwise compilations are only computed when they are not present.

  • allowed_filter (dict or set, optional) – Specifies which gates are allowed to be used in this non-local compilation. If a dict, keys must be gate names (like “CNOT”) and values QubitGraph objects indicating where that gate (if it’s present in the library) may be used. If a set, then it specifies a set of qubits and any gate in the current library that is confined within that set is allowed. If None, then all gates within the library are allowed.

  • verbosity (int, optional) – An integer >= 0 specifying how much detail to send to stdout.

  • check (bool, optional) – Whether to perform internal consistency checks.

Return type:

None

add_specific_compilation_rule(gate_label, circuit, unitary)#

Add a compilation rule for a gate at a specific location (target labels)

Parameters:
  • gate_label (Label) – The gate label to add a rule for. Includes the gate’s name and its target state space labels (gate_label.sslbls).

  • circuit (Circuit) – The rule, given as a circuit on the gate’s local state space, i.e. the circuit’s line labels should be the same as gate_label.sslbls.

  • unitary (numpy.ndarray) – The unitary corresponding to the gate. This can be left as None if gate_label.name names a standard or internal gate known to pyGSTi.

Return type:

None

apply_to_circuits(circuits, **kwargs)#

Use these compilation rules to convert one list of circuits into another one.

Additional kwargs are passed through to Circuit.change_gate_library during translation. Common kwargs include depth_compression=False or allow_unchanged_gates=True.

Parameters:

circuits (list of Circuits) – The initial circuits, which should contain the gates present within the circuits/functions of this compilation rules object.

Return type:

list of Circuits

apply_to_processorspec(processor_spec, action='replace', gates_to_skip=None)#

Use these compilation rules to convert one processor specification into another one.

Parameters:
  • processor_spec (QubitProcessorSpec) – The initial processor specification, which should contain the gates present within the circuits/functions of this compilation rules object.

  • action ({"replace", "add"}) – Whether the existing gates in processor_spec are conveyed to the the returned processor spec. If “replace”, then they are not conveyed, if “add” they are.

  • gates_to_skip (list) – Gate names or labels to skip during processor specification construction.

Return type:

QubitProcessorSpec

classmethod cast(obj)#

Convert an object into compilation rules, if it isn’t already.

Parameters:

obj (object) – The object to convert.

Return type:

CompilationRules

create_aux_info()#

Create auxiliary information that should be stored along with the compilation rules herein.

(Currently unused, but perhaps useful in the future.)

Return type:

dict

classmethod create_standard(base_processor_spec, compile_type='absolute', what_to_compile=('1Qcliffords',), verbosity=1)#

Create a common set of compilation rules based on a base processor specification.

Parameters:
  • base_processor_spec (QubitProcessorSpec) – The processor specification of “native” Clifford gates which all the compilation rules will be in terms of.

  • compile_type ({"absolute","paulieq"}) – The “compilation type” for this rules set. If “absolute”, then compilations must match the gate operation being compiled exactly. If “paulieq”, then compilations only need to match the desired gate operation up to a Paui operation (which is useful for compiling multi-qubit Clifford gates / stabilizer states without unneeded 1-qubit gate over-heads).

  • what_to_compile ({"1Qcliffords", "localcnots", "allcnots", "paulis"}) – What operations should rules be created for? Allowed values may depend on the value of compile_type.

Return type:

CliffordCompilationRules

filter_connectivity(gate_name, allowed_filter)#

Compute the QubitGraph giving the available gate_name gates subject to allowed_filter.

The filter adds constraints to by specifying the availability of gate_name.

Parameters:
  • gate_name (str) – The gate name.

  • allowed_filter (dict or set, optional) – Specifies which gates are allowed to be to construct this connectivity. If a dict, keys must be gate names (like “CNOT”) and values QubitGraph objects indicating where that gate (if it’s present in the library) may be used. If a set, then it specifies a set of qubits and any gate in the current library that is confined within that set is allowed. If None, then all gates within the library are allowed.

Return type:

QubitGraph

retrieve_compilation_of(oplabel, force=False, allowed_filter=None, verbosity=1, check=True)#

Get a compilation of oplabel in the context of allowed_filter, if any.

This is often more convenient than querying the CompilationLibrary directly as a dictionary, because:

  1. If allowed_filter is not None, this handles the correct querying of the dictionary to find out if there is a previously saved compilation with this allowed_filter context.

  2. If a compilation is not present, this method will try to compute one.

This method does not store the compilation. To store the compilation first call the method add_compilation_of().

Parameters:
  • oplabel (Label) – The label of the gate to compile.

  • force (bool, optional) – If True, then an attempt is made to recompute a compilation even if oplabel already exists in this CompilationLibrary. Otherwise compilations are only computed when they are not present.

  • allowed_filter (dict or set, optional) – Specifies which gates are allowed to be used in this non-local compilation. If a dict, keys must be gate names (like “CNOT”) and values QubitGraph objects indicating where that gate (if it’s present in the library) may be used. If a set, then it specifies a set of qubits and any gate in the current library that is confined within that set is allowed. If None, then all gates within the library are allowed.

  • verbosity (int, optional) – An integer >= 0 specifying how much detail to send to stdout.

  • check (bool, optional) – Whether to perform internal consistency checks.

Return type:

Circuit