input: attn: (M, h), v: (N, h, C//h), index0: (M), index1: (M) output: output: [N, h, C//h]
(ctx, attn, v, index0, index1)
| 207 | class AttentionStep2(Function): |
| 208 | @staticmethod |
| 209 | def forward(ctx, attn, v, index0, index1): |
| 210 | """ |
| 211 | input: attn: (M, h), v: (N, h, C//h), index0: (M), index1: (M) |
| 212 | output: output: [N, h, C//h] |
| 213 | """ |
| 214 | assert attn.is_contiguous() and v.is_contiguous() and index0.is_contiguous() and index1.is_contiguous() |
| 215 | |
| 216 | M, h = attn.shape |
| 217 | N_q = index0.max().item() + 1 |
| 218 | N_v, h, C_div_h = v.shape |
| 219 | C = int(C_div_h * h) |
| 220 | |
| 221 | output = torch.cuda.FloatTensor(N_q, h, C//h).zero_() |
| 222 | pointops_cuda.attention_step2_forward_cuda(N_q, M, h, C, attn, v, index0, index1, output) |
| 223 | ctx.M = M |
| 224 | |
| 225 | # print("attn[:5,:5]: ", attn[:5, :5]) |
| 226 | |
| 227 | ctx.save_for_backward(attn, v, index0, index1) |
| 228 | return output |
| 229 | |
| 230 | @staticmethod |
| 231 | def backward(ctx, grad_output): |
nothing calls this directly
no outgoing calls
no test coverage detected