class_docstr: A model bridge for using torch-based models.
  
  Specifies an interface that is implemented by TorchModel. In particular,
  model should have methods fit, predict, and gen. See TorchModel for the
  API for each of these methods.
  
  Requires that all parameters have been transformed to RangeParameters
  or FixedParameters with float type and no log scale.
  
  This class converts Ax parameter types to torch tensors before passing
  them to the model.
class_docstr_tok: ["A","model","bridge","for","using","torch-based","models",".","Specifies","an","interface","that","is","implemented","by","TorchModel",".","In","particular",",","model","should","have","methods","fit",",","predict",",","and","gen.","See","TorchModel","for","the","API","for","each","of","these","methods",".","Requires","that","all","parameters","have","been","transformed","to","RangeParameters","or","FixedParameters","with","float","type","and","no","log","scale",".","This","class","converts","Ax","parameter","types","to","torch","tensors","before","passing","them","to","the","model","."]
docstr: Generate new candidates according to search_space and
  optimization_config.
  
  The outcome constraints should be transformed to no longer be relative.
docstr_tok: ["Generate","new","candidates","according","to","search_space","and","optimization_config",".","The","outcome","constraints","should","be","transformed","to","no","longer","be","relative","."]
code: def _gen(
      self,
      n: int,
      search_space: SearchSpace,
      pending_observations: Dict[str, List[ObservationFeatures]],
      fixed_features: Optional[ObservationFeatures],
      model_gen_options: Optional[TConfig] = None,
      optimization_config: Optional[OptimizationConfig] = None,
  ) -> GenResults:
      """Generate new candidates according to search_space and
      optimization_config.
  
      The outcome constraints should be transformed to no longer be relative.
      """
      if self.model is None:
          raise ValueError(FIT_MODEL_ERROR.format(action="_gen"))
  
      augmented_model_gen_options = {
          **self._default_model_gen_options,
          **(model_gen_options or {}),
      }
      (
          search_space_digest,
          torch_opt_config,
      ) = self._get_transformed_model_gen_args(
          search_space=search_space,
          pending_observations=pending_observations,
          fixed_features=fixed_features,
          model_gen_options=augmented_model_gen_options,
          optimization_config=optimization_config,
      )
  
      # Generate the candidates
      # TODO(ehotaj): For some reason, we're getting models which do not support MOO
      # even when optimization_config has multiple objectives, so we can't use
      # self.is_moo_problem here.
      is_moo_problem = self.is_moo_problem and isinstance(
          self.model, (BoTorchModel, MultiObjectiveBotorchModel)
      )
      gen_results = not_none(self.model).gen(
          n=n,
          search_space_digest=search_space_digest,
          torch_opt_config=torch_opt_config,
      )
  
      gen_metadata = gen_results.gen_metadata
      if is_moo_problem and "objective_thresholds" in gen_metadata:
          # If objective_thresholds are supplied by the user, then the transformed
          # user-specified objective thresholds are in gen_metadata. Otherwise,
          # if using a hypervolume based acquisition function, then
          # the inferred objective thresholds are in gen_metadata.
          opt_config_metrics = (
              torch_opt_config.opt_config_metrics
              or not_none(self._optimization_config).metrics
          )
          gen_metadata[
              "objective_thresholds"
          ] = self._untransform_objective_thresholds(
              objective_thresholds=gen_metadata["objective_thresholds"],
              objective_weights=torch_opt_config.objective_weights,
              bounds=search_space_digest.bounds,
              opt_config_metrics=opt_config_metrics,
              fixed_features=torch_opt_config.fixed_features,
          )
  
      # Transform array to observations
      observation_features = self._array_to_observation_features(
          X=gen_results.points.detach().cpu().clone().numpy(),
          candidate_metadata=gen_results.candidate_metadata,
      )
      try:
          xbest = not_none(self.model).best_point(
              search_space_digest=search_space_digest,
              torch_opt_config=torch_opt_config,
          )
      except NotImplementedError:
          xbest = None
  
      best_obsf = None
      if xbest is not None:
          best_obsf = ObservationFeatures(
              parameters={
                  p: float(xbest[i])
                  for i, p in enumerate(self.parameters)
              }
          )
  
      return GenResults(
          observation_features=observation_features,
          weights=gen_results.weights.tolist(),
          best_observation_features=best_obsf,
          gen_metadata=gen_metadata,
      )
  
imports: from __future__ import annotations
  from collections import defaultdict
  from copy import deepcopy
  from logging import Logger
  from typing import Any, Callable, Dict, List, Optional, Set, Tuple, Type, Union
  import numpy
  import torch
  from ax.core.arm import Arm
  from ax.core.data import Data
  from ax.core.experiment import Experiment
  from ax.core.generator_run import extract_arm_predictions
  from ax.core.metric import Metric
  from ax.core.observation import Observation, ObservationData, ObservationFeatures, separate_observations
  from ax.core.optimization_config import MultiObjectiveOptimizationConfig, OptimizationConfig
  from ax.core.outcome_constraint import ComparisonOp, ObjectiveThreshold, ScalarizedOutcomeConstraint
  from ax.core.search_space import SearchSpace
  from ax.core.types import TCandidateMetadata, TModelPredictArm
  from ax.exceptions.core import DataRequiredError, UnsupportedError
  from ax.modelbridge.base import gen_arms, GenResults, ModelBridge
  from ax.modelbridge.modelbridge_utils import array_to_observation_data, extract_objective_thresholds, extract_objective_weights, extract_outcome_constraints, extract_parameter_constraints, extract_risk_measure, extract_search_space_digest, get_fixed_features, observation_data_to_array, observation_features_to_array, parse_observation_features, pending_observations_as_array_list, process_contextual_datasets, SearchSpaceDigest, transform_callback, validate_and_apply_final_transform
  from ax.modelbridge.transforms.base import Transform
  from ax.modelbridge.transforms.cast import Cast
  from ax.models.torch.botorch_modular.model import BoTorchModel
  from ax.models.torch.botorch_moo import MultiObjectiveBotorchModel
  from ax.models.torch.botorch_moo_defaults import infer_objective_thresholds
  from ax.models.torch_base import TorchModel, TorchOptConfig
  from ax.models.types import TConfig
  from ax.utils.common.logger import get_logger
  from ax.utils.common.typeutils import not_none
  from botorch.utils.datasets import MultiTaskDataset, SupervisedDataset
  from torch import Tensor
label_desc: Use image node_id 14 for calling the TorchModelBridge obj's underlying member method code with example usage: obj._gen(n, search_space, pending_observations, fixed_features, model_gen_options, optimization_config) and returns: GenResults