Skip to content

Transformations API Reference

Pass Management

PassManager

Manage and execute a sequence of passes on a model.

The PassManager implements a compiler-style pass pattern, enabling both general-purpose and algorithm-specific manipulations of optimization models. Each pass is an atomic operation that transforms the model or extracts information from the model. The PassManager runs each pass in order and produces an IR that records the transformations applied and supports back-transformations.

Parameters:

  • passes (Sequence[BasePass], default: None ) –

    An ordered sequence of Pass instances to apply, default None.

add(pass_: BasePass) -> None

Append a pass to the configured passes.

Parameters:

  • pass_ (BasePass) –

    The pass to add to this PassManager's configured passes.

run(model: Model) -> IR

Apply all configured passes.

Apply all configured passes to the given model and return the resulting intermediate representation.

Parameters:

  • model (Model) –

    The model to be transformed.

Returns:

  • IR

    The intermediate representation of the model after transformation.

backwards(solution: Solution, ir: IR) -> Solution

Apply the back transformation to the given solution.

Parameters:

  • solution (Solution) –

    The solution to transform back to a representation fitting the original (input) model of this PassManager.

  • ir (IR) –

    The intermediate representation (IR) resulted from the run call.

Returns:

  • Solution

    A solution object representing a solution to the original problem passed to this PassManager's run method.

__str__() -> str

Human readable string.

__repr__() -> str

Debug string.

IR

Intermediate representation of a transformed model.

The IR contains the resulting model after transformation along with the analysis cache and execution log generated during execution of the PassManager.

Notes

IR objects are typically created as the result of running the PassManager on a model. Use the model, cache, and execution_log properties to access the transformation results.

model: Model property

Get the transformed model.

Returns:

  • Model

    The model after execution of the PassManager.

cache: AnalysisCache property

Get the analysis cache.

Returns:

  • AnalysisCache

    The analysis cache containing analysis results from running the PassManager.

execution_log: list[LogElement] property

Get the execution log.

Returns:

  • list[LogElement]

    A list of log elements documenting the pass manager process.

Pipeline

Bases: PyPipeline, PipelineProto, BasePass

A pipeline for executing multiple transformation passes in sequence.

Pipelines organize and execute multiple passes, managing dependencies and ensuring they run in the correct order.

Parameters:

  • passes (list[BasePass]) –

    The transformation passes to include in the pipeline.

  • name (str, default: None ) –

    A custom name for the pipeline. If not provided, a default name will be generated.

satisfies: set[str] property

Get the set of pass requirements that this pipeline satisfies.

Returns:

  • set of str

    Names of pass requirements satisfied by executing this pipeline.

passes: list[BasePass] property

Get all passes that are part of the pipeline.

Returns:

  • list of BasePass

    The transformation passes in this pipeline.

add(new_pass: BasePass) -> None

Add a new pass to the pipeline.

Parameters:

  • new_pass (BasePass) –

    The transformation pass to add to the pipeline.

clear() -> None

Clear all passes from the pipeline.

Removes all transformation passes, leaving an empty pipeline.

__len__() -> int

Get the number of passes in the pipeline.

Returns:

  • int

    The number of transformation passes in this pipeline.

__str__() -> str

Get a string representation of the pipeline.

Returns:

  • str

    A human-readable string describing the pipeline.

__repr__() -> str

Get a detailed string representation of the pipeline for debugging.

Returns:

  • str

    A detailed string representation suitable for debugging.

Pass Types

TransformationPass

Bases: PyTransformationPass, BasePass

Base class for transformation passes that modify models.

Transformation passes apply changes to models and can also convert solutions backwards to match the input representation.

Notes

This is an abstract class. Subclasses must implement the name, run, and backwards methods.

invalidates: list[str] property

Get a list of passes that are invalidated by this pass.

Returns:

  • list of str

    Names of passes whose results become invalid after this pass runs.

run(model: Model, cache: AnalysisCache) -> TransformationOutcome | tuple[PyModel, PyActionType] | tuple[PyModel, PyActionType, Any] abstractmethod

Run/Execute this transformation pass.

Parameters:

  • model (Model) –

    The model to transform.

  • cache (AnalysisCache) –

    Cache containing analysis results.

Returns:

  • TransformationOutcome or tuple

    The transformation result, either as a TransformationOutcome object or as a tuple of (model, action_type) or (model, action_type, analysis).

backwards(solution: Solution, cache: AnalysisCache) -> Solution abstractmethod

Convert a solution back to fit this pass' input.

Converts a solution from a representation fitting this pass' output to a solution representation fitting this pass' input.

