


import argparse
import json

import torch

from diffusers import DDPMScheduler, LDMPipeline, UNetaDModel, VQModel




def    a__    (		snake_case__					:							Tuple						,   snake_case__					:							Dict=1     ):

  if n_shave_prefix_segments >= 0:
    return ".".join(path.split("""."""     )[n_shave_prefix_segments:]     )
  else:
    return ".".join(path.split("""."""     )[:n_shave_prefix_segments]     )




def    a__    (		snake_case__					:							str						,   snake_case__					:							Tuple=0     ):
  _UpperCAmelCase		:							Dict							=     []
  for old_item in old_list:
    _UpperCAmelCase		:							Optional[Any]							=     old_item.replace("""in_layers.0"""						,   """norm1"""     )
    _UpperCAmelCase		:							Tuple							=     new_item.replace("""in_layers.2"""						,   """conv1"""     )

    _UpperCAmelCase		:							Dict							=     new_item.replace("""out_layers.0"""						,   """norm2"""     )
    _UpperCAmelCase		:							Tuple							=     new_item.replace("""out_layers.3"""						,   """conv2"""     )

    _UpperCAmelCase		:							List[str]							=     new_item.replace("""emb_layers.1"""						,   """time_emb_proj"""     )
    _UpperCAmelCase		:							List[str]							=     new_item.replace("""skip_connection"""						,   """conv_shortcut"""     )

    _UpperCAmelCase		:							int							=     shave_segments(_UpperCamelCase						,   n_shave_prefix_segments=_UpperCamelCase     )

    mapping.append({"""old""": old_item, """new""": new_item}     )

  return mapping




def    a__    (		snake_case__					:							List[Any]						,   snake_case__					:							List[Any]=0     ):
  _UpperCAmelCase		:							Any							=     []
  for old_item in old_list:
    _UpperCAmelCase		:							Optional[int]							=     old_item

    _UpperCAmelCase		:							str							=     new_item.replace("""norm.weight"""						,   """group_norm.weight"""     )
    _UpperCAmelCase		:							List[Any]							=     new_item.replace("""norm.bias"""						,   """group_norm.bias"""     )

    _UpperCAmelCase		:							str							=     new_item.replace("""proj_out.weight"""						,   """proj_attn.weight"""     )
    _UpperCAmelCase		:							Optional[int]							=     new_item.replace("""proj_out.bias"""						,   """proj_attn.bias"""     )

    _UpperCAmelCase		:							int							=     shave_segments(_UpperCamelCase						,   n_shave_prefix_segments=_UpperCamelCase     )

    mapping.append({"""old""": old_item, """new""": new_item}     )

  return mapping




