Coverage for / home / jenkins / .local / lib / python3.10 / site-packages / hyper_parallel / core / tensor_parallel / mc2_style.py: 100%
33 statements
« prev ^ index » next coverage.py v7.13.1, created at 2026-10-25 05:45 +0800
« prev ^ index » next coverage.py v7.13.1, created at 2026-10-25 05:45 +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"""Parallel styles for MC2 fused linear layers (PyTorch / Ascend)."""
16from __future__ import annotations
18from typing import Optional
20from torch import nn
22from hyper_parallel.core.dtensor.device_mesh import DeviceMesh
23from hyper_parallel.core.dtensor.placement_types import Placement, Shard
24from hyper_parallel.core.tensor_parallel.mc2 import MC2Linear
25from hyper_parallel.core.tensor_parallel.style import ColwiseParallel, RowwiseParallel
27__all__ = ["MC2ColwiseParallel", "MC2RowwiseParallel"]
30def _replace_with_mc2_linear(
31 module: nn.Module,
32 mode: str,
33 device_mesh: DeviceMesh,
34 sequence_dim: int,
35) -> MC2Linear:
36 """Replace ``nn.Linear`` with configured ``MC2Linear`` in place."""
37 if not isinstance(module, nn.Linear):
38 raise NotImplementedError(
39 f"MC2 parallel style only supports Linear modules, but got {type(module).__name__}."
40 )
41 module = MC2Linear.from_linear(module)
42 module.configure_mc2(
43 mode,
44 device_mesh.get_group(),
45 device_mesh.size(),
46 sequence_dim=sequence_dim,
47 )
48 return module
51class MC2ColwiseParallel(ColwiseParallel):
52 """Column parallelism using fused all-gather and matmul (MC2).
54 Requires a sequence-sharded input layout so AllGather can be folded into the
55 matmul. Unlike :class:`ColwiseParallel`, this style does **not** redistribute
56 the input to ``Replicate()`` before the Linear.
57 """
59 def __init__(
60 self,
61 *,
62 input_layouts: Optional[Placement] = None,
63 output_layouts: Optional[Placement] = None,
64 use_local_output: Optional[bool] = None,
65 ) -> None:
66 super().__init__(
67 input_layouts=input_layouts,
68 output_layouts=output_layouts,
69 use_local_output=use_local_output,
70 )
71 if not isinstance(self.input_layouts[0], Shard):
72 raise ValueError("MC2ColwiseParallel requires a sharded input layout.")
73 # Keep sequence sharding; fused kernel performs the all-gather.
74 self.desired_input_layouts = self.input_layouts
75 self._sequence_dim = self.input_layouts[0].dim
77 def apply(self, module: nn.Module, device_mesh: DeviceMesh) -> nn.Module:
78 """Replace Linear with MC2Linear then apply column-wise sharding hooks."""
79 module = _replace_with_mc2_linear(
80 module, "all_gather", device_mesh, self._sequence_dim
81 )
82 return super().apply(module, device_mesh)
85class MC2RowwiseParallel(RowwiseParallel):
86 """Row parallelism using fused matmul and reduce-scatter (MC2).
88 Requires a sequence-sharded output layout so ReduceScatter replaces AllReduce
89 and restores sequence parallelism after the row-parallel Linear.
90 """
92 def __init__(
93 self,
94 *,
95 input_layouts: Optional[Placement] = None,
96 output_layouts: Optional[Placement] = None,
97 reduce_dtype=None,
98 use_local_output: bool = True,
99 ) -> None:
100 super().__init__(
101 input_layouts=input_layouts,
102 output_layouts=output_layouts,
103 reduce_dtype=reduce_dtype,
104 use_local_output=use_local_output,
105 )
106 if not isinstance(self.output_layouts[0], Shard):
107 raise ValueError("MC2RowwiseParallel requires a sharded output layout.")
108 self._sequence_dim = self.output_layouts[0].dim
110 def apply(self, module: nn.Module, device_mesh: DeviceMesh) -> nn.Module:
111 """Replace Linear with MC2Linear then apply row-wise sharding hooks."""
112 module = _replace_with_mc2_linear(
113 module, "reduce_scatter", device_mesh, self._sequence_dim
114 )
115 return super().apply(module, device_mesh)