Parameters:

  • solution (Solution) –

    The solution in the output representation.

  • cache (AnalysisCache) –

    Cache containing analysis results.

Returns:

  • Solution

    The solution converted to the input representation.

AnalysisPass

Bases: PyAnalysisPass, BasePass, Generic[T]

Base class for analysis passes that compute information about models.

Analysis passes inspect models and compute results without modifying them. They can depend on other analysis passes and cache their results for efficient access in subsequent passes.

run(model: Model, cache: AnalysisCache) -> T abstractmethod

Execute this analysis pass on a model.

Parameters:

  • model (Model) –

    The model to analyze.

  • cache (AnalysisCache) –

    Cache containing results from previous analysis passes.

Returns:

  • T

    The result of the analysis.

Built-in Pipelines

ToUnconstrainedBinaryPipeline

Convert a model to an unconstrained binary model.

This pipeline transforms any model with constraints to an unconstrained binary model. It allows the input model to contain binary, spin or integer variables. Spin and integer variables are automatically converted to a binary representation. If the input model has linear constraints they are added to the model's objective as quadratic penalties scaled by the the maximum bias of the input model's objective times the penalty_scaling paramter.

Notes

If the model's constraints are not linear, an error is raised.

Paramters

penalty_scaling : float The factor used to scale the quadratic penalties with, by default 10.

Raises:

  • AnalysisPassError

    If the model's constraints are not all linear.

Example

from luna_model import Model, Vtype from luna_model.transformation import PassManager, pipelines model = Model() x = model.add_variable("x", vtype=Vtype.BINARY) y = model.add_variable("y", vtype=Vtype.SPIN) z = model.add_variable("z", vtype=Vtype.INTEGER, lower=0, upper=12) model.objective = x + y + z model.constraints += x + y + z <= 3, "c0" model.constraints += x - y - z >= 0, "c1" model.constraints += x + y == 2, "c2" pm = PassManager([pipelines.ToUnconstrainedBinaryPipeline()]) ir = pm.run(model)

__new__(penalty_scaling: float = 10.0) -> PipelineProto

Todo.

Built-in Passes

BinarySpinPass

Bases: ConcreteTransformationPass

Convert between Binary and Spin variable types.

Transform the variables of type binary to spin typed variables or vice versa. Target vtype is set by the vtype parameter.

Parameters:

  • vtype (Literal[BINARY, SPIN]) –

    The target vtype to convert the variables to. If set to Vtype.SPIN all binary variables in the model are converted to spin variables. If set to Vtype.BINARY all spin variables are converted to binary variables.

  • prefix (str, default: None ) –

    An optional prefix to prepend to the name of the new variables created. If none specified a default prefix is used.

Examples:

>>> from luna_model import Model, Vtype
>>> from luna_model.transformation import PassManager
>>> from luna_model.transformation.passes import BinarySpinPass
>>> model = Model()
>>> x = model.add_variable("x", vtype=Vtype.BINARY)
>>> y = model.add_variable("y", vtype=Vtype.BINARY)
>>> model.objective = x * y + x - 2 * y
>>> pm = PassManager([BinarySpinPass(vtype=Vtype.SPIN)])
>>> ir = pm.run(model)
>>> spin_model = ir.model

invalidates: list[str] property

Get a list of passes that are invalidated by this pass.

Returns:

  • list of str

    Names of passes whose results become invalid after this pass runs.

vtype: Vtype property

Get the target variable type to convert to.

prefix: str | None property

Get the optional naming prefix.

ChangeSensePass

Bases: ConcreteTransformationPass

Change the optimization sense between minimization and maximization.

Converts the optimization sense by negating the objective function.

Parameters:

  • sense (Sense) –

    The target sense to convert the optimization sense to.

Examples:

>>> from luna_model import Model, Vtype, Sense
>>> from luna_model.transformation import PassManager
>>> from luna_model.transformation.passes import ChangeSensePass
>>> model = Model(sense=Sense.MAX)
>>> x = model.add_variable("x", vtype=Vtype.BINARY)
>>> y = model.add_variable("y", vtype=Vtype.BINARY)
>>> model.objective = x * y + x - 2 * y
>>> pm = PassManager([ChangeSensePass(Sense.MIN)])
>>> ir = pm.run(model)
>>> min_model = ir.model

invalidates: list[str] property

Get a list of passes that are invalidated by this pass.

Returns:

  • list of str

    Names of passes whose results become invalid after this pass runs.

sense: Sense property

Get the target optimization sense.

MaxBiasAnalysis

Bases: ConcreteAnalysisPass

