Coverage for / home / jenkins / .local / lib / python3.10 / site-packages / hyper_parallel / core / dtensor / _from_local_utils.py: 64%
47 statements
« prev ^ index » next coverage.py v7.13.1, created at 2026-08-04 05:18 +0800
« prev ^ index » next coverage.py v7.13.1, created at 2026-08-04 05:18 +0800
1# Copyright 2026 Huawei Technologies Co., Ltd
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14# ============================================================================
15"""Utilities for :meth:`DTensor.from_local` with ``run_check=True`` (PyTorch parity)."""
16from __future__ import annotations
18from typing import Optional, Sequence, Tuple
20from hyper_parallel.core.dtensor.device_mesh import DeviceMesh
21from hyper_parallel.core.dtensor.placement_types import Placement
22from hyper_parallel.platform import get_platform
24platform = get_platform()
25Tensor = platform.Tensor
28def _ensure_mesh_process_groups(mesh: DeviceMesh) -> None:
29 if hasattr(mesh, "_dim_group_names") and mesh._dim_group_names is not None:
30 return
31 mesh._dim_group_names = DeviceMesh._init_process_groups( # pylint: disable=protected-access
32 mesh._mesh_shape,
33 mesh.mesh_dim_names,
34 mesh._rank_list,
35 )
38def mesh_broadcast(
39 tensor: Tensor,
40 mesh: DeviceMesh,
41 mesh_dim: int,
42 *,
43 group_src: int = 0,
44) -> Tensor:
45 """Broadcast *tensor* along one mesh dimension."""
46 _ensure_mesh_process_groups(mesh)
47 group = mesh.get_group(mesh_dim)
48 if hasattr(tensor, "is_contiguous") and not tensor.is_contiguous():
49 tensor = tensor.contiguous()
50 rank_list = mesh.get_rank_list_along_axis(mesh_dim)
51 src = rank_list[group_src]
52 platform.broadcast(tensor, src, group=group)
53 return tensor
56def _tensor_meta(local_tensor: Tensor, *, check_shape_stride: bool) -> dict:
57 meta = {
58 "dtype": str(local_tensor.dtype),
59 "requires_grad": bool(getattr(local_tensor, "requires_grad", False)),
60 }
61 if check_shape_stride:
62 meta["shape"] = tuple(local_tensor.shape)
63 if hasattr(local_tensor, "stride"):
64 meta["stride"] = tuple(local_tensor.stride())
65 return meta
68def check_tensor_meta(
69 local_tensor: Tensor,
70 group,
71 group_size: int,
72 *,
73 check_shape_stride: bool,
74) -> None:
75 """Gather tensor metadata across *group* and verify consistency."""
76 local_meta = _tensor_meta(local_tensor, check_shape_stride=check_shape_stride)
77 gathered = [None] * group_size
78 platform.all_gather_object(gathered, local_meta, group=group)
79 if not all(meta == local_meta for meta in gathered if meta is not None):
80 raise ValueError(
81 "Inconsistent tensor metadata across ranks in from_local(run_check=True): "
82 f"local={local_meta}, gathered={gathered}"
83 )
86def _mesh_check_group(device_mesh: DeviceMesh):
87 """Return the process group and size covering all ranks in *device_mesh*."""
88 _ensure_mesh_process_groups(device_mesh)
89 if device_mesh.ndim == 1:
90 return device_mesh.get_group(0), device_mesh.size(0)
91 flat_mesh = device_mesh.flatten()
92 _ensure_mesh_process_groups(flat_mesh)
93 return flat_mesh.get_group(0), flat_mesh.size(0)
96def run_from_local_checks(
97 local_tensor: Tensor,
98 device_mesh: DeviceMesh,
99 resolved_placements: Sequence[Placement],
100 *,
101 shape: Optional[Tuple[int, ...]] = None,
102 stride: Optional[Tuple[int, ...]] = None,
103) -> None:
104 """Validate local shards and align replicate placements before wrapping as DTensor."""
105 check_shape_stride = shape is None and stride is None
106 group, group_size = _mesh_check_group(device_mesh)
107 check_tensor_meta(
108 local_tensor,
109 group,
110 group_size,
111 check_shape_stride=check_shape_stride,
112 )
113 for mesh_dim, placement in enumerate(resolved_placements):
114 if placement.is_replicate():
115 mesh_broadcast(local_tensor, device_mesh, mesh_dim)