Coverage for  / home / jenkins / .local / lib / python3.10 / site-packages / hyper_parallel / components / functional / _triton / gated_delta_net / state_summary.py: 0%

110 statements  

« 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# 

16# The state-summary decomposition follows the MIT-licensed context-parallel 

17# implementation in flash-linear-attention/fla/ops/cp/chunk_delta_h.py. 

18 

19# pylint: disable=missing-public-type-hints,invalid-name 

20 

21"""Fixed-shape Triton-Ascend kernels for GDN state summaries.""" 

22 

23__all__ = ["gdn_packed_state_summary_kernel", "gdn_state_grad_ext_kernel"] 

24 

25import triton 

26import triton.language as tl 

27 

28from .utils import get_autotune_config 

29 

30 

31@triton.autotune( 

32 configs=get_autotune_config( 

33 multibuffer_list=(True, False), 

34 set_workspace_multibuffer_list=(2, 4), 

35 tile_mix_vector_loop_num_list=(2,), 

36 tile_mix_cube_loop_num_list=(2,), 

37 ), 

38 key=["H", "K", "V", "BT", "BV"], 

39) 

40@triton.jit(do_not_specialize=["T"]) 

41def gdn_packed_state_summary_kernel( 

42 k, 

43 w, 

44 u, 

45 g, 

46 packed_summary, 

47 T, 

48 H: tl.constexpr, 

49 K: tl.constexpr, 

50 V: tl.constexpr, 

51 BT: tl.constexpr, 

52 BV: tl.constexpr, 

53 NT: tl.constexpr, 

54): 

55 """Build the local affine state transition and extension in one buffer.""" 

56 i_v = tl.program_id(0) 

57 i_bh = tl.program_id(1) 

58 i_b = i_bh // H 

59 i_h = i_bh % H 

60 

61 stride_k = H * K 

62 stride_v = H * V 

63 k += (i_b * T * H + i_h) * K 

64 w += (i_b * T * H + i_h) * K 

65 u += (i_b * T * H + i_h) * V 

66 g += i_b * T * H + i_h 

67 packed_summary += i_bh * K * (V + K) 

68 

69 col = tl.arange(0, BV) 

70 row1 = tl.arange(0, 64) 

71 row2 = 64 + tl.arange(0, 64) 

72 is_transition = i_v * BV >= V 

73 transition_col = i_v * BV - V + col 

74 b_h1 = tl.where( 

75 is_transition & (row1[:, None] == transition_col[None, :]), 1.0, 0.0 

76 ).to(tl.float32) 

77 b_h2 = tl.where( 

78 is_transition & (row2[:, None] == transition_col[None, :]), 1.0, 0.0 

79 ).to(tl.float32) 

80 

81 for i_t in range(NT): 

82 p_w1 = tl.make_block_ptr( 

83 w, (T, K), (stride_k, 1), (i_t * BT, 0), (BT, 64), (1, 0) 

84 ) 

85 p_w2 = tl.make_block_ptr( 

86 w, (T, K), (stride_k, 1), (i_t * BT, 64), (BT, 64), (1, 0) 

87 ) 

88 b_w1 = tl.load(p_w1, boundary_check=(0, 1)) 

89 b_w2 = tl.load(p_w2, boundary_check=(0, 1)) 

90 b_v = tl.dot(b_w1, b_h1.to(b_w1.dtype)) 

91 b_v += tl.dot(b_w2, b_h2.to(b_w2.dtype)) 

92 

93 p_u = tl.make_block_ptr( 

94 u, 

95 (T, V), 

96 (stride_v, 1), 

97 (i_t * BT, i_v * BV), 

98 (BT, BV), 

99 (1, 0), 

100 ) 

101 b_v = tl.load(p_u, boundary_check=(0, 1)) - b_v 

102 

103 last_idx = min((i_t + 1) * BT, T) - 1 

104 token = i_t * BT + tl.arange(0, BT) 

105 mask = token < T 

106 b_g_last = tl.load(g + last_idx * H).to(tl.float32) 

107 b_g = tl.load(g + token * H, mask=mask, other=0.0).to(tl.float32) 

108 b_v *= tl.where(mask, tl.exp(b_g_last - b_g), 0.0)[:, None] 

109 decay = tl.exp(b_g_last) 

110 b_h1 *= decay 

111 b_h2 *= decay 

112 b_v = b_v.to(k.dtype.element_ty) 

113 

114 p_k1 = tl.make_block_ptr( 

115 k, (K, T), (1, stride_k), (0, i_t * BT), (64, BT), (0, 1) 

116 ) 

117 p_k2 = tl.make_block_ptr( 

118 k, (K, T), (1, stride_k), (64, i_t * BT), (64, BT), (0, 1) 

119 ) 

120 b_h1 += tl.dot(tl.load(p_k1, boundary_check=(0, 1)), b_v) 

121 b_h2 += tl.dot(tl.load(p_k2, boundary_check=(0, 1)), b_v) 

122 

123 p_out1 = tl.make_block_ptr( 

124 packed_summary, 

125 (K, V + K), 

126 (V + K, 1), 

127 (0, i_v * BV), 

128 (64, BV), 

129 (1, 0), 

130 ) 

131 p_out2 = tl.make_block_ptr( 

132 packed_summary, 

133 (K, V + K), 

134 (V + K, 1), 

135 (64, i_v * BV), 

136 (64, BV), 

137 (1, 0), 

138 ) 

139 tl.store(p_out1, b_h1, boundary_check=(0, 1)) 

140 tl.store(p_out2, b_h2, boundary_check=(0, 1)) 

141 

142 

