class_docstr: Crop the spatial dimensions (last two dimensions) of the input by the
  specified amounts.
  
  Parameters
  ----------
  x: tensor<[\*D, H1, W1],T> (Required)
      * Must be at least rank ``3``.
  crop_height: const<2, i32> (Required)
      * Amount to be cropped from the top and bottom of the height dimension
        (``axis=-2``).
  crop_width: const<2, i32> (Required)
      * Amount to be cropped from the left and right sides of the width dimension (``axis=-1``).
  
  Returns
  -------
  tensor<[\*D, H2, W2],T>
      * Tensor with same type as the input.
      * ``H2`` = ``H1 - crop_height[0] - crop_height[1]``.
      * ``W2`` = ``W1 - crop_width[0] - crop_width[1]``.
  
  Attributes
  ----------
  T: fp16, fp32
class_docstr_tok: ["Crop","the","spatial","dimensions","(","last","two","dimensions",")","of","the","input","by","the","specified","amounts",".","Parameters","--","--","--","--","--","x",":","tensor","<","[","\\","*","D",",","H1",",","W1","]",",","T",">","(","Required",")","*","Must","be","at","least","rank","``","3","``",".","crop_height",":","const","<","2",",","i32",">","(","Required",")","*","Amount","to","be","cropped","from","the","top","and","bottom","of","the","height","dimension","(","``","axis=-2","``",")",".","crop_width",":","const","<","2",",","i32",">","(","Required",")","*","Amount","to","be","cropped","from","the","left","and","right","sides","of","the","width","dimension","(","``","axis=-1","``",")",".","Returns","--","--","--","-","tensor","<","[","\\","*","D",",","H2",",","W2","]",",","T",">","*","Tensor","with","same","type","as","the","input",".","*","``","H2","``","=","``","H1","-","crop_height","[","0","]","-","crop_height","[","1","]","``",".","*","``","W2","``","=","``","W1","-","crop_width","[","0","]","-","crop_width","[","1","]","``",".","Attributes","--","--","--","--","--","T",":","fp16",",","fp32"]
code: def type_inference(self):
      if self.x.rank < 3:
          raise ValueError(
              'input to the "crop" op must at least be of rank 3. Provided {}'.format(
                  self.x.rank
              )
          )
  
      crop_height = self.crop_height.val
      crop_width = self.crop_width.val
  
      if len(crop_height.flatten()) != 2:
          raise ValueError(
              "crop_height must have 2 elements. Provided {}".format(
                  len(crop_height.flatten())
              )
          )
  
      if len(crop_width.flatten()) != 2:
          raise ValueError(
              "crop_width must have 2 elements. Provided {}".format(
                  len(crop_width.flatten())
              )
          )
  
      input_shape = list(self.x.shape)
      ret_shape = (
          input_shape[:-2]
          + [input_shape[-2] - crop_height[0] - crop_height[1]]
          + [input_shape[-1] - crop_width[0] - crop_width[1]]
      )
      return types.tensor(self.x.dtype, ret_shape)
  
imports: import numpy
  from coremltools.converters.mil.mil import DefaultInputs, InputSpec, Operation, TensorInputType, get_new_symbol, types
  from coremltools.converters.mil.mil.ops.defs._op_reqs import register_op
  from coremltools.converters.mil.mil.ops.defs.iOS15 import _IOS15_TARGET
  from coremltools.converters.mil.mil.types.symbolic import is_symbolic
label_desc: Use image node_id 1 for calling the crop obj's underlying member method code with example usage: obj.type_inference() and returns: types