class_docstr: A class for storing a single mini-batch (consisting of multiple micro-batches) as input to
  a single partition.
  Args:
      device: the local device that runs the partition.
      rank: the rank of the partition in the pipeline.
      chunks: number of micro-batches in a mini-batch
      num_inputs: number of inputs to the partition.
      consumers: list of consumers of outputs of the partition. Each consumer in the list is a tuple
          (remote_partition_rref, input_idx, output_idx) where remote_partition_rref points to a
          remote DistributedPipelineRecord for consumer partiton for this mini-batch. The output number
          output_idx of this partition will be used as the input number input_idx of that partition.
class_docstr_tok: ["A","class","for","storing","a","single","mini-batch","(","consisting","of","multiple","micro-batches",")","as","input","to","a","single","partition",".","Args",":","device",":","the","local","device","that","runs","the","partition",".","rank",":","the","rank","of","the","partition","in","the","pipeline",".","chunks",":","number","of","micro-batches","in","a","mini-batch","num_inputs",":","number","of","inputs","to","the","partition",".","consumers",":","list","of","consumers","of","outputs","of","the","partition",".","Each","consumer","in","the","list","is","a","tuple","(","remote_partition_rref",",","input_idx",",","output_idx",")","where","remote_partition_rref","points","to","a","remote","DistributedPipelineRecord","for","consumer","partiton","for","this","mini-batch",".","The","output","number","output_idx","of","this","partition","will","be","used","as","the","input","number","input_idx","of","that","partition","."]
docstr: Prepares micro-batches for computation.
docstr_tok: ["Prepares","micro-batches","for","computation","."]
code: def fence(self, chunk: int) -> None:
      """Prepares micro-batches for computation."""
      # Ensure that batches[chunk-1] is executed after batches[chunk] in
      # backpropagation by an explicit dependency.
      # TODO: This dependency injection causes deadlock if this partition
      # gets its input from model input. 1) Figure out why 2) If we need to live
      # with this constraint, replace the condition 'self.rank > 0' below with
      # a more accurate one.
      if chunk != 0 and self.consumers and self.rank > 0:
          batch = self.batches[chunk]
          assert batch is not None
          dependant_tensors = list(batch.tensors)
          for remote_ph_list in self.forwarded_phony[chunk - 1]:
              for remote_ph in remote_ph_list:
                  phony = remote_ph.to_here()
                  dependant_tensors[0] = join(
                      dependant_tensors[0], phony
                  )
          self.batches[chunk] = Batch(tuple(dependant_tensors), chunk)
  
imports: from threading import Condition
  from types import TracebackType
  from typing import Dict, List, Optional, Tuple, Type, Union, cast
  import torch
  from torch import Tensor
  from torch.autograd.profiler import record_function
  from torch.distributed import rpc
  from fairscale.nn.pipe import microbatch
  from fairscale.nn.pipe.checkpoint import Checkpointing, TensorOrTensors
  from fairscale.nn.pipe.dependency import fork, join
  from fairscale.nn.pipe.microbatch import Batch
  from fairscale.nn.pipe.stream import as_cuda, current_stream, is_cuda, use_device, use_stream
  from fairscale.nn.pipe.worker import Task, create_workers
  from .data import DataConsumer
label_desc: Use image node_id 5 for calling the DistributedPipelineRecord obj's underlying member method code with example usage: obj.fence(chunk) without return types