Advanced Transformation Topics
Advanced techniques for model transformations in LunaModel.
Sequential Passes
Apply multiple passes in sequence using PassManager.
Python
from luna_model.transformation import PassManager
from luna_model.transformation.passes import ChangeSensePass, BinarySpinPass
from luna_model import Sense, Vtype
# Apply passes in sequence
pm = PassManager([
ChangeSensePass(Sense.MIN),
BinarySpinPass(Vtype.SPIN, prefix=None),
])
ir = pm.run(model)
transformed = ir.model
Pipeline
Group passes together as a single unit.
Python
from luna_model.transformation import Pipeline, PassManager
from luna_model.transformation.passes import ChangeSensePass, BinarySpinPass
from luna_model import Sense, Vtype
# Create a named pipeline
preprocessing = Pipeline([
ChangeSensePass(Sense.MIN),
BinarySpinPass(Vtype.SPIN, prefix=None),
], name="preprocessing")
# Use in PassManager
pm = PassManager([preprocessing])
ir = pm.run(model)
Conditional Execution with IfElsePass
Execute different passes based on runtime conditions.
Python
from luna_model.transformation import PassManager, Pipeline, IfElsePass
from luna_model.transformation import analyse
from luna_model.transformation.passes import BinarySpinPass, MaxBiasAnalysis
from luna_model import Vtype
# Analysis to check model properties
@analyse(name="model-complexity")
def check_model_complexity(model, cache):
"""Analyze model complexity."""
num_vars = model.num_variables()
num_constraints = model.num_constraints()
return {"vars": num_vars, "constraints": num_constraints}
# Conditional transformation based on model size
conditional = IfElsePass(
requires=["model-complexity"],
condition=lambda cache: cache["model-complexity"]["vars"] > 100,
then=Pipeline([BinarySpinPass(Vtype.SPIN, prefix=None)]),
otherwise=Pipeline([]),
name="conditional-spin",
)
pm = PassManager([check_model_complexity, conditional])
ir = pm.run(model)
Using AnalysisCache
Passes can share data through the AnalysisCache.
Python
from luna_model.transformation import analyse, transform, ActionType, PassManager
# Analysis pass stores data in cache
@analyse(name="compute-stats")
def compute_stats(model, cache):
"""Compute model statistics."""
return {
"num_vars": model.num_variables(),
"num_constraints": model.num_constraints(),
}
# Transformation uses cached analysis
@transform(name="use-stats", requires=["compute-stats"])
def use_stats(model, cache):
"""Transform based on cached statistics."""
stats = cache["compute-stats"]
# Only apply transformation if model is small enough
if stats["num_vars"] < 50:
model.sense = Sense.MIN
return model, ActionType.DID_TRANSFORM
return model, ActionType.DID_NOTHING
pm = PassManager([compute_stats, use_stats])
ir = pm.run(model)
Backwards Transformation
Map solutions from transformed models back to original variable space.
Python
from luna_model.transformation import PassManager
from luna_model.transformation.passes import BinarySpinPass
from luna_model import Vtype
# Transform model
pm = PassManager([BinarySpinPass(Vtype.SPIN, prefix=None)])
ir = pm.run(model)
transformed_model = ir.model
# Solve transformed model (solver not shown)
# solution = solve(transformed_model)
# Map solution back to original model variables
# original_solution = pm.backwards(solution, ir)
Creating Reusable Pipelines
Python
from luna_model.transformation import Pipeline
from luna_model.transformation.passes import ChangeSensePass, BinarySpinPass
from luna_model import Sense, Vtype
def create_spin_conversion_pipeline():
"""Create pipeline for spin variable conversion."""
return Pipeline([
ChangeSensePass(Sense.MIN),
BinarySpinPass(Vtype.SPIN, prefix=None),
], name="spin-conversion")
# Use the pipeline
spin_pipeline = create_spin_conversion_pipeline()
pm = PassManager([spin_pipeline])
ir = pm.run(model)
See Also
- PassManager - Managing passes
- Built-in Passes - Available passes
- Custom Passes - Creating passes