| 582 | |
| 583 | |
| 584 | class AttentionStep2WithRelPosValue_v2(Function): |
| 585 | @staticmethod |
| 586 | def forward(ctx, attn, v, index0_offsets, n_max, index1, table, rel_idx): |
| 587 | """ |
| 588 | input: attn: (M, h), v: (N, h, hdim), index0_offsets: (M), index1: (M), table: (L, h, hdim, 3), rel_idx: (M, 3) |
| 589 | output: output: [N, h, hdim] |
| 590 | """ |
| 591 | assert attn.is_contiguous() and v.is_contiguous() and index0_offsets.is_contiguous() and index1.is_contiguous() and table.is_contiguous() and rel_idx.is_contiguous() |
| 592 | |
| 593 | M, h = attn.shape |
| 594 | N, h, hdim = v.shape |
| 595 | # N_q = int(index0_offsets.max().item()) + 1 |
| 596 | |
| 597 | output = torch.cuda.FloatTensor(N, h, hdim).zero_() |
| 598 | pointops_cuda.attention_step2_with_rel_pos_value_forward_cuda_v2(N, M, h, hdim, n_max, attn, v, index0_offsets, index1, table, rel_idx, output) |
| 599 | |
| 600 | # print("attn[:5,:5]: ", attn[:5, :5]) |
| 601 | |
| 602 | ctx.n_max = n_max |
| 603 | ctx.save_for_backward(attn, v, index0_offsets, index1, table, rel_idx) |
| 604 | return output |
| 605 | |
| 606 | @staticmethod |
| 607 | def backward(ctx, grad_output): |
| 608 | """ |
| 609 | input: grad_output: (N, h, C//h) |
| 610 | output: (M, h), (N, h, C//h), None, None, (L, h, hdim, 3), None |
| 611 | """ |
| 612 | n_max = ctx.n_max |
| 613 | attn, v, index0_offsets, index1, table, rel_idx = ctx.saved_tensors |
| 614 | N, h, hdim = grad_output.shape |
| 615 | N = v.shape[0] |
| 616 | M = attn.shape[0] |
| 617 | L = table.shape[0] |
| 618 | |
| 619 | # grad_output = grad_output.contiguous() |
| 620 | # print("grad_output.is_contiguous(): ", grad_output.is_contiguous()) |
| 621 | assert attn.is_contiguous() and v.is_contiguous() and index0_offsets.is_contiguous() and index1.is_contiguous() and grad_output.is_contiguous() and table.is_contiguous() and rel_idx.is_contiguous() |
| 622 | |
| 623 | # print("back: attn[:5,:5]: ", attn[:5, :5]) |
| 624 | |
| 625 | # print("attn.shape: {} v.shape: {}, index0_offsets.shape: {}, index1.shape: {}".format(attn.shape, v.shape, index0_offsets.shape, index1.shape)) |
| 626 | |
| 627 | grad_attn = torch.cuda.FloatTensor(M, h).zero_() |
| 628 | grad_v = torch.cuda.FloatTensor(N, h, hdim).zero_() |
| 629 | grad_table = torch.cuda.FloatTensor(L, h, hdim, 3).zero_() |
| 630 | |
| 631 | # print("attn.shape: {}, grad_attn.shape: {}".format(attn.shape, grad_attn.shape)) |
| 632 | # print("v.shape: {}, grad_v.shape: {}".format(v.shape, grad_v.shape)) |
| 633 | # print("table.shape: {}, grad_table.shape: {}".format(table.shape, grad_table.shape)) |
| 634 | |
| 635 | # torch.cuda.synchronize() |
| 636 | # start = time.time() |
| 637 | |
| 638 | pointops_cuda.attention_step2_with_rel_pos_value_backward_cuda_v2(N, M, h, hdim, n_max, grad_output, index0_offsets, index1, attn, v, table, rel_idx, grad_attn, grad_v, grad_table) |
| 639 | |
| 640 | # torch.cuda.synchronize() |
| 641 | # end = time.time() |
nothing calls this directly
no outgoing calls
no test coverage detected