


from typing import Callable, List, Optional, Union

import torch

from ...models import UNetaDModel
from ...schedulers import CMStochasticIterativeScheduler
from ...utils import (
    is_accelerate_available,
    is_accelerate_version,
    logging,
    randn_tensor,
    replace_example_docstring,
)
from ..pipeline_utils import DiffusionPipeline, ImagePipelineOutput


snake_case			:      Optional[Any] 							=   logging.get_logger(__name__)  # pylint: disable=invalid-name


snake_case			:      int 							=   '\n    Examples:\n        ```py\n        >>> import torch\n\n        >>> from diffusers import ConsistencyModelPipeline\n\n        >>> device = \"cuda\"\n        >>> # Load the cd_imagenet64_l2 checkpoint.\n        >>> model_id_or_path = \"openai/diffusers-cd_imagenet64_l2\"\n        >>> pipe = ConsistencyModelPipeline.from_pretrained(model_id_or_path, torch_dtype=torch.float16)\n        >>> pipe.to(device)\n\n        >>> # Onestep Sampling\n        >>> image = pipe(num_inference_steps=1).images[0]\n        >>> image.save(\"cd_imagenet64_l2_onestep_sample.png\")\n\n        >>> # Onestep sampling, class-conditional image generation\n        >>> # ImageNet-64 class label 145 corresponds to king penguins\n        >>> image = pipe(num_inference_steps=1, class_labels=145).images[0]\n        >>> image.save(\"cd_imagenet64_l2_onestep_sample_penguin.png\")\n\n        >>> # Multistep sampling, class-conditional image generation\n        >>> # Timesteps can be explicitly specified; the particular timesteps below are from the original Github repo:\n        >>> # https://github.com/openai/consistency_models/blob/main/scripts/launch.sh#L77\n        >>> image = pipe(num_inference_steps=None, timesteps=[22, 0], class_labels=145).images[0]\n        >>> image.save(\"cd_imagenet64_l2_multistep_sample_penguin.png\")\n        ```\n'



