
"""simple docstring"""




import json
import os
from collections.abc import Mapping
from typing import Dict, List, Optional, Union

import numpy as np
import torch

from .imports import is_safetensors_available

def __snake_case (      UpperCamelCase						,					UpperCamelCase						,					UpperCamelCase						,					UpperCamelCase=None    )       ->    List[Any]:


		"""simple docstring"""





		a__   		=     None
		# Check the string instead of the dtype to be compatible with versions of PyTorch that don't have bfloat16.
		if str(weight.dtype    ) == "torch.bfloat16":
				# Need to reinterpret the underlined data as int16 since NumPy does not handle bfloat16s.
				a__   		=     weight.view(torch.intaa    )
				a__   		=     '''bfloat16'''
		a__   		=     weight.cpu().numpy()
		a__   		=     os.path.join(UpperCamelCase						,					f"{weight_name}.dat"    )
		if index is not None:
				if dtype is None:
						a__   		=     str(array.dtype    )
				a__   		=     {'''dtype''': dtype, '''shape''': list(array.shape    )}
		if array.ndim == 0:
				a__   		=     array[None]
		a__   		=     np.memmap(UpperCamelCase						,					dtype=array.dtype						,					mode='''w+'''						,					shape=array.shape    )
		a__   		=     array[:]
		file_array.flush()
		return index

def __snake_case (      UpperCamelCase						,					UpperCamelCase    )       ->    Optional[Any]:


		"""simple docstring"""





		a__   		=     tuple(weight_info['''shape''']    )
		if shape == ():
				# NumPy memory-mapped arrays can't have 0 dims so it was saved as 1d tensor
				a__   		=     (1,)

		a__   		=     weight_info['''dtype''']
		if dtype == "bfloat16":
				# NumPy does not support bfloat16 so this was saved as a int16
				a__   		=     '''int16'''

		a__   		=     np.memmap(UpperCamelCase						,					dtype=UpperCamelCase						,					shape=UpperCamelCase						,					mode='''r'''    )

		if len(weight_info['''shape''']    ) == 0:
				a__   		=     weight[0]
		a__   		=     torch.tensor(UpperCamelCase    )
		if weight_info["dtype"] == "bfloat16":
				a__   		=     weight.view(torch.bfloataa    )

		return weight

def __snake_case (      UpperCamelCase						,					UpperCamelCase    )       ->    Optional[int]:


		"""simple docstring"""





		if index is None or len(UpperCamelCase    ) == 0:
				# Nothing to save
				return

		a__   		=     os.path.join(UpperCamelCase						,					'''index.json'''    )
		if os.path.isfile(UpperCamelCase    ):
				with open(UpperCamelCase						,					'''r'''						,					encoding='''utf-8'''    ) as f:
						a__   		=     json.load(UpperCamelCase    )
		else:
				a__   		=     {}
		current_index.update(UpperCamelCase    )

		with open(UpperCamelCase						,					'''w'''						,					encoding='''utf-8'''    ) as f:
				json.dump(UpperCamelCase						,					UpperCamelCase						,					indent=2    )

def __snake_case (      UpperCamelCase						,					UpperCamelCase    )       ->    List[str]:


		"""simple docstring"""





		os.makedirs(UpperCamelCase						,					exist_ok=UpperCamelCase    )
		a__   		=     {}
		for name, parameter in state_dict.items():
				a__   		=     offload_weight(UpperCamelCase						,					UpperCamelCase						,					UpperCamelCase						,					index=UpperCamelCase    )

		# Update index
		save_offload_index(UpperCamelCase						,					UpperCamelCase    )
class SCREAMING_SNAKE_CASE       (      lowerCAmelCase					):






	'''simple docstring'''







	def __init__(  self :int       ,    __magic_name__ :Mapping       ,    __magic_name__ :str			)			->   Union[str, Any]:

			'''simple docstring'''






			a__   		=     dataset
			a__   		=     prefix


	def __getitem__(  self :Optional[int]       ,    __magic_name__ :Any			)			->   Union[str, Any]:

			'''simple docstring'''






			return self.dataset[F"{self.prefix}{key}"]


	def __iter__(  self :Optional[Any]			)			->   Dict:

			'''simple docstring'''






			return iter([key for key in self.dataset if key.startswith(self.prefix			)]			)






	def __len__(  self :str			)			->   Dict:

			'''simple docstring'''






			return len(self.dataset			)

