Skip to content

Programs

A Qoala program is a Python callable annotated such that euqalyptus can intercept its body and emit Qoala HIR. There are two equivalent ways to declare one.

@QoalaProgram — the decorator

from euqalyptus import QoalaProgram

@QoalaProgram
def my_program():
    ...

The decorator wraps your function in an instance with .compile() and .module accessors. Calling the decorated object is equivalent to calling .compile():

ret_val, module = my_program()           # equivalent to my_program.compile()
ret_val, module = my_program.compile()

After a successful compile, my_program.module returns the QoalaModule. Accessing it before compilation raises NotYetCompiledError.

QoalaProgramBase — the class

from euqalyptus import QoalaProgramBase

class MyProgram(QoalaProgramBase):
    def main(self):
        ...

You implement main(self), then instantiate and compile:

program = MyProgram()
ret_val, module = program.compile()

Quirky __new__

QoalaProgramBase.__new__ uses some hacks to wire cls.main as the entry function. As a result, an instance of a subclass of QoalaProgramBase is not an instance of QoalaProgramBase — it is an instance of QoalaProgram. Don't rely on isinstance(obj, QoalaProgramBase).

If main is missing or remains @abstractmethod, instantiation raises QuantumProgramNotImplementedError.

When to use which

Decorator Class
Single-shot scripts
You need state across compilations
Inheritance for a family of related programs
You want the program to also be callable as a regular function ✓ (via compile())
Importable in tests as one symbol both both

For most short examples, the decorator is the natural fit. The class form starts to pay off when you have a couple of different programs that share helpers — for instance, the teleportation example is two near-identical programs that could share a base class.

What the entry function may contain

Inside the body of a @QoalaProgram (or a main method), the SDK objects don't actually do their operation directly — they record an AST node into the active program's module. Conceptually:

@QoalaProgram
def example():
    # Declares a remote symbol; recorded into the AST.
    Remote("Bob")

    # Records a qnet.eprs / qnet.new_qubit op into the current function body.
    q = Entangle("Bob")

    # Records a qnet.measure op; m is a QoalaInteger AST node, not a Python int.
    m = q.measure()

This is why operations in qoala programs look like ordinary Python: the SDK is using constructors and methods to build the IR. You can mix in regular Python control structures (loops over compile-time values, helper functions, …) freely — anything that is evaluated before or after the SDK calls is just regular Python. What you cannot do is treat the runtime SDK values (such as m above) as plain Python values: comparing m == 0 returns a recorded comparison expression, not a boolean. For control flow that depends on runtime values, see Branching.

After compilation

The QoalaModule returned from .compile() exposes the textual HIR via module.asm (the canonical input to qoala-opt) and the generic-form variant via module.generic_asm. The full list of recorded functions is reachable through module.functions, the remote declarations encountered during compilation through module.remotes, and the function currently being built (useful for introspection mid-compile, less so afterward) through module.current_function. For details on compile()'s arguments and what the module exposes, see Compilation.

API reference

QoalaProgram

QoalaProgram(entry_fun: Callable)

Decorator that turns a Python function into a Qoala program.

Applying @QoalaProgram to a function marks it as a Qoala program. The decorator wraps the function in an object that exposes a :meth:compile method; calling compile() runs the decorated function under the SDK's recording mode and produces a :class:QoalaModule containing Qoala HIR.

Example
@QoalaProgram
def my_function():
    q = LocalQubit()
    q.measure()

_, module = my_function.compile()
print(module.asm)

Calling the decorated object is equivalent to calling .compile() on it; my_function() and my_function.compile() both return the same (return_value, QoalaModule) tuple.

module property

module: QoalaModule

The compiled :class:QoalaModule.

Returns:

Type Description
QoalaModule

The module produced by the most recent successful call to

QoalaModule

meth:compile.

Raises:

Type Description
NotYetCompiledError

If :meth:compile has not yet been called (or has not returned successfully) on this program.

compile

compile(*args: Any, compile_lazy: bool = False, singular_comm_ops: bool = False, **kwargs: Any) -> Tuple[int, QoalaModule]

Compile the decorated program into a Qoala HIR module.

compile() runs the decorated function under the SDK's recording mode, so every SDK call inside the function body is intercepted and recorded as an AST node rather than performing its nominal action. Once the function returns, the recorded AST is walked and emitted as MLIR via the qnet Python bindings, yielding a :class:QoalaModule whose .asm property is the textual HIR consumable by qoala-opt.

compile() acquires a process-wide lock and uses class-level state on :class:QoalaProgram to track the program currently being compiled, so two programs cannot be compiled concurrently from the same process — calls serialize.

Parameters:

Name Type Description Default
*args Any

Positional arguments forwarded to the entry function.

()
compile_lazy bool

