


'''simple docstring'''





from dataclasses import dataclass
from typing import Optional

import numpy as np
import torch
import torch.nn as nn

from ..utils import BaseOutput, is_torch_version, randn_tensor
from .attention_processor import SpatialNorm
from .unet_ad_blocks import UNetMidBlockaD, get_down_block, get_up_block




@dataclass
class    UpperCAmelCase					(       UpperCamelCase__    ):
			lowercase						= 4_2




class    UpperCAmelCase					(       nn.Module    ):




			def __init__(						self							:		Union[str, Any]       ,       __magic_name__							:		int=3       ,       __magic_name__							:		List[str]=3       ,       __magic_name__							:		int=("DownEncoderBlock2D",)       ,       __magic_name__							:		int=(6_4,)       ,       __magic_name__							:		List[str]=2       ,       __magic_name__							:		Dict=3_2       ,       __magic_name__							:		Dict="silu"       ,       __magic_name__							:		List[str]=True       ,       ):







						"""simple docstring"""







						super().__init__()
						UpperCamelCase         =					layers_per_block

						UpperCamelCase         =					torch.nn.Convad(
						    _a       ,       block_out_channels[0]       ,       kernel_size=3       ,       stride=1       ,       padding=1       ,       )

						UpperCamelCase         =					None
						UpperCamelCase         =					nn.ModuleList([]						)

						# down
						UpperCamelCase         =					block_out_channels[0]
						for i, down_block_type in enumerate(_a						):
									UpperCamelCase         =					output_channel
									UpperCamelCase         =					block_out_channels[i]
									UpperCamelCase         =					i == len(_a						) - 1

									UpperCamelCase         =					get_down_block(
									    _a       ,       num_layers=self.layers_per_block       ,       in_channels=_a       ,       out_channels=_a       ,       add_downsample=not is_final_block       ,       resnet_eps=1e-6       ,       downsample_padding=0       ,       resnet_act_fn=_a       ,       resnet_groups=_a       ,       attention_head_dim=_a       ,       temb_channels=_a       ,       )
									self.down_blocks.append(_a						)

						# mid
						UpperCamelCase         =					UNetMidBlockaD(
						    in_channels=block_out_channels[-1]       ,       resnet_eps=1e-6       ,       resnet_act_fn=_a       ,       output_scale_factor=1       ,       resnet_time_scale_shift="""default"""       ,       attention_head_dim=block_out_channels[-1]       ,       resnet_groups=_a       ,       temb_channels=_a       ,       )

						# out
						UpperCamelCase         =					nn.GroupNorm(num_channels=block_out_channels[-1]       ,       num_groups=_a       ,       eps=1e-6						)
						UpperCamelCase         =					nn.SiLU()

						UpperCamelCase         =					2 * out_channels if double_z else out_channels
						UpperCamelCase         =					nn.Convad(block_out_channels[-1]       ,       _a       ,       3       ,       padding=1						)

						UpperCamelCase         =					False





			def   lowerCamelCase_					(						self							:		Optional[Any]       ,       __magic_name__							:		Union[str, Any]						):







						"""simple docstring"""







						UpperCamelCase         =					x
						UpperCamelCase         =					self.conv_in(_a						)

						if self.training and self.gradient_checkpointing:

									def create_custom_forward(__magic_name__							:		Dict						):
												def custom_forward(*__magic_name__							:		List[str]						):
															return module(*_a						)

												return custom_forward

									# down
									if is_torch_version(""">="""       ,       """1.11.0"""						):
												for down_block in self.down_blocks:
															UpperCamelCase         =					torch.utils.checkpoint.checkpoint(
															    create_custom_forward(_a						)       ,       _a       ,       use_reentrant=_a						)
												# middle
												UpperCamelCase         =					torch.utils.checkpoint.checkpoint(
												    create_custom_forward(self.mid_block						)       ,       _a       ,       use_reentrant=_a						)
									else:
												for down_block in self.down_blocks:
															UpperCamelCase         =					torch.utils.checkpoint.checkpoint(create_custom_forward(_a						)       ,       _a						)
												# middle
												UpperCamelCase         =					torch.utils.checkpoint.checkpoint(create_custom_forward(self.mid_block						)       ,       _a						)

						else:
									# down
									for down_block in self.down_blocks:
												UpperCamelCase         =					down_block(_a						)

									# middle
									UpperCamelCase         =					self.mid_block(_a						)

						# post-process
						UpperCamelCase         =					self.conv_norm_out(_a						)
						UpperCamelCase         =					self.conv_act(_a						)
						UpperCamelCase         =					self.conv_out(_a						)

						return sample




