





from __future__ import annotations

import math

def   a_   (			lowerCAmelCase_				:      Union[str, Any],     lowerCAmelCase_				:      int     ):
   if len(__lowerCAmelCase     ) != 2 or len(a[0]     ) != 2 or len(__lowerCAmelCase     ) != 2 or len(b[0]     ) != 2:
      raise Exception('Matrices are not 2x2'     )
   __lowerCAmelCase							     =     [
       [a[0][0] * b[0][0] + a[0][1] * b[1][0], a[0][0] * b[0][1] + a[0][1] * b[1][1]],
       [a[1][0] * b[0][0] + a[1][1] * b[1][0], a[1][0] * b[0][1] + a[1][1] * b[1][1]],
   ]
   return new_matrix

def   a_   (			lowerCAmelCase_				:      Tuple,     lowerCAmelCase_				:      Dict     ):
   return [
       [matrix_a[row][col] + matrix_b[row][col] for col in range(len(matrix_a[row]     )     )]
       for row in range(len(__lowerCAmelCase     )     )
   ]

def   a_   (			lowerCAmelCase_				:      Optional[int],     lowerCAmelCase_				:      Union[str, Any]     ):
   return [
       [matrix_a[row][col] - matrix_b[row][col] for col in range(len(matrix_a[row]     )     )]
       for row in range(len(__lowerCAmelCase     )     )
   ]

def   a_   (			lowerCAmelCase_				:      Optional[int]     ):
   if len(__lowerCAmelCase     ) % 2 != 0 or len(a[0]     ) % 2 != 0:
      raise Exception('Odd matrices are not supported!'     )

   __lowerCAmelCase							     =     len(__lowerCAmelCase     )
   __lowerCAmelCase							     =     matrix_length // 2

   __lowerCAmelCase							     =     [[a[i][j] for j in range(__lowerCAmelCase,     __lowerCAmelCase     )] for i in range(__lowerCAmelCase     )]
   __lowerCAmelCase							     =     [
       [a[i][j] for j in range(__lowerCAmelCase,     __lowerCAmelCase     )] for i in range(__lowerCAmelCase,     __lowerCAmelCase     )
   ]

   __lowerCAmelCase							     =     [[a[i][j] for j in range(__lowerCAmelCase     )] for i in range(__lowerCAmelCase     )]
   __lowerCAmelCase							     =     [[a[i][j] for j in range(__lowerCAmelCase     )] for i in range(__lowerCAmelCase,     __lowerCAmelCase     )]

   return top_left, top_right, bot_left, bot_right

def   a_   (			lowerCAmelCase_				:      Optional[Any]     ):
   return len(__lowerCAmelCase     ), len(matrix[0]     )

def   a_   (			lowerCAmelCase_				:      str     ):
   print('\n'.join(str(__lowerCAmelCase     ) for line in matrix     )     )

def   a_   (			lowerCAmelCase_				:      int,     lowerCAmelCase_				:      Any     ):
   if matrix_dimensions(__lowerCAmelCase     ) == (2, 2):
      return default_matrix_multiplication(__lowerCAmelCase,     __lowerCAmelCase     )

   __lowerCAmelCase							     =     split_matrix(__lowerCAmelCase     )
   __lowerCAmelCase							     =     split_matrix(__lowerCAmelCase     )

   __lowerCAmelCase							     =     actual_strassen(__lowerCAmelCase,     matrix_subtraction(__lowerCAmelCase,     __lowerCAmelCase     )     )
   __lowerCAmelCase							     =     actual_strassen(matrix_addition(__lowerCAmelCase,     __lowerCAmelCase     ),     __lowerCAmelCase     )
   __lowerCAmelCase							     =     actual_strassen(matrix_addition(__lowerCAmelCase,     __lowerCAmelCase     ),     __lowerCAmelCase     )
   __lowerCAmelCase							     =     actual_strassen(__lowerCAmelCase,     matrix_subtraction(__lowerCAmelCase,     __lowerCAmelCase     )     )
   __lowerCAmelCase							     =     actual_strassen(matrix_addition(__lowerCAmelCase,     __lowerCAmelCase     ),     matrix_addition(__lowerCAmelCase,     __lowerCAmelCase     )     )
   __lowerCAmelCase							     =     actual_strassen(matrix_subtraction(__lowerCAmelCase,     __lowerCAmelCase     ),     matrix_addition(__lowerCAmelCase,     __lowerCAmelCase     )     )
   __lowerCAmelCase							     =     actual_strassen(matrix_subtraction(__lowerCAmelCase,     __lowerCAmelCase     ),     matrix_addition(__lowerCAmelCase,     __lowerCAmelCase     )     )

   __lowerCAmelCase							     =     matrix_addition(matrix_subtraction(matrix_addition(__lowerCAmelCase,     __lowerCAmelCase     ),     __lowerCAmelCase     ),     __lowerCAmelCase     )
   __lowerCAmelCase							     =     matrix_addition(__lowerCAmelCase,     __lowerCAmelCase     )
   __lowerCAmelCase							     =     matrix_addition(__lowerCAmelCase,     __lowerCAmelCase     )
   __lowerCAmelCase							     =     matrix_subtraction(matrix_subtraction(matrix_addition(__lowerCAmelCase,     __lowerCAmelCase     ),     __lowerCAmelCase     ),     __lowerCAmelCase     )

   # construct the new matrix from our 4 quadrants
   __lowerCAmelCase							     =     []
   for i in range(len(__lowerCAmelCase     )     ):
      new_matrix.append(top_left[i] + top_right[i]     )
   for i in range(len(__lowerCAmelCase     )     ):
      new_matrix.append(bot_left[i] + bot_right[i]     )
   return new_matrix