When True, only the internal pseudo-AST is built; MLIR emission is skipped. Useful in tests that want to assert structural properties without paying the cost of emission. Defaults to False.

False
singular_comm_ops bool

When True, classical sends that carry a single value are emitted as the scalar HIR ops (qnet.send_int, qnet.send_float) instead of the default tensor-form variants (qnet.send_ints, qnet.send_floats). This avoids generating tensor values in HIR and simplifies the downstream pipeline. The flag does not affect receives: recv_int and recv_float are first-class scalar SDK calls and always emit scalar HIR. Defaults to False.

False
**kwargs Any

Keyword arguments forwarded to the entry function.

{}

Returns:

Type Description
int

A tuple (return_value, module) where return_value

QoalaModule

is whatever the entry function returned (often None)

Tuple[int, QoalaModule]

and module is the compiled :class:QoalaModule.

compile_lazy_flag classmethod

compile_lazy_flag(new_flag_value: Optional[bool] = None) -> bool

Get or set the class-level compile_lazy toggle.

When set, subsequent calls to :meth:compile skip the MLIR-emission stage by default and build only the internal pseudo-AST. Useful in tests and repeated-compilation harnesses.

Parameters:

Name Type Description Default
new_flag_value Optional[bool]

When not None, sets the toggle to this value. When None (the default), only reads the current value.

None

Returns:

Type Description
bool

The current value of the toggle (after the optional set).

compile_singular_comm_ops classmethod

compile_singular_comm_ops(new_flag_value: Optional[bool] = None) -> bool

Get or set the class-level singular_comm_ops toggle.

When set, subsequent calls to :meth:compile emit the scalar HIR ops (qnet.send_int, qnet.send_float) for single-value classical sends instead of their tensor-form counterparts. The flag does not affect receives — see :meth:compile for the full discussion.

Parameters:

Name Type Description Default
new_flag_value Optional[bool]

When not None, sets the toggle to this value. When None (the default), only reads the current value.

None

Returns:

Type Description
bool

The current value of the toggle (after the optional set).

current_function classmethod

current_function() -> QoalaFunction

Return the :class:QoalaFunction currently being built.

Used by the SDK constructors to find the function they should record into; rarely useful in user code.

Returns:

Type Description
QoalaFunction

The active program's current function.

Raises:

Type Description
RuntimeError

If no program is currently being compiled.

get_declared_remote classmethod

get_declared_remote(remote_name: str) -> Any

Look up a previously declared remote by name.

Parameters:

Name Type Description Default
remote_name str

The symbolic name of the remote peer.

required

Returns:

Name Type Description
The Any

class:DeclaredRemote object for remote_name if

Any

one was declared in the current compilation, otherwise

Any

None.

add_declared_remote classmethod

add_declared_remote(remote_name: str, remote: Any) -> None

Register a remote-peer declaration in the current compilation.

Used internally by :class:~euqalyptus.operations.Remote to record a new alias; user code should call Remote("Name") instead.

Parameters:

Name Type Description Default
remote_name str

The symbolic name of the remote.

required
remote Any

The :class:DeclaredRemote AST node to associate with remote_name.

required

Raises:

Type Description
RuntimeError

If a remote with the same name has already been declared in this compilation.

QoalaProgramBase

QoalaProgramBase(entry_fun: Callable)

Bases: QoalaProgram, ABC

Class-based alternative to the @QoalaProgram decorator.

Subclass QoalaProgramBase and implement the abstract :meth:main method to define a Qoala program. Instantiating the subclass and calling .compile() runs main under the SDK's recording mode, just like the decorator form.

Example
class MyProgram(QoalaProgramBase):
    def main(self):
        q = LocalQubit()
        q.measure()

program = MyProgram()
_, module = program.compile()
Warning

Due to the way __new__ is wired, an instance of a subclass of QoalaProgramBase is not an instance of QoalaProgramBase — it is an instance of :class:QoalaProgram. Do not rely on isinstance(obj, QoalaProgramBase).

main abstractmethod

main(*args: Any, **kwargs: Any) -> Any

Entry point of a class-based Qoala program.

Subclasses must implement this method. Inside its body you can use any quantum or classical primitive from the euqalyptus package — types, qubit operations, communication, and control-flow constructs — just as you would inside a @QoalaProgram decorated function.

Parameters:

Name Type Description Default
*args Any

Positional arguments forwarded by :meth:QoalaProgram.compile.

()
**kwargs Any

Keyword arguments forwarded by :meth:QoalaProgram.compile.

{}

Returns:

Type Description
Any

Whatever value the program wants to return to the caller

Any

(typically classical measurement outcomes or None).

Any

The returned value becomes the first element of the

Any

(return_value, QoalaModule) tuple from

Any

meth:compile.