





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 					__SCREAMING_SNAKE_CASE  (  __lowercase:		Union[str, Any]     ,							__lowercase:		Optional[int]     ,							__lowercase:		Tuple     ,							__lowercase:		Any=None):



  '''simple docstring'''






  __lowerCAmelCase			=				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.
    __lowerCAmelCase			=				weight.view(torch.intaa)
    __lowerCAmelCase			=				'''bfloat16'''
  __lowerCAmelCase			=				weight.cpu().numpy()
  __lowerCAmelCase			=				os.path.join(lowercase__     ,							F'''{weight_name}.dat''')
  if index is not None:
    if dtype is None:
      __lowerCAmelCase			=				str(array.dtype)
    __lowerCAmelCase			=				{'''dtype''': dtype, '''shape''': list(array.shape)}
  if array.ndim == 0:
    __lowerCAmelCase			=				array[None]
  __lowerCAmelCase			=				np.memmap(lowercase__     ,							dtype=array.dtype     ,							mode='''w+'''     ,							shape=array.shape)
  __lowerCAmelCase			=				array[:]
  file_array.flush()
  return index


def 					__SCREAMING_SNAKE_CASE  (  __lowercase:		Optional[Any]     ,							__lowercase:		Optional[int]):



  '''simple docstring'''






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

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

  __lowerCAmelCase			=				np.memmap(lowercase__     ,							dtype=lowercase__     ,							shape=lowercase__     ,							mode='''r''')

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

  return weight


def 					__SCREAMING_SNAKE_CASE  (  __lowercase:		Any     ,							__lowercase:		Optional[Any]):



  '''simple docstring'''






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

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

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


def 					__SCREAMING_SNAKE_CASE  (  __lowercase:		List[str]     ,							__lowercase:		List[Any]):



  '''simple docstring'''






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

  # Update index
  save_offload_index(lowercase__     ,							lowercase__)

class   __snake_case				(			A_   ):






    '''simple docstring'''





    def __init__(   self						:		str			,						snake_case						:		str			,						snake_case						:		Optional[Any]							):

      """simple docstring"""





      __lowerCAmelCase			=				dataset
      __lowerCAmelCase			=				prefix





    def __getitem__(   self						:		Dict			,						snake_case						:		Optional[int]							):

      """simple docstring"""





      return self.dataset[f'''{self.prefix}{key}''']





    def __iter__(   self						:		Optional[int]							):

      """simple docstring"""





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





    def __len__(   self						:		Union[str, Any]							):

      """simple docstring"""





      return len(self.dataset							)