class    UpperCAmelCase					(       nn.Module    ):




			def __init__(						self							:		str       ,       __magic_name__							:		List[str]=3       ,       __magic_name__							:		Optional[int]=3       ,       __magic_name__							:		List[str]=("UpDecoderBlock2D",)       ,       __magic_name__							:		Optional[Any]=(6_4,)       ,       __magic_name__							:		Tuple=2       ,       __magic_name__							:		List[str]=3_2       ,       __magic_name__							:		Tuple="silu"       ,       __magic_name__							:		List[Any]="group"       ,       ):







						"""simple docstring"""







						super().__init__()
						UpperCamelCase         =					layers_per_block

						UpperCamelCase         =					nn.Convad(
						    _a       ,       block_out_channels[-1]       ,       kernel_size=3       ,       stride=1       ,       padding=1       ,       )

						UpperCamelCase         =					None
						UpperCamelCase         =					nn.ModuleList([]						)

						UpperCamelCase         =					in_channels if norm_type == """spatial""" else None

						# mid
						UpperCamelCase         =					UNetMidBlockaD(
						    in_channels=block_out_channels[-1]       ,       resnet_eps=1e-6       ,       resnet_act_fn=_a       ,       output_scale_factor=1       ,       resnet_time_scale_shift="""default""" if norm_type == """group""" else norm_type       ,       attention_head_dim=block_out_channels[-1]       ,       resnet_groups=_a       ,       temb_channels=_a       ,       )

						# up
						UpperCamelCase         =					list(reversed(_a						)						)
						UpperCamelCase         =					reversed_block_out_channels[0]
						for i, up_block_type in enumerate(_a						):
									UpperCamelCase         =					output_channel
									UpperCamelCase         =					reversed_block_out_channels[i]

									UpperCamelCase         =					i == len(_a						) - 1

									UpperCamelCase         =					get_up_block(
									    _a       ,       num_layers=self.layers_per_block + 1       ,       in_channels=_a       ,       out_channels=_a       ,       prev_output_channel=_a       ,       add_upsample=not is_final_block       ,       resnet_eps=1e-6       ,       resnet_act_fn=_a       ,       resnet_groups=_a       ,       attention_head_dim=_a       ,       temb_channels=_a       ,       resnet_time_scale_shift=_a       ,       )
									self.up_blocks.append(_a						)
									UpperCamelCase         =					output_channel

						# out
						if norm_type == "spatial":
									UpperCamelCase         =					SpatialNorm(block_out_channels[0]       ,       _a						)
						else:
									UpperCamelCase         =					nn.GroupNorm(num_channels=block_out_channels[0]       ,       num_groups=_a       ,       eps=1e-6						)
						UpperCamelCase         =					nn.SiLU()
						UpperCamelCase         =					nn.Convad(block_out_channels[0]       ,       _a       ,       3       ,       padding=1						)

						UpperCamelCase         =					False





			def   lowerCamelCase_					(						self							:		str       ,       __magic_name__							:		Optional[int]       ,       __magic_name__							:		List[Any]=None						):







						"""simple docstring"""







						UpperCamelCase         =					z
						UpperCamelCase         =					self.conv_in(_a						)

						UpperCamelCase         =					next(iter(self.up_blocks.parameters()						)						).dtype
						if self.training and self.gradient_checkpointing:

									def create_custom_forward(__magic_name__							:		Optional[Any]						):
												def custom_forward(*__magic_name__							:		Any						):
															return module(*_a						)

												return custom_forward

									if is_torch_version(""">="""       ,       """1.11.0"""						):
												# middle
												UpperCamelCase         =					torch.utils.checkpoint.checkpoint(
												    create_custom_forward(self.mid_block						)       ,       _a       ,       _a       ,       use_reentrant=_a						)
												UpperCamelCase         =					sample.to(_a						)

												# up
												for up_block in self.up_blocks:
															UpperCamelCase         =					torch.utils.checkpoint.checkpoint(
															    create_custom_forward(_a						)       ,       _a       ,       _a       ,       use_reentrant=_a						)
									else:
												# middle
												UpperCamelCase         =					torch.utils.checkpoint.checkpoint(
												    create_custom_forward(self.mid_block						)       ,       _a       ,       _a						)
												UpperCamelCase         =					sample.to(_a						)

												# up
												for up_block in self.up_blocks:
															UpperCamelCase         =					torch.utils.checkpoint.checkpoint(create_custom_forward(_a						)       ,       _a       ,       _a						)
						else:
									# middle
									UpperCamelCase         =					self.mid_block(_a       ,       _a						)
									UpperCamelCase         =					sample.to(_a						)

									# up
									for up_block in self.up_blocks:
												UpperCamelCase         =					up_block(_a       ,       _a						)

        # post-process
						if latent_embeds is None:
									UpperCamelCase         =					self.conv_norm_out(_a						)
						else:
									UpperCamelCase         =					self.conv_norm_out(_a       ,       _a						)
						UpperCamelCase         =					self.conv_act(_a						)
						UpperCamelCase         =					self.conv_out(_a						)

						return sample