143@triton.autotune( 

144 configs=get_autotune_config( 

145 multibuffer_list=(True, False), 

146 set_workspace_multibuffer_list=(2, 4), 

147 tile_mix_vector_loop_num_list=(2,), 

148 tile_mix_cube_loop_num_list=(2,), 

149 ), 

150 key=["H", "K", "V", "BT"], 

151) 

152@triton.jit(do_not_specialize=["T"]) 

153def gdn_state_grad_ext_kernel( 

154 q, 

155 k, 

156 w, 

157 g, 

158 do, 

159 dv, 

160 grad_state_ext, 

161 scale, 

162 T, 

163 H: tl.constexpr, 

164 K: tl.constexpr, 

165 V: tl.constexpr, 

166 BT: tl.constexpr, 

167 BV: tl.constexpr, 

168 NT: tl.constexpr, 

169): 

170 """Build the local-loss contribution to the incoming state gradient.""" 

171 i_v = tl.program_id(0) 

172 i_bh = tl.program_id(1) 

173 i_b = i_bh // H 

174 i_h = i_bh % H 

175 

176 stride_k = H * K 

177 stride_v = H * V 

178 q += (i_b * T * H + i_h) * K 

179 k += (i_b * T * H + i_h) * K 

180 w += (i_b * T * H + i_h) * K 

181 g += i_b * T * H + i_h 

182 do += (i_b * T * H + i_h) * V 

183 dv += (i_b * T * H + i_h) * V 

184 grad_state_ext += i_bh * K * V 

185 

186 b_dh1 = tl.zeros([64, BV], dtype=tl.float32) 

187 b_dh2 = tl.zeros([64, BV], dtype=tl.float32) 

188 

189 for reverse_idx in range(NT): 

190 i_t = NT - 1 - reverse_idx 

191 last_idx = min((i_t + 1) * BT, T) - 1 

192 token = i_t * BT + tl.arange(0, BT) 

193 mask = token < T 

194 b_g_last = tl.load(g + last_idx * H).to(tl.float32) 

195 b_g = tl.load(g + token * H, mask=mask, other=0.0).to(tl.float32) 

196 

197 p_k1 = tl.make_block_ptr( 

198 k, (T, K), (stride_k, 1), (i_t * BT, 0), (BT, 64), (1, 0) 

199 ) 

200 p_k2 = tl.make_block_ptr( 

201 k, (T, K), (stride_k, 1), (i_t * BT, 64), (BT, 64), (1, 0) 

202 ) 

203 b_k1 = tl.load(p_k1, boundary_check=(0, 1)) 

204 b_k2 = tl.load(p_k2, boundary_check=(0, 1)) 

205 b_dv = tl.dot(b_k1, b_dh1.to(b_k1.dtype)) 

206 b_dv += tl.dot(b_k2, b_dh2.to(b_k2.dtype)) 

207 b_dv *= tl.where(mask, tl.exp(b_g_last - b_g), 0.0)[:, None] 

208 

209 p_dv = tl.make_block_ptr( 

210 dv, 

211 (T, V), 

212 (stride_v, 1), 

213 (i_t * BT, i_v * BV), 

214 (BT, BV), 

215 (1, 0), 

216 ) 

217 b_dv += tl.load(p_dv, boundary_check=(0, 1)) 

218 

219 p_do = tl.make_block_ptr( 

220 do, 

221 (T, V), 

222 (stride_v, 1), 

223 (i_t * BT, i_v * BV), 

224 (BT, BV), 

225 (1, 0), 

226 ) 

227 b_do = tl.load(p_do, boundary_check=(0, 1)) 

228 decay = tl.exp(b_g_last) 

229 b_dh1 *= decay 

230 b_dh2 *= decay 

231 

232 p_q1 = tl.make_block_ptr( 

233 q, (K, T), (1, stride_k), (0, i_t * BT), (64, BT), (0, 1) 

234 ) 

235 p_q2 = tl.make_block_ptr( 

236 q, (K, T), (1, stride_k), (64, i_t * BT), (64, BT), (0, 1) 

237 ) 

238 p_w1 = tl.make_block_ptr( 

239 w, (K, T), (1, stride_k), (0, i_t * BT), (64, BT), (0, 1) 

240 ) 

241 p_w2 = tl.make_block_ptr( 

242 w, (K, T), (1, stride_k), (64, i_t * BT), (64, BT), (0, 1) 

243 ) 

244 b_q1 = tl.load(p_q1, boundary_check=(0, 1)) 

245 b_q2 = tl.load(p_q2, boundary_check=(0, 1)) 

246 b_w1 = tl.load(p_w1, boundary_check=(0, 1)) 

247 b_w2 = tl.load(p_w2, boundary_check=(0, 1)) 

248 gate = tl.exp(b_g)[None, :] 

249 b_q1 *= gate 

250 b_q2 *= gate 

251 b_dh1 += tl.dot(b_q1, b_do.to(b_q1.dtype)) * scale 

252 b_dh1 -= tl.dot(b_w1, b_dv.to(b_w1.dtype)) 

253 b_dh2 += tl.dot(b_q2, b_do.to(b_q2.dtype)) * scale 

254 b_dh2 -= tl.dot(b_w2, b_dv.to(b_w2.dtype)) 

255 

256 p_out1 = tl.make_block_ptr( 

257 grad_state_ext, (K, V), (V, 1), (0, i_v * BV), (64, BV), (1, 0) 

258 ) 

259 p_out2 = tl.make_block_ptr( 

260 grad_state_ext, (K, V), (V, 1), (64, i_v * BV), (64, BV), (1, 0) 

261 ) 

262 tl.store(p_out1, b_dh1, boundary_check=(0, 1)) 

263 tl.store(p_out2, b_dh2, boundary_check=(0, 1))