code: def Save(
      dir,
      func,
      inputs,
      outputs,
      batch_size=1,
      use_external_files_to_store_parameters=False,
  ):
      if not os.path.exists(dir):
          os.makedirs(dir)
      model_file_path = os.path.join(dir, model_file)
      func.save(
          model_file_path,
          C.ModelFormat.ONNX,
          use_external_files_to_store_parameters=use_external_files_to_store_parameters,
      )
      onnx_model = onnx.load(model_file_path)
      onnx_model_description = onnx_model.graph.doc_string
      uid_name_map = dict(
          tuple(x[3:-3].split(", "))
          for x in re.findall(r"<<<[^>]*>>>", onnx_model_description)[
              1:
          ]
      )
      # input names are mapped from uid to names (requested by skype team)
      input_names = [
          x.uid if not x.name else x.name for x in func.arguments
      ]
      # handle block outputs
      output_names = []
      block_uid_count = {}
  
      # when block are exported as a single onnx node, the onnx node output takes name from block node output.
      # when block are exported by exporting nodes within that block, the onnx node output takes name from inner node output.
      # the cntk node that provides the name will have its uid stored in the uid_name_map.
      # this function tries to find the deepest inner output node whose uid is in uid_name_map.
      def find_deepest_inner_block_output(output):
          # might be a placeholder
          if not output.is_output:
              return False, output
          if output.owner and output.owner.is_block:
              block_uid_count[output.owner.uid] = (
                  block_uid_count[output.owner.uid] + 1
                  if output.owner.uid in block_uid_count
                  else 0
              )
              found, inner_output = find_deepest_inner_block_output(
                  output.owner.block_root.outputs[
                      block_uid_count[output.owner.uid]
                  ]
              )
              if found:
                  return True, inner_output
          return output.uid in uid_name_map, output
  
      for output in func.outputs:
          _, output = find_deepest_inner_block_output(output)
          output_names.append(uid_name_map[output.uid])
  
      test_data_dir = os.path.join(dir, data_dir)
      if not os.path.exists(test_data_dir):
          os.makedirs(test_data_dir)
  
      SaveData(
          test_data_dir,
          "input",
          onnx_model.graph.input,
          func.arguments,
          inputs,
          input_names,
          batch_size,
      )
      SaveData(
          test_data_dir,
          "output",
          onnx_model.graph.output,
          func.outputs,
          outputs,
          output_names,
          batch_size,
      )
  
file_path: CNTK/bindings/python/cntk/tests/onnx_model_test.py
imports: import cntk
  import numpy
  import pytest
  import os
  import re
  import shutil
  import time
  import tempfile
  from onnx import numpy_helper
  from .onnx_verify_helper import generate_sequence_data, generate_sequential_data, generate_sparse_data, verify_results_with_onnxruntime, generate_sparse_data_non_seq
  from .onnx_test_helper import find_onnx_value_info_proto_with_matching_name, save_cntk_data_as_onnx_tensor, save_test_data, save_onnx_model_with_validation_data
  from .onnx_op_test import verify_sequence_model
label_desc: Use image node_id 4 for calling a global function with example usage: Save(dir, func, inputs, outputs, batch_size, use_external_files_to_store_parameters) and returns: unknown,  output, False,  output, True,  inner_output