class    UpperCAmelCase					(       nn.Module    ):




			def __init__(						self							:		str       ,       __magic_name__							:		Any       ,       __magic_name__							:		Tuple       ,       __magic_name__							:		List[str]       ,       __magic_name__							:		Optional[Any]=None       ,       __magic_name__							:		str="random"       ,       __magic_name__							:		Optional[int]=False       ,       __magic_name__							:		List[str]=True						):







						"""simple docstring"""







						super().__init__()
						UpperCamelCase         =					n_e
						UpperCamelCase         =					vq_embed_dim
						UpperCamelCase         =					beta
						UpperCamelCase         =					legacy

						UpperCamelCase         =					nn.Embedding(self.n_e       ,       self.vq_embed_dim						)
						self.embedding.weight.data.uniform_(-1.0 / self.n_e       ,       1.0 / self.n_e						)

						UpperCamelCase         =					remap
						if self.remap is not None:
									self.register_buffer("""used"""       ,       torch.tensor(np.load(self.remap						)						)						)
									UpperCamelCase         =					self.used.shape[0]
									UpperCamelCase         =					unknown_index  # "random" or "extra" or integer
									if self.unknown_index == "extra":
												UpperCamelCase         =					self.re_embed
												UpperCamelCase         =					self.re_embed + 1
									print(
									    F'Remapping {self.n_e} indices to {self.re_embed} indices. '
									    F'Using {self.unknown_index} for unknown indices.'						)
						else:
									UpperCamelCase         =					n_e

						UpperCamelCase         =					sane_index_shape




			def   lowerCamelCase_					(						self							:		Any       ,       __magic_name__							:		Dict						):







						"""simple docstring"""







						UpperCamelCase         =					inds.shape
						assert len(_a						) > 1
						UpperCamelCase         =					inds.reshape(ishape[0]       ,       -1						)
						UpperCamelCase         =					self.used.to(_a						)
						UpperCamelCase         =					(inds[:, :, None] == used[None, None, ...]).long()
						UpperCamelCase         =					match.argmax(-1						)
						UpperCamelCase         =					match.sum(2						) < 1
						if self.unknown_index == "random":
									UpperCamelCase         =					torch.randint(0       ,       self.re_embed       ,       size=new[unknown].shape						).to(device=new.device						)
						else:
									UpperCamelCase         =					self.unknown_index
						return new.reshape(_a						)




			def   lowerCamelCase_					(						self							:		Tuple       ,       __magic_name__							:		str						):







						"""simple docstring"""







						UpperCamelCase         =					inds.shape
						assert len(_a						) > 1
						UpperCamelCase         =					inds.reshape(ishape[0]       ,       -1						)
						UpperCamelCase         =					self.used.to(_a						)
						if self.re_embed > self.used.shape[0]:  # extra token
									UpperCamelCase         =					0  # simply set to zero
						UpperCamelCase         =					torch.gather(used[None, :][inds.shape[0] * [0], :]       ,       1       ,       _a						)
						return back.reshape(_a						)




			def   lowerCamelCase_					(						self							:		List[str]       ,       __magic_name__							:		Any						):







						"""simple docstring"""







						UpperCamelCase         =					z.permute(0       ,       2       ,       3       ,       1						).contiguous()
						UpperCamelCase         =					z.view(-1       ,       self.vq_embed_dim						)

						# distances from z to embeddings e_j (z - e)^2 = z^2 + e^2 - 2 e * z
						UpperCamelCase         =					torch.argmin(torch.cdist(_a       ,       self.embedding.weight						)       ,       dim=1						)

						UpperCamelCase         =					self.embedding(_a						).view(z.shape						)
						UpperCamelCase         =					None
						UpperCamelCase         =					None

						# compute loss for embedding
						if not self.legacy:
									UpperCamelCase         =					self.beta * torch.mean((z_q.detach() - z) ** 2						) + torch.mean((z_q - z.detach()) ** 2						)
						else:
									UpperCamelCase         =					torch.mean((z_q.detach() - z) ** 2						) + self.beta * torch.mean((z_q - z.detach()) ** 2						)

						# preserve gradients
						UpperCamelCase         =					z + (z_q - z).detach()

						# reshape back to match original input shape
						UpperCamelCase         =					z_q.permute(0       ,       3       ,       1       ,       2						).contiguous()

						if self.remap is not None:
									UpperCamelCase         =					min_encoding_indices.reshape(z.shape[0]       ,       -1						)  # add batch axis
									UpperCamelCase         =					self.remap_to_used(_a						)
									UpperCamelCase         =					min_encoding_indices.reshape(-1       ,       1						)  # flatten

						if self.sane_index_shape:
									UpperCamelCase         =					min_encoding_indices.reshape(z_q.shape[0]       ,       z_q.shape[2]       ,       z_q.shape[3]						)

						return z_q, loss, (perplexity, min_encodings, min_encoding_indices)





			def   lowerCamelCase_					(						self							:		List[Any]       ,       __magic_name__							:		Dict       ,       __magic_name__							:		Union[str, Any]						):







						"""simple docstring"""







						if self.remap is not None:
									UpperCamelCase         =					indices.reshape(shape[0]       ,       -1						)  # add batch axis
									UpperCamelCase         =					self.unmap_to_all(_a						)
									UpperCamelCase         =					indices.reshape(-1						)  # flatten again

						# get quantized latent vectors
						UpperCamelCase         =					self.embedding(_a						)

						if shape is not None:
									UpperCamelCase         =					z_q.view(_a						)
									# reshape back to match original input shape
									UpperCamelCase         =					z_q.permute(0       ,       3       ,       1       ,       2						).contiguous()

						return z_q