Analysis pass that computes the maximum absolute coefficient value in the objective.

Examples:

>>> from luna_model import Model, Vtype
>>> from luna_model.transformation import PassManager
>>> from luna_model.transformation.passes import MaxBiasAnalysis
>>> model = Model()
>>> x = model.add_variable("x", vtype=Vtype.BINARY)
>>> y = model.add_variable("y", vtype=Vtype.BINARY)
>>> model.objective = x * y + x - 2 * y
>>> pm = PassManager([MaxBiasAnalysis()])
>>> ir = pm.run(model)
>>> ir.cache["max-bias"].val
2.0

CheckModelSpecsAnalysis

Bases: ConcreteAnalysisPass

Analysis pass that checks the model's specs for correctness.

This analysis pass checks if the input model satisfies the specifications (ModelSpecs) this pass is initilized with. If the specs are not satified by the model it raises an error during runtime.

Examples:

>>> from luna_model import Model, Vtype
>>> from luna_model.transformation import PassManager
>>> from luna_model.transformation.passes import CheckModelSpecsAnalysis
>>> model = Model()
>>> x = model.add_variable("x", vtype=Vtype.BINARY)
>>> y = model.add_variable("y", vtype=Vtype.BINARY)
>>> model.objective = x * y + x - 2 * y
>>> specs = ModelSpecs(max_degree=2)
>>> pm = PassManager([CheckModelSpecsAnalysis(specs)])
>>> ir = pm.run(model)
>>> # no errors raised

MinValueForConstraintAnalysis

Bases: ConcreteAnalysisPass

Analysis pass that computes the min value possible for all constraints.

This analysis pass computes the minimal value possible for all constraints of the input model.

Examples:

>>> from luna_model import Model, Vtype
>>> from luna_model.transformation import PassManager
>>> from luna_model.transformation.passes import CheckModelSpecsAnalysis
>>> model = Model()
>>> x = model.add_variable("x", vtype=Vtype.BINARY)
>>> y = model.add_variable("y", vtype=Vtype.BINARY)
>>> model.objective = x * y + x - 2 * y
>>> model.constraints += -5 * x + y <= 2, "my-constraint"
>>> pm = PassManager([MinValueForConstraintAnalysis()])
>>> ir = pm.run(model)
>>> ir.cache["min-value-for-constraint"].vals
{'my-constraint': -5.0}

SpecsAnalysis

Bases: ConcreteAnalysisPass

Analysis pass that computes the model's specs and stores them in the cache.

This analysis pass computes the ModelSpecs of the input model and writes it to the AnalysisCache to be used by transformation passes following it during the PassManager execution. This analysis pass can, for example, be used in combination with the IfElsePass to guide the transformation depending on the specifications (ModelSpecs) of a model.

Notes

This pass is not to be confused with the CheckModelSpecsAnalysis, which checks if an input model's specs satisfy a given set of ModelSpecs.

Examples:

>>> from luna_model import Model, Vtype
>>> from luna_model.transformation import PassManager
>>> from luna_model.transformation.passes import SpecsAnalysis
>>> model = Model()
>>> x = model.add_variable("x", vtype=Vtype.BINARY)
>>> y = model.add_variable("y", vtype=Vtype.BINARY)
>>> model.objective = x * y + x - 2 * y
>>> pm = PassManager([SpecsAnalysis()])
>>> ir = pm.run(model)
>>> ir.cache["specs"]
ModelSpecs(sense=Minimize, vtype=Binary, constraints=, max_degree=2, max_constraint_degree=0, max_num_variables=2)

EqualityConstraintsToQuadraticPenaltyPass

Bases: ConcreteTransformationPass

Move all equality constraints to the model's objective as a quadratic penalties.

Converts the model by moving all equality constraints to the objective as quadratic penalties. Requires the MaxBiasAnalysis pass to be executed before this pass.

Less-equal (<=) or greater-equal (>=) constraints are not respected by this transformation and have to be handled before this pass using, e.g., the GeToLeConstraintsPass and the LeToEqConstraintsPass.

Notes

This pass requires the MaxBiasAnalysis pass to be executed before this pass.

Parameters:

  • penalty_scaling (float, default: 10.0 ) –

    The factor used to scale the penalties with, default 10.0.

Examples:

