TensorPlay
latest (dev)
Copy
View Markdown

Latest development documentation · Updated 2026-10-08

Source code for tensorplay.distributed.checkpoint.default_planner

from __future__ import annotations

import io
import logging
import math
import pickle
import sys
from bisect import bisect_right, insort
from collections import ChainMap
from dataclasses import replace
from typing import Any

import tensorplay as tp

from ._nested_dict import flatten_state_dict, unflatten_state_dict
from ._sharded_tensor_utils import _flatten_sharded_tensors
from ._traverse import get_element, set_element
from ._dedup_save_plans import dedup_save_plans
from .metadata import BytesStorageMetadata, Metadata, MetadataIndex, StorageMeta, TensorStorageMetadata
from .planner import LoadPlan, LoadPlanner, SavePlan, SavePlanner, WriteItemType
from .planner_helpers import (
    _compare_save_plans,
    _contains_usable_plan,
    _merge_delta_local_plans,
    _create_default_local_metadata as _planner_create_default_local_metadata,
    create_default_global_load_plan as _planner_create_default_global_load_plan,
    create_default_global_save_plan as _planner_create_default_global_save_plan,
    create_default_local_load_plan as _planner_create_default_local_load_plan,
    create_default_local_save_plan as _planner_create_default_local_save_plan,
    _create_default_metadata_only_plan,
    _create_read_items,
    _create_write_items,
    _init_state_dict,
)

__all__ = ["DefaultSavePlanner", "DefaultLoadPlanner", "create_default_local_load_plan", "create_default_global_load_plan", "create_default_local_save_plan", "create_default_global_save_plan"]

logger = logging.getLogger(__name__)


def _narrow(value: tp.Tensor, offsets: tuple[int, ...], lengths: tuple[int, ...]) -> tp.Tensor:
    result = value
    for dim, (offset, length) in enumerate(zip(offsets, lengths)):
        if length:
            result = result.narrow(dim, int(offset), int(length))
    return result