def   a_   (			lowerCAmelCase_				:      Optional[int],     lowerCAmelCase_				:      Union[str, Any]     ):
   if matrix_dimensions(__lowerCAmelCase     )[1] != matrix_dimensions(__lowerCAmelCase     )[0]:
      __lowerCAmelCase							     =     (
          """Unable to multiply these matrices, please check the dimensions.\n"""
          F"""Matrix A: {matrixa}\n"""
          F"""Matrix B: {matrixa}"""
      )
      raise Exception(__lowerCAmelCase     )
   __lowerCAmelCase							     =     matrix_dimensions(__lowerCAmelCase     )
   __lowerCAmelCase							     =     matrix_dimensions(__lowerCAmelCase     )

   if dimensiona[0] == dimensiona[1] and dimensiona[0] == dimensiona[1]:
      return [matrixa, matrixa]

   __lowerCAmelCase							     =     max(*__lowerCAmelCase,     *__lowerCAmelCase     )
   __lowerCAmelCase							     =     int(math.pow(2,     math.ceil(math.loga(__lowerCAmelCase     )     )     )     )
   __lowerCAmelCase							     =     matrixa
   __lowerCAmelCase							     =     matrixa

   # Adding zeros to the matrices so that the arrays dimensions are the same and also
   # power of 2
   for i in range(0,     __lowerCAmelCase     ):
      if i < dimensiona[0]:
         for _ in range(dimensiona[1],     __lowerCAmelCase     ):
            new_matrixa[i].append(0     )
      else:
         new_matrixa.append([0] * maxim     )
      if i < dimensiona[0]:
         for _ in range(dimensiona[1],     __lowerCAmelCase     ):
            new_matrixa[i].append(0     )
      else:
         new_matrixa.append([0] * maxim     )

   __lowerCAmelCase							     =     actual_strassen(__lowerCAmelCase,     __lowerCAmelCase     )

   # Removing the additional zeros
   for i in range(0,     __lowerCAmelCase     ):
      if i < dimensiona[0]:
         for _ in range(dimensiona[1],     __lowerCAmelCase     ):
            final_matrix[i].pop()
      else:
         final_matrix.pop()
   return final_matrix


if __name__ == "__main__":
   _snake_case  :   List[Any]						   =  [
       [2, 3, 4, 5],
       [6, 4, 3, 1],
       [2, 3, 6, 7],
       [3, 1, 2, 4],
       [2, 3, 4, 5],
       [6, 4, 3, 1],
       [2, 3, 6, 7],
       [3, 1, 2, 4],
       [2, 3, 4, 5],
       [6, 2, 3, 1],
   ]
   _snake_case  :   Union[str, Any]						   =  [[0, 2, 1, 1], [16, 2, 3, 3], [2, 2, 7, 7], [13, 11, 22, 4]]
   print(strassen(matrixa, matrixa))








from dataclasses import dataclass
from typing import Optional

import torch
from torch import nn

from ..configuration_utils import ConfigMixin, register_to_config
from ..utils import BaseOutput
from .attention import BasicTransformerBlock
from .modeling_utils import ModelMixin



@dataclass
class     _UpperCAmelCase   (   _UpperCamelCase   ):

  """simple docstring"""


  a_      =			42





