HOW-TO

Custom Resolvers

Custom Resolvers

See also: Concepts: Interpolation, API: language

Registering a Custom Resolver

OmegaConf resolvers are registered with OmegaConf.register_new_resolver:

from omegaconf import OmegaConf

OmegaConf.register_new_resolver(
    "double",
    lambda x: float(x) * 2,
    replace=False,  # raise if already registered
)

After registration, use the resolver in any config:

@L.params
class hps:
    lr: float = 1e-3

doubled_lr = L.ref("${double:${hps.lr}}")

When to Register

Resolvers must be registered before OmegaConf resolves any interpolation that uses them. The safest place is at module import time (before laco.load).

import laco calls laco.register_resolvers() automatically, so all L.r.* resolvers are available after any import laco. Your custom resolvers should be registered similarly early.

Using L.r.* Built-In Resolvers

The bundled resolvers live in laco.language.r:

import laco.language as L

@L.params
class hps:
    base_lr: float = 1e-3
    warmup_steps: int = 500

# Derived values via resolvers
peak_lr = L.r.div(hps.base_lr, 10)         # base_lr / 10
total_steps = L.r.sum(hps.warmup_steps, 5000)

See the resolver table for all 11 methods.

Hydra Plugin Registration

Laco also ships hydra_plugins.laco_resolvers, which registers all L.r.* resolvers into the global OmegaConf registry when Hydra initializes. This means Hydra apps that never import laco directly still get the resolvers if laco is installed.

Overwriting an Existing Resolver

OmegaConf.register_new_resolver("double", lambda x: x * 3, replace=True)

Pass replace=True to overwrite. Without it, registering the same name twice raises ValueError.