





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        __magic_name__	(				lowerCamelCase__				):





     """simple docstring"""



     __UpperCamelCase            =  42




class        __magic_name__	(				lowerCamelCase__     ,					lowerCamelCase__				):





     """simple docstring"""



     __UpperCamelCase            =  True



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





        '''simple docstring'''




        super().__init__()

        # pass init params to Encoder
        A_       :					List[Any]        =      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
        A_       :					Optional[int]        =      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      ,   )

        A_       :					Optional[int]        =      nn.Convad(2 * latent_channels      ,   2 * latent_channels      ,   1	)
        A_       :					Optional[Any]        =      nn.Convad(snake_case      ,   snake_case      ,   1	)

        A_       :					Any        =      False
        A_       :					Dict        =      False

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



     def     SCREAMING_SNAKE_CASE		(				self							:List[Any]      ,   snake_case							:Optional[int]      ,   snake_case							:Union[str, Any]=False	):





        '''simple docstring'''




        if isinstance(snake_case      ,   (Encoder, Decoder)	):
           A_       :					Union[str, Any]        =      value



     def     SCREAMING_SNAKE_CASE		(				self							:List[Any]      ,   snake_case							:bool = True	):





        '''simple docstring'''




        A_       :					List[Any]        =      use_tiling



     def     SCREAMING_SNAKE_CASE		(				self							:Optional[Any]	):





        '''simple docstring'''




        self.enable_tiling(snake_case	)



     def     SCREAMING_SNAKE_CASE		(				self							:int	):





        '''simple docstring'''




        A_       :					Any        =      True



     def     SCREAMING_SNAKE_CASE		(				self							:Optional[int]	):





        '''simple docstring'''




        A_       :					Optional[int]        =      False



     @property
     # Copied from diffusers.models.unet_2d_condition.UNet2DConditionModel.attn_processors
     def     SCREAMING_SNAKE_CASE		(				self							:Tuple	):





        '''simple docstring'''




        A_       :					Optional[int]        =      {}

        def fn_recursive_add_processors(snake_case							:str      ,   snake_case							:torch.nn.Module      ,   snake_case							:Dict[str, AttentionProcessor]	):
           if hasattr(snake_case      ,   "set_processor"	):
              A_       :					List[str]        =      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     SCREAMING_SNAKE_CASE		(				self							:Any      ,   snake_case							:Union[AttentionProcessor, Dict[str, AttentionProcessor]]	):





        '''simple docstring'''




        A_       :					List[Any]        =      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(snake_case							:str      ,   snake_case							:torch.nn.Module      ,   snake_case							:Optional[int]	):
           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     SCREAMING_SNAKE_CASE		(				self							:Tuple	):





        '''simple docstring'''




        self.set_attn_processor(AttnProcessor()	)



     @apply_forward_hook
     def     SCREAMING_SNAKE_CASE		(				self							:Any      ,   snake_case							:torch.FloatTensor      ,   snake_case							: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:
           A_       :					Tuple        =      [self.encoder(snake_case	) for x_slice in x.split(1	)]
           A_       :					int        =      torch.cat(snake_case	)
        else:
           A_       :					List[Any]        =      self.encoder(snake_case	)

        A_       :					Optional[Any]        =      self.quant_conv(snake_case	)
        A_       :					List[str]        =      DiagonalGaussianDistribution(snake_case	)

        if not return_dict:
           return (posterior,)

        return AutoencoderKLOutput(latent_dist=snake_case	)



     def     SCREAMING_SNAKE_CASE		(				self							:Any      ,   snake_case							:torch.FloatTensor      ,   snake_case							: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	)

        A_       :					List[Any]        =      self.post_quant_conv(snake_case	)
        A_       :					Any        =      self.decoder(snake_case	)

        if not return_dict:
           return (dec,)

        return DecoderOutput(sample=snake_case	)



     @apply_forward_hook
     def     SCREAMING_SNAKE_CASE		(				self							:Tuple      ,   snake_case							:torch.FloatTensor      ,   snake_case							:bool = True	):





        '''simple docstring'''




        if self.use_slicing and z.shape[0] > 1:
           A_       :					Union[str, Any]        =      [self._decode(snake_case	).sample for z_slice in z.split(1	)]
           A_       :					Any        =      torch.cat(snake_case	)
        else:
           A_       :					str        =      self._decode(snake_case	).sample

        if not return_dict:
           return (decoded,)

        return DecoderOutput(sample=snake_case	)



     def     SCREAMING_SNAKE_CASE		(				self							:Optional[int]      ,   snake_case							:Optional[Any]      ,   snake_case							:Optional[int]      ,   snake_case							:Any	):





        '''simple docstring'''




        A_       :					str        =      min(a.shape[2]      ,   b.shape[2]      ,   snake_case	)
        for y in range(snake_case	):
           A_       :					List[Any]        =      a[:, :, -blend_extent + y, :] * (1 - y / blend_extent) + b[:, :, y, :] * (y / blend_extent)
        return b



     def     SCREAMING_SNAKE_CASE		(				self							:int      ,   snake_case							:List[str]      ,   snake_case							:Dict      ,   snake_case							:Tuple	):





        '''simple docstring'''




        A_       :					List[Any]        =      min(a.shape[3]      ,   b.shape[3]      ,   snake_case	)
        for x in range(snake_case	):
           A_       :					List[str]        =      a[:, :, :, -blend_extent + x] * (1 - x / blend_extent) + b[:, :, :, x] * (x / blend_extent)
        return b



     def     SCREAMING_SNAKE_CASE		(				self							:Any      ,   snake_case							:torch.FloatTensor      ,   snake_case							:bool = True	):





        '''simple docstring'''




        A_       :					Optional[int]        =      int(self.tile_sample_min_size * (1 - self.tile_overlap_factor)	)
        A_       :					Optional[int]        =      int(self.tile_latent_min_size * self.tile_overlap_factor	)
        A_       :					int        =      self.tile_latent_min_size - blend_extent

        # Split the image into 512x512 tiles and encode them separately.
        A_       :					Dict        =      []
        for i in range(0      ,   x.shape[2]      ,   snake_case	):
           A_       :					List[Any]        =      []
           for j in range(0      ,   x.shape[3]      ,   snake_case	):
              A_       :					int        =      x[:, :, i : i + self.tile_sample_min_size, j : j + self.tile_sample_min_size]
              A_       :					int        =      self.encoder(snake_case	)
              A_       :					List[str]        =      self.quant_conv(snake_case	)
              row.append(snake_case	)
           rows.append(snake_case	)
        A_       :					Any        =      []
        for i, row in enumerate(snake_case	):
           A_       :					List[Any]        =      []
           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:
                 A_       :					List[Any]        =      self.blend_v(rows[i - 1][j]      ,   snake_case      ,   snake_case	)
              if j > 0:
                 A_       :					Optional[int]        =      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	)	)

        A_       :					Tuple        =      torch.cat(snake_case      ,   dim=2	)
        A_       :					Tuple        =      DiagonalGaussianDistribution(snake_case	)

        if not return_dict:
           return (posterior,)

        return AutoencoderKLOutput(latent_dist=snake_case	)



     def     SCREAMING_SNAKE_CASE		(				self							:List[Any]      ,   snake_case							:torch.FloatTensor      ,   snake_case							:bool = True	):





        '''simple docstring'''




        A_       :					Optional[int]        =      int(self.tile_latent_min_size * (1 - self.tile_overlap_factor)	)
        A_       :					str        =      int(self.tile_sample_min_size * self.tile_overlap_factor	)
        A_       :					List[Any]        =      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.
        A_       :					Union[str, Any]        =      []
        for i in range(0      ,   z.shape[2]      ,   snake_case	):
           A_       :					Union[str, Any]        =      []
           for j in range(0      ,   z.shape[3]      ,   snake_case	):
              A_       :					Any        =      z[:, :, i : i + self.tile_latent_min_size, j : j + self.tile_latent_min_size]
              A_       :					List[str]        =      self.post_quant_conv(snake_case	)
              A_       :					Tuple        =      self.decoder(snake_case	)
              row.append(snake_case	)
           rows.append(snake_case	)
        A_       :					Tuple        =      []
        for i, row in enumerate(snake_case	):
           A_       :					Union[str, Any]        =      []
           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:
                 A_       :					Any        =      self.blend_v(rows[i - 1][j]      ,   snake_case      ,   snake_case	)
              if j > 0:
                 A_       :					Tuple        =      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	)	)

        A_       :					Union[str, Any]        =      torch.cat(snake_case      ,   dim=2	)
        if not return_dict:
           return (dec,)

        return DecoderOutput(sample=snake_case	)





     def     SCREAMING_SNAKE_CASE		(				self							:Optional[Any]      ,   snake_case							:torch.FloatTensor      ,   snake_case							:bool = False      ,   snake_case							:bool = True      ,   snake_case							:Optional[torch.Generator] = None      ,   ):





        '''simple docstring'''




        A_       :					Optional[int]        =      sample
        A_       :					int        =      self.encode(snake_case	).latent_dist
        if sample_posterior:
           A_       :					Dict        =      posterior.sample(generator=snake_case	)
        else:
           A_       :					Optional[Any]        =      posterior.mode()
        A_       :					Union[str, Any]        =      self.decode(snake_case	).sample

        if not return_dict:
           return (dec,)

        return DecoderOutput(sample=snake_case	)







