



'''simple docstring'''


from collections import OrderedDict
from typing import Any, Mapping, Optional

from ... import PreTrainedTokenizer
from ...configuration_utils import PretrainedConfig
from ...onnx import OnnxConfig, OnnxConfigWithPast, OnnxSeqaSeqConfigWithPast
from ...onnx.utils import compute_effective_axis_dimension
from ...utils import TensorType, is_torch_available, logging


lowercase_      :				Dict   					=    logging.get_logger(__name__)

lowercase_      :				Dict   					=    {
    '''Helsinki-NLP/opus-mt-en-de''': '''https://huggingface.co/Helsinki-NLP/opus-mt-en-de/resolve/main/config.json''',
    # See all Marian models at https://huggingface.co/models?filter=marian
}




class      __UpperCamelCase       (_UpperCAmelCase			):
	__A			  =					'''marian'''
	__A			  =					['''past_key_values''']
	__A			  =					{'''num_attention_heads''': '''encoder_attention_heads''', '''hidden_size''': '''d_model'''}







	def __init__(    self ,				_lowerCAmelCase=5_8101 ,				_lowerCAmelCase=None ,				_lowerCAmelCase=1024 ,				_lowerCAmelCase=12 ,				_lowerCAmelCase=4096 ,				_lowerCAmelCase=16 ,				_lowerCAmelCase=12 ,				_lowerCAmelCase=4096 ,				_lowerCAmelCase=16 ,				_lowerCAmelCase=0.0 ,				_lowerCAmelCase=0.0 ,				_lowerCAmelCase=True ,				_lowerCAmelCase=True ,				_lowerCAmelCase="gelu" ,				_lowerCAmelCase=1024 ,				_lowerCAmelCase=0.1 ,				_lowerCAmelCase=0.0 ,				_lowerCAmelCase=0.0 ,				_lowerCAmelCase=0.02 ,				_lowerCAmelCase=5_8100 ,				_lowerCAmelCase=False ,				_lowerCAmelCase=5_8100 ,				_lowerCAmelCase=0 ,				_lowerCAmelCase=0 ,				_lowerCAmelCase=True ,				**_lowerCAmelCase ,				)    ->    Optional[int]:
							'''simple docstring'''






							lowercase        =							vocab_size
							lowercase        =							decoder_vocab_size or vocab_size
							lowercase        =							max_position_embeddings
							lowercase        =							d_model
							lowercase        =							encoder_ffn_dim
							lowercase        =							encoder_layers
							lowercase        =							encoder_attention_heads
							lowercase        =							decoder_ffn_dim
							lowercase        =							decoder_layers
							lowercase        =							decoder_attention_heads
							lowercase        =							dropout
							lowercase        =							attention_dropout
							lowercase        =							activation_dropout
							lowercase        =							activation_function
							lowercase        =							init_std
							lowercase        =							encoder_layerdrop
							lowercase        =							decoder_layerdrop
							lowercase        =							use_cache
							lowercase        =							encoder_layers
							lowercase        =							scale_embedding  # scale factor will be sqrt(d_model) if True
							lowercase        =							share_encoder_decoder_embeddings
							super().__init__(
							    pad_token_id=_lowerCAmelCase ,				eos_token_id=_lowerCAmelCase ,				is_encoder_decoder=_lowerCAmelCase ,				decoder_start_token_id=_lowerCAmelCase ,				forced_eos_token_id=_lowerCAmelCase ,				**_lowerCAmelCase ,				)




