class_docstr: Grid Search algorithm
  
  Parameters
  ----------
  n_values: int or dict
      Number of trials for each dimensions, or dictionary specifying number of trials for each
      dimension independently (name, n_values). For categorical dimensions, n_values will not be
      used, and all categories will be used to build the grid.
docstr: Build a grid of trials
  
  Parameters
  ----------
  n_values: int or dict
      Dictionary specifying number of trials for each dimension independently
      (name, n_values). For categorical dimensions, n_values will not be used, and all
      categories will be used to build the grid.
  max_trials: int
      Maximum number of trials for the grid. If n_values lead to more trials than max_trials,
      the n_values will be adjusted down. Will raise ValueError if it is impossible to build
      a grid smaller than max_trials (for instance if choices are too large).
docstr_tok: ["Build","a","grid","of","trials","Parameters","--","--","--","--","--","n_values",":","int","or","dict","Dictionary","specifying","number","of","trials","for","each","dimension","independently","(","name",",","n_values",")",".","For","categorical","dimensions",",","n_values","will","not","be","used",",","and","all","categories","will","be","used","to","build","the","grid",".","max_trials",":","int","Maximum","number","of","trials","for","the","grid",".","If","n_values","lead","to","more","trials","than","max_trials",",","the","n_values","will","be","adjusted","down",".","Will","raise","ValueError","if","it","is","impossible","to","build","a","grid","smaller","than","max_trials","(","for","instance","if","choices","are","too","large",")","."]
code: def build_grid(
      space: Space, n_values: dict[str, int], max_trials: int = 10000
  ):
      """Build a grid of trials
  
      Parameters
      ----------
      n_values: int or dict
          Dictionary specifying number of trials for each dimension independently
          (name, n_values). For categorical dimensions, n_values will not be used, and all
          categories will be used to build the grid.
      max_trials: int
          Maximum number of trials for the grid. If n_values lead to more trials than max_trials,
          the n_values will be adjusted down. Will raise ValueError if it is impossible to build
          a grid smaller than max_trials (for instance if choices are too large).
  
      """
      adjust = 0
      n_trials = float("inf")
      coordinates: list[list] = []
  
      while n_trials > max_trials:
          coordinates = []
          capped_values = []
          for name, dim in space.items():
              capped_value = max(n_values[name] - adjust, 1)
              capped_values.append(capped_value)
              coordinates.append(list(grid(dim, capped_value)))
  
          if all(value <= 1 for value in capped_values):
              raise ValueError(
                  f"Cannot build a grid smaller than {max_trials}. "
                  "Try reducing the number of choices in categorical dimensions."
              )
  
          n_trials = numpy.prod(
              [len(dim_values) for dim_values in coordinates]
          )
          # TODO: Use binary search instead of incrementing by one.
          adjust += 1
  
      if adjust > 1:
          log.warning(
              f"`n_values` reduced by {adjust-1} to limit number of trials below {max_trials}."
          )
  
      return list(itertools.product(*coordinates))
  
imports: from __future__ import annotations
  import itertools
  import logging
  import numpy
  from orion.algo.base import BaseAlgorithm
  from orion.algo.space import Categorical, Dimension, Fidelity, Integer, Real, Space
  from orion.core.utils import format_trials
label_desc: Use image node_id 2 for calling the GridSearch obj's underlying member method code with example usage: obj.build_grid(space, n_values, max_trials) and returns: list