code: def assign(
      self, cur_assigns: Dict[str, BandType] = None
  ) -> Dict[ChunkData, BandType]:
      graph = self._chunk_graph
      assign_result = dict()
      cur_assigns = cur_assigns or dict()
      # assigned by expect worker or band
      initial_assigned_op_keys = set(cur_assigns)
  
      op_key_to_chunks = defaultdict(list)
      for chunk in graph:
          op_key_to_chunks[chunk.op.key].append(chunk)
  
      op_keys = OrderedSet(self._op_keys)
      chunk_to_assign = [
          op_key_to_chunks[op_key][0]
          for op_key in op_keys
          if op_key not in cur_assigns
      ]
      assigned_counts = defaultdict(lambda: 0)
      for band in cur_assigns.values():
          assigned_counts[band] += 1
  
      # build undirected graph
      undirected_chunk_graph = self._build_undirected_chunk_graph(
          chunk_to_assign
      )
  
      # calculate the number of chunks to be assigned to each band
      # given number of bands and existing assignments
      band_quotas = self._calc_band_assign_limits(
          len(chunk_to_assign) + sum(assigned_counts.values()),
          assigned_counts,
      )
  
      # calculate expected descendant count (spread range) of
      # every band and subtract assigned number from it
      average_spread_range = (
          len(graph) * 1.0 / len(self.get_device_band_slots())
      )
      spread_ranges = defaultdict(lambda: average_spread_range)
      # assign from other chunks to be assigned
      # TODO: sort by what?
      sorted_candidates = chunk_to_assign.copy()
      while max(band_quotas.values()):
          band = max(band_quotas, key=lambda k: band_quotas[k])
          cur = sorted_candidates.pop()
          while cur.op.key in cur_assigns:
              cur = sorted_candidates.pop()
          self._assign_by_bfs(
              undirected_chunk_graph,
              cur,
              band,
              band_quotas,
              spread_ranges,
              op_keys,
              cur_assigns,
          )
  
      key_to_assign = {
          n.op.key for n in chunk_to_assign
      } | initial_assigned_op_keys
      for op_key, band in cur_assigns.items():
          if op_key in key_to_assign:
              for chunk in op_key_to_chunks[op_key]:
                  assign_result[chunk] = band
  
      return assign_result
  
imports: from abc import ABC, abstractmethod
  from collections import defaultdict
  from operator import itemgetter
  from typing import List, Dict, Union
  import numpy
  from ....core import ChunkGraph, ChunkData
  from ....core.operand import Operand, Fetch
  from ....lib.ordered_set import OrderedSet
  from ....resource import Resource
  from ....typing import BandType
  from ....utils import implements
label_desc: Use image node_id 5 for calling the GraphAssigner obj's underlying member method code with example usage: obj.assign(cur_assigns) and returns: assign_result