class_docstr: images - leave them in original dimension (unpadded), but do normalize them.
          Should be CPU tensors of shape B*T*3*H*W
  
  mem_profile - How extravagant I can use the GPU memory.
              Usually more memory -> faster speed but I have not drawn the exact relation
              0 - Use the most memory
              1 - Intermediate, larger buffer
              2 - Intermediate, small buffer
              3 - Use the minimal amount of GPU memory
              Note that *none* of the above options will affect the accuracy
              This is a space-time tradeoff, not a space-performance one
  
  mem_freq - Period at which new memory are put in the bank
              Higher number -> less memory usage
              Unlike the last option, this *is* a space-performance tradeoff
class_docstr_tok: ["images","-","leave","them","in","original","dimension","(","unpadded",")",",","but","do","normalize","them",".","Should","be","CPU","tensors","of","shape","B","*","T","*","3","*","H","*","W","mem_profile","-","How","extravagant","I","can","use","the","GPU","memory",".","Usually","more","memory","-",">","faster","speed","but","I","have","not","drawn","the","exact","relation","0","-","Use","the","most","memory","1","-","Intermediate",",","larger","buffer","2","-","Intermediate",",","small","buffer","3","-","Use","the","minimal","amount","of","GPU","memory","Note","that","*","none","*","of","the","above","options","will","affect","the","accuracy","This","is","a","space-time","tradeoff",",","not","a","space-performance","one","mem_freq","-","Period","at","which","new","memory","are","put","in","the","bank","Higher","number","-",">","less","memory","usage","Unlike","the","last","option",",","this","*","is","*","a","space-performance","tradeoff"]
docstr: Do a complete pass that includes propagation and fusion
  key_k/key_v -  memory feature of the starting frame
  idx - Frame index of the starting frame
  forward - forward/backward propagation
  step_cb - Callback function used for GUI (progress bar) only
docstr_tok: ["Do","a","complete","pass","that","includes","propagation","and","fusion","key_k\/key_v","-","memory","feature","of","the","starting","frame","idx","-","Frame","index","of","the","starting","frame","forward","-","forward\/backward","propagation","step_cb","-","Callback","function","used","for","GUI","(","progress","bar",")","only"]
code: def do_pass(self, key_k, key_v, idx, forward=True, step_cb=None):
      """
      Do a complete pass that includes propagation and fusion
      key_k/key_v -  memory feature of the starting frame
      idx - Frame index of the starting frame
      forward - forward/backward propagation
      step_cb - Callback function used for GUI (progress bar) only
      """
  
      # Pointer in the memory bank
      num_certain_keys = self.certain_mem_k.shape[2]
      m_front = num_certain_keys
  
      # Determine the required size of the memory bank
      if forward:
          closest_ti = min(
              [ti for ti in self.interacted if ti > idx] + [self.t]
          )
          total_m = (
              (closest_ti - idx - 1) // self.mem_freq
              + 1
              + num_certain_keys
          )
      else:
          closest_ti = max(
              [ti for ti in self.interacted if ti < idx] + [-1]
          )
          total_m = (
              (idx - closest_ti - 1) // self.mem_freq
              + 1
              + num_certain_keys
          )
      K, CK, _, H, W = key_k.shape
      _, CV, _, _, _ = key_v.shape
  
      # Pre-allocate keys/values memory
      keys = paddle.empty((K, CK, total_m, H, W), dtype="float32")
      values = paddle.empty((K, CV, total_m, H, W), dtype="float32")
  
      # Initial key/value passed in
      keys[:, :, 0:num_certain_keys] = self.certain_mem_k
      values[:, :, 0:num_certain_keys] = self.certain_mem_v
      prev_in_mem = True
      last_ti = idx
  
      # Note that we never reach closest_ti, just the frame before it
      if forward:
          this_range = range(idx + 1, closest_ti)
          step = +1
          end = closest_ti - 1
      else:
          this_range = range(idx - 1, closest_ti, -1)
          step = -1
          end = closest_ti + 1
  
      for ti in this_range:
          if prev_in_mem:
              this_k = keys[:, :, :m_front]
              this_v = values[:, :, :m_front]
          else:
              this_k = keys[:, :, : m_front + 1]
              this_v = values[:, :, : m_front + 1]
  
          out_mask, quary_key = self.get_query_kv_mask(
              ti, this_k, this_v
          )
          out_mask = aggregate_wbg(
              paddle.to_tensor(out_mask), keep_bg=True
          )
  
          if ti != end:
              (
                  keys[:, :, m_front : m_front + 1],
                  values[:, :, m_front : m_front + 1],
              ) = calculate_memorize(
                  self.prop_net_memory,
                  self.get_image_buffered(ti).numpy(),
                  out_mask[1:].numpy(),
              )
              if abs(ti - last_ti) >= self.mem_freq:
                  # Memorize the frame
                  m_front += 1
                  last_ti = ti
                  prev_in_mem = True
              else:
                  prev_in_mem = False
  
          # In-place fusion, maximizes the use of queried buffer
          # esp. for long sequence where the buffer will be flushed
          if (closest_ti != self.t) and (closest_ti != -1):
              self.prob[:, ti] = self.fuse_one_frame(
                  closest_ti,
                  idx,
                  ti,
                  self.prob[:, ti],
                  out_mask,
                  key_k,
                  quary_key,
              )
          else:
              self.prob[:, ti] = out_mask
  
          # Callback function for the GUI
          if step_cb is not None:
              step_cb()
  
      return closest_ti
  
imports: import os
  import paddle.nn.functional
  import numpy
  from .load_model import *
  from .util.tensor_util import pad_divide_by, images_to_paddle
  from .video_tools import load_video, aggregate_wbg
label_desc: Use image node_id 11 for calling the InferenceCore obj's underlying member method code with example usage: obj.do_pass(key_k, key_v, idx, forward, step_cb) and returns: closest_ti