code: def compare_shapes(
      mlmodel, input_key_values, expected_outputs, pred=None
  ):
      """
      Inputs:
          - mlmodel: MLModel.
  
          - input_key_values: str -> np.array or PIL.Image. Keys must match those in
            input_placeholders.
  
          - expected_outputs: dict[str, np.array].
  
          - pred: Prediction to use, if it has already been computed.
      """
      if _IS_MACOS:
          if not pred:
              pred = run_core_ml_predict(mlmodel, input_key_values)
          for o, expected in expected_outputs.items():
              coreml_out = _get_coreml_out_from_dict(pred, o)
  
              # output is dictionary (for classifier)
              if isinstance(coreml_out, dict) and isinstance(
                  expected, dict
              ):
                  assert len(coreml_out) == len(expected)
                  continue
  
              # output is numpy objects
              np_types = (np.generic, np.ndarray)
              if isinstance(coreml_out, np_types) and isinstance(
                  expected, np_types
              ):
                  msg = "Output: {}. expected shape {} != actual shape {}".format(
                      o, expected.shape, coreml_out.shape
                  )
                  # Core ML does not support scalar as output
                  # remove this special case when support is added
                  if expected.shape == () and coreml_out.shape == (1,):
                      continue
                  assert coreml_out.shape == expected.shape, msg
  
                  # Validate the shape consistency across runtime returned values and
                  # the output information in the mlprogram proto.
                  spec = mlmodel.get_spec()
                  if spec.WhichOneof("Type") == "mlProgram":
                      # The proto output and the runtime outputs are different for classifier
                      if spec.description.predictedFeatureName != "":
                          continue
                      proto_shape = _get_proto_output_shape(spec, o)
                      if proto_shape != []:
                          assert proto_shape == list(
                              coreml_out.shape
                          ), f"the output shape, for output named {o}, returned by the model is {coreml_out.shape} which does match with the shape present in the proto spec, which is {proto_shape}"
                  continue
  
              # output is other types (for classifier)
              assert type(coreml_out) == type(expected)
  
imports: import itertools
  import copy
  import os
  from functools import partial
  from pathlib import Path
  from typing import Dict, List, Tuple
  import numpy
  import pytest
  from PIL import Image
  import coremltools
  import coremltools.models.utils
  from coremltools._deps import _IS_MACOS
  from coremltools.converters.mil.mil import Block, Function, Program
  from coremltools.converters.mil.mil.passes.defs.preprocess import NameSanitizer
  from coremltools.converters.mil.mil.passes.defs.quantization import AbstractQuantizationPass
  from coremltools.converters.mil.mil.passes.pass_registry import PASS_REGISTRY
  from coremltools.proto import FeatureTypes_pb2
label_desc: Use image node_id 21 for calling a global function with example usage: compare_shapes(mlmodel, input_key_values, expected_outputs, pred) without return types