class_docstr: Fold ``mul`` + ``add`` into a ``batchnorm``
  if the ``const`` feeding into the ``mul``/``add`` is of shape ``(1,C,1,1)`` or ``(C,1,1)``
  and input to ``mul`` is of rank 4.
  
  .. code-block::
  
      Given:
               [Const]   [Const]
                  |         |
                  V         V
      [...] --> [Mul] --> [Add] --> [...]
  
      That is,
  
          %2 = op1(%1)
          %3 = mul(%2, constant)
          %4 = add(%3, constant)
          %5 = op2(%4)
          ...
  
      Result:
  
      [...] --> [BatchNorm] --> [...]
  
      That is,
          %2 = op1(%1)
          %4 = batchnorm(%2)
          %5 = op2(%4)
          ...
code: def apply(self, prog):
      for f in prog.functions.values():
          block_changed = True
          while block_changed:
              block_changed = self._fuse_elementwise_to_batchnorm_block(
                  f
              )
  
imports: import numpy
  from coremltools.converters.mil.mil import Block
  from coremltools.converters.mil.mil import Builder
  from coremltools.converters.mil.mil import Operation, Var
  from coremltools.converters.mil.mil import types
  from coremltools.converters.mil.mil.ops.defs._utils import broadcast_shapes
  from coremltools.converters.mil.mil.passes.graph_pass import AbstractGraphPass
  from coremltools.converters.mil.mil.passes.helper import block_context_manager
  from coremltools.converters.mil.mil.passes.pass_registry import register_pass
label_desc: Use image node_id 1 for calling the fuse_elementwise_to_batchnorm obj's underlying member method code with example usage: obj.apply(prog) without return types