code: def EXPERIMENTAL__find_bicliques(
      df,
      k,
      offset=0,
      max_iter=-1,
      support=1.0,
      min_features=1,
      min_machines=10,
  ):
      """
      Find the top k maximal bicliques
  
      Parameters
      ----------
      df :  cudf:DataFrame
          A dataframe containing the bipartite graph edge list
          Columns must be called 'src', 'dst', and 'flag'
  
      k  :  int
          The max number of bicliques to return
          -1 mean all
  
      offset : int
  
      Returns
      -------
      B : cudf.DataFrame
          A dataframe containing the list of machine and features.  This is not
          the full edge list to save space.  Since it is a biclique, it is ease
          to recreate the edges
  
          B['id']    - a cluster ID (this is a one up number - up to k)
          B['vert']  - the vertex ID
          B['type']  - 0 == machine, 1 == feature
  
  
      S : cudf.DataFrame
          A dataframe of statistics on the returned info.
          This dataframe is (relatively small) of size k.
  
          S['id']       - the cluster ID
          S['total']    - total vertex count
          S['machines'] - number of machine nodes
          S['features'] - number of feature vertices
          S['bad_ration'] - the ratio of bad machine / total machines
      """
      # must be factor of 10
      PART_SIZE = int(1000)
  
      x = [col for col in df.columns]
      if "src" not in x:
          raise NameError("src column not found")
      if "dst" not in x:
          raise NameError("dst column not found")
      if "flag" not in x:
          raise NameError("flag column not found")
  
      if support > 1.0 or support < 0.1:
          raise NameError("support must be between 0.1 and 1.0")
  
      # this removes a prep step that offset the values for CUDA process
      if offset > 0:
          df["dst"] = df["dst"] - offset
  
      # break the data into chunks to improve join/search performance
      src_by_dst, num_parts = _partition_data_by_feature(df, PART_SIZE)
  
      # Get a list of all the dst (features) sorted by degree
      f_list = _count_features(df, True)
  
      # create a dataframe for the answers
      bicliques = cudf.DataFrame()
      stats = cudf.DataFrame()
  
      # create a dataframe to help prevent duplication of work
      machine_old = cudf.DataFrame()
  
      # create a dataframe for stats
      stats = cudf.DataFrame()
  
      answer_id = 0
      iter_max = len(f_list)
  
      if max_iter != -1:
          iter_max = max_iter
  
      # Loop over all the features (dst) or until K is reached
      for i in range(iter_max):
          # pop the next feature to process
          feature = f_list["dst"][i]
          degree = f_list["count"][i]
  
          # compute the index to this item (which dataframe chunk is in)
          idx = int(feature / PART_SIZE)
  
          # get all machines that have this feature
          machines = get_src_from_dst(src_by_dst[idx], feature)
  
          # if this set of machines is the same as the last, skip this feature
          if not is_same_as_last(machine_old, machines):
              # now from those machines, hop out to the list of all the features
              feature_list = get_all_feature(
                  src_by_dst, machines, num_parts
              )
  
              # summarize occurances
              ic = _count_features(feature_list, True)
  
              goal = int(degree * support)  # NOQA
  
              # only get dst nodes with the same degree
              c = ic.query("count >= @goal")
  
              # need more than X feature to make a biclique
              if len(c) > min_features:
                  if len(machines) >= min_machines:
                      bicliques, stats = update_results(
                          machines, c, answer_id, bicliques, stats
                      )
  
                      answer_id = answer_id + 1
  
          # end - if same
  
          machine_old = machines
  
          if k > -1:
              if answer_id == k:
                  break
  
      # end for loop
  
      # All done, reset data
      if offset > 0:
          df["dst"] = df["dst"] + offset
  
      return bicliques, stats
  
file_path: cugraph/python/cugraph/cugraph/experimental/structure/bicliques.py
imports: import cudf
  import numpy
  from collections import OrderedDict
label_desc: Use image node_id 1 for calling a global function with example usage: EXPERIMENTAL__find_bicliques(df, k, offset, max_iter, support, min_features, min_machines) and returns: bicliques,  stats