


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


snake_case__			 =						['''\nclass''', '''\ndef''', '''\n#''', '''\n@''', '''\nprint''', '''\nif''']


class 					lowerCAmelCase_ (       _a):




						def __init__(	self						:   str   ,     __A						:   str   ,     __A						:   List[Any]   ,     __A						:   Dict=None   ,     __A						:   Union[str, Any]=1						)      ->Union[str, Any]:






									"""simple docstring"""






									a__ :Tuple						  =    tokenizer
									a__ :Any						  =    dataset
									a__ :List[Any]						  =    len(__A						) if n_tasks is None else n_tasks
									a__ :List[str]						  =    n_copies






						def __iter__(	self						:   Any						)      ->Optional[int]:






									"""simple docstring"""






									a__ :int						  =    []
									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()						)
									a__ :Union[str, Any]						  =    self.tokenizer(__A   ,     padding=__A   ,     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 					lowerCAmelCase_ (       _a):




						def __init__(	self						:   int   ,     __A						:   str   ,     __A						:   Dict   ,     __A						:   List[str]						)      ->List[str]:






									"""simple docstring"""






									a__ :Optional[int]						  =    start_length
									a__ :Optional[Any]						  =    eof_strings
									a__ :Dict						  =    tokenizer






						def __call__(	self						:   int   ,     __A						:   Optional[Any]   ,     __A						:   Optional[Any]   ,     **__A						:   Dict						)      ->Optional[Any]:






									"""simple docstring"""






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






def 				lowerCamelCase__	(      a	:   Any				)    ->	int:





			"""simple docstring"""
			a__ :Tuple						  =    re.split("(%s)" % "|".join(a				)	,  a				)
			# last string should be ""
			return "".join(string_list[:-2]				)


def 				lowerCamelCase__	(      a	:   List[str]	,  a	:   Union[str, Any]	,  a	:   Optional[Any]	,  a	:   List[str]	,  a	:   Tuple	,  a	:   Tuple=20	,  **a	:   Any				)    ->	Any:





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

									a__  ,  a__ :Tuple						  =    accelerator.gather((generated_tokens, generated_tasks)				)
									a__ :List[Any]						  =    generated_tokens.cpu().numpy()
									a__ :List[Any]						  =    generated_tasks.cpu().numpy()

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

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


def 				lowerCamelCase__	(      )    ->	str:





			"""simple docstring"""
			# Setup configuration
			a__ :Tuple						  =    HfArgumentParser(a				)
			a__ :List[Any]						  =    parser.parse_args()

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

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

			# Use dataset load to feed to accelerate
			a__ :Union[str, Any]						  =    Accelerator()
			set_seed(args.seed	,  device_specific=a				)

			# Load model and tokenizer
			a__ :str						  =    AutoTokenizer.from_pretrained(args.model_ckpt				)
			a__ :List[str]						  =    tokenizer.eos_token
			a__ :Tuple						  =    AutoModelForCausalLM.from_pretrained(args.model_ckpt				)

			# Generation settings
			a__ :int						  =    {
			    "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	,  a	,  a				)]				),
			}

			# Load evaluation dataset and metric
			a__ :Optional[int]						  =    load_dataset("openai_humaneval"				)
			a__ :List[Any]						  =    load_metric("code_eval"				)

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

			a__ :int						  =    TokenizedDataset(a	,  human_eval["test"]	,  n_copies=a	,  n_tasks=a				)
			# do not confuse args.batch_size, which is actually the num_return_sequences
			a__ :Dict						  =    DataLoader(a	,  batch_size=1				)

			# Run a quick test to see if code evaluation is enabled
			try:
						a__ :Any						  =    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

			a__  ,  a__ :List[Any]						  =    accelerator.prepare(a	,  a				)

			a__ :Dict						  =    complete_code(
			    a	,  a	,  a	,  a	,  n_tasks=a	,  batch_size=args.batch_size	,  **a	,  )

			if accelerator.is_main_process:
						a__ :List[Any]						  =    []

						for task in tqdm(range(a				)				):
									a__ :Optional[int]						  =    human_eval["test"][task]["test"]
									a__ :Any						  =    F'''check({human_eval['test'][task]['entry_point']})'''
									references.append("\n" + test_func + "\n" + entry_point				)

						# Evaluate completions with "code_eval" metric
						a__  ,  a__ :Any						  =    code_eval_metric.compute(
						    references=a	,  predictions=a	,  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(a	,  a				)


# 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()






def 				lowerCamelCase__	(      a	:   int	,  a	:   int				)    ->	Any:





			"""simple docstring"""
			# "extended trapezoidal rule"
			# int(f) = dx/2 * (f1 + 2f2 + ... + fn)
			a__ :Optional[int]						  =    (boundary[1] - boundary[0]) / steps
			a__ :str						  =    boundary[0]
			a__ :Optional[int]						  =    boundary[1]
			a__ :str						  =    make_points(a	,  a	,  a				)
			a__ :Any						  =    0.0
			y += (h / 2.0) * f(a				)
			for i in x_i:
						# print(i)
						y += h * f(a				)
			y += (h / 2.0) * f(a				)
			return y


def 				lowerCamelCase__	(      a	:   Any	,  a	:   str	,  a	:   Dict				)    ->	int:





			"""simple docstring"""
			a__ :Union[str, Any]						  =    a + h
			while x < (b - h):
						yield x
						a__ :str						  =    x + h


def 				lowerCamelCase__	(      a	:   Optional[int]				)    ->	List[Any]:  # enter your function here





			"""simple docstring"""
			a__ :Tuple						  =    (x - 0) * (x - 0)
			return y


def 				lowerCamelCase__	(      )    ->	List[str]:





			"""simple docstring"""
			a__ :Optional[Any]						  =    0.0  # Lower bound of integration
			a__ :Optional[Any]						  =    1.0  # Upper bound of integration
			a__ :List[str]						  =    1_0.0  # define number of steps or resolution
			a__ :int						  =    [a, b]  # define boundary of integration
			a__ :str						  =    method_a(a	,  a				)
			print(F'''y = {y}'''				)


if __name__ == "__main__":
		main()


