






"""simple docstring"""
from dataclasses import dataclass
from typing import Dict, Optional, Tuple, Union

import torch
import torch.nn as nn

from ..configuration_utils import ConfigMixin, register_to_config
from ..utils import BaseOutput, apply_forward_hook
from .attention_processor import AttentionProcessor, AttnProcessor
from .modeling_utils import ModelMixin
from .vae import Decoder, DecoderOutput, DiagonalGaussianDistribution, Encoder







@dataclass
class 			UpperCamelCase_       (__UpperCAmelCase     ):
	__magic_name__	      =				42







class 			UpperCamelCase_       (__UpperCAmelCase				,						__UpperCAmelCase     ):
	__magic_name__	      =				True





	@register_to_config
	def __init__(      self					: Dict	,	lowerCAmelCase_					: int = 3	,	lowerCAmelCase_					: int = 3	,	lowerCAmelCase_					: Tuple[str] = ("DownEncoderBlock2D",)	,	lowerCAmelCase_					: Tuple[str] = ("UpDecoderBlock2D",)	,	lowerCAmelCase_					: Tuple[int] = (64,)	,	lowerCAmelCase_					: int = 1	,	lowerCAmelCase_					: str = "silu"	,	lowerCAmelCase_					: int = 4	,	lowerCAmelCase_					: int = 32	,	lowerCAmelCase_					: int = 32	,	lowerCAmelCase_					: float = 0.1_8_2_1_5	,	)						->			Optional[Any]:
				super().__init__()

				# pass init params to Encoder
				UpperCAmelCase_     : Optional[int]			     =					Encoder(
				    in_channels=lowerCamelCase__	,	out_channels=lowerCamelCase__	,	down_block_types=lowerCamelCase__	,	block_out_channels=lowerCamelCase__	,	layers_per_block=lowerCamelCase__	,	act_fn=lowerCamelCase__	,	norm_num_groups=lowerCamelCase__	,	double_z=lowerCamelCase__	,	)

				# pass init params to Decoder
				UpperCAmelCase_     : List[str]			     =					Decoder(
				    in_channels=lowerCamelCase__	,	out_channels=lowerCamelCase__	,	up_block_types=lowerCamelCase__	,	block_out_channels=lowerCamelCase__	,	layers_per_block=lowerCamelCase__	,	norm_num_groups=lowerCamelCase__	,	act_fn=lowerCamelCase__	,	)

				UpperCAmelCase_     : List[str]			     =					nn.Convad(2 * latent_channels	,	2 * latent_channels	,	1						)
				UpperCAmelCase_     : int			     =					nn.Convad(lowerCamelCase__	,	lowerCamelCase__	,	1						)

				UpperCAmelCase_     : Dict			     =					False
				UpperCAmelCase_     : Optional[Any]			     =					False

				# only relevant if vae tiling is enabled
				UpperCAmelCase_     : Tuple			     =					self.config.sample_size
				UpperCAmelCase_     : Tuple			     =					(
				    self.config.sample_size[0]
				    if isinstance(self.config.sample_size	,	(list, tuple)						)
				    else self.config.sample_size
				)
				UpperCAmelCase_     : Union[str, Any]			     =					int(sample_size / (2 ** (len(self.config.block_out_channels						) - 1))						)
				UpperCAmelCase_     : Any			     =					0.2_5





	def      _SCREAMING_SNAKE_CASE      (      self					: int	,	lowerCAmelCase_					: Optional[Any]	,	lowerCAmelCase_					: int=False						)						->			Optional[Any]:
				if isinstance(lowerCamelCase__	,	(Encoder, Decoder)						):
							UpperCAmelCase_     : Any			     =					value





	def      _SCREAMING_SNAKE_CASE      (      self					: Optional[int]	,	lowerCAmelCase_					: bool = True						)						->			List[str]:
				UpperCAmelCase_     : int			     =					use_tiling





	def      _SCREAMING_SNAKE_CASE      (      self					: List[Any]						)						->			int:
				self.enable_tiling(lowerCamelCase__						)





	def      _SCREAMING_SNAKE_CASE      (      self					: Any						)						->			Optional[Any]:
				UpperCAmelCase_     : Optional[Any]			     =					True





	def      _SCREAMING_SNAKE_CASE      (      self					: Union[str, Any]						)						->			int:
				UpperCAmelCase_     : Optional[int]			     =					False





	@property
	# Copied from diffusers.models.unet_2d_condition.UNet2DConditionModel.attn_processors
	def      _SCREAMING_SNAKE_CASE      (      self					: int						)						->			List[Any]:
				UpperCAmelCase_     : Tuple			     =					{}

				def fn_recursive_add_processors(lowerCAmelCase_					: str	,	lowerCAmelCase_					: torch.nn.Module	,	lowerCAmelCase_					: Dict[str, AttentionProcessor]						):
							if hasattr(lowerCamelCase__	,	"set_processor"						):
										UpperCAmelCase_     : Tuple			     =					module.processor

							for sub_name, child in module.named_children():
										fn_recursive_add_processors(f"""{name}.{sub_name}"""	,	lowerCamelCase__	,	lowerCamelCase__						)

							return processors

				for name, module in self.named_children():
							fn_recursive_add_processors(lowerCamelCase__	,	lowerCamelCase__	,	lowerCamelCase__						)

				return processors





	def      _SCREAMING_SNAKE_CASE      (      self					: Union[str, Any]	,	lowerCAmelCase_					: Union[AttentionProcessor, Dict[str, AttentionProcessor]]						)						->			Union[str, Any]:
				UpperCAmelCase_     : Tuple			     =					len(self.attn_processors.keys()						)

				if isinstance(lowerCamelCase__	,	lowerCamelCase__						) and len(lowerCamelCase__						) != count:
							raise ValueError(
							    f"""A dict of processors was passed, but the number of processors {len(lowerCamelCase__						)} does not match the"""
							    f""" number of attention layers: {count}. Please make sure to pass {count} processor classes."""						)

				def fn_recursive_attn_processor(lowerCAmelCase_					: str	,	lowerCAmelCase_					: torch.nn.Module	,	lowerCAmelCase_					: str						):
							if hasattr(lowerCamelCase__	,	"set_processor"						):
										if not isinstance(lowerCamelCase__	,	lowerCamelCase__						):
													module.set_processor(lowerCamelCase__						)
										else:
													module.set_processor(processor.pop(f"""{name}.processor"""						)						)

							for sub_name, child in module.named_children():
										fn_recursive_attn_processor(f"""{name}.{sub_name}"""	,	lowerCamelCase__	,	lowerCamelCase__						)

				for name, module in self.named_children():
							fn_recursive_attn_processor(lowerCamelCase__	,	lowerCamelCase__	,	lowerCamelCase__						)





	def      _SCREAMING_SNAKE_CASE      (      self					: int						)						->			int:
				self.set_attn_processor(AttnProcessor()						)





	@apply_forward_hook
	def      _SCREAMING_SNAKE_CASE      (      self					: Dict	,	lowerCAmelCase_					: torch.FloatTensor	,	lowerCAmelCase_					: bool = True						)						->			List[str]:
				if self.use_tiling and (x.shape[-1] > self.tile_sample_min_size or x.shape[-2] > self.tile_sample_min_size):
							return self.tiled_encode(lowerCamelCase__	,	return_dict=lowerCamelCase__						)

				if self.use_slicing and x.shape[0] > 1:
							UpperCAmelCase_     : str			     =					[self.encoder(lowerCamelCase__						) for x_slice in x.split(1						)]
							UpperCAmelCase_     : Union[str, Any]			     =					torch.cat(lowerCamelCase__						)
				else:
							UpperCAmelCase_     : Any			     =					self.encoder(lowerCamelCase__						)

				UpperCAmelCase_     : Optional[Any]			     =					self.quant_conv(lowerCamelCase__						)
				UpperCAmelCase_     : List[Any]			     =					DiagonalGaussianDistribution(lowerCamelCase__						)

				if not return_dict:
							return (posterior,)

				return AutoencoderKLOutput(latent_dist=lowerCamelCase__						)





	def      _SCREAMING_SNAKE_CASE      (      self					: List[Any]	,	lowerCAmelCase_					: torch.FloatTensor	,	lowerCAmelCase_					: bool = True						)						->			List[Any]:
				if self.use_tiling and (z.shape[-1] > self.tile_latent_min_size or z.shape[-2] > self.tile_latent_min_size):
							return self.tiled_decode(lowerCamelCase__	,	return_dict=lowerCamelCase__						)

				UpperCAmelCase_     : List[str]			     =					self.post_quant_conv(lowerCamelCase__						)
				UpperCAmelCase_     : Optional[Any]			     =					self.decoder(lowerCamelCase__						)

				if not return_dict:
							return (dec,)

				return DecoderOutput(sample=lowerCamelCase__						)





	@apply_forward_hook
	def      _SCREAMING_SNAKE_CASE      (      self					: Dict	,	lowerCAmelCase_					: torch.FloatTensor	,	lowerCAmelCase_					: bool = True						)						->			Optional[int]:
				if self.use_slicing and z.shape[0] > 1:
							UpperCAmelCase_     : Any			     =					[self._decode(lowerCamelCase__						).sample for z_slice in z.split(1						)]
							UpperCAmelCase_     : List[str]			     =					torch.cat(lowerCamelCase__						)
				else:
							UpperCAmelCase_     : Optional[int]			     =					self._decode(lowerCamelCase__						).sample

				if not return_dict:
							return (decoded,)

				return DecoderOutput(sample=lowerCamelCase__						)





	def      _SCREAMING_SNAKE_CASE      (      self					: Optional[int]	,	lowerCAmelCase_					: Optional[int]	,	lowerCAmelCase_					: List[Any]	,	lowerCAmelCase_					: Optional[int]						)						->			Any:
				UpperCAmelCase_     : Optional[int]			     =					min(a.shape[2]	,	b.shape[2]	,	lowerCamelCase__						)
				for y in range(lowerCamelCase__						):
							UpperCAmelCase_     : Tuple			     =					a[:, :, -blend_extent + y, :] * (1 - y / blend_extent) + b[:, :, y, :] * (y / blend_extent)
				return b





	def      _SCREAMING_SNAKE_CASE      (      self					: Any	,	lowerCAmelCase_					: int	,	lowerCAmelCase_					: Union[str, Any]	,	lowerCAmelCase_					: Union[str, Any]						)						->			Optional[Any]:
				UpperCAmelCase_     : int			     =					min(a.shape[3]	,	b.shape[3]	,	lowerCamelCase__						)
				for x in range(lowerCamelCase__						):
							UpperCAmelCase_     : Dict			     =					a[:, :, :, -blend_extent + x] * (1 - x / blend_extent) + b[:, :, :, x] * (x / blend_extent)
				return b





	def      _SCREAMING_SNAKE_CASE      (      self					: str	,	lowerCAmelCase_					: torch.FloatTensor	,	lowerCAmelCase_					: bool = True						)						->			Dict:
				UpperCAmelCase_     : int			     =					int(self.tile_sample_min_size * (1 - self.tile_overlap_factor)						)
				UpperCAmelCase_     : List[Any]			     =					int(self.tile_latent_min_size * self.tile_overlap_factor						)
				UpperCAmelCase_     : List[str]			     =					self.tile_latent_min_size - blend_extent

				# Split the image into 512x512 tiles and encode them separately.
				UpperCAmelCase_     : Union[str, Any]			     =					[]
				for i in range(0	,	x.shape[2]	,	lowerCamelCase__						):
							UpperCAmelCase_     : List[str]			     =					[]
							for j in range(0	,	x.shape[3]	,	lowerCamelCase__						):
										UpperCAmelCase_     : Optional[Any]			     =					x[:, :, i : i + self.tile_sample_min_size, j : j + self.tile_sample_min_size]
										UpperCAmelCase_     : Dict			     =					self.encoder(lowerCamelCase__						)
										UpperCAmelCase_     : Tuple			     =					self.quant_conv(lowerCamelCase__						)
										row.append(lowerCamelCase__						)
							rows.append(lowerCamelCase__						)
				UpperCAmelCase_     : Dict			     =					[]
				for i, row in enumerate(lowerCamelCase__						):
							UpperCAmelCase_     : Union[str, Any]			     =					[]
							for j, tile in enumerate(lowerCamelCase__						):
										# blend the above tile and the left tile
										# to the current tile and add the current tile to the result row
										if i > 0:
													UpperCAmelCase_     : List[Any]			     =					self.blend_v(rows[i - 1][j]	,	lowerCamelCase__	,	lowerCamelCase__						)
										if j > 0:
													UpperCAmelCase_     : Union[str, Any]			     =					self.blend_h(row[j - 1]	,	lowerCamelCase__	,	lowerCamelCase__						)
										result_row.append(tile[:, :, :row_limit, :row_limit]						)
							result_rows.append(torch.cat(lowerCamelCase__	,	dim=3						)						)

				UpperCAmelCase_     : Any			     =					torch.cat(lowerCamelCase__	,	dim=2						)
				UpperCAmelCase_     : Union[str, Any]			     =					DiagonalGaussianDistribution(lowerCamelCase__						)

				if not return_dict:
							return (posterior,)

				return AutoencoderKLOutput(latent_dist=lowerCamelCase__						)





	def      _SCREAMING_SNAKE_CASE      (      self					: List[Any]	,	lowerCAmelCase_					: torch.FloatTensor	,	lowerCAmelCase_					: bool = True						)						->			Optional[int]:
				UpperCAmelCase_     : Union[str, Any]			     =					int(self.tile_latent_min_size * (1 - self.tile_overlap_factor)						)
				UpperCAmelCase_     : Tuple			     =					int(self.tile_sample_min_size * self.tile_overlap_factor						)
				UpperCAmelCase_     : Dict			     =					self.tile_sample_min_size - blend_extent

				# Split z into overlapping 64x64 tiles and decode them separately.
				# The tiles have an overlap to avoid seams between tiles.
				UpperCAmelCase_     : Optional[Any]			     =					[]
				for i in range(0	,	z.shape[2]	,	lowerCamelCase__						):
							UpperCAmelCase_     : Dict			     =					[]
							for j in range(0	,	z.shape[3]	,	lowerCamelCase__						):
										UpperCAmelCase_     : Any			     =					z[:, :, i : i + self.tile_latent_min_size, j : j + self.tile_latent_min_size]
										UpperCAmelCase_     : Tuple			     =					self.post_quant_conv(lowerCamelCase__						)
										UpperCAmelCase_     : Any			     =					self.decoder(lowerCamelCase__						)
										row.append(lowerCamelCase__						)
							rows.append(lowerCamelCase__						)
				UpperCAmelCase_     : Dict			     =					[]
				for i, row in enumerate(lowerCamelCase__						):
							UpperCAmelCase_     : Optional[int]			     =					[]
							for j, tile in enumerate(lowerCamelCase__						):
										# blend the above tile and the left tile
										# to the current tile and add the current tile to the result row
										if i > 0:
													UpperCAmelCase_     : Optional[int]			     =					self.blend_v(rows[i - 1][j]	,	lowerCamelCase__	,	lowerCamelCase__						)
										if j > 0:
													UpperCAmelCase_     : Union[str, Any]			     =					self.blend_h(row[j - 1]	,	lowerCamelCase__	,	lowerCamelCase__						)
										result_row.append(tile[:, :, :row_limit, :row_limit]						)
							result_rows.append(torch.cat(lowerCamelCase__	,	dim=3						)						)

				UpperCAmelCase_     : Optional[Any]			     =					torch.cat(lowerCamelCase__	,	dim=2						)
				if not return_dict:
							return (dec,)

				return DecoderOutput(sample=lowerCamelCase__						)





	def      _SCREAMING_SNAKE_CASE      (      self					: List[Any]	,	lowerCAmelCase_					: torch.FloatTensor	,	lowerCAmelCase_					: bool = False	,	lowerCAmelCase_					: bool = True	,	lowerCAmelCase_					: Optional[torch.Generator] = None	,	)						->			Optional[Any]:
				UpperCAmelCase_     : str			     =					sample
				UpperCAmelCase_     : List[Any]			     =					self.encode(lowerCamelCase__						).latent_dist
				if sample_posterior:
							UpperCAmelCase_     : int			     =					posterior.sample(generator=lowerCamelCase__						)
				else:
							UpperCAmelCase_     : Optional[Any]			     =					posterior.mode()
				UpperCAmelCase_     : List[Any]			     =					self.decode(lowerCamelCase__						).sample

				if not return_dict:
							return (dec,)

				return DecoderOutput(sample=lowerCamelCase__						)




"""simple docstring"""






def   a_						(					lowerCamelCase       ):
				return str(lowerCamelCase       ) == str(lowerCamelCase       )[::-1]



def   a_						(					lowerCamelCase       ):
				return int(lowerCamelCase       ) + int(str(lowerCamelCase       )[::-1]       )



def   a_						(					lowerCamelCase = 1_0_0_0_0       ):
				UpperCAmelCase__             =							[]
				for num in range(1					,			lowerCamelCase       ):
								UpperCAmelCase__             =							0
								UpperCAmelCase__             =							num
								while iterations < 5_0:
												UpperCAmelCase__             =							sum_reverse(lowerCamelCase       )
												iterations += 1
												if is_palindrome(lowerCamelCase       ):
																break
								else:
												lychrel_nums.append(lowerCamelCase       )
				return len(lowerCamelCase       )


if __name__ == "__main__":
						print(F"""{solution() = }""")