[docs]
class DefaultSavePlanner(SavePlanner):
    def __init__(self, flatten_state_dict: bool = True, flatten_sharded_tensors: bool = True, dedup_replicated_tensors: bool | None = None, dedup_save_to_lowest_rank: bool = False, enable_plan_caching: bool = False) -> None:
        self.flatten_state_dict = flatten_state_dict
        self.flatten_sharded_tensors = flatten_sharded_tensors
        del dedup_replicated_tensors
        self.dedup_save_to_lowest_rank = dedup_save_to_lowest_rank
        self._cached_plans_key = self.__class__.__name__
        self._enable_plan_caching = enable_plan_caching
        self.mappings: dict[str, tuple[Any, ...]] = {}

    def set_up_planner(self, state_dict: dict[str, Any], storage_meta: StorageMeta | None = None, is_coordinator: bool = False) -> None:
        del storage_meta
        if self.flatten_state_dict:
            self.state_dict, self.mappings = flatten_state_dict(state_dict)
        else:
            self.state_dict = state_dict
        if self.flatten_sharded_tensors:
            self.state_dict = _flatten_sharded_tensors(self.state_dict)
        self.is_coordinator = is_coordinator

    def create_local_plan(self) -> SavePlan:
        plan = create_default_local_save_plan(self.state_dict, self.is_coordinator)
        if self.flatten_state_dict:
            plan = replace(plan, planner_data=self.mappings)
        self.plan = plan
        if self._enable_plan_caching:
            if (
                self._cached_plans_key in SavePlanner._cached_save_plan
                and _compare_save_plans(
                    plan, SavePlanner._cached_save_plan[self._cached_plans_key]
                )
            ):
                return SavePlan([], usable=False)
            self._pending_local_plan = plan
        return self.plan

    def create_global_plan(self, all_plans: list[SavePlan]) -> tuple[list[SavePlan], Metadata]:
        if self._enable_plan_caching:
            global_plan_delta, global_plan, metadata = self._create_global_plan_with_caching(all_plans)
        else:
            global_plan, metadata = self._create_global_plan(all_plans)
            global_plan_delta = global_plan
        self.global_plan = global_plan
        self.metadata = metadata
        return global_plan_delta, self.metadata

    def _dedup_save_plans(self, all_plans: list[SavePlan]) -> list[SavePlan]:
        return dedup_save_plans(all_plans, self.dedup_save_to_lowest_rank)

    def _create_global_plan(
        self, all_plans: list[SavePlan]
    ) -> tuple[list[SavePlan], Metadata]:
        deduped_plans = self._dedup_save_plans(all_plans)
        global_plan, metadata = create_default_global_save_plan(deduped_plans)
        if self.flatten_state_dict:
            planner_data_dict = [plan.planner_data for plan in global_plan]
            metadata = replace(
                metadata,
                planner_data=dict(ChainMap(*planner_data_dict)),
            )
        validation_errors = _validate_global_plan(global_plan, metadata)
        if validation_errors:
            error_summary = "; ".join(validation_errors)
            if len(error_summary) > 500:
                error_summary = error_summary[:500] + "... (truncated)"
            raise ValueError(f"Failed to validate global plan: {error_summary}")
        return global_plan, metadata

    def _create_global_plan_with_caching(
        self, all_plans: list[SavePlan]
    ) -> tuple[list[SavePlan], list[SavePlan], Metadata]:
        global_plan_delta: list[SavePlan] = []
        if self._cached_plans_key not in SavePlanner._cached_all_plans:
            global_plan, metadata = self._create_global_plan(all_plans)
            SavePlanner._cached_all_plans[self._cached_plans_key] = all_plans
            SavePlanner._cached_global_plan[self._cached_plans_key] = global_plan
            SavePlanner._cached_metadata[self._cached_plans_key] = metadata
            return global_plan, global_plan, metadata

        if not _contains_usable_plan(all_plans):
            global_plan_delta = [SavePlan([], usable=False)] * len(all_plans)
            global_plan = SavePlanner._cached_global_plan[self._cached_plans_key]
            metadata = SavePlanner._cached_metadata[self._cached_plans_key]
        else:
            merged_plans = _merge_delta_local_plans(
                SavePlanner._cached_all_plans[self._cached_plans_key], all_plans
            )
            SavePlanner._cached_all_plans[self._cached_plans_key] = merged_plans
            global_plan, metadata = self._create_global_plan(merged_plans)
            for cached_plan, new_plan in zip(
                SavePlanner._cached_global_plan[self._cached_plans_key], global_plan
            ):
                if _compare_save_plans(cached_plan, new_plan):
                    global_plan_delta.append(SavePlan([], usable=False))
                else:
                    global_plan_delta.append(new_plan)
            SavePlanner._cached_global_plan[self._cached_plans_key] = global_plan
            SavePlanner._cached_metadata[self._cached_plans_key] = metadata
        return global_plan_delta, global_plan, metadata

    def finish_plan(self, new_plan: SavePlan) -> SavePlan:
        finished_plan = new_plan
        if self._enable_plan_caching:
            finished_plan = self._finish_plan_with_caching(new_plan)
            if hasattr(self, "_pending_local_plan"):
                SavePlanner._cached_save_plan[self._cached_plans_key] = self._pending_local_plan
                del self._pending_local_plan
        self.plan = finished_plan
        return self.plan

    def _finish_plan_with_caching(self, new_plan: SavePlan) -> SavePlan:
        if not new_plan.usable:
            return SavePlanner._cached_final_save_plan[self._cached_plans_key]
        SavePlanner._cached_final_save_plan[self._cached_plans_key] = new_plan
        return new_plan

    def lookup_object(self, index: MetadataIndex) -> Any:
        from .utils import find_state_dict_object

        return find_state_dict_object(self.state_dict, index)

    def transform_object(self, write_item: Any, object: Any) -> Any:
        if write_item.type is WriteItemType.BYTE_IO:
            stream = io.BytesIO()
            pickle.dump(object, stream, pickle.HIGHEST_PROTOCOL)
            stream.seek(0)
            return stream
        if hasattr(object, "to_local") and callable(object.to_local):
            return object.to_local()
        return object

    def resolve_data(self, write_item: Any) -> Any:
        return self.transform_object(write_item, self.lookup_object(write_item.index))




