code: def setup_grads_device(
      self,
      params: List[torch.Tensor],
      grads_device_map: Dict[torch.Tensor, torch.device],
  ) -> None:
      total_chunk_mem = sum(
          self.chunk_manager.get_chunk(p).chunk_mem for p in params
      )
  
      offload_optim_chunk_mem = (
          total_chunk_mem * self.offload_optim_frac
      )
      offloaded_optim_chunk_mem = 0
      chunks = set(self.chunk_manager.get_chunk(p) for p in params)
      for chunk in chunks:
          params = chunk.get_tensors()
          # init offload optim settings
          # keep gathered chunks are in CUDA
          if (
              chunk.keep_gathered
              or offloaded_optim_chunk_mem >= offload_optim_chunk_mem
          ):
              device = get_current_device()
          else:
              device = torch.device("cpu")
              # real offloaded mem is chunk.shard_mem, for simplicity we use chunk mem here
              offloaded_optim_chunk_mem += chunk.chunk_mem
          for p in params:
              grads_device_map[p] = device
      self.keep_gathered_chunk_mem = total_chunk_mem * (
          1 - self.shard_param_frac
      )
      self.keep_cuda_chunk_mem = total_chunk_mem * (
          1 - self.offload_param_frac
      )
  
imports: import functools
  import warnings
  from abc import ABC, abstractmethod
  from time import time
  from typing import Dict, List, Optional, Tuple, Type
  import torch
  from colossalai.utils import get_current_device
  from colossalai.utils.memory import colo_device_memory_capacity
  from colossalai.zero.gemini.chunk import Chunk
  from .chunk import Chunk, ChunkManager
  from .memory_tracer import ChunkMemStatsCollector
label_desc: Use image node_id 3 for calling the StaticPlacementPolicy obj's underlying member method code with example usage: obj.setup_grads_device(params, grads_device_map) without return types