>>> from luna_model import Model, Vtype, Sense
>>> from luna_model.transformation import PassManager
>>> from luna_model.transformation.passes import MaxBiasAnalysis
>>> from luna_model.transformation.passes import EqualityConstraintsToQuadraticPenaltyPass
>>> model = Model(sense=Sense.MAX)
>>> x = model.add_variable("x", vtype=Vtype.BINARY)
>>> y = model.add_variable("y", vtype=Vtype.BINARY)
>>> model.objective = x * y + x - 2 * y
>>> model.constraints += x + y == 0
>>> pm = PassManager(
...     [
...         MaxBiasAnalysis(),
...         EqualityConstraintsToQuadraticPenaltyPass(),
...     ]
... )
>>> ir = pm.run(model)
>>> print(ir.model.objective)
41 x y + 21 x + 18 y

invalidates: list[str] property

Get a list of passes that are invalidated by this pass.

Returns:

  • list of str

    Names of passes whose results become invalid after this pass runs.

GeToLeConstraintsPass

Bases: ConcreteTransformationPass

Convert the model's constraints by chaning all greater-equal (>=) constraints to less-equal (<=) constraints.

Examples:

>>> from luna_model import Model, Vtype, Sense
>>> from luna_model.transformation import PassManager
>>> from luna_model.transformation.passes import GeToLeConstraintsPass
>>> model = Model(sense=Sense.MAX)
>>> x = model.add_variable("x", vtype=Vtype.BINARY)
>>> y = model.add_variable("y", vtype=Vtype.BINARY)
>>> model.objective = x * y + x - 2 * y
>>> model.constraints += x + y >= 0, "ge_constr"
>>> pm = PassManager([GeToLeConstraintsPass()])
>>> ir = pm.run(model)
>>> ir.model.constraints["ge_constr"]
-x - y <= 0

invalidates: list[str] property

Get a list of passes that are invalidated by this pass.

Returns:

  • list of str

    Names of passes whose results become invalid after this pass runs.

IntegerToBinaryPass

Bases: ConcreteTransformationPass

Convert integer variables to a binary representation.

Transform the variables of type integer to be represented by binary typed variables.

Examples:

>>> from luna_model import Model, Vtype
>>> from luna_model.transformation import PassManager
>>> from luna_model.transformation.passes import BinarySpinPass
>>> model = Model()
>>> x = model.add_variable("x", vtype=Vtype.INTEGER, lower=0, upper=3)
>>> y = model.add_variable("y", vtype=Vtype.BINARY)
>>> model.objective = x * y + x - 2 * y
>>> pm = PassManager([IntegerToBinaryPass()])
>>> ir = pm.run(model)
>>> print(ir.model.objective)
y x_b0 + 2 y x_b1 - 2 y + x_b0 + 2 x_b1

invalidates: list[str] property

Get a list of passes that are invalidated by this pass.

Returns:

  • list of str

    Names of passes whose results become invalid after this pass runs.

LeToEqConstraintsPass

Bases: ConcreteTransformationPass

Convert the model's constraints by chaning all less-equal (<=) constraints to equality (==) constraints.

Examples:

>>> from luna_model import Model, Vtype, Sense
>>> from luna_model.transformation import PassManager
>>> from luna_model.transformation.passes import MinValueForConstraintAnalysis
>>> from luna_model.transformation.passes import LeToEqConstraintsPass
>>> model = Model(sense=Sense.MAX)
>>> x = model.add_variable("x", vtype=Vtype.BINARY)
>>> y = model.add_variable("y", vtype=Vtype.BINARY)
>>> model.objective = x * y + x - 2 * y
>>> model.constraints += x + y <= 3, "le_constr"
>>> pm = PassManager([MinValueForConstraintAnalysis(), LeToEqConstraintsPass()])
>>> ir = pm.run(model)
>>> ir.model.constraints["le_constr"]
x + y + slack_le_constr == 0
>>> print(ir.model.get_variable("slack_le_constr"))
slack_le_constr: Integer(lower=0, upper=3)

invalidates: list[str] property

Get a list of passes that are invalidated by this pass.

Returns:

  • list of str

    Names of passes whose results become invalid after this pass runs.

Decorators

TransformationPass

Bases: PyTransformationPass, BasePass

Base class for transformation passes that modify models.

Transformation passes apply changes to models and can also convert solutions backwards to match the input representation.

Notes

This is an abstract class. Subclasses must implement the name, run, and backwards methods.

invalidates: list[str] property

Get a list of passes that are invalidated by this pass.

Returns:

  • list of str

    Names of passes whose results become invalid after this pass runs.

run(model: Model, cache: AnalysisCache) -> TransformationOutcome | tuple[PyModel, PyActionType] | tuple[PyModel, PyActionType, Any] abstractmethod

Run/Execute this transformation pass.

