code: def _prepare(self):
      if self._mode == "homo":
          if self._role == "arbiter":
              batch_info = self._ctx.arbiter.get("batch_info")
              self._batch_size = batch_info["batch_size"]
              self._batch_num = batch_info["batch_num"]
          elif self._role == "guest":
              self._batch_num = (
                  len(self._dataset) + self._batch_size - 1
              ) // self._batch_size
              self._ctx.arbiter.put("batch_num", self._batch_num)
      elif self._mode == "local":
          self._batch_num = (
              len(self._dataset) + self._batch_size - 1
          ) // self._batch_size
      elif self._mode == "hetero":
          # NOTE: index should be align first, using after doing psi
          if self._role != "arbiter":
              self._batch_num = (
                  len(self._dataset) + self._batch_size - 1
              ) // self._batch_size
              if self._role == "guest" and self._sync_arbiter:
                  self._ctx.arbiter.put("batch_num", self._batch_num)
          elif self._sync_arbiter:
              self._batch_num = self._ctx.guest.get("batch_num")
  
      if self._role == "arbiter":
          return
  
      if self._batch_size == len(self._dataset):
          self._batch_splits.append(
              BatchEncoding(self._dataset, batch_id=0)
          )
      else:
          if self._mode in ["homo", "local"] or self._role == "guest":
              indexer = sorted(
                  list(
                      self._dataset.get_indexer(
                          target="sample_id"
                      ).collect()
                  )
              )
              if self._shuffle:
                  random.seed = self._random_state
                  random.shuffle(indexer)
  
              for i, iter_ctx in self._ctx.sub_ctx(
                  "dataloader_batch"
              ).ctxs_range(self._batch_num):
                  batch_indexer = indexer[
                      self._batch_size * i : self._batch_size * (i + 1)
                  ]
                  batch_indexer = self._ctx.computing.parallelize(
                      batch_indexer,
                      include_key=True,
                      partition=self._dataset.block_table.num_partitions,
                  )
  
                  sub_frame = self._dataset.loc(
                      batch_indexer, preserve_order=False
                  )
  
                  if self._mode == "hetero" and self._role == "guest":
                      iter_ctx.hosts.put(
                          "batch_indexes",
                          sub_frame.get_indexer(target="sample_id"),
                      )
  
                  self._batch_splits.append(
                      BatchEncoding(sub_frame, batch_id=i)
                  )
  
          elif self._mode == "hetero" and self._role == "host":
              for i, iter_ctx in self._ctx.sub_ctx(
                  "dataloader_batch"
              ).ctxs_range(self._batch_num):
                  batch_indexes = iter_ctx.guest.get("batch_indexes")
                  sub_frame = self._dataset.loc(
                      batch_indexes, preserve_order=True
                  )
                  self._batch_splits.append(
                      BatchEncoding(sub_frame, batch_id=i)
                  )
  
imports: import random
label_desc: Use image node_id 2 for calling the FullBatchDataLoader obj's underlying member method code with example usage: obj._prepare() without return types