| 80 | grouping = Grouping.apply |
| 81 | |
| 82 | class AttentionStep1(Function): |
| 83 | @staticmethod |
| 84 | def forward(ctx, q, k, index0, index1): |
| 85 | """ |
| 86 | input: q: (N, h, C//h), k: (N, h, C//h), index0: (M), index1: (M) |
| 87 | output: output: [N, h, C//h] |
| 88 | """ |
| 89 | assert q.is_contiguous() and k.is_contiguous() and index0.is_contiguous() and index1.is_contiguous() |
| 90 | |
| 91 | N_q, h, C_div_h = q.shape |
| 92 | N_k = k.shape[0] |
| 93 | M = index0.shape[0] |
| 94 | C = int(C_div_h * h) |
| 95 | |
| 96 | output = torch.cuda.FloatTensor(M, h).zero_() |
| 97 | pointops_cuda.attention_step1_forward_cuda(N_k, M, h, C, q, k, index0, index1, output) |
| 98 | ctx.N_q = N_q |
| 99 | ctx.N_k = N_k |
| 100 | ctx.C = C |
| 101 | ctx.save_for_backward(q, k, index0, index1) |
| 102 | return output |
| 103 | |
| 104 | @staticmethod |
| 105 | def backward(ctx, grad_output): |
| 106 | """ |
| 107 | input: grad_output: (N, h, C//h) |
| 108 | output: (M, h), (N, h, C//h), None, None |
| 109 | """ |
| 110 | |
| 111 | N_q = ctx.N_q |
| 112 | N_k = ctx.N_k |
| 113 | C = ctx.C |
| 114 | q, k, index0, index1 = ctx.saved_tensors |
| 115 | M, h = grad_output.shape |
| 116 | |
| 117 | grad_output = grad_output.contiguous() |
| 118 | # print("grad_output.is_contiguous(): ", grad_output.is_contiguous()) |
| 119 | assert q.is_contiguous() and k.is_contiguous() and index0.is_contiguous() and index1.is_contiguous() and grad_output.is_contiguous() |
| 120 | |
| 121 | # print("back: attn[:5,:5]: ", attn[:5, :5]) |
| 122 | |
| 123 | # print("attn.shape: {} v.shape: {}, index0.shape: {}, index1.shape: {}".format(attn.shape, v.shape, index0.shape, index1.shape)) |
| 124 | |
| 125 | grad_q = torch.cuda.FloatTensor(N_q, h, C//h).zero_() |
| 126 | grad_k = torch.cuda.FloatTensor(N_k, h, C//h).zero_() |
| 127 | |
| 128 | # torch.cuda.synchronize() |
| 129 | # start = time.time() |
| 130 | |
| 131 | pointops_cuda.attention_step1_backward_cuda(N_q, M, h, C, grad_output, index0, index1, q, k, grad_q, grad_k) |
| 132 | |
| 133 | # torch.cuda.synchronize() |
| 134 | # end = time.time() |
| 135 | # print("time v7: {}".format(end - start)) |
| 136 | # # input() |
| 137 | |
| 138 | return grad_q, grad_k, None, None |
| 139 |
nothing calls this directly
no outgoing calls
no test coverage detected