[docs]
class DefaultLoadPlanner(LoadPlanner):
    def __init__(self, flatten_state_dict: bool = True, flatten_sharded_tensors: bool = True, allow_partial_load: bool = False) -> None:
        self.flatten_state_dict = flatten_state_dict
        self.flatten_sharded_tensors = flatten_sharded_tensors
        self.allow_partial_load = allow_partial_load
        self.original_state_dict: dict[str, Any] = {}
        self.mappings: dict[str, tuple[Any, ...]] = {}

    def set_up_planner(self, state_dict: dict[str, Any], metadata: Metadata | None = None, is_coordinator: bool = False) -> None:
        _init_state_dict(state_dict)
        self.original_state_dict = state_dict
        if self.flatten_sharded_tensors:
            state_dict = _flatten_sharded_tensors(state_dict)
        if self.flatten_state_dict:
            self.state_dict, self.mappings = flatten_state_dict(state_dict)
        else:
            self.state_dict = state_dict
        self.metadata = metadata
        self.is_coordinator = is_coordinator

    def create_local_plan(self) -> LoadPlan:
        if self.metadata is None:
            raise ValueError("metadata is required")
        self.plan = _planner_create_default_local_load_plan(
            self.state_dict, self.metadata, not self.allow_partial_load
        )
        return self.plan

    def create_global_plan(self, global_plan: list[LoadPlan]) -> list[LoadPlan]:
        return _planner_create_default_global_load_plan(global_plan)

    def finish_plan(self, new_plan: LoadPlan) -> LoadPlan:
        return new_plan

    def load_bytes(self, read_item: Any, value: io.BytesIO) -> None:
        value.seek(0)
        loaded = pickle.load(value)
        key = read_item.dest_index.fqn
        if self.flatten_state_dict and key in self.mappings:
            set_element(self.original_state_dict, self.mappings[key], loaded)
        else:
            self.state_dict[key] = loaded

    def lookup_tensor(self, index: MetadataIndex) -> tp.Tensor:
        value = self.state_dict[index.fqn]
        if not hasattr(value, "__get_tensor_shard__"):
            from .utils import find_state_dict_object

            value = find_state_dict_object(self.state_dict, index)
        if hasattr(value, "__get_tensor_shard__"):
            value = value.__get_tensor_shard__(index)
        elif hasattr(value, "to_local") and callable(value.to_local):
            value = value.to_local()
        if not isinstance(value, tp.Tensor):
            raise TypeError(f"{index.fqn} is not a tensor")
        return value

    def resolve_tensor(self, read_item: Any) -> tp.Tensor:
        tensor = _narrow(self.lookup_tensor(read_item.dest_index), read_item.dest_offsets, read_item.lengths)
        return self.transform_tensor(read_item, tensor)

    def transform_tensor(self, read_item: Any, tensor: tp.Tensor) -> tp.Tensor:
        return tensor

    def commit_tensor(self, read_item: Any, tensor: tp.Tensor) -> None:
        del read_item, tensor



class _EmptyStateDictLoadPlanner(DefaultLoadPlanner):
    def __init__(self, keys: set[str] | None = None, *args: Any, **kwargs: Any) -> None:
        super().__init__(*args, **kwargs)
        self.keys = keys

    def _should_include_key(self, key: str, metadata: Metadata) -> bool:
        if self.keys is None or key in self.keys:
            return True
        planner_data = metadata.planner_data or {}
        path = planner_data.get(key)
        if path is None:
            return False
        names: list[str] = []
        for part in path:
            names.append(str(part) if not names else f"{names[-1]}.{part}")
        return any(name in self.keys for name in names)

    def set_up_planner(self, state_dict: dict[str, Any], metadata: Metadata | None = None, is_coordinator: bool = False) -> None:
        if state_dict:
            raise ValueError("empty planner requires an empty state dictionary")
        if metadata is None:
            raise ValueError("metadata is required")
        for key, value in metadata.state_dict_metadata.items():
            if self.keys is not None and key not in self.keys:
                if not self._should_include_key(key, metadata):
                    continue
            if isinstance(value, TensorStorageMetadata):
                state_dict[key] = tp.empty(value.size, dtype=value.properties.dtype)
            else:
                state_dict[key] = None
            if metadata.planner_data is not None and key in metadata.planner_data:
                set_element(state_dict, metadata.planner_data[key], state_dict.pop(key))
        super().set_up_planner(state_dict, metadata, is_coordinator)


