unilab.utils.sim2sim

Cross-backend sim2sim contract snapshot and resolution.

Functions

extract_contract_snapshot(full_cfg)

Extract the contract fields from a resolved training config keyed by dotted path.

policy_load_dim_guard(*[, env_obs_dim, ...])

Re-raise a tensor shape mismatch during checkpoint load as a sim2sim diagnostic.

resolve_sim2sim_config(source_run_dir, ...)

Validate a target play config against the source training contract.

Classes

Sim2SimConfigResolver

Object facade over the module-level sim2sim contract API.

Exceptions

CrossBackendIncompatibleError

Raised when a target play config diverges from the source training contract.

exception unilab.utils.sim2sim.CrossBackendIncompatibleError[source]

Bases: RuntimeError

Raised when a target play config diverges from the source training contract.

unilab.utils.sim2sim.extract_contract_snapshot(full_cfg)[source]

Extract the contract fields from a resolved training config keyed by dotted path.

Parameters:

full_cfg (DictConfig)

Return type:

dict[str, Any]

unilab.utils.sim2sim.resolve_sim2sim_config(source_run_dir, target_cfg, *, algo_name=None, strict=True)[source]

Validate a target play config against the source training contract.

Returns None if source_run_dir is None; otherwise returns target_cfg unchanged (never mutated). Raises CrossBackendIncompatibleError under strict when any DENYLIST field differs, including asymmetric presence for ENV_STRUCTURAL_DENYLIST paths.

Parameters:
Return type:

DictConfig | None

unilab.utils.sim2sim.policy_load_dim_guard(*, env_obs_dim=None, env_action_dim=None, algo_name=None)[source]

Re-raise a tensor shape mismatch during checkpoint load as a sim2sim diagnostic.

Non-matching errors propagate unchanged, so a valid load is never blocked.

Parameters:
Return type:

Iterator[None]

class unilab.utils.sim2sim.Sim2SimConfigResolver[source]

Bases: object

Object facade over the module-level sim2sim contract API.

ALLOWLIST = ['training.sim_backend', 'env.scene', 'training.play_steps', 'env.domain_rand', 'env.noise_config', 'env.commands.vel_limit']
WARNING_LIST = ['reward.scales', 'reward.base_height_target', 'reward.max_tilt_deg', 'reward.min_base_height', 'env.control_config.simulate_action_latency', 'env.ctrl_dt']
DENYLIST = ['algo.obs_groups', 'env.control_config.action_scale', 'env.observations', 'env.actions', 'env.policy_observation_group', 'env.critic_observation_group', 'algo.policy.actor_hidden_dims', 'algo.policy.critic_hidden_dims', 'algo.empirical_normalization', 'algo.obs_normalization', 'env.commands.motion.params.sampling_mode']
ENV_STRUCTURAL_DENYLIST = ['env.control_config.action_scale', 'env.observations', 'env.actions', 'env.policy_observation_group', 'env.critic_observation_group', 'env.commands.motion.params.sampling_mode']
static extract_snapshot(full_cfg)[source]

See extract_contract_snapshot().

Parameters:

full_cfg (DictConfig)

Return type:

dict[str, Any]

static resolve(source_run_dir, target_cfg, *, algo_name=None, strict=True)[source]

See resolve_sim2sim_config().

Parameters:
Return type:

DictConfig | None

static load_dim_guard(*, env_obs_dim=None, env_action_dim=None, algo_name=None)[source]

See policy_load_dim_guard().

Parameters: