docstr: morton3D, CUDA implementation
  Args:
      coords: [N, 3], int32, in [0, 128) (for some reason there is no uint32 tensor in torch...)
      TODO: check if the coord range is valid! (current 128 is safe)
  Returns:
      indices: [N], int32, in [0, 128^3)
docstr_tok: ["morton3D",",","CUDA","implementation","Args",":","coords",":","[","N",",","3","]",",","int32",",","in","[","0",",","128",")","(","for","some","reason","there","is","no","uint32","tensor","in","torch","...",")","TODO",":","check","if","the","coord","range","is","valid","!","(","current","128","is","safe",")","Returns",":","indices",":","[","N","]",",","int32",",","in","[","0",",","128^3",")"]
code: def forward(ctx, coords):
      """morton3D, CUDA implementation
      Args:
          coords: [N, 3], int32, in [0, 128) (for some reason there is no uint32 tensor in torch...)
          TODO: check if the coord range is valid! (current 128 is safe)
      Returns:
          indices: [N], int32, in [0, 128^3)
  
      """
      if not coords.is_cuda:
          coords = coords.cuda()
  
      N = coords.shape[0]
  
      indices = torch.empty(N, dtype=torch.int32, device=coords.device)
  
      get_backend().morton3D(coords.int(), N, indices)
  
      return indices
  
imports: import torch
  from torch.autograd import Function
  from torch.cuda.amp import custom_bwd, custom_fwd
label_desc: Use image node_id 1 for calling the _morton3D obj's underlying member method code with example usage: obj.forward(ctx, coords) and returns: indices