code: def _max_pool(  # type: ignore
      self,
      x,
      auto_pad,
      ceil_mode,
      dilations,
      kernel_shape,
      pads,
      storage_order,
      strides,
  ):
      if pads is None:
          pads = [0 for i in range(len(kernel_shape) * 2)]
      if strides is None:
          strides = [1 for i in range(len(kernel_shape))]
      if dilations is None:
          dilations = [1 for i in range(len(kernel_shape))]
  
      n_dims = len(kernel_shape)
      new_pads = np.array(
          [(pads[i], pads[i + n_dims]) for i in range(n_dims)]
      )
  
      input_spatial_shape = x.shape[2:]
      output_spatial_shape = [0 for s in input_spatial_shape]
      if ceil_mode:
          for i in range(len(input_spatial_shape)):
              output_spatial_shape[i] = int(
                  np.ceil(
                      (
                          input_spatial_shape[i]
                          + new_pads[i].sum()
                          - ((kernel_shape[i] - 1) * dilations[i] + 1)
                      )
                      / strides[i]
                      + 1
                  )
              )
      else:
          for i in range(len(input_spatial_shape)):
              output_spatial_shape[i] = int(
                  np.floor(
                      (
                          input_spatial_shape[i]
                          + new_pads[i].sum()
                          - ((kernel_shape[i] - 1) * dilations[i] + 1)
                      )
                      / strides[i]
                      + 1
                  )
              )
  
      if auto_pad and auto_pad != "NOTSET":
          # Deprecated attribute
          if auto_pad in ("SAME_UPPER", "SAME_LOWER"):
              for i in range(len(input_spatial_shape)):
                  if auto_pad == "SAME_UPPER":
                      output_spatial_shape[i] = int(
                          np.ceil(input_spatial_shape[i] / strides[i])
                      )
                  else:
                      output_spatial_shape[i] = int(
                          np.floor(input_spatial_shape[i] / strides[i])
                      )
                  pad_i = (
                      (output_spatial_shape[i] - 1) * strides[i]
                      + ((kernel_shape[i] - 1) * dilations[i] + 1)
                      - input_spatial_shape[i]
                  )
                  new_pads[i, 0] = pad_i // 2
                  new_pads[i, 1] = pad_i - new_pads[i, 0]
          else:
              for i in range(len(input_spatial_shape)):
                  output_spatial_shape[i] = int(
                      np.ceil(
                          (
                              input_spatial_shape[i]
                              - (
                                  (kernel_shape[i] - 1) * dilations[i]
                                  + 1
                              )
                              + 1
                          )
                          / strides[i]
                      )
                  )
  
      if len(input_spatial_shape) == 1:
          return self._max_pool_1d(
              x,
              auto_pad,
              ceil_mode,
              dilations,
              kernel_shape,
              new_pads,
              storage_order,
              strides,
              output_spatial_shape,
          )
  
      if len(input_spatial_shape) == 2:
          return self._max_pool_2d(
              x,
              auto_pad,
              ceil_mode,
              dilations,
              kernel_shape,
              new_pads,
              storage_order,
              strides,
              output_spatial_shape,
          )
  
      if len(input_spatial_shape) == 3:
          return self._max_pool_3d(
              x,
              auto_pad,
              ceil_mode,
              dilations,
              kernel_shape,
              new_pads,
              storage_order,
              strides,
              output_spatial_shape,
          )
  
      raise RuntimeError(f"Not implemented yet for shape {x.shape}.")
  
file_path: onnx/onnx/reference/ops/op_max_pool.py
imports: import numpy
  from onnx.reference.ops._op_common_pool import CommonPool
label_desc: Use image node_id 2 for calling the MaxPool obj's underlying member method code with example usage: obj._max_pool(x, auto_pad, ceil_mode, dilations, kernel_shape, pads, storage_order, strides) and returns: self, self, self