class_docstr: Like :class:`Trace_ELBO` but uses :func:`pyro.ops.jit.compile` to compile
  :meth:`loss_and_grads`.
  
  This works only for a limited set of models:
  
  -   Models must have static structure.
  -   Models must not depend on any global data (except the param store).
  -   All model inputs that are tensors must be passed in via ``*args``.
  -   All model inputs that are *not* tensors must be passed in via
      ``**kwargs``, and compilation will be triggered once per unique
      ``**kwargs``.
class_docstr_tok: ["Like",":","class",":","`","Trace_ELBO","`","but","uses",":","func",":","`","pyro.ops.jit.compile","`","to","compile",":","meth",":","`","loss_and_grads","`",".","This","works","only","for","a","limited","set","of","models",":","-","Models","must","have","static","structure",".","-","Models","must","not","depend","on","any","global","data","(","except","the","param","store",")",".","-","All","model","inputs","that","are","tensors","must","be","passed","in","via","``","*","args","``",".","-","All","model","inputs","that","are","*","not","*","tensors","must","be","passed","in","via","``","*","*","kwargs","``",",","and","compilation","will","be","triggered","once","per","unique","``","*","*","kwargs","``","."]
code: def loss_and_surrogate_loss(self, model, guide, *args, **kwargs):
      kwargs["_pyro_model_id"] = id(model)
      kwargs["_pyro_guide_id"] = id(guide)
      if getattr(self, "_loss_and_surrogate_loss", None) is None:
          # build a closure for loss_and_surrogate_loss
          weakself = weakref.ref(self)
  
          @pyro.ops.jit.trace(
              ignore_warnings=self.ignore_jit_warnings,
              jit_options=self.jit_options,
          )
          def loss_and_surrogate_loss(*args, **kwargs):
              kwargs.pop("_pyro_model_id")
              kwargs.pop("_pyro_guide_id")
              self = weakself()
              loss = 0.0
              surrogate_loss = 0.0
              for model_trace, guide_trace in self._get_traces(
                  model, guide, args, kwargs
              ):
                  elbo_particle = 0
                  surrogate_elbo_particle = 0
                  log_r = None
  
                  # compute elbo and surrogate elbo
                  for name, site in model_trace.nodes.items():
                      if site["type"] == "sample":
                          elbo_particle = (
                              elbo_particle + site["log_prob_sum"]
                          )
                          surrogate_elbo_particle = (
                              surrogate_elbo_particle
                              + site["log_prob_sum"]
                          )
  
                  for name, site in guide_trace.nodes.items():
                      if site["type"] == "sample":
                          (
                              log_prob,
                              score_function_term,
                              entropy_term,
                          ) = site["score_parts"]
  
                          elbo_particle = (
                              elbo_particle - site["log_prob_sum"]
                          )
  
                          if not is_identically_zero(entropy_term):
                              surrogate_elbo_particle = (
                                  surrogate_elbo_particle
                                  - entropy_term.sum()
                              )
  
                          if not is_identically_zero(
                              score_function_term
                          ):
                              if log_r is None:
                                  log_r = _compute_log_r(
                                      model_trace, guide_trace
                                  )
                              site = log_r.sum_to(
                                  site["cond_indep_stack"]
                              )
                              surrogate_elbo_particle = (
                                  surrogate_elbo_particle
                                  + (site * score_function_term).sum()
                              )
  
                  loss = loss - elbo_particle / self.num_particles
                  surrogate_loss = (
                      surrogate_loss
                      - surrogate_elbo_particle / self.num_particles
                  )
  
              return loss, surrogate_loss
  
          self._loss_and_surrogate_loss = loss_and_surrogate_loss
  
      return self._loss_and_surrogate_loss(*args, **kwargs)
  
imports: import weakref
  import pyro
  import pyro.ops.jit
  from pyro.distributions.util import is_identically_zero
  from pyro.infer.elbo import ELBO
  from pyro.infer.enum import get_importance_trace
  from pyro.infer.util import MultiFrameTensor, get_plate_stacks, is_validation_enabled, torch_item
  from pyro.util import check_if_enumerated, warn_if_nan
label_desc: Use image node_id 1 for calling the JitTrace_ELBO obj's underlying member method code with example usage: obj.loss_and_surrogate_loss(model, guide) and returns: self, loss,  surrogate_loss