def    a__    (		snake_case__					:							Dict						,   snake_case__					:							int						,   snake_case__					:							Optional[int]						,   snake_case__					:							Dict=None						,   snake_case__					:							int=None						,   snake_case__					:							List[Any]=None     ):
  assert isinstance(_UpperCamelCase						,   _UpperCamelCase     ), "Paths should be a list of dicts containing 'old' and 'new' keys."

  # Splits the attention layers into three variables.
  if attention_paths_to_split is not None:
    for path, path_map in attention_paths_to_split.items():
      _UpperCAmelCase		:							str							=     old_checkpoint[path]
      _UpperCAmelCase		:							Optional[Any]							=     old_tensor.shape[0] // 3

      _UpperCAmelCase		:							Dict							=     (-1, channels) if len(old_tensor.shape     ) == 3 else (-1)

      _UpperCAmelCase		:							Optional[Any]							=     old_tensor.shape[0] // config["""num_head_channels"""] // 3

      _UpperCAmelCase		:							str							=     old_tensor.reshape((num_heads, 3 * channels // num_heads) + old_tensor.shape[1:]     )
      _UpperCAmelCase,_UpperCAmelCase,_UpperCAmelCase		:							List[str]							=     old_tensor.split(channels // num_heads						,   dim=1     )

      _UpperCAmelCase		:							Optional[Any]							=     query.reshape(_UpperCamelCase     )
      _UpperCAmelCase		:							Any							=     key.reshape(_UpperCamelCase     )
      _UpperCAmelCase		:							Optional[Any]							=     value.reshape(_UpperCamelCase     )

  for path in paths:
    _UpperCAmelCase		:							List[Any]							=     path["""new"""]

    # These have already been assigned
    if attention_paths_to_split is not None and new_path in attention_paths_to_split:
      continue

    # Global renaming happens here
    _UpperCAmelCase		:							int							=     new_path.replace("""middle_block.0"""						,   """mid_block.resnets.0"""     )
    _UpperCAmelCase		:							str							=     new_path.replace("""middle_block.1"""						,   """mid_block.attentions.0"""     )
    _UpperCAmelCase		:							Union[str, Any]							=     new_path.replace("""middle_block.2"""						,   """mid_block.resnets.1"""     )

    if additional_replacements is not None:
      for replacement in additional_replacements:
        _UpperCAmelCase		:							Any							=     new_path.replace(replacement["""old"""]						,   replacement["""new"""]     )

        # proj_attn.weight has to be converted from conv 1D to linear
    if "proj_attn.weight" in new_path:
      _UpperCAmelCase		:							Tuple							=     old_checkpoint[path["""old"""]][:, :, 0]
    else:
      _UpperCAmelCase		:							List[Any]							=     old_checkpoint[path["""old"""]]




def    a__    (		snake_case__					:							List[str]						,   snake_case__					:							List[str]     ):
  _UpperCAmelCase		:							Any							=     {}

  _UpperCAmelCase		:							Optional[int]							=     checkpoint["""time_embed.0.weight"""]
  _UpperCAmelCase		:							Union[str, Any]							=     checkpoint["""time_embed.0.bias"""]
  _UpperCAmelCase		:							Tuple							=     checkpoint["""time_embed.2.weight"""]
  _UpperCAmelCase		:							Optional[Any]							=     checkpoint["""time_embed.2.bias"""]

  _UpperCAmelCase		:							int							=     checkpoint["""input_blocks.0.0.weight"""]
  _UpperCAmelCase		:							List[Any]							=     checkpoint["""input_blocks.0.0.bias"""]

  _UpperCAmelCase		:							Optional[int]							=     checkpoint["""out.0.weight"""]
  _UpperCAmelCase		:							Tuple							=     checkpoint["""out.0.bias"""]
  _UpperCAmelCase		:							Any							=     checkpoint["""out.2.weight"""]
  _UpperCAmelCase		:							Any							=     checkpoint["""out.2.bias"""]

  # Retrieves the keys for the input blocks only
  _UpperCAmelCase		:							List[str]							=     len({""".""".join(layer.split("""."""     )[:2]     ) for layer in checkpoint if """input_blocks""" in layer}     )
  _UpperCAmelCase		:							Optional[int]							=     {
      layer_id: [key for key in checkpoint if f'''input_blocks.{layer_id}''' in key]
      for layer_id in range(_UpperCamelCase     )
  }

  # Retrieves the keys for the middle blocks only
  _UpperCAmelCase		:							Dict							=     len({""".""".join(layer.split("""."""     )[:2]     ) for layer in checkpoint if """middle_block""" in layer}     )
  _UpperCAmelCase		:							List[Any]							=     {
      layer_id: [key for key in checkpoint if f'''middle_block.{layer_id}''' in key]
      for layer_id in range(_UpperCamelCase     )
  }

  # Retrieves the keys for the output blocks only
  _UpperCAmelCase		:							List[Any]							=     len({""".""".join(layer.split("""."""     )[:2]     ) for layer in checkpoint if """output_blocks""" in layer}     )
  _UpperCAmelCase		:							Dict							=     {
      layer_id: [key for key in checkpoint if f'''output_blocks.{layer_id}''' in key]
      for layer_id in range(_UpperCamelCase     )
  }

  for i in range(1						,   _UpperCamelCase     ):
    _UpperCAmelCase		:							str							=     (i - 1) // (config["""num_res_blocks"""] + 1)
    _UpperCAmelCase		:							str							=     (i - 1) % (config["""num_res_blocks"""] + 1)

    _UpperCAmelCase		:							Any							=     [key for key in input_blocks[i] if f'''input_blocks.{i}.0''' in key]
    _UpperCAmelCase		:							Dict							=     [key for key in input_blocks[i] if f'''input_blocks.{i}.1''' in key]

    if f'''input_blocks.{i}.0.op.weight''' in checkpoint:
      _UpperCAmelCase		:							int							=     checkpoint[
          f'''input_blocks.{i}.0.op.weight'''
      ]
      _UpperCAmelCase		:							Dict							=     checkpoint[
          f'''input_blocks.{i}.0.op.bias'''
      ]
      continue

    _UpperCAmelCase		:							int							=     renew_resnet_paths(_UpperCamelCase     )
    _UpperCAmelCase		:							Optional[Any]							=     {"""old""": f'''input_blocks.{i}.0''', """new""": f'''down_blocks.{block_id}.resnets.{layer_in_block_id}'''}
    _UpperCAmelCase		:							str							=     {"""old""": """resnets.2.op""", """new""": """downsamplers.0.op"""}
    assign_to_checkpoint(
        _UpperCamelCase						,   _UpperCamelCase						,   _UpperCamelCase						,   additional_replacements=[meta_path, resnet_op]						,   config=_UpperCamelCase     )

    if len(_UpperCamelCase     ):
      _UpperCAmelCase		:							Tuple							=     renew_attention_paths(_UpperCamelCase     )
      _UpperCAmelCase		:							Tuple							=     {
          """old""": f'''input_blocks.{i}.1''',
          """new""": f'''down_blocks.{block_id}.attentions.{layer_in_block_id}''',
      }
      _UpperCAmelCase		:							List[str]							=     {
          f'''input_blocks.{i}.1.qkv.bias''': {
              """key""": f'''down_blocks.{block_id}.attentions.{layer_in_block_id}.key.bias''',
              """query""": f'''down_blocks.{block_id}.attentions.{layer_in_block_id}.query.bias''',
              """value""": f'''down_blocks.{block_id}.attentions.{layer_in_block_id}.value.bias''',
          },
          f'''input_blocks.{i}.1.qkv.weight''': {
              """key""": f'''down_blocks.{block_id}.attentions.{layer_in_block_id}.key.weight''',
              """query""": f'''down_blocks.{block_id}.attentions.{layer_in_block_id}.query.weight''',
              """value""": f'''down_blocks.{block_id}.attentions.{layer_in_block_id}.value.weight''',
          },
      }
      assign_to_checkpoint(
          _UpperCamelCase						,   _UpperCamelCase						,   _UpperCamelCase						,   additional_replacements=[meta_path]						,   attention_paths_to_split=_UpperCamelCase						,   config=_UpperCamelCase						,   )

  _UpperCAmelCase		:							Optional[Any]							=     middle_blocks[0]
  _UpperCAmelCase		:							Dict							=     middle_blocks[1]
  _UpperCAmelCase		:							List[str]							=     middle_blocks[2]

  _UpperCAmelCase		:							int							=     renew_resnet_paths(_UpperCamelCase     )
  assign_to_checkpoint(_UpperCamelCase						,   _UpperCamelCase						,   _UpperCamelCase						,   config=_UpperCamelCase     )

  _UpperCAmelCase		:							str							=     renew_resnet_paths(_UpperCamelCase     )
  assign_to_checkpoint(_UpperCamelCase						,   _UpperCamelCase						,   _UpperCamelCase						,   config=_UpperCamelCase     )

  _UpperCAmelCase		:							List[Any]							=     renew_attention_paths(_UpperCamelCase     )
  _UpperCAmelCase		:							List[Any]							=     {
      """middle_block.1.qkv.bias""": {
          """key""": """mid_block.attentions.0.key.bias""",
          """query""": """mid_block.attentions.0.query.bias""",
          """value""": """mid_block.attentions.0.value.bias""",
      },
      """middle_block.1.qkv.weight""": {
          """key""": """mid_block.attentions.0.key.weight""",
          """query""": """mid_block.attentions.0.query.weight""",
          """value""": """mid_block.attentions.0.value.weight""",
      },
  }
  assign_to_checkpoint(
      _UpperCamelCase						,   _UpperCamelCase						,   _UpperCamelCase						,   attention_paths_to_split=_UpperCamelCase						,   config=_UpperCamelCase     )

  for i in range(_UpperCamelCase     ):
    _UpperCAmelCase		:							Dict							=     i // (config["""num_res_blocks"""] + 1)
    _UpperCAmelCase		:							Any							=     i % (config["""num_res_blocks"""] + 1)
    _UpperCAmelCase		:							Tuple							=     [shave_segments(_UpperCamelCase						,   2     ) for name in output_blocks[i]]
    _UpperCAmelCase		:							List[Any]							=     {}

    for layer in output_block_layers:
      _UpperCAmelCase,_UpperCAmelCase		:							Dict							=     layer.split("""."""     )[0], shave_segments(_UpperCamelCase						,   1     )
      if layer_id in output_block_list:
        output_block_list[layer_id].append(_UpperCamelCase     )
      else:
        _UpperCAmelCase		:							Any							=     [layer_name]

    if len(_UpperCamelCase     ) > 1:
      _UpperCAmelCase		:							List[str]							=     [key for key in output_blocks[i] if f'''output_blocks.{i}.0''' in key]
      _UpperCAmelCase		:							List[Any]							=     [key for key in output_blocks[i] if f'''output_blocks.{i}.1''' in key]

      _UpperCAmelCase		:							int							=     renew_resnet_paths(_UpperCamelCase     )
      _UpperCAmelCase		:							str							=     renew_resnet_paths(_UpperCamelCase     )

      _UpperCAmelCase		:							List[str]							=     {"""old""": f'''output_blocks.{i}.0''', """new""": f'''up_blocks.{block_id}.resnets.{layer_in_block_id}'''}
      assign_to_checkpoint(_UpperCamelCase						,   _UpperCamelCase						,   _UpperCamelCase						,   additional_replacements=[meta_path]						,   config=_UpperCamelCase     )

      if ["conv.weight", "conv.bias"] in output_block_list.values():
        _UpperCAmelCase		:							Dict							=     list(output_block_list.values()     ).index(["""conv.weight""", """conv.bias"""]     )
        _UpperCAmelCase		:							Dict							=     checkpoint[
            f'''output_blocks.{i}.{index}.conv.weight'''
        ]
        _UpperCAmelCase		:							Any							=     checkpoint[
            f'''output_blocks.{i}.{index}.conv.bias'''
        ]

        # Clear attentions as they have been attributed above.
        if len(_UpperCamelCase     ) == 2:
          _UpperCAmelCase		:							str							=     []

      if len(_UpperCamelCase     ):
        _UpperCAmelCase		:							List[Any]							=     renew_attention_paths(_UpperCamelCase     )
        _UpperCAmelCase		:							int							=     {
            """old""": f'''output_blocks.{i}.1''',
            """new""": f'''up_blocks.{block_id}.attentions.{layer_in_block_id}''',
        }
        _UpperCAmelCase		:							Any							=     {
            f'''output_blocks.{i}.1.qkv.bias''': {
                """key""": f'''up_blocks.{block_id}.attentions.{layer_in_block_id}.key.bias''',
                """query""": f'''up_blocks.{block_id}.attentions.{layer_in_block_id}.query.bias''',
                """value""": f'''up_blocks.{block_id}.attentions.{layer_in_block_id}.value.bias''',
            },
            f'''output_blocks.{i}.1.qkv.weight''': {
                """key""": f'''up_blocks.{block_id}.attentions.{layer_in_block_id}.key.weight''',
                """query""": f'''up_blocks.{block_id}.attentions.{layer_in_block_id}.query.weight''',
                """value""": f'''up_blocks.{block_id}.attentions.{layer_in_block_id}.value.weight''',
            },
        }
        assign_to_checkpoint(
            _UpperCamelCase						,   _UpperCamelCase						,   _UpperCamelCase						,   additional_replacements=[meta_path]						,   attention_paths_to_split=to_split if any("""qkv""" in key for key in attentions     ) else None						,   config=_UpperCamelCase						,   )
    else:
      _UpperCAmelCase		:							List[str]							=     renew_resnet_paths(_UpperCamelCase						,   n_shave_prefix_segments=1     )
      for path in resnet_0_paths:
        _UpperCAmelCase		:							Optional[int]							=     """.""".join(["""output_blocks""", str(_UpperCamelCase     ), path["""old"""]]     )
        _UpperCAmelCase		:							Optional[Any]							=     """.""".join(["""up_blocks""", str(_UpperCamelCase     ), """resnets""", str(_UpperCamelCase     ), path["""new"""]]     )

        _UpperCAmelCase		:							Union[str, Any]							=     checkpoint[old_path]

  return new_checkpoint


if __name__ == "__main__":
 SCREAMING_SNAKE_CASE__					:     List[str]       =     argparse.ArgumentParser()

 parser.add_argument(
     '--checkpoint_path', default=None, type=str, required=True, help='Path to the checkpoint to convert.'
 )

 parser.add_argument(
     '--config_file',
     default=None,
     type=str,
     required=True,
     help='The config json file corresponding to the architecture.',
 )

 parser.add_argument('--dump_path', default=None, type=str, required=True, help='Path to the output model.')

 SCREAMING_SNAKE_CASE__					:     Dict       =     parser.parse_args()

 SCREAMING_SNAKE_CASE__					:     Union[str, Any]       =     torch.load(args.checkpoint_path)

 with open(args.config_file) as f:
  SCREAMING_SNAKE_CASE__					:     Any       =     json.loads(f.read())

 SCREAMING_SNAKE_CASE__					:     Union[str, Any]       =     convert_ldm_checkpoint(checkpoint, config)

 if "ldm" in config:
  del config["ldm"]

 SCREAMING_SNAKE_CASE__					:     Optional[int]       =     UNetaDModel(**config)
 model.load_state_dict(converted_checkpoint)

 try:
  SCREAMING_SNAKE_CASE__					:     List[str]       =     DDPMScheduler.from_config('/'.join(args.checkpoint_path.split('/')[:-1]))
  SCREAMING_SNAKE_CASE__					:     Optional[int]       =     VQModel.from_pretrained('/'.join(args.checkpoint_path.split('/')[:-1]))

  SCREAMING_SNAKE_CASE__					:     int       =     LDMPipeline(unet=model, scheduler=scheduler, vae=vqvae)
  pipe.save_pretrained(args.dump_path)
 except:  # noqa: E722
  model.save_pretrained(args.dump_path)













from __future__ import annotations

import math
def 		lowercase__  (				_UpperCamelCase       ,							_UpperCamelCase) ->			list:
      """simple docstring"""

      if len(_UpperCamelCase) != 2 or len(a[0]) != 2 or len(_UpperCamelCase) != 2 or len(b[0]) != 2:
            raise Exception('Matrices are not 2x2')
      UpperCamelCase					       =  [
          [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 		lowercase__  (				_UpperCamelCase       ,							_UpperCamelCase) ->			Union[str, Any]:
      """simple docstring"""

      return [
          [matrix_a[row][col] + matrix_b[row][col] for col in range(len(matrix_a[row]))]
          for row in range(len(_UpperCamelCase))
      ]
def 		lowercase__  (				_UpperCamelCase       ,							_UpperCamelCase) ->			Optional[int]:
      """simple docstring"""

      return [
          [matrix_a[row][col] - matrix_b[row][col] for col in range(len(matrix_a[row]))]
          for row in range(len(_UpperCamelCase))
      ]
def 		lowercase__  (				_UpperCamelCase) ->			tuple[list, list, list, list]:
      """simple docstring"""

      if len(_UpperCamelCase) % 2 != 0 or len(a[0]) % 2 != 0:
            raise Exception('Odd matrices are not supported!')

      UpperCamelCase					       =  len(_UpperCamelCase)
      UpperCamelCase					       =  matrix_length // 2

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

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

      return top_left, top_right, bot_left, bot_right
def 		lowercase__  (				_UpperCamelCase) ->			tuple[int, int]:
      """simple docstring"""

      return len(_UpperCamelCase), len(matrix[0])
def 		lowercase__  (				_UpperCamelCase) ->			None:
      """simple docstring"""

      print('\n'.join(str(_UpperCamelCase) for line in matrix))
def 		lowercase__  (				_UpperCamelCase       ,							_UpperCamelCase) ->			list:
      """simple docstring"""

      if matrix_dimensions(_UpperCamelCase) == (2, 2):
            return default_matrix_multiplication(_UpperCamelCase       ,							_UpperCamelCase)

      UpperCamelCase       ,  UpperCamelCase       ,  UpperCamelCase       ,  UpperCamelCase					       =  split_matrix(_UpperCamelCase)
      UpperCamelCase       ,  UpperCamelCase       ,  UpperCamelCase       ,  UpperCamelCase					       =  split_matrix(_UpperCamelCase)

      UpperCamelCase					       =  actual_strassen(_UpperCamelCase       ,							matrix_subtraction(_UpperCamelCase       ,							_UpperCamelCase))
      UpperCamelCase					       =  actual_strassen(matrix_addition(_UpperCamelCase       ,							_UpperCamelCase)       ,							_UpperCamelCase)
      UpperCamelCase					       =  actual_strassen(matrix_addition(_UpperCamelCase       ,							_UpperCamelCase)       ,							_UpperCamelCase)
      UpperCamelCase					       =  actual_strassen(_UpperCamelCase       ,							matrix_subtraction(_UpperCamelCase       ,							_UpperCamelCase))
      UpperCamelCase					       =  actual_strassen(matrix_addition(_UpperCamelCase       ,							_UpperCamelCase)       ,							matrix_addition(_UpperCamelCase       ,							_UpperCamelCase))
      UpperCamelCase					       =  actual_strassen(matrix_subtraction(_UpperCamelCase       ,							_UpperCamelCase)       ,							matrix_addition(_UpperCamelCase       ,							_UpperCamelCase))
      UpperCamelCase					       =  actual_strassen(matrix_subtraction(_UpperCamelCase       ,							_UpperCamelCase)       ,							matrix_addition(_UpperCamelCase       ,							_UpperCamelCase))

      UpperCamelCase					       =  matrix_addition(matrix_subtraction(matrix_addition(_UpperCamelCase       ,							_UpperCamelCase)       ,							_UpperCamelCase)       ,							_UpperCamelCase)
      UpperCamelCase					       =  matrix_addition(_UpperCamelCase       ,							_UpperCamelCase)
      UpperCamelCase					       =  matrix_addition(_UpperCamelCase       ,							_UpperCamelCase)
      UpperCamelCase					       =  matrix_subtraction(matrix_subtraction(matrix_addition(_UpperCamelCase       ,							_UpperCamelCase)       ,							_UpperCamelCase)       ,							_UpperCamelCase)

      # construct the new matrix from our 4 quadrants
      UpperCamelCase					       =  []
      for i in range(len(_UpperCamelCase)):
            new_matrix.append(top_left[i] + top_right[i])
      for i in range(len(_UpperCamelCase)):
            new_matrix.append(bot_left[i] + bot_right[i])
      return new_matrix
def 		lowercase__  (				_UpperCamelCase       ,							_UpperCamelCase) ->			list:
      """simple docstring"""

      if matrix_dimensions(_UpperCamelCase)[1] != matrix_dimensions(_UpperCamelCase)[0]:
            UpperCamelCase					       =  (
                'Unable to multiply these matrices, please check the dimensions.\n'
                F'Matrix A: {matrixa}\n'
                F'Matrix B: {matrixa}'
            )
            raise Exception(_UpperCamelCase)
      UpperCamelCase					       =  matrix_dimensions(_UpperCamelCase)
      UpperCamelCase					       =  matrix_dimensions(_UpperCamelCase)

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

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

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

      UpperCamelCase					       =  actual_strassen(_UpperCamelCase       ,							_UpperCamelCase)

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


if __name__ == "__main__":
       __magic_name__   :  Optional[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],
       ]
       __magic_name__   :  List[str]        =							[[0, 2, 1, 1], [16, 2, 3, 3], [2, 2, 7, 7], [13, 11, 22, 4]]
       print(strassen(matrixa, matrixa))



