

from typing import Optional

import numpy as np
import torch
from torch import nn
from transformers import GPTaConfig, GPTaLMHeadModel
from transformers.modeling_utils import ModuleUtilsMixin

from ...configuration_utils import ConfigMixin, register_to_config
from ...models import ModelMixin

class     __UpperCamelCase     (       __snake_case  ,  __snake_case  ,  __snake_case    ):
	SCREAMING_SNAKE_CASE__     					=  [R"h\.\d+\.attn\.bias", R"h\.\d+\.attn\.masked_bias"]




	@register_to_config
	def __init__(		self						:    Optional[Any]		,						lowerCAmelCase						:    Any		,						lowerCAmelCase						:    Union[str, Any]		,						lowerCAmelCase						:    str = None		,						lowerCAmelCase						:    List[Any] = 50_257		,						lowerCAmelCase						:    str = 1_024		,						lowerCAmelCase						:    List[str] = 768		,						lowerCAmelCase						:    Any = 12		,						lowerCAmelCase						:    Dict = 12		,						lowerCAmelCase						:    str = None		,						lowerCAmelCase						:    Dict = "gelu_new"		,						lowerCAmelCase						:    str = 0.1		,						lowerCAmelCase						:    Optional[int] = 0.1		,						lowerCAmelCase						:    str = 0.1		,						lowerCAmelCase						:    List[str] = 1e-5		,						lowerCAmelCase						:    Union[str, Any] = 0.02		,						lowerCAmelCase						:    Union[str, Any] = True		,						lowerCAmelCase						:    str = True		,						lowerCAmelCase						:    Optional[int] = False		,						lowerCAmelCase						:    Any = False		,						):


		'''simple docstring'''







		super().__init__()

		UpperCAmelCase_												=      prefix_length

		if prefix_inner_dim != n_embd and prefix_hidden_dim is None:
			raise ValueError(
			    F"`prefix_hidden_dim` cannot be `None` when `prefix_inner_dim`: {prefix_hidden_dim} and"
			    F" `n_embd`: {n_embd} are not equal."				)

		UpperCAmelCase_												=      prefix_inner_dim
		UpperCAmelCase_												=      prefix_hidden_dim

		UpperCAmelCase_												=      (
		    nn.Linear(self.prefix_inner_dim		,						self.prefix_hidden_dim				)
		    if self.prefix_hidden_dim is not None
		    else nn.Identity()
		)
		UpperCAmelCase_												=      (
		    nn.Linear(self.prefix_hidden_dim		,						A__				) if self.prefix_hidden_dim is not None else nn.Identity()
		)

		UpperCAmelCase_												=      GPTaConfig(
		    vocab_size=A__		,						n_positions=A__		,						n_embd=A__		,						n_layer=A__		,						n_head=A__		,						n_inner=A__		,						activation_function=A__		,						resid_pdrop=A__		,						embd_pdrop=A__		,						attn_pdrop=A__		,						layer_norm_epsilon=A__		,						initializer_range=A__		,						scale_attn_weights=A__		,						use_cache=A__		,						scale_attn_by_inverse_layer_idx=A__		,						reorder_and_upcast_attn=A__		,						)
		UpperCAmelCase_												=      GPTaLMHeadModel(A__				)




	def    __A       (		self						:    Optional[Any]		,						lowerCAmelCase						:    int		,						lowerCAmelCase						:    Union[str, Any]		,						lowerCAmelCase						:    Any = None		,						lowerCAmelCase						:    Dict = None		,						):


		'''simple docstring'''







		UpperCAmelCase_												=      self.transformer.transformer.wte(A__				)
		UpperCAmelCase_												=      self.encode_prefix(A__				)
		UpperCAmelCase_												=      self.decode_prefix(A__				)
		UpperCAmelCase_												=      torch.cat((prefix_embeds, embedding_text)		,						dim=1				)

		if labels is not None:
			UpperCAmelCase_												=      self.get_dummy_token(input_ids.shape[0]		,						input_ids.device				)
			UpperCAmelCase_												=      torch.cat((dummy_token, input_ids)		,						dim=1				)
		UpperCAmelCase_												=      self.transformer(inputs_embeds=A__		,						labels=A__		,						attention_mask=A__				)
		if self.prefix_hidden_dim is not None:
			return out, hidden
		else:
			return out




	def    __A       (		self						:    int		,						lowerCAmelCase						:    Optional[Any]		,						lowerCAmelCase						:    List[Any]				):


		'''simple docstring'''







		return torch.zeros(A__		,						self.prefix_length		,						dtype=torch.intaa		,						device=A__				)




	def    __A       (		self						:    Union[str, Any]		,						lowerCAmelCase						:    Union[str, Any]				):


		'''simple docstring'''







		return self.encode_prefix(A__				)




	@torch.no_grad()
	def    __A       (		self						:    Tuple		,						lowerCAmelCase						:    List[str]		,						lowerCAmelCase						:    str		,						lowerCAmelCase						:    Tuple				):


		'''simple docstring'''







		UpperCAmelCase_												=      torch.split(A__		,						1		,						dim=0				)
		UpperCAmelCase_												=      []
		UpperCAmelCase_												=      []
		for feature in features:
			UpperCAmelCase_												=      self.decode_prefix(feature.to(A__				)				)  # back to the clip feature
			# Only support beam search for now
			UpperCAmelCase_												=      self.generate_beam(
			    input_embeds=A__		,						device=A__		,						eos_token_id=A__				)
			generated_tokens.append(output_tokens[0]				)
			generated_seq_lengths.append(seq_lengths[0]				)
		UpperCAmelCase_												=      torch.stack(A__				)
		UpperCAmelCase_												=      torch.stack(A__				)
		return generated_tokens, generated_seq_lengths




	@torch.no_grad()
	def    __A       (		self						:    Tuple		,						lowerCAmelCase						:    Optional[int]=None		,						lowerCAmelCase						:    List[str]=None		,						lowerCAmelCase						:    Any=None		,						lowerCAmelCase						:    Optional[int] = 5		,						lowerCAmelCase						:    Optional[int] = 67		,						lowerCAmelCase						:    List[str] = 1.0		,						lowerCAmelCase						:    Tuple = None		,						):


		'''simple docstring'''







		UpperCAmelCase_												=      eos_token_id
		UpperCAmelCase_												=      None
		UpperCAmelCase_												=      None
		UpperCAmelCase_												=      torch.ones(A__		,						device=A__		,						dtype=torch.int				)
		UpperCAmelCase_												=      torch.zeros(A__		,						device=A__		,						dtype=torch.bool				)

		if input_embeds is not None:
			UpperCAmelCase_												=      input_embeds
		else:
			UpperCAmelCase_												=      self.transformer.transformer.wte(A__				)

		for i in range(A__				):
			UpperCAmelCase_												=      self.transformer(inputs_embeds=A__				)
			UpperCAmelCase_												=      outputs.logits
			UpperCAmelCase_												=      logits[:, -1, :] / (temperature if temperature > 0 else 1.0)
			UpperCAmelCase_												=      logits.softmax(-1				).log()

			if scores is None:
				UpperCAmelCase_												=      logits.topk(A__		,						-1				)
				UpperCAmelCase_												=      generated.expand(A__		,						*generated.shape[1:]				)
				UpperCAmelCase_												=      next_tokens.permute(1		,						0				), scores.squeeze(0				)
				if tokens is None:
					UpperCAmelCase_												=      next_tokens
				else:
					UpperCAmelCase_												=      tokens.expand(A__		,						*tokens.shape[1:]				)
					UpperCAmelCase_												=      torch.cat((tokens, next_tokens)		,						dim=1				)
			else:
				UpperCAmelCase_												=      -float(np.inf				)
				UpperCAmelCase_												=      0
				UpperCAmelCase_												=      scores[:, None] + logits
				seq_lengths[~is_stopped] += 1
				UpperCAmelCase_												=      scores_sum / seq_lengths[:, None]
				UpperCAmelCase_												=      scores_sum_average.view(-1				).topk(A__		,						-1				)
				UpperCAmelCase_												=      next_tokens // scores_sum.shape[1]
				UpperCAmelCase_												=      seq_lengths[next_tokens_source]
				UpperCAmelCase_												=      next_tokens % scores_sum.shape[1]
				UpperCAmelCase_												=      next_tokens.unsqueeze(1				)
				UpperCAmelCase_												=      tokens[next_tokens_source]
				UpperCAmelCase_												=      torch.cat((tokens, next_tokens)		,						dim=1				)
				UpperCAmelCase_												=      generated[next_tokens_source]
				UpperCAmelCase_												=      scores_sum_average * seq_lengths
				UpperCAmelCase_												=      is_stopped[next_tokens_source]

			UpperCAmelCase_												=      self.transformer.transformer.wte(next_tokens.squeeze()				).view(generated.shape[0]		,						1		,						-1				)
			UpperCAmelCase_												=      torch.cat((generated, next_token_embed)		,						dim=1				)
			UpperCAmelCase_												=      is_stopped + next_tokens.eq(A__				).squeeze()
			if is_stopped.all():
				break

		UpperCAmelCase_												=      scores / seq_lengths
		UpperCAmelCase_												=      scores.argsort(descending=A__				)
		# tokens tensors are already padded to max_seq_length
		UpperCAmelCase_												=      [tokens[i] for i in order]
		UpperCAmelCase_												=      torch.stack(A__		,						dim=0				)
		UpperCAmelCase_												=      torch.tensor([seq_lengths[i] for i in order]		,						dtype=seq_lengths.dtype				)
		return output_texts, seq_lengths







