nvalchemi.dynamics.DistributedPipeline#
- class nvalchemi.dynamics.DistributedPipeline(stages, synchronized=False, debug_mode=False, mesh=None, **dist_kwargs)[source]#
Orchestrates multi-rank pipeline execution.
Maps GPU ranks to pipeline stages and coordinates the distributed step loop. Each rank executes only its assigned stage.
- Parameters:
stages (dict[int, BaseDynamics]) – Mapping from rank to its assigned pipeline stage.
synchronized (bool) –
If
True, insert a globaldist.barrier()across all pipeline ranks after everystep()call, forcing every rank to complete its current step before any rank proceeds to the next one. This is primarily useful for debugging ordering or deadlock issues because it eliminates all inter-rank timing skew.Note
This is distinct from the per-stage
comm_modeparameter on_CommunicationMixin, which controls the blocking behavior of pairwiseisend/irecvbetween adjacent stages.synchronizedenforces a global synchronization point across the entire pipeline and will significantly reduce throughput; it should be disabled (False) in production.debug_mode (bool)
mesh (Any)
dist_kwargs (Any)
- stages#
Rank-to-stage mapping.
- Type:
dict[int, BaseDynamics]
- synchronized#
Whether a global
dist.barrier()is inserted after every step.- Type:
bool
- _dist_initialized#
Whether this DistributedPipeline instance initialized the distributed process group (used to determine cleanup responsibility).
- Type:
bool
Examples
>>> # Context manager usage (recommended): >>> pipeline = DistributedPipeline(stages={0: opt_stage, 1: md_stage}) >>> with pipeline: ... pipeline.run() ... >>> # Manual usage: >>> pipeline = DistributedPipeline(stages={0: opt_stage, 1: md_stage}) >>> pipeline.init_distributed() >>> pipeline.setup() >>> pipeline.run() >>> pipeline.cleanup() >>> # Composing multiple pipelines together >>> full_pipeline = pipe1 | pipe2 | pipe3 >>> with full_pipeline: ... pipeline.run() ...
- cleanup()[source]#
Destroy the
torch.distributedprocess group.Only destroys the process group if it was initialized by this
DistributedPipelineinstance (viainit_distributed()). If the process group was externally initialized (e.g., bytorchrun), this method is a no-op.- Return type:
None
- property global_rank: int#
Get the global rank for this process.
- init_distributed()[source]#
Initialize the
torch.distributedprocess group.If
torch.distributedis already initialized, this method is a no-op. Otherwise, it callstorch.distributed.init_process_group(**self._dist_kwargs).The backend and other distributed options are configured via the constructor’s
**dist_kwargsparameter.Notes
When launching with
torchrun, the process group is typically already initialized. This method provides a convenient fallback for scripts that do not usetorchrun.- Return type:
None
- property local_rank: int#
Get the local rank for this process.
- property local_stage: BaseDynamics#
Get the stage associated with the rank this is executed on.
- run()[source]#
Run the pipeline loop until all stages report done.
After each
step(), anall_reducesynchronizes thedoneflags across all ranks so that every process can observe the global termination state.- Return type:
None
- setup()[source]#
Wire up
prior_rank/next_rankbetween adjacent stages.Sorts stages by rank and connects each stage to its predecessor and successor.
- Raises:
ValueError – If fewer than 2 stages are provided, or if adjacent stages have mismatched buffer configurations.
RuntimeError – If the world size does not match the number of configured pipeline stages.
- Return type:
None
- step()[source]#
Execute one timestep for the local rank’s stage.
The stage (a
BaseDynamicssubclass) handles both the dynamics step and buffer synchronization.Supports two modes for the first stage:
Mode 1 (external batch loop): Standard flow where the first stage receives from
_prestep_sync_bufferslike other stages.Mode 2 (inflight batching): When the first stage has
inflight_mode=True(i.e., a sampler is configured), it builds the initial batch from the sampler and refills graduated samples instead of receiving from a prior stage.When
self.synchronizedisTrue, a globaldist.barrier()is issued at the end of each step so that no rank advances until every rank in the pipeline has finished the current step.- Raises:
RuntimeError – If
torch.distributedis not initialized, or if the world size does not match the number of configured pipeline stages.KeyError – If the current rank is not in the global rank stage mapping.
- Return type:
None