Parameters:

  • model (Model) –

    The model to transform.

  • cache (AnalysisCache) –

    Cache containing analysis results.

Returns:

  • TransformationOutcome or tuple

    The transformation result, either as a TransformationOutcome object or as a tuple of (model, action_type) or (model, action_type, analysis).

backwards(solution: Solution, cache: AnalysisCache) -> Solution abstractmethod

Convert a solution back to fit this pass' input.

Converts a solution from a representation fitting this pass' output to a solution representation fitting this pass' input.

Parameters:

  • solution (Solution) –

    The solution in the output representation.

  • cache (AnalysisCache) –

    Cache containing analysis results.

Returns:

  • Solution

    The solution converted to the input representation.

AnalysisPass

Bases: PyAnalysisPass, BasePass, Generic[T]

Base class for analysis passes that compute information about models.

Analysis passes inspect models and compute results without modifying them. They can depend on other analysis passes and cache their results for efficient access in subsequent passes.

run(model: Model, cache: AnalysisCache) -> T abstractmethod

Execute this analysis pass on a model.

Parameters:

  • model (Model) –

    The model to analyze.

  • cache (AnalysisCache) –

    Cache containing results from previous analysis passes.

Returns:

  • T

    The result of the analysis.

Control Flow

IfElsePass

Bases: PyIfElsePass, BasePass

Conditional pass that executes different pipelines based on a runtime condition.

The IfElsePass evaluates a condition function against the analysis cache at runtime and executes either the then pipeline or the otherwise pipeline based on the result. This enables branching logic in transformation workflows, allowing different transformation strategies based on model properties discovered during analysis.

Parameters:

  • requires (list[str]) –

    List of pass names that must be run before this pass. These passes provide the data used by the condition function.

  • condition (Callable[[AnalysisCache], bool]) –

    A function that takes an AnalysisCache and returns a boolean. If True, the then pipeline is executed; otherwise, the otherwise pipeline runs.

  • then (Pipeline) –

    The pipeline to execute when the condition evaluates to True.

  • otherwise (Pipeline) –

    The pipeline to execute when the condition evaluates to False.

  • name (str, default: None ) –

    Optional name for this pass. If not provided, a default name is generated.

Examples:

Execute different transformations based on the maximum bias:

>>> from luna_model import Model, Vtype
>>> from luna_model.transformation import PassManager, Pipeline, IfElsePass
>>> from luna_model.transformation.passes import MaxBiasAnalysis, BinarySpinPass
>>> # Create conditional pass
>>> conditional = IfElsePass(
...     requires=["max-bias"],
...     condition=lambda cache: cache["max-bias"].val > 10.0,
...     then=Pipeline([BinarySpinPass(vtype=Vtype.BINARY)]),
...     otherwise=Pipeline([]),
...     name="conditional-spin-conversion",
... )

Let's create a model that satisfies the condition:

>>> model = Model("example")
>>> x = model.add_variable("x", vtype=Vtype.SPIN)
>>> y = model.add_variable("y")
>>> z = model.add_variable("z")
>>> model.objective = 2 * x + 12 * y * z

And use it in the pass manager:

>>> pm = PassManager([MaxBiasAnalysis(), conditional])
>>> result = pm.run(model)
>>> print(result.model)
Model: example
Minimize
  12 * y * z - 4 * x_x + 2
Binary
  y z x_x

And now a model that does not satisfy the condition:

>>> model = Model("example")
>>> x = model.add_variable("x", vtype=Vtype.SPIN)
>>> y = model.add_variable("y")
>>> z = model.add_variable("z")
>>> model.objective = 2 * x + 8 * y * z

And use it in the pass manager:

>>> pm = PassManager([MaxBiasAnalysis(), conditional])
>>> result = pm.run(model)
>>> print(result.model)
Model: example
Minimize
  8 * y * z + 2 * x
Binary
  y z
Spin
  x
Notes

The condition function has access to all analysis results computed by the passes listed in requires. Both pipelines can contain arbitrarily complex sequences of transformations and analyses.

The condition is evaluated once per IfElsePass execution. If you need to re-evaluate during pipeline execution, nest multiple IfElsePass instances.

LogElement

An element of the execution log of an intermediate representation (IR).

Log elements record information about transformation passes, including the pass name, timing information, and the type of action performed.

pass_name: str property

The name of the pass.

Returns:

  • str

    The name of the pass that was executed.

timing: Timing property

Get timing information for this log element.

Returns:

  • Timing

    Timing information for the pass.

kind: ActionType | None property

Get the type of transformation action performed.

Returns:

  • ActionType or None

    The type of transformation action, or None if not available.