docstr: Evict tensors from CUDA device.
  
  Args:
      hold_cuda_tensor_list (List[StatefulTensor]): the list of tensor in state of HOLD-like
      cuda_demand (int, optional): the volume of data needed on cuda device. Defaults to 0.
      warmup (bool, optional): a flag indicates whether in the phase of warmup. Defaults to True.
      compute_list (List[StatefulTensor], optional): TODO. Defaults to [].
      compute_idx (int, optional): the idx of computing device. Defaults to 0.
  
  Raises:
      RuntimeError:
  
  Returns:
      int: the volume of memory that is evicted
docstr_tok: ["Evict","tensors","from","CUDA","device",".","Args",":","hold_cuda_tensor_list","(","List","[","StatefulTensor","]",")",":","the","list","of","tensor","in","state","of","HOLD-like","cuda_demand","(","int",",","optional",")",":","the","volume","of","data","needed","on","cuda","device",".","Defaults","to","0.","warmup","(","bool",",","optional",")",":","a","flag","indicates","whether","in","the","phase","of","warmup",".","Defaults","to","True",".","compute_list","(","List","[","StatefulTensor","]",",","optional",")",":","TODO",".","Defaults","to","[","]",".","compute_idx","(","int",",","optional",")",":","the","idx","of","computing","device",".","Defaults","to","0",".","Raises",":","RuntimeError",":","Returns",":","int",":","the","volume","of","memory","that","is","evicted"]
code: def evict_tensors(
      self,
      hold_cuda_tensor_list: List[StatefulTensor],
      cuda_demand: int = 0,
      warmup: bool = True,
      compute_list: List[StatefulTensor] = [],
      compute_idx: int = 0,
      **kwargs,
  ) -> int:
      """
      Evict tensors from CUDA device.
  
      Args:
          hold_cuda_tensor_list (List[StatefulTensor]): the list of tensor in state of HOLD-like
          cuda_demand (int, optional): the volume of data needed on cuda device. Defaults to 0.
          warmup (bool, optional): a flag indicates whether in the phase of warmup. Defaults to True.
          compute_list (List[StatefulTensor], optional): TODO. Defaults to [].
          compute_idx (int, optional): the idx of computing device. Defaults to 0.
  
      Raises:
          RuntimeError:
  
      Returns:
          int: the volume of memory that is evicted
      """
      start = time()
      cuda_capacity = colo_device_memory_capacity(get_current_device())
      used_cuda_model_data = StatefulTensor.GST_MGR.total_mem["cuda"]
      if warmup:
          # We designate a part of CUDA memory for model data in warmup iterations.
          max_cuda_non_model_data_per_period = (
              cuda_capacity * self._warmup_non_model_data_ratio
          )
      else:
          # max non-model-data cuda memory consumption of this sampling moment and the next sampling moment.
          max_cuda_non_model_data_per_period = (
              self.mem_stats_collector.next_period_non_model_data_usage(
                  "cuda"
              )
          )
          cuda_capacity *= self._steady_cuda_cap_ratio
      total_cuda_model_data = (
          cuda_capacity - max_cuda_non_model_data_per_period
      )
      avail_cuda_model_data = (
          total_cuda_model_data - used_cuda_model_data
      )
      freed_cuda_model_data = 0
      end = time()
      if avail_cuda_model_data < cuda_demand:
          # Move cuda_demand - avail_cuda_model_data volume of tensors
          # to_free_cuda_model_data = cuda_demand - avail_cuda_model_data
          to_free_cuda_model_data = cuda_demand - avail_cuda_model_data
          to_free_tensor_list = hold_cuda_tensor_list
          if not warmup:
              to_free_tensor_list = self._sort_hold_cuda_tensors(
                  tuple(hold_cuda_tensor_list),
                  compute_idx,
                  tuple(compute_list),
              )
              # print(self._sort_hold_cuda_tensors.cache_info())
          end = time()
          for t in to_free_tensor_list:
              if freed_cuda_model_data >= to_free_cuda_model_data:
                  break
              freed_cuda_model_data += t.payload_size
              colo_model_data_tensor_move_inline(t, torch.device("cpu"))
          if freed_cuda_model_data < to_free_cuda_model_data:
              raise RuntimeError(
                  f"Adjust layout failed! No enough CUDA memory! Need {to_free_cuda_model_data}, freed {freed_cuda_model_data}"
              )
      return freed_cuda_model_data, end - start
  
imports: import functools
  from abc import ABC, abstractmethod
  from time import time
  from typing import List, Optional, Type
  import torch
  from colossalai.legacy.utils.memory import colo_device_memory_capacity
  from colossalai.utils import get_current_device
  from colossalai.zero.gemini.memory_tracer import MemStatsCollector
  from .stateful_tensor import StatefulTensor
  from .tensor_utils import colo_model_data_tensor_move_inline
label_desc: Use image node_id 2 for calling the AutoTensorPlacementPolicy obj's underlying member method code with example usage: obj.evict_tensors(hold_cuda_tensor_list, cuda_demand, warmup, compute_list, compute_idx) and returns: freed_cuda_model_data,  unknown