import os
import tempfile
from functools import partial
from unittest import TestCase
from unittest.mock import patch

import numpy as np
import pytest

from datasets.arrow_dataset import Dataset
from datasets.search import ElasticSearchIndex, FaissIndex, MissingIndex

from .utils import require_elasticsearch, require_faiss


_UpperCamelCase			:	Optional[Any]								=pytest.mark.integration






@require_faiss
class 						UpperCAmelCase__ (							__snake_case							):







		def  A__      (					self		):
						_A	:				Any   =      Dataset.from_dict({'''filename''': ['''my_name-train''' + '''_''' + str(A__		) for x in np.arange(30		).tolist()]}		)
						return dset







		def  A__      (					self		):
						import faiss

						_A	:				Dataset   =      self._create_dummy_dataset()
						_A	:				List[str]   =      dset.map(
						    lambda A__       ,A__		: {"vecs": i * np.ones(5       ,dtype=np.floataa		)}       ,with_indices=A__       ,keep_in_memory=A__		)
						_A	:				Tuple   =      dset.add_faiss_index('''vecs'''       ,batch_size=100       ,metric_type=faiss.METRIC_INNER_PRODUCT		)
						_A  ,				_A	:				List[Any]   =      dset.get_nearest_examples('''vecs'''       ,np.ones(5       ,dtype=np.floataa		)		)
						self.assertEqual(examples['''filename'''][0]       ,'''my_name-train_29'''		)
						dset.drop_index('''vecs'''		)







		def  A__      (					self		):
						import faiss

						_A	:				Dataset   =      self._create_dummy_dataset()
						dset.add_faiss_index_from_external_arrays(
						    external_arrays=np.ones((30, 5)		) * np.arange(30		).reshape(-1       ,1		)       ,index_name='''vecs'''       ,batch_size=100       ,metric_type=faiss.METRIC_INNER_PRODUCT       ,)
						_A  ,				_A	:				Tuple   =      dset.get_nearest_examples('''vecs'''       ,np.ones(5       ,dtype=np.floataa		)		)
						self.assertEqual(examples['''filename'''][0]       ,'''my_name-train_29'''		)







		def  A__      (					self		):
						import faiss

						_A	:				Dataset   =      self._create_dummy_dataset()
						dset.add_faiss_index_from_external_arrays(
						    external_arrays=np.ones((30, 5)		) * np.arange(30		).reshape(-1       ,1		)       ,index_name='''vecs'''       ,metric_type=faiss.METRIC_INNER_PRODUCT       ,)

						# Setting delete=False and unlinking manually is not pretty... but it is required on Windows to
						# ensure somewhat stable behaviour. If we don't, we get PermissionErrors. This is an age-old issue.
						# see https://bugs.python.org/issue14243 and
						# https://stackoverflow.com/questions/23212435/permission-denied-to-write-to-my-temporary-file/23212515
						with tempfile.NamedTemporaryFile(delete=A__		) as tmp_file:
										dset.save_faiss_index('''vecs'''       ,tmp_file.name		)
										dset.load_faiss_index('''vecs2'''       ,tmp_file.name		)
						os.unlink(tmp_file.name		)

						_A  ,				_A	:				Optional[int]   =      dset.get_nearest_examples('''vecs2'''       ,np.ones(5       ,dtype=np.floataa		)		)
						self.assertEqual(examples['''filename'''][0]       ,'''my_name-train_29'''		)







		def  A__      (					self		):
						_A	:				Dataset   =      self._create_dummy_dataset()
						dset.add_faiss_index_from_external_arrays(
						    external_arrays=np.ones((30, 5)		) * np.arange(30		).reshape(-1       ,1		)       ,index_name='''vecs'''		)
						dset.drop_index('''vecs'''		)
						self.assertRaises(A__       ,partial(dset.get_nearest_examples       ,'''vecs2'''       ,np.ones(5       ,dtype=np.floataa		)		)		)







		def  A__      (					self		):
						from elasticsearch import Elasticsearch

						_A	:				Dataset   =      self._create_dummy_dataset()
						with patch('''elasticsearch.Elasticsearch.search'''		) as mocked_search, patch(
						    '''elasticsearch.client.IndicesClient.create'''		) as mocked_index_create, patch('''elasticsearch.helpers.streaming_bulk'''		) as mocked_bulk:
										_A	:				str   =      {'''acknowledged''': True}
										mocked_bulk.return_value([(True, None)] * 30		)
										_A	:				Optional[Any]   =      {'''hits''': {'''hits''': [{'''_score''': 1, '''_id''': 29}]}}
										_A	:				Optional[Any]   =      Elasticsearch()

										dset.add_elasticsearch_index('''filename'''       ,es_client=A__		)
										_A  ,				_A	:				Tuple   =      dset.get_nearest_examples('''filename'''       ,'''my_name-train_29'''		)
										self.assertEqual(examples['''filename'''][0]       ,'''my_name-train_29'''		)






