class_docstr: Perform convolution over input. Supports 1-D, 2-D, and 3-D convolution.
  
  Parameters
  ----------
  x: tensor<[n, C_in, \*d_in], T> (Required)
  
      * ``d_in`` are (possibly runtime-determined) spatial dimensions. For example,
        ``d_in = [224, 224]`` for 2D convolution.
      * ``1 <= len(d_in) <= 3``.
      * ``C_in`` is the number of input channels or depth dimensions.
      * ``n``  is the batch dimension.
  
  weight: tensor<[C_out, C_in/groups, \*K], T> (Required)
  
      * Filter weights.
      * ``C_in`` is the number of input channels.
      * ``C_in`` must be divisible by ``groups``.
      * ``K`` are kernel sizes. For example, ``K = [KH, KW]`` for 2-D convolution.
      * When ``dilations`` is not all ``1``, ``weight`` has to be ``const``
        at compile time
  
  strides: const tensor<[S], i32> (Optional)
  
      * Default to one vector of length equal to the number of spatial dimensions.
      * Strides along each of the spatial dimensions.
      * ``S == len(d_in)``.
  
  pad_type: const str (Required)
  
      Must be one of the following:
  
          * ``valid``: No padding. This is equivalent to custom pad with
            ``pad[2*i] == pad[2*i+1] == 0, for i=0,...,len(d_in)-1``.
          * ``custom``: Specify custom padding in the parameter ``pad``.
          * ``same``: Input is padded such that out spatial shapes are
            ``d_out[i] = ceil(d_in[i] / strides[i])``.
          * ``same_lower``: Similar to ``same`` but the padding
            will place extra rows/cols on the top/left if the padding amount is odd.
  
      Specifically, for ``i = 0,..,,len(d_in)-1``, the equivalent paddings are
      calculated as follows:
  
          * ``dilated_kernel = (K[i] - 1) * dilate[i] + 1``
          * If ``dilated_kernel`` is odd,
            ``padding[2*i] = padding[2*i+1] = floor(dilated_kernel / 2)``
          * Otherwise:
            ``padding[2*i] = ceil((dilated_kernel - 1) / 2)``,
            ``padding[2*i+1] = floor((dilated_kernel - 1) / 2)``
  
  pad: const tensor<[P], i32> (Optional. Default to all zeros)
  
      * ``len(P) = 2 * len(d_in)``
      * ``pad`` should be specified if and only if ``pad_type == custom``,
        otherwise errors occur.
      * ``pad`` represents the number of elements to pad before and after each
        dimension. Specifically, ``pad[0], pad[1]`` are the pad size before / after
        spatial dimension 0, ``pad[2], pad[3]`` are the pad size before / after
        spatial dimension 1, etc.
  
  dilations: const tensor<[S], i32> (Optional. Default to all 1s)
  
      * Dilation value along each spatial dimension in ``d_in``.
        See `visualization <https://github.com/vdumoulin/conv_arithmetic/blob/master/README.md>`_.
      * ``S == len(d_in)``.
  
  groups: const tensor<[], i32> (Optional, default to 1)
  
      * Input and output channels are split by ``groups``.
      * ``C_in`` must be divisible by ``groups``.
      * Maximum value for group is ``C_in``, in which case it is a depthwise
        convolution.
  
      For examples (assuming ``C_in = 16, C_out = 32``):
  
          * ``groups == 1``, ``weight`` has shape ``[32, 16, KH, KW]``: All input
            channels are convolved with the ``weight`` kernel to produce all output
            channels.
          * ``groups == 2``, ``weight`` has shape ``[32, 8, KH, KW]``: Input
            channels 0~7 are convolved with half of the ``weight`` kernel to produce
            output channels 0~15. Similarly, input channels 8~15 are convolved with
            the other half of ``weight`` to product output channels 16~31.
          * ``groups == C_in``, ``weight`` has shape ``[32, 1, KH, KW]``: Each input
            channel is convolved with its own set of filters and each produce
            ``C_out / C_in = 2`` channels. This is equivalent to depthwise
            convolution.
  
  bias: const tensor<[C_out],T> (Optional, default to all 0)
      * Bias along output channels.
  
  Returns
  -------
  tensor<[n, C_out, \*d_out], T>
      * Output activation has the same rank and spatial dimension as the input.
        That is, ``len(d_out) == len(d_in)``.
      * For ``i=0,..,len(d_in)-1, d_out[i] = floor [(D_in[i] + pad[2*i] +
        pad[2*i+1] - (K[i]-1)*dilations[i] - 1) / strides[i] ] + 1``.
  
  Attributes
  ----------
  T: fp16, fp32
  
  See Also
  --------
  conv_transpose
