"""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 				snake_case       ( __UpperCAmelCase				):




					"""simple docstring"""

					snake_case__				    = 42






class 				snake_case       ( __UpperCAmelCase      ,    __UpperCAmelCase				):




					"""simple docstring"""

					snake_case__				    = 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    ,):
									super().__init__()

									# pass init params to Encoder
									UpperCAmelCase__             =							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__             =							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__             =							nn.Convad(2 * latent_channels    ,2 * latent_channels    ,1			)
									UpperCAmelCase__             =							nn.Convad(lowerCamelCase__    ,lowerCamelCase__    ,1			)

									UpperCAmelCase__             =							False
									UpperCAmelCase__             =							False

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







					def 		__lowerCAmelCase						(				self   :	int    ,lowerCamelCase__   :	Optional[Any]    ,lowerCamelCase__   :	int=False			):
									if isinstance(lowerCamelCase__    ,(Encoder, Decoder)			):
													UpperCAmelCase__             =							value







					def 		__lowerCAmelCase						(				self   :	Optional[int]    ,lowerCamelCase__   :	bool = True			):
									UpperCAmelCase__             =							use_tiling







					def 		__lowerCAmelCase						(				self   :	List[Any]			):
									self.enable_tiling(lowerCamelCase__			)







					def 		__lowerCAmelCase						(				self   :	Any			):
									UpperCAmelCase__             =							True







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







					@property
					# Copied from diffusers.models.unet_2d_condition.UNet2DConditionModel.attn_processors
					def 		__lowerCAmelCase						(				self   :	int			):
									UpperCAmelCase__             =							{}

									def fn_recursive_add_processors(lowerCamelCase__   :	str    ,lowerCamelCase__   :	torch.nn.Module    ,lowerCamelCase__   :	Dict[str, AttentionProcessor]			):
													if hasattr(lowerCamelCase__    ,'set_processor'			):
																	UpperCAmelCase__             =							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 		__lowerCAmelCase						(				self   :	Union[str, Any]    ,lowerCamelCase__   :	Union[AttentionProcessor, Dict[str, AttentionProcessor]]			):
									UpperCAmelCase__             =							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 		__lowerCAmelCase						(				self   :	int			):
									self.set_attn_processor(AttnProcessor()			)







					@apply_forward_hook
					def 		__lowerCAmelCase						(				self   :	Dict    ,lowerCamelCase__   :	torch.FloatTensor    ,lowerCamelCase__   :	bool = True			):
									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__             =							[self.encoder(lowerCamelCase__			) for x_slice in x.split(1			)]
													UpperCAmelCase__             =							torch.cat(lowerCamelCase__			)
									else:
													UpperCAmelCase__             =							self.encoder(lowerCamelCase__			)

									UpperCAmelCase__             =							self.quant_conv(lowerCamelCase__			)
									UpperCAmelCase__             =							DiagonalGaussianDistribution(lowerCamelCase__			)

									if not return_dict:
													return (posterior,)

									return AutoencoderKLOutput(latent_dist=lowerCamelCase__			)







					def 		__lowerCAmelCase						(				self   :	List[Any]    ,lowerCamelCase__   :	torch.FloatTensor    ,lowerCamelCase__   :	bool = True			):
									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__             =							self.post_quant_conv(lowerCamelCase__			)
									UpperCAmelCase__             =							self.decoder(lowerCamelCase__			)

									if not return_dict:
													return (dec,)

									return DecoderOutput(sample=lowerCamelCase__			)







					@apply_forward_hook
					def 		__lowerCAmelCase						(				self   :	Dict    ,lowerCamelCase__   :	torch.FloatTensor    ,lowerCamelCase__   :	bool = True			):
									if self.use_slicing and z.shape[0] > 1:
													UpperCAmelCase__             =							[self._decode(lowerCamelCase__			).sample for z_slice in z.split(1			)]
													UpperCAmelCase__             =							torch.cat(lowerCamelCase__			)
									else:
													UpperCAmelCase__             =							self._decode(lowerCamelCase__			).sample

									if not return_dict:
													return (decoded,)

									return DecoderOutput(sample=lowerCamelCase__			)







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







					def 		__lowerCAmelCase						(				self   :	Any    ,lowerCamelCase__   :	int    ,lowerCamelCase__   :	Union[str, Any]    ,lowerCamelCase__   :	Union[str, Any]			):
									UpperCAmelCase__             =							min(a.shape[3]    ,b.shape[3]    ,lowerCamelCase__			)
									for x in range(lowerCamelCase__			):
													UpperCAmelCase__             =							a[:, :, :, -blend_extent + x] * (1 - x / blend_extent) + b[:, :, :, x] * (x / blend_extent)
									return b







					def 		__lowerCAmelCase						(				self   :	str    ,lowerCamelCase__   :	torch.FloatTensor    ,lowerCamelCase__   :	bool = True			):
									UpperCAmelCase__             =							int(self.tile_sample_min_size * (1 - self.tile_overlap_factor)			)
									UpperCAmelCase__             =							int(self.tile_latent_min_size * self.tile_overlap_factor			)
									UpperCAmelCase__             =							self.tile_latent_min_size - blend_extent

									# Split the image into 512x512 tiles and encode them separately.
									UpperCAmelCase__             =							[]
									for i in range(0    ,x.shape[2]    ,lowerCamelCase__			):
													UpperCAmelCase__             =							[]
													for j in range(0    ,x.shape[3]    ,lowerCamelCase__			):
																	UpperCAmelCase__             =							x[:, :, i : i + self.tile_sample_min_size, j : j + self.tile_sample_min_size]
																	UpperCAmelCase__             =							self.encoder(lowerCamelCase__			)
																	UpperCAmelCase__             =							self.quant_conv(lowerCamelCase__			)
																	row.append(lowerCamelCase__			)
													rows.append(lowerCamelCase__			)
									UpperCAmelCase__             =							[]
									for i, row in enumerate(lowerCamelCase__			):
													UpperCAmelCase__             =							[]
													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__             =							self.blend_v(rows[i - 1][j]    ,lowerCamelCase__    ,lowerCamelCase__			)
																	if j > 0:
																					UpperCAmelCase__             =							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__             =							torch.cat(lowerCamelCase__    ,dim=2			)
									UpperCAmelCase__             =							DiagonalGaussianDistribution(lowerCamelCase__			)

									if not return_dict:
													return (posterior,)

									return AutoencoderKLOutput(latent_dist=lowerCamelCase__			)







					def 		__lowerCAmelCase						(				self   :	List[Any]    ,lowerCamelCase__   :	torch.FloatTensor    ,lowerCamelCase__   :	bool = True			):
									UpperCAmelCase__             =							int(self.tile_latent_min_size * (1 - self.tile_overlap_factor)			)
									UpperCAmelCase__             =							int(self.tile_sample_min_size * self.tile_overlap_factor			)
									UpperCAmelCase__             =							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__             =							[]
									for i in range(0    ,z.shape[2]    ,lowerCamelCase__			):
													UpperCAmelCase__             =							[]
													for j in range(0    ,z.shape[3]    ,lowerCamelCase__			):
																	UpperCAmelCase__             =							z[:, :, i : i + self.tile_latent_min_size, j : j + self.tile_latent_min_size]
																	UpperCAmelCase__             =							self.post_quant_conv(lowerCamelCase__			)
																	UpperCAmelCase__             =							self.decoder(lowerCamelCase__			)
																	row.append(lowerCamelCase__			)
													rows.append(lowerCamelCase__			)
									UpperCAmelCase__             =							[]
									for i, row in enumerate(lowerCamelCase__			):
													UpperCAmelCase__             =							[]
													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__             =							self.blend_v(rows[i - 1][j]    ,lowerCamelCase__    ,lowerCamelCase__			)
																	if j > 0:
																					UpperCAmelCase__             =							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__             =							torch.cat(lowerCamelCase__    ,dim=2			)
									if not return_dict:
													return (dec,)

									return DecoderOutput(sample=lowerCamelCase__			)







					def 		__lowerCAmelCase						(				self   :	List[Any]    ,lowerCamelCase__   :	torch.FloatTensor    ,lowerCamelCase__   :	bool = False    ,lowerCamelCase__   :	bool = True    ,lowerCamelCase__   :	Optional[torch.Generator] = None    ,):
									UpperCAmelCase__             =							sample
									UpperCAmelCase__             =							self.encode(lowerCamelCase__			).latent_dist
									if sample_posterior:
													UpperCAmelCase__             =							posterior.sample(generator=lowerCamelCase__			)
									else:
													UpperCAmelCase__             =							posterior.mode()
									UpperCAmelCase__             =							self.decode(lowerCamelCase__			).sample

									if not return_dict:
													return (dec,)

									return DecoderOutput(sample=lowerCamelCase__			)





from typing import TYPE_CHECKING

from ...utils import (
    OptionalDependencyNotAvailable,
    _LazyModule,
    is_tf_available,
    is_tokenizers_available,
    is_torch_available,
)


lowercase  :					str						    =							{
    """configuration_funnel""": ["""FUNNEL_PRETRAINED_CONFIG_ARCHIVE_MAP""", """FunnelConfig"""],
    """convert_funnel_original_tf_checkpoint_to_pytorch""": [],
    """tokenization_funnel""": ["""FunnelTokenizer"""],
}

try:
  if not is_tokenizers_available():
    raise OptionalDependencyNotAvailable()
except OptionalDependencyNotAvailable:
  pass
else:
  lowercase  :					Tuple						    =							["""FunnelTokenizerFast"""]

try:
  if not is_torch_available():
    raise OptionalDependencyNotAvailable()
except OptionalDependencyNotAvailable:
  pass
else:
  lowercase  :					List[str]						    =							[
      """FUNNEL_PRETRAINED_MODEL_ARCHIVE_LIST""",
      """FunnelBaseModel""",
      """FunnelForMaskedLM""",
      """FunnelForMultipleChoice""",
      """FunnelForPreTraining""",
      """FunnelForQuestionAnswering""",
      """FunnelForSequenceClassification""",
      """FunnelForTokenClassification""",
      """FunnelModel""",
      """FunnelPreTrainedModel""",
      """load_tf_weights_in_funnel""",
  ]

try:
  if not is_tf_available():
    raise OptionalDependencyNotAvailable()
except OptionalDependencyNotAvailable:
  pass
else:
  lowercase  :					Optional[Any]						    =							[
      """TF_FUNNEL_PRETRAINED_MODEL_ARCHIVE_LIST""",
      """TFFunnelBaseModel""",
      """TFFunnelForMaskedLM""",
      """TFFunnelForMultipleChoice""",
      """TFFunnelForPreTraining""",
      """TFFunnelForQuestionAnswering""",
      """TFFunnelForSequenceClassification""",
      """TFFunnelForTokenClassification""",
      """TFFunnelModel""",
      """TFFunnelPreTrainedModel""",
  ]


if TYPE_CHECKING:
  from .configuration_funnel import FUNNEL_PRETRAINED_CONFIG_ARCHIVE_MAP, FunnelConfig
  from .tokenization_funnel import FunnelTokenizer

  try:
    if not is_tokenizers_available():
      raise OptionalDependencyNotAvailable()
  except OptionalDependencyNotAvailable:
    pass
  else:
    from .tokenization_funnel_fast import FunnelTokenizerFast

  try:
    if not is_torch_available():
      raise OptionalDependencyNotAvailable()
  except OptionalDependencyNotAvailable:
    pass
  else:
    from .modeling_funnel import (
        FUNNEL_PRETRAINED_MODEL_ARCHIVE_LIST,
        FunnelBaseModel,
        FunnelForMaskedLM,
        FunnelForMultipleChoice,
        FunnelForPreTraining,
        FunnelForQuestionAnswering,
        FunnelForSequenceClassification,
        FunnelForTokenClassification,
        FunnelModel,
        FunnelPreTrainedModel,
        load_tf_weights_in_funnel,
    )

  try:
    if not is_tf_available():
      raise OptionalDependencyNotAvailable()
  except OptionalDependencyNotAvailable:
    pass
  else:
    from .modeling_tf_funnel import (
        TF_FUNNEL_PRETRAINED_MODEL_ARCHIVE_LIST,
        TFFunnelBaseModel,
        TFFunnelForMaskedLM,
        TFFunnelForMultipleChoice,
        TFFunnelForPreTraining,
        TFFunnelForQuestionAnswering,
        TFFunnelForSequenceClassification,
        TFFunnelForTokenClassification,
        TFFunnelModel,
        TFFunnelPreTrainedModel,
    )

else:
  import sys

  lowercase  :					Any						    =							_LazyModule(__name__, globals()["""__file__"""], _import_structure, module_spec=__spec__)
