class_docstr: **All classes in 'botorch_modular' directory are under
  construction, incomplete, and should be treated as alpha
  versions only.**
  
  Modular `Model` class for combining BoTorch subcomponents
  in Ax. Specified via `Surrogate` and `Acquisition`, which wrap
  BoTorch `Model` and `AcquisitionFunction`, respectively, for
  convenient use in Ax.
  
  Args:
      acquisition_class: Type of `Acquisition` to be used in
          this model, auto-selected based on experiment and data
          if not specified.
      acquisition_options: Optional dict of kwargs, passed to
          the constructor of BoTorch `AcquisitionFunction`.
      botorch_acqf_class: Type of `AcquisitionFunction` to be
          used in this model, auto-selected based on experiment
          and data if not specified.
      surrogate_specs: Optional Mapping of names onto SurrogateSpecs, which specify
          how to initialize specific Surrogates to model specific outcomes. If None
          is provided a single Surrogate will be created and set up automatically
          based on the data provided.
      surrogate: In liu of SurrogateSpecs, an instance of `Surrogate` may be
          provided to be used as the sole Surrogate for all outcomes
      refit_on_update: Unused.
      refit_on_cv: Whether to reoptimize model parameters during call to
          `BoTorchmodel.cross_validate`.
      warm_start_refit: Whether to load parameters from either the provided
          state dict or the state dict of the current BoTorch `Model` during
          refitting. If False, model parameters will be reoptimized from
          scratch on refit. NOTE: This setting is ignored during
          `cross_validate` if the corresponding `refit_on_...` is False.
class_docstr_tok: ["*","*","All","classes","in","'botorch_modular","'","directory","are","under","construction",",","incomplete",",","and","should","be","treated","as","alpha","versions","only",".","*","*","Modular","`","Model","`","class","for","combining","BoTorch","subcomponents","in","Ax",".","Specified","via","`","Surrogate","`","and","`","Acquisition","`",",","which","wrap","BoTorch","`","Model","`","and","`","AcquisitionFunction","`",",","respectively",",","for","convenient","use","in","Ax",".","Args",":","acquisition_class",":","Type","of","`","Acquisition","`","to","be","used","in","this","model",",","auto-selected","based","on","experiment","and","data","if","not","specified",".","acquisition_options",":","Optional","dict","of","kwargs",",","passed","to","the","constructor","of","BoTorch","`","AcquisitionFunction","`",".","botorch_acqf_class",":","Type","of","`","AcquisitionFunction","`","to","be","used","in","this","model",",","auto-selected","based","on","experiment","and","data","if","not","specified",".","surrogate_specs",":","Optional","Mapping","of","names","onto","SurrogateSpecs",",","which","specify","how","to","initialize","specific","Surrogates","to","model","specific","outcomes",".","If","None","is","provided","a","single","Surrogate","will","be","created","and","set","up","automatically","based","on","the","data","provided",".","surrogate",":","In","liu","of","SurrogateSpecs",",","an","instance","of","`","Surrogate","`","may","be","provided","to","be","used","as","the","sole","Surrogate","for","all","outcomes","refit_on_update",":","Unused",".","refit_on_cv",":","Whether","to","reoptimize","model","parameters","during","call","to","`","BoTorchmodel.cross_validate","`",".","warm_start_refit",":","Whether","to","load","parameters","from","either","the","provided","state","dict","or","the","state","dict","of","the","current","BoTorch","`","Model","`","during","refitting",".","If","False",",","model","parameters","will","be","reoptimized","from","scratch","on","refit",".","NOTE",":","This","setting","is","ignored","during","`","cross_validate","`","if","the","corresponding","`","refit_on_","...","`","is","False","."]
code: def gen(
      self,
      n: int,
      search_space_digest: SearchSpaceDigest,
      torch_opt_config: TorchOptConfig,
  ) -> TorchGenResults:
      (
          acq_options,
          opt_options,
      ) = construct_acquisition_and_optimizer_options(
          acqf_options=self.acquisition_options,
          model_gen_options=torch_opt_config.model_gen_options,
      )
      # update bounds / target values
      search_space_digest = dataclasses.replace(
          self.search_space_digest,
          bounds=search_space_digest.bounds,
          target_values=search_space_digest.target_values or {},
      )
  
      acqf = self._instantiate_acquisition(
          search_space_digest=search_space_digest,
          torch_opt_config=torch_opt_config,
          acq_options=acq_options,
      )
      botorch_rounding_func = get_rounding_func(
          torch_opt_config.rounding_func
      )
      candidates, expected_acquisition_value = acqf.optimize(
          n=n,
          search_space_digest=search_space_digest,
          inequality_constraints=_to_inequality_constraints(
              linear_constraints=torch_opt_config.linear_constraints
          ),
          fixed_features=torch_opt_config.fixed_features,
          rounding_func=botorch_rounding_func,
          optimizer_options=checked_cast(dict, opt_options),
      )
      gen_metadata = self._get_gen_metadata_from_acqf(
          acqf=acqf,
          torch_opt_config=torch_opt_config,
          expected_acquisition_value=expected_acquisition_value,
      )
      return TorchGenResults(
          points=candidates.detach().cpu(),
          weights=torch.ones(n, dtype=self.dtype),
          gen_metadata=gen_metadata,
      )
  
imports: import dataclasses
  from copy import deepcopy
  from dataclasses import dataclass, field
  from functools import wraps
  from typing import Any, Callable, Dict, List, Mapping, Optional, OrderedDict, Tuple, Type, TypeVar
  import numpy
  import torch
  from ax.core.search_space import SearchSpaceDigest
  from ax.core.types import TCandidateMetadata, TGenMetadata
  from ax.exceptions.core import UserInputError
  from ax.models.torch.botorch import get_feature_importances_from_botorch_model, get_rounding_func
  from ax.models.torch.botorch_modular.acquisition import Acquisition
  from ax.models.torch.botorch_modular.surrogate import Surrogate
  from ax.models.torch.botorch_modular.utils import check_metric_dataset_match, choose_botorch_acqf_class, construct_acquisition_and_optimizer_options, get_subset_datasets
  from ax.models.torch.utils import _to_inequality_constraints
  from ax.models.torch_base import TorchGenResults, TorchModel, TorchOptConfig
  from ax.utils.common.base import Base
  from ax.utils.common.constants import Keys
  from ax.utils.common.docutils import copy_doc
  from ax.utils.common.typeutils import checked_cast
  from botorch.acquisition.acquisition import AcquisitionFunction
  from botorch.models.deterministic import FixedSingleSampleModel
  from botorch.models.model import Model
  from botorch.models.transforms.input import InputTransform
  from botorch.models.transforms.outcome import OutcomeTransform
  from botorch.utils.datasets import SupervisedDataset
  from gpytorch.kernels.kernel import Kernel
  from gpytorch.likelihoods import Likelihood
  from gpytorch.mlls.exact_marginal_log_likelihood import ExactMarginalLogLikelihood
  from gpytorch.mlls.marginal_log_likelihood import MarginalLogLikelihood
  from torch import Tensor
label_desc: Use image node_id 9 for calling the BoTorchModel obj's underlying member method code with example usage: obj.gen(n, search_space_digest, torch_opt_config) and returns: TorchGenResults