class_docstr: Parallel version of DDIM sampler. Utilizes Parallel Sampling (https://arxiv.org/abs/2305.16317).
  It reduces the latency of a model, but the total compute cost is increased.
  
  The main three parameters that affect the performance of the algorithm are:
      Parallelism (int): Defines the maximal size of the window. That many diffusion steps can happen in
          parallel.
      Tolerance (float): Sets the maximal error tolerance defined as a ratio between drift of the trajectory
          and noise. The larger the tolerance the faster the method is. The smaller the tolerance the better
          quality output is achieved.
      Number of GPUs (int): Number of GPUs utilizing DataParallel parallelism to compute diffusion steps in
          parallel.
  
  Different combination of these parameters values can result in different latency-quality-compute trade-off.
  For more details please refer to the Parallel Sampling paper (https://arxiv.org/abs/2305.16317).
class_docstr_tok: ["Parallel","version","of","DDIM","sampler",".","Utilizes","Parallel","Sampling","(","https",":","\/\/arxiv.org\/abs\/2305.16317",")",".","It","reduces","the","latency","of","a","model",",","but","the","total","compute","cost","is","increased",".","The","main","three","parameters","that","affect","the","performance","of","the","algorithm","are",":","Parallelism","(","int",")",":","Defines","the","maximal","size","of","the","window",".","That","many","diffusion","steps","can","happen","in","parallel",".","Tolerance","(","float",")",":","Sets","the","maximal","error","tolerance","defined","as","a","ratio","between","drift","of","the","trajectory","and","noise",".","The","larger","the","tolerance","the","faster","the","method","is",".","The","smaller","the","tolerance","the","better","quality","output","is","achieved",".","Number","of","GPUs","(","int",")",":","Number","of","GPUs","utilizing","DataParallel","parallelism","to","compute","diffusion","steps","in","parallel",".","Different","combination","of","these","parameters","values","can","result","in","different","latency-quality-compute","trade-off",".","For","more","details","please","refer","to","the","Parallel","Sampling","paper","(","https",":","\/\/arxiv.org\/abs\/2305.16317",")","."]
code: def _get_x_prev(
      self,
      batch_size: int,
      steps: int,
      x: torch.tensor,
      e_t: torch.tensor,
      temperature: float,
      noise_dropout: float,
      quantize_denoised: bool,
      window_start: int,
      window_end: int,
      device: Any,
  ):
      alphas = self.ddim_alphas
      alphas_prev = self.ddim_alphas_prev
      sqrt_one_minus_alphas = self.ddim_sqrt_one_minus_alphas
      sigmas = self.ddim_sigmas
      window_size = window_end - window_start
  
      def prepare_tensor(x):
          x = torch.tensor(x, device=device).flip(dims=[0])
          x = (
              x.unsqueeze(1)
              .repeat(1, batch_size)
              .reshape(window_size, batch_size, 1, 1, 1)
          )
          return x
  
      # Select parameters corresponding to the currently considered timesteps. Note that index_end < index_start,
      # because during diffusion the time is reversed (we go from timestep step to 0)
      index_start = steps - window_start
      index_end = steps - window_end
      a_t = prepare_tensor(alphas[index_end:index_start])
      a_prev = prepare_tensor(alphas_prev[index_end:index_start])
      sigma_t = prepare_tensor(sigmas[index_end:index_start])
      sqrt_one_minus_at = prepare_tensor(
          sqrt_one_minus_alphas[index_end:index_start]
      )
  
      # Current prediction for x_0
      pred_x0 = (x - sqrt_one_minus_at * e_t) / a_t.sqrt()
      if quantize_denoised:
          pred_x0, _, *_ = self.model.first_stage_model.quantize(
              pred_x0
          )
  
      # Direction pointing to x_t
      dir_xt = (1.0 - a_prev - sigma_t**2).sqrt() * e_t
  
      noise = sigma_t * noise_like(x.shape, device) * temperature
      if noise_dropout > 0.0:
          noise = torch.nn.functional.dropout(noise, p=noise_dropout)
  
      x_prev = a_prev.sqrt() * pred_x0 + dir_xt + noise
      return x_prev
  
file_path: NeMo/nemo/collections/multimodal/models/text_to_image/stable_diffusion/samplers/para_ddim.py
imports: from typing import Any, Tuple
  import numpy
  import torch
  import torch.nn
  from tqdm import tqdm
  from nemo.collections.multimodal.models.text_to_image.stable_diffusion.samplers import Sampler
  from nemo.collections.multimodal.models.text_to_image.stable_diffusion.samplers.base_sampler import AbstractBaseSampler
  from nemo.collections.multimodal.modules.stable_diffusion.diffusionmodules.util import noise_like
label_desc: Use image node_id 4 for calling the ParaDDIMSampler obj's underlying member method code with example usage: obj._get_x_prev(batch_size, steps, x, e_t, temperature, noise_dropout, quantize_denoised, window_start, window_end, device) and returns: x_prev, x