






import tensorflow as tf

from ...tf_utils import shape_list

class     _SCREAMING_SNAKE_CASE       (			tf.keras.layers.Layer      ):





	def __init__(		self				:					Tuple ,  __lowerCamelCase				:					Optional[int] ,  __lowerCamelCase				:					Dict ,  __lowerCamelCase				:					List[Any] ,  __lowerCamelCase				:					Dict ,  __lowerCamelCase				:					Optional[int]=1 ,  __lowerCamelCase				:					Tuple=False ,  **__lowerCamelCase				:					Dict	):
		super().__init__(**__lowerCamelCase	)

		UpperCamelCase     :str          =	vocab_size
		UpperCamelCase     :Union[str, Any]          =	d_embed
		UpperCamelCase     :Optional[Any]          =	d_proj

		UpperCamelCase     :Union[str, Any]          =	cutoffs + [vocab_size]
		UpperCamelCase     :int          =	[0] + self.cutoffs
		UpperCamelCase     :List[str]          =	div_val

		UpperCamelCase     :Optional[Any]          =	self.cutoffs[0]
		UpperCamelCase     :Optional[int]          =	len(self.cutoffs	) - 1
		UpperCamelCase     :Tuple          =	self.shortlist_size + self.n_clusters
		UpperCamelCase     :List[str]          =	keep_order

		UpperCamelCase     :str          =	[]
		UpperCamelCase     :Optional[Any]          =	[]





	def 						_A (		self				:					Tuple ,  __lowerCamelCase				:					List[str]	):
		if self.n_clusters > 0:
			UpperCamelCase     :List[str]          =	self.add_weight(
			    shape=(self.n_clusters, self.d_embed) ,  initializer="""zeros""" ,  trainable=__lowerCamelCase ,  name="""cluster_weight"""	)
			UpperCamelCase     :Union[str, Any]          =	self.add_weight(
			    shape=(self.n_clusters,) ,  initializer="""zeros""" ,  trainable=__lowerCamelCase ,  name="""cluster_bias"""	)

		if self.div_val == 1:
			for i in range(len(self.cutoffs	)	):
				if self.d_proj != self.d_embed:
					UpperCamelCase     :Optional[Any]          =	self.add_weight(
					    shape=(self.d_embed, self.d_proj) ,  initializer="""zeros""" ,  trainable=__lowerCamelCase ,  name=F"""out_projs_._{i}""" ,  )
					self.out_projs.append(__lowerCamelCase	)
				else:
					self.out_projs.append(__lowerCamelCase	)
				UpperCamelCase     :List[str]          =	self.add_weight(
				    shape=(self.vocab_size, self.d_embed) ,  initializer="""zeros""" ,  trainable=__lowerCamelCase ,  name=F"""out_layers_._{i}_._weight""" ,  )
				UpperCamelCase     :Dict          =	self.add_weight(
				    shape=(self.vocab_size,) ,  initializer="""zeros""" ,  trainable=__lowerCamelCase ,  name=F"""out_layers_._{i}_._bias""" ,  )
				self.out_layers.append((weight, bias)	)
		else:
			for i in range(len(self.cutoffs	)	):
				UpperCamelCase     ,      UpperCamelCase     :int          =	self.cutoff_ends[i], self.cutoff_ends[i + 1]
				UpperCamelCase     :Optional[int]          =	self.d_embed // (self.div_val**i)

				UpperCamelCase     :Tuple          =	self.add_weight(
				    shape=(d_emb_i, self.d_proj) ,  initializer="""zeros""" ,  trainable=__lowerCamelCase ,  name=F"""out_projs_._{i}"""	)
				self.out_projs.append(__lowerCamelCase	)
				UpperCamelCase     :Optional[Any]          =	self.add_weight(
				    shape=(r_idx - l_idx, d_emb_i) ,  initializer="""zeros""" ,  trainable=__lowerCamelCase ,  name=F"""out_layers_._{i}_._weight""" ,  )
				UpperCamelCase     :List[str]          =	self.add_weight(
				    shape=(r_idx - l_idx,) ,  initializer="""zeros""" ,  trainable=__lowerCamelCase ,  name=F"""out_layers_._{i}_._bias""" ,  )
				self.out_layers.append((weight, bias)	)
		super().build(__lowerCamelCase	)





	@staticmethod
	def 						_A (		__lowerCamelCase				:					List[Any] ,  __lowerCamelCase				:					Dict ,  __lowerCamelCase				:					Optional[int] ,  __lowerCamelCase				:					Optional[Any]=None	):
		UpperCamelCase     :Tuple          =	x
		if proj is not None:
			UpperCamelCase     :Any          =	tf.einsum("""ibd,ed->ibe""" ,  __lowerCamelCase ,  __lowerCamelCase	)
		return tf.einsum("""ibd,nd->ibn""" ,  __lowerCamelCase ,  __lowerCamelCase	) + b





	@staticmethod
	def 						_A (		__lowerCamelCase				:					List[Any] ,  __lowerCamelCase				:					List[Any]	):
		UpperCamelCase     :Any          =	shape_list(__lowerCamelCase	)
		UpperCamelCase     :Optional[Any]          =	tf.range(lp_size[0] ,  dtype=target.dtype	)
		UpperCamelCase     :str          =	tf.stack([r, target] ,  1	)
		return tf.gather_nd(__lowerCamelCase ,  __lowerCamelCase	)





	def 						_A (		self				:					str ,  __lowerCamelCase				:					Tuple ,  __lowerCamelCase				:					Tuple ,  __lowerCamelCase				:					int=True ,  __lowerCamelCase				:					List[Any]=False	):
		UpperCamelCase     :List[Any]          =	0
		if self.n_clusters == 0:
			UpperCamelCase     :List[str]          =	self._logit(__lowerCamelCase ,  self.out_layers[0][0] ,  self.out_layers[0][1] ,  self.out_projs[0]	)
			if target is not None:
				UpperCamelCase     :Tuple          =	tf.nn.sparse_softmax_cross_entropy_with_logits(labels=__lowerCamelCase ,  logits=__lowerCamelCase	)
			UpperCamelCase     :int          =	tf.nn.log_softmax(__lowerCamelCase ,  axis=-1	)
		else:
			UpperCamelCase     :List[str]          =	shape_list(__lowerCamelCase	)
			UpperCamelCase     :List[Any]          =	[]
			UpperCamelCase     :Union[str, Any]          =	tf.zeros(hidden_sizes[:2]	)
			for i in range(len(self.cutoffs	)	):
				UpperCamelCase     ,      UpperCamelCase     :str          =	self.cutoff_ends[i], self.cutoff_ends[i + 1]
				if target is not None:
					UpperCamelCase     :int          =	(target >= l_idx) & (target < r_idx)
					UpperCamelCase     :int          =	tf.where(__lowerCamelCase	)
					UpperCamelCase     :Tuple          =	tf.boolean_mask(__lowerCamelCase ,  __lowerCamelCase	) - l_idx

				if self.div_val == 1:
					UpperCamelCase     :Tuple          =	self.out_layers[0][0][l_idx:r_idx]
					UpperCamelCase     :Union[str, Any]          =	self.out_layers[0][1][l_idx:r_idx]
				else:
					UpperCamelCase     :List[str]          =	self.out_layers[i][0]
					UpperCamelCase     :Union[str, Any]          =	self.out_layers[i][1]

				if i == 0:
					UpperCamelCase     :str          =	tf.concat([cur_W, self.cluster_weight] ,  0	)
					UpperCamelCase     :List[str]          =	tf.concat([cur_b, self.cluster_bias] ,  0	)

					UpperCamelCase     :Union[str, Any]          =	self._logit(__lowerCamelCase ,  __lowerCamelCase ,  __lowerCamelCase ,  self.out_projs[0]	)
					UpperCamelCase     :List[Any]          =	tf.nn.log_softmax(__lowerCamelCase	)
					out.append(head_logprob[..., : self.cutoffs[0]]	)
					if target is not None:
						UpperCamelCase     :str          =	tf.boolean_mask(__lowerCamelCase ,  __lowerCamelCase	)
						UpperCamelCase     :Tuple          =	self._gather_logprob(__lowerCamelCase ,  __lowerCamelCase	)
				else:
					UpperCamelCase     :int          =	self._logit(__lowerCamelCase ,  __lowerCamelCase ,  __lowerCamelCase ,  self.out_projs[i]	)
					UpperCamelCase     :Optional[int]          =	tf.nn.log_softmax(__lowerCamelCase	)
					UpperCamelCase     :Dict          =	self.cutoffs[0] + i - 1  # No probability for the head cluster
					UpperCamelCase     :List[str]          =	head_logprob[..., cluster_prob_idx, None] + tail_logprob
					out.append(__lowerCamelCase	)
					if target is not None:
						UpperCamelCase     :List[Any]          =	tf.boolean_mask(__lowerCamelCase ,  __lowerCamelCase	)
						UpperCamelCase     :List[str]          =	tf.boolean_mask(__lowerCamelCase ,  __lowerCamelCase	)
						UpperCamelCase     :Any          =	self._gather_logprob(__lowerCamelCase ,  __lowerCamelCase	)
						cur_logprob += cur_head_logprob[:, self.cutoff_ends[1] + i - 1]
				if target is not None:
					loss += tf.scatter_nd(__lowerCamelCase ,  -cur_logprob ,  shape_list(__lowerCamelCase	)	)
			UpperCamelCase     :Dict          =	tf.concat(__lowerCamelCase ,  axis=-1	)

		if target is not None:
			if return_mean:
				UpperCamelCase     :Dict          =	tf.reduce_mean(__lowerCamelCase	)
			# Add the training-time loss value to the layer using `self.add_loss()`.
			self.add_loss(__lowerCamelCase	)

			# Log the loss as a metric (we could log arbitrary metrics,
			# including different metrics for training and inference.
			self.add_metric(__lowerCamelCase ,  name=self.name ,  aggregation="""mean""" if return_mean else """"""	)

		return out







