


import json
import multiprocessing
import os
import re
from collections import defaultdict

import torch
from accelerate import Accelerator
from accelerate.utils import set_seed
from arguments import HumanEvalArguments
from datasets import load_dataset, load_metric
from torch.utils.data import IterableDataset
from torch.utils.data.dataloader import DataLoader
from tqdm import tqdm

import transformers
from transformers import AutoModelForCausalLM, AutoTokenizer, HfArgumentParser, StoppingCriteria, StoppingCriteriaList


A	:		Any    =       ['\nclass', '\ndef', '\n#', '\n@', '\nprint', '\nif']



class 							A   (	lowercase__							):
					'''simple docstring'''






					def __init__(self   :						int				, _UpperCAmelCase   :						Optional[Any]				, _UpperCAmelCase   :						List[str]				, _UpperCAmelCase   :						List[Any]=None				, _UpperCAmelCase   :						Tuple=1		)						->       Union[str, Any]:




							"""simple docstring"""


							lowercase__					      =		tokenizer
							lowercase__					      =		dataset
							lowercase__					      =		len(lowercase_		) if n_tasks is None else n_tasks
							lowercase__					      =		n_copies


					def __iter__(self   :						str		)						->       Union[str, Any]:




							"""simple docstring"""


							lowercase__					      =		[]
							for task in range(self.n_tasks		):
									# without strip, the model generate commented codes ...
									prompts.append(self.tokenizer.eos_token + self.dataset[task]["""prompt"""].strip()		)
							lowercase__					      =		self.tokenizer(lowercase_				, padding=lowercase_				, return_tensors="""pt"""		)
							for task in range(self.n_tasks		):
									for _ in range(self.n_copies		):
											yield {
											    "ids": outputs.input_ids[task],
											    "task_id": task,
											    "input_len": outputs.attention_mask[task].sum(),
											}






class 							A   (	lowercase__							):
					'''simple docstring'''






					def __init__(self   :						Optional[int]				, _UpperCAmelCase   :						str				, _UpperCAmelCase   :						Optional[Any]				, _UpperCAmelCase   :						int		)						->       List[Any]:




							"""simple docstring"""


							lowercase__					      =		start_length
							lowercase__					      =		eof_strings
							lowercase__					      =		tokenizer


					def __call__(self   :						List[str]				, _UpperCAmelCase   :						Optional[Any]				, _UpperCAmelCase   :						Tuple				, **_UpperCAmelCase   :						List[Any]		)						->       List[str]:




							"""simple docstring"""


							lowercase__					      =		self.tokenizer.batch_decode(input_ids[:, self.start_length :]		)
							lowercase__					      =		[]
							for decoded_generation in decoded_generations:
									done.append(any(stop_string in decoded_generation for stop_string in self.eof_strings		)		)
							return all(lowercase_		)






def 			UpperCamelCase (     __magic_name__					:							Optional[Any]					)       ->  Any:
		"""simple docstring"""




		lowercase__					      =		re.split("""(%s)""" % """|""".join(__lowerCamelCase					)   ,   __lowerCamelCase					)
		# last string should be ""
		return "".join(string_list[:-2]					)






def 			UpperCamelCase (     __magic_name__					:							List[str]   ,   __magic_name__					:							int   ,   __magic_name__					:							Any   ,   __magic_name__					:							List[str]   ,   __magic_name__					:							List[str]   ,   __magic_name__					:							Dict=20   ,   **__magic_name__					:							int					)       ->  int:
		"""simple docstring"""




		lowercase__					      =		defaultdict(__lowerCamelCase					)  # dict of list of generated tokens
		for step, batch in tqdm(enumerate(__lowerCamelCase					)					):
				with torch.no_grad():
						lowercase__					      =		batch["ids"].shape[-1]
						lowercase__					      =		accelerator.unwrap_model(__lowerCamelCase					).generate(
						    input_ids=batch["""ids"""][:, : batch["""input_len"""]]   ,   num_return_sequences=__lowerCamelCase   ,   **__lowerCamelCase					)
						# each task is generated batch_size times
						lowercase__					      =		batch["task_id"].repeat(__lowerCamelCase					)
						lowercase__					      =		accelerator.pad_across_processes(
						    __lowerCamelCase   ,   dim=1   ,   pad_index=tokenizer.pad_token_id					)

						lowercase__					      =		accelerator.gather((generated_tokens, generated_tasks)					)
						lowercase__					      =		generated_tokens.cpu().numpy()
						lowercase__					      =		generated_tasks.cpu().numpy()

						for task, generated_tokens in zip(__lowerCamelCase   ,   __lowerCamelCase					):
								gen_token_dict[task].append(__lowerCamelCase					)

		lowercase__					      =		[[] for _ in range(__lowerCamelCase					)]
		for task, generated_tokens in gen_token_dict.items():
				for s in generated_tokens:
						lowercase__					      =		tokenizer.decode(__lowerCamelCase   ,   skip_special_tokens=__lowerCamelCase   ,   clean_up_tokenization_spaces=__lowerCamelCase					)
						code_gens[task].append(remove_last_block(__lowerCamelCase					)					)
		return code_gens






