"""simple docstring"""



import logging
import os
import sys
from dataclasses import dataclass, field
from typing import Optional

from seqaseq_trainer import SeqaSeqTrainer
from seqaseq_training_args import SeqaSeqTrainingArguments

import transformers
from transformers import (
    AutoConfig,
    AutoModelForSeqaSeqLM,
    AutoTokenizer,
    HfArgumentParser,
    MBartTokenizer,
    MBartTokenizerFast,
    set_seed,
)
from transformers.trainer_utils import EvaluationStrategy, is_main_process
from transformers.training_args import ParallelMode
from utils import (
    SeqaSeqDataCollator,
    SeqaSeqDataset,
    assert_all_frozen,
    build_compute_metrics_fn,
    check_output_dir,
    freeze_embeds,
    freeze_params,
    lmap,
    save_json,
    use_task_specific_params,
    write_txt_file,
)


_UpperCamelCase								=		logging.getLogger(__name__)
@dataclass
class 						__UpperCAmelCase    :







			'''simple docstring'''
			_UpperCamelCase  :						str					     =				field(
			    metadata={'help': 'Path to pretrained model or model identifier from huggingface.co/models'}     )
			_UpperCamelCase  :						Optional[str]					     =				field(
			    default=__A							,   metadata={'help': 'Pretrained config name or path if not the same as model_name'}     )
			_UpperCamelCase  :						Optional[str]					     =				field(
			    default=__A							,   metadata={'help': 'Pretrained tokenizer name or path if not the same as model_name'}     )
			_UpperCamelCase  :						Optional[str]					     =				field(
			    default=__A							,   metadata={'help': 'Where do you want to store the pretrained models downloaded from huggingface.co'}							,   )
			_UpperCamelCase  :						bool					     =				field(default=__A							,   metadata={'help': 'Whether tp freeze the encoder.'}     )
			_UpperCamelCase  :						bool					     =				field(default=__A							,   metadata={'help': 'Whether  to freeze the embeddings.'}     )





@dataclass
class 						__UpperCAmelCase    :







			'''simple docstring'''
			_UpperCamelCase  :						str					     =				field(
			    metadata={'help': 'The input data dir. Should contain the .tsv files (or other data files) for the task.'}     )
			_UpperCamelCase  :						Optional[str]					     =				field(
			    default='summarization'							,   metadata={'help': 'Task name, summarization (or summarization_{dataset} for pegasus) or translation'}							,   )
			_UpperCamelCase  :						Optional[int]					     =				field(
			    default=1024							,   metadata={
			        'help': (
			            'The maximum total input sequence length after tokenization. Sequences longer '
			            'than this will be truncated, sequences shorter will be padded.'
			        )
			    }							,   )
			_UpperCamelCase  :						Optional[int]					     =				field(
			    default=128							,   metadata={
			        'help': (
			            'The maximum total sequence length for target text after tokenization. Sequences longer '
			            'than this will be truncated, sequences shorter will be padded.'
			        )
			    }							,   )
			_UpperCamelCase  :						Optional[int]					     =				field(
			    default=142							,   metadata={
			        'help': (
			            'The maximum total sequence length for validation target text after tokenization. Sequences longer '
			            'than this will be truncated, sequences shorter will be padded. '
			            'This argument is also used to override the ``max_length`` param of ``model.generate``, which is used '
			            'during ``evaluate`` and ``predict``.'
			        )
			    }							,   )
			_UpperCamelCase  :						Optional[int]					     =				field(
			    default=142							,   metadata={
			        'help': (
			            'The maximum total sequence length for test target text after tokenization. Sequences longer '
			            'than this will be truncated, sequences shorter will be padded.'
			        )
			    }							,   )
			_UpperCamelCase  :						Optional[int]					     =				field(default=-1							,   metadata={'help': '# training examples. -1 means use all.'}     )
			_UpperCamelCase  :						Optional[int]					     =				field(default=-1							,   metadata={'help': '# validation examples. -1 means use all.'}     )
			_UpperCamelCase  :						Optional[int]					     =				field(default=-1							,   metadata={'help': '# test examples. -1 means use all.'}     )
			_UpperCamelCase  :						Optional[str]					     =				field(default=__A							,   metadata={'help': 'Source language id for translation.'}     )
			_UpperCamelCase  :						Optional[str]					     =				field(default=__A							,   metadata={'help': 'Target language id for translation.'}     )
			_UpperCamelCase  :						Optional[int]					     =				field(default=__A							,   metadata={'help': '# num_beams to use for evaluation.'}     )
			_UpperCamelCase  :						bool					     =				field(
			    default=__A							,   metadata={'help': 'If only pad tokens should be ignored. This assumes that `config.pad_token_id` is defined.'}							,   )





