Coverage for / home / jenkins / .local / lib / python3.10 / site-packages / hyper_parallel / core / shard / ops / parallel_masked_scatter.py: 69%
26 statements
« prev ^ index » next coverage.py v7.13.1, created at 2026-07-06 05:41 +0800
« prev ^ index » next coverage.py v7.13.1, created at 2026-07-06 05:41 +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"""
16Distributed implementation for MaskedScatter operator.
17"""
19from typing import Tuple
21from .parallel_ops import DistributedOp
24def _normalize_masked_scatter_args(input_tensor, mask, source):
25 return (input_tensor, mask, source), {}
28class MaskedScatterDistributedOp(DistributedOp):
29 """Distributed implementation for torch.Tensor.masked_scatter."""
31 def preprocess(self, args: tuple, kwargs: dict) -> tuple:
32 """
33 Preprocess arguments for MaskedScatter operator.
35 torch.masked_scatter(input, mask, source) takes three positional tensor inputs
36 with no keyword-only parameters.
38 Args:
39 args (tuple): Positional arguments (input, mask, source).
40 kwargs (dict): Keyword arguments (none expected).
42 Returns:
43 tuple: (local_args, local_kwargs, cache_values)
44 """
45 args, kwargs = _normalize_masked_scatter_args(*args, **kwargs)
46 input_tensor, mask, source = args[0], args[1], args[2]
47 local_args = (
48 input_tensor.to_local(),
49 mask.to_local(),
50 source.to_local(),
51 )
52 local_kwargs = {}
53 cache_values = [
54 input_tensor.layout,
55 mask.layout,
56 source.layout,
57 ]
58 return local_args, local_kwargs, cache_values
60 def infer_layout(self, cache_values: list) -> Tuple[tuple, None]:
61 """
62 Infer output layout for torch.Tensor.masked_scatter.
64 PyTorch semantics:
65 masked_scatter_(mask, source)
66 Copies elements from source into self tensor at positions where the mask is True.
67 Elements from source are taken in order.
69 Distributed restrictions:
70 Because `masked_scatter` consumes elements from `source` sequentially based on
71 the flattened index of `True` values in `mask`, sharding the input or mask
72 would require a global prefix sum (scan) to determine the correct offset
73 in `source` for each rank. Without this communication overhead, correct
74 behavior cannot be guaranteed on sharded tensors.
76 Therefore, this implementation enforces that all inputs (input, mask, source)
77 must be fully Replicated (Unsharded).
79 Rules:
80 1. Inputs must not have Partial status.
81 2. All inputs (input, mask, source) must be fully Replicated — no dimension may be sharded.
82 3. Output layout follows the input layout.
84 Args:
85 cache_values (list): [input_layout, mask_layout, source_layout]
87 Returns:
88 tuple: ((output_layout,), None)
90 Raises:
91 ValueError: If any input tensor is sharded.
92 """
93 input_layout = cache_values[0]
94 mask_layout = cache_values[1]
95 source_layout = cache_values[2]
97 layouts = [input_layout, mask_layout, source_layout]
98 if not self._allow_partial_inputs:
99 self._check_partial_inputs(layouts)
101 # Check strict replication for all involved distributed tensors
102 for i, layout in enumerate(layouts):
103 if layout is None:
104 continue
106 # Use alias_tensor_map for sharding checks — it handles StridedShard tuple mappings.
107 # "None" means Replicated; anything else indicates sharding.
108 for dim_alias in layout.alias_tensor_map:
109 if dim_alias != "None":
110 raise ValueError(
111 f"For {self.op_name}, input {i} is sharded (Layout: {layout}). "
112 f"masked_scatter currently only supports fully Replicated (Unsharded) tensors "
113 f"due to sequential dependency on source elements."
114 )
116 # Output layout follows input layout (which we verified is Replicated/None)
117 return ((input_layout,), None)