"""simple docstring"""





import logging
import os
from typing import List, Tuple

import numpy as np
import psutil
import torch
import torch.distributed as dist

from transformers import RagRetriever


__A  =				logging.getLogger(__name__)
class  _snake_case     (					a__		):






						def __init__(       self      :			Optional[int]							,					UpperCAmelCase      :			Any							,					UpperCAmelCase      :			Any							,					UpperCAmelCase      :			Union[str, Any]							,					UpperCAmelCase      :			Union[str, Any]=None    ):
													super().__init__(
													    UpperCAmelCase							,					question_encoder_tokenizer=UpperCAmelCase							,					generator_tokenizer=UpperCAmelCase							,					index=UpperCAmelCase							,					init_retrieval=UpperCAmelCase							,					)
													__lowerCamelCase					:		Tuple		   =     None






						def       lowerCamelCase__     (       self      :			str							,					UpperCAmelCase      :			int    ):
													logger.info("initializing retrieval"    )

													# initializing a separate process group for retrieval as the default
													# nccl backend doesn't support gather/scatter operations while gloo
													# is too slow to replace nccl for the core gpu communication
													if dist.is_initialized():
																				logger.info("dist initialized"    )
																				# needs to be set manually
																				__lowerCamelCase					:		List[Any]		   =     self._infer_socket_ifname()
																				# avoid clash with the NCCL port
																				__lowerCamelCase					:		Dict		   =     str(distributed_port + 1    )
																				__lowerCamelCase					:		Optional[int]		   =     dist.new_group(ranks=UpperCAmelCase							,					backend="gloo"    )

													# initialize retriever only on the main worker
													if not dist.is_initialized() or self._is_main():
																				logger.info("dist not initialized / main"    )
																				self.index.init_index()

													# all processes wait untill the retriever is initialized by the main process
													if dist.is_initialized():
																				torch.distributed.barrier(group=self.process_group    )






						def       lowerCamelCase__     (       self      :			Dict    ):
													return dist.get_rank(group=self.process_group    ) == 0






						def       lowerCamelCase__     (       self      :			Any							,					UpperCAmelCase      :			Optional[Any]							,					UpperCAmelCase      :			str							,					UpperCAmelCase      :			Dict=torch.floataa    ):
													__lowerCamelCase					:		Any		   =     torch.empty(UpperCAmelCase							,					dtype=UpperCAmelCase    )
													dist.scatter(UpperCAmelCase							,					src=0							,					scatter_list=UpperCAmelCase							,					group=self.process_group    )
													return target_tensor






						def       lowerCamelCase__     (       self      :			int    ):
													__lowerCamelCase					:		str		   =     psutil.net_if_addrs()
													# a hacky way to deal with varying network interface names
													__lowerCamelCase					:		Union[str, Any]		   =     next((addr for addr in addrs if addr.startswith("e"    ))							,					UpperCAmelCase    )
													return ifname







						def       lowerCamelCase__     (       self      :			int							,					UpperCAmelCase      :			np.ndarray							,					UpperCAmelCase      :			int    ):

													# single GPU training
													if not dist.is_initialized():
																				__lowerCamelCase   ,  __lowerCamelCase					:		Tuple		   =     self._main_retrieve(UpperCAmelCase							,					UpperCAmelCase    )
																				return retrieved_doc_embeds, doc_ids, self.index.get_doc_dicts(UpperCAmelCase    )

													# distributed training
													__lowerCamelCase					:		Optional[int]		   =     dist.get_world_size(group=self.process_group    )

													# gather logic
													__lowerCamelCase					:		Any		   =     None
													if self._is_main():
																				__lowerCamelCase					:		List[Any]		   =     [torch.empty(question_hidden_states.shape							,					dtype=torch.floataa    ) for _ in range(UpperCAmelCase    )]
													dist.gather(torch.tensor(UpperCAmelCase    )							,					dst=0							,					gather_list=UpperCAmelCase							,					group=self.process_group    )

													# scatter logic
													__lowerCamelCase					:		Dict		   =     question_hidden_states.shape[0]
													__lowerCamelCase					:		Optional[Any]		   =     []
													__lowerCamelCase					:		List[str]		   =     []
													if self._is_main():
																				assert len(UpperCAmelCase    ) == world_size
																				__lowerCamelCase   ,  __lowerCamelCase					:		Optional[Any]		   =     self._main_retrieve(torch.cat(UpperCAmelCase    ).numpy()							,					UpperCAmelCase    )
																				__lowerCamelCase   ,  __lowerCamelCase					:		Optional[Any]		   =     torch.tensor(UpperCAmelCase    ), torch.tensor(UpperCAmelCase    )
																				__lowerCamelCase					:		List[Any]		   =     self._chunk_tensor(UpperCAmelCase							,					UpperCAmelCase    )
																				__lowerCamelCase					:		Any		   =     self._chunk_tensor(UpperCAmelCase							,					UpperCAmelCase    )
													__lowerCamelCase					:		List[Any]		   =     self._scattered(UpperCAmelCase							,					[n_queries, n_docs]							,					target_type=torch.intaa    )
													__lowerCamelCase					:		Tuple		   =     self._scattered(UpperCAmelCase							,					[n_queries, n_docs, question_hidden_states.shape[1]]    )

													return retrieved_doc_embeds.numpy(), doc_ids.numpy(), self.index.get_doc_dicts(UpperCAmelCase    )
"""simple docstring"""





import math
from datetime import datetime, timedelta


def    lowercase_   (   _lowerCamelCase:	int      ) ->      datetime:



							'''simple docstring'''

							__lowerCamelCase					:		List[Any]		   =     year % 19
							__lowerCamelCase					:		List[str]		   =     year % 4
							__lowerCamelCase					:		Dict		   =     year % 7
							__lowerCamelCase					:		Optional[Any]		   =     math.floor(year / 100      )
							__lowerCamelCase					:		Tuple		   =     math.floor((13 + 8 * leap_day_inhibits) / 25      )
							__lowerCamelCase					:		List[str]		   =     leap_day_inhibits / 4
							__lowerCamelCase					:		Optional[Any]		   =     (
							    15 - lunar_orbit_correction + leap_day_inhibits - leap_day_reinstall_number
							) % 30
							__lowerCamelCase					:		Union[str, Any]		   =     (4 + leap_day_inhibits - leap_day_reinstall_number) % 7

							# days to be added to March 21
							__lowerCamelCase					:		Union[str, Any]		   =     (19 * metonic_cycle + secular_moon_shift) % 30

							# PHM -> Paschal Full Moon
							__lowerCamelCase					:		List[Any]		   =     (
							    2 * julian_leap_year
							    + 4 * non_leap_year
							    + 6 * days_to_add
							    + century_starting_point
							) % 7

							if days_to_add == 29 and days_from_phm_to_sunday == 6:
														return datetime(_lowerCamelCase						,   4						,   19      )
							elif days_to_add == 28 and days_from_phm_to_sunday == 6:
														return datetime(_lowerCamelCase						,   4						,   18      )
							else:
														return datetime(_lowerCamelCase						,   3						,   22      ) + timedelta(
														    days=int(days_to_add + days_from_phm_to_sunday      )      )


if __name__ == "__main__":
				for year in (1994, 2000, 2010, 2021, 2023):
								__A  =				'''will be''' if year > datetime.now().year else '''was'''
								print(F"""Easter in {year} {tense} {gauss_easter(year)}""")