Rate this Page

Source code for torchrl.trainers.algorithms.configs.data

# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

from __future__ import annotations

from dataclasses import dataclass, field
from typing import Any, Literal, TYPE_CHECKING

from omegaconf import MISSING

from torchrl.data.replay_buffers import WriterEnsemble
from torchrl.trainers.algorithms.configs.common import ConfigBase

if TYPE_CHECKING:
    _ReplayServiceBackend = Literal["direct", "ray"]
    _ReplayTransport = Literal["auto", "direct", "ray", "distributed"]
    _SliceOutputLayout = Literal["flat", "batch_time"]
else:
    # OmegaConf structured configs resolve these aliases at runtime and do not
    # support Literal on all TorchRL-supported versions.
    _ReplayServiceBackend = str
    _ReplayTransport = str
    _SliceOutputLayout = str


@dataclass
class WriterConfig(ConfigBase):
    """Base configuration class for replay buffer writers."""

    _target_: str = "torchrl.data.replay_buffers.Writer"

    def __post_init__(self) -> None:
        """Post-initialization hook for writer configurations."""


[docs] @dataclass class RoundRobinWriterConfig(WriterConfig): """Hydra configuration for :class:`~torchrl.data.RoundRobinWriter`.""" _target_: str = "torchrl.data.replay_buffers.RoundRobinWriter" compilable: bool = False track_generations: bool = False def __post_init__(self) -> None: """Post-initialization hook for round-robin writer configurations.""" super().__post_init__()
@dataclass class SamplerConfig(ConfigBase): """Base configuration class for replay buffer samplers.""" _target_: str = "torchrl.data.replay_buffers.Sampler" def __post_init__(self) -> None: """Post-initialization hook for sampler configurations."""
[docs] @dataclass class RandomSamplerConfig(SamplerConfig): """Configuration for random sampling from replay buffer.""" _target_: str = "torchrl.data.replay_buffers.RandomSampler" def __post_init__(self) -> None: """Post-initialization hook for random sampler configurations.""" super().__post_init__()
[docs] @dataclass class ConsumingSamplerConfig(SamplerConfig): """Hydra configuration for :class:`~torchrl.data.replay_buffers.ConsumingSampler`. Every kwarg accepted by ``ConsumingSampler.__init__`` is exposed as a field here. """ _target_: str = "torchrl.data.replay_buffers.ConsumingSampler" max_sample_count: int = 1
def _make_writer_ensemble(writers: list[Any], p: Any = None) -> WriterEnsemble: """Build a writer ensemble from Hydra's keyword-based representation.""" del p # Kept for compatibility with the historical Config schema. return WriterEnsemble(*writers) @dataclass class WriterEnsembleConfig(WriterConfig): """Configuration for ensemble writer that combines multiple writers.""" _target_: str = "torchrl.trainers.algorithms.configs.data._make_writer_ensemble" writers: list[Any] = field(default_factory=list) p: Any = None @dataclass class TensorDictMaxValueWriterConfig(WriterConfig): """Configuration for TensorDict max value writer.""" _target_: str = "torchrl.data.replay_buffers.TensorDictMaxValueWriter" rank_key: Any = None reduction: str = "sum" @dataclass class TensorDictRoundRobinWriterConfig(WriterConfig): """Hydra configuration for :class:`~torchrl.data.TensorDictRoundRobinWriter`.""" _target_: str = "torchrl.data.replay_buffers.TensorDictRoundRobinWriter" compilable: bool = False track_generations: bool = False @dataclass class ImmutableDatasetWriterConfig(WriterConfig): """Configuration for immutable dataset writer.""" _target_: str = "torchrl.data.replay_buffers.ImmutableDatasetWriter" @dataclass class SamplerEnsembleConfig(SamplerConfig): """Configuration for ensemble sampler that combines multiple samplers.""" _target_: str = "torchrl.data.replay_buffers.SamplerEnsemble" samplers: list[Any] = field(default_factory=list) p: Any = None @dataclass class PrioritizedSliceSamplerConfig(SamplerConfig): """Configuration for prioritized slice sampling from replay buffer.""" num_slices: int | None = None slice_len: int | None = None end_key: Any = None end_keys: Any = None traj_key: Any = None ends: Any = None trajectories: Any = None cache_values: bool = False truncated_key: Any = ("next", "truncated") init_key: Any = "is_init" strict_length: bool = True compile: Any = False span: Any = False use_gpu: Any = False max_capacity: int | None = None alpha: float | None = None beta: float | None = None eps: float | None = None reduction: str | None = None _target_: str = "torchrl.data.replay_buffers.PrioritizedSliceSampler"
[docs] @dataclass class SliceSamplerWithoutReplacementConfig(SamplerConfig): """Hydra configuration for :class:`~torchrl.data.SliceSamplerWithoutReplacement`.""" _target_: str = "torchrl.data.replay_buffers.SliceSamplerWithoutReplacement" num_slices: int | None = None slice_len: int | None = None end_key: Any = None end_keys: Any = None traj_key: Any = None ends: Any = None trajectories: Any = None cache_values: bool = False truncated_key: Any = ("next", "truncated") init_key: Any = "is_init" strict_length: bool = True output_layout: _SliceOutputLayout = "flat" slice_end_key: Any = ("collector", "slice_end") time_dim_name: str | None = "time" compile: Any = False span: Any = False use_gpu: Any = False
[docs] @dataclass class SliceSamplerConfig(SamplerConfig): """Hydra configuration for :class:`~torchrl.data.SliceSampler`.""" _target_: str = "torchrl.data.replay_buffers.SliceSampler" num_slices: int | None = None slice_len: int | None = None end_key: Any = None end_keys: Any = None traj_key: Any = None step_key: Any = "step_count" fragmented: bool = False ends: Any = None trajectories: Any = None cache_values: bool = False truncated_key: Any = ("next", "truncated") init_key: Any = "is_init" strict_length: bool = True pad_output: bool = False output_layout: _SliceOutputLayout = "flat" slice_end_key: Any = ("collector", "slice_end") time_dim_name: str | None = "time" compile: Any = False span: Any = False use_gpu: Any = False
[docs] @dataclass class StreamingSliceSamplerConfig(SamplerConfig): """Hydra configuration for :class:`~torchrl.data.StreamingSliceSampler`.""" _target_: str = "torchrl.data.replay_buffers.StreamingSliceSampler" slice_len: int = MISSING end_key: Any = None end_keys: Any = None traj_key: Any = None cache_values: bool = False truncated_key: Any = ("next", "truncated") init_key: Any = "is_init" strict_length: bool = True pad_output: bool = False compile: Any = False span: Any = False use_gpu: Any = False
[docs] @dataclass class PrioritizedSamplerConfig(SamplerConfig): """Configuration for prioritized sampling from replay buffer.""" max_capacity: int | None = None alpha: float | None = None beta: float | None = None eps: float | None = None reduction: str | None = None _target_: str = "torchrl.data.replay_buffers.PrioritizedSampler"
[docs] @dataclass class SamplerWithoutReplacementConfig(SamplerConfig): """Configuration for sampling without replacement.""" _target_: str = "torchrl.data.replay_buffers.SamplerWithoutReplacement" drop_last: bool = False shuffle: bool = True
@dataclass class SampleUnitConfig(ConfigBase): """Base configuration class for replay buffer sample units. See also :class:`~torchrl.data.replay_buffers.SampleUnit`. """ _target_: str = "torchrl.data.replay_buffers.SampleUnit" def __post_init__(self) -> None: """Post-initialization hook for sample unit configurations.""" @dataclass class TransitionConfig(SampleUnitConfig): """Hydra configuration for :class:`~torchrl.data.replay_buffers.Transition`. ``Transition.__init__`` takes no arguments, so this config only carries the instantiation target. """ _target_: str = "torchrl.data.replay_buffers.Transition" @dataclass class SequenceConfig(SampleUnitConfig): """Hydra configuration for :class:`~torchrl.data.replay_buffers.Sequence`. Every kwarg accepted by ``Sequence.__init__`` is exposed as a field here with the same default. """ _target_: str = "torchrl.data.replay_buffers.Sequence" length: int = MISSING episode_boundary: str = "pad" done_key: Any = ("next", "done") burn_in: int = 0 bootstrap: int = 0 dilation: int = 1 @dataclass class StorageConfig(ConfigBase): """Base configuration class for replay buffer storage.""" _partial_: bool = False _target_: str = "torchrl.data.replay_buffers.Storage" def __post_init__(self) -> None: """Post-initialization hook for storage configurations."""
[docs] @dataclass class TensorStorageConfig(StorageConfig): """Configuration for tensor-based storage in replay buffer.""" _target_: str = "torchrl.data.replay_buffers.TensorStorage" max_size: int | None = None storage: Any = None device: Any = None ndim: int | None = None compilable: bool = False def __post_init__(self) -> None: """Post-initialization hook for tensor storage configurations.""" super().__post_init__()
[docs] @dataclass class ListStorageConfig(StorageConfig): """Hydra configuration for :class:`~torchrl.data.replay_buffers.ListStorage`. Every kwarg accepted by ``ListStorage.__init__`` is exposed as a field here. """ _target_: str = "torchrl.data.replay_buffers.ListStorage" max_size: int | None = None compilable: bool = False device: Any = None
[docs] @dataclass class StorageEnsembleWriterConfig(StorageConfig): """Hydra configuration for :class:`~torchrl.data.replay_buffers.WriterEnsemble`. This name is a historical typo for :class:`~torchrl.trainers.algorithms.configs.data.WriterEnsembleConfig`. The Config is kept so existing Hydra group references do not vanish without a deprecation cycle. Fields match :class:`~torchrl.trainers.algorithms.configs.data.WriterEnsembleConfig` (``writers``, ``p``). ``WriterEnsemble.__init__`` only accepts ``*writers``; ``p`` is stored for Config parity and is not a constructor argument. """ _target_: str = "torchrl.trainers.algorithms.configs.data._make_writer_ensemble" writers: list[Any] = field(default_factory=list) p: Any = None
[docs] @dataclass class LazyStackStorageConfig(StorageConfig): """Configuration for lazy stack storage.""" _target_: str = "torchrl.data.replay_buffers.LazyStackStorage" max_size: int | None = None compilable: bool = False stack_dim: int = 0
[docs] @dataclass class StorageEnsembleConfig(StorageConfig): """Configuration for storage ensemble.""" _target_: str = "torchrl.data.replay_buffers.StorageEnsemble" storages: list[Any] = MISSING transforms: list[Any] = MISSING
[docs] @dataclass class LazyMemmapStorageConfig(StorageConfig): """Hydra configuration for :class:`~torchrl.data.replay_buffers.LazyMemmapStorage`. Every kwarg accepted by ``LazyMemmapStorage.__init__`` is exposed as a field here. """ _target_: str = "torchrl.data.replay_buffers.LazyMemmapStorage" max_size: int | None = None scratch_dir: Any = None device: Any = "cpu" ndim: int = 1 existsok: bool = False compilable: bool = False shared_init: bool = False auto_cleanup: bool | None = None
[docs] @dataclass class LazyTensorStorageConfig(StorageConfig): """Hydra configuration for :class:`~torchrl.data.replay_buffers.LazyTensorStorage`. Every kwarg accepted by ``LazyTensorStorage.__init__`` is exposed as a field here. """ _target_: str = "torchrl.data.replay_buffers.LazyTensorStorage" max_size: int | None = None device: Any = "cpu" ndim: int = 1 compilable: bool = False consolidated: bool = False shared_init: bool = False cleanup_memmap: bool = True
@dataclass class ReplayBufferBaseConfig(ConfigBase): """Base configuration class for replay buffers.""" _partial_: bool = False def __post_init__(self) -> None: """Post-initialization hook for replay buffer configurations."""
[docs] @dataclass class TensorDictReplayBufferConfig(ReplayBufferBaseConfig): """Hydra configuration for :class:`~torchrl.data.replay_buffers.TensorDictReplayBuffer`. Every kwarg accepted by ``TensorDictReplayBuffer.__init__`` (plus the ``ReplayBuffer`` kwargs it forwards via ``**kwargs``) is exposed as a field here. """ _target_: str = "torchrl.data.replay_buffers.TensorDictReplayBuffer" priority_key: str = "td_error" sampler: Any = None sample_unit: Any = None storage: Any = None writer: Any = None collate_fn: Any = None pin_memory: bool = False prefetch: int | None = None transform: Any = None transform_factory: Any = None batch_size: int | None = None dim_extend: int | None = None checkpointer: Any = None generator: Any = None consume_after_n_samples: int | None = None shared: bool = False compilable: bool | None = None delayed_init: bool | None = None service_backend: _ReplayServiceBackend = "direct" service_backend_options: dict[str, Any] = field(default_factory=dict) def __post_init__(self) -> None: """Post-initialization hook for TensorDict replay buffer configurations.""" super().__post_init__()
[docs] @dataclass class ReplayBufferConfig(ReplayBufferBaseConfig): """Hydra configuration for :class:`~torchrl.data.replay_buffers.ReplayBuffer`. Every kwarg accepted by ``ReplayBuffer.__init__`` is exposed as a field here. """ _target_: str = "torchrl.data.replay_buffers.ReplayBuffer" storage: Any = None sampler: Any = None sample_unit: Any = None writer: Any = None collate_fn: Any = None pin_memory: bool = False prefetch: int | None = None transform: Any = None transform_factory: Any = None batch_size: int | None = None dim_extend: int | None = None checkpointer: Any = None generator: Any = None consume_after_n_samples: int | None = None shared: bool = False compilable: bool | None = None delayed_init: bool | None = None service_backend: _ReplayServiceBackend = "direct" service_backend_options: dict[str, Any] = field(default_factory=dict) transport: _ReplayTransport = "auto" transport_options: dict[str, Any] | None = None