(ctx, inputs, embeddings, offsets, per_level_scale, base_resolution, calc_grad_inputs=False, gridtype=0, align_corners=False)
| 20 | @staticmethod |
| 21 | @custom_fwd |
| 22 | def forward(ctx, inputs, embeddings, offsets, per_level_scale, base_resolution, calc_grad_inputs=False, gridtype=0, align_corners=False): |
| 23 | # inputs: [B, D], float in [0, 1] |
| 24 | # embeddings: [sO, C], float |
| 25 | # offsets: [L + 1], int |
| 26 | # RETURN: [B, F], float |
| 27 | |
| 28 | inputs = inputs.contiguous() |
| 29 | |
| 30 | B, D = inputs.shape # batch size, coord dim |
| 31 | L = offsets.shape[0] - 1 # level |
| 32 | C = embeddings.shape[1] # embedding dim for each level |
| 33 | S = np.log2(per_level_scale) # resolution multiplier at each level, apply log2 for later CUDA exp2f |
| 34 | H = base_resolution # base resolution |
| 35 | |
| 36 | # manually handle autocast (only use half precision embeddings, inputs must be float for enough precision) |
| 37 | # if C % 2 != 0, force float, since half for atomicAdd is very slow. |
| 38 | if torch.is_autocast_enabled() and C % 2 == 0: |
| 39 | embeddings = embeddings.to(torch.half) |
| 40 | |
| 41 | # L first, optimize cache for cuda kernel, but needs an extra permute later |
| 42 | outputs = torch.empty(L, B, C, device=inputs.device, dtype=embeddings.dtype) |
| 43 | |
| 44 | if calc_grad_inputs: |
| 45 | dy_dx = torch.empty(B, L * D * C, device=inputs.device, dtype=embeddings.dtype) |
| 46 | else: |
| 47 | dy_dx = torch.empty(1, device=inputs.device, dtype=embeddings.dtype) # placeholder... TODO: a better way? |
| 48 | |
| 49 | _backend.grid_encode_forward(inputs, embeddings, offsets, outputs, B, D, C, L, S, H, calc_grad_inputs, dy_dx, gridtype, align_corners) |
| 50 | |
| 51 | # permute back to [B, L * C] |
| 52 | outputs = outputs.permute(1, 0, 2).reshape(B, L * C) |
| 53 | |
| 54 | ctx.save_for_backward(inputs, embeddings, offsets, dy_dx) |
| 55 | ctx.dims = [B, D, C, L, S, H, gridtype] |
| 56 | ctx.calc_grad_inputs = calc_grad_inputs |
| 57 | ctx.align_corners = align_corners |
| 58 | |
| 59 | return outputs |
| 60 | |
| 61 | @staticmethod |
| 62 | #@once_differentiable |
nothing calls this directly
no outgoing calls
no test coverage detected