def create_default_local_load_plan(state_dict: dict[str, Any], metadata: Metadata, strict: bool = True) -> LoadPlan:
    return _planner_create_default_local_load_plan(state_dict, metadata, strict)


def create_default_global_load_plan(all_plans: list[LoadPlan]) -> list[LoadPlan]:
    return _planner_create_default_global_load_plan(all_plans)


def create_default_local_save_plan(state_dict: dict[str, Any], is_coordinator: bool = True) -> SavePlan:
    return _planner_create_default_local_save_plan(state_dict, is_coordinator)


def create_default_global_save_plan(
    all_plans: list[SavePlan], rewrite_index_hints: bool = True
) -> tuple[list[SavePlan], Metadata]:
    return _planner_create_default_global_save_plan(all_plans, rewrite_index_hints)


def _create_default_local_metadata(state_dict: dict[str, Any]) -> Metadata:
    return _planner_create_default_local_metadata(state_dict)


def _check_box_overlap(
    box0: Any, box1: Any
) -> bool:
    for dimension in range(len(box0.offsets)):
        if box0.offsets[dimension] >= box1.offsets[dimension] + box1.sizes[dimension]:
            return False
        if box1.offsets[dimension] >= box0.offsets[dimension] + box0.sizes[dimension]:
            return False
    return True


def _check_box_bounds(outer_box_size: tuple[int, ...], inner_box: Any) -> bool:
    for dimension in range(len(outer_box_size)):
        if inner_box.offsets[dimension] < 0:
            return False
        if inner_box.sizes[dimension] < 0:
            return False
        if inner_box.offsets[dimension] + inner_box.sizes[dimension] > outer_box_size[dimension]:
            return False
    return True


def _validate_global_plan(global_plan: list[SavePlan], metadata: Metadata) -> list[str]:
    errors: list[str] = []
    for key, value in metadata.state_dict_metadata.items():
        if isinstance(value, BytesStorageMetadata):
            continue
        if len(value.size) == 0:
            continue
        chunks = value.chunks
        chunks_volume = 0
        for chunk in chunks:
            if not _check_box_bounds(value.size, chunk):
                message = (
                    f"key:{key} has out of bounds chunk: "
                    f"tensor-size:{value.size} chunk: {chunk}"
                )
                logger.warning(message)
                errors.append(message)
            chunks_volume += math.prod(chunk.sizes)

        if len(chunks) > 1:
            dimensions = len(value.size)
            sweep_dimension = max(
                range(dimensions), default=0, key=lambda dimension: value.size[dimension]
            )
            sorted_indices = sorted(
                range(len(chunks)),
                key=lambda index: (
                    chunks[index].offsets[sweep_dimension],
                    *(chunks[index].offsets[dimension] for dimension in range(dimensions)),
                ),
            )
            active: list[tuple[int, int]] = []
            for index in sorted_indices:
                current = chunks[index]
                start = current.offsets[sweep_dimension]
                end = start + current.sizes[sweep_dimension]
                cutoff = bisect_right(active, (start, sys.maxsize))
                if cutoff:
                    del active[:cutoff]
                for _, other_index in active:
                    other = chunks[other_index]
                    if _check_box_overlap(current, other):
                        message = f"key:{key} has overlapping chunks: {current} {other}"
                        logger.warning(message)
                        errors.append(message)
                insort(active, (end, index))

        tensor_volume = math.prod(value.size)
        if len(global_plan) > 1 and chunks_volume != tensor_volume:
            message = (
                f"key:{key} invalid fill tensor-volume: "
                f"{tensor_volume} chunks-volume: {chunks_volume}"
            )
            logger.warning(message)
            errors.append(message)
    return errors
Ask DeepWiki