class_docstr: Grid search tuner divides search space into evenly spaced grid, and performs brute-force traverse.
  
  Recommended when the search space is small, or if you want to find strictly optimal hyperparameters.
  
  **Implementation**
  
  The original grid search approach performs an exhaustive search through a space consists of ``choice`` and ``randint``.
  
  NNI's implementation extends grid search to support all search spaces types.
  
  When the search space contains continuous parameters like ``normal`` and ``loguniform``,
  grid search tuner works in following steps:
  
  1. Divide the search space into a grid.
  2. Perform an exhaustive searth through the grid.
  3. Subdivide the grid into a finer-grained new grid.
  4. Goto step 2, until experiment end.
  
  As a deterministic algorithm, grid search has no argument.
  
  Examples
  --------
  
  .. code-block::
  
      config.tuner.name = 'GridSearch'
code: def import_data(self, data):
      # TODO
      # use tuple to dedup in case of order/precision issue causes matching failed
      # and remove `epoch_bar` to use uniform dedup mechanism
      for trial in data:
          params_str = nni.dump(trial["parameter"], sort_keys=True)
          self.history.add(params_str)
  
imports: import logging
  import math
  import numpy
  from scipy.special import erfinv
  import nni
  from nni.common.hpo_utils import ParameterSpec, deformat_parameters, format_search_space
  from nni.tuner import Tuner
label_desc: Use image node_id 5 for calling the GridSearchTuner obj's underlying member method code with example usage: obj.import_data(data) without return types