
'''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 __A  (    lowerCAmelCase_ ,       lowerCAmelCase_ ,       lowerCAmelCase_ ,       lowerCAmelCase_=None       ):
     _UpperCAmelCase					:  Union[str, Any]         =    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.
          _UpperCAmelCase					:  List[Any]         =    weight.view(torch.intaa       )
          _UpperCAmelCase					:  Union[str, Any]         =    """bfloat16"""
     _UpperCAmelCase					:  Optional[int]         =    weight.cpu().numpy()
     _UpperCAmelCase					:  Optional[Any]         =    os.path.join(lowerCAmelCase_ ,       f"{weight_name}.dat"       )
     if index is not None:
          if dtype is None:
               _UpperCAmelCase					:  Optional[Any]         =    str(array.dtype       )
          _UpperCAmelCase					:  Dict         =    {"""dtype""": dtype, """shape""": list(array.shape       )}
     if array.ndim == 0:
          _UpperCAmelCase					:  Tuple         =    array[None]
     _UpperCAmelCase					:  Any         =    np.memmap(lowerCAmelCase_ ,       dtype=array.dtype ,       mode="""w+""" ,       shape=array.shape       )
     _UpperCAmelCase					:  Optional[int]         =    array[:]
     file_array.flush()
     return index







def __A  (    lowerCAmelCase_ ,       lowerCAmelCase_       ):
     _UpperCAmelCase					:  Dict         =    tuple(weight_info["""shape"""]       )
     if shape == ():
          # NumPy memory-mapped arrays can't have 0 dims so it was saved as 1d tensor
          _UpperCAmelCase					:  Optional[Any]         =    (1,)

     _UpperCAmelCase					:  List[str]         =    weight_info["""dtype"""]
     if dtype == "bfloat16":
          # NumPy does not support bfloat16 so this was saved as a int16
          _UpperCAmelCase					:  Union[str, Any]         =    """int16"""

     _UpperCAmelCase					:  Optional[Any]         =    np.memmap(lowerCAmelCase_ ,       dtype=lowerCAmelCase_ ,       shape=lowerCAmelCase_ ,       mode="""r"""       )

     if len(weight_info["""shape"""]       ) == 0:
          _UpperCAmelCase					:  str         =    weight[0]
     _UpperCAmelCase					:  str         =    torch.tensor(lowerCAmelCase_       )
     if weight_info["dtype"] == "bfloat16":
          _UpperCAmelCase					:  List[str]         =    weight.view(torch.bfloataa       )

     return weight







def __A  (    lowerCAmelCase_ ,       lowerCAmelCase_       ):
     if index is None or len(lowerCAmelCase_       ) == 0:
          # Nothing to save
          return

     _UpperCAmelCase					:  Tuple         =    os.path.join(lowerCAmelCase_ ,       """index.json"""       )
     if os.path.isfile(lowerCAmelCase_       ):
          with open(lowerCAmelCase_ ,       """r""" ,       encoding="""utf-8"""       ) as f:
               _UpperCAmelCase					:  Optional[int]         =    json.load(lowerCAmelCase_       )
     else:
          _UpperCAmelCase					:  Union[str, Any]         =    {}
     current_index.update(lowerCAmelCase_       )

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







def __A  (    lowerCAmelCase_ ,       lowerCAmelCase_       ):
     os.makedirs(lowerCAmelCase_ ,       exist_ok=lowerCAmelCase_       )
     _UpperCAmelCase					:  List[Any]         =    {}
     for name, parameter in state_dict.items():
          _UpperCAmelCase					:  Optional[int]         =    offload_weight(lowerCAmelCase_ ,       lowerCAmelCase_ ,       lowerCAmelCase_ ,       index=lowerCAmelCase_       )

     # Update index
     save_offload_index(lowerCAmelCase_ ,       lowerCAmelCase_       )







class 	__lowerCAmelCase    (  __a				):



     def __init__(self						,	lowerCAmelCase__						,	lowerCAmelCase__	):
          _UpperCAmelCase					:  Optional[int]         =    dataset
          _UpperCAmelCase					:  Any         =    prefix



     def __getitem__(self						,	lowerCAmelCase__	):
          return self.dataset[F"{self.prefix}{key}"]



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



     def __len__(self	):
          return len(self.dataset	)







class 	__lowerCAmelCase    (  __a				):



     def __init__(self						,	lowerCAmelCase__ = None						,	lowerCAmelCase__ = None						,	lowerCAmelCase__ = None						,	lowerCAmelCase__=None						,	):
          if state_dict is None and save_folder is None:
               raise ValueError("""Need either a `state_dict` or a `save_folder` containing offloaded weights."""	)

          _UpperCAmelCase					:  str         =    {} if state_dict is None else state_dict
          _UpperCAmelCase					:  Union[str, Any]         =    save_folder
          if index is None and save_folder is not None:
               with open(os.path.join(lowerCAmelCase__						,	"""index.json"""	)	) as f:
                    _UpperCAmelCase					:  Dict         =    json.load(lowerCAmelCase__	)
          _UpperCAmelCase					:  Optional[Any]         =    {} if index is None else index
          _UpperCAmelCase					:  Any         =    list(self.state_dict.keys()	)
          self.all_keys.extend([key for key in self.index if key not in self.all_keys]	)
          _UpperCAmelCase					:  List[Any]         =    device



     def __getitem__(self						,	lowerCAmelCase__	):
          # State dict gets priority
          if key in self.state_dict:
               return self.state_dict[key]
          _UpperCAmelCase					:  int         =    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

               _UpperCAmelCase					:  str         =    """cpu""" if self.device is None else self.device
               with safe_open(weight_info["""safetensors_file"""]						,	framework="""pt"""						,	device=lowerCAmelCase__	) as f:
                    _UpperCAmelCase					:  List[Any]         =    f.get_tensor(weight_info.get("""weight_name"""						,	lowerCAmelCase__	)	)

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

          _UpperCAmelCase					:  str         =    os.path.join(self.save_folder						,	F"{key}.dat"	)
          return load_offloaded_weight(lowerCAmelCase__						,	lowerCAmelCase__	)



     def __iter__(self	):
          return iter(self.all_keys	)



     def __len__(self	):
          return len(self.all_keys	)







def __A  (    lowerCAmelCase_ ,       lowerCAmelCase_       ):
     _UpperCAmelCase					:  Union[str, Any]         =    {}
     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'''