class     _UpperCAmelCase   (   _UpperCamelCase		,   _UpperCamelCase   ):

  """simple docstring"""


  @register_to_config
  def __init__(    self			:		Optional[int] ,  lowerCAmelCase_			:		int = 1_6 ,  lowerCAmelCase_			:		int = 8_8 ,  lowerCAmelCase_			:		Optional[int] = None ,  lowerCAmelCase_			:		Optional[int] = None ,  lowerCAmelCase_			:		int = 1 ,  lowerCAmelCase_			:		float = 0.0 ,  lowerCAmelCase_			:		int = 3_2 ,  lowerCAmelCase_			:		Optional[int] = None ,  lowerCAmelCase_			:		bool = False ,  lowerCAmelCase_			:		Optional[int] = None ,  lowerCAmelCase_			:		str = "geglu" ,  lowerCAmelCase_			:		bool = True ,  lowerCAmelCase_			:		bool = True ,  )							->						Dict:
     super().__init__()
     __lowerCAmelCase							     =     num_attention_heads
     __lowerCAmelCase							     =     attention_head_dim
     __lowerCAmelCase							     =     num_attention_heads * attention_head_dim

     __lowerCAmelCase							     =     in_channels

     __lowerCAmelCase							     =     torch.nn.GroupNorm(num_groups=lowerCAmelCase_ ,  num_channels=lowerCAmelCase_ ,  eps=1e-6 ,  affine=lowerCAmelCase_					)
     __lowerCAmelCase							     =     nn.Linear(lowerCAmelCase_ ,  lowerCAmelCase_					)

     # 3. Define transformers blocks
     __lowerCAmelCase							     =     nn.ModuleList(
         [
             BasicTransformerBlock(
                 lowerCAmelCase_ ,  lowerCAmelCase_ ,  lowerCAmelCase_ ,  dropout=lowerCAmelCase_ ,  cross_attention_dim=lowerCAmelCase_ ,  activation_fn=lowerCAmelCase_ ,  attention_bias=lowerCAmelCase_ ,  double_self_attention=lowerCAmelCase_ ,  norm_elementwise_affine=lowerCAmelCase_ ,  )
             for d in range(lowerCAmelCase_					)
         ]					)

     __lowerCAmelCase							     =     nn.Linear(lowerCAmelCase_ ,  lowerCAmelCase_					)






  def     lowercase		(    self			:		Dict ,  lowerCAmelCase_			:		Tuple ,  lowerCAmelCase_			:		List[Any]=None ,  lowerCAmelCase_			:		Optional[int]=None ,  lowerCAmelCase_			:		Union[str, Any]=None ,  lowerCAmelCase_			:		Optional[int]=1 ,  lowerCAmelCase_			:		Optional[int]=None ,  lowerCAmelCase_			:		bool = True ,  )							->						str:
     __lowerCAmelCase     ,     __lowerCAmelCase     ,     __lowerCAmelCase     ,     __lowerCAmelCase							     =     hidden_states.shape
     __lowerCAmelCase							     =     batch_frames // num_frames

     __lowerCAmelCase							     =     hidden_states

     __lowerCAmelCase							     =     hidden_states[None, :].reshape(lowerCAmelCase_ ,  lowerCAmelCase_ ,  lowerCAmelCase_ ,  lowerCAmelCase_ ,  lowerCAmelCase_					)
     __lowerCAmelCase							     =     hidden_states.permute(0 ,  2 ,  1 ,  3 ,  4					)

     __lowerCAmelCase							     =     self.norm(lowerCAmelCase_					)
     __lowerCAmelCase							     =     hidden_states.permute(0 ,  3 ,  4 ,  2 ,  1					).reshape(batch_size * height * width ,  lowerCAmelCase_ ,  lowerCAmelCase_					)

     __lowerCAmelCase							     =     self.proj_in(lowerCAmelCase_					)

     # 2. Blocks
     for block in self.transformer_blocks:
        __lowerCAmelCase							     =     block(
            lowerCAmelCase_ ,  encoder_hidden_states=lowerCAmelCase_ ,  timestep=lowerCAmelCase_ ,  cross_attention_kwargs=lowerCAmelCase_ ,  class_labels=lowerCAmelCase_ ,  )

     # 3. Output
     __lowerCAmelCase							     =     self.proj_out(lowerCAmelCase_					)
     __lowerCAmelCase							     =     (
         hidden_states[None, None, :]
         .reshape(lowerCAmelCase_ ,  lowerCAmelCase_ ,  lowerCAmelCase_ ,  lowerCAmelCase_ ,  lowerCAmelCase_					)
         .permute(0 ,  3 ,  4 ,  1 ,  2					)
         .contiguous()
     )
     __lowerCAmelCase							     =     hidden_states.reshape(lowerCAmelCase_ ,  lowerCAmelCase_ ,  lowerCAmelCase_ ,  lowerCAmelCase_					)

     __lowerCAmelCase							     =     hidden_states + residual

     if not return_dict:
        return (output,)

     return TransformerTemporalModelOutput(sample=lowerCAmelCase_					)