class_docstr_tok: ["Perform","convolution","over","input",".","Supports","1-D",",","2-D",",","and","3-D","convolution",".","Parameters","--","--","--","--","--","x",":","tensor","<","[","n",",","C_in",",","\\","*","d_in","]",",","T",">","(","Required",")","*","``","d_in","``","are","(","possibly","runtime-determined",")","spatial","dimensions",".","For","example",",","``","d_in","=","[","224",",","224","]","``","for","2D","convolution",".","*","``","1","<","=","len","(","d_in",")","<","=","3","``",".","*","``","C_in","``","is","the","number","of","input","channels","or","depth","dimensions",".","*","``","n","``","is","the","batch","dimension",".","weight",":","tensor","<","[","C_out",",","C_in\/groups",",","\\","*","K","]",",","T",">","(","Required",")","*","Filter","weights",".","*","``","C_in","``","is","the","number","of","input","channels",".","*","``","C_in","``","must","be","divisible","by","``","groups","``",".","*","``","K","``","are","kernel","sizes",".","For","example",",","``","K","=","[","KH",",","KW","]","``","for","2-D","convolution",".","*","When","``","dilations","``","is","not","all","``","1","``",",","``","weight","``","has","to","be","``","const","``","at","compile","time","strides",":","const","tensor","<","[","S","]",",","i32",">","(","Optional",")","*","Default","to","one","vector","of","length","equal","to","the","number","of","spatial","dimensions",".","*","Strides","along","each","of","the","spatial","dimensions",".","*","``","S","==","len","(","d_in",")","``",".","pad_type",":","const","str","(","Required",")","Must","be","one","of","the","following",":","*","``","valid","``",":","No","padding",".","This","is","equivalent","to","custom","pad","with","``","pad","[","2","*","i","]","==","pad","[","2","*","i+1","]","==","0",",","for","i=0",",","...",",","len","(","d_in",")","-1","``",".","*","``","custom","``",":","Specify","custom","padding","in","the","parameter","``","pad","``",".","*","``","same","``",":","Input","is","padded","such","that","out","spatial","shapes","are","``","d_out","[","i","]","=","ceil","(","d_in","[","i","]","\/","strides","[","i","]",")","``",".","*","``","same_lower","``",":","Similar","to","``","same","``","but","the","padding","will","place","extra","rows\/cols","on","the","top\/left","if","the","padding","amount","is","odd",".","Specifically",",","for","``","i","=","0",",","..",",",",len","(","d_in",")","-1","``",",","the","equivalent","paddings","are","calculated","as","follows",":","*","``","dilated_kernel","=","(","K","[","i","]","-","1",")","*","dilate","[","i","]","+","1","``","*","If","``","dilated_kernel","``","is","odd",",","``","padding","[","2","*","i","]","=","padding","[","2","*","i+1","]","=","floor","(","dilated_kernel","\/","2",")","``","*","Otherwise",":","``","padding","[","2","*","i","]","=","ceil","(","(","dilated_kernel","-","1",")","\/","2",")","``",",","``","padding","[","2","*","i+1","]","=","floor","(","(","dilated_kernel","-","1",")","\/","2",")","``","pad",":","const","tensor","<","[","P","]",",","i32",">","(","Optional",".","Default","to","all","zeros",")","*","``","len","(","P",")","=","2","*","len","(","d_in",")","``","*","``","pad","``","should","be","specified","if","and","only","if","``","pad_type","==","custom","``",",","otherwise","errors","occur",".","*","``","pad","``","represents","the","number","of","elements","to","pad","before","and","after","each","dimension",".","Specifically",",","``","pad","[","0","]",",","pad","[","1","]","``","are","the","pad","size","before","\/","after","spatial","dimension","0",",","``","pad","[","2","]",",","pad","[","3","]","``","are","the","pad","size","before","\/","after","spatial","dimension","1",",","etc",".","dilations",":","const","tensor","<","[","S","]",",","i32",">","(","Optional",".","Default","to","all","1s",")","*","Dilation","value","along","each","spatial","dimension","in","``","d_in","``",".","See","`","visualization","<","https",":","\/\/github.com\/vdumoulin\/conv_arithmetic\/blob\/master\/README.md",">","`","_",".","*","``","S","==","len","(","d_in",")","``",".","groups",":","const","tensor","<","[","]",",","i32",">","(","Optional",",","default","to","1",")","*","Input","and","output","channels","are","split","by","``","groups","``",".","*","``","C_in","``","must","be","divisible","by","``","groups","``",".","*","Maximum","value","for","group","is","``","C_in","``",",","in","which","case","it","is","a","depthwise","convolution",".","For","examples","(","assuming","``","C_in","=","16",",","C_out","=","32","``",")",":","*","``","groups","==","1","``",",","``","weight","``","has","shape","``","[","32",",","16",",","KH",",","KW","]","``",":","All","input","channels","are","convolved","with","the","``","weight","``","kernel","to","produce","all","output","channels",".","*","``","groups","==","2","``",",","``","weight","``","has","shape","``","[","32",",","8",",","KH",",","KW","]","``",":","Input","channels","0~7","are","convolved","with","half","of","the","``","weight","``","kernel","to","produce","output","channels","0~15",".","Similarly",",","input","channels","8~15","are","convolved","with","the","other","half","of","``","weight","``","to","product","output","channels","16~31",".","*","``","groups","==","C_in","``",",","``","weight","``","has","shape","``","[","32",",","1",",","KH",",","KW","]","``",":","Each","input","channel","is","convolved","with","its","own","set","of","filters","and","each","produce","``","C_out","\/","C_in","=","2","``","channels",".","This","is","equivalent","to","depthwise","convolution",".","bias",":","const","tensor","<","[","C_out","]",",","T",">","(","Optional",",","default","to","all","0",")","*","Bias","along","output","channels",".","Returns","--","--","--","-","tensor","<","[","n",",","C_out",",","\\","*","d_out","]",",","T",">","*","Output","activation","has","the","same","rank","and","spatial","dimension","as","the","input",".","That","is",",","``","len","(","d_out",")","==","len","(","d_in",")","``",".","*","For","``","i=0",",","..",",","len","(","d_in",")","-1",",","d_out","[","i","]","=","floor","[","(","D_in","[","i","]","+","pad","[","2","*","i","]","+","pad","[","2","*","i+1","]","-","(","K","[","i","]","-1",")","*","dilations","[","i","]","-","1",")","\/","strides","[","i","]","]","+","1","``",".","Attributes","--","--","--","--","--","T",":","fp16",",","fp32","See","Also","--","--","--","--","conv_transpose"]
code: def type_inference(self):
      inshape = self.x.shape
      f_shape = self.weight.shape
      kernel_shape = f_shape[2:]
      C_out = f_shape[0]
      C_in = self.x.shape[1]
      groups = self.groups.val
  
      if self.bias is not None and (
          len(self.bias.shape) > 1 or self.bias.shape[0] != C_out
      ):
          msg = "# of bias values {} not equal to # output channels {}"
          raise ValueError(msg.format(self.bias.shape[0], C_out))
      if C_in % groups != 0:
          msg = "# of input channels {} not divisible by groups {}"
          raise ValueError(msg.format(C_in, groups))
      if C_in // groups != self.weight.shape[1]:
          msg = "C_in / groups = {}/{} != weight[1] ({})"
          raise ValueError(
              msg.format(C_in, groups, self.weight.shape[1])
          )
  
      strides = self.strides.val
      dilations = self.dilations.val
  
      # The same_lower padding is not supported in iOS15
      if (
          curr_opset_version() == _IOS15_TARGET
          and self.pad_type.val == "same_lower"
      ):
          msg = "iOS15 version of conv does not support pad_type = `same_lower`"
          raise ValueError(msg)
  
      # Ignore self.pad if pad_type != custom
      custom_pad = (
          None if self.pad_type.val != "custom" else self.pad.val
      )
  
      is_weight_dynamic = not self.weight.is_descendant_of_const
      if is_weight_dynamic and any(
          [True if d > 1 else False for d in dilations]
      ):
          raise ValueError(
              "Convolution with dynamic weights does not support dilations!"
          )
  
      N = inshape[0]
      C_out = f_shape[0]
      # spatial dimensions
      d_out_shape = spatial_dimensions_out_shape(
          pad_type=self.pad_type.val,
          input_shape=inshape[2:],
          kernel_shape=kernel_shape,
          strides=strides,
          dilations=dilations,
          custom_pad=custom_pad,
      )
      retshape = [N, C_out] + d_out_shape
      return types.tensor(self.x.dtype, tuple(retshape))
  
file_path: coremltools/coremltools/converters/mil/mil/ops/defs/iOS15/conv.py
imports: from coremltools.converters.mil.mil import Operation, types
  from coremltools.converters.mil.mil.block import curr_opset_version
  from coremltools.converters.mil.mil.input_type import DefaultInputs, InputSpec, TensorInputType
  from coremltools.converters.mil.mil.ops.defs._op_reqs import register_op
  from coremltools.converters.mil.mil.ops.defs._utils import spatial_dimensions_out_shape
  from coremltools.converters.mil.mil.ops.defs.iOS15 import _IOS15_TARGET
label_desc: Use image node_id 2 for calling the conv obj's underlying member method code with example usage: obj.type_inference() and returns: types