code: def _get_feasibility(G, sources, components=None, depth_limit=None):
      """
      Evaluate the feasibility for breadth first traversal from multiple sources
      in a graph.
  
      Parameters
      ----------
      G : cugraph.Graph
          The adjacency list will be computed if not already present.
  
      sources :  cudf.Series
          Subset of vertices from which the traversals start. A BFS is run for
          each source in the Series.
          The size of the series should be at least one and cannot exceed
          the size of the graph.
  
      depth_limit : Integer, optional, default=None
          Limit the depth of the search. Terminates if no more vertices are
          reachable within the distance of depth_limit
  
      components : cudf.DataFrame, optional, default=None
          GPU Dataframe containing the component information.
          Passing this information may impact the return type.
          When no component information is passed BFS uses one component
          behavior settings.
  
          components['vertex'] : cudf.Series
              vertex IDs
          components['color'] : cudf.Series
              component IDs/color for vertices.
  
      Returns
      -------
      mem_footprint : integer
          Estimated memory foot print size in Bytes
      """
  
      # Fixme not implemented in RMM yet
      # using 96GB upper bound for now
      # mem = get_device_memory_info()
      mem = 9.6e10
      n_sources = sources.size
      V = G.number_of_vertices()
      E = G.number_of_edges()
      mean_component_sz = V
      n_components = 1
  
      # Retreive types
      size_of_v = 4
      size_of_e = 4
      size_of_w = 0
      if G.adjlist.weights is not None:
          if G.adjlist.weights.dtype is np.float64:
              size_of_w = 8
          else:
              size_of_w = 4
      if G.adjlist.offsets.dtype is np.float64:
          size_of_v = 8
      if G.adjlist.indices.dtype is np.float64:
          size_of_e = 8
  
      # Graph size
      G_sz = E * size_of_e + E * size_of_w + V * size_of_v
  
      # The impact of depth limit depends on the sparsity
      # pattern and diameter. We cannot leverage it without
      # traversing the full dataset a the moment.
  
      # dense output
      output_sz = n_sources * 2 * V * size_of_v
  
      # sparse output
      if components is not None:
          tmp = components["color"].value_counts()
          n_components = tmp.size
          if n_sources / n_components > 100:
              warnings.warn(
                  "High number of seeds per component result in large output."
              )
          mean_component_sz = tmp.mean()
          output_sz = mean_component_sz * n_sources * 2 * size_of_e
  
      # counting 10% for context, handle and temporary allocations
      mem_footprint = (G_sz + output_sz) * 1.1
      if mem_footprint > mem:
          warnings.warn(
              f"Cannot execute in-memory :{mem_footprint} Bytes"
          )
  
      return mem_footprint
  
imports: import numpy
  import cudf
  import warnings
label_desc: Use image node_id 1 for calling a global function with example usage: _get_feasibility(G, sources, components, depth_limit) and returns: mem_footprint