def 			UpperCamelCase (     )       ->  Union[str, Any]:
		"""simple docstring"""




		lowercase__					      =		HfArgumentParser(__lowerCamelCase					)
		lowercase__					      =		parser.parse_args()

		transformers.logging.set_verbosity_error()
		# enables code execution in code_eval metric
		lowercase__					      =		args.HF_ALLOW_CODE_EVAL
		# make sure tokenizer plays nice with multiprocessing
		lowercase__					      =		"false"

		if args.num_workers is None:
				lowercase__					      =		multiprocessing.cpu_count()

		# Use dataset load to feed to accelerate
		lowercase__					      =		Accelerator()
		set_seed(args.seed   ,   device_specific=__lowerCamelCase					)

		# Load model and tokenizer
		lowercase__					      =		AutoTokenizer.from_pretrained(args.model_ckpt					)
		lowercase__					      =		tokenizer.eos_token
		lowercase__					      =		AutoModelForCausalLM.from_pretrained(args.model_ckpt					)

		# Generation settings
		lowercase__					      =		{
		    "do_sample": args.do_sample,
		    "temperature": args.temperature,
		    "max_new_tokens": args.max_new_tokens,
		    "top_p": args.top_p,
		    "top_k": args.top_k,
		    "stopping_criteria": StoppingCriteriaList([EndOfFunctionCriteria(0   ,   __lowerCamelCase   ,   __lowerCamelCase					)]					),
		}

		# Load evaluation dataset and metric
		lowercase__					      =		load_dataset("""openai_humaneval"""					)
		lowercase__					      =		load_metric("""code_eval"""					)

		lowercase__					      =		args.num_tasks if args.num_tasks is not None else len(human_eval["""test"""]					)
		lowercase__					      =		args.n_samples // args.batch_size

		lowercase__					      =		TokenizedDataset(__lowerCamelCase   ,   human_eval["""test"""]   ,   n_copies=__lowerCamelCase   ,   n_tasks=__lowerCamelCase					)
		# do not confuse args.batch_size, which is actually the num_return_sequences
		lowercase__					      =		DataLoader(__lowerCamelCase   ,   batch_size=1					)

		# Run a quick test to see if code evaluation is enabled
		try:
				lowercase__					      =		code_eval_metric.compute(references=[""""""]   ,   predictions=[[""""""]]					)
		except ValueError as exception:
				print(
				    """Code evaluation not enabled. Read the warning below carefully and then use `--HF_ALLOW_CODE_EVAL=\"1\"`"""
				    """ flag to enable code evaluation."""					)
				raise exception

		lowercase__					      =		accelerator.prepare(__lowerCamelCase   ,   __lowerCamelCase					)

		lowercase__					      =		complete_code(
		    __lowerCamelCase   ,   __lowerCamelCase   ,   __lowerCamelCase   ,   __lowerCamelCase   ,   n_tasks=__lowerCamelCase   ,   batch_size=args.batch_size   ,   **__lowerCamelCase   ,   )

		if accelerator.is_main_process:
				lowercase__					      =		[]

				for task in tqdm(range(__lowerCamelCase					)					):
						lowercase__					      =		human_eval["test"][task]["test"]
						lowercase__					      =		f'''check({human_eval["test"][task]["entry_point"]})'''
						references.append("""\n""" + test_func + """\n""" + entry_point					)

				# Evaluate completions with "code_eval" metric
				lowercase__					      =		code_eval_metric.compute(
				    references=__lowerCamelCase   ,   predictions=__lowerCamelCase   ,   num_workers=args.num_workers					)
				print(f'''Results: {pass_at_k}'''					)

				# Save results to json file
				with open(args.output_file   ,   """w"""					) as fp:
						json.dump(__lowerCamelCase   ,   __lowerCamelCase					)


# For some reason the folliwng seems to be necessary sometimes for code_eval to work nice with multiprocessing
# https://stackoverflow.com/questions/60804599/python-multiprocessing-keeps-spawning-the-whole-script
if __name__ == "__main__":
		main()





import warnings

from ...utils import logging
from .image_processing_clip import CLIPImageProcessor


A	:		List[Any]    =       logging.get_logger(__name__)



class 							A   (	UpperCAmelCase__							):
					'''simple docstring'''






					def __init__(self   :						List[Any]				, *_UpperCAmelCase   :						int				, **_UpperCAmelCase   :						List[str]		)						->       None:




							"""simple docstring"""


							warnings.warn(
							    """The class CLIPFeatureExtractor is deprecated and will be removed in version 5 of Transformers. Please"""
							    """ use CLIPImageProcessor instead."""				, _UpperCAmelCase				, )
							super().__init__(*_UpperCAmelCase				, **_UpperCAmelCase		)

