code: def make_convolution_dimension_numbers(
      dimension_numbers: Union[
          None, ConvolutionDimensionNumbers, Tuple[str, str, str]
      ],
      num_spatial_dimensions: int,
  ) -> ConvolutionDimensionNumbers:
      """Builds a ConvolutionDimensionNumbers object from a specification.
  
      Args:
        dimension_numbers: optional, either a ConvolutionDimensionNumbers object or
          a tuple (lhs_spec, rhs_spec, out_spec). Each element is a string of length
          N+2 identifying by position: (1) batch dimensions in lhs, rhs, and the
          output with the character 'N', (2) feature dimensions in lhs and the
          output with the character 'C', (3) input and output feature dimensions in
          rhs with the characters 'I' and 'O' respectively, and (4) spatial
          dimension correspondences between lhs, rhs, and the output using any
          distinct characters. For example, to indicate dimension numbers consistent
          with the Conv operation with two spatial dimensions, one could use
          ('NCHW', 'OIHW', 'NCHW'). As another example, to indicate dimension
          numbers consistent with the TensorFlow Conv2D operation, one could use
          ('NHWC', 'HWIO', 'NHWC'). When using the latter form of convolution
          dimension specification, window strides are associated with spatial
          dimension character labels according to the order in which the labels
          appear in the rhs_spec string, so that window_strides[0] is matched with
          the dimension corresponding to the first character appearing in rhs_spec
          that is not 'I' or 'O'. By default, use the same dimension numbering as
          Conv and ConvWithGeneralPadding.
        num_spatial_dimensions: the number of spatial dimensions.
  
      Returns:
        A `ConvolutionDimensionNumbers` object.
      """
      if dimension_numbers is None:
          nd = num_spatial_dimensions
          dimension_numbers = ConvolutionDimensionNumbers()
          dimension_numbers.input_batch_dimension = 0
          dimension_numbers.input_feature_dimension = 1
          dimension_numbers.output_batch_dimension = 0
          dimension_numbers.output_feature_dimension = 1
          dimension_numbers.kernel_output_feature_dimension = 0
          dimension_numbers.kernel_input_feature_dimension = 1
          dimension_numbers.input_spatial_dimensions.extend(
              range(2, 2 + nd)
          )
          dimension_numbers.kernel_spatial_dimensions.extend(
              range(2, 2 + nd)
          )
          dimension_numbers.output_spatial_dimensions.extend(
              range(2, 2 + nd)
          )
      elif isinstance(dimension_numbers, tuple):
          lhs_spec, rhs_spec, out_spec = dimension_numbers
          dimension_numbers = ConvolutionDimensionNumbers()
  
          dimension_numbers.input_batch_dimension = lhs_spec.index("N")
          dimension_numbers.input_feature_dimension = lhs_spec.index(
              "C"
          )
          dimension_numbers.output_batch_dimension = out_spec.index("N")
          dimension_numbers.output_feature_dimension = out_spec.index(
              "C"
          )
          dimension_numbers.kernel_output_feature_dimension = (
              rhs_spec.index("O")
          )
          dimension_numbers.kernel_input_feature_dimension = (
              rhs_spec.index("I")
          )
  
          dimension_numbers.kernel_spatial_dimensions.extend(
              i for i, c in enumerate(rhs_spec) if c not in {"I", "O"}
          )
          dimension_numbers.input_spatial_dimensions.extend(
              sorted(
                  (
                      i
                      for i, c in enumerate(lhs_spec)
                      if c not in {"N", "C"}
                  ),
                  key=lambda i: rhs_spec.index(lhs_spec[i]),
              )
          )
          dimension_numbers.output_spatial_dimensions.extend(
              sorted(
                  (
                      i
                      for i, c in enumerate(out_spec)
                      if c not in {"N", "C"}
                  ),
                  key=lambda i: rhs_spec.index(out_spec[i]),
              )
          )
      return dimension_numbers
  
imports: from __future__ import annotations
  import atexit
  import contextlib
  import enum
  import gzip
  import inspect
  import logging
  import os
  import threading
  from typing import Any, List, Mapping, Optional, Sequence, Tuple, Union
  import ml_dtypes
  import numpy
  from .None import xla_extension
label_desc: Use image node_id 24 for calling a global function with example usage: make_convolution_dimension_numbers(dimension_numbers, num_spatial_dimensions) and returns: dimension_numbers