class_docstr: Forecaster for a :class:`ForecastingModel` using Hamiltonian Monte Carlo.
  
  On initialization, this will run :class:`~pyro.infer.mcmc.nuts.NUTS`
  sampler to get posterior samples of the model.
  
  After construction, this can be called to generate sample forecasts.
  
  :param ForecastingModel model: A forecasting model subclass instance.
  :param data: A tensor dataset with time dimension -2.
  :type data: ~torch.Tensor
  :param covariates: A tensor of covariates with time dimension -2.
      For models not using covariates, pass a shaped empty tensor
      ``torch.empty(duration, 0)``.
  :type covariates: ~torch.Tensor
  :param int num_warmup: number of MCMC warmup steps.
  :param int num_samples: number of MCMC samples.
  :param int num_chains: number of parallel MCMC chains.
  :param bool dense_mass: a flag to control whether the mass matrix is dense
      or diagonal. Defaults to False.
  :param str time_reparam: If not None (default), reparameterize all
      time-dependent variables via the Haar wavelet transform (if "haar") or
      the discrete cosine transform (if "dct").
  :param bool jit_compile: whether to use the PyTorch JIT to trace the log
      density computation, and use this optimized executable trace in the
      integrator. Defaults to False.
  :param int max_tree_depth: Max depth of the binary tree created during the
      doubling scheme of the :class:`~pyro.infer.mcmc.nuts.NUTS` sampler.
      Defaults to 10.
class_docstr_tok: ["Forecaster","for","a",":","class",":","`","ForecastingModel","`","using","Hamiltonian","Monte","Carlo",".","On","initialization",",","this","will","run",":","class",":","`","~pyro.infer.mcmc.nuts.NUTS","`","sampler","to","get","posterior","samples","of","the","model",".","After","construction",",","this","can","be","called","to","generate","sample","forecasts",".",":","param","ForecastingModel","model",":","A","forecasting","model","subclass","instance",".",":","param","data",":","A","tensor","dataset","with","time","dimension","-2.",":","type","data",":","~torch.Tensor",":","param","covariates",":","A","tensor","of","covariates","with","time","dimension","-2",".","For","models","not","using","covariates",",","pass","a","shaped","empty","tensor","``","torch.empty","(","duration",",","0",")","``",".",":","type","covariates",":","~torch.Tensor",":","param","int","num_warmup",":","number","of","MCMC","warmup","steps",".",":","param","int","num_samples",":","number","of","MCMC","samples",".",":","param","int","num_chains",":","number","of","parallel","MCMC","chains",".",":","param","bool","dense_mass",":","a","flag","to","control","whether","the","mass","matrix","is","dense","or","diagonal",".","Defaults","to","False",".",":","param","str","time_reparam",":","If","not","None","(","default",")",",","reparameterize","all","time-dependent","variables","via","the","Haar","wavelet","transform","(","if","``","haar","''",")","or","the","discrete","cosine","transform","(","if","``","dct","''",")",".",":","param","bool","jit_compile",":","whether","to","use","the","PyTorch","JIT","to","trace","the","log","density","computation",",","and","use","this","optimized","executable","trace","in","the","integrator",".","Defaults","to","False",".",":","param","int","max_tree_depth",":","Max","depth","of","the","binary","tree","created","during","the","doubling","scheme","of","the",":","class",":","`","~pyro.infer.mcmc.nuts.NUTS","`","sampler",".","Defaults","to","10","."]
code: def forward(self, data, covariates, num_samples, batch_size=None):
      assert data.size(-2) <= covariates.size(-2)
      assert isinstance(num_samples, int) and num_samples > 0
      if batch_size is not None:
          batches = []
          while num_samples > 0:
              batch = self.forward(
                  data, covariates, min(num_samples, batch_size)
              )
              batches.append(batch)
              num_samples -= batch_size
          return torch.cat(batches)
  
      assert self.max_plate_nesting >= 1
      dim = -1 - self.max_plate_nesting
  
      with torch.no_grad():
          weights = torch.ones(self._num_samples, device=data.device)
          indices = torch.multinomial(
              weights,
              num_samples,
              replacement=num_samples > self._num_samples,
          )
          for name, node in list(self._trace.nodes.items()):
              sample = self._samples[name].index_select(0, indices)
              node["value"] = sample.reshape(
                  (num_samples,)
                  + (1,) * (node["value"].dim() - sample.dim())
                  + sample.shape[1:]
              )
  
          with ExitStack() as stack:
              if data.size(-2) < covariates.size(-2):
                  stack.enter_context(
                      PrefixReplayMessenger(self._trace)
                  )
                  stack.enter_context(
                      PrefixConditionMessenger(
                          self.model._prefix_condition_data
                      )
                  )
              with pyro.plate("particles", num_samples, dim=dim):
                  return self.model(data, covariates)
  
imports: import logging
  from abc import ABCMeta, abstractmethod
  from contextlib import ExitStack
  import torch
  import torch.nn
  import pyro
  import pyro.distributions
  import pyro.poutine
  from pyro.infer import MCMC, NUTS, SVI, Trace_ELBO
  from pyro.infer.autoguide import AutoNormal, init_to_sample
  from pyro.infer.predictive import _guess_max_plate_nesting
  from pyro.nn.module import PyroModule
  from pyro.optim import DCTAdam
  from .util import MarkDCTParamMessenger, PrefixConditionMessenger, PrefixReplayMessenger, PrefixWarmStartMessenger, reshape_batch, time_reparam_dct, time_reparam_haar
label_desc: Use image node_id 3 for calling the HMCForecaster obj's underlying member method code with example usage: obj.forward(data, covariates, num_samples, batch_size) and returns: torch, self