def  _A(		lowerCAmelCase			,  lowerCAmelCase			,  lowerCAmelCase							):
							logger.info(F'''***** {split} metrics *****'''							)
							for key in sorted(metrics.keys()							):
														logger.info(F'''  {key} = {metrics[key]}'''							)
							save_json(lowerCAmelCase			,  os.path.join(lowerCAmelCase			,  F'''{split}_results.json'''							)							)

def  _A(		):
							# See all possible arguments in src/transformers/training_args.py
							# or by passing the --help flag to this script.
							# We now keep distinct sets of args, for a cleaner separation of concerns.

							A__       :     Optional[int]								=			HfArgumentParser((ModelArguments, DataTrainingArguments, SeqaSeqTrainingArguments)							)

							if len(sys.argv							) == 2 and sys.argv[1].endswith(""".json"""							):
														# If we pass only one argument to the script and it's the path to a json file,
														# let's parse it to get our arguments.
														A__				,							A__				,							A__       :     Optional[Any]								=			parser.parse_json_file(json_file=os.path.abspath(sys.argv[1]							)							)
							else:
														A__				,							A__				,							A__       :     Tuple								=			parser.parse_args_into_dataclasses()

							check_output_dir(lowerCAmelCase							)

							# Setup logging
							logging.basicConfig(
							    format="""%(asctime)s - %(levelname)s - %(name)s - %(message)s"""			,  datefmt="""%m/%d/%Y %H:%M:%S"""			,  level=logging.INFO if training_args.local_rank in [-1, 0] else logging.WARN			,  )
							logger.warning(
							    """Process rank: %s, device: %s, n_gpu: %s, distributed training: %s, 16-bits training: %s"""			,  training_args.local_rank			,  training_args.device			,  training_args.n_gpu			,  bool(training_args.parallel_mode == ParallelMode.DISTRIBUTED							)			,  training_args.fpaa			,  )
							transformers.utils.logging.enable_default_handler()
							transformers.utils.logging.enable_explicit_format()
							# Set the verbosity to info of the Transformers logger (on main process only):
							if is_main_process(training_args.local_rank							):
														transformers.utils.logging.set_verbosity_info()
							logger.info("""Training/evaluation parameters %s"""			,  lowerCAmelCase							)

							# Set seed
							set_seed(training_args.seed							)

							# Load pretrained model and tokenizer
							#
							# Distributed training:
							# The .from_pretrained methods guarantee that only one local process can concurrently
							# download model & vocab.

							A__       :     Dict								=			AutoConfig.from_pretrained(
							    model_args.config_name if model_args.config_name else model_args.model_name_or_path			,  cache_dir=model_args.cache_dir			,  )

							A__       :     int								=			("""encoder_layerdrop""", """decoder_layerdrop""", """dropout""", """attention_dropout""")
							for p in extra_model_params:
														if getattr(lowerCAmelCase			,  lowerCAmelCase			,  lowerCAmelCase							):
																					assert hasattr(lowerCAmelCase			,  lowerCAmelCase							), F'''({config.__class__.__name__}) doesn\'t have a `{p}` attribute'''
																					setattr(lowerCAmelCase			,  lowerCAmelCase			,  getattr(lowerCAmelCase			,  lowerCAmelCase							)							)

							A__       :     int								=			AutoTokenizer.from_pretrained(
							    model_args.tokenizer_name if model_args.tokenizer_name else model_args.model_name_or_path			,  cache_dir=model_args.cache_dir			,  )
							A__       :     int								=			AutoModelForSeqaSeqLM.from_pretrained(
							    model_args.model_name_or_path			,  from_tf=""".ckpt""" in model_args.model_name_or_path			,  config=lowerCAmelCase			,  cache_dir=model_args.cache_dir			,  )

							# use task specific params
							use_task_specific_params(lowerCAmelCase			,  data_args.task							)

							# set num_beams for evaluation
							if data_args.eval_beams is None:
														A__       :     int								=			model.config.num_beams

							# set decoder_start_token_id for MBart
							if model.config.decoder_start_token_id is None and isinstance(lowerCAmelCase			,  (MBartTokenizer, MBartTokenizerFast)							):
														assert (
														    data_args.tgt_lang is not None and data_args.src_lang is not None
														), "mBart requires --tgt_lang and --src_lang"
														if isinstance(lowerCAmelCase			,  lowerCAmelCase							):
																					A__       :     Optional[int]								=			tokenizer.lang_code_to_id[data_args.tgt_lang]
														else:
																					A__       :     Union[str, Any]								=			tokenizer.convert_tokens_to_ids(data_args.tgt_lang							)

							if model_args.freeze_embeds:
														freeze_embeds(lowerCAmelCase							)
							if model_args.freeze_encoder:
														freeze_params(model.get_encoder()							)
														assert_all_frozen(model.get_encoder()							)

							A__       :     List[Any]								=			SeqaSeqDataset

							# Get datasets
							A__       :     Optional[int]								=			(
							    dataset_class(
							        lowerCAmelCase			,  type_path="""train"""			,  data_dir=data_args.data_dir			,  n_obs=data_args.n_train			,  max_target_length=data_args.max_target_length			,  max_source_length=data_args.max_source_length			,  prefix=model.config.prefix or """"""			,  )
							    if training_args.do_train
							    else None
							)
							A__       :     Any								=			(
							    dataset_class(
							        lowerCAmelCase			,  type_path="""val"""			,  data_dir=data_args.data_dir			,  n_obs=data_args.n_val			,  max_target_length=data_args.val_max_target_length			,  max_source_length=data_args.max_source_length			,  prefix=model.config.prefix or """"""			,  )
							    if training_args.do_eval or training_args.evaluation_strategy != EvaluationStrategy.NO
							    else None
							)
							A__       :     Optional[Any]								=			(
							    dataset_class(
							        lowerCAmelCase			,  type_path="""test"""			,  data_dir=data_args.data_dir			,  n_obs=data_args.n_test			,  max_target_length=data_args.test_max_target_length			,  max_source_length=data_args.max_source_length			,  prefix=model.config.prefix or """"""			,  )
							    if training_args.do_predict
							    else None
							)

							# Initialize our Trainer
							A__       :     Union[str, Any]								=			(
							    build_compute_metrics_fn(data_args.task			,  lowerCAmelCase							) if training_args.predict_with_generate else None
							)
							A__       :     List[Any]								=			SeqaSeqTrainer(
							    model=lowerCAmelCase			,  args=lowerCAmelCase			,  data_args=lowerCAmelCase			,  train_dataset=lowerCAmelCase			,  eval_dataset=lowerCAmelCase			,  data_collator=SeqaSeqDataCollator(
							        lowerCAmelCase			,  lowerCAmelCase			,  model.config.decoder_start_token_id			,  training_args.tpu_num_cores							)			,  compute_metrics=lowerCAmelCase			,  tokenizer=lowerCAmelCase			,  )

							A__       :     Optional[Any]								=			{}
							# Training
							if training_args.do_train:
														logger.info("""*** Train ***"""							)

														A__       :     int								=			trainer.train(
														    model_path=model_args.model_name_or_path if os.path.isdir(model_args.model_name_or_path							) else None							)
														A__       :     Dict								=			train_result.metrics
														A__       :     Tuple								=			data_args.n_train

														trainer.save_model()  # this also saves the tokenizer

														if trainer.is_world_process_zero():
																					handle_metrics("""train"""			,  lowerCAmelCase			,  training_args.output_dir							)
																					all_metrics.update(lowerCAmelCase							)

																					# Need to save the state, since Trainer.save_model saves only the tokenizer with the model
																					trainer.state.save_to_json(os.path.join(training_args.output_dir			,  """trainer_state.json"""							)							)

																					# For convenience, we also re-save the tokenizer to the same directory,
																					# so that you can share your model easily on huggingface.co/models =)
																					tokenizer.save_pretrained(training_args.output_dir							)

    # Evaluation
							if training_args.do_eval:
														logger.info("""*** Evaluate ***"""							)

														A__       :     Any								=			trainer.evaluate(metric_key_prefix="""val"""							)
														A__       :     Tuple								=			data_args.n_val
														A__       :     Union[str, Any]								=			round(metrics["""val_loss"""]			,  4							)

														if trainer.is_world_process_zero():
																					handle_metrics("""val"""			,  lowerCAmelCase			,  training_args.output_dir							)
																					all_metrics.update(lowerCAmelCase							)

							if training_args.do_predict:
														logger.info("""*** Predict ***"""							)

														A__       :     str								=			trainer.predict(test_dataset=lowerCAmelCase			,  metric_key_prefix="""test"""							)
														A__       :     int								=			test_output.metrics
														A__       :     List[str]								=			data_args.n_test

														if trainer.is_world_process_zero():
																					A__       :     Optional[Any]								=			round(metrics["""test_loss"""]			,  4							)
																					handle_metrics("""test"""			,  lowerCAmelCase			,  training_args.output_dir							)
																					all_metrics.update(lowerCAmelCase							)

																					if training_args.predict_with_generate:
																												A__       :     Union[str, Any]								=			tokenizer.batch_decode(
																												    test_output.predictions			,  skip_special_tokens=lowerCAmelCase			,  clean_up_tokenization_spaces=lowerCAmelCase							)
																												A__       :     Optional[Any]								=			lmap(str.strip			,  lowerCAmelCase							)
																												write_txt_file(lowerCAmelCase			,  os.path.join(training_args.output_dir			,  """test_generations.txt"""							)							)

							if trainer.is_world_process_zero():
														save_json(lowerCAmelCase			,  os.path.join(training_args.output_dir			,  """all_results.json"""							)							)

							return all_metrics

def  _A(		lowerCAmelCase							):
							# For xla_spawn (TPUs)
							main()


if __name__ == "__main__":
				main()






"""simple docstring"""



from collections import defaultdict
class 						__UpperCAmelCase    :







			'''simple docstring'''





			def __init__(			self   ,      snake_case_   ,      snake_case_							):







										'''simple docstring'''


										A__       :     Tuple								=			total  # total no of tasks (N)

										# DP table will have a dimension of (2^M)*N
										# initially all values are set to -1
										A__       :     Optional[int]								=			[
										    [-1 for i in range(total + 1							)] for j in range(2 ** len(snake_case_							)							)
										]

										A__       :     Optional[int]								=			defaultdict(snake_case_							)  # stores the list of persons for each task

										# final_mask is used to check if all persons are included by setting all bits
										# to 1
										A__       :     Optional[int]								=			(1 << len(snake_case_							)) - 1





			def 		lowerCamelCase					(			self   ,      snake_case_   ,      snake_case_							):







										'''simple docstring'''


										if mask == self.final_mask:
																	return 1

										# if not everyone gets the task and no more tasks are available, return 0
										if task_no > self.total_tasks:
																	return 0

										# if case already considered
										if self.dp[mask][task_no] != -1:
																	return self.dp[mask][task_no]

										# Number of ways when we don't this task in the arrangement
										A__       :     Optional[int]								=			self.count_ways_until(snake_case_   ,      task_no + 1							)

										# now assign the tasks one by one to all possible persons and recursively
										# assign for the remaining tasks.
										if task_no in self.task:
																	for p in self.task[task_no]:
																								# if p is already given a task
																								if mask & (1 << p):
																															continue

																								# assign this task to p and change the mask value. And recursively
																								# assign tasks with the new mask value.
																								total_ways_util += self.count_ways_until(mask | (1 << p)   ,      task_no + 1							)

        # save the value.
										A__       :     List[str]								=			total_ways_util

										return self.dp[mask][task_no]





			def 		lowerCamelCase					(			self   ,      snake_case_							):







										'''simple docstring'''


										for i in range(len(snake_case_							)							):
																	for j in task_performed[i]:
																								self.task[j].append(snake_case_							)

        # call the function to fill the DP table, final answer is stored in dp[0][1]
										return self.count_ways_until(0   ,      1							)


if __name__ == "__main__":
				_UpperCamelCase								=		5  # total no of tasks (the value of N)

				# the list of tasks that can be done by M persons.
				_UpperCamelCase								=		[[1, 3, 4], [1, 2, 5], [3, 4]]
				print(
				    AssignmentUsingBitmask(task_performed, total_tasks).count_no_of_ways(
				        task_performed
				    )
				)





