parameters: (n: Node, module_instance)
docstring: Given a Conv2D instance and a node check the following conditions:
      - the input type can be expanded to a size 4 tensor: t =  (x_1, x_2, H, W)
      - the current node type can be expanded to a size 4 tensor: t' =  (x_1', x_2', x_3', x_4')
      - x_2 is consistent with the module's in_channels
      - let o = (x_1, out_channels, H_out, W_out)
      then the output is the greatest upper bound of o and the existing node type t'.
docstring_summary: Given a Conv2D instance and a node check the following conditions:
      - the input type can be expanded to a size 4 tensor: t =  (x_1, x_2, H, W)
      - the current node type can be expanded to a size 4 tensor: t' =  (x_1', x_2', x_3', x_4')
      - x_2 is consistent with the module's in_channels
      - let o = (x_1, out_channels, H_out, W_out)
      then the output is the greatest upper bound of o and the existing node type t'.
docstring_tokens: Given a Conv2D instance and a node check the following conditions : - the input type can be expanded to a size 4 tensor : t = ( x_1 x_2 H W ) - the current node type can be expanded to a size 4 tensor : t = ( x_1 x_2 x_3 x_4 ) - x_2 is consistent with the module s in_channels - let o = ( x_1 out_channels H_out W_out ) then the output is the greatest upper bound of o and the existing node type t .
function: def conv2d_inference_rule(n: Node, module_instance):
      """
      Given a Conv2D instance and a node check the following conditions:
      - the input type can be expanded to a size 4 tensor: t =  (x_1, x_2, H, W)
      - the current node type can be expanded to a size 4 tensor: t' =  (x_1', x_2', x_3', x_4')
      - x_2 is consistent with the module's in_channels
      - let o = (x_1, out_channels, H_out, W_out)
      then the output is the greatest upper bound of o and the existing node type t'.
      """
      assert isinstance(n.args[0], Node)
      n.args[0].type = expand_to_tensor_dim(n.args[0].type, 4)
      arg_type = n.args[0].type
      curr_node_type = expand_to_tensor_dim(n.type, 4)
  
      if is_consistent(arg_type.__args__[1], module_instance.in_channels):
          w_in = arg_type.__args__[3]
          h_in = arg_type.__args__[2]
          h_out = calculate_out_dimension(h_in, module_instance, 0)
          w_out = calculate_out_dimension(w_in, module_instance, 1)
          new_type = TensorType((arg_type.__args__[0], module_instance.out_channels, h_out, w_out))
          gub = get_greatest_upper_bound(new_type, curr_node_type)
          n.type = gub
          return n.type
      else:
          raise TypeError(f'Cannot apply {module_instance} with input type { arg_type} and existing type {n.type} on {n}')
function_tokens: def conv2d_inference_rule ( n : Node , module_instance ) : assert isinstance ( n . args [ 0 ] , Node ) n . args [ 0 ] . type = expand_to_tensor_dim ( n . args [ 0 ] . type , 4 ) arg_type = n . args [ 0 ] . type curr_node_type = expand_to_tensor_dim ( n . type , 4 ) if is_consistent ( arg_type . __args__ [ 1 ] , module_instance . in_channels ) : w_in = arg_type . __args__ [ 3 ] h_in = arg_type . __args__ [ 2 ] h_out = calculate_out_dimension ( h_in , module_instance , 0 ) w_out = calculate_out_dimension ( w_in , module_instance , 1 ) new_type = TensorType ( ( arg_type . __args__ [ 0 ] , module_instance . out_channels , h_out , w_out ) ) gub = get_greatest_upper_bound ( new_type , curr_node_type ) n . type = gub return n . type else : raise TypeError ( f'Cannot apply {module_instance} with input type { arg_type} and existing type {n.type} on {n}' )