code: def _terminal_node_ids(
      layers: List[List[node_proto_view.NodeProtoView]],
      skipped_node_ids: Set[str],
  ) -> Set[str]:
      """Returns nodes across all layers that have no downstream nodes to run."""
      terminal_node_ids: Set[str] = set()
      for layer_nodes in layers:
          for node in layer_nodes:
              # Ignore skipped nodes.
              if node.node_info.id in skipped_node_ids:
                  continue
              if not node.downstream_nodes or all(
                  downstream_node in skipped_node_ids
                  for downstream_node in node.downstream_nodes
              ):
                  terminal_node_ids.add(node.node_info.id)
      return terminal_node_ids
  
imports: import collections
  import textwrap
  from typing import Callable, Dict, List, Mapping, Optional, Set
  from absl import logging
  from tfx.orchestration import node_proto_view
  from tfx.orchestration.experimental.core import mlmd_state
  from tfx.orchestration.experimental.core import pipeline_state
  from tfx.orchestration.experimental.core import service_jobs
  from tfx.orchestration.experimental.core import task
  from tfx.orchestration.experimental.core import task_gen
  from tfx.orchestration.experimental.core import task_gen_utils
  from tfx.orchestration import mlmd_connection_manager
  from tfx.orchestration.portable.input_resolution import exceptions
  from tfx.orchestration.portable.mlmd import execution_lib
  from tfx.proto.orchestration import pipeline_pb2
  from tfx.utils import status
  from tfx.utils import topsort
  from ml_metadata.proto import metadata_store_pb2
label_desc: Use image node_id 3 for calling a global function with example usage: _terminal_node_ids(layers, skipped_node_ids) and returns: terminal_node_ids