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

        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
        
EISeg/eiseg/plugin/video/inference_core.py