from timeit import timeit

_lowerCAmelCase				:   Tuple						       =						{
    '''MALAYALAM''': True,
    '''String''': False,
    '''rotor''': True,
    '''level''': True,
    '''A''': True,
    '''BB''': True,
    '''ABC''': False,
    '''amanaplanacanalpanama''': True,  # "a man a plan a canal panama"
}
# Ensure our test data is valid
assert all((key == key[::-1]) is value for key, value in test_data.items())

def   __snake_case    (       _lowerCAmelCase			:			str						)			->    bool:
   A_       :					List[str]        =      0
   A_       :					str        =      len(_lowerCAmelCase						) - 1
   while start_i < end_i:
      if s[start_i] == s[end_i]:
         start_i += 1
         end_i -= 1
      else:
         return False
   return True

def   __snake_case    (       _lowerCAmelCase			:			str						)			->    bool:
   A_       :					int        =      len(_lowerCAmelCase						) // 2
   A_       :					Union[str, Any]        =      len(_lowerCAmelCase						)

   # We need to traverse till half of the length of string
   # as we can get access of the i'th last element from
   # i'th index.
   # eg: [0,1,2,3,4,5] => 4th index can be accessed
   # with the help of 1st index (i==n-i-1)
   # where n is length of string
   return all(s[i] == s[n - i - 1] for i in range(_lowerCAmelCase						)						)