class   __snake_case				(			A_   ):






    '''simple docstring'''





    def __init__(   self						:		Optional[Any]			,						snake_case						:		List[str] = None			,						snake_case						:		str = None			,						snake_case						:		Any = None			,						snake_case						:		Tuple=None			,						):

      """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.'''							)

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





    def __getitem__(   self						:		Union[str, Any]			,						snake_case						:		List[str]							):

      """simple docstring"""





      if key in self.state_dict:
        return self.state_dict[key]
      __lowerCAmelCase			=				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

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

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

      __lowerCAmelCase			=				os.path.join(self.save_folder			,						f'''{key}.dat'''							)
      return load_offloaded_weight(snake_case			,						snake_case							)





    def __iter__(   self						:		Tuple							):

      """simple docstring"""





      return iter(self.all_keys							)





    def __len__(   self						:		Optional[int]							):

      """simple docstring"""





      return len(self.all_keys							)


def 					__SCREAMING_SNAKE_CASE  (  __lowercase:		Optional[int]     ,							__lowercase:		str):



  '''simple docstring'''






  __lowerCAmelCase			=				{}
  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







import math
import warnings
from dataclasses import dataclass
from typing import List, Optional, Tuple, Union

import numpy as np
import torch
from scipy import integrate

from ..configuration_utils import ConfigMixin, register_to_config
from ..utils import BaseOutput
from .scheduling_utils import KarrasDiffusionSchedulers, SchedulerMixin

@dataclass
# Copied from diffusers.schedulers.scheduling_ddpm.DDPMSchedulerOutput with DDPM->LMSDiscrete
class   __snake_case				(			_a   ):






    '''simple docstring'''
    _lowerCAmelCase     =	42
    _lowerCAmelCase     =	None


def 					__SCREAMING_SNAKE_CASE  (							__lowercase:		Union[str, Any]     ,							__lowercase:		Optional[Any]=0.999     ,							__lowercase:		List[str]="cosine"     ,							):



  '''simple docstring'''






  if alpha_transform_type == "cosine":

    def alpha_bar_fn(__lowercase:		List[Any]):
      return math.cos((t + 0.008) / 1.008 * math.pi / 2) ** 2

  elif alpha_transform_type == "exp":

    def alpha_bar_fn(__lowercase:		int):
      return math.exp(t * -12.0)

  else:
    raise ValueError(F'''Unsupported alpha_tranform_type: {alpha_transform_type}''')

  __lowerCAmelCase			=				[]
  for i in range(__lowercase):
    __lowerCAmelCase			=				i / num_diffusion_timesteps
    __lowerCAmelCase			=				(i + 1) / num_diffusion_timesteps
    betas.append(min(1 - alpha_bar_fn(__lowercase) / alpha_bar_fn(__lowercase)     ,							__lowercase))
  return torch.tensor(__lowercase     ,							dtype=torch.floataa)




class   __snake_case				(			_a       ,				_a   ):






    '''simple docstring'''
    _lowerCAmelCase     =	[e.name for e in KarrasDiffusionSchedulers]
    _lowerCAmelCase     =	1





    @register_to_config
    def __init__(   self						:		Optional[int]			,						snake_case						:		int = 1_000			,						snake_case						:		float = 0.0001			,						snake_case						:		float = 0.02			,						snake_case						:		str = "linear"			,						snake_case						:		Optional[Union[np.ndarray, List[float]]] = None			,						snake_case						:		Optional[bool] = False			,						snake_case						:		str = "epsilon"			,						snake_case						:		str = "linspace"			,						snake_case						:		int = 0			,						):

      """simple docstring"""





      if trained_betas is not None:
        __lowerCAmelCase			=				torch.tensor(snake_case			,						dtype=torch.floataa							)
      elif beta_schedule == "linear":
        __lowerCAmelCase			=				torch.linspace(snake_case			,						snake_case			,						snake_case			,						dtype=torch.floataa							)
      elif beta_schedule == "scaled_linear":
        # this schedule is very specific to the latent diffusion model.
        __lowerCAmelCase			=				(
            torch.linspace(beta_start**0.5			,						beta_end**0.5			,						snake_case			,						dtype=torch.floataa							) ** 2
        )
      elif beta_schedule == "squaredcos_cap_v2":
        # Glide cosine schedule
        __lowerCAmelCase			=				betas_for_alpha_bar(snake_case							)
      else:
        raise NotImplementedError(f'''{beta_schedule} does is not implemented for {self.__class__}'''							)

      __lowerCAmelCase			=				1.0 - self.betas
      __lowerCAmelCase			=				torch.cumprod(self.alphas			,						dim=0							)

      __lowerCAmelCase			=				np.array(((1 - self.alphas_cumprod) / self.alphas_cumprod) ** 0.5							)
      __lowerCAmelCase			=				np.concatenate([sigmas[::-1], [0.0]]							).astype(np.floataa							)
      __lowerCAmelCase			=				torch.from_numpy(snake_case							)

      # setable values
      __lowerCAmelCase			=				None
      __lowerCAmelCase			=				use_karras_sigmas
      self.set_timesteps(snake_case			,						snake_case							)
      __lowerCAmelCase			=				[]
      __lowerCAmelCase			=				False





    @property
    def 	A		(   self						:		Any							):

      """simple docstring"""





      if self.config.timestep_spacing in ["linspace", "trailing"]:
        return self.sigmas.max()

      return (self.sigmas.max() ** 2 + 1) ** 0.5





    def 	A		(   self						:		Union[str, Any]			,						snake_case						:		torch.FloatTensor			,						snake_case						:		Union[float, torch.FloatTensor]							):

      """simple docstring"""





      if isinstance(snake_case			,						torch.Tensor							):
        __lowerCAmelCase			=				timestep.to(self.timesteps.device							)
      __lowerCAmelCase			=				(self.timesteps == timestep).nonzero().item()
      __lowerCAmelCase			=				self.sigmas[step_index]
      __lowerCAmelCase			=				sample / ((sigma**2 + 1) ** 0.5)
      __lowerCAmelCase			=				True
      return sample





    def 	A		(   self						:		Optional[int]			,						snake_case						:		List[str]			,						snake_case						:		int			,						snake_case						:		Any							):

      """simple docstring"""





      def lms_derivative(snake_case						:		Union[str, Any]							):
        __lowerCAmelCase			=				1.0
        for k in range(snake_case							):
          if current_order == k:
            continue
          prod *= (tau - self.sigmas[t - k]) / (self.sigmas[t - current_order] - self.sigmas[t - k])
        return prod

      __lowerCAmelCase			=				integrate.quad(snake_case			,						self.sigmas[t]			,						self.sigmas[t + 1]			,						epsrel=1e-4							)[0]

      return integrated_coeff





    def 	A		(   self						:		List[str]			,						snake_case						:		int			,						snake_case						:		Union[str, torch.device] = None							):

      """simple docstring"""





      __lowerCAmelCase			=				num_inference_steps

      # "linspace", "leading", "trailing" corresponds to annotation of Table 2. of https://arxiv.org/abs/2305.08891
      if self.config.timestep_spacing == "linspace":
        __lowerCAmelCase			=				np.linspace(0			,						self.config.num_train_timesteps - 1			,						snake_case			,						dtype=snake_case							)[
            ::-1
        ].copy()
      elif self.config.timestep_spacing == "leading":
        __lowerCAmelCase			=				self.config.num_train_timesteps // self.num_inference_steps
        # creates integer timesteps by multiplying by ratio
        # casting to int to avoid issues when num_inference_step is power of 3
        __lowerCAmelCase			=				(np.arange(0			,						snake_case							) * step_ratio).round()[::-1].copy().astype(snake_case							)
        timesteps += self.config.steps_offset
      elif self.config.timestep_spacing == "trailing":
        __lowerCAmelCase			=				self.config.num_train_timesteps / self.num_inference_steps
        # creates integer timesteps by multiplying by ratio
        # casting to int to avoid issues when num_inference_step is power of 3
        __lowerCAmelCase			=				(np.arange(self.config.num_train_timesteps			,						0			,						-step_ratio							)).round().copy().astype(snake_case							)
        timesteps -= 1
      else:
        raise ValueError(
            f'''{self.config.timestep_spacing} is not supported. Please make sure to choose one of \'linspace\', \'leading\' or \'trailing\'.'''							)

      __lowerCAmelCase			=				np.array(((1 - self.alphas_cumprod) / self.alphas_cumprod) ** 0.5							)
      __lowerCAmelCase			=				np.log(snake_case							)
      __lowerCAmelCase			=				np.interp(snake_case			,						np.arange(0			,						len(snake_case							)							)			,						snake_case							)

      if self.use_karras_sigmas:
        __lowerCAmelCase			=				self._convert_to_karras(in_sigmas=snake_case							)
        __lowerCAmelCase			=				np.array([self._sigma_to_t(snake_case			,						snake_case							) for sigma in sigmas]							)

      __lowerCAmelCase			=				np.concatenate([sigmas, [0.0]]							).astype(np.floataa							)

      __lowerCAmelCase			=				torch.from_numpy(snake_case							).to(device=snake_case							)
      if str(snake_case							).startswith('''mps'''							):
        # mps does not support float64
        __lowerCAmelCase			=				torch.from_numpy(snake_case							).to(snake_case			,						dtype=torch.floataa							)
      else:
        __lowerCAmelCase			=				torch.from_numpy(snake_case							).to(device=snake_case							)

      __lowerCAmelCase			=				[]





    def 	A		(   self						:		List[Any]			,						snake_case						:		List[Any]			,						snake_case						:		Dict							):

      """simple docstring"""





      __lowerCAmelCase			=				np.log(snake_case							)

      # get distribution
      __lowerCAmelCase			=				log_sigma - log_sigmas[:, np.newaxis]

      # get sigmas range
      __lowerCAmelCase			=				np.cumsum((dists >= 0)			,						axis=0							).argmax(axis=0							).clip(max=log_sigmas.shape[0] - 2							)
      __lowerCAmelCase			=				low_idx + 1

      __lowerCAmelCase			=				log_sigmas[low_idx]
      __lowerCAmelCase			=				log_sigmas[high_idx]

      # interpolate sigmas
      __lowerCAmelCase			=				(low - log_sigma) / (low - high)
      __lowerCAmelCase			=				np.clip(snake_case			,						0			,						1							)

      # transform interpolation to time range
      __lowerCAmelCase			=				(1 - w) * low_idx + w * high_idx
      __lowerCAmelCase			=				t.reshape(sigma.shape							)
      return t





    def 	A		(   self						:		List[Any]			,						snake_case						:		torch.FloatTensor							):

      """simple docstring"""





      __lowerCAmelCase			=				in_sigmas[-1].item()
      __lowerCAmelCase			=				in_sigmas[0].item()

      __lowerCAmelCase			=				7.0  # 7.0 is the value used in the paper
      __lowerCAmelCase			=				np.linspace(0			,						1			,						self.num_inference_steps							)
      __lowerCAmelCase			=				sigma_min ** (1 / rho)
      __lowerCAmelCase			=				sigma_max ** (1 / rho)
      __lowerCAmelCase			=				(max_inv_rho + ramp * (min_inv_rho - max_inv_rho)) ** rho
      return sigmas





    def 	A		(   self						:		List[str]			,						snake_case						:		torch.FloatTensor			,						snake_case						:		Union[float, torch.FloatTensor]			,						snake_case						:		torch.FloatTensor			,						snake_case						:		int = 4			,						snake_case						:		bool = True			,						):

      """simple docstring"""





      if not self.is_scale_input_called:
        warnings.warn(
            '''The `scale_model_input` function should be called before `step` to ensure correct denoising. '''
            '''See `StableDiffusionPipeline` for a usage example.'''							)

      if isinstance(snake_case			,						torch.Tensor							):
        __lowerCAmelCase			=				timestep.to(self.timesteps.device							)
      __lowerCAmelCase			=				(self.timesteps == timestep).nonzero().item()
      __lowerCAmelCase			=				self.sigmas[step_index]

      # 1. compute predicted original sample (x_0) from sigma-scaled predicted noise
      if self.config.prediction_type == "epsilon":
        __lowerCAmelCase			=				sample - sigma * model_output
      elif self.config.prediction_type == "v_prediction":
        # * c_out + input * c_skip
        __lowerCAmelCase			=				model_output * (-sigma / (sigma**2 + 1) ** 0.5) + (sample / (sigma**2 + 1))
      elif self.config.prediction_type == "sample":
        __lowerCAmelCase			=				model_output
      else:
        raise ValueError(
            f'''prediction_type given as {self.config.prediction_type} must be one of `epsilon`, or `v_prediction`'''							)

      # 2. Convert to an ODE derivative
      __lowerCAmelCase			=				(sample - pred_original_sample) / sigma
      self.derivatives.append(snake_case							)
      if len(self.derivatives							) > order:
        self.derivatives.pop(0							)

      # 3. Compute linear multistep coefficients
      __lowerCAmelCase			=				min(step_index + 1			,						snake_case							)
      __lowerCAmelCase			=				[self.get_lms_coefficient(snake_case			,						snake_case			,						snake_case							) for curr_order in range(snake_case							)]

      # 4. Compute previous sample based on the derivatives path
      __lowerCAmelCase			=				sample + sum(
          coeff * derivative for coeff, derivative in zip(snake_case			,						reversed(self.derivatives							)							)							)

      if not return_dict:
        return (prev_sample,)

      return LMSDiscreteSchedulerOutput(prev_sample=snake_case			,						pred_original_sample=snake_case							)





    def 	A		(   self						:		Optional[int]			,						snake_case						:		torch.FloatTensor			,						snake_case						:		torch.FloatTensor			,						snake_case						:		torch.FloatTensor			,						):

      """simple docstring"""





      __lowerCAmelCase			=				self.sigmas.to(device=original_samples.device			,						dtype=original_samples.dtype							)
      if original_samples.device.type == "mps" and torch.is_floating_point(snake_case							):
        # mps does not support float64
        __lowerCAmelCase			=				self.timesteps.to(original_samples.device			,						dtype=torch.floataa							)
        __lowerCAmelCase			=				timesteps.to(original_samples.device			,						dtype=torch.floataa							)
      else:
        __lowerCAmelCase			=				self.timesteps.to(original_samples.device							)
        __lowerCAmelCase			=				timesteps.to(original_samples.device							)

      __lowerCAmelCase			=				[(schedule_timesteps == t).nonzero().item() for t in timesteps]

      __lowerCAmelCase			=				sigmas[step_indices].flatten()
      while len(sigma.shape							) < len(original_samples.shape							):
        __lowerCAmelCase			=				sigma.unsqueeze(-1							)

      __lowerCAmelCase			=				original_samples + noise * sigma
      return noisy_samples





    def __len__(   self						:		Dict							):

      """simple docstring"""





      return self.config.num_train_timesteps
