class_docstr: Abstract base class for models based on multi-output GPyTorch models.
  
  This is meant to be used with a gpytorch ModelList wrapper for independent
  evaluation of submodels. Those submodels can themselves be multi-output
  models, in which case the task covariances will be ignored.
  
  :meta private:
class_docstr_tok: ["Abstract","base","class","for","models","based","on","multi-output","GPyTorch","models",".","This","is","meant","to","be","used","with","a","gpytorch","ModelList","wrapper","for","independent","evaluation","of","submodels",".","Those","submodels","can","themselves","be","multi-output","models",",","in","which","case","the","task","covariances","will","be","ignored",".",":","meta","private",":"]
docstr: The batch shape of the model.
  
  This is a batch shape from an I/O perspective, independent of the internal
  representation of the model (as e.g. in BatchedMultiOutputGPyTorchModel).
  For a model with `m` outputs, a `test_batch_shape x q x d`-shaped input `X`
  to the `posterior` method returns a Posterior object over an output of
  shape `broadcast(test_batch_shape, model.batch_shape) x q x m`.
docstr_tok: ["The","batch","shape","of","the","model",".","This","is","a","batch","shape","from","an","I\/O","perspective",",","independent","of","the","internal","representation","of","the","model","(","as","e.g",".","in","BatchedMultiOutputGPyTorchModel",")",".","For","a","model","with","`","m","`","outputs",",","a","`","test_batch_shape","x","q","x","d","`","-shaped","input","`","X","`","to","the","`","posterior","`","method","returns","a","Posterior","object","over","an","output","of","shape","`","broadcast","(","test_batch_shape",",","model.batch_shape",")","x","q","x","m","`","."]
code: def batch_shape(self) -> torch.Size:
      r"""The batch shape of the model.
  
      This is a batch shape from an I/O perspective, independent of the internal
      representation of the model (as e.g. in BatchedMultiOutputGPyTorchModel).
      For a model with `m` outputs, a `test_batch_shape x q x d`-shaped input `X`
      to the `posterior` method returns a Posterior object over an output of
      shape `broadcast(test_batch_shape, model.batch_shape) x q x m`.
      """
      batch_shapes = {m.batch_shape for m in self.models}
      if len(batch_shapes) > 1:
          msg = (
              f"Component models of {self.__class__.__name__} have different "
              "batch shapes"
          )
          try:
              broadcast_shape = torch.broadcast_shapes(*batch_shapes)
              warnings.warn(
                  msg + ". Broadcasting batch shapes.", stacklevel=2
              )
              return broadcast_shape
          except RuntimeError:
              raise NotImplementedError(
                  msg + " that are not broadcastble."
              )
      return next(iter(batch_shapes))
  
imports: from __future__ import annotations
  import itertools
  import warnings
  from abc import ABC
  from copy import deepcopy
  from typing import Any, List, Optional, Tuple, TYPE_CHECKING, Union
  import torch
  from botorch.acquisition.objective import PosteriorTransform
  from botorch.exceptions.errors import BotorchTensorDimensionError, InputDataError
  from botorch.exceptions.warnings import _get_single_precision_warning, BotorchTensorDimensionWarning
  from botorch.models.model import Model, ModelList
  from botorch.models.utils import _make_X_full, add_output_dim, gpt_posterior_settings, mod_batch_shape, multioutput_to_batch_mode_transform
  from botorch.posteriors.fully_bayesian import GaussianMixturePosterior
  from botorch.posteriors.gpytorch import GPyTorchPosterior
  from botorch.utils.multitask import separate_mtmvn
  from botorch.utils.transforms import is_ensemble
  from gpytorch.distributions import MultitaskMultivariateNormal, MultivariateNormal
  from gpytorch.likelihoods.gaussian_likelihood import FixedNoiseGaussianLikelihood
  from linear_operator.operators import BlockDiagLinearOperator, CatLinearOperator
  from torch import Tensor
label_desc: Use image node_id 1 for calling the ModelListGPyTorchModel obj's underlying member method code with example usage: obj.batch_shape() and returns: next, broadcast_shape