@require_faiss
class 						UpperCAmelCase__ (							__snake_case							):







		def  A__      (					self		):
						import faiss

						_A	:				Union[str, Any]   =      FaissIndex(metric_type=faiss.METRIC_INNER_PRODUCT		)

						# add vectors
						index.add_vectors(np.eye(5       ,dtype=np.floataa		)		)
						self.assertIsNotNone(index.faiss_index		)
						self.assertEqual(index.faiss_index.ntotal       ,5		)
						index.add_vectors(np.zeros((5, 5)       ,dtype=np.floataa		)		)
						self.assertEqual(index.faiss_index.ntotal       ,10		)

						# single query
						_A	:				str   =      np.zeros(5       ,dtype=np.floataa		)
						_A	:				Dict   =      1
						_A  ,				_A	:				Optional[int]   =      index.search(A__		)
						self.assertRaises(A__       ,index.search       ,query.reshape(-1       ,1		)		)
						self.assertGreater(scores[0]       ,0		)
						self.assertEqual(indices[0]       ,1		)

						# batched queries
						_A	:				Optional[Any]   =      np.eye(5       ,dtype=np.floataa		)[::-1]
						_A  ,				_A	:				Dict   =      index.search_batch(A__		)
						self.assertRaises(A__       ,index.search_batch       ,queries[0]		)
						_A	:				Tuple   =      [scores[0] for scores in total_scores]
						_A	:				List[str]   =      [indices[0] for indices in total_indices]
						self.assertGreater(np.min(A__		)       ,0		)
						self.assertListEqual([4, 3, 2, 1, 0]       ,A__		)







		def  A__      (					self		):
						import faiss

						_A	:				List[Any]   =      FaissIndex(string_factory='''Flat'''		)
						index.add_vectors(np.eye(5       ,dtype=np.floataa		)		)
						self.assertIsInstance(index.faiss_index       ,faiss.IndexFlat		)
						_A	:				str   =      FaissIndex(string_factory='''LSH'''		)
						index.add_vectors(np.eye(5       ,dtype=np.floataa		)		)
						self.assertIsInstance(index.faiss_index       ,faiss.IndexLSH		)
						with self.assertRaises(A__		):
										_A	:				List[str]   =      FaissIndex(string_factory='''Flat'''       ,custom_index=faiss.IndexFlat(5		)		)







		def  A__      (					self		):
						import faiss

						_A	:				Any   =      faiss.IndexFlat(5		)
						_A	:				Any   =      FaissIndex(custom_index=A__		)
						index.add_vectors(np.eye(5       ,dtype=np.floataa		)		)
						self.assertIsInstance(index.faiss_index       ,faiss.IndexFlat		)







		def  A__      (					self		):
						import faiss

						_A	:				Optional[int]   =      FaissIndex(metric_type=faiss.METRIC_INNER_PRODUCT		)
						index.add_vectors(np.eye(5       ,dtype=np.floataa		)		)

						# Setting delete=False and unlinking manually is not pretty... but it is required on Windows to
						# ensure somewhat stable behaviour. If we don't, we get PermissionErrors. This is an age-old issue.
						# see https://bugs.python.org/issue14243 and
						# https://stackoverflow.com/questions/23212435/permission-denied-to-write-to-my-temporary-file/23212515
						with tempfile.NamedTemporaryFile(delete=A__		) as tmp_file:
										index.save(tmp_file.name		)
										_A	:				str   =      FaissIndex.load(tmp_file.name		)
						os.unlink(tmp_file.name		)

						_A	:				Tuple   =      np.zeros(5       ,dtype=np.floataa		)
						_A	:				Tuple   =      1
						_A  ,				_A	:				Union[str, Any]   =      index.search(A__		)
						self.assertGreater(scores[0]       ,0		)
						self.assertEqual(indices[0]       ,1		)