class      __UpperCamelCase       (_UpperCAmelCase			):







	@property
	# Copied from transformers.models.bart.configuration_bart.BartOnnxConfig.inputs
	def   _a   (    self						)    ->    Mapping[str, Mapping[int, str]]:
							'''simple docstring'''






							if self.task in ["default", "seq2seq-lm"]:
													lowercase        =							OrderedDict(
													    [
													        ("""input_ids""", {0: """batch""", 1: """encoder_sequence"""}),
													        ("""attention_mask""", {0: """batch""", 1: """encoder_sequence"""}),
													    ]						)

													if self.use_past:
																			lowercase        =							{0: """batch"""}
																			lowercase        =							{0: """batch""", 1: """past_decoder_sequence + sequence"""}
													else:
																			lowercase        =							{0: """batch""", 1: """decoder_sequence"""}
																			lowercase        =							{0: """batch""", 1: """decoder_sequence"""}

													if self.use_past:
																			self.fill_with_past_key_values_(_lowerCAmelCase ,				direction="""inputs"""						)
							elif self.task == "causal-lm":
													# TODO: figure this case out.
													lowercase        =							OrderedDict(
													    [
													        ("""input_ids""", {0: """batch""", 1: """encoder_sequence"""}),
													        ("""attention_mask""", {0: """batch""", 1: """encoder_sequence"""}),
													    ]						)
													if self.use_past:
																			lowercase     ,   lowercase        =							self.num_layers
																			for i in range(_lowerCAmelCase						):
																									lowercase        =							{0: """batch""", 2: """past_sequence + sequence"""}
																									lowercase        =							{0: """batch""", 2: """past_sequence + sequence"""}
							else:
													lowercase        =							OrderedDict(
													    [
													        ("""input_ids""", {0: """batch""", 1: """encoder_sequence"""}),
													        ("""attention_mask""", {0: """batch""", 1: """encoder_sequence"""}),
													        ("""decoder_input_ids""", {0: """batch""", 1: """decoder_sequence"""}),
													        ("""decoder_attention_mask""", {0: """batch""", 1: """decoder_sequence"""}),
													    ]						)

							return common_inputs







	@property
	# Copied from transformers.models.bart.configuration_bart.BartOnnxConfig.outputs
	def   _a   (    self						)    ->    Mapping[str, Mapping[int, str]]:
							'''simple docstring'''






							if self.task in ["default", "seq2seq-lm"]:
													lowercase        =							super().outputs
							else:
													lowercase        =							super(_lowerCAmelCase ,				self						).outputs
													if self.use_past:
																			lowercase     ,   lowercase        =							self.num_layers
																			for i in range(_lowerCAmelCase						):
																									lowercase        =							{0: """batch""", 2: """past_sequence + sequence"""}
																									lowercase        =							{0: """batch""", 2: """past_sequence + sequence"""}
							return common_outputs







	def   _a   (    self ,				_lowerCAmelCase ,				_lowerCAmelCase = -1 ,				_lowerCAmelCase = -1 ,				_lowerCAmelCase = False ,				_lowerCAmelCase = None ,				)    ->    Mapping[str, Any]:
							'''simple docstring'''






							lowercase        =							self._generate_dummy_inputs_for_encoder_and_decoder(
							    _lowerCAmelCase ,				_lowerCAmelCase ,				_lowerCAmelCase ,				_lowerCAmelCase ,				_lowerCAmelCase						)

							# Generate decoder inputs
							lowercase        =							seq_length if not self.use_past else 1
							lowercase        =							self._generate_dummy_inputs_for_encoder_and_decoder(
							    _lowerCAmelCase ,				_lowerCAmelCase ,				_lowerCAmelCase ,				_lowerCAmelCase ,				_lowerCAmelCase						)
							lowercase        =							{F"""decoder_{name}""": tensor for name, tensor in decoder_inputs.items()}
							lowercase        =							dict(**_lowerCAmelCase ,				**_lowerCAmelCase						)

							if self.use_past:
													if not is_torch_available():
																			raise ValueError("""Cannot generate dummy past_keys inputs without PyTorch installed."""						)
													else:
																			import torch
													lowercase     ,   lowercase        =							common_inputs["""input_ids"""].shape
													lowercase        =							common_inputs["""decoder_input_ids"""].shape[1]
													lowercase     ,   lowercase        =							self.num_attention_heads
													lowercase        =							(
													    batch,
													    num_encoder_attention_heads,
													    encoder_seq_length,
													    self._config.hidden_size // num_encoder_attention_heads,
													)
													lowercase        =							decoder_seq_length + 3
													lowercase        =							(
													    batch,
													    num_decoder_attention_heads,
													    decoder_past_length,
													    self._config.hidden_size // num_decoder_attention_heads,
													)

													lowercase        =							torch.cat(
													    [common_inputs["""decoder_attention_mask"""], torch.ones(_lowerCAmelCase ,				_lowerCAmelCase						)] ,				dim=1						)

													lowercase        =							[]
													# If the number of encoder and decoder layers are present in the model configuration, both are considered
													lowercase     ,   lowercase        =							self.num_layers
													lowercase        =							min(_lowerCAmelCase ,				_lowerCAmelCase						)
													lowercase        =							max(_lowerCAmelCase ,				_lowerCAmelCase						) - min_num_layers
													lowercase        =							"""encoder""" if num_encoder_layers > num_decoder_layers else """decoder"""

													for _ in range(_lowerCAmelCase						):
																			common_inputs["past_key_values"].append(
																			    (
																			        torch.zeros(_lowerCAmelCase						),
																			        torch.zeros(_lowerCAmelCase						),
																			        torch.zeros(_lowerCAmelCase						),
																			        torch.zeros(_lowerCAmelCase						),
																			    )						)
													# TODO: test this.
													lowercase        =							encoder_shape if remaining_side_name == """encoder""" else decoder_shape
													for _ in range(_lowerCAmelCase ,				_lowerCAmelCase						):
																			common_inputs["past_key_values"].append((torch.zeros(_lowerCAmelCase						), torch.zeros(_lowerCAmelCase						))						)
							return common_inputs







	def   _a   (    self ,				_lowerCAmelCase ,				_lowerCAmelCase = -1 ,				_lowerCAmelCase = -1 ,				_lowerCAmelCase = False ,				_lowerCAmelCase = None ,				)    ->    Mapping[str, Any]:
							'''simple docstring'''






							lowercase        =							self._generate_dummy_inputs_for_encoder_and_decoder(
							    _lowerCAmelCase ,				_lowerCAmelCase ,				_lowerCAmelCase ,				_lowerCAmelCase ,				_lowerCAmelCase						)

							if self.use_past:
													if not is_torch_available():
																			raise ValueError("""Cannot generate dummy past_keys inputs without PyTorch installed."""						)
													else:
																			import torch
													lowercase     ,   lowercase        =							common_inputs["""input_ids"""].shape
													# Not using the same length for past_key_values
													lowercase        =							seqlen + 2
													lowercase     ,   lowercase        =							self.num_layers
													lowercase     ,   lowercase        =							self.num_attention_heads
													lowercase        =							(
													    batch,
													    num_encoder_attention_heads,
													    past_key_values_length,
													    self._config.hidden_size // num_encoder_attention_heads,
													)

													lowercase        =							common_inputs["""attention_mask"""].dtype
													lowercase        =							torch.cat(
													    [common_inputs["""attention_mask"""], torch.ones(_lowerCAmelCase ,				_lowerCAmelCase ,				dtype=_lowerCAmelCase						)] ,				dim=1						)
													lowercase        =							[
													    (torch.zeros(_lowerCAmelCase						), torch.zeros(_lowerCAmelCase						)) for _ in range(_lowerCAmelCase						)
													]
							return common_inputs







	def   _a   (    self ,				_lowerCAmelCase ,				_lowerCAmelCase = -1 ,				_lowerCAmelCase = -1 ,				_lowerCAmelCase = False ,				_lowerCAmelCase = None ,				)    ->    Mapping[str, Any]:
							'''simple docstring'''






							lowercase        =							compute_effective_axis_dimension(
							    _lowerCAmelCase ,				fixed_dimension=OnnxConfig.default_fixed_batch ,				num_token_to_add=0						)

							# If dynamic axis (-1) we forward with a fixed dimension of 8 tokens to avoid optimizations made by ONNX
							lowercase        =							tokenizer.num_special_tokens_to_add(_lowerCAmelCase						)
							lowercase        =							compute_effective_axis_dimension(
							    _lowerCAmelCase ,				fixed_dimension=OnnxConfig.default_fixed_sequence ,				num_token_to_add=_lowerCAmelCase						)

							# Generate dummy inputs according to compute batch and sequence
							lowercase        =							[""" """.join([tokenizer.unk_token]						) * seq_length] * batch_size
							lowercase        =							dict(tokenizer(_lowerCAmelCase ,				return_tensors=_lowerCAmelCase						)						)
							return common_inputs







	def   _a   (    self ,				_lowerCAmelCase ,				_lowerCAmelCase = -1 ,				_lowerCAmelCase = -1 ,				_lowerCAmelCase = False ,				_lowerCAmelCase = None ,				)    ->    Mapping[str, Any]:
							'''simple docstring'''






							if self.task in ["default", "seq2seq-lm"]:
													lowercase        =							self._generate_dummy_inputs_for_default_and_seqaseq_lm(
													    _lowerCAmelCase ,				batch_size=_lowerCAmelCase ,				seq_length=_lowerCAmelCase ,				is_pair=_lowerCAmelCase ,				framework=_lowerCAmelCase						)

							else:
													lowercase        =							self._generate_dummy_inputs_for_causal_lm(
													    _lowerCAmelCase ,				batch_size=_lowerCAmelCase ,				seq_length=_lowerCAmelCase ,				is_pair=_lowerCAmelCase ,				framework=_lowerCAmelCase						)

							return common_inputs







	def   _a   (    self ,				_lowerCAmelCase ,				_lowerCAmelCase ,				_lowerCAmelCase ,				_lowerCAmelCase						)    ->    List[str]:
							'''simple docstring'''






							if self.task in ["default", "seq2seq-lm"]:
													lowercase        =							super()._flatten_past_key_values_(_lowerCAmelCase ,				_lowerCAmelCase ,				_lowerCAmelCase ,				_lowerCAmelCase						)
							else:
													lowercase        =							super(_lowerCAmelCase ,				self						)._flatten_past_key_values_(
													    _lowerCAmelCase ,				_lowerCAmelCase ,				_lowerCAmelCase ,				_lowerCAmelCase						)







	@property
	def   _a   (    self						)    ->    float:
							'''simple docstring'''






							return 1E-4







