def __init__(
        self,
        past_names: list[str],
        present_names: list[str],
        batch_size: int,
        num_kv_heads: int,
        head_dim: int,
        max_cache_len: int = 2048,
        dtype: str = "float32",
        device: str = "gpu",
        device_id: int = 0,
        backend: str = "ort",
    ):
        """Initialize the cache.

        :param past_names: List of past key and value names.
        :param present_names: List of present key and value names.
            Names must be in the same order as past_names.
        :param batch_size: Batch size.
        :param num_kv_heads: Number of key-value heads.
        :param head_dim: Dimension of each key-value head.
        :param max_cache_len: Maximum length of the cache.
        :param dtype: Data type of the key-value tensors.
        :param device: Device type for the cache tensors.
        :param device_id: Device ID for the cache tensors.
        :param backend: Backend for the cache tensors. Options: "ort" or "torch".
            There is no implemetation difference for this class between "ort" and "torch".
        """
        super().__init__(
            past_names, present_names, batch_size, num_kv_heads, head_dim, dtype, device, device_id, backend
        )
        if device == "dml" and max_cache_len % 4 == 0:
            # there is an overflow bug in DML for max_cache_len % 4 == 0
            max_cache_len += 1
        self.max_cache_len = max_cache_len
        # will just use ortvalue since we don't need to access the cache
        # allocate cache with zeros
        # both past and present will use the same cache
        self.cache = {
            k: self.get_empty_ortvalue(self.batch_size, self.num_kv_heads, self.max_cache_len, self.head_dim)
            for k in self.past_names
        }
Initialize the cache.

        :param past_names: List of past key and value names.
        :param present_names: List of present key and value names.
            Names must be in the same order as past_names.
        :param batch_size: Batch size.
        :param num_kv_heads: Number of key-value heads.
        :param head_dim: Dimension of each key-value head.
        :param max_cache_len: Maximum length of the cache.
        :param dtype: Data type of the key-value tensors.
        :param device: Device type for the cache tensors.
        :param device_id: Device ID for the cache tensors.
        :param backend: Backend for the cache tensors. Options: "ort" or "torch".
            There is no implemetation difference for this class between "ort" and "torch".
        
examples/utils/kv_cache_utils.py