@@ -110,7 +110,7 @@ class _LinearGatedUntunedOps:
110110
111111
112112class _LinearGatedConcatOps (_LinearGatedOps ):
113- matmul_fwd_fn = partial (gemm_gated , concat_layout = ("B" ,))
113+ matmul_fwd_fn = partial (gemm_gated , concat_layout = ("B" , "bias" ))
114114 matmul_bwd_dx = partial (gemm , dynamic_scheduler = True , concat_layout = ("B" ,))
115115 matmul_bwd_dw = partial (gemm , dynamic_scheduler = True , concat_layout = ("out" ,))
116116 matmul_bwd_dw_inplace = partial (
@@ -119,7 +119,7 @@ class _LinearGatedConcatOps(_LinearGatedOps):
119119
120120
121121class _LinearGatedConcatUntunedOps (_LinearGatedUntunedOps ):
122- matmul_fwd_fn = partial (gemm_gated , tuned = False , concat_layout = ("B" ,))
122+ matmul_fwd_fn = partial (gemm_gated , tuned = False , concat_layout = ("B" , "bias" ))
123123 matmul_bwd_dx = partial (gemm , dynamic_scheduler = True , tuned = False , concat_layout = ("B" ,))
124124 matmul_bwd_dw = partial (gemm , dynamic_scheduler = True , tuned = False , concat_layout = ("out" ,))
125125 matmul_bwd_dw_inplace = partial (
@@ -274,10 +274,11 @@ def linear_gated_func(
274274
275275class DActLinearFunc (torch .autograd .Function ):
276276 @staticmethod
277- def forward (ctx , preact , weight , x , activation , fuse_grad_accum , ops ):
277+ def forward (ctx , preact , weight , x , activation , bias , fuse_grad_accum , ops ):
278278 """
279279 x: (..., in_features)
280280 weight: (out_features, in_features)
281+ bias: (out_features,) or None
281282 out: (..., out_features)
282283 Takes in an extra preact argument which is the pre-activation, to be used in the backward pass.
283284 """
@@ -289,7 +290,7 @@ def forward(ctx, preact, weight, x, activation, fuse_grad_accum, ops):
289290 weight_og = weight
290291 batch_shape = x .shape [:- 1 ]
291292 x = x .reshape (- 1 , x .shape [- 1 ])
292- out = ops .matmul_fwd_fn (x , weight .T )
293+ out = ops .matmul_fwd_fn (x , weight .T , bias = bias )
293294 # Store preact instead of x, we will recompute x (postact) in backward.
294295 # dpreact needs gemm_dact(dout, weight, preact) → needs both weight and preact.
295296 # dweight needs postact: if dpreact is also needed, postact comes from gemm_dact;
@@ -300,6 +301,8 @@ def forward(ctx, preact, weight, x, activation, fuse_grad_accum, ops):
300301 ctx , preact , weight , weight_og , needs_x_w_grad = (need_weight , need_preact )
301302 )
302303 ctx .activation = activation
304+ ctx .bias_dtype = bias .dtype if bias is not None else None
305+ ctx .compute_dbias = bias is not None and ctx .needs_input_grad [4 ]
303306 return out .reshape (* batch_shape , out .shape [- 1 ])
304307
305308 @staticmethod
@@ -313,6 +316,7 @@ def backward(ctx, dout):
313316 preact , weight , weight_og = ctx .saved_tensors
314317 batch_shape = dout .shape [:- 1 ]
315318 dout = _ensure_contiguous (dout .reshape (- 1 , dout .shape [- 1 ]))
319+ dbias = dout .sum (0 , dtype = ctx .bias_dtype ) if ctx .compute_dbias else None
316320 if ctx .needs_input_grad [0 ]:
317321 # Need dpreact: gemm_dact(dout, weight, preact) → (dpreact, postact)
318322 preact = preact .reshape (- 1 , preact .shape [- 1 ])
@@ -331,17 +335,17 @@ def backward(ctx, dout):
331335 dweight = linear_bwd_compute_weight_grad (
332336 ctx , dout , x , weight_og , ops .matmul_bwd_dw , ops .matmul_bwd_dw_inplace
333337 )
334- return dpreact , dweight , None , None , None , None
338+ return dpreact , dweight , None , None , dbias , None , None
335339
336340
337- def act_linear_func (preact , weight , x , activation , fuse_grad_accum = False , tuned = True ):
341+ def act_linear_func (preact , weight , x , activation , bias = None , fuse_grad_accum = False , tuned = True ):
338342 ops = _DActLinearOps if tuned else _DActLinearUntunedOps
339- return DActLinearFunc .apply (preact , weight , x , activation , fuse_grad_accum , ops )
343+ return DActLinearFunc .apply (preact , weight , x , activation , bias , fuse_grad_accum , ops )
340344
341345
342- def gated_linear_func (preact , weight , x , activation , fuse_grad_accum = False , tuned = True ):
346+ def gated_linear_func (preact , weight , x , activation , bias = None , fuse_grad_accum = False , tuned = True ):
343347 ops = _DGatedLinearOps if tuned else _DGatedLinearUntunedOps
344- return DActLinearFunc .apply (preact , weight , x , activation , fuse_grad_accum , ops )
348+ return DActLinearFunc .apply (preact , weight , x , activation , bias , fuse_grad_accum , ops )
345349
346350
347351class Linear (nn .Linear ):
0 commit comments