'''simple docstring'''


from random import shuffle

import tensorflow as tf
from numpy import array







def      SCREAMING_SNAKE_CASE				(				lowercase_    :      List[str] ,  lowercase_    :      Optional[int]						):
						lowercase        =							int(lowercase_						)
						assert noofclusters < len(lowercase_						)

						# Find out the dimensionality
						lowercase        =							len(vectors[0]						)

						# Will help select random centroids from among the available vectors
						lowercase        =							list(range(len(lowercase_						)						)						)
						shuffle(lowercase_						)

						# GRAPH OF COMPUTATION
						# We initialize a new graph and set it as the default during each run
						# of this algorithm. This ensures that as this function is called
						# multiple times, the default graph doesn't keep getting crowded with
						# unused ops and Variables from previous function calls.

						lowercase        =							tf.Graph()

						with graph.as_default():
												# SESSION OF COMPUTATION

												lowercase        =							tf.Session()

												##CONSTRUCTING THE ELEMENTS OF COMPUTATION

												##First lets ensure we have a Variable vector for each centroid,
												##initialized to one of the vectors from the available data points
												lowercase        =							[
												    tf.Variable(vectors[vector_indices[i]]						) for i in range(lowercase_						)
												]
												##These nodes will assign the centroid Variables the appropriate
												##values
												lowercase        =							tf.placeholder("""float64""" ,  [dim]						)
												lowercase        =							[]
												for centroid in centroids:
																		cent_assigns.append(tf.assign(lowercase_ ,  lowercase_						)						)

												##Variables for cluster assignments of individual vectors(initialized
												##to 0 at first)
												lowercase        =							[tf.Variable(0						) for i in range(len(lowercase_						)						)]
												##These nodes will assign an assignment Variable the appropriate
												##value
												lowercase        =							tf.placeholder("""int32"""						)
												lowercase        =							[]
												for assignment in assignments:
																		cluster_assigns.append(tf.assign(lowercase_ ,  lowercase_						)						)

												##Now lets construct the node that will compute the mean
												# The placeholder for the input
												lowercase        =							tf.placeholder("""float""" ,  [None, dim]						)
												# The Node/op takes the input and computes a mean along the 0th
												# dimension, i.e. the list of input vectors
												lowercase        =							tf.reduce_mean(lowercase_ ,  0						)

												##Node for computing Euclidean distances
												# Placeholders for input
												lowercase        =							tf.placeholder("""float""" ,  [dim]						)
												lowercase        =							tf.placeholder("""float""" ,  [dim]						)
												lowercase        =							tf.sqrt(tf.reduce_sum(tf.pow(tf.sub(lowercase_ ,  lowercase_						) ,  2						)						)						)

												##This node will figure out which cluster to assign a vector to,
												##based on Euclidean distances of the vector from the centroids.
												# Placeholder for input
												lowercase        =							tf.placeholder("""float""" ,  [noofclusters]						)
												lowercase        =							tf.argmin(lowercase_ ,  0						)

												##INITIALIZING STATE VARIABLES

												##This will help initialization of all Variables defined with respect
												##to the graph. The Variable-initializer should be defined after
												##all the Variables have been constructed, so that each of them
												##will be included in the initialization.
												lowercase        =							tf.initialize_all_variables()

												# Initialize all variables
												sess.run(lowercase_						)

												##CLUSTERING ITERATIONS

												# Now perform the Expectation-Maximization steps of K-Means clustering
												# iterations. To keep things simple, we will only do a set number of
												# iterations, instead of using a Stopping Criterion.
												lowercase        =							100
												for _ in range(lowercase_						):
																		##EXPECTATION STEP
																		##Based on the centroid locations till last iteration, compute
																		##the _expected_ centroid assignments.
																		# Iterate over each vector
																		for vector_n in range(len(lowercase_						)						):
																								lowercase        =							vectors[vector_n]
																								# Compute Euclidean distance between this vector and each
																								# centroid. Remember that this list cannot be named
																								#'centroid_distances', since that is the input to the
																								# cluster assignment node.
																								lowercase        =							[
																								    sess.run(lowercase_ ,  feed_dict={va: vect, va: sess.run(lowercase_						)}						)
																								    for centroid in centroids
																								]
																								# Now use the cluster assignment node, with the distances
																								# as the input
																								lowercase        =							sess.run(
																								    lowercase_ ,  feed_dict={centroid_distances: distances}						)
																								# Now assign the value to the appropriate state variable
																								sess.run(
																								    cluster_assigns[vector_n] ,  feed_dict={assignment_value: assignment}						)

																		##MAXIMIZATION STEP
																		# Based on the expected state computed from the Expectation Step,
																		# compute the locations of the centroids so as to maximize the
																		# overall objective of minimizing within-cluster Sum-of-Squares
																		for cluster_n in range(lowercase_						):
																								# Collect all the vectors assigned to this cluster
																								lowercase        =							[
																								    vectors[i]
																								    for i in range(len(lowercase_						)						)
																								    if sess.run(assignments[i]						) == cluster_n
																								]
																								# Compute new centroid location
																								lowercase        =							sess.run(
																								    lowercase_ ,  feed_dict={mean_input: array(lowercase_						)}						)
																								# Assign value to appropriate variable
																								sess.run(
																								    cent_assigns[cluster_n] ,  feed_dict={centroid_value: new_location}						)

        # Return centroids and assignments
												lowercase        =							sess.run(lowercase_						)
												lowercase        =							sess.run(lowercase_						)
												return centroids, assignments


