def get_max_memory_used(self, swap_tasks, swapped_out_tensor):
    delta = len(swap_tasks)
    if (self.next_swap_tasks_index == 0):
        tmp = copy.copy(self.tensor_access_list)
        tmp.extend(swap_tasks)
        self.time_axis = sorted(tmp, key=cmp_to_key(self.custom_cmp))
        self.end_time_axis = sorted(copy.copy(tmp), key=cmp_to_key(self.custom_cmp_end_time))
    else:
        swap_tasks = swap_tasks[self.next_swap_tasks_index:]
        self.time_axis = self.insert_sort(self.time_axis, swap_tasks, self.custom_cmp)
        self.end_time_axis = self.insert_sort(self.end_time_axis, swap_tasks, self.custom_cmp_end_time)
    self.index_of_end_time_axis = {self.end_time_axis[i]: i for i in range(len(self.end_time_axis))}
    memory_used = 0
    max_memory_actual = float('-inf')
    in_gpu_tensors = set()
    max_memory_tensors = set()
    last_input_tensor_access = None
    max_last_access = None
    wait_to_be_released = []
    max_time = None
    for tensor in self.tensors:
        if (tensor.in_gpu_at_beginning and (tensor not in swapped_out_tensor)):
            in_gpu_tensors.add(tensor)
            memory_used += tensor.size
    for (time_index, event) in enumerate(self.time_axis):
        i = (len(wait_to_be_released) - 1)
        while (i >= 0):
            access = wait_to_be_released[i]
            if (event.time >= access.end_time):
                wait_to_be_released.pop(i)
                memory_used -= access.tensor.size
                in_gpu_tensors.remove(access.tensor)
            i -= 1
        if isinstance(event, TensorAccess):
            if (event.access_type == AccessType.output):
                if (event.tensor not in in_gpu_tensors):
                    if (event.operation_name not in optimizer_op):
                        memory_used += event.tensor.size
                    in_gpu_tensors.add(event.tensor)
            elif event.release_flag:
                wait_to_be_released.append(event)
            else:
                last_input_tensor_access = event
        elif isinstance(event, SwapTask):
            last_event = None
            idx = self.index_of_end_time_axis[event]
            for j in range((idx - 1), (- 1), (- 1)):
                if (isinstance(self.end_time_axis[j], TensorAccess) and (self.end_time_axis[j].end_time <= event.start_time)):
                    last_event = self.end_time_axis[j]
                    break
            if (last_event is None):
                last_event = self.tensor_access_list[0]
            event.execute_ref = last_event
            event.execute_time = (event.start_time - last_event.end_time)
            if (event.task_type == TaskType.swap_in):
                memory_used += event.tensor.size
                in_gpu_tensors.add(event.tensor)
            else:
                memory_used -= event.tensor.size
                in_gpu_tensors.remove(event.tensor)
        if (memory_used > max_memory_actual):
            max_memory_actual = memory_used
            max_memory_tensors = copy.copy(in_gpu_tensors)
            max_last_access = last_input_tensor_access
            max_time = event.time
    self.next_swap_tasks_index = delta
    return (max_memory_actual, max_memory_tensors, max_last_access, max_time, self.time_axis)
def get_max_memory_used(self, swap_tasks, swapped_out_tensor):
    delta = len(swap_tasks)
    if (self.next_swap_tasks_index == 0):
        tmp = copy.copy(self.tensor_access_list)
        tmp.extend(swap_tasks)
        self.time_axis = sorted(tmp, key=cmp_to_key(self.custom_cmp))
        self.end_time_axis = sorted(copy.copy(tmp), key=cmp_to_key(self.custom_cmp_end_time))
    else:
        swap_tasks = swap_tasks[self.next_swap_tasks_index:]
        self.time_axis = self.insert_sort(self.time_axis, swap_tasks, self.custom_cmp)
        self.end_time_axis = self.insert_sort(self.end_time_axis, swap_tasks, self.custom_cmp_end_time)
    self.index_of_end_time_axis = {self.end_time_axis[i]: i for i in range(len(self.end_time_axis))}
    memory_used = 0
    max_memory_actual = float('-inf')
    in_gpu_tensors = set()
    max_memory_tensors = set()
    last_input_tensor_access = None
    max_last_access = None
    wait_to_be_released = []
    max_time = None
    for tensor in self.tensors:
        if (tensor.in_gpu_at_beginning and (tensor not in swapped_out_tensor)):
            in_gpu_tensors.add(tensor)
            memory_used += tensor.size
    for (time_index, event) in enumerate(self.time_axis):
        i = (len(wait_to_be_released) - 1)
        while (i >= 0):
            access = wait_to_be_released[i]
            if (event.time >= access.end_time):
                wait_to_be_released.pop(i)
                memory_used -= access.tensor.size
                in_gpu_tensors.remove(access.tensor)
            i -= 1
        if isinstance(event, TensorAccess):
            if (event.access_type == AccessType.output):
                if (event.tensor not in in_gpu_tensors):
                    if (event.operation_name not in optimizer_op):
                        memory_used += event.tensor.size
                    in_gpu_tensors.add(event.tensor)
            elif event.release_flag:
                wait_to_be_released.append(event)
            else:
                last_input_tensor_access = event
        elif isinstance(event, SwapTask):
            last_event = None
            idx = self.index_of_end_time_axis[event]
            for j in range((idx - 1), (- 1), (- 1)):
                if (isinstance(self.end_time_axis[j], TensorAccess) and (self.end_time_axis[j].end_time <= event.start_time)):
                    last_event = self.end_time_axis[j]
                    break
            if (last_event is None):
                last_event = self.tensor_access_list[0]
            event.execute_ref = last_event
            event.execute_time = (event.start_time - last_event.end_time)
            if (event.task_type == TaskType.swap_in):
                memory_used += event.tensor.size
                in_gpu_tensors.add(event.tensor)
            else:
                memory_used -= event.tensor.size
                in_gpu_tensors.remove(event.tensor)
        if (memory_used > max_memory_actual):
            max_memory_actual = memory_used
            max_memory_tensors = copy.copy(in_gpu_tensors)
            max_last_access = last_input_tensor_access
            max_time = event.time
    self.next_swap_tasks_index = delta
    return (max_memory_actual, max_memory_tensors, max_last_access, max_time, self.time_axis)