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: Interact -> Propagate -> Fuse
  
  mask - One-hot mask of the interacted frame, background included
  idx - Frame index of the interacted frame
  total_cb, step_cb - Callback functions for the GUI
  
  Return: all mask results in np format for DAVIS evaluation
docstr_tok: ["Interact","-",">","Propagate","-",">","Fuse","mask","-","One-hot","mask","of","the","interacted","frame",",","background","included","idx","-","Frame","index","of","the","interacted","frame","total_cb",",","step_cb","-","Callback","functions","for","the","GUI","Return",":","all","mask","results","in","np","format","for","DAVIS","evaluation"]
code: def interact(self, mask, idx, total_cb=None, step_cb=None):
      """
      Interact -> Propagate -> Fuse
  
      mask - One-hot mask of the interacted frame, background included
      idx - Frame index of the interacted frame
      total_cb, step_cb - Callback functions for the GUI
  
      Return: all mask results in np format for DAVIS evaluation
      """
      self.interacted.add(idx)
      mask, _ = pad_divide_by(mask, 16, mask.shape[-2:])
      # print('self.k is %d' % self.k)
      self.mask_diff = mask - self.prob[:, idx]
      self.pos_mask_diff = self.mask_diff.clip(0, 1)
      self.neg_mask_diff = (-self.mask_diff).clip(0, 1)
  
      self.prob[:, idx] = mask
  
      key_k, key_v = calculate_memorize(
          self.prop_net_memory,
          self.get_image_buffered(idx).numpy(),
          mask[1:].numpy(),
      )
      key_k = paddle.to_tensor(key_k).astype("float32")
      key_v = paddle.to_tensor(key_v).astype("float32")
      if self.certain_mem_k is None:
          self.certain_mem_k = key_k
          self.certain_mem_v = key_v
      else:
          K, CK, _, H, W = self.certain_mem_k.shape
          CV = self.certain_mem_v.shape[1]
          self.certain_mem_k = paddle.concat(
              [
                  self.certain_mem_k,
                  paddle.zeros((self.k - K, CK, _, H, W)),
              ],
              0,
          )
          self.certain_mem_v = paddle.concat(
              [
                  self.certain_mem_v,
                  paddle.zeros((self.k - K, CV, _, H, W)),
              ],
              0,
          )
          self.certain_mem_k = paddle.concat(
              [self.certain_mem_k, key_k], 2
          )
          self.certain_mem_v = paddle.concat(
              [self.certain_mem_v, key_v], 2
          )
      # self.certain_mem_k = key_k
      # self.certain_mem_v = key_v
  
      if total_cb is not None:
          # Finds the total num. frames to process
          front_limit = min(
              [ti for ti in self.interacted if ti > idx] + [self.t]
          )
          back_limit = max(
              [ti for ti in self.interacted if ti < idx] + [-1]
          )
          total_num = (
              front_limit - back_limit - 2
          )  # -1 for shift, -1 for center frame
  
          if total_num > 0:
              total_cb(total_num)
  
      with paddle.no_grad():
          self.do_pass(key_k, key_v, idx, True, step_cb=step_cb)
          self.do_pass(key_k, key_v, idx, False, step_cb=step_cb)
  
      # This is a more memory-efficient argmax
      for ti in range(self.t):
          self.masks[ti] = paddle.argmax(self.prob[:, ti], axis=0)
      out_masks = self.masks
  
      # Trim paddings
      if self.pad[2] + self.pad[3] > 0:
          out_masks = out_masks[:, :, self.pad[2] : -self.pad[3], :]
      if self.pad[0] + self.pad[1] > 0:
          out_masks = out_masks[:, :, :, self.pad[0] : -self.pad[1]]
  
      self.np_masks = (out_masks.detach().numpy()[:, 0]).astype(
          np.int64
      )
  
      return self.np_masks
  
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 13 for calling the InferenceCore obj's underlying member method code with example usage: obj.interact(mask, idx, total_cb, step_cb) and returns: self