import torch

from diffusers import HeunDiscreteScheduler
from diffusers.utils import torch_device

from .test_schedulers import SchedulerCommonTest







class 	__lowerCAmelCase    (  __a				):
     snake_case   :    List[str]							      =      (HeunDiscreteScheduler,)
     snake_case   :    Optional[Any]							      =      1_0



     def     snake_case_ (self						,	**lowerCAmelCase__	):
          _UpperCAmelCase					:  Union[str, Any]         =    {
              """num_train_timesteps""": 1_1_0_0,
              """beta_start""": 0.0_0_0_1,
              """beta_end""": 0.0_2,
              """beta_schedule""": """linear""",
          }

          config.update(**lowerCAmelCase__	)
          return config



     def     snake_case_ (self	):
          for timesteps in [1_0, 5_0, 1_0_0, 1_0_0_0]:
               self.check_over_configs(num_train_timesteps=lowerCAmelCase__	)



     def     snake_case_ (self	):
          for beta_start, beta_end in zip([0.0_0_0_0_1, 0.0_0_0_1, 0.0_0_1]						,	[0.0_0_0_2, 0.0_0_2, 0.0_2]	):
               self.check_over_configs(beta_start=lowerCAmelCase__						,	beta_end=lowerCAmelCase__	)



     def     snake_case_ (self	):
          for schedule in ["linear", "scaled_linear", "exp"]:
               self.check_over_configs(beta_schedule=lowerCAmelCase__	)



     def     snake_case_ (self	):
          for clip_sample_range in [1.0, 2.0, 3.0]:
               self.check_over_configs(clip_sample_range=lowerCAmelCase__						,	clip_sample=lowerCAmelCase__	)



     def     snake_case_ (self	):
          for prediction_type in ["epsilon", "v_prediction", "sample"]:
               self.check_over_configs(prediction_type=lowerCAmelCase__	)



     def     snake_case_ (self	):
          _UpperCAmelCase					:  Tuple         =    self.scheduler_classes[0]
          _UpperCAmelCase					:  Optional[int]         =    self.get_scheduler_config()
          _UpperCAmelCase					:  List[str]         =    scheduler_class(**lowerCAmelCase__	)

          scheduler.set_timesteps(self.num_inference_steps	)

          _UpperCAmelCase					:  str         =    self.dummy_model()
          _UpperCAmelCase					:  List[Any]         =    self.dummy_sample_deter * scheduler.init_noise_sigma
          _UpperCAmelCase					:  Tuple         =    sample.to(lowerCAmelCase__	)

          for i, t in enumerate(scheduler.timesteps	):
               _UpperCAmelCase					:  Union[str, Any]         =    scheduler.scale_model_input(lowerCAmelCase__						,	lowerCAmelCase__	)

               _UpperCAmelCase					:  Any         =    model(lowerCAmelCase__						,	lowerCAmelCase__	)

               _UpperCAmelCase					:  Tuple         =    scheduler.step(lowerCAmelCase__						,	lowerCAmelCase__						,	lowerCAmelCase__	)
               _UpperCAmelCase					:  Optional[Any]         =    output.prev_sample

          _UpperCAmelCase					:  Optional[Any]         =    torch.sum(torch.abs(lowerCAmelCase__	)	)
          _UpperCAmelCase					:  int         =    torch.mean(torch.abs(lowerCAmelCase__	)	)

          if torch_device in ["cpu", "mps"]:
               assert abs(result_sum.item() - 0.1_2_3_3	) < 1e-2
               assert abs(result_mean.item() - 0.0_0_0_2	) < 1e-3
          else:
               # CUDA
               assert abs(result_sum.item() - 0.1_2_3_3	) < 1e-2
               assert abs(result_mean.item() - 0.0_0_0_2	) < 1e-3



     def     snake_case_ (self	):
          _UpperCAmelCase					:  Optional[int]         =    self.scheduler_classes[0]
          _UpperCAmelCase					:  Any         =    self.get_scheduler_config(prediction_type="""v_prediction"""	)
          _UpperCAmelCase					:  Any         =    scheduler_class(**lowerCAmelCase__	)

          scheduler.set_timesteps(self.num_inference_steps	)

          _UpperCAmelCase					:  Optional[Any]         =    self.dummy_model()
          _UpperCAmelCase					:  Any         =    self.dummy_sample_deter * scheduler.init_noise_sigma
          _UpperCAmelCase					:  Any         =    sample.to(lowerCAmelCase__	)

          for i, t in enumerate(scheduler.timesteps	):
               _UpperCAmelCase					:  List[str]         =    scheduler.scale_model_input(lowerCAmelCase__						,	lowerCAmelCase__	)

               _UpperCAmelCase					:  List[Any]         =    model(lowerCAmelCase__						,	lowerCAmelCase__	)

               _UpperCAmelCase					:  Optional[Any]         =    scheduler.step(lowerCAmelCase__						,	lowerCAmelCase__						,	lowerCAmelCase__	)
               _UpperCAmelCase					:  Union[str, Any]         =    output.prev_sample

          _UpperCAmelCase					:  Union[str, Any]         =    torch.sum(torch.abs(lowerCAmelCase__	)	)
          _UpperCAmelCase					:  str         =    torch.mean(torch.abs(lowerCAmelCase__	)	)

          if torch_device in ["cpu", "mps"]:
               assert abs(result_sum.item() - 4.6_934e-07	) < 1e-2
               assert abs(result_mean.item() - 6.1_112e-10	) < 1e-3
          else:
               # CUDA
               assert abs(result_sum.item() - 4.693_428_650_170_972e-07	) < 1e-2
               assert abs(result_mean.item() - 0.0_0_0_2	) < 1e-3



     def     snake_case_ (self	):
          _UpperCAmelCase					:  Tuple         =    self.scheduler_classes[0]
          _UpperCAmelCase					:  Any         =    self.get_scheduler_config()
          _UpperCAmelCase					:  Optional[int]         =    scheduler_class(**lowerCAmelCase__	)

          scheduler.set_timesteps(self.num_inference_steps						,	device=lowerCAmelCase__	)

          _UpperCAmelCase					:  List[Any]         =    self.dummy_model()
          _UpperCAmelCase					:  Dict         =    self.dummy_sample_deter.to(lowerCAmelCase__	) * scheduler.init_noise_sigma

          for t in scheduler.timesteps:
               _UpperCAmelCase					:  Union[str, Any]         =    scheduler.scale_model_input(lowerCAmelCase__						,	lowerCAmelCase__	)

               _UpperCAmelCase					:  Optional[Any]         =    model(lowerCAmelCase__						,	lowerCAmelCase__	)

               _UpperCAmelCase					:  Optional[int]         =    scheduler.step(lowerCAmelCase__						,	lowerCAmelCase__						,	lowerCAmelCase__	)
               _UpperCAmelCase					:  int         =    output.prev_sample

          _UpperCAmelCase					:  Any         =    torch.sum(torch.abs(lowerCAmelCase__	)	)
          _UpperCAmelCase					:  Optional[Any]         =    torch.mean(torch.abs(lowerCAmelCase__	)	)

          if str(lowerCAmelCase__	).startswith("""cpu"""	):
               # The following sum varies between 148 and 156 on mps. Why?
               assert abs(result_sum.item() - 0.1_2_3_3	) < 1e-2
               assert abs(result_mean.item() - 0.0_0_0_2	) < 1e-3
          elif str(lowerCAmelCase__	).startswith("""mps"""	):
               # Larger tolerance on mps
               assert abs(result_mean.item() - 0.0_0_0_2	) < 1e-2
          else:
               # CUDA
               assert abs(result_sum.item() - 0.1_2_3_3	) < 1e-2
               assert abs(result_mean.item() - 0.0_0_0_2	) < 1e-3



     def     snake_case_ (self	):
          _UpperCAmelCase					:  int         =    self.scheduler_classes[0]
          _UpperCAmelCase					:  str         =    self.get_scheduler_config()
          _UpperCAmelCase					:  Union[str, Any]         =    scheduler_class(**lowerCAmelCase__						,	use_karras_sigmas=lowerCAmelCase__	)

          scheduler.set_timesteps(self.num_inference_steps						,	device=lowerCAmelCase__	)

          _UpperCAmelCase					:  Optional[int]         =    self.dummy_model()
          _UpperCAmelCase					:  Optional[Any]         =    self.dummy_sample_deter.to(lowerCAmelCase__	) * scheduler.init_noise_sigma
          _UpperCAmelCase					:  Union[str, Any]         =    sample.to(lowerCAmelCase__	)

          for t in scheduler.timesteps:
               _UpperCAmelCase					:  Dict         =    scheduler.scale_model_input(lowerCAmelCase__						,	lowerCAmelCase__	)

               _UpperCAmelCase					:  Optional[Any]         =    model(lowerCAmelCase__						,	lowerCAmelCase__	)

               _UpperCAmelCase					:  Optional[int]         =    scheduler.step(lowerCAmelCase__						,	lowerCAmelCase__						,	lowerCAmelCase__	)
               _UpperCAmelCase					:  Optional[Any]         =    output.prev_sample

          _UpperCAmelCase					:  Union[str, Any]         =    torch.sum(torch.abs(lowerCAmelCase__	)	)
          _UpperCAmelCase					:  List[Any]         =    torch.mean(torch.abs(lowerCAmelCase__	)	)

          assert abs(result_sum.item() - 0.0_0_0_1_5	) < 1e-2
          assert abs(result_mean.item() - 1.9_869_554_535_034_695e-07	) < 1e-2


