class_docstr: Identify the pattern of a ``rank-0`` binary elementwise operation followed by an ``expand_dims`` op.
  In the MIL backend, the output of the ``elementwise`` op becomes rank 1. Hence, an ``expand_dims`` op
  should be added after both of the ``rank-0`` tensors, and the final ``expand_dims`` should be removed.
  If the output var of the binary elementwise op is consumed by more than one op, a ``squeeze`` op
  is inserted.
  
  `Input`
  
  .. code-block::
  
          [...](rank-0) --> sub --> expand_dims (axes=[0]) --> [...]
                             ^   |
                             |   |--> op2
                             |   |
                             |   |--> op3
                             |
                       [scalar const]
  
  `Output`
  
  .. code-block::
  
          [...](rank-0) --> expand_dims (axes=[0]) --> sub --> [...]
                                                        ^   |
                                                        |   |--> squeeze ---> op2
                                                        |                |
                                                        |                |--> op3
                                                        |
                                                  expand_dims (axes=[0])
                                                        ^
                                                        |
                                                        |
                                                  [scalar const]
code: def _rank0_expand_dims_swap(self, block):
      fusion_occurred = False
      for op in list(block.operations):
          for b in op.blocks:
              block_changed = True
              while block_changed:
                  block_changed = self._rank0_expand_dims_swap(b)
          if len(op.blocks) > 0:
              # This op can't be elementwise binary ops
              continue
  
          if op.op_type in [
              "add",
              "sub",
              "mul",
              "real_div",
              "floor_div",
          ]:
              fusion_occurred = self._try_to_transform(op, block)
              # has to break as the downstream iterator is affected.
              if fusion_occurred:
                  return fusion_occurred
      return fusion_occurred
  
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 3 for calling the rank0_expand_dims_swap obj's underlying member method code with example usage: obj._rank0_expand_dims_swap(block) and returns: fusion_occurred, fusion_occurred