Coverage for / home / jenkins / .local / lib / python3.10 / site-packages / hyper_parallel / core / shard / ops / parallel_argsort.py: 97%
36 statements
« prev ^ index » next coverage.py v7.13.1, created at 2026-08-21 04:29 +0800
« prev ^ index » next coverage.py v7.13.1, created at 2026-08-21 04:29 +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 Argsort operator.
17"""
19import copy
20from typing import Tuple
22from .parallel_ops import DistributedOp
25def _normalize_argsort_args(x, dim=-1, descending=False, stable=False):
26 """Normalize torch.argsort arguments to (args, kwargs).
28 torch.argsort(input, dim=-1, descending=False, *, stable=False)
29 Only `stable` is keyword-only; all other params are positional.
30 """
31 return (x, dim, descending), {'stable': stable}
34class ArgsortDistributedOp(DistributedOp):
35 """Distributed implementation for torch.argsort."""
37 _MS_PRIMITIVE_OP_NAMES = frozenset({'ArgSort'})
39 def preprocess(self, args: tuple, kwargs: dict) -> tuple:
40 """
41 Preprocess arguments for Argsort operator.
43 Args:
44 args (tuple): Input arguments, first element is the input tensor.
45 kwargs (dict): Keyword arguments (dim, descending, stable).
47 Returns:
48 tuple: (local_args, local_kwargs, cache_values)
49 """
50 args, kwargs = _normalize_argsort_args(*args, **kwargs)
51 input_tensor = args[0]
52 dim = args[1]
53 descending = args[2]
54 stable = kwargs['stable']
56 if self.op_name in self._MS_PRIMITIVE_OP_NAMES:
57 local_args = (input_tensor.to_local(), dim, descending, stable)
58 local_kwargs = {}
59 else:
60 local_args = (input_tensor.to_local(),)
61 local_kwargs = {'dim': dim, 'descending': descending, 'stable': stable}
63 cache_values = [input_tensor.layout, dim]
64 return local_args, local_kwargs, cache_values
66 def infer_layout(self, cache_values: list) -> Tuple[tuple, None]:
67 """
68 Infer output layout for Argsort operator.
70 Rules:
71 1. Input must not have Partial status.
72 2. dim must be an integer within the valid range [-ndim, ndim-1].
73 3. The sort dimension must not be sharded.
74 4. Output layout is identical to the input layout.
76 Args:
77 cache_values (list): [input_layout, dim] where dim is the sort dimension.
79 Returns:
80 tuple: ((output_layout,), None)
82 Raises:
83 ValueError: If input has Partial status, dim is out of range, or the sort
84 dimension is sharded.
85 """
86 layout = cache_values[0]
87 dim = cache_values[1]
89 if not self._allow_partial_inputs:
90 self._check_partial_inputs([layout])
92 if not isinstance(dim, int):
93 raise ValueError(
94 f"For {self.op_name}, dimension should be int, but got {type(dim)}"
95 )
97 alias_map = layout.alias_tensor_map
98 ndim = len(alias_map)
100 if dim < -ndim or dim >= ndim:
101 raise ValueError(
102 f"For {self.op_name}, dimension out of range "
103 f"(expected to be in range of [{-ndim}, {ndim - 1}], but got {dim})"
104 )
106 if dim < 0:
107 dim += ndim
109 if alias_map[dim] != "None":
110 raise ValueError(
111 f"For {self.op_name}, sorting along a sharded dimension "
112 f"(dim {dim} mapped to {alias_map[dim]}) is not supported. "
113 f"Please redistribute the tensor to Replicate on this dimension before sorting."
114 )
116 return ((copy.deepcopy(layout),), None)