


"""simple docstring"""


from __future__ import annotations

import math






def      a__ (				__lowercase     ,			__lowercase   )	->	list:
				if len(__lowercase   ) != 2 or len(a[0]   ) != 2 or len(__lowercase   ) != 2 or len(b[0]   ) != 2:
								raise Exception("Matrices are not 2x2"   )
				_A					  =			[
				    [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__ (				__lowercase     ,			__lowercase   )	->	Optional[Any]:
				return [
				    [matrix_a[row][col] + matrix_b[row][col] for col in range(len(matrix_a[row]   )   )]
				    for row in range(len(__lowercase   )   )
				]






def      a__ (				__lowercase     ,			__lowercase   )	->	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(__lowercase   )   )
				]






def      a__ (				__lowercase   )	->	tuple[list, list, list, list]:
				if len(__lowercase   ) % 2 != 0 or len(a[0]   ) % 2 != 0:
								raise Exception("Odd matrices are not supported!"   )

				_A					  =			len(__lowercase   )
				_A					  =			matrix_length // 2

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

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

				return top_left, top_right, bot_left, bot_right






def      a__ (				__lowercase   )	->	tuple[int, int]:
				return len(__lowercase   ), len(matrix[0]   )






def      a__ (				__lowercase   )	->	None:
				print("\n".join(str(__lowercase   ) for line in matrix   )   )






def      a__ (				__lowercase     ,			__lowercase   )	->	list:
				if matrix_dimensions(__lowercase   ) == (2, 2):
								return default_matrix_multiplication(__lowercase     ,			__lowercase   )

				_A  ,		_A  ,		_A  ,		_A					  =			split_matrix(__lowercase   )
				_A  ,		_A  ,		_A  ,		_A					  =			split_matrix(__lowercase   )

				_A					  =			actual_strassen(__lowercase     ,			matrix_subtraction(__lowercase     ,			__lowercase   )   )
				_A					  =			actual_strassen(matrix_addition(__lowercase     ,			__lowercase   )     ,			__lowercase   )
				_A					  =			actual_strassen(matrix_addition(__lowercase     ,			__lowercase   )     ,			__lowercase   )
				_A					  =			actual_strassen(__lowercase     ,			matrix_subtraction(__lowercase     ,			__lowercase   )   )
				_A					  =			actual_strassen(matrix_addition(__lowercase     ,			__lowercase   )     ,			matrix_addition(__lowercase     ,			__lowercase   )   )
				_A					  =			actual_strassen(matrix_subtraction(__lowercase     ,			__lowercase   )     ,			matrix_addition(__lowercase     ,			__lowercase   )   )
				_A					  =			actual_strassen(matrix_subtraction(__lowercase     ,			__lowercase   )     ,			matrix_addition(__lowercase     ,			__lowercase   )   )

				_A					  =			matrix_addition(matrix_subtraction(matrix_addition(__lowercase     ,			__lowercase   )     ,			__lowercase   )     ,			__lowercase   )
				_A					  =			matrix_addition(__lowercase     ,			__lowercase   )
				_A					  =			matrix_addition(__lowercase     ,			__lowercase   )
				_A					  =			matrix_subtraction(matrix_subtraction(matrix_addition(__lowercase     ,			__lowercase   )     ,			__lowercase   )     ,			__lowercase   )

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






def      a__ (				__lowercase     ,			__lowercase   )	->	list:
				if matrix_dimensions(__lowercase   )[1] != matrix_dimensions(__lowercase   )[0]:
								_A					  =			(
								    "Unable to multiply these matrices, please check the dimensions.\n"
								    f"""Matrix A: {matrixa}\n"""
								    f"""Matrix B: {matrixa}"""
								)
								raise Exception(__lowercase   )
				_A					  =			matrix_dimensions(__lowercase   )
				_A					  =			matrix_dimensions(__lowercase   )

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

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

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

				_A					  =			actual_strassen(__lowercase     ,			__lowercase   )

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


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



"""simple docstring"""


import argparse
import json
import os
from collections import OrderedDict

import numpy as np
import tensorflow as tf
import torch






