code: def check_metric_dataset_match(
      metric_names: List[str],
      datasets: List[SupervisedDataset],
      exact_match: bool,
  ) -> None:
      """Check that the metric names match the outcome names of datasets.
  
      Based on `exact_match` we either require that metric names are
      a subset of all outcomes or require the them to be the same.
  
      Also checks that there are no duplicates in metric or outcome names.
  
      Args:
          metric_names: A list of metric names.
          datasets: A list of `SupervisedDataset` objects.
          exact_match: If True, metric names must be the same as the union of
              outcomes names of the datasets. Otherwise, we check that the
              metric names are a subset of all outcomes.
  
      Raises:
          ValueError: If there is no match.
      """
      all_outcomes = sum((ds.outcome_names for ds in datasets), [])
      set_all_outcomes = set(all_outcomes)
      set_all_metrics = set(metric_names)
      if len(set_all_outcomes) != len(all_outcomes):
          raise AxError("Found duplicate outcomes in the datasets.")
      if len(set_all_metrics) != len(metric_names):
          raise AxError("Found duplicate metric names.")
  
      if not exact_match:
          if not set_all_metrics.issubset(set_all_outcomes):
              raise AxError(
                  "Metric names must be a subset of the outcome names of the datasets."
                  f"Got {metric_names=} but the datasets model {set_all_outcomes}."
              )
      elif set_all_metrics != set_all_outcomes:
          raise AxError(
              "Each metric name must correspond to an outcome in the datasets. "
              f"Got {metric_names=} but the datasets model {set_all_outcomes}."
          )
  
imports: import warnings
  from logging import Logger
  from typing import Any, Callable, Dict, List, Optional, OrderedDict, Tuple, Type
  import torch
  from ax.core.search_space import SearchSpaceDigest
  from ax.exceptions.core import AxError, AxWarning, UnsupportedError
  from ax.models.types import TConfig
  from ax.utils.common.constants import Keys
  from ax.utils.common.logger import get_logger
  from ax.utils.common.typeutils import checked_cast, not_none
  from botorch.acquisition.acquisition import AcquisitionFunction
  from botorch.acquisition.logei import qLogNoisyExpectedImprovement
  from botorch.acquisition.multi_objective.logei import qLogNoisyExpectedHypervolumeImprovement
  from botorch.fit import fit_fully_bayesian_model_nuts, fit_gpytorch_mll
  from botorch.models.fully_bayesian import SaasFullyBayesianSingleTaskGP
  from botorch.models.gp_regression import SingleTaskGP
  from botorch.models.gp_regression_fidelity import SingleTaskMultiFidelityGP
  from botorch.models.gp_regression_mixed import MixedSingleTaskGP
  from botorch.models.gpytorch import BatchedMultiOutputGPyTorchModel, GPyTorchModel
  from botorch.models.model import Model, ModelList
  from botorch.models.multitask import MultiTaskGP
  from botorch.models.pairwise_gp import PairwiseGP
  from botorch.utils.datasets import SupervisedDataset
  from botorch.utils.transforms import is_fully_bayesian
  from gpytorch.mlls.marginal_log_likelihood import MarginalLogLikelihood
  from torch import Tensor
label_desc: Use image node_id 10 for calling a global function with example usage: check_metric_dataset_match(metric_names, datasets, exact_match) without return types