




"""simple docstring"""



import glob
import os
from typing import Dict, List, Union

import torch

from diffusers.utils import is_safetensors_available


if is_safetensors_available():
      import safetensors.torch

from huggingface_hub import snapshot_download

from diffusers import DiffusionPipeline, __version__
from diffusers.schedulers.scheduling_utils import SCHEDULER_CONFIG_NAME
from diffusers.utils import CONFIG_NAME, DIFFUSERS_CACHE, ONNX_WEIGHTS_NAME, WEIGHTS_NAME




class       UpperCAmelCase_    (		A_				):




    def __init__(       self		:			List[Any] ) ->				Union[str, Any]:




     '''simple docstring'''

     self.register_to_config()
     super().__init__()




    def 				__magic_name__				(       self		:			Optional[int]      ,					snake_case_		:			Any      ,					snake_case_		:			int ) ->				Any:




     '''simple docstring'''

     if dicta == dicta:
      return True
     else:
      A__, A__			=							self._remove_meta_keys(snake_case_ )
      A__, A__			=							self._remove_meta_keys(snake_case_ )
      if configa == configa:
       print(F"""Warning !: Mismatch in keys {meta_keysa} and {meta_keysa}.""" )
       return True
     return False




    def 				__magic_name__				(       self		:			Tuple      ,					snake_case_		:			Dict ) ->				List[str]:




     '''simple docstring'''

     A__			=							[]
     A__			=							config_dict.copy()
     for key in config_dict.keys():
      if key.startswith("_" ):
       temp_dict.pop(snake_case_ )
       meta_keys.append(snake_case_ )
     return (temp_dict, meta_keys)




    @torch.no_grad()
    def 				__magic_name__				(       self		:			Union[str, Any]      ,					snake_case_		:			List[Union[str, os.PathLike]]      ,					**snake_case_		:			Dict ) ->				List[Any]:




     '''simple docstring'''

     A__			=							kwargs.pop("cache_dir"      ,					snake_case_ )
     A__			=							kwargs.pop("resume_download"      ,					snake_case_ )
     A__			=							kwargs.pop("force_download"      ,					snake_case_ )
     A__			=							kwargs.pop("proxies"      ,					snake_case_ )
     A__			=							kwargs.pop("local_files_only"      ,					snake_case_ )
     A__			=							kwargs.pop("use_auth_token"      ,					snake_case_ )
     A__			=							kwargs.pop("revision"      ,					snake_case_ )
     A__			=							kwargs.pop("torch_dtype"      ,					snake_case_ )
     A__			=							kwargs.pop("device_map"      ,					snake_case_ )

     A__			=							kwargs.pop("alpha"      ,					0.5 )
     A__			=							kwargs.pop("interp"      ,					snake_case_ )

     print("Received list"      ,					snake_case_ )
     print(F"""Combining with alpha={alpha}, interpolation mode={interp}""" )

     A__			=							len(snake_case_ )
     # Ignore result from model_index_json comparision of the two checkpoints
     A__			=							kwargs.pop("force"      ,					snake_case_ )

     # If less than 2 checkpoints, nothing to merge. If more than 3, not supported for now.
     if checkpoint_count > 3 or checkpoint_count < 2:
      raise ValueError(
          "Received incorrect number of checkpoints to merge. Ensure that either 2 or 3 checkpoints are being"
          " passed." )

     print("Received the right number of checkpoints" )
     # chkpt0, chkpt1 = pretrained_model_name_or_path_list[0:2]
     # chkpt2 = pretrained_model_name_or_path_list[2] if checkpoint_count == 3 else None

     # Validate that the checkpoints can be merged
     # Step 1: Load the model config and compare the checkpoints. We'll compare the model_index.json first while ignoring the keys starting with '_'
     A__			=							[]
     for pretrained_model_name_or_path in pretrained_model_name_or_path_list:
      A__			=							DiffusionPipeline.load_config(
          snake_case_      ,					cache_dir=snake_case_      ,					resume_download=snake_case_      ,					force_download=snake_case_      ,					proxies=snake_case_      ,					local_files_only=snake_case_      ,					use_auth_token=snake_case_      ,					revision=snake_case_      ,					)
      config_dicts.append(snake_case_ )

     A__			=							True
     for idx in range(1      ,					len(snake_case_ ) ):
      comparison_result &= self._compare_model_configs(config_dicts[idx - 1]      ,					config_dicts[idx] )
      if not force and comparison_result is False:
       raise ValueError("Incompatible checkpoints. Please check model_index.json for the models." )
       print(config_dicts[0]      ,					config_dicts[1] )
     print("Compatible model_index.json files found" )
     # Step 2: Basic Validation has succeeded. Let's download the models and save them into our local files.
     A__			=							[]
     for pretrained_model_name_or_path, config_dict in zip(snake_case_      ,					snake_case_ ):
      A__			=							[k for k in config_dict.keys() if not k.startswith("_" )]
      A__			=							[os.path.join(snake_case_      ,					"*" ) for k in folder_names]
      allow_patterns += [
          WEIGHTS_NAME,
          SCHEDULER_CONFIG_NAME,
          CONFIG_NAME,
          ONNX_WEIGHTS_NAME,
          DiffusionPipeline.config_name,
      ]
      A__			=							config_dict.get("_class_name" )
      A__			=							{"diffusers": __version__, "pipeline_class": requested_pipeline_class}

      A__			=							(
          pretrained_model_name_or_path
          if os.path.isdir(snake_case_ )
          else snapshot_download(
              snake_case_      ,					cache_dir=snake_case_      ,					resume_download=snake_case_      ,					proxies=snake_case_      ,					local_files_only=snake_case_      ,					use_auth_token=snake_case_      ,					revision=snake_case_      ,					allow_patterns=snake_case_      ,					user_agent=snake_case_      ,					)
      )
      print("Cached Folder"      ,					snake_case_ )
      cached_folders.append(snake_case_ )

     # Step 3:-
     # Load the first checkpoint as a diffusion pipeline and modify its module state_dict in place
     A__			=							DiffusionPipeline.from_pretrained(
         cached_folders[0]      ,					torch_dtype=snake_case_      ,					device_map=snake_case_ )
     final_pipe.to(self.device )

     A__			=							None
     if len(snake_case_ ) > 2:
      A__			=							os.path.join(cached_folders[2] )

     if interp == "sigmoid":
      A__			=							CheckpointMergerPipeline.sigmoid
     elif interp == "inv_sigmoid":
      A__			=							CheckpointMergerPipeline.inv_sigmoid
     elif interp == "add_diff":
      A__			=							CheckpointMergerPipeline.add_difference
     else:
      A__			=							CheckpointMergerPipeline.weighted_sum

     # Find each module's state dict.
     for attr in final_pipe.config.keys():
      if not attr.startswith("_" ):
       A__			=							os.path.join(cached_folders[1]      ,					snake_case_ )
       if os.path.exists(snake_case_ ):
        A__			=							[
            *glob.glob(os.path.join(snake_case_      ,					"*.safetensors" ) ),
            *glob.glob(os.path.join(snake_case_      ,					"*.bin" ) ),
        ]
        A__			=							files[0] if len(snake_case_ ) > 0 else None
       if len(snake_case_ ) < 3:
        A__			=							None
       else:
        A__			=							os.path.join(cached_folders[2]      ,					snake_case_ )
        if os.path.exists(snake_case_ ):
         A__			=							[
             *glob.glob(os.path.join(snake_case_      ,					"*.safetensors" ) ),
             *glob.glob(os.path.join(snake_case_      ,					"*.bin" ) ),
         ]
         A__			=							files[0] if len(snake_case_ ) > 0 else None
                # For an attr if both checkpoint_path_1 and 2 are None, ignore.
                # If atleast one is present, deal with it according to interp method, of course only if the state_dict keys match.
       if checkpoint_path_a is None and checkpoint_path_a is None:
        print(F"""Skipping {attr}: not present in 2nd or 3d model""" )
        continue
       try:
        A__			=							getattr(snake_case_      ,					snake_case_ )
        if isinstance(snake_case_      ,					snake_case_ ):  # ignore requires_safety_checker boolean
         continue
        A__			=							getattr(snake_case_      ,					"state_dict" )
        A__			=							theta_a()

        A__			=							getattr(snake_case_      ,					"load_state_dict" )
        A__			=							(
            safetensors.torch.load_file(snake_case_ )
            if (is_safetensors_available() and checkpoint_path_a.endswith(".safetensors" ))
            else torch.load(snake_case_      ,					map_location="cpu" )
        )
        A__			=							None
        if checkpoint_path_a:
         A__			=							(
             safetensors.torch.load_file(snake_case_ )
             if (is_safetensors_available() and checkpoint_path_a.endswith(".safetensors" ))
             else torch.load(snake_case_      ,					map_location="cpu" )
         )

        if not theta_a.keys() == theta_a.keys():
         print(F"""Skipping {attr}: key mismatch""" )
         continue
        if theta_a and not theta_a.keys() == theta_a.keys():
         print(F"""Skipping {attr}:y mismatch""" )
       except Exception as e:
        print(F"""Skipping {attr} do to an unexpected error: {str(snake_case_ )}""" )
        continue
       print(F"""MERGING {attr}""" )

       for key in theta_a.keys():
        if theta_a:
         A__			=							theta_func(theta_a[key]      ,					theta_a[key]      ,					theta_a[key]      ,					snake_case_ )
        else:
         A__			=							theta_func(theta_a[key]      ,					theta_a[key]      ,					snake_case_      ,					snake_case_ )

       del theta_a
       del theta_a
       update_theta_a(snake_case_ )

       del theta_a
     return final_pipe




    @staticmethod
    def 				__magic_name__				(       snake_case_		:			List[Any]      ,					snake_case_		:			Optional[int]      ,					snake_case_		:			Any      ,					snake_case_		:			int ) ->				Optional[Any]:




     '''simple docstring'''

     return ((1 - alpha) * thetaa) + (alpha * thetaa)




    @staticmethod
    def 				__magic_name__				(       snake_case_		:			List[str]      ,					snake_case_		:			List[Any]      ,					snake_case_		:			Optional[int]      ,					snake_case_		:			Optional[Any] ) ->				Tuple:




     '''simple docstring'''

     A__			=							alpha * alpha * (3 - (2 * alpha))
     return thetaa + ((thetaa - thetaa) * alpha)




    @staticmethod
    def 				__magic_name__				(       snake_case_		:			str      ,					snake_case_		:			Dict      ,					snake_case_		:			List[Any]      ,					snake_case_		:			Tuple ) ->				Any:




     '''simple docstring'''

     import math

     A__			=							0.5 - math.sin(math.asin(1.0 - 2.0 * alpha ) / 3.0 )
     return thetaa + ((thetaa - thetaa) * alpha)




    @staticmethod
    def 				__magic_name__				(       snake_case_		:			int      ,					snake_case_		:			Any      ,					snake_case_		:			Dict      ,					snake_case_		:			Any ) ->				str:




     '''simple docstring'''

     return thetaa + (thetaa - thetaa) * (1.0 - alpha)











