





'''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     lowerCAmelCase__ (				UpperCAmelCase_    ):

       '''simple docstring'''
       _lowerCamelCase								=42






class     lowerCAmelCase__ (				nn.Module    ):

       '''simple docstring'''

       def __init__( self					:				Tuple       ,     a__					:				str=3       ,     a__					:				Optional[int]=3       ,     a__					:				str=("DownEncoderBlock2D",)       ,     a__					:				Optional[int]=(64,)       ,     a__					:				List[Any]=2       ,     a__					:				Tuple=32       ,     a__					:				List[Any]="silu"       ,     a__					:				Dict=True       ,     ):
              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 			__snake_case      ( self					:				Any       ,     a__					:				Optional[int]						):
              UpperCAmelCase  =						x
              UpperCAmelCase  =						self.conv_in(a__						)

              if self.training and self.gradient_checkpointing:

                     def create_custom_forward(a__					:				Dict						):
                            def custom_forward(*a__					:				Union[str, Any]						):
                                   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     lowerCAmelCase__ (				nn.Module    ):

       '''simple docstring'''

       def __init__( self					:				List[str]       ,     a__					:				Optional[int]=3       ,     a__					:				List[str]=3       ,     a__					:				Dict=("UpDecoderBlock2D",)       ,     a__					:				List[str]=(64,)       ,     a__					:				Union[str, Any]=2       ,     a__					:				Optional[Any]=32       ,     a__					:				Union[str, Any]="silu"       ,     a__					:				str="group"       ,     ):
              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 			__snake_case      ( self					:				Dict       ,     a__					:				Optional[Any]       ,     a__					:				Any=None						):
              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(a__					:				Optional[int]						):
                            def custom_forward(*a__					:				Tuple						):
                                   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     lowerCAmelCase__ (				nn.Module    ):

       '''simple docstring'''

       def __init__( self					:				List[Any]       ,     a__					:				Optional[int]       ,     a__					:				Optional[int]       ,     a__					:				str       ,     a__					:				List[str]=None       ,     a__					:				str="random"       ,     a__					:				List[str]=False       ,     a__					:				Tuple=True						):
              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 			__snake_case      ( self					:				str       ,     a__					:				Dict						):
              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 			__snake_case      ( self					:				Optional[int]       ,     a__					:				Optional[int]						):
              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 			__snake_case      ( self					:				List[Any]       ,     a__					:				Optional[Any]						):
              # reshape z -> (batch, height, width, channel) and flatten
              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 			__snake_case      ( self					:				str       ,     a__					:				Any       ,     a__					:				str						):
              # shape specifying (batch, height, width, channel)
              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     lowerCAmelCase__ (				UpperCAmelCase_    ):

       '''simple docstring'''

       def __init__( self					:				Optional[Any]       ,     a__					:				Union[str, Any]       ,     a__					:				Union[str, Any]=False						):
              UpperCAmelCase  =						parameters
              UpperCAmelCase,					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  =						UpperCAmelCase  =						torch.zeros_like(
                         self.mean       ,     device=self.parameters.device       ,     dtype=self.parameters.dtype						)

       def 			__snake_case      ( self					:				Optional[Any]       ,     a__					:				Optional[torch.Generator] = None						):
              # make sure sample is on the same device as the parameters and has same dtype
              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 			__snake_case      ( self					:				List[Any]       ,     a__					:				str=None						):
              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 			__snake_case      ( self					:				Tuple       ,     a__					:				str       ,     a__					:				List[Any]=[1, 2, 3]						):
              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 			__snake_case      ( self					:				Optional[int]						):
              return self.mean









import operator as op


def 							__snake_case							(    lowerCAmelCase_	)				->						str:
    SCREAMING_SNAKE_CASE__											=			[]
    SCREAMING_SNAKE_CASE__											=			lambda lowerCAmelCase_ ,							lowerCAmelCase_	: int(x / y	)  # noqa: E731 integer division operation
    SCREAMING_SNAKE_CASE__											=			{
        '''^''': op.pow,
        '''*''': op.mul,
        '''/''': div,
        '''+''': op.add,
        '''-''': op.sub,
    }  # operators & their respective operation

    # print table header
    print('''Symbol'''.center(8	) ,							'''Action'''.center(1_2	) ,							'''Stack''' ,							sep=''' | '''	)
    print('''-''' * (3_0 + len(lowerCAmelCase_	))	)

    for x in post_fix:
        if x.isdigit():  # if x in digit
            stack.append(lowerCAmelCase_	)  # append x to stack
            # output in tabular format
            print(x.rjust(8	) ,							('''push(''' + x + ''')''').ljust(1_2	) ,							''','''.join(lowerCAmelCase_	) ,							sep=''' | '''	)
        else:
            SCREAMING_SNAKE_CASE__											=			stack.pop()  # pop stack
            # output in tabular format
            print(''''''.rjust(8	) ,							('''pop(''' + b + ''')''').ljust(1_2	) ,							''','''.join(lowerCAmelCase_	) ,							sep=''' | '''	)

            SCREAMING_SNAKE_CASE__											=			stack.pop()  # pop stack
            # output in tabular format
            print(''''''.rjust(8	) ,							('''pop(''' + a + ''')''').ljust(1_2	) ,							''','''.join(lowerCAmelCase_	) ,							sep=''' | '''	)

            stack.append(
                str(opr[x](int(lowerCAmelCase_	) ,							int(lowerCAmelCase_	)	)	)	)  # evaluate the 2 values popped from stack & push result to stack
            # output in tabular format
            print(
                x.rjust(8	) ,							('''push(''' + a + x + b + ''')''').ljust(1_2	) ,							''','''.join(lowerCAmelCase_	) ,							sep=''' | ''' ,							)

    return int(stack[0]	)


if __name__ == "__main__":
  _A					:				Dict				=			input("""\n\nEnter a Postfix Equation (space separated) = """).split(""" """)
  print("""\n\tResult = """, solve(Postfix))