"""simple docstring"""





def 			UpperCAmelCase__							(  SCREAMING_SNAKE_CASE     :						int							,						SCREAMING_SNAKE_CASE     :						int			):







      '''simple docstring'''




      while b:
            lowerCAmelCase						,		lowerCAmelCase  						=       b, a % b
      return a


def 			UpperCAmelCase__							(  SCREAMING_SNAKE_CASE     :						int							,						SCREAMING_SNAKE_CASE     :						int			):







      '''simple docstring'''




      return a if b == 0 else euclidean_gcd_recursive(SCREAMING_SNAKE_CASE							,						a % b			)


def 			UpperCAmelCase__							(  ):







      '''simple docstring'''




      print(F'euclidean_gcd(3, 5) = {euclidean_gcd(3							,						5			)}'			)
      print(F'euclidean_gcd(5, 3) = {euclidean_gcd(5							,						3			)}'			)
      print(F'euclidean_gcd(1, 3) = {euclidean_gcd(1							,						3			)}'			)
      print(F'euclidean_gcd(3, 6) = {euclidean_gcd(3							,						6			)}'			)
      print(F'euclidean_gcd(6, 3) = {euclidean_gcd(6							,						3			)}'			)

      print(F'euclidean_gcd_recursive(3, 5) = {euclidean_gcd_recursive(3							,						5			)}'			)
      print(F'euclidean_gcd_recursive(5, 3) = {euclidean_gcd_recursive(5							,						3			)}'			)
      print(F'euclidean_gcd_recursive(1, 3) = {euclidean_gcd_recursive(1							,						3			)}'			)
      print(F'euclidean_gcd_recursive(3, 6) = {euclidean_gcd_recursive(3							,						6			)}'			)
      print(F'euclidean_gcd_recursive(6, 3) = {euclidean_gcd_recursive(6							,						3			)}'			)


if __name__ == "__main__":
       main()