"""simple docstring"""



import os

from apache_beam.io.filesystems import FileSystems
from apache_beam.pipeline import Pipeline

from .logging import get_logger


SCREAMING_SNAKE_CASE							=			2 << 20  # 2mb
SCREAMING_SNAKE_CASE							=			get_logger(__name__)




class       UpperCAmelCase_    (		A_				):




    def 				__magic_name__				(       self		:			Tuple ) ->				Optional[int]:




     '''simple docstring'''

     A__			=							self._options.get_all_options().get("runner" )
     return runner in [None, "DirectRunner", "PortableRunner"]







def     _SCREAMING_SNAKE_CASE  (				lowercase_     ,					lowercase_     ,					lowercase_=False		)		->						Dict:
 A__			=							FileSystems
 if fs.exists(lowercase_		):
  if force_upload:
   logger.info(f"""Remote path already exist: {remote_file_path}. Overwriting it as force_upload=True."""		)
  else:
   logger.info(f"""Remote path already exist: {remote_file_path}. Skipping it as force_upload=False."""		)
   return
 with fs.create(lowercase_		) as remote_file:
  with open(lowercase_     ,					"rb"		) as local_file:
   A__			=							local_file.read(lowercase_		)
   while chunk:
    remote_file.write(lowercase_		)
    A__			=							local_file.read(lowercase_		)







def     _SCREAMING_SNAKE_CASE  (				lowercase_     ,					lowercase_     ,					lowercase_=False		)		->						int:
 A__			=							FileSystems
 if os.path.exists(lowercase_		):
  if force_download:
   logger.info(f"""Local path already exist: {remote_file_path}. Overwriting it as force_upload=True."""		)
  else:
   logger.info(f"""Local path already exist: {remote_file_path}. Skipping it as force_upload=False."""		)
   return
 with fs.open(lowercase_		) as remote_file:
  with open(lowercase_     ,					"wb"		) as local_file:
   A__			=							remote_file.read(lowercase_		)
   while chunk:
    local_file.write(lowercase_		)
    A__			=							remote_file.read(lowercase_		)





