class_docstr: Differentiable rendering function for the Pulsar renderer.
  
  Usually this will be used through the `Renderer` module, which takes care of
  setting up the buffers and putting them on the correct device. If you use
  the function directly, you will have to do this manually.
  
  The steps for this are two-fold: first, you need to create a native Renderer
  object to provide the required buffers. This is the `native_renderer` parameter
  for this function. You can create it by creating a `pytorch3d._C.PulsarRenderer`
  object (with parameters for width, height and maximum number of balls it should
  be able to render). This object by default resides on the CPU. If you want to
  shift the buffers to a different device, just assign an empty tensor on the target
  device to its property `device_tracker`.
  
  To convert camera parameters from a more convenient representation to the
  required vectors as in this function, you can use the static
  function `pytorch3d.renderer.points.pulsar.Renderer._transform_cam_params`.
  
  Args:
      * ctx: Pytorch context.
      * vert_pos: vertex positions. [Bx]Nx3 tensor of positions in 3D space.
      * vert_col: vertex colors. [Bx]NxK tensor of channels.
      * vert_rad: vertex radii. [Bx]N tensor of radiuses, >0.
      * cam_pos: camera position(s). [Bx]3 tensor in 3D coordinates.
      * pixel_0_0_center: [Bx]3 tensor center(s) of the upper left pixel(s) in
                          world coordinates.
      * pixel_vec_x: [Bx]3 tensor from one pixel center to the next in image x
                     direction in world coordinates.
      * pixel_vec_y: [Bx]3 tensor from one pixel center to the next in image y
                     direction in world coordinates.
      * focal_length: [Bx]1 tensor of focal lengths in world coordinates.
      * principal_point_offsets: [Bx]2 tensor of principal point offsets in pixels.
      * gamma: sphere transparency in [1.,1E-5], with 1 being mostly transparent.
               [Bx]1.
      * max_depth: maximum depth for spheres to render. Set this as tighly
                   as possible to have good numerical accuracy for gradients.
      * native_renderer: a `pytorch3d._C.PulsarRenderer` object.
      * min_depth: a float with the minimum depth a sphere must have to be renderer.
                   Must be 0. or > max(focal_length).
      * bg_col: K tensor with a background color to use or None (uses all ones).
      * opacity: [Bx]N tensor of opacity values in [0., 1.] or None (uses all ones).
      * percent_allowed_difference: a float in [0., 1.[ with the maximum allowed
                   difference in color space. This is used to speed up the
                   computation. Default: 0.01.
      * max_n_hits: a hard limit on the number of hits per ray. Default: max int.
      * mode: render mode in {0, 1}. 0: render an image; 1: render the hit map.
      * return_forward_info: whether to return a second map. This second map contains
          13 channels: first channel contains sm_m (the maximum exponent factor
          observed), the second sm_d (the normalization denominator, the sum of all
          coefficients), the third the maximum closest possible intersection for a
          hit. The following channels alternate with the float encoded integer index
          of a sphere and its weight. They are the five spheres with the highest
          color contribution to this pixel color, ordered descending.
  
      Returns:
          * image: [Bx]HxWxK float tensor with the resulting image.
          * forw_info: [Bx]HxWx13 float forward information as described above,
                if enabled.
class_docstr_tok: ["Differentiable","rendering","function","for","the","Pulsar","renderer",".","Usually","this","will","be","used","through","the","`","Renderer","`","module",",","which","takes","care","of","setting","up","the","buffers","and","putting","them","on","the","correct","device",".","If","you","use","the","function","directly",",","you","will","have","to","do","this","manually",".","The","steps","for","this","are","two-fold",":","first",",","you","need","to","create","a","native","Renderer","object","to","provide","the","required","buffers",".","This","is","the","`","native_renderer","`","parameter","for","this","function",".","You","can","create","it","by","creating","a","`","pytorch3d._C.PulsarRenderer","`","object","(","with","parameters","for","width",",","height","and","maximum","number","of","balls","it","should","be","able","to","render",")",".","This","object","by","default","resides","on","the","CPU",".","If","you","want","to","shift","the","buffers","to","a","different","device",",","just","assign","an","empty","tensor","on","the","target","device","to","its","property","`","device_tracker","`",".","To","convert","camera","parameters","from","a","more","convenient","representation","to","the","required","vectors","as","in","this","function",",","you","can","use","the","static","function","`","pytorch3d.renderer.points.pulsar.Renderer._transform_cam_params","`",".","Args",":","*","ctx",":","Pytorch","context",".","*","vert_pos",":","vertex","positions",".","[","Bx","]","Nx3","tensor","of","positions","in","3D","space",".","*","vert_col",":","vertex","colors",".","[","Bx","]","NxK","tensor","of","channels",".","*","vert_rad",":","vertex","radii",".","[","Bx","]","N","tensor","of","radiuses",",",">","0",".","*","cam_pos",":","camera","position","(","s",")",".","[","Bx","]","3","tensor","in","3D","coordinates",".","*","pixel_0_0_center",":","[","Bx","]","3","tensor","center","(","s",")","of","the","upper","left","pixel","(","s",")","in","world","coordinates",".","*","pixel_vec_x",":","[","Bx","]","3","tensor","from","one","pixel","center","to","the","next","in","image","x","direction","in","world","coordinates",".","*","pixel_vec_y",":","[","Bx","]","3","tensor","from","one","pixel","center","to","the","next","in","image","y","direction","in","world","coordinates",".","*","focal_length",":","[","Bx","]","1","tensor","of","focal","lengths","in","world","coordinates",".","*","principal_point_offsets",":","[","Bx","]","2","tensor","of","principal","point","offsets","in","pixels",".","*","gamma",":","sphere","transparency","in","[","1.,1E-5","]",",","with","1","being","mostly","transparent",".","[","Bx","]","1",".","*","max_depth",":","maximum","depth","for","spheres","to","render",".","Set","this","as","tighly","as","possible","to","have","good","numerical","accuracy","for","gradients",".","*","native_renderer",":","a","`","pytorch3d._C.PulsarRenderer","`","object",".","*","min_depth",":","a","float","with","the","minimum","depth","a","sphere","must","have","to","be","renderer",".","Must","be","0.","or",">","max","(","focal_length",")",".","*","bg_col",":","K","tensor","with","a","background","color","to","use","or","None","(","uses","all","ones",")",".","*","opacity",":","[","Bx","]","N","tensor","of","opacity","values","in","[","0.",",","1",".","]","or","None","(","uses","all","ones",")",".","*","percent_allowed_difference",":","a","float","in","[","0.",",","1",".","[","with","the","maximum","allowed","difference","in","color","space",".","This","is","used","to","speed","up","the","computation",".","Default",":","0.01",".","*","max_n_hits",":","a","hard","limit","on","the","number","of","hits","per","ray",".","Default",":","max","int",".","*","mode",":","render","mode","in","{","0",",","1","}",".","0",":","render","an","image",";","1",":","render","the","hit","map",".","*","return_forward_info",":","whether","to","return","a","second","map",".","This","second","map","contains","13","channels",":","first","channel","contains","sm_m","(","the","maximum","exponent","factor","observed",")",",","the","second","sm_d","(","the","normalization","denominator",",","the","sum","of","all","coefficients",")",",","the","third","the","maximum","closest","possible","intersection","for","a","hit",".","The","following","channels","alternate","with","the","float","encoded","integer","index","of","a","sphere","and","its","weight",".","They","are","the","five","spheres","with","the","highest","color","contribution","to","this","pixel","color",",","ordered","descending",".","Returns",":","*","image",":","[","Bx","]","HxWxK","float","tensor","with","the","resulting","image",".","*","forw_info",":","[","Bx","]","HxWx13","float","forward","information","as","described","above",",","if","enabled","."]
code: def backward(ctx, grad_im, *args):
      global GAMMA_WARNING_EMITTED
      (
          vert_pos,
          vert_col,
          vert_rad,
          cam_pos,
          pixel_0_0_center,
          pixel_vec_x,
          pixel_vec_y,
          focal_length,
          principal_point_offsets,
          bg_col,
          opacity,
          image,
          info,
      ) = ctx.saved_tensors
      if (
          (
              ctx.needs_input_grad[0]
              or ctx.needs_input_grad[2]
              or ctx.needs_input_grad[3]
              or ctx.needs_input_grad[4]
              or ctx.needs_input_grad[5]
              or ctx.needs_input_grad[6]
              or ctx.needs_input_grad[7]
          )
          and ctx.gamma < 1e-3
          and not GAMMA_WARNING_EMITTED
      ):
          warnings.warn(
              "Optimizing for non-color parameters and having a gamma value < 1E-3! "
              "This is probably not going to produce usable gradients."
          )
          GAMMA_WARNING_EMITTED = True
      if ctx.mode == 0:
          (
              grad_pos,
              grad_col,
              grad_rad,
              grad_cam_pos,
              grad_pixel_0_0_center,
              grad_pixel_vec_x,
              grad_pixel_vec_y,
              grad_opacity,
          ) = ctx.native_renderer.backward(
              grad_im,
              image,
              info,
              vert_pos,
              vert_col,
              vert_rad,
              cam_pos,
              pixel_0_0_center,
              pixel_vec_x,
              pixel_vec_y,
              focal_length,
              principal_point_offsets,
              ctx.gamma,
              ctx.max_depth,
              ctx.min_depth,
              bg_col,
              opacity,
              ctx.percent_allowed_difference,
              ctx.max_n_hits,
              ctx.mode,
              ctx.needs_input_grad[0],
              ctx.needs_input_grad[1],
              ctx.needs_input_grad[2],
              ctx.needs_input_grad[3]
              or ctx.needs_input_grad[4]
              or ctx.needs_input_grad[5]
              or ctx.needs_input_grad[6]
              or ctx.needs_input_grad[7],
              ctx.needs_input_grad[14],
              None,  # No debug information provided.
          )
      else:
          raise ValueError(
              "Performing a backward pass for a "
              "rendering with `mode != 0`! This is not possible."
          )
      return (
          grad_pos,
          grad_col,
          grad_rad,
          grad_cam_pos,
          grad_pixel_0_0_center,
          grad_pixel_vec_x,
          grad_pixel_vec_y,
          None,  # focal_length
          None,  # principal_point_offsets
          None,  # gamma
          None,  # max_depth
          None,  # native_renderer
          None,  # min_depth
          None,  # bg_col
          grad_opacity,
          None,  # percent_allowed_difference
          None,  # max_n_hits
          None,  # mode
          None,  # return_forward_info
      )
  
file_path: pytorch3d/pytorch3d/renderer/points/pulsar/renderer.py
imports: import logging
  import warnings
  from typing import Optional, Tuple, Union
  import torch
  from pytorch3d import _C
  from pytorch3d.transforms import axis_angle_to_matrix, rotation_6d_to_matrix
label_desc: Use image node_id 2 for calling the _Render obj's underlying member method code with example usage: obj.backward(ctx, grad_im) and returns: grad_pos,  grad_col,  grad_rad,  grad_cam_pos,  grad_pixel_0_0_center,  grad_pixel_vec_x,  grad_pixel_vec_y,  None,  None,  None,  None,  None,  None,  None,  grad_opacity,  None,  None,  None,  None