class_docstr: Implements the raysampler of NeRF.
  
  Depending on the `self.training` flag, the raysampler either samples
  a chunk of random rays (`self.training==True`), or returns a subset of rays
  of the full image grid (`self.training==False`).
  The chunking of rays allows for efficient evaluation of the NeRF implicit
  surface function without encountering out-of-GPU-memory errors.
  
  Additionally, this raysampler supports pre-caching of the ray bundles
  for a set of input cameras (`self.precache_rays`).
  Pre-caching the rays before training greatly speeds-up the ensuing
  raysampling step of the training NeRF iterations.
class_docstr_tok: ["Implements","the","raysampler","of","NeRF",".","Depending","on","the","`","self.training","`","flag",",","the","raysampler","either","samples","a","chunk","of","random","rays","(","`","self.training==True","`",")",",","or","returns","a","subset","of","rays","of","the","full","image","grid","(","`","self.training==False","`",")",".","The","chunking","of","rays","allows","for","efficient","evaluation","of","the","NeRF","implicit","surface","function","without","encountering","out-of-GPU-memory","errors",".","Additionally",",","this","raysampler","supports","pre-caching","of","the","ray","bundles","for","a","set","of","input","cameras","(","`","self.precache_rays","`",")",".","Pre-caching","the","rays","before","training","greatly","speeds-up","the","ensuing","raysampling","step","of","the","training","NeRF","iterations","."]
docstr: Precaches the rays emitted from the list of cameras `cameras`,
  where each camera is uniquely identified with the corresponding hash
  from `camera_hashes`.
  
  The cached rays are moved to cpu and stored in `self._ray_cache`.
  Raises `ValueError` when caching two cameras with the same hash.
  
  Args:
      cameras: A list of `N` cameras for which the rays are pre-cached.
      camera_hashes: A list of `N` unique identifiers of each
          camera from `cameras`.
docstr_tok: ["Precaches","the","rays","emitted","from","the","list","of","cameras","`","cameras","`",",","where","each","camera","is","uniquely","identified","with","the","corresponding","hash","from","`","camera_hashes","`",".","The","cached","rays","are","moved","to","cpu","and","stored","in","`","self._ray_cache","`",".","Raises","`","ValueError","`","when","caching","two","cameras","with","the","same","hash",".","Args",":","cameras",":","A","list","of","`","N","`","cameras","for","which","the","rays","are","pre-cached",".","camera_hashes",":","A","list","of","`","N","`","unique","identifiers","of","each","camera","from","`","cameras","`","."]
code: def precache_rays(
      self, cameras: List[CamerasBase], camera_hashes: List
  ):
      """
      Precaches the rays emitted from the list of cameras `cameras`,
      where each camera is uniquely identified with the corresponding hash
      from `camera_hashes`.
  
      The cached rays are moved to cpu and stored in `self._ray_cache`.
      Raises `ValueError` when caching two cameras with the same hash.
  
      Args:
          cameras: A list of `N` cameras for which the rays are pre-cached.
          camera_hashes: A list of `N` unique identifiers of each
              camera from `cameras`.
      """
      print(f"Precaching {len(cameras)} ray bundles ...")
      full_chunksize = (
          self._grid_raysampler._xy_grid.numel()
          // 2
          * self._grid_raysampler._n_pts_per_ray
      )
      if self.get_n_chunks(full_chunksize, 1) != 1:
          raise ValueError(
              "There has to be one chunk for precaching rays!"
          )
      for camera_i, (camera, camera_hash) in enumerate(
          zip(cameras, camera_hashes)
      ):
          ray_bundle = self.forward(
              camera,
              caching=True,
              chunksize=full_chunksize,
          )
          if camera_hash in self._ray_cache:
              raise ValueError("There are redundant cameras!")
          self._ray_cache[camera_hash] = RayBundle(
              *[v.to("cpu").detach() for v in ray_bundle]
          )
          self._print_precaching_progress(camera_i, len(cameras))
      print("")
  
file_path: pytorch3d/projects/nerf/nerf/raysampler.py
imports: import math
  from typing import List
  import torch
  from pytorch3d.renderer import MonteCarloRaysampler, NDCMultinomialRaysampler, RayBundle
  from pytorch3d.renderer.cameras import CamerasBase
  from pytorch3d.renderer.implicit.sample_pdf import sample_pdf
label_desc: Use image node_id 4 for calling the NeRFRaysampler obj's underlying member method code with example usage: obj.precache_rays(cameras, camera_hashes) without return types