@triton.jit
def mlstm_matmul_kernel_backward_db(dH, Q, K, V, F, I, M, B, dB, NH: tl.
    constexpr, S: tl.constexpr, D: tl.constexpr, SB: tl.constexpr):
    bh_id = tl.program_id(0)
    sb_id = tl.program_id(1)
    batch_id = bh_id // NH
    head_id = bh_id % NH
    batch_offset_dh = batch_id * NH * S * D + head_id * S * D
    batch_offset_f = batch_id * NH * S + head_id * S
    offset_dh = tl.arange(0, SB) + sb_id * SB
    offset_vk = tl.arange(0, SB) + sb_id * SB
    d_range = tl.arange(0, D)
    dh_range = batch_offset_dh + offset_dh[:, None] * D + d_range[None, :]
    dh_mask = (offset_dh[:, None] < S) & (d_range[None, :] < D)
    dh = tl.load(dH + dh_range, dh_mask)
    q = tl.load(Q + dh_range, dh_mask)
    m = tl.load(M + batch_offset_f + offset_dh, offset_dh < S)
    f = tl.load(F + batch_offset_f + offset_dh, offset_dh < S)
    f = tl.cumsum(tl.log(tl.sigmoid(f)))
    scale = tl.sqrt(tl.full((1,), D, dtype=tl.float32))
    dn_acc = tl.zeros((SB,), dtype=tl.float32)
    for j in range(sb_id, -1, -1):
        vk_range = batch_offset_dh + offset_vk[:, None] * D + d_range[None, :]
        vk_mask = (offset_vk[:, None] < S) & (d_range[None, :] < D)
        v = tl.load(V + vk_range, vk_mask)
        f_next = tl.load(F + batch_offset_f + offset_vk, offset_vk < S)
        i = tl.load(I + batch_offset_f + offset_vk, offset_vk < S)
        f_next = tl.log(tl.sigmoid(f_next))
        if j == sb_id:
            f_next = tl.cumsum(f_next)
            d = f[:, None] - f_next[None, :] + i[None, :]
            mask = offset_dh[:, None] >= offset_vk[None, :]
            d = tl.where(mask, d, -float('inf'))
        else:
            f += tl.sum(f_next)
            f_next = tl.cumsum(f_next)
            d = f[:, None] - f_next[None, :] + i[None, :]
        d = tl.exp(d - m[:, None])
        dc = matrix_mult(dh, tl.trans(v), SB)
        k = tl.load(K + vk_range, vk_mask) / scale
        c_tilde = matrix_mult(q, tl.trans(k), SB) * d
        dn_acc += tl.sum(c_tilde * dc, 1)
        offset_vk -= SB
    b = tl.load(B + batch_offset_f + offset_dh, offset_dh < S)
    n = tl.maximum(tl.abs(b), tl.exp(-m)) + 1e-06
    dn = -dn_acc * (1 / tl.exp(tl.log(n) * 2.0))
    db = sign(b) * dn * tl.where(tl.abs(b) > tl.exp(-m), 1.0, 0.0)
    tl.store(dB + batch_offset_f + offset_dh, db, offset_dh < S)