class    UpperCAmelCase					(       UpperCamelCase__    ):




			def __init__(						self							:		Tuple       ,       __magic_name__							:		Tuple       ,       __magic_name__							:		int=False						):







						"""simple docstring"""







						UpperCamelCase         =					parameters
						UpperCamelCase         =					torch.chunk(_a       ,       2       ,       dim=1						)
						UpperCamelCase         =					torch.clamp(self.logvar       ,       -30.0       ,       20.0						)
						UpperCamelCase         =					deterministic
						UpperCamelCase         =					torch.exp(0.5 * self.logvar						)
						UpperCamelCase         =					torch.exp(self.logvar						)
						if self.deterministic:
									UpperCamelCase         =					torch.zeros_like(
									    self.mean       ,       device=self.parameters.device       ,       dtype=self.parameters.dtype						)




			def   lowerCamelCase_					(						self							:		Optional[Any]       ,       __magic_name__							:		Optional[int] = None						):







						"""simple docstring"""







						UpperCamelCase         =					randn_tensor(
						    self.mean.shape       ,       generator=_a       ,       device=self.parameters.device       ,       dtype=self.parameters.dtype						)
						UpperCamelCase         =					self.mean + self.std * sample
						return x




			def   lowerCamelCase_					(						self							:		Tuple       ,       __magic_name__							:		Tuple=None						):







						"""simple docstring"""







						if self.deterministic:
									return torch.Tensor([0.0]						)
						else:
									if other is None:
												return 0.5 * torch.sum(torch.pow(self.mean       ,       2						) + self.var - 1.0 - self.logvar       ,       dim=[1, 2, 3]						)
									else:
												return 0.5 * torch.sum(
												    torch.pow(self.mean - other.mean       ,       2						) / other.var
												    + self.var / other.var
												    - 1.0
												    - self.logvar
												    + other.logvar       ,       dim=[1, 2, 3]       ,       )




			def   lowerCamelCase_					(						self							:		Any       ,       __magic_name__							:		Dict       ,       __magic_name__							:		Dict=[1, 2, 3]						):







						"""simple docstring"""







						if self.deterministic:
									return torch.Tensor([0.0]						)
						UpperCamelCase         =					np.log(2.0 * np.pi						)
						return 0.5 * torch.sum(logtwopi + self.logvar + torch.pow(sample - self.mean       ,       2						) / self.var       ,       dim=_a						)





			def   lowerCamelCase_					(						self							:		Optional[int]						):







						"""simple docstring"""







						return self.mean








def 							_lowercase    (		SCREAMING_SNAKE_CASE_   :		str	):





			"""simple docstring"""




			return [
			    txt[:a] + txt[a].upper() + txt[a + 1 :]
			    for a in range(len(SCREAMING_SNAKE_CASE_	)	)
			    if txt[a].isalpha()
			]


if __name__ == "__main__":
			__import__("doctest").testmod()