def      a__ (				__lowercase   )	->	List[Any]:
				_A					  =			os.path.join(args.tf_model_dir     ,			"parameters.json"   )
				_A					  =			json.loads(open(__lowercase   ).read()   )
				if not params:
								raise ValueError(
								    f"""It seems that the json file at {parameter_file} is empty. Make sure you have a correct json file."""   )
				if not args.output.endswith(".pt"   ):
								_A					  =			args.output + ".pt"
				_A					  =			OrderedDict()
				with tf.device("/CPU:0"   ):
								_A					  =			tf.train.load_checkpoint(args.tf_model_dir   )
								_A					  =			reader.get_variable_to_shape_map()
								for key_name in shapes.keys():
												_A					  =			reader.get_tensor(__lowercase   ).astype(np.floataa   )
												if key_name.endswith("/adam_m"   ) or key_name.endswith("/adam_v"   ):
																continue
												if key_name.startswith("pasts/"   ):
																if key_name.startswith("pasts/mlp"   ):
																				_A					  =			int(key_name[9]   )
																elif key_name.startswith("pasts/out"   ):
																				_A					  =			8
																_A					  =			"model.sqout.%d.weight" % (player * 2)  # enter to nn.Sequencial with Tanh, so 2 at a time
																_A					  =			vnp.transpose([1, 0]   ).copy()  # Mesh-Tensorflow is a diagonal matrix
																_A					  =			torch.tensor(__lowercase   )
												elif key_name.startswith("model/moe"   ):
																_A					  =			int(key_name[9:].split("/"   )[0]   )
																if key_name.endswith("/switch_gating/kernel"   ):
																				_A					  =			"model.blocks.%d.feed_forward.mlp.router.classifier.weight" % player
																				_A					  =			vnp.transpose([1, 0]   ).copy()  # Mesh-Tensorflow is a diagonal matrix
																				_A					  =			torch.tensor(__lowercase   )
																elif key_name.endswith("/softmlp/kernel"   ):
																				_A					  =			"model.blocks.%d.feed_forward.soft_bypass_mlp.weight" % player
																				_A					  =			vnp.transpose([1, 0]   ).copy()  # Mesh-Tensorflow is a diagonal matrix
																				_A					  =			torch.tensor(__lowercase   )
																elif key_name.endswith("/wo/kernel"   ) or key_name.endswith("/wi/kernel"   ):
																				_A					  =			key_name[-9:-7]
																				for i in range(16   ):
																								_A					  =			"model.blocks.%d.feed_forward.mlp.experts.expert_%d.%s.weight" % (player, i, nlayer)
																								_A					  =			(
																								    vnp[i].transpose([1, 0]   ).copy()
																								)  # In Mesh-Tensorflow, it is one array, so it is divided
																								_A					  =			torch.tensor(__lowercase   )
												elif key_name.startswith("model/mlp"   ):
																_A					  =			int(key_name[9:].split("/"   )[0]   )
																if key_name.endswith("/p1/kernel"   ):
																				_A					  =			"model.blocks.%d.feed_forward.mlp.wi.weight" % player
																				_A					  =			vnp.transpose([1, 0]   ).copy()  # Mesh-Tensorflow is a diagonal matrix
																				_A					  =			torch.tensor(__lowercase   )
																elif key_name.endswith("/p1/bias"   ):
																				_A					  =			"model.blocks.%d.feed_forward.mlp.wi.bias" % player
																				_A					  =			vnp.copy()  # same because it is one dimensional
																				_A					  =			torch.tensor(__lowercase   )
																elif key_name.endswith("/p2/kernel"   ):
																				_A					  =			"model.blocks.%d.feed_forward.mlp.wo.weight" % player
																				_A					  =			vnp.transpose([1, 0]   ).copy()  # Mesh-Tensorflow is a diagonal matrix
																				_A					  =			torch.tensor(__lowercase   )
																elif key_name.endswith("/p2/bias"   ):
																				_A					  =			"model.blocks.%d.feed_forward.mlp.wo.bias" % player
																				_A					  =			vnp.copy()  # same because it is one dimensional
																				_A					  =			torch.tensor(__lowercase   )
												elif key_name.startswith("model/ln"   ):
																_A					  =			int(key_name[8:].split("/"   )[0]   )
																if key_name.endswith("/b"   ):
																				_A					  =			"model.blocks.%d.feed_forward.norm.bias" % player
																				_A					  =			vnp.copy()  # same because it is one dimensional
																				_A					  =			torch.tensor(__lowercase   )
																elif key_name.endswith("/g"   ):
																				_A					  =			"model.blocks.%d.feed_forward.norm.weight" % player
																				_A					  =			vnp.copy()  # same because it is one dimensional
																				_A					  =			torch.tensor(__lowercase   )
												elif key_name.startswith("model/att"   ):
																_A					  =			int(key_name[9:].split("/"   )[0]   )
																if key_name.endswith("/qkv/kernel"   ):
																				_A					  =			vnp.copy()  # Compute same dimension as Mesh-tensorflow using einsum
																				_A					  =			state[:, 0, :, :]
																				_A					  =			state[:, 1, :, :]
																				_A					  =			state[:, 2, :, :]
																				_A					  =			(
																				    state_q.reshape([state_q.shape[0], state_q.shape[1] * state_q.shape[2]]   )
																				    .transpose([1, 0]   )
																				    .copy()
																				)  # Mesh-Tensorflow is a diagonal matrix
																				_A					  =			(
																				    state_k.reshape([state_k.shape[0], state_k.shape[1] * state_k.shape[2]]   )
																				    .transpose([1, 0]   )
																				    .copy()
																				)  # Mesh-Tensorflow is a diagonal matrix
																				_A					  =			(
																				    state_v.reshape([state_v.shape[0], state_v.shape[1] * state_v.shape[2]]   )
																				    .transpose([1, 0]   )
																				    .copy()
																				)  # Mesh-Tensorflow is a diagonal matrix
																				_A					  =			"model.blocks.%d.self_attn.self_attn.q_proj.weight" % player
																				_A					  =			torch.tensor(__lowercase   )
																				_A					  =			"model.blocks.%d.self_attn.self_attn.k_proj.weight" % player
																				_A					  =			torch.tensor(__lowercase   )
																				_A					  =			"model.blocks.%d.self_attn.self_attn.v_proj.weight" % player
																				_A					  =			torch.tensor(__lowercase   )
																elif key_name.endswith("/o/kernel"   ):
																				_A					  =			"model.blocks.%d.self_attn.self_attn.out_proj.weight" % player
																				_A					  =			(
																				    vnp.reshape([vnp.shape[0] * vnp.shape[1], vnp.shape[2]]   ).transpose([1, 0]   ).copy()
																				)  # Mesh-Tensorflow is a diagonal matrix
																				_A					  =			torch.tensor(__lowercase   )
												elif key_name.startswith("model/an"   ):
																_A					  =			int(key_name[8:].split("/"   )[0]   )
																if key_name.endswith("/b"   ):
																				_A					  =			"model.blocks.%d.self_attn.norm.bias" % player
																				_A					  =			vnp.copy()  # same because it is one dimensional
																				_A					  =			torch.tensor(__lowercase   )
																elif key_name.endswith("/g"   ):
																				_A					  =			"model.blocks.%d.self_attn.norm.weight" % player
																				_A					  =			vnp.copy()  # same because it is one dimensional
																				_A					  =			torch.tensor(__lowercase   )
												elif (
												    key_name.startswith("model/wte"   )
												    or key_name.startswith("model/wpe"   )
												    or key_name.startswith("model/ete"   )
												):
																_A					  =			{"wte": "embed_tokens", "wpe": "position_embeddings", "ete": "extra_position_embeddings"}[
																    key_name[-3:]
																]
																_A					  =			"model.%s.weight" % nlayer
																_A					  =			vnp.copy()  # same in embedded
																_A					  =			torch.tensor(__lowercase   )
																if key_name.startswith("model/wte"   ):
																				_A					  =			"lm_head.weight"
																				_A					  =			vnp.copy()  # same in embedded
																				_A					  =			torch.tensor(__lowercase   )
												elif key_name.startswith("model/wob"   ):
																_A					  =			"final_logits_bias"
																_A					  =			vnp.copy()  # same in embedded
																_A					  =			state.reshape((1, -1)   )
																_A					  =			torch.tensor(__lowercase   )
												elif key_name == "model/dense/kernel":
																_A					  =			"model.last_project.weight"
																_A					  =			vnp.transpose([1, 0]   ).copy()  # Mesh-Tensorflow is a diagonal matrix
																_A					  =			torch.tensor(__lowercase   )
												elif key_name == "model/dense_1/bias":
																_A					  =			"model.last_project.bias"
																_A					  =			vnp.copy()  # same because it is one dimensional
																_A					  =			torch.tensor(__lowercase   )
				torch.save(__lowercase     ,			args.output   )


if __name__ == "__main__":
		a_       							=    argparse.ArgumentParser(
		    description="model converter.", formatter_class=argparse.ArgumentDefaultsHelpFormatter
		)
		parser.add_argument("--tf_model_dir", metavar="PATH", type=str, required=True, help="import model")
		parser.add_argument("--output", metavar="PATH", type=str, required=True, help="output model")
		a_       							=    parser.parse_args()
		convert_tf_gptsan_to_pt(args)