jaqalpaq.core package
- class jaqalpaq.core.AbstractGate(name, parameters=None, ideal_unitary=None)
The abstract base class for gate definitions. Everything here can be used whether the gate is defined by a macro in Jaqal, or is a gate defined by a pulse sequence in a gate definition file.
- Parameters:
name (str) – The name of the gate.
parameters (list(Parameter) or None) – What arguments (numbers, qubits, etc) the gate should be called with. If None, the gate takes no parameters.
ideal_unitary (function) – (deprecated) A function mapping a list of all classical arguments to a numpy 2D array representation of the gate’s ideal action in the computational basis.
- copy(*, name=None, parameters=None, ideal_unitary=False, origin=False, unitary=None)
Returns a shallow copy of the gate or gate definition.
- Parameters:
name – (optional) change the name in the copy.
parameters – (optional) change the parameters in the copy.
- property name
The name of the gate.
- property parameters
What arguments (numbers, qubits, etc) the gate should be called with.
- parse_parameters(*args, **kwargs)
Create a
GateStatementthat calls this gate. The arguments to this method will be the arguments the gate is called with. If all arguments are keyword arguments, their names should match the names of this gate’s parameters, and the values will be passed accordingly. If all arguments are positional arguments, each value will be passed to the next parameter in sequence. For convenience, calling the AbstractGate like a function is equivalent to this.- Returns:
The new statement.
- Return type:
- Raises:
JaqalError – If both keyword and positional arguments are passed.
JaqalError – If the wrong number of arguments are passed.
JaqalError – If the parameter names don’t match the parameters this gate takes.
- class jaqalpaq.core.AnnotatedValue(name, kind)
An abstract base class that represents a named (and optionally type-annotated) value. The actual value it represents may be context-dependent, but the name and type annotation are not. Currently, it’s used to implement both gate parameters and let statements, though it may find other uses as the language evolves.
- Parameters:
name (str) – The name the AnnotatedValue is labeled with.
kind – Optionally, an annotation denoting the the type of the value. If None, can hold a value of any type (like a macro parameter).
- property classical
A boolean flag denoting whether this AnnotatedValue has a classical type (ParamType.INT or ParamType.FLOAT) or a quantum type (ParamType.QUBIT or ParamType.REGISTER).
- Raises:
JaqalError – If the AnnotatedValue doesn’t have a type annotation.
- property kind
Optionally, an annotation denoting the type of the value.
- property name
The name the AnnotatedValue is labeled with.
- resolve_value(context=None)
Determines what value the AnnotatedValue represents in a particular context. For example, a gate parameter may have different values each time the gate is called. The implementation provided here simply checks to see if the name of this AnnotatedValue is defined in the context, and if so returns its value. However, subclasses are likely to provide different behavior.
- Parameters:
context (dict) – A dictionary mapping names defined in the scope of interest to the values corresponding to those names.
- Returns:
What value the AnnotatedValue represents.
- Raises:
JaqalError – If the AnnotatedValue doesn’t represent a fixed value within the context specified.
- class jaqalpaq.core.BlockBuilder(name)
Base class for several other builder objects. Stores statements and other blocks in a block.
- block(parallel=False)
Create, add, and return a new block builder to the statements stored in this block. Although it is not legal in Jaqal to nest blocks of the same type (except at top level), this builder ignores that restriction.
To create a block builder without adding it to this block, use the appropriate class constructor directly. This is useful when creating a macro or loop.
- Parameters:
parallel (bool or None) – Set to False (default) for a sequential block, True for a parallel block.
- Returns:
The new block builder.
- Return type:
- branch()
- build(inject_pulses=None, autoload_pulses=False, import_path=None)
Create a circuit.
Recursively construct an immutable core object of the appropriate type, as described by this Builder.
- Parameters:
inject_pulses – If given, use these pulses specifically.
autoload_pulses (bool) – Whether to employ the usepulses statement for parsing. Requires appropriate gate definitions.
import_path (str) – The path to be used for relative Jaqal imports.
- Returns:
An appropriate core type object.
- case(state, block)
- property expression
Return the expression being built, as a list.
- gate(name, *args, no_duplicate=False)
Add a gate to this block.
- Parameters:
name (str) – The name of the gate.
args – Any arguments to the gate.
no_duplicate (bool) – If True, only add this gate if it is not a duplicate of the gate to go right before it (or it is the first gate).
- loop(iterations, block, unevaluated=False)
Creates a new
LoopStatementobject, and adds it to the end of this block.- Parameters:
iterations (int) – How many times to repeat the loop.
block (BlockStatement, BlockBuilder) – The contents of the loop. If a
BlockStatementis passed, it will be used as the loop’s body. ABlockBuildermay also be passed, in which case the block it builds will be used as the loop’s body.unevaluated (bool) – If False, do not create a LoopStatement object to return.
- Returns:
The new loop.
- Return type:
- subcircuit(iterations=None)
Create, add, and return a new block builder to the statements stored in this block. Although it is not legal in Jaqal to nest certain blocks, this builder ignores these restrictions.
To create a subcircuit builder without adding it to this block, use the SubcircuitBlockBuilder class directly.
- Parameters:
iterations (int, str, AnnotatedValue, or None) – The number of times to run this on the hardware to accumulate statistics.
- class jaqalpaq.core.BlockStatement(parallel=False, subcircuit=False, iterations=1, statements=None)
Represents a Jaqal block statement; either sequential or parallel. Can contain other blocks, loop statements, and gate statements.
- Parameters:
parallel (bool) – Set to False (default) for a sequential block or True for a parallel block.
subcircuit (bool) – Set to False (default) for a standard sequential or parallel block of statements. Set to True to include an implicit prepare and measure as the first and last statements of this block.
iterations (bool) – The number of times a subcircuit block is run on the hardware. Not used for non-subcircuit blocks.
statements (list(GateStatement, LoopStatement, BlockStatement)) – The contents of the block; defaults to an empty block.
- property iterations
The number of times this block is run on the hardware. Only valid for subcircuit blocks; it will always return 1 otherwise.
- property parallel
True if this is a parallel block, False if sequential.
- property statements
The contents of the block. In addition to read-only access through this property, a basic sequence protocol (
len(), iteration, and indexing) is also supported to access the contents.
- property subcircuit
True if this is a subcircuit block, False otherwise.
- class jaqalpaq.core.Circuit(native_gates=None, *, name=None)
An immutable representation of an entire Jaqal program. The constants, registers, and native_gates properties correspond to the statements of the Jaqal program’s header; the macros and body properties correspond to the body statements of the Jaqal program.
This initializer should rarely be called directly; instead, the
jaqalpaq.core.CircuitBuilderobject-oriented interface orjaqalpaq.core.build()S-expression-based interface should be used to construct circuit objects.- Parameters:
native_gates (Optional[dict] or Optional[list]) – Set these gates as the native gates to be used in this circuit. If not given, gate definitions are automatically generated.
- Raises:
JaqalError – If native_gates is a dict and any gate’s name doesn’t match its dictionary key.
JaqalError – If any of the native_gates aren’t
GateDefinition. For example, if a macro is passed as a native gate.
- property body
Read-only access to a
BlockStatementobject that contains the main body of the program.
- property constants
Read-only access to a dictionary mapping names to
Constantobjects, corresponding toletstatements in the header of a Jaqal file.
- fundamental_registers()
- Returns:
all of the circuit’s registers that correspond to
registerstatements, that is, all those that are not aliases for some other register.- Return type:
list(Register)
- property macros
Read-only access to a dictionary mapping names to
Macroobjects, corresponding tomacrostatements in a Jaqal file.
- property native_gates
Read-only access to a dictionary mapping names to
GateDefinitionobjects, corresponding to the contents of a gate definition file.
- property registers
Read-only access to a dictionary mapping names to
Registerobjects, corresponding toregisterandmapstatements in the header of a Jaqal file.
- property usepulses
Read-only access to a list of
UsePulsesStatementobjects, corresponding tofrom ? usepulses ?statements in a Jaqal file.
- class jaqalpaq.core.CircuitBuilder(native_gates=None)
Object-oriented interface to the build() command. Build up a circuit from its components and then create a full Circuit on demand.
Unlike in legal Jaqal, we allow intermixing of body and header statements.
- build(context=None)
Override the build method to provide the native gates.
- let(name, value, unevaluated=False)
Creates a new
Constant, mapping the given name to the given value, and adds it to the circuit. Equivalent to the Jaqal header statementlet name value.- Parameters:
name (str) – The name of the new constant.
value (int or float) – The numeric value of the new constant.
unevaluated (bool) – If False, do not create a Register object to return.
- Returns:
The new object.
- macro(name, parameters=None, body=None, unevaluated=False)
Defines a
Macroand adds it to the circuit. Equivalent to the Jaqal statementmacro name parameters {body}.- Parameters:
name (str) – The name of the macro.
parameters (list) – What arguments (numbers, qubits, etc) the macro should be called with. If None, the macro takes no parameters.
body – What statements the macro expands to when called. This may also be a BlockBuilder.
unevaluated (bool) – If False, do not create a Macro object to return.
- Returns:
The new macro.
- Return type:
- Raises:
JaqalError – if the name of the macro or any of its parameters is invalid (see
validate_identifier()).
- map(name, source, idxs=None, unevaluated=False)
Creates a new
Register(orNamedQubit, if idxs is a single index rather than a slice) mapped to some subset of an existing register, and adds it to the circuit. Equivalent to the Jaqal header statementmap name source[idxs].- Parameters:
name (str) – The name of the new register.
source (Register or str) – The source register to map the new register onto, or its name.
idxs (slice, int, AnnotatedValue, str, or None) – Which qubits in the source register to map. If None, map the entire register.
unevaluated (bool) – If False, do not create a Register object to return.
- Returns:
The new register.
- Return type:
- register(name, size, unevaluated=False)
Allocates a new fundamental
Registerof the given size, adding it to the circuit under the given name. Equivalent to the Jaqal header statementregister name[size].- Parameters:
name (str) – The name of the register.
size (int) – How many qubits are in the register.
unevaluated (bool) – If False, do not create a Register object to return.
- Returns:
The new register.
- stretch_register(new_size)
If this circuit has a fundamental register smaller than
new_size, increase its size tonew_size.- Parameters:
new_size (int) – How large the register should become.
- Returns:
True if the register now contains exactly
new_sizequbits, False if the register previously contained and still contains more than that.- Return type:
bool
- Raises:
JaqalError – If the circuit does not have a fundamental register.
- usepulses(module, names=<built-in function all>, unevaluated=False)
Allocates a new
UsePulsesStatementrepresenting the given pulse file.- Parameters:
module (str) – the . delineated module path
names (list[str]) – either the special value all, or a list of tokens to import
unevaluated (bool) – If False, do not create a UsePulsesStatement object to return.
- Returns:
The new usepulses import.
- class jaqalpaq.core.Constant(name, value)
Bases:
AnnotatedValueRepresents a Jaqal let statement.
- Parameters:
name (str) – The name to bind the constant to.
value (Constant, int, or float) – The numeric value to bind to that name; can be either a literal value or another Constant.
- resolve_value(context=None)
Overrides:
AnnotatedValue.resolve_value()Unlike the superclass, ignores the context and simply returns the fixed value of the constant.
- property value
The fixed value of the constant.
- class jaqalpaq.core.GateDefinition(*args, origin=None, unitary=True, **kwargs)
Base:
AbstractGateRepresents a gate that’s implemented by a pulse sequence in a gate definition file. :param bool unitary: Whether or not the gate represents a purely unitary action.
- property classical_parameters
The classical parameters (ints or floats) this gate takes.
- Raises:
JaqalError – If this gate has parameters without type annotations; for example, if it is a macro.
- property ideal_unitary
(deprecated) The ideal unitary action of the gate on its target qubits
- property origin
The Jaqal module in which this gate is defined.
- property quantum_parameters
The quantum parameters (qubits or registers) this gate takes.
- Raises:
JaqalError – If this gate has parameters without type annotations; for example, if it is a macro.
- property unitary
Whether or not the gate is (ideally) unitary.
- property used_qubits
Return the parameters in this gate that are qubits. Subclasses may return the special symbol all indicating they operate on all qubits. Otherwise this is identical to quantum_parameters.
- class jaqalpaq.core.GateStatement(gate_def, parameters=None)
Represents a Jaqal gate statement.
- Parameters:
gate_def (GateDefinition) – The gate to call.
parameters (dict) – A map from gate parameter names to the values to pass for those parameters. Can be omitted for gates that have no parameters.
- property gate_def
The
GateDefinitionof the gate being called.
- property name
The name of the gate being called.
- property parameters
Read-only access to the dictionary mapping gate parameter names to the associated values.
- property used_qubits
An iterator over the qubits acted on by this gate statement. This may include the special symbol all indicating the gate operates on all qubits.
- class jaqalpaq.core.LoopStatement(iterations, statements=None)
Represents a Jaqal loop statement.
- Parameters:
iterations (int) – The number of times to repeat the loop.
statements (BlockStatement) – The block to repeat. If omitted, a new sequential block will be created.
- property iterations
The number of times this Loop will be executed. May be an integer or a let constant or a Macro parameter.
- property statements
The block that’s repeated by the loop statement. In addition to read-only access through this property, the same basic sequence protocol (
len(), iteration, and indexing) that theBlockStatementsupports can also be used on the LoopStatement, and will be passed through.
- class jaqalpaq.core.Macro(name, parameters=None, body=None)
Base:
AbstractGateRepresents a gate that’s implemented by Jaqal macro statement.
- Parameters:
name (str) – The name of the gate.
parameters (list(Parameter) or None) – What arguments (numbers, qubits, etc) the gate should be called with. If None, the gate takes no parameters.
body (BlockStatement or None) – The implementation of the macro. If None, an empty sequential BlockStatement is created.
- property body
A
BlockStatementthat implements the macro.
- copy(*, body=None, **kwargs)
Returns a shallow copy of the gate or gate definition.
- Parameters:
name – (optional) change the name in the copy.
parameters – (optional) change the parameters in the copy.
body – (optional) change the body of the macro in the copy
- class jaqalpaq.core.NamedQubit(name, alias_from, alias_index)
Represents a single qubit, which has had a name associated with it, typically by a map statement.
- Parameters:
- Raises:
JaqalError – If the index is an int larger than the the size of the source register.
- property alias_from
Specifies which register this qubit is taken from.
- property alias_index
Specifies which qubit in the
alias_fromregister this qubit actually represents.
- property fundamental
Always false, because single qubits cannot be defined with register statements.
- property name
The name by which the qubit can be referenced.
- renamed(name)
Creates a copy of this qubit with a different name.
- Parameters:
name (str) – The name to give the new qubit.
- Returns:
A new qubit with the same referent as this one but a different name.
- Return type:
- resolve_qubit(context=None)
Follow all map statements back to find which fundamental register, and which qubit in that register, this qubit is equivalent to.
- Parameters:
context (dict) – The context that’s used to resolve any
AnnotatedValueneeded to actually fix the referenced qubit.- Returns:
The fundamental register, and what index into that register, this qubit corresponds to.
- Return type:
(Register, int)
- class jaqalpaq.core.ParallelBlockBuilder
Build up a parallel code block.
- class jaqalpaq.core.ParamMeta(cls, bases, classdict, *, boundary=None, _simple=False, **kwds)
- property types
A list of all the types in this enumeration. This just excludes NONE.
- class jaqalpaq.core.ParamType(value)
- FLOAT = 2
- INT = 4
- NONE = None
- QUBIT = 1
- REGISTER = 3
- classmethod make(obj)
Create a new ParamType or raise a JaqalError if not possible.
- class jaqalpaq.core.Parameter(name, kind)
Base:
AnnotatedValueRepresents a parameter that a gate or macro accepts. In addition to the functionality of the base class, it also supports type-checking. Furthermore, it can be indexed and sliced, if it represents a
Registerparameter. Thus, it can be used within the body of a macro exactly as if it were a register defined by amaporregisterstatement.- validate(value)
Checks to see if the given value can be passed to this Parameter. Specifically, the value’s type is checked against any type annotation this Parameter may have.
- Parameters:
value – The candidate value to validate.
- Raises:
JaqalError – If the value is not acceptable for this Parameter.
- class jaqalpaq.core.Register(name, size=None, alias_from=None, alias_slice=None)
Represents a qubit register, whether defined by a register statement or a map statement. Can be indexed into (but not sliced) to obtain a specific
NamedQubitfrom the register.- Parameters:
name (str) – The name by which the register can be referenced.
size (int or None) – If the register is a fundamental register (defined by a register statement), specifies how many qubits are allocated for it. Must be omitted for non-fundamental registers.
alias_from (Register, Parameter, or None) – If the register is defined by a map statement, specifies which register it’s mapped from all or a subset of. If omitted, the register is a fundamental register.
alias_slice (slice or None) – If the register isn’t fundamental, specifies what subset of the
alias_fromregister is mapped to this register. Can be omitted to map all of the register. Must be omitted for a fundamental register. Some or all of the slice can be specified by Parameters rather than integers.
- Raises:
JaqalError – if passed a Parameter of the wrong type.
- property alias_from
What register this register’s mapped from, or None if it’s fundamental.
- property alias_slice
If the register isn’t fundamental, specifies what subset of the
alias_fromregister is mapped to this register. None if this register is fundamental or if all ofalias_fromis mapped to it.
- property fundamental
True if the register is defined by a register statement, False if it’s mapped from some other register.
- property name
The name by which the register can be referenced.
- resolve_qubit(idx, context=None)
Given a specific qubit in this register, follow all map statements back to find which fundamental register, and which qubit in that register, the specified qubit is equivalent to.
- Parameters:
idx (int) – Which qubit from this register to resolve.
context (dict) – The context that’s used to resolve any
AnnotatedValueneeded to actually fix the referenced qubit.
- Returns:
The fundamental register, and what index into that register, the specified qubit corresponds to.
- Return type:
(Register, int)
- resolve_size(context=None)
Determines how many qubits are in the register.
- Parameters:
context (dict) – The context that’s used to resolve any
AnnotatedValueneeded to actually fix the register’s size.- Returns:
The size of the register.
- Return type:
int
- property size
How many qubits are in the register.
Note: This may return a
Constantif that is how the size is defined. To always get an integer, use ex: int(reg.size).- Raises:
JaqalError – If the register’s size is undefined because it’s mapped from a
Parameter.
- class jaqalpaq.core.SequentialBlockBuilder
Build up a sequential code block.
jaqalpaq.core.algorithm subpackage
- jaqalpaq.core.algorithm.expand_macros(circuit, preserve_definitions=False)
Expand macros in the given circuit.
- Parameters:
circuit (Circuit) – The circuit in which to expand macros.
preserve_definitions (bool) – If True, leave the definitions in.
- Returns:
A new, normalized circuit. Although the circuit will be new, it may share structure with the input circuit, thus the input should not be changed.
- Return type:
- jaqalpaq.core.algorithm.expand_subcircuits(circuit, prepare_def=None, measure_def=None)
Expand subcircuit blocks by adding a prepare and measure gate as the first and last gates in the sequential block.
- Parameters:
circuit (Circuit) – The circuit in which to expand subcircuits.
prepare_def (str or GateDefinition) – The definition of the gate to place in the beginning of each subcircuit. If a string is provided, look up in the circuit’s native gates. If not given, create a new definition using this string or ‘prepare_all’.
measure_def (str or GateDefinition) – The definition of the gate to place at the end of each subcircuit. If a string is provided, look up in the circuit’s native gates. If not given, create a new definition using this string or ‘measure_all’.
- jaqalpaq.core.algorithm.fill_in_let(circuit, override_dict=None)
Fill in the value in a let-statement directly into the circuit.
- Parameters:
circuit (Circuit) – The circuit to fill in let statement constants.
override_dict (dict) – A dictionary mapping strings to ints or floats to use instead of the values in the Jaqal file.
- Returns:
A new, normalized circuit. Although the circuit will be new, it may share structure with the input circuit, thus the input should not be changed.
- Return type:
- jaqalpaq.core.algorithm.get_used_qubit_indices(obj, context=None)
Recursively find all qubits used in this object.
- Parameters:
obj (Circuit, BlockStatement, LoopStatement, or GateStatement) – The statement or circuit to query.
context (dict) – If using this method to inspect an instruction in a macro call, provides information about the current scope. Unless you know precisely what you’re doing, you should most likely omit this.
- Returns:
A mapping from fundamental register names to sets of the indices within those registers which are used by the instruction.
- Return type:
dict
- jaqalpaq.core.algorithm.normalize_blocks_with_unitary_timing(circuit)
Normalize the given circuit to contain only parallel blocks. This is possible by assuming that all gates run in parallel run in one unit of time.
This does not expand loops, macros, lets, or maps.