






"""simple docstring"""





import mpmath  # for roots of unity
import numpy as np






class      a						:






    def __init__(       self     :							Optional[Any]       ,						__SCREAMING_SNAKE_CASE     :							Optional[Any]=None       ,						__SCREAMING_SNAKE_CASE     :							List[Any]=None					)     ->		Any:
      # Input as list
      lowerCamelCase_         =						list(poly_a or [0]					)[:]
      lowerCamelCase_         =						list(poly_b or [0]					)[:]

      # Remove leading zero coefficients
      while self.polyA[-1] == 0:
        self.polyA.pop()
      lowerCamelCase_         =						len(self.polyA					)

      while self.polyB[-1] == 0:
        self.polyB.pop()
      lowerCamelCase_         =						len(self.polyB					)

      # Add 0 to make lengths equal a power of 2
      lowerCamelCase_         =						int(
          2 ** np.ceil(np.loga(len(self.polyA					) + len(self.polyB					) - 1					)					)					)

      while len(self.polyA					) < self.c_max_length:
        self.polyA.append(0					)
      while len(self.polyB					) < self.c_max_length:
        self.polyB.append(0					)
      # A complex root used for the fourier transform
      lowerCamelCase_         =						complex(mpmath.root(x=1       ,						n=self.c_max_length       ,						k=1					)					)

      # The product
      lowerCamelCase_         =						self.__multiply()






    def    UpperCamelCase       (       self     :							int       ,						__SCREAMING_SNAKE_CASE     :							int					)     ->		Optional[Any]:
      lowerCamelCase_         =						[[x] for x in self.polyA] if which == 'A' else [[x] for x in self.polyB]
      # Corner case
      if len(__SCREAMING_SNAKE_CASE					) <= 1:
        return dft[0]
      #
      lowerCamelCase_         =						self.c_max_length // 2
      while next_ncol > 0:
        lowerCamelCase_         =						[[] for i in range(__SCREAMING_SNAKE_CASE					)]
        lowerCamelCase_         =						self.root**next_ncol

        # First half of next step
        lowerCamelCase_         =						1
        for j in range(self.c_max_length // (next_ncol * 2)					):
          for i in range(__SCREAMING_SNAKE_CASE					):
            new_dft[i].append(dft[i][j] + current_root * dft[i + next_ncol][j]					)
          current_root *= root
        # Second half of next step
        lowerCamelCase_         =						1
        for j in range(self.c_max_length // (next_ncol * 2)					):
          for i in range(__SCREAMING_SNAKE_CASE					):
            new_dft[i].append(dft[i][j] - current_root * dft[i + next_ncol][j]					)
          current_root *= root
        # Update
        lowerCamelCase_         =						new_dft
        lowerCamelCase_         =						next_ncol // 2
      return dft[0]






    def    UpperCamelCase       (       self     :							List[Any]					)     ->		List[str]:
      lowerCamelCase_         =						self.__dft('A'					)
      lowerCamelCase_         =						self.__dft('B'					)
      lowerCamelCase_         =						[[dft_a[i] * dft_b[i] for i in range(self.c_max_length					)]]
      del dft_a
      del dft_b

      # Corner Case
      if len(inverce_c[0]					) <= 1:
        return inverce_c[0]
      # Inverse DFT
      lowerCamelCase_         =						2
      while next_ncol <= self.c_max_length:
        lowerCamelCase_         =						[[] for i in range(__SCREAMING_SNAKE_CASE					)]
        lowerCamelCase_         =						self.root ** (next_ncol // 2)
        lowerCamelCase_         =						1
        # First half of next step
        for j in range(self.c_max_length // next_ncol					):
          for i in range(next_ncol // 2					):
            # Even positions
            new_inverse_c[i].append(
                (
                    inverce_c[i][j]
                    + inverce_c[i][j + self.c_max_length // next_ncol]
                )
                / 2					)
            # Odd positions
            new_inverse_c[i + next_ncol // 2].append(
                (
                    inverce_c[i][j]
                    - inverce_c[i][j + self.c_max_length // next_ncol]
                )
                / (2 * current_root)					)
          current_root *= root
        # Update
        lowerCamelCase_         =						new_inverse_c
        next_ncol *= 2
      # Unpack
      lowerCamelCase_         =						[round(x[0].real       ,						8					) + round(x[0].imag       ,						8					) * 1J for x in inverce_c]

      # Remove leading 0's
      while inverce_c[-1] == 0:
        inverce_c.pop()
      return inverce_c






    def __str__(       self     :							Union[str, Any]					)     ->		Dict:
      lowerCamelCase_         =						'A = ' + ' + '.join(
          F'''{coef}*x^{i}''' for coef, i in enumerate(self.polyA[: self.len_A]					)					)
      lowerCamelCase_         =						'B = ' + ' + '.join(
          F'''{coef}*x^{i}''' for coef, i in enumerate(self.polyB[: self.len_B]					)					)
      lowerCamelCase_         =						'A*B = ' + ' + '.join(
          F'''{coef}*x^{i}''' for coef, i in enumerate(self.product					)					)

      return F'''{a}\n{b}\n{c}'''


# Unit tests
if __name__ == "__main__":
  import doctest

  doctest.testmod()












"""simple docstring"""





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


_SCREAMING_SNAKE_CASE					:				Union[str, Any]					    =						['''\nclass''', '''\ndef''', '''\n#''', '''\n@''', '''\nprint''', '''\nif''']






class      a						(					__snake_case		):






    def __init__(       self     :							Dict       ,						__SCREAMING_SNAKE_CASE     :							Any       ,						__SCREAMING_SNAKE_CASE     :							Optional[Any]       ,						__SCREAMING_SNAKE_CASE     :							Any=None       ,						__SCREAMING_SNAKE_CASE     :							Tuple=1					)     ->		str:
      lowerCamelCase_         =						tokenizer
      lowerCamelCase_         =						dataset
      lowerCamelCase_         =						len(__SCREAMING_SNAKE_CASE					) if n_tasks is None else n_tasks
      lowerCamelCase_         =						n_copies






    def __iter__(       self     :							Dict					)     ->		Any:
      lowerCamelCase_         =						[]
      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()					)
      lowerCamelCase_         =						self.tokenizer(__SCREAMING_SNAKE_CASE       ,						padding=__SCREAMING_SNAKE_CASE       ,						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						(					__snake_case		):






    def __init__(       self     :							Union[str, Any]       ,						__SCREAMING_SNAKE_CASE     :							str       ,						__SCREAMING_SNAKE_CASE     :							int       ,						__SCREAMING_SNAKE_CASE     :							Any					)     ->		List[Any]:
      lowerCamelCase_         =						start_length
      lowerCamelCase_         =						eof_strings
      lowerCamelCase_         =						tokenizer






    def __call__(       self     :							Union[str, Any]       ,						__SCREAMING_SNAKE_CASE     :							Optional[int]       ,						__SCREAMING_SNAKE_CASE     :							Dict       ,						**__SCREAMING_SNAKE_CASE     :							Union[str, Any]					)     ->		Optional[Any]:
      lowerCamelCase_         =						self.tokenizer.batch_decode(input_ids[:, self.start_length :]					)
      lowerCamelCase_         =						[]
      for decoded_generation in decoded_generations:
        done.append(any(stop_string in decoded_generation for stop_string in self.eof_strings					)					)
      return all(__SCREAMING_SNAKE_CASE					)







def      lowerCamelCase__       (							_lowerCamelCase       :		List[Any] )      ->				Tuple:
  lowerCamelCase_         =						re.split('(%s)' % '|'.join(_lowerCamelCase )		,				_lowerCamelCase )
  # last string should be ""
  return "".join(string_list[:-2] )







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

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

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

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







def      lowerCamelCase__       (							)      ->				Tuple:
  # Setup configuration
  lowerCamelCase_         =						HfArgumentParser(_lowerCamelCase )
  lowerCamelCase_         =						parser.parse_args()

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

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

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

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

  # Generation settings
  lowerCamelCase_         =						{
      '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
  lowerCamelCase_         =						load_dataset('openai_humaneval' )
  lowerCamelCase_         =						load_metric('code_eval' )

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

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

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

  lowerCamelCase_     ,	lowerCamelCase_         =						accelerator.prepare(_lowerCamelCase		,				_lowerCamelCase )

  lowerCamelCase_         =						complete_code(
      _lowerCamelCase		,				_lowerCamelCase		,				_lowerCamelCase		,				_lowerCamelCase		,				n_tasks=_lowerCamelCase		,				batch_size=args.batch_size		,				**_lowerCamelCase		,				)

  if accelerator.is_main_process:
    lowerCamelCase_         =						[]

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

    # Evaluate completions with "code_eval" metric
    lowerCamelCase_     ,	lowerCamelCase_         =						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()