class SCREAMING_SNAKE_CASE       (      lowerCAmelCase					):






	'''simple docstring'''







	def __init__(  self :List[Any]       ,    __magic_name__ :Dict[str, torch.Tensor] = None       ,    __magic_name__ :Optional[Union[str, os.PathLike]] = None       ,    __magic_name__ :Mapping = None       ,    __magic_name__ :Dict=None       ,    )			->   Tuple:

			'''simple docstring'''






			if state_dict is None and save_folder is None:
					raise ValueError('''Need either a `state_dict` or a `save_folder` containing offloaded weights.'''			)

			a__   		=     {} if state_dict is None else state_dict
			a__   		=     save_folder
			if index is None and save_folder is not None:
					with open(os.path.join(__magic_name__       ,    '''index.json'''			)			) as f:
							a__   		=     json.load(__magic_name__			)
			a__   		=     {} if index is None else index
			a__   		=     list(self.state_dict.keys()			)
			self.all_keys.extend([key for key in self.index if key not in self.all_keys]			)
			a__   		=     device


	def __getitem__(  self :Union[str, Any]       ,    __magic_name__ :str			)			->   str:

			'''simple docstring'''






			if key in self.state_dict:
					return self.state_dict[key]
			a__   		=     self.index[key]
			if weight_info.get('''safetensors_file'''			) is not None:
					if not is_safetensors_available():
							raise ImportError('''These offloaded weights require the use of safetensors: `pip install safetensors`.'''			)

					from safetensors import safe_open

					a__   		=     '''cpu''' if self.device is None else self.device
					with safe_open(weight_info['''safetensors_file''']       ,    framework='''pt'''       ,    device=__magic_name__			) as f:
							a__   		=     f.get_tensor(weight_info.get('''weight_name'''       ,    __magic_name__			)			)

					if "dtype" in weight_info:
							return tensor.to(getattr(__magic_name__       ,    weight_info['''dtype''']			)			)
					else:
							return tensor

			a__   		=     os.path.join(self.save_folder       ,    F"{key}.dat"			)
			return load_offloaded_weight(__magic_name__       ,    __magic_name__			)


	def __iter__(  self :str			)			->   str:

			'''simple docstring'''






			return iter(self.all_keys			)






	def __len__(  self :Optional[Any]			)			->   str:

			'''simple docstring'''






			return len(self.all_keys			)

def __snake_case (      UpperCamelCase						,					UpperCamelCase    )       ->    List[str]:


		"""simple docstring"""





		a__   		=     {}
		for module_name in submodule_names:
				# We want to catch module_name parameter (module_name.xxx) or potentially module_name, but not any of the
				# submodules that could being like module_name (transformers.h.1 and transformers.h.10 for instance)
				result.update(
				    {
				        key: param
				        for key, param in state_dict.items()
				        if key == module_name or key.startswith(module_name + '''.'''    )
				    }    )
		return result






"""simple docstring"""




__lowerCAmelCase							:  Any 				=		{
    '''0''': 1,
    '''1''': 1,
    '''2''': 2,
    '''3''': 6,
    '''4''': 24,
    '''5''': 120,
    '''6''': 720,
    '''7''': 5040,
    '''8''': 40320,
    '''9''': 362880,
}

__lowerCAmelCase							:  List[Any] 				=		{145: 145}

__lowerCAmelCase							:  Any 				=		{
    145: 0,
    169: 3,
    36301: 3,
    1454: 3,
    871: 2,
    45361: 2,
    872: 2,
}

def __snake_case (      UpperCamelCase    )       ->    int:


		"""simple docstring"""





		if n in CACHE_SUM_DIGIT_FACTORIALS:
				return CACHE_SUM_DIGIT_FACTORIALS[n]
		a__   		=     sum(DIGIT_FACTORIALS[let] for let in str(UpperCamelCase    )    )
		a__   		=     ret
		return ret

def __snake_case (      UpperCamelCase						,					UpperCamelCase = None    )       ->    int:


		"""simple docstring"""





		a__   		=     previous or set()
		if n in CHAIN_LENGTH_CACHE:
				return CHAIN_LENGTH_CACHE[n]
		a__   		=     sum_digit_factorials(UpperCamelCase    )
		if next_number in previous:
				a__   		=     0
				return 0
		else:
				previous.add(UpperCamelCase    )
				a__   		=     1 + chain_length(UpperCamelCase						,					UpperCamelCase    )
				a__   		=     ret
				return ret

def __snake_case (      UpperCamelCase = 60						,					UpperCamelCase = 1_000_000    )       ->    int:


		"""simple docstring"""





		return sum(1 for i in range(1						,					UpperCamelCase    ) if chain_length(UpperCamelCase    ) == num_terms    )


if __name__ == "__main__":
					print(f"{solution() = }")




