code: def pad(array, pad_width, mode="constant", **kwargs):
      """Pads an array with specified widths and values.
  
      Args:
        array(cupy.ndarray): The array to pad.
        pad_width(sequence, array_like or int): Number of values padded to the
            edges of each axis. ((before_1, after_1), ... (before_N, after_N))
            unique pad widths for each axis. ((before, after),) yields same
            before and after pad for each axis. (pad,) or int is a shortcut for
            before = after = pad width for all axes. You cannot specify
            ``cupy.ndarray``.
        mode(str or function, optional): One of the following string values or a
            user supplied function
  
            'constant' (default)
                Pads with a constant value.
            'edge'
                Pads with the edge values of array.
            'linear_ramp'
                Pads with the linear ramp between end_value and the array edge
                value.
            'maximum'
                Pads with the maximum value of all or part of the vector along
                each axis.
            'mean'
                Pads with the mean value of all or part of the vector along each
                axis.
            'median'
                Pads with the median value of all or part of the vector along
                each axis. (Not Implemented)
            'minimum'
                Pads with the minimum value of all or part of the vector along
                each axis.
            'reflect'
                Pads with the reflection of the vector mirrored on the first and
                last values of the vector along each axis.
            'symmetric'
                 Pads with the reflection of the vector mirrored along the edge
                 of the array.
            'wrap'
                Pads with the wrap of the vector along the axis. The first
                values are used to pad the end and the end values are used to
                pad the beginning.
            'empty'
                Pads with undefined values.
            <function>
                Padding function, see Notes.
        stat_length(sequence or int, optional): Used in 'maximum', 'mean',
            'median', and 'minimum'.  Number of values at edge of each axis used
            to calculate the statistic value.
            ((before_1, after_1), ... (before_N, after_N)) unique statistic
            lengths for each axis. ((before, after),) yields same before and
            after statistic lengths for each axis. (stat_length,) or int is a
            shortcut for before = after = statistic length for all axes.
            Default is ``None``, to use the entire axis. You cannot specify
            ``cupy.ndarray``.
        constant_values(sequence or scalar, optional): Used in 'constant'. The
            values to set the padded values for each axis.
            ((before_1, after_1), ... (before_N, after_N)) unique pad constants
            for each axis.
            ((before, after),) yields same before and after constants for each
            axis.
            (constant,) or constant is a shortcut for before = after = constant
            for all axes.
            Default is 0. You cannot specify ``cupy.ndarray``.
        end_values(sequence or scalar, optional): Used in 'linear_ramp'. The
            values used for the ending value of the linear_ramp and that will
            form the edge of the padded array.
            ((before_1, after_1), ... (before_N, after_N)) unique end values
            for each axis.
            ((before, after),) yields same before and after end
            values for each axis.
            (constant,) or constant is a shortcut for before = after = constant
            for all axes.
            Default is 0. You cannot specify ``cupy.ndarray``.
        reflect_type({'even', 'odd'}, optional): Used in 'reflect', and
            'symmetric'.  The 'even' style is the default with an unaltered
            reflection around the edge value.  For the 'odd' style, the extended
            part of the array is created by subtracting the reflected values from
            two times the edge value.
  
      Returns:
        cupy.ndarray: Padded array with shape extended by ``pad_width``.
  
      .. note::
          For an array with rank greater than 1, some of the padding of later
          axes is calculated from padding of previous axes.  This is easiest to
          think about with a rank 2 array where the corners of the padded array
          are calculated by using padded values from the first axis.
  
          The padding function, if used, should modify a rank 1 array in-place.
          It has the following signature:
  
          ``padding_func(vector, iaxis_pad_width, iaxis, kwargs)``
  
          where
  
          vector (cupy.ndarray)
              A rank 1 array already padded with zeros.  Padded values are
              ``vector[:iaxis_pad_width[0]]`` and
              ``vector[-iaxis_pad_width[1]:]``.
          iaxis_pad_width (tuple)
              A 2-tuple of ints, ``iaxis_pad_width[0]`` represents the number of
              values padded at the beginning of vector where
              ``iaxis_pad_width[1]`` represents the number of values padded at
              the end of vector.
          iaxis (int)
              The axis currently being calculated.
          kwargs (dict)
              Any keyword arguments the function requires.
  
      Examples
      --------
      >>> a = cupy.array([1, 2, 3, 4, 5])
      >>> cupy.pad(a, (2, 3), 'constant', constant_values=(4, 6))
      array([4, 4, 1, ..., 6, 6, 6])
  
      >>> cupy.pad(a, (2, 3), 'edge')
      array([1, 1, 1, ..., 5, 5, 5])
  
      >>> cupy.pad(a, (2, 3), 'linear_ramp', end_values=(5, -4))
      array([ 5,  3,  1,  2,  3,  4,  5,  2, -1, -4])
  
      >>> cupy.pad(a, (2,), 'maximum')
      array([5, 5, 1, 2, 3, 4, 5, 5, 5])
  
      >>> cupy.pad(a, (2,), 'mean')
      array([3, 3, 1, 2, 3, 4, 5, 3, 3])
  
      >>> a = cupy.array([[1, 2], [3, 4]])
      >>> cupy.pad(a, ((3, 2), (2, 3)), 'minimum')
      array([[1, 1, 1, 2, 1, 1, 1],
             [1, 1, 1, 2, 1, 1, 1],
             [1, 1, 1, 2, 1, 1, 1],
             [1, 1, 1, 2, 1, 1, 1],
             [3, 3, 3, 4, 3, 3, 3],
             [1, 1, 1, 2, 1, 1, 1],
             [1, 1, 1, 2, 1, 1, 1]])
  
      >>> a = cupy.array([1, 2, 3, 4, 5])
      >>> cupy.pad(a, (2, 3), 'reflect')
      array([3, 2, 1, 2, 3, 4, 5, 4, 3, 2])
  
      >>> cupy.pad(a, (2, 3), 'reflect', reflect_type='odd')
      array([-1,  0,  1,  2,  3,  4,  5,  6,  7,  8])
  
      >>> cupy.pad(a, (2, 3), 'symmetric')
      array([2, 1, 1, 2, 3, 4, 5, 5, 4, 3])
  
      >>> cupy.pad(a, (2, 3), 'symmetric', reflect_type='odd')
      array([0, 1, 1, 2, 3, 4, 5, 5, 6, 7])
  
      >>> cupy.pad(a, (2, 3), 'wrap')
      array([4, 5, 1, 2, 3, 4, 5, 1, 2, 3])
  
      >>> def pad_with(vector, pad_width, iaxis, kwargs):
      ...     pad_value = kwargs.get('padder', 10)
      ...     vector[:pad_width[0]] = pad_value
      ...     vector[-pad_width[1]:] = pad_value
      >>> a = cupy.arange(6)
      >>> a = a.reshape((2, 3))
      >>> cupy.pad(a, 2, pad_with)
      array([[10, 10, 10, 10, 10, 10, 10],
             [10, 10, 10, 10, 10, 10, 10],
             [10, 10,  0,  1,  2, 10, 10],
             [10, 10,  3,  4,  5, 10, 10],
             [10, 10, 10, 10, 10, 10, 10],
             [10, 10, 10, 10, 10, 10, 10]])
      >>> cupy.pad(a, 2, pad_with, padder=100)
      array([[100, 100, 100, 100, 100, 100, 100],
             [100, 100, 100, 100, 100, 100, 100],
             [100, 100,   0,   1,   2, 100, 100],
             [100, 100,   3,   4,   5, 100, 100],
             [100, 100, 100, 100, 100, 100, 100],
             [100, 100, 100, 100, 100, 100, 100]])
      """
      if isinstance(pad_width, numbers.Integral):
          pad_width = ((pad_width, pad_width),) * array.ndim
      else:
          pad_width = numpy.asarray(pad_width)
  
          if not pad_width.dtype.kind == "i":
              raise TypeError("`pad_width` must be of integral type.")
  
          # Broadcast to shape (array.ndim, 2)
          pad_width = _as_pairs(pad_width, array.ndim, as_index=True)
  
      if callable(mode):
          # Old behavior: Use user-supplied function with numpy.apply_along_axis
          function = mode
          # Create a new zero padded array
          padded, _ = _pad_simple(array, pad_width, fill_value=0)
          # And apply along each axis
  
          for axis in range(padded.ndim):
              # Iterate using ndindex as in apply_along_axis, but assuming that
              # function operates inplace on the padded array.
  
              # view with the iteration axis at the end
              view = cupy.moveaxis(padded, axis, -1)
  
              # compute indices for the iteration axes, and append a trailing
              # ellipsis to prevent 0d arrays decaying to scalars (gh-8642)
              inds = numpy.ndindex(view.shape[:-1])
              inds = (ind + (Ellipsis,) for ind in inds)
              for ind in inds:
                  function(view[ind], pad_width[axis], axis, kwargs)
  
          return padded
  
      # Make sure that no unsupported keywords were passed for the current mode
      allowed_kwargs = {
          "empty": [],
          "edge": [],
          "wrap": [],
          "constant": ["constant_values"],
          "linear_ramp": ["end_values"],
          "maximum": ["stat_length"],
          "mean": ["stat_length"],
          # 'median': ['stat_length'],
          "minimum": ["stat_length"],
          "reflect": ["reflect_type"],
          "symmetric": ["reflect_type"],
      }
      try:
          unsupported_kwargs = set(kwargs) - set(allowed_kwargs[mode])
      except KeyError:
          raise ValueError("mode '{}' is not supported".format(mode))
      if unsupported_kwargs:
          raise ValueError(
              "unsupported keyword arguments for mode '{}': {}".format(
                  mode, unsupported_kwargs
              )
          )
  
      if mode == "constant":
          values = kwargs.get("constant_values", 0)
          if (
              isinstance(values, numbers.Number)
              and values == 0
              and (array.ndim == 1 or array.size < 4e6)
          ):
              # faster path for 1d arrays or small n-dimensional arrays
              return _pad_simple(array, pad_width, 0)[0]
  
      stat_functions = {
          "maximum": cupy.max,
          "minimum": cupy.min,
          "mean": cupy.mean,
          # 'median': cupy.median,
      }
  
      # Create array with final shape and original values
      # (padded area is undefined)
      padded, original_area_slice = _pad_simple(array, pad_width)
      # And prepare iteration over all dimensions
      # (zipping may be more readable than using enumerate)
      axes = range(padded.ndim)
  
      if mode == "constant":
          values = _as_pairs(values, padded.ndim)
          for axis, width_pair, value_pair in zip(
              axes, pad_width, values
          ):
              roi = _view_roi(padded, original_area_slice, axis)
              _set_pad_area(roi, axis, width_pair, value_pair)
  
      elif mode == "empty":
          pass  # Do nothing as _pad_simple already returned the correct result
  
      elif array.size == 0:
          # Only modes 'constant' and 'empty' can extend empty axes, all other
          # modes depend on `array` not being empty
          # -> ensure every empty axis is only 'padded with 0'
          for axis, width_pair in zip(axes, pad_width):
              if array.shape[axis] == 0 and any(width_pair):
                  raise ValueError(
                      "can't extend empty axis {} using modes other than "
                      "'constant' or 'empty'".format(axis)
                  )
          # passed, don't need to do anything more as _pad_simple already
          # returned the correct result
  
      elif mode == "edge":
          for axis, width_pair in zip(axes, pad_width):
              roi = _view_roi(padded, original_area_slice, axis)
              edge_pair = _get_edges(roi, axis, width_pair)
              _set_pad_area(roi, axis, width_pair, edge_pair)
  
      elif mode == "linear_ramp":
          end_values = kwargs.get("end_values", 0)
          end_values = _as_pairs(end_values, padded.ndim)
          for axis, width_pair, value_pair in zip(
              axes, pad_width, end_values
          ):
              roi = _view_roi(padded, original_area_slice, axis)
              ramp_pair = _get_linear_ramps(
                  roi, axis, width_pair, value_pair
              )
              _set_pad_area(roi, axis, width_pair, ramp_pair)
  
      elif mode in stat_functions:
          func = stat_functions[mode]
          length = kwargs.get("stat_length", None)
          length = _as_pairs(length, padded.ndim, as_index=True)
          for axis, width_pair, length_pair in zip(
              axes, pad_width, length
          ):
              roi = _view_roi(padded, original_area_slice, axis)
              stat_pair = _get_stats(
                  roi, axis, width_pair, length_pair, func
              )
              _set_pad_area(roi, axis, width_pair, stat_pair)
  
      elif mode in {"reflect", "symmetric"}:
          method = kwargs.get("reflect_type", "even")
          include_edge = True if mode == "symmetric" else False
          for axis, (left_index, right_index) in zip(axes, pad_width):
              if array.shape[axis] == 1 and (
                  left_index > 0 or right_index > 0
              ):
                  # Extending singleton dimension for 'reflect' is legacy
                  # behavior; it really should raise an error.
                  edge_pair = _get_edges(
                      padded, axis, (left_index, right_index)
                  )
                  _set_pad_area(
                      padded, axis, (left_index, right_index), edge_pair
                  )
                  continue
  
              roi = _view_roi(padded, original_area_slice, axis)
              while left_index > 0 or right_index > 0:
                  # Iteratively pad until dimension is filled with reflected
                  # values. This is necessary if the pad area is larger than
                  # the length of the original values in the current dimension.
                  left_index, right_index = _set_reflect_both(
                      roi,
                      axis,
                      (left_index, right_index),
                      method,
                      include_edge,
                  )
  
      elif mode == "wrap":
          for axis, (left_index, right_index) in zip(axes, pad_width):
              roi = _view_roi(padded, original_area_slice, axis)
              while left_index > 0 or right_index > 0:
                  # Iteratively pad until dimension is filled with wrapped
                  # values. This is necessary if the pad area is larger than
                  # the length of the original values in the current dimension.
                  left_index, right_index = _set_wrap_both(
                      roi, axis, (left_index, right_index)
                  )
  
      return padded
  
file_path: cupy/cupy/_padding/pad.py
imports: import numbers
  import numpy
  import cupy
label_desc: Use image node_id 12 for calling a global function with example usage: pad(array, pad_width, mode) and returns: padded, padded, _pad_simple