unilab.base.process_device¶
Training-worker device routing for UniSim backends.
The learner device and the device consumed by a simulator are related, but
they do not always use the same index namespace. In particular, the
off-policy launcher keeps the host-visible CUDA namespace while the PPO
torchrun launcher remaps CUDA_VISIBLE_DEVICES and therefore exposes a
rank-local index to child processes. The helpers in this module keep that
translation on the cold path, next to the backend process binding contract.
Functions
|
Return an env override carrying the rank-selected simulator device. |
|
Bind a resolved backend process device in the current process. |
Bind one backend's process-global accelerator device. |
|
|
Select the CUDA device used by an in-process Genesis worker. |
|
Pin Genesis to its rank device before the first torch CUDA call. |
|
Resolve the integer simulator device id for a training rank. |
|
|
|
Warn when a multi-rank simulator still resolves to device zero. |
- unilab.base.process_device.apply_backend_env_device_override(env_cfg_override, backend_type, *, devices=None, rank=0, local_rank=None, world_size=1, learner_device=None)[source]¶
Return an env override carrying the rank-selected simulator device.
The input mapping is never mutated. If no topology/device can be resolved, the owner-configured value is preserved. This lets one helper serve training, playback, and custom entrypoints while retaining the historical default (device zero) for single-process calls.
- unilab.base.process_device.bind_backend_process_device(resolved)[source]¶
Bind a resolved backend process device in the current process.
Top-level on purpose: uni_rl’s off-policy collectors receive this as the injected
backend_device_binderand pickle it by reference into spawn-based subprocesses. The mjwarp import stays lazy so the binder is importable without themjwarpextra installed.
- unilab.base.process_device.bind_backend_process_device_for_backend(backend_type, resolved)[source]¶
Bind one backend’s process-global accelerator device.
This top-level callable is intentionally backend-aware and lazy. It can be wrapped with
functools.partial()and injected into uni_rl’s spawn-based collectors while remaining pickleable by module reference.
- unilab.base.process_device.bind_genesis_process_device(resolved)[source]¶
Select the CUDA device used by an in-process Genesis worker.
Genesis initializes a process-wide session whose Quadrants CUDA runtime always binds the first entry of
CUDA_VISIBLE_DEVICES; torch’s current device alone is not honored (issue #1508). A non-zero request is therefore honored by pinning visibility to the target GPU before any CUDA context exists, after which the in-process device iscuda:0. The returned string is the device the rest of this process must actually use — callers that computed a pre-pin device (learner, probes, collectors) have to adopt the returned value. Binding must happen before constructing the backend (and beforegs.init), including in spawn-based collector processes, and remains in effect for the lifetime of the process.
- unilab.base.process_device.pin_genesis_device_before_cuda_init(backend_type, *, devices=None, rank=0, local_rank=None, world_size=1, learner_device=None)[source]¶
Pin Genesis to its rank device before the first torch CUDA call.
torch.cuda.is_available()already latchesCUDA_VISIBLE_DEVICESin the CUDA runtime, so the pin must run ahead of any torch CUDA query — entrypoints should call this before registry/bootstrap/device detection. Pure config topology (training.devices/LOCAL_RANK/ an explicitcuda:Nlearner device) resolves without touching torch. Returns the in-process device the caller must use when a pin happened, elseNone.
- unilab.base.process_device.resolve_backend_env_device_id(backend_type, *, devices=None, rank=0, local_rank=None, world_size=1, learner_device=None)[source]¶
Resolve the integer simulator device id for a training rank.
- Parameters:
backend_type (
str) – Selected UniSim backend.devices (
Sequence[int] |None) –training.devicesin the host-visible namespace. This is used by the off-policy launcher and by single-process PPO.rank (
int) – Off-policy data-parallel rank (rank zero by default).local_rank (
int|None) –LOCAL_RANKfrom torchrun. In a distributed PPO worker this is the logical index inside the launcher’s remappedCUDA_VISIBLE_DEVICESlist.world_size (
int) – Torchrun world size. Values greater than one select thelocal_ranknamespace; values of one selectdevices[rank].learner_device (
str|None) – Explicit learner device fallback when no topology was configured (for example APPO or a single-device play command).
- Return type:
Returns
Nonefor backends without an explicit simulator device field. For a torchrun worker the returned id is intentionally local (rather than the host index indevices), because the worker subprocess inherits the remappedCUDA_VISIBLE_DEVICESenvironment.
- unilab.base.process_device.warn_if_backend_device_collision(backend_type, *, devices, rank, device_id, source='environment')[source]¶
Warn when a multi-rank simulator still resolves to device zero.
This is a transition guard for older adapters/configuration paths. Rank zero legitimately owns device zero; only a non-zero rank resolving to zero is a collision. The warning is intentionally emitted at construction time, never from a hot simulation path.