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_						=pytest.mark.integration


@require_faiss
class 							__UpperCamelCase			( __UpperCAmelCase  ):





				'''simple docstring'''



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



				def       __snake_case		( self						):
											import faiss

											lowerCAmelCase   =		self._create_dummy_dataset()
											lowerCAmelCase   =		dset.map(
											    lambda UpperCAmelCase_       , UpperCAmelCase_						: {"vecs": i * np.ones(5       , dtype=np.floataa						)}       , with_indices=__lowerCAmelCase       , keep_in_memory=__lowerCAmelCase						)
											lowerCAmelCase   =		dset.add_faiss_index('''vecs'''       , batch_size=1_00       , metric_type=faiss.METRIC_INNER_PRODUCT						)
											lowerCAmelCase   ,     lowerCAmelCase   =		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       __snake_case		( self						):
											import faiss

											lowerCAmelCase   =		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=1_00       , metric_type=faiss.METRIC_INNER_PRODUCT       , )
											lowerCAmelCase   ,     lowerCAmelCase   =		dset.get_nearest_examples('''vecs'''       , np.ones(5       , dtype=np.floataa						)						)
											self.assertEqual(examples['''filename'''][0]       , '''my_name-train_29'''						)



				def       __snake_case		( self						):
											import faiss

											lowerCAmelCase   =		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=__lowerCAmelCase						) as tmp_file:
																		dset.save_faiss_index('''vecs'''       , tmp_file.name						)
																		dset.load_faiss_index('''vecs2'''       , tmp_file.name						)
											os.unlink(tmp_file.name						)

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



				def       __snake_case		( self						):
											lowerCAmelCase   =		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(__lowerCAmelCase       , partial(dset.get_nearest_examples       , '''vecs2'''       , np.ones(5       , dtype=np.floataa						)						)						)






				def       __snake_case		( self						):
											from elasticsearch import Elasticsearch

											lowerCAmelCase   =		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:
																		lowerCAmelCase   =		{'''acknowledged''': True}
																		mocked_bulk.return_value([(True, None)] * 30						)
																		lowerCAmelCase   =		{'''hits''': {'''hits''': [{'''_score''': 1, '''_id''': 29}]}}
																		lowerCAmelCase   =		Elasticsearch()

																		dset.add_elasticsearch_index('''filename'''       , es_client=__lowerCAmelCase						)
																		lowerCAmelCase   ,     lowerCAmelCase   =		dset.get_nearest_examples('''filename'''       , '''my_name-train_29'''						)
																		self.assertEqual(examples['''filename'''][0]       , '''my_name-train_29'''						)




@require_faiss
class 							__UpperCamelCase			( __UpperCAmelCase  ):





				'''simple docstring'''



				def       __snake_case		( self						):
											import faiss

											lowerCAmelCase   =		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
											lowerCAmelCase   =		np.zeros(5       , dtype=np.floataa						)
											lowerCAmelCase   =		1
											lowerCAmelCase   ,     lowerCAmelCase   =		index.search(__lowerCAmelCase						)
											self.assertRaises(__lowerCAmelCase       , index.search       , query.reshape(-1       , 1						)						)
											self.assertGreater(scores[0]       , 0						)
											self.assertEqual(indices[0]       , 1						)

											# batched queries
											lowerCAmelCase   =		np.eye(5       , dtype=np.floataa						)[::-1]
											lowerCAmelCase   ,     lowerCAmelCase   =		index.search_batch(__lowerCAmelCase						)
											self.assertRaises(__lowerCAmelCase       , index.search_batch       , queries[0]						)
											lowerCAmelCase   =		[scores[0] for scores in total_scores]
											lowerCAmelCase   =		[indices[0] for indices in total_indices]
											self.assertGreater(np.min(__lowerCAmelCase						)       , 0						)
											self.assertListEqual([4, 3, 2, 1, 0]       , __lowerCAmelCase						)



				def       __snake_case		( self						):
											import faiss

											lowerCAmelCase   =		FaissIndex(string_factory='''Flat'''						)
											index.add_vectors(np.eye(5       , dtype=np.floataa						)						)
											self.assertIsInstance(index.faiss_index       , faiss.IndexFlat						)
											lowerCAmelCase   =		FaissIndex(string_factory='''LSH'''						)
											index.add_vectors(np.eye(5       , dtype=np.floataa						)						)
											self.assertIsInstance(index.faiss_index       , faiss.IndexLSH						)
											with self.assertRaises(__lowerCAmelCase						):
																		lowerCAmelCase   =		FaissIndex(string_factory='''Flat'''       , custom_index=faiss.IndexFlat(5						)						)



				def       __snake_case		( self						):
											import faiss

											lowerCAmelCase   =		faiss.IndexFlat(5						)
											lowerCAmelCase   =		FaissIndex(custom_index=__lowerCAmelCase						)
											index.add_vectors(np.eye(5       , dtype=np.floataa						)						)
											self.assertIsInstance(index.faiss_index       , faiss.IndexFlat						)






				def       __snake_case		( self						):
											import faiss

											lowerCAmelCase   =		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=__lowerCAmelCase						) as tmp_file:
																		index.save(tmp_file.name						)
																		lowerCAmelCase   =		FaissIndex.load(tmp_file.name						)
											os.unlink(tmp_file.name						)

											lowerCAmelCase   =		np.zeros(5       , dtype=np.floataa						)
											lowerCAmelCase   =		1
											lowerCAmelCase   ,     lowerCAmelCase   =		index.search(__lowerCAmelCase						)
											self.assertGreater(scores[0]       , 0						)
											self.assertEqual(indices[0]       , 1						)




@require_faiss
def       UpperCAmelCase       (     _snake_case							):
							import faiss

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

							lowerCAmelCase   =		'''index.faiss'''
							lowerCAmelCase   =		F"""mock://{index_name}"""
							index.save(__snake_case						, storage_options=mockfs.storage_options							)
							lowerCAmelCase   =		FaissIndex.load(__snake_case						, storage_options=mockfs.storage_options							)

							lowerCAmelCase   =		np.zeros(5						, dtype=np.floataa							)
							lowerCAmelCase   =		1
							lowerCAmelCase   ,     lowerCAmelCase   =		index.search(__snake_case							)
							assert scores[0] > 0
							assert indices[0] == 1


@require_elasticsearch
class 							__UpperCamelCase			( __UpperCAmelCase  ):





				'''simple docstring'''



				def       __snake_case		( 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:
																		lowerCAmelCase   =		Elasticsearch()
																		lowerCAmelCase   =		{'''acknowledged''': True}
																		lowerCAmelCase   =		ElasticSearchIndex(es_client=__lowerCAmelCase						)
																		mocked_bulk.return_value([(True, None)] * 3						)
																		index.add_documents(['''foo''', '''bar''', '''foobar''']						)

																		# single query
																		lowerCAmelCase   =		'''foo'''
																		lowerCAmelCase   =		{'''hits''': {'''hits''': [{'''_score''': 1, '''_id''': 0}]}}
																		lowerCAmelCase   ,     lowerCAmelCase   =		index.search(__lowerCAmelCase						)
																		self.assertEqual(scores[0]       , 1						)
																		self.assertEqual(indices[0]       , 0						)

																		# single query with timeout
																		lowerCAmelCase   =		'''foo'''
																		lowerCAmelCase   =		{'''hits''': {'''hits''': [{'''_score''': 1, '''_id''': 0}]}}
																		lowerCAmelCase   ,     lowerCAmelCase   =		index.search(__lowerCAmelCase       , request_timeout=30						)
																		self.assertEqual(scores[0]       , 1						)
																		self.assertEqual(indices[0]       , 0						)

																		# batched queries
																		lowerCAmelCase   =		['''foo''', '''bar''', '''foobar''']
																		lowerCAmelCase   =		{'''hits''': {'''hits''': [{'''_score''': 1, '''_id''': 1}]}}
																		lowerCAmelCase   ,     lowerCAmelCase   =		index.search_batch(__lowerCAmelCase						)
																		lowerCAmelCase   =		[scores[0] for scores in total_scores]
																		lowerCAmelCase   =		[indices[0] for indices in total_indices]
																		self.assertGreater(np.min(__lowerCAmelCase						)       , 0						)
																		self.assertListEqual([1, 1, 1]       , __lowerCAmelCase						)

																		# batched queries with timeout
																		lowerCAmelCase   =		['''foo''', '''bar''', '''foobar''']
																		lowerCAmelCase   =		{'''hits''': {'''hits''': [{'''_score''': 1, '''_id''': 1}]}}
																		lowerCAmelCase   ,     lowerCAmelCase   =		index.search_batch(__lowerCAmelCase       , request_timeout=30						)
																		lowerCAmelCase   =		[scores[0] for scores in total_scores]
																		lowerCAmelCase   =		[indices[0] for indices in total_indices]
																		self.assertGreater(np.min(__lowerCAmelCase						)       , 0						)
																		self.assertListEqual([1, 1, 1]       , __lowerCAmelCase						)









from ...configuration_utils import PretrainedConfig
from ...utils import logging


UpperCAmelCase_						=logging.get_logger(__name__)

UpperCAmelCase_						={
    """google/switch-base-8""": """https://huggingface.co/google/switch-base-8/blob/main/config.json""",
}


class 							__UpperCamelCase			( __UpperCAmelCase  ):





				'''simple docstring'''



				__a							: Any										="""switch_transformers"""
				__a							: Union[str, Any]										=["""past_key_values"""]
				__a							: Dict										={"""hidden_size""": """d_model""", """num_attention_heads""": """num_heads""", """num_hidden_layers""": """num_layers"""}



				def __init__( self       , UpperCAmelCase_=3_21_28       , UpperCAmelCase_=7_68       , UpperCAmelCase_=64       , UpperCAmelCase_=20_48       , UpperCAmelCase_=64       , UpperCAmelCase_=12       , UpperCAmelCase_=3       , UpperCAmelCase_=12       , UpperCAmelCase_=3       , UpperCAmelCase_=12       , UpperCAmelCase_=8       , UpperCAmelCase_=False       , UpperCAmelCase_=0.01       , UpperCAmelCase_="float32"       , UpperCAmelCase_=False       , UpperCAmelCase_=32       , UpperCAmelCase_=1_28       , UpperCAmelCase_=0.1       , UpperCAmelCase_=1E-6       , UpperCAmelCase_=0.001       , UpperCAmelCase_=0.001       , UpperCAmelCase_=1.0       , UpperCAmelCase_="relu"       , UpperCAmelCase_=True       , UpperCAmelCase_=False       , UpperCAmelCase_=True       , UpperCAmelCase_=0       , UpperCAmelCase_=1       , **UpperCAmelCase_       , ):
											lowerCAmelCase   =		vocab_size
											lowerCAmelCase   =		d_model
											lowerCAmelCase   =		d_kv
											lowerCAmelCase   =		d_ff

											lowerCAmelCase   =		num_sparse_encoder_layers

											lowerCAmelCase   =		num_layers
											lowerCAmelCase   =		(
											    num_decoder_layers if num_decoder_layers is not None else self.num_layers
											)  # default = symmetry
											lowerCAmelCase   =		num_sparse_decoder_layers

											# This tells us, each how many encoder layer we'll have to set a sparse layer.
											if self.num_sparse_encoder_layers > 0:
																		lowerCAmelCase   =		self.num_layers // self.num_sparse_encoder_layers
											else:
																		lowerCAmelCase   =		self.num_layers  # HACK: this will create 0 sparse layers

											# This tells us, each how many encoder layer we'll have to set a sparse layer.
											if self.num_sparse_decoder_layers > 0:
																		lowerCAmelCase   =		self.num_decoder_layers // self.num_sparse_decoder_layers
											else:
																		lowerCAmelCase   =		self.num_decoder_layers  # HACK: this will create 0 sparse layers

											lowerCAmelCase   =		num_heads
											lowerCAmelCase   =		num_experts
											lowerCAmelCase   =		expert_capacity
											lowerCAmelCase   =		router_bias
											lowerCAmelCase   =		router_jitter_noise
											if router_dtype not in ["float32", "float16", "bfloat16"]:
																		raise ValueError(F"""`router_dtype` must be one of 'float32', 'float16' or 'bfloat16', got {router_dtype}"""						)
											lowerCAmelCase   =		router_dtype

											lowerCAmelCase   =		router_ignore_padding_tokens
											lowerCAmelCase   =		relative_attention_num_buckets
											lowerCAmelCase   =		relative_attention_max_distance

											lowerCAmelCase   =		dropout_rate
											lowerCAmelCase   =		layer_norm_epsilon
											lowerCAmelCase   =		initializer_factor
											lowerCAmelCase   =		feed_forward_proj
											lowerCAmelCase   =		use_cache
											lowerCAmelCase   =		add_router_probs

											lowerCAmelCase   =		router_z_loss_coef
											lowerCAmelCase   =		router_aux_loss_coef

											lowerCAmelCase   =		self.feed_forward_proj.split('''-'''						)
											lowerCAmelCase   =		act_info[-1]
											lowerCAmelCase   =		act_info[0] == '''gated'''

											if len(UpperCAmelCase_						) > 1 and act_info[0] != "gated" or len(UpperCAmelCase_						) > 2:
																		raise ValueError(
																		    F"""`feed_forward_proj`: {feed_forward_proj} is not a valid activation function of the dense layer."""
																		    '''Please make sure `feed_forward_proj` is of the format `gated-{ACT_FN}` or `{ACT_FN}`, e.g. '''
																		    '''\'gated-gelu\' or \'relu\''''						)

											# for backwards compatibility
											if feed_forward_proj == "gated-gelu":
																		lowerCAmelCase   =		'''gelu_new'''

											super().__init__(
											    pad_token_id=UpperCAmelCase_       , eos_token_id=UpperCAmelCase_       , is_encoder_decoder=UpperCAmelCase_       , **UpperCAmelCase_       , )



