


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__   (	__a   ):
					__SCREAMING_SNAKE_CASE       :  "DiagonalGaussianDistribution"







class        UpperCamelCase__   (	__a							,				__a   ):
					__SCREAMING_SNAKE_CASE       :  Tuple						=   True

					@register_to_config
					def __init__(     self       :   Union[str, Any]							,					UpperCamelCase__       :   int = 3							,					UpperCamelCase__       :   int = 3							,					UpperCamelCase__       :   Tuple[str] = ("DownEncoderBlock2D",)							,					UpperCamelCase__       :   Tuple[str] = ("UpDecoderBlock2D",)							,					UpperCamelCase__       :   Tuple[int] = (64,)							,					UpperCamelCase__       :   int = 1							,					UpperCamelCase__       :   str = "silu"							,					UpperCamelCase__       :   int = 4							,					UpperCamelCase__       :   int = 32							,					UpperCamelCase__       :   int = 32							,					UpperCamelCase__       :   float = 0.18_215							,					):






												'''simple docstring'''






												super().__init__()

												# pass init params to Encoder
												lowercase_  							=			Encoder(
												    in_channels=snake_case__							,					out_channels=snake_case__							,					down_block_types=snake_case__							,					block_out_channels=snake_case__							,					layers_per_block=snake_case__							,					act_fn=snake_case__							,					norm_num_groups=snake_case__							,					double_z=snake_case__							,					)

												# pass init params to Decoder
												lowercase_  							=			Decoder(
												    in_channels=snake_case__							,					out_channels=snake_case__							,					up_block_types=snake_case__							,					block_out_channels=snake_case__							,					layers_per_block=snake_case__							,					norm_num_groups=snake_case__							,					act_fn=snake_case__							,					)

												lowercase_  							=			nn.Convad(2 * latent_channels							,					2 * latent_channels							,					1       )
												lowercase_  							=			nn.Convad(snake_case__							,					snake_case__							,					1       )

												lowercase_  							=			False
												lowercase_  							=			False

												# only relevant if vae tiling is enabled
												lowercase_  							=			self.config.sample_size
												lowercase_  							=			(
												    self.config.sample_size[0]
												    if isinstance(self.config.sample_size							,					(list, tuple)       )
												    else self.config.sample_size
												)
												lowercase_  							=			int(sample_size / (2 ** (len(self.config.block_out_channels       ) - 1))       )
												lowercase_  							=			0.25

					def   UpperCAmelCase__       (     self       :   int							,					UpperCamelCase__       :   Dict							,					UpperCamelCase__       :   Optional[int]=False       ):






												'''simple docstring'''






												if isinstance(snake_case__							,					(Encoder, Decoder)       ):
																			lowercase_  							=			value

					def   UpperCAmelCase__       (     self       :   Any							,					UpperCamelCase__       :   bool = True       ):






												'''simple docstring'''






												lowercase_  							=			use_tiling

					def   UpperCAmelCase__       (     self       :   Optional[int]       ):






												'''simple docstring'''






												self.enable_tiling(snake_case__       )

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






												'''simple docstring'''






												lowercase_  							=			True

					def   UpperCAmelCase__       (     self       :   str       ):






												'''simple docstring'''






												lowercase_  							=			False

					@property
					# Copied from diffusers.models.unet_2d_condition.UNet2DConditionModel.attn_processors
					def   UpperCAmelCase__       (     self       :   List[str]       ):






												'''simple docstring'''






												lowercase_  							=			{}

												def fn_recursive_add_processors(UpperCamelCase__       :   str							,					UpperCamelCase__       :   torch.nn.Module							,					UpperCamelCase__       :   Dict[str, AttentionProcessor]       ):
																			if hasattr(snake_case__							,					"""set_processor"""       ):
																										lowercase_  							=			module.processor

																			for sub_name, child in module.named_children():
																										fn_recursive_add_processors(F'''{name}.{sub_name}'''							,					snake_case__							,					snake_case__       )

																			return processors

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

												return processors

					def   UpperCAmelCase__       (     self       :   List[Any]							,					UpperCamelCase__       :   Union[AttentionProcessor, Dict[str, AttentionProcessor]]       ):






												'''simple docstring'''






												lowercase_  							=			len(self.attn_processors.keys()       )

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

												def fn_recursive_attn_processor(UpperCamelCase__       :   str							,					UpperCamelCase__       :   torch.nn.Module							,					UpperCamelCase__       :   List[Any]       ):
																			if hasattr(snake_case__							,					"""set_processor"""       ):
																										if not isinstance(snake_case__							,					snake_case__       ):
																																	module.set_processor(snake_case__       )
																										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}'''							,					snake_case__							,					snake_case__       )

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

					def   UpperCAmelCase__       (     self       :   Optional[int]       ):






												'''simple docstring'''






												self.set_attn_processor(AttnProcessor()       )

					@apply_forward_hook
					def   UpperCAmelCase__       (     self       :   Union[str, Any]							,					UpperCamelCase__       :   torch.FloatTensor							,					UpperCamelCase__       :   bool = True       ):






												'''simple docstring'''






												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(snake_case__							,					return_dict=snake_case__       )

												if self.use_slicing and x.shape[0] > 1:
																			lowercase_  							=			[self.encoder(snake_case__       ) for x_slice in x.split(1       )]
																			lowercase_  							=			torch.cat(snake_case__       )
												else:
																			lowercase_  							=			self.encoder(snake_case__       )

												lowercase_  							=			self.quant_conv(snake_case__       )
												lowercase_  							=			DiagonalGaussianDistribution(snake_case__       )

												if not return_dict:
																			return (posterior,)

												return AutoencoderKLOutput(latent_dist=snake_case__       )

					def   UpperCAmelCase__       (     self       :   Optional[int]							,					UpperCamelCase__       :   torch.FloatTensor							,					UpperCamelCase__       :   bool = True       ):






												'''simple docstring'''






												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(snake_case__							,					return_dict=snake_case__       )

												lowercase_  							=			self.post_quant_conv(snake_case__       )
												lowercase_  							=			self.decoder(snake_case__       )

												if not return_dict:
																			return (dec,)

												return DecoderOutput(sample=snake_case__       )

					@apply_forward_hook
					def   UpperCAmelCase__       (     self       :   Any							,					UpperCamelCase__       :   torch.FloatTensor							,					UpperCamelCase__       :   bool = True       ):






												'''simple docstring'''






												if self.use_slicing and z.shape[0] > 1:
																			lowercase_  							=			[self._decode(snake_case__       ).sample for z_slice in z.split(1       )]
																			lowercase_  							=			torch.cat(snake_case__       )
												else:
																			lowercase_  							=			self._decode(snake_case__       ).sample

												if not return_dict:
																			return (decoded,)

												return DecoderOutput(sample=snake_case__       )

					def   UpperCAmelCase__       (     self       :   Dict							,					UpperCamelCase__       :   List[str]							,					UpperCamelCase__       :   Dict							,					UpperCamelCase__       :   Any       ):






												'''simple docstring'''






												lowercase_  							=			min(a.shape[2]							,					b.shape[2]							,					snake_case__       )
												for y in range(snake_case__       ):
																			lowercase_  							=			a[:, :, -blend_extent + y, :] * (1 - y / blend_extent) + b[:, :, y, :] * (y / blend_extent)
												return b

					def   UpperCAmelCase__       (     self       :   int							,					UpperCamelCase__       :   Any							,					UpperCamelCase__       :   List[str]							,					UpperCamelCase__       :   Optional[int]       ):






												'''simple docstring'''






												lowercase_  							=			min(a.shape[3]							,					b.shape[3]							,					snake_case__       )
												for x in range(snake_case__       ):
																			lowercase_  							=			a[:, :, :, -blend_extent + x] * (1 - x / blend_extent) + b[:, :, :, x] * (x / blend_extent)
												return b

					def   UpperCAmelCase__       (     self       :   Optional[int]							,					UpperCamelCase__       :   torch.FloatTensor							,					UpperCamelCase__       :   bool = True       ):






												'''simple docstring'''






												lowercase_  							=			int(self.tile_sample_min_size * (1 - self.tile_overlap_factor)       )
												lowercase_  							=			int(self.tile_latent_min_size * self.tile_overlap_factor       )
												lowercase_  							=			self.tile_latent_min_size - blend_extent

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

												lowercase_  							=			torch.cat(snake_case__							,					dim=2       )
												lowercase_  							=			DiagonalGaussianDistribution(snake_case__       )

												if not return_dict:
																			return (posterior,)

												return AutoencoderKLOutput(latent_dist=snake_case__       )

					def   UpperCAmelCase__       (     self       :   Any							,					UpperCamelCase__       :   torch.FloatTensor							,					UpperCamelCase__       :   bool = True       ):






												'''simple docstring'''






												lowercase_  							=			int(self.tile_latent_min_size * (1 - self.tile_overlap_factor)       )
												lowercase_  							=			int(self.tile_sample_min_size * self.tile_overlap_factor       )
												lowercase_  							=			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.
												lowercase_  							=			[]
												for i in range(0							,					z.shape[2]							,					snake_case__       ):
																			lowercase_  							=			[]
																			for j in range(0							,					z.shape[3]							,					snake_case__       ):
																										lowercase_  							=			z[:, :, i : i + self.tile_latent_min_size, j : j + self.tile_latent_min_size]
																										lowercase_  							=			self.post_quant_conv(snake_case__       )
																										lowercase_  							=			self.decoder(snake_case__       )
																										row.append(snake_case__       )
																			rows.append(snake_case__       )
												lowercase_  							=			[]
												for i, row in enumerate(snake_case__       ):
																			lowercase_  							=			[]
																			for j, tile in enumerate(snake_case__       ):
																										# blend the above tile and the left tile
																										# to the current tile and add the current tile to the result row
																										if i > 0:
																																	lowercase_  							=			self.blend_v(rows[i - 1][j]							,					snake_case__							,					snake_case__       )
																										if j > 0:
																																	lowercase_  							=			self.blend_h(row[j - 1]							,					snake_case__							,					snake_case__       )
																										result_row.append(tile[:, :, :row_limit, :row_limit]       )
																			result_rows.append(torch.cat(snake_case__							,					dim=3       )       )

												lowercase_  							=			torch.cat(snake_case__							,					dim=2       )
												if not return_dict:
																			return (dec,)

												return DecoderOutput(sample=snake_case__       )







					def   UpperCAmelCase__       (     self       :   int							,					UpperCamelCase__       :   torch.FloatTensor							,					UpperCamelCase__       :   bool = False							,					UpperCamelCase__       :   bool = True							,					UpperCamelCase__       :   Optional[torch.Generator] = None							,					):






												'''simple docstring'''






												lowercase_  							=			sample
												lowercase_  							=			self.encode(snake_case__       ).latent_dist
												if sample_posterior:
																			lowercase_  							=			posterior.sample(generator=snake_case__       )
												else:
																			lowercase_  							=			posterior.mode()
												lowercase_  							=			self.decode(snake_case__       ).sample

												if not return_dict:
																			return (dec,)

												return DecoderOutput(sample=snake_case__       )






def 			UpperCAmelCase_				(      UpperCAmelCase__=2_8_1_2_3  ):
					lowercase_  							=			[1] * (limit + 1)

					for i in range(2						,							int(limit**0.5  ) + 1  ):
										sum_divs[i * i] += i
										for k in range(i + 1						,							limit // i + 1  ):
															sum_divs[k * i] += k + i

					lowercase_  							=			set()
					lowercase_  							=			0

					for n in range(1						,							limit + 1  ):
										if sum_divs[n] > n:
															abundants.add(UpperCAmelCase__  )

										if not any((n - a in abundants) for a in abundants  ):
															res += n

					return res


if __name__ == "__main__":
							print(solution())