class    __lowercase  (       __SCREAMING_SNAKE_CASE							):

       """simple docstring"""


       def __init__(    self				, A_				, A_	)->	None:
           super().__init__()

           self.register_modules(
               unet=UpperCamelCase__				, scheduler=UpperCamelCase__				, )

           _SCREAMING_SNAKE_CASE      = None





       def 		__magic_name__			(    self				, A_=0	)->	int:







           if is_accelerate_available() and is_accelerate_version('>='				, '0.14.0'	):
               from accelerate import cpu_offload
           else:
               raise ImportError('`enable_sequential_cpu_offload` requires `accelerate v0.14.0` or higher'	)

           _SCREAMING_SNAKE_CASE      = torch.device(F'''cuda:{gpu_id}'''	)

           if self.device.type != "cpu":
               self.to('cpu'				, silence_dtype_warnings=UpperCamelCase__	)
               torch.cuda.empty_cache()  # otherwise we don't see the memory savings (but they probably exist)

           for cpu_offloaded_model in [self.unet]:
               cpu_offload(UpperCamelCase__				, UpperCamelCase__	)

           if self.safety_checker is not None:
               cpu_offload(self.safety_checker				, execution_device=UpperCamelCase__				, offload_buffers=UpperCamelCase__	)





       def 		__magic_name__			(    self				, A_=0	)->	Dict:







           if is_accelerate_available() and is_accelerate_version('>='				, '0.17.0.dev0'	):
               from accelerate import cpu_offload_with_hook
           else:
               raise ImportError('`enable_model_cpu_offload` requires `accelerate v0.17.0` or higher.'	)

           _SCREAMING_SNAKE_CASE      = torch.device(F'''cuda:{gpu_id}'''	)

           if self.device.type != "cpu":
               self.to('cpu'				, silence_dtype_warnings=UpperCamelCase__	)
               torch.cuda.empty_cache()  # otherwise we don't see the memory savings (but they probably exist)

           _SCREAMING_SNAKE_CASE      = None
           for cpu_offloaded_model in [self.unet]:
               _SCREAMING_SNAKE_CASE      = cpu_offload_with_hook(UpperCamelCase__				, UpperCamelCase__				, prev_module_hook=UpperCamelCase__	)

           if self.safety_checker is not None:
               _SCREAMING_SNAKE_CASE      = cpu_offload_with_hook(self.safety_checker				, UpperCamelCase__				, prev_module_hook=UpperCamelCase__	)

           # We'll offload the last model manually.
           _SCREAMING_SNAKE_CASE      = hook





       @property
       # Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.StableDiffusionPipeline._execution_device
       def 		__magic_name__			(    self	)->	List[str]:







           if not hasattr(self.unet				, '_hf_hook'	):
               return self.device
           for module in self.unet.modules():
               if (
                   hasattr(UpperCamelCase__				, '_hf_hook'	)
                   and hasattr(module._hf_hook				, 'execution_device'	)
                   and module._hf_hook.execution_device is not None
               ):
                   return torch.device(module._hf_hook.execution_device	)
           return self.device





       def 		__magic_name__			(    self				, A_				, A_				, A_				, A_				, A_				, A_				, A_				, A_=None	)->	Tuple:
           _SCREAMING_SNAKE_CASE      = (batch_size, num_channels, height, width)
           if isinstance(UpperCamelCase__				, UpperCamelCase__	) and len(UpperCamelCase__	) != batch_size:
               raise ValueError(
                   F'''You have passed a list of generators of length {len(UpperCamelCase__	)}, but requested an effective batch'''
                   F''' size of {batch_size}. Make sure the batch size matches the length of the generators.'''	)

           if latents is None:
               _SCREAMING_SNAKE_CASE      = randn_tensor(UpperCamelCase__				, generator=UpperCamelCase__				, device=UpperCamelCase__				, dtype=UpperCamelCase__	)
           else:
               _SCREAMING_SNAKE_CASE      = latents.to(device=UpperCamelCase__				, dtype=UpperCamelCase__	)

           # scale the initial noise by the standard deviation required by the scheduler
           _SCREAMING_SNAKE_CASE      = latents * self.scheduler.init_noise_sigma
           return latents





       def 		__magic_name__			(    self				, A_				, A_ = "pil"	)->	Union[str, Any]:







           if output_type not in ["pt", "np", "pil"]:
               raise ValueError(
                   F'''output_type={output_type} is not supported. Make sure to choose one of [\'pt\', \'np\', or \'pil\']'''	)

           # Equivalent to diffusers.VaeImageProcessor.denormalize
           _SCREAMING_SNAKE_CASE      = (sample / 2 + 0.5).clamp(0				, 1	)
           if output_type == "pt":
               return sample

           # Equivalent to diffusers.VaeImageProcessor.pt_to_numpy
           _SCREAMING_SNAKE_CASE      = sample.cpu().permute(0				, 2				, 3				, 1	).numpy()
           if output_type == "np":
               return sample

           # Output_type must be 'pil'
           _SCREAMING_SNAKE_CASE      = self.numpy_to_pil(UpperCamelCase__	)
           return sample





       def 		__magic_name__			(    self				, A_				, A_				, A_=None	)->	List[str]:







           if self.unet.config.num_class_embeds is not None:
               if isinstance(UpperCamelCase__				, UpperCamelCase__	):
                   _SCREAMING_SNAKE_CASE      = torch.tensor(UpperCamelCase__				, dtype=torch.int	)
               elif isinstance(UpperCamelCase__				, UpperCamelCase__	):
                   assert batch_size == 1, "Batch size must be 1 if classes is an int"
                   _SCREAMING_SNAKE_CASE      = torch.tensor([class_labels]				, dtype=torch.int	)
               elif class_labels is None:
                   # Randomly generate batch_size class labels
                   # TODO: should use generator here? int analogue of randn_tensor is not exposed in ...utils
                   _SCREAMING_SNAKE_CASE      = torch.randint(0				, self.unet.config.num_class_embeds				, size=(batch_size,)	)
               _SCREAMING_SNAKE_CASE      = class_labels.to(UpperCamelCase__	)
           else:
               _SCREAMING_SNAKE_CASE      = None
           return class_labels





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







           if num_inference_steps is None and timesteps is None:
               raise ValueError('Exactly one of `num_inference_steps` or `timesteps` must be supplied.'	)

           if num_inference_steps is not None and timesteps is not None:
               logger.warning(
                   F'''Both `num_inference_steps`: {num_inference_steps} and `timesteps`: {timesteps} are supplied;'''
                   ' `timesteps` will be used over `num_inference_steps`.'	)

           if latents is not None:
               _SCREAMING_SNAKE_CASE      = (batch_size, 3, img_size, img_size)
               if latents.shape != expected_shape:
                   raise ValueError(F'''The shape of latents is {latents.shape} but is expected to be {expected_shape}.'''	)

           if (callback_steps is None) or (
               callback_steps is not None and (not isinstance(UpperCamelCase__				, UpperCamelCase__	) or callback_steps <= 0)
           ):
               raise ValueError(
                   F'''`callback_steps` has to be a positive integer but is {callback_steps} of type'''
                   F''' {type(UpperCamelCase__	)}.'''	)





       @torch.no_grad()
       @replace_example_docstring(UpperCamelCase__	)
       def __call__(    self				, A_ = 1				, A_ = None				, A_ = 1				, A_ = None				, A_ = None				, A_ = None				, A_ = "pil"				, A_ = True				, A_ = None				, A_ = 1				, )->	str:
           _SCREAMING_SNAKE_CASE      = self.unet.config.sample_size
           _SCREAMING_SNAKE_CASE      = self._execution_device

           # 1. Check inputs
           self.check_inputs(UpperCamelCase__				, UpperCamelCase__				, UpperCamelCase__				, UpperCamelCase__				, UpperCamelCase__				, UpperCamelCase__	)

           # 2. Prepare image latents
           # Sample image latents x_0 ~ N(0, sigma_0^2 * I)
           _SCREAMING_SNAKE_CASE      = self.prepare_latents(
               batch_size=UpperCamelCase__				, num_channels=self.unet.config.in_channels				, height=UpperCamelCase__				, width=UpperCamelCase__				, dtype=self.unet.dtype				, device=UpperCamelCase__				, generator=UpperCamelCase__				, latents=UpperCamelCase__				, )

           # 3. Handle class_labels for class-conditional models
           _SCREAMING_SNAKE_CASE      = self.prepare_class_labels(UpperCamelCase__				, UpperCamelCase__				, class_labels=UpperCamelCase__	)

           # 4. Prepare timesteps
           if timesteps is not None:
               self.scheduler.set_timesteps(timesteps=UpperCamelCase__				, device=UpperCamelCase__	)
               _SCREAMING_SNAKE_CASE      = self.scheduler.timesteps
               _SCREAMING_SNAKE_CASE      = len(UpperCamelCase__	)
           else:
               self.scheduler.set_timesteps(UpperCamelCase__	)
               _SCREAMING_SNAKE_CASE      = self.scheduler.timesteps

           # 5. Denoising loop
           # Multistep sampling: implements Algorithm 1 in the paper
           with self.progress_bar(total=UpperCamelCase__	) as progress_bar:
               for i, t in enumerate(UpperCamelCase__	):
                   _SCREAMING_SNAKE_CASE      = self.scheduler.scale_model_input(UpperCamelCase__				, UpperCamelCase__	)
                   _SCREAMING_SNAKE_CASE      = self.unet(UpperCamelCase__				, UpperCamelCase__				, class_labels=UpperCamelCase__				, return_dict=UpperCamelCase__	)[0]

                   _SCREAMING_SNAKE_CASE      = self.scheduler.step(UpperCamelCase__				, UpperCamelCase__				, UpperCamelCase__				, generator=UpperCamelCase__	)[0]

                   # call the callback, if provided
                   progress_bar.update()
                   if callback is not None and i % callback_steps == 0:
                       callback(UpperCamelCase__				, UpperCamelCase__				, UpperCamelCase__	)

        # 6. Post-process image sample
           _SCREAMING_SNAKE_CASE      = self.postprocess_image(UpperCamelCase__				, output_type=UpperCamelCase__	)

           # Offload last model to CPU
           if hasattr(self				, 'final_offload_hook'	) and self.final_offload_hook is not None:
               self.final_offload_hook.offload()

           if not return_dict:
               return (image,)

           return ImagePipelineOutput(images=UpperCamelCase__	)




