docstr: Feeds PastCovariatesTorchModel with input and output chunks of a PastCovariatesSequentialDataset to forecast
  the next ``n`` target values per target variable.
  
  Parameters:
  ----------
  n
      prediction length
  input_batch
      ``(past_target, past_covariates, future_past_covariates, static_covariates)``
  roll_size
      roll input arrays after every sequence by ``roll_size``. Initially, ``roll_size`` is equivalent to
      ``self.output_chunk_length``
docstr_tok: ["Feeds","PastCovariatesTorchModel","with","input","and","output","chunks","of","a","PastCovariatesSequentialDataset","to","forecast","the","next","``","n","``","target","values","per","target","variable",".","Parameters",":","--","--","--","--","--","n","prediction","length","input_batch","``","(","past_target",",","past_covariates",",","future_past_covariates",",","static_covariates",")","``","roll_size","roll","input","arrays","after","every","sequence","by","``","roll_size","``",".","Initially",",","``","roll_size","``","is","equivalent","to","``","self.output_chunk_length","``"]
code: def _get_batch_prediction(
      self, n: int, input_batch: Tuple, roll_size: int
  ) -> torch.Tensor:
      """
      Feeds PastCovariatesTorchModel with input and output chunks of a PastCovariatesSequentialDataset to forecast
      the next ``n`` target values per target variable.
  
      Parameters:
      ----------
      n
          prediction length
      input_batch
          ``(past_target, past_covariates, future_past_covariates, static_covariates)``
      roll_size
          roll input arrays after every sequence by ``roll_size``. Initially, ``roll_size`` is equivalent to
          ``self.output_chunk_length``
      """
      dim_component = 2
      (
          past_target,
          past_covariates,
          future_past_covariates,
          static_covariates,
      ) = input_batch
  
      n_targets = past_target.shape[dim_component]
      n_past_covs = (
          past_covariates.shape[dim_component]
          if past_covariates is not None
          else 0
      )
  
      input_past = torch.cat(
          [
              ds
              for ds in [past_target, past_covariates]
              if ds is not None
          ],
          dim=dim_component,
      )
  
      out = self._produce_predict_output(
          x=(input_past, static_covariates)
      )[:, self.first_prediction_index :, :]
  
      batch_prediction = [out[:, :roll_size, :]]
      prediction_length = roll_size
  
      while prediction_length < n:
          # we want the last prediction to end exactly at `n` into the future.
          # this means we may have to truncate the previous prediction and step
          # back the roll size for the last chunk
          if prediction_length + self.output_chunk_length > n:
              spillover_prediction_length = (
                  prediction_length + self.output_chunk_length - n
              )
              roll_size -= spillover_prediction_length
              prediction_length -= spillover_prediction_length
              batch_prediction[-1] = batch_prediction[-1][
                  :, :roll_size, :
              ]
  
          # ==========> PAST INPUT <==========
          # roll over input series to contain the latest target and covariates
          input_past = torch.roll(input_past, -roll_size, 1)
  
          # update target input to include next `roll_size` predictions
          if self.input_chunk_length >= roll_size:
              input_past[:, -roll_size:, :n_targets] = out[
                  :, :roll_size, :
              ]
          else:
              input_past[:, :, :n_targets] = out[
                  :, -self.input_chunk_length :, :
              ]
  
          # set left and right boundaries for extracting future elements
          if self.input_chunk_length >= roll_size:
              left_past, right_past = (
                  prediction_length - roll_size,
                  prediction_length,
              )
          else:
              left_past, right_past = (
                  prediction_length - self.input_chunk_length,
                  prediction_length,
              )
  
          # update past covariates to include next `roll_size` future past covariates elements
          if n_past_covs and self.input_chunk_length >= roll_size:
              input_past[
                  :, -roll_size:, n_targets : n_targets + n_past_covs
              ] = future_past_covariates[:, left_past:right_past, :]
          elif n_past_covs:
              input_past[
                  :, :, n_targets : n_targets + n_past_covs
              ] = future_past_covariates[:, left_past:right_past, :]
  
          # take only last part of the output sequence where needed
          out = self._produce_predict_output(
              x=(input_past, static_covariates)
          )[:, self.first_prediction_index :, :]
  
          batch_prediction.append(out)
          prediction_length += self.output_chunk_length
  
      # bring predictions into desired format and drop unnecessary values
      batch_prediction = torch.cat(batch_prediction, dim=1)
      batch_prediction = batch_prediction[:, :n, :]
      return batch_prediction
  
imports: from abc import ABC, abstractmethod
  from functools import wraps
  from typing import Any, Dict, Optional, Sequence, Tuple, Union
  import pytorch_lightning
  import torch
  import torch.nn
  import torchmetrics
  from joblib import Parallel, delayed
  from darts.logging import get_logger, raise_if, raise_log
  from darts.models.components.layer_norm_variants import RINorm
  from darts.timeseries import TimeSeries
  from darts.utils.likelihood_models import Likelihood
  from darts.utils.timeseries_generation import _build_forecast_series
  from darts.utils.torch import MonteCarloDropout
label_desc: Use image node_id 2 for calling the PLPastCovariatesModule obj's underlying member method code with example usage: obj._get_batch_prediction(n, input_batch, roll_size) and returns: batch_prediction