"""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  )       ->					Tuple:
													self.register_to_config()
													super().__init__()





						def 					snake_case__						(							self		,__UpperCAmelCase		,__UpperCAmelCase  )       ->					int:
													if dicta == dicta:
																				return True
													else:
																				A__  ,	A__						  =				self._remove_meta_keys(__UpperCAmelCase  )
																				A__  ,	A__						  =				self._remove_meta_keys(__UpperCAmelCase  )
																				if configa == configa:
																											print(f'''Warning !: Mismatch in keys {meta_keysa} and {meta_keysa}.'''  )
																											return True
													return False





						def 					snake_case__						(							self		,__UpperCAmelCase  )       ->					Any:
													A__						  =				[]
													A__						  =				config_dict.copy()
													for key in config_dict.keys():
																				if key.startswith('_'  ):
																											temp_dict.pop(__UpperCAmelCase  )
																											meta_keys.append(__UpperCAmelCase  )
													return (temp_dict, meta_keys)





						@torch.no_grad()
						def 					snake_case__						(							self		,__UpperCAmelCase		,**__UpperCAmelCase  )       ->					List[Any]:
													A__						  =				kwargs.pop('cache_dir'		,__UpperCAmelCase  )
													A__						  =				kwargs.pop('resume_download'		,__UpperCAmelCase  )
													A__						  =				kwargs.pop('force_download'		,__UpperCAmelCase  )
													A__						  =				kwargs.pop('proxies'		,__UpperCAmelCase  )
													A__						  =				kwargs.pop('local_files_only'		,__UpperCAmelCase  )
													A__						  =				kwargs.pop('use_auth_token'		,__UpperCAmelCase  )
													A__						  =				kwargs.pop('revision'		,__UpperCAmelCase  )
													A__						  =				kwargs.pop('torch_dtype'		,__UpperCAmelCase  )
													A__						  =				kwargs.pop('device_map'		,__UpperCAmelCase  )

													A__						  =				kwargs.pop('alpha'		,0.5  )
													A__						  =				kwargs.pop('interp'		,__UpperCAmelCase  )

													print('Received list'		,__UpperCAmelCase  )
													print(f'''Combining with alpha={alpha}, interpolation mode={interp}'''  )

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

													# 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(
																				    __UpperCAmelCase		,cache_dir=__UpperCAmelCase		,resume_download=__UpperCAmelCase		,force_download=__UpperCAmelCase		,proxies=__UpperCAmelCase		,local_files_only=__UpperCAmelCase		,use_auth_token=__UpperCAmelCase		,revision=__UpperCAmelCase		,)
																				config_dicts.append(__UpperCAmelCase  )

													A__						  =				True
													for idx in range(1		,len(__UpperCAmelCase  )  ):
																				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(__UpperCAmelCase		,__UpperCAmelCase  ):
																				A__						  =				[k for k in config_dict.keys() if not k.startswith('_'  )]
																				A__						  =				[os.path.join(__UpperCAmelCase		,'*'  ) 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(__UpperCAmelCase  )
																				    else snapshot_download(
																				        __UpperCAmelCase		,cache_dir=__UpperCAmelCase		,resume_download=__UpperCAmelCase		,proxies=__UpperCAmelCase		,local_files_only=__UpperCAmelCase		,use_auth_token=__UpperCAmelCase		,revision=__UpperCAmelCase		,allow_patterns=__UpperCAmelCase		,user_agent=__UpperCAmelCase		,)
																				)
																				print('Cached Folder'		,__UpperCAmelCase  )
																				cached_folders.append(__UpperCAmelCase  )

													# 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=__UpperCAmelCase		,device_map=__UpperCAmelCase  )
													final_pipe.to(self.device  )

													A__						  =				None
													if len(__UpperCAmelCase  ) > 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]		,__UpperCAmelCase  )
																											if os.path.exists(__UpperCAmelCase  ):
																																		A__						  =				[
																																		    *glob.glob(os.path.join(__UpperCAmelCase		,'*.safetensors'  )  ),
																																		    *glob.glob(os.path.join(__UpperCAmelCase		,'*.bin'  )  ),
																																		]
																																		A__						  =				files[0] if len(__UpperCAmelCase  ) > 0 else None
																											if len(__UpperCAmelCase  ) < 3:
																																		A__						  =				None
																											else:
																																		A__						  =				os.path.join(cached_folders[2]		,__UpperCAmelCase  )
																																		if os.path.exists(__UpperCAmelCase  ):
																																									A__						  =				[
																																									    *glob.glob(os.path.join(__UpperCAmelCase		,'*.safetensors'  )  ),
																																									    *glob.glob(os.path.join(__UpperCAmelCase		,'*.bin'  )  ),
																																									]
																																									A__						  =				files[0] if len(__UpperCAmelCase  ) > 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(__UpperCAmelCase		,__UpperCAmelCase  )
																																		if isinstance(__UpperCAmelCase		,__UpperCAmelCase  ):  # ignore requires_safety_checker boolean
																																									continue
																																		A__						  =				getattr(__UpperCAmelCase		,'state_dict'  )
																																		A__						  =				theta_a()

																																		A__						  =				getattr(__UpperCAmelCase		,'load_state_dict'  )
																																		A__						  =				(
																																		    safetensors.torch.load_file(__UpperCAmelCase  )
																																		    if (is_safetensors_available() and checkpoint_path_a.endswith('.safetensors'  ))
																																		    else torch.load(__UpperCAmelCase		,map_location='cpu'  )
																																		)
																																		A__						  =				None
																																		if checkpoint_path_a:
																																									A__						  =				(
																																									    safetensors.torch.load_file(__UpperCAmelCase  )
																																									    if (is_safetensors_available() and checkpoint_path_a.endswith('.safetensors'  ))
																																									    else torch.load(__UpperCAmelCase		,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(__UpperCAmelCase  )}'''  )
																																		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]		,__UpperCAmelCase  )
																																		else:
																																									A__						  =				theta_func(theta_a[key]		,theta_a[key]		,__UpperCAmelCase		,__UpperCAmelCase  )

																											del theta_a
																											del theta_a
																											update_theta_a(__UpperCAmelCase  )

																											del theta_a
													return final_pipe





						@staticmethod
						def 					snake_case__						(							__UpperCAmelCase		,__UpperCAmelCase		,__UpperCAmelCase		,__UpperCAmelCase  )       ->					Dict:
													return ((1 - alpha) * thetaa) + (alpha * thetaa)





						@staticmethod
						def 					snake_case__						(							__UpperCAmelCase		,__UpperCAmelCase		,__UpperCAmelCase		,__UpperCAmelCase  )       ->					Tuple:
													A__						  =				alpha * alpha * (3 - (2 * alpha))
													return thetaa + ((thetaa - thetaa) * alpha)





						@staticmethod
						def 					snake_case__						(							__UpperCAmelCase		,__UpperCAmelCase		,__UpperCAmelCase		,__UpperCAmelCase  )       ->					Optional[Any]:
													import math

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





						@staticmethod
						def 					snake_case__						(							__UpperCAmelCase		,__UpperCAmelCase		,__UpperCAmelCase		,__UpperCAmelCase  )       ->					Dict:
													return thetaa + (thetaa - thetaa) * (1.0 - alpha)






"""simple docstring"""




def 	UpperCAmelCase       (						UpperCamelCase__ = 100							,     UpperCamelCase__ = 100					):






							"""simple docstring"""





							return max(
							    sum(int(UpperCamelCase__					) for x in str(base**power					)					)
							    for base in range(UpperCamelCase__					)
							    for power in range(UpperCamelCase__					)					)


# Tests
if __name__ == "__main__":
				import doctest

				doctest.testmod()