import inspect
import warnings

import torch

from .state import AcceleratorState, GradientState
from .utils import DistributedType, honor_type, is_tpu_available


if is_tpu_available(check_device=False):
							import torch_xla.core.xla_model as xm


def 				SCREAMING_SNAKE_CASE (     UpperCAmelCase__   ,UpperCAmelCase__							):

				"""simple docstring"""






				if isinstance(UpperCAmelCase__   ,(list, tuple)							):
								return honor_type(UpperCAmelCase__   ,(move_to_device(UpperCAmelCase__   ,UpperCAmelCase__							) for t in state)							)
				elif isinstance(UpperCAmelCase__   ,UpperCAmelCase__							):
								return type(UpperCAmelCase__							)({k: move_to_device(UpperCAmelCase__   ,UpperCAmelCase__							) for k, v in state.items()}							)
				elif isinstance(UpperCAmelCase__   ,torch.Tensor							):
								return state.to(UpperCAmelCase__							)
				return state



class    __lowercase  (       torch.optim.Optimizer							):

							"""simple docstring"""


							def __init__(    self				, A_				, A_=True				, A_=None	)->	List[str]:
											_SCREAMING_SNAKE_CASE      = optimizer
											_SCREAMING_SNAKE_CASE      = scaler
											_SCREAMING_SNAKE_CASE      = AcceleratorState()
											_SCREAMING_SNAKE_CASE      = GradientState()
											_SCREAMING_SNAKE_CASE      = device_placement
											_SCREAMING_SNAKE_CASE      = False
											_SCREAMING_SNAKE_CASE      = None

											# Handle device placement
											if device_placement:
															_SCREAMING_SNAKE_CASE      = self.optimizer.state_dict()
															if self.accelerator_state.distributed_type == DistributedType.TPU:
																			xm.send_cpu_data_to_device(A_				, self.accelerator_state.device	)
															else:
																			_SCREAMING_SNAKE_CASE      = move_to_device(A_				, self.accelerator_state.device	)
															self.optimizer.load_state_dict(A_	)





							@property
							def 		__magic_name__			(    self	)->	Tuple:
											return self.optimizer.state





							@state.setter
							def 		__magic_name__			(    self				, A_	)->	str:
											_SCREAMING_SNAKE_CASE      = state





							@property
							def 		__magic_name__			(    self	)->	Optional[Any]:
											return self.optimizer.param_groups





							@param_groups.setter
							def 		__magic_name__			(    self				, A_	)->	Tuple:
											_SCREAMING_SNAKE_CASE      = param_groups





							@property
							def 		__magic_name__			(    self	)->	Any:
											return self.optimizer.defaults





							@defaults.setter
							def 		__magic_name__			(    self				, A_	)->	Dict:
											_SCREAMING_SNAKE_CASE      = defaults





							def 		__magic_name__			(    self				, A_	)->	Any:
											self.optimizer.add_param_group(A_	)





							def 		__magic_name__			(    self				, A_	)->	int:
											if self.accelerator_state.distributed_type == DistributedType.TPU and self.device_placement:
															xm.send_cpu_data_to_device(A_				, self.accelerator_state.device	)
											self.optimizer.load_state_dict(A_	)





							def 		__magic_name__			(    self	)->	List[str]:
											return self.optimizer.state_dict()





							def 		__magic_name__			(    self				, A_=None	)->	Any:
											if self.gradient_state.sync_gradients:
															_SCREAMING_SNAKE_CASE      = 'set_to_none' in inspect.signature(self.optimizer.zero_grad	).parameters
															if accept_arg:
																			if set_to_none is None:
																							_SCREAMING_SNAKE_CASE      = False
																			self.optimizer.zero_grad(set_to_none=A_	)
															else:
																			if set_to_none is not None:
																							raise ValueError('`set_to_none` for Optimizer.zero_grad` is not supported by this optimizer.'	)
																			self.optimizer.zero_grad()





							def 		__magic_name__			(    self				, A_=None	)->	Optional[int]:
											if self.gradient_state.sync_gradients:
															if self.accelerator_state.distributed_type == DistributedType.TPU:
																			_SCREAMING_SNAKE_CASE      = {'closure': closure} if closure is not None else {}
																			xm.optimizer_step(self.optimizer				, optimizer_args=A_	)
															elif self.scaler is not None:
																			_SCREAMING_SNAKE_CASE      = False
																			if self._last_scale is None:
																							# `get_scale` is an async operation requiring full synchronization
																							# on CPU and GPUs before finishing. As a result, we store away
																							# the prior one to reduce the call overhead
																							_SCREAMING_SNAKE_CASE      = self.scaler.get_scale()
																							_SCREAMING_SNAKE_CASE      = True
																			self.scaler.step(self.optimizer				, A_	)
																			self.scaler.update()
																			_SCREAMING_SNAKE_CASE      = self.scaler.get_scale()
																			if not new_scale:
																							# If we reduced the loss scale, it means the optimizer step was skipped because of gradient overflow.
																							_SCREAMING_SNAKE_CASE      = scale_after < self._last_scale
																			_SCREAMING_SNAKE_CASE      = scale_after

															else:
																			self.optimizer.step(A_	)





							def 		__magic_name__			(    self				, A_	)->	Dict:
											for param_group in self.optimizer.param_groups:
															_SCREAMING_SNAKE_CASE      = [parameters_map.get(A_				, A_	) for p in param_group['params']]





							@property
							def 		__magic_name__			(    self	)->	str:
											warnings.warn(
											    'The `is_overflow` property is deprecated and will be removed in version 1.0 of Accelerate use '
											    '`optimizer.step_was_skipped` instead.'				, A_				, )
											return self._is_overflow





							@property
							def 		__magic_name__			(    self	)->	int:
											return self._is_overflow





							def __getstate__(    self	)->	Dict:
											return self.__dict__.copy()





							def __setstate__(    self				, A_	)->	List[str]:
											self.__dict__.update(A_	)