def   __snake_case    (       _lowerCAmelCase			:			str						)			->    bool:
   if len(_lowerCAmelCase						) <= 2:
      return True
   if s[0] == s[len(_lowerCAmelCase						) - 1]:
      return is_palindrome_recursive(s[1:-1]						)
   else:
      return False

def   __snake_case    (       _lowerCAmelCase			:			str						)			->    bool:
   return s == s[::-1]

def   __snake_case    (       _lowerCAmelCase			:			str						)			->    None:
   A_       :					int        =      f"all({name}(key) is value for key, value in test_data.items())"
   A_       :					List[str]        =      f"from __main__ import test_data, {name}"
   A_       :					str        =      500000
   A_       :					List[str]        =      timeit(stmt=_lowerCAmelCase					,					setup=_lowerCAmelCase					,					number=_lowerCAmelCase						)
   print(f"{name:<35} finished {number:,} runs in {result:.5f} seconds"						)


if __name__ == "__main__":
 for key, value in test_data.items():
  assert is_palindrome(key) is is_palindrome_recursive(key)
  assert is_palindrome(key) is is_palindrome_slice(key)
  print(F'''{key:21} {value}''')
 print('''a man a plan a canal panama''')

 # finished 500,000 runs in 0.46793 seconds
 benchmark_function('''is_palindrome_slice''')
 # finished 500,000 runs in 0.85234 seconds
 benchmark_function('''is_palindrome''')
 # finished 500,000 runs in 1.32028 seconds
 benchmark_function('''is_palindrome_recursive''')
 # finished 500,000 runs in 2.08679 seconds
 benchmark_function('''is_palindrome_traversal''')