@require_faiss
def  a__ (__lowercase							:List[Any]   )		-> int:
				import faiss

				_A	:				Any   =      FaissIndex(metric_type=faiss.METRIC_INNER_PRODUCT   )
				index.add_vectors(np.eye(5					,  dtype=np.floataa   )   )

				_A	:				List[Any]   =      '''index.faiss'''
				_A	:				Any   =      f"""mock://{index_name}"""
				index.save(__lowercase					,  storage_options=mockfs.storage_options   )
				_A	:				Dict   =      FaissIndex.load(__lowercase					,  storage_options=mockfs.storage_options   )

				_A	:				Tuple   =      np.zeros(5					,  dtype=np.floataa   )
				_A	:				Union[str, Any]   =      1
				_A  ,				_A	:				Optional[int]   =      index.search(__lowercase   )
				assert scores[0] > 0
				assert indices[0] == 1






@require_elasticsearch
class 						UpperCAmelCase__ (							__snake_case							):







		def  A__      (					self		):
						from elasticsearch import Elasticsearch

						with patch('''elasticsearch.Elasticsearch.search'''		) as mocked_search, patch(
						    '''elasticsearch.client.IndicesClient.create'''		) as mocked_index_create, patch('''elasticsearch.helpers.streaming_bulk'''		) as mocked_bulk:
										_A	:				Tuple   =      Elasticsearch()
										_A	:				Tuple   =      {'''acknowledged''': True}
										_A	:				int   =      ElasticSearchIndex(es_client=A__		)
										mocked_bulk.return_value([(True, None)] * 3		)
										index.add_documents(['''foo''', '''bar''', '''foobar''']		)

										# single query
										_A	:				Dict   =      '''foo'''
										_A	:				Optional[Any]   =      {'''hits''': {'''hits''': [{'''_score''': 1, '''_id''': 0}]}}
										_A  ,				_A	:				Optional[Any]   =      index.search(A__		)
										self.assertEqual(scores[0]       ,1		)
										self.assertEqual(indices[0]       ,0		)

										# single query with timeout
										_A	:				Union[str, Any]   =      '''foo'''
										_A	:				Optional[int]   =      {'''hits''': {'''hits''': [{'''_score''': 1, '''_id''': 0}]}}
										_A  ,				_A	:				Optional[int]   =      index.search(A__       ,request_timeout=30		)
										self.assertEqual(scores[0]       ,1		)
										self.assertEqual(indices[0]       ,0		)

										# batched queries
										_A	:				Dict   =      ['''foo''', '''bar''', '''foobar''']
										_A	:				Dict   =      {'''hits''': {'''hits''': [{'''_score''': 1, '''_id''': 1}]}}
										_A  ,				_A	:				Dict   =      index.search_batch(A__		)
										_A	:				Union[str, Any]   =      [scores[0] for scores in total_scores]
										_A	:				Tuple   =      [indices[0] for indices in total_indices]
										self.assertGreater(np.min(A__		)       ,0		)
										self.assertListEqual([1, 1, 1]       ,A__		)

										# batched queries with timeout
										_A	:				Union[str, Any]   =      ['''foo''', '''bar''', '''foobar''']
										_A	:				int   =      {'''hits''': {'''hits''': [{'''_score''': 1, '''_id''': 1}]}}
										_A  ,				_A	:				str   =      index.search_batch(A__       ,request_timeout=30		)
										_A	:				Dict   =      [scores[0] for scores in total_scores]
										_A	:				List[str]   =      [indices[0] for indices in total_indices]
										self.assertGreater(np.min(A__		)       ,0		)
										self.assertListEqual([1, 1, 1]       ,A__		)



