






import json
import os
import subprocess
import unittest
from ast import literal_eval

import pytest
from parameterized import parameterized, parameterized_class

from . import is_sagemaker_available


if is_sagemaker_available():
					from sagemaker import Session, TrainingJobAnalytics
					from sagemaker.huggingface import HuggingFace
@pytest.mark.skipif(
    literal_eval(os.getenv("TEST_SAGEMAKER"			,       "False" ) ) is not True			,       reason="Skipping test because should only be run when releasing minor transformers version"			,       )
@pytest.mark.usefixtures("sm_env" )
@parameterized_class(
    [
        {
            "framework": "pytorch",
            "script": "run_glue_model_parallelism.py",
            "model_name_or_path": "roberta-large",
            "instance_type": "ml.p3dn.24xlarge",
            "results": {"train_runtime": 1_6_0_0, "eval_accuracy": 0.3, "eval_loss": 1.2},
        },
        {
            "framework": "pytorch",
            "script": "run_glue.py",
            "model_name_or_path": "roberta-large",
            "instance_type": "ml.p3dn.24xlarge",
            "results": {"train_runtime": 1_6_0_0, "eval_accuracy": 0.3, "eval_loss": 1.2},
        },
    ] )
class      UpperCamelCase (				unittest.TestCase ):







		"""simple docstring"""



		def       A(  self		:       Any		)    ->   List[Any]:


						'''simple docstring'''
						if self.framework == "pytorch":
										subprocess.run(
										    f'cp ./examples/pytorch/text-classification/run_glue.py {self.env.test_path}/run_glue.py'.split()						,encoding='utf-8'						,check=_SCREAMING_SNAKE_CASE						,)
						assert hasattr(self						,'env'		)
		def       A(  self		:       List[Any]						,_SCREAMING_SNAKE_CASE		:       List[Any]		)    ->   Tuple:


						'''simple docstring'''
						# configuration for running training on smdistributed Model Parallel
						A	 =      {
						    'enabled': True,
						    'processes_per_host': 8,
						}
						A	 =      {
						    'enabled': True,
						    'parameters': {
						        'microbatches': 4,
						        'placement_strategy': 'spread',
						        'pipeline': 'interleaved',
						        'optimize': 'speed',
						        'partitions': 4,
						        'ddp': True,
						    },
						}

						A	 =      {'smdistributed': {'modelparallel': smp_options}, 'mpi': mpi_options}

						A	 =      'trainer' if self.script == 'run_glue.py' else 'smtrainer'
						# creates estimator
						return HuggingFace(
						    entry_point=self.script						,source_dir=self.env.test_path						,role=self.env.role						,image_uri=self.env.image_uri						,base_job_name=f'{self.env.base_job_name}-{instance_count}-smp-{name_extension}'						,instance_count=_SCREAMING_SNAKE_CASE						,instance_type=self.instance_type						,debugger_hook_config=_SCREAMING_SNAKE_CASE						,hyperparameters={
						        **self.env.hyperparameters,
						        'model_name_or_path': self.model_name_or_path,
						        'max_steps': 5_0_0,
						    }						,metric_definitions=self.env.metric_definitions						,distribution=_SCREAMING_SNAKE_CASE						,py_version='py36'						,)
		def       A(  self		:       Optional[Any]						,_SCREAMING_SNAKE_CASE		:       Any		)    ->   Optional[Any]:


						'''simple docstring'''
						TrainingJobAnalytics(_SCREAMING_SNAKE_CASE		).export_csv(f'{self.env.test_path}/{job_name}_metrics.csv'		)







		@parameterized.expand([(1,)]		)
		def       A(  self		:       List[str]						,_SCREAMING_SNAKE_CASE		:       Any		)    ->   List[str]:


						'''simple docstring'''
						# create estimator
						A	 =      self.create_estimator(_SCREAMING_SNAKE_CASE		)

						# run training
						estimator.fit()

						# result dataframe
						A	 =      TrainingJobAnalytics(estimator.latest_training_job.name		).dataframe()

						# extract kpis
						A	 =      list(result_metrics_df[result_metrics_df.metric_name == 'eval_accuracy']['value']		)
						A	 =      list(result_metrics_df[result_metrics_df.metric_name == 'eval_loss']['value']		)
						# get train time from SageMaker job, this includes starting, preprocessing, stopping
						A	 =      (
						    Session().describe_training_job(estimator.latest_training_job.name		).get('TrainingTimeInSeconds'						,9_9_9_9_9_9		)
						)

						# assert kpis
						assert train_runtime <= self.results["train_runtime"]
						assert all(t >= self.results['eval_accuracy'] for t in eval_accuracy		)
						assert all(t <= self.results['eval_loss'] for t in eval_loss		)

						# dump tests result into json file to share in PR
						with open(f'{estimator.latest_training_job.name}.json'						,'w'		) as outfile:
										json.dump({'train_time': train_runtime, 'eval_accuracy': eval_accuracy, 'eval_loss': eval_loss}						,_SCREAMING_SNAKE_CASE		)













import warnings
from typing import List, Optional, Union

from ...processing_utils import ProcessorMixin
from ...tokenization_utils_base import BatchEncoding, PaddingStrategy, PreTokenizedInput, TextInput, TruncationStrategy
from ...utils import TensorType
class      UpperCamelCase (				snake_case__ ):







		"""simple docstring"""



		snake_case    =   ["image_processor", "tokenizer"]
		snake_case    =   "LayoutLMv2ImageProcessor"
		snake_case    =   ("LayoutXLMTokenizer", "LayoutXLMTokenizerFast")
		def __init__(  self		:       List[str]						,_SCREAMING_SNAKE_CASE		:       List[str]=None						,_SCREAMING_SNAKE_CASE		:       Optional[int]=None						,**_SCREAMING_SNAKE_CASE		:       Tuple		)    ->   List[str]:


						'''simple docstring'''
						if "feature_extractor" in kwargs:
										warnings.warn(
										    'The `feature_extractor` argument is deprecated and will be removed in v5, use `image_processor`'
										    ' instead.'						,_SCREAMING_SNAKE_CASE						,)
										A	 =      kwargs.pop('feature_extractor'		)

						A	 =      image_processor if image_processor is not None else feature_extractor
						if image_processor is None:
										raise ValueError('You need to specify an `image_processor`.'		)
						if tokenizer is None:
										raise ValueError('You need to specify a `tokenizer`.'		)

						super().__init__(_SCREAMING_SNAKE_CASE						,_SCREAMING_SNAKE_CASE		)
		def __call__(  self		:       Union[str, Any]						,_SCREAMING_SNAKE_CASE		:       Optional[int]						,_SCREAMING_SNAKE_CASE		:       Union[TextInput, PreTokenizedInput, List[TextInput], List[PreTokenizedInput]] = None						,_SCREAMING_SNAKE_CASE		:       Optional[Union[PreTokenizedInput, List[PreTokenizedInput]]] = None						,_SCREAMING_SNAKE_CASE		:       Union[List[List[int]], List[List[List[int]]]] = None						,_SCREAMING_SNAKE_CASE		:       Optional[Union[List[int], List[List[int]]]] = None						,_SCREAMING_SNAKE_CASE		:       bool = True						,_SCREAMING_SNAKE_CASE		:       Union[bool, str, PaddingStrategy] = False						,_SCREAMING_SNAKE_CASE		:       Union[bool, str, TruncationStrategy] = None						,_SCREAMING_SNAKE_CASE		:       Optional[int] = None						,_SCREAMING_SNAKE_CASE		:       int = 0						,_SCREAMING_SNAKE_CASE		:       Optional[int] = None						,_SCREAMING_SNAKE_CASE		:       Optional[bool] = None						,_SCREAMING_SNAKE_CASE		:       Optional[bool] = None						,_SCREAMING_SNAKE_CASE		:       bool = False						,_SCREAMING_SNAKE_CASE		:       bool = False						,_SCREAMING_SNAKE_CASE		:       bool = False						,_SCREAMING_SNAKE_CASE		:       bool = False						,_SCREAMING_SNAKE_CASE		:       bool = True						,_SCREAMING_SNAKE_CASE		:       Optional[Union[str, TensorType]] = None						,**_SCREAMING_SNAKE_CASE		:       Tuple						,)    ->   BatchEncoding:


						'''simple docstring'''
						# verify input
						if self.image_processor.apply_ocr and (boxes is not None):
										raise ValueError(
										    'You cannot provide bounding boxes '
										    'if you initialized the image processor with apply_ocr set to True.'		)

						if self.image_processor.apply_ocr and (word_labels is not None):
										raise ValueError(
										    'You cannot provide word labels if you initialized the image processor with apply_ocr set to True.'		)

						if return_overflowing_tokens is True and return_offsets_mapping is False:
										raise ValueError('You cannot return overflowing tokens without returning the offsets mapping.'		)

						# first, apply the image processor
						A	 =      self.image_processor(images=_SCREAMING_SNAKE_CASE						,return_tensors=_SCREAMING_SNAKE_CASE		)

						# second, apply the tokenizer
						if text is not None and self.image_processor.apply_ocr and text_pair is None:
										if isinstance(_SCREAMING_SNAKE_CASE						,_SCREAMING_SNAKE_CASE		):
														A	 =      [text]  # add batch dimension (as the image processor always adds a batch dimension)
										A	 =      features['words']

						A	 =      self.tokenizer(
						    text=text if text is not None else features['words']						,text_pair=text_pair if text_pair is not None else None						,boxes=boxes if boxes is not None else features['boxes']						,word_labels=_SCREAMING_SNAKE_CASE						,add_special_tokens=_SCREAMING_SNAKE_CASE						,padding=_SCREAMING_SNAKE_CASE						,truncation=_SCREAMING_SNAKE_CASE						,max_length=_SCREAMING_SNAKE_CASE						,stride=_SCREAMING_SNAKE_CASE						,pad_to_multiple_of=_SCREAMING_SNAKE_CASE						,return_token_type_ids=_SCREAMING_SNAKE_CASE						,return_attention_mask=_SCREAMING_SNAKE_CASE						,return_overflowing_tokens=_SCREAMING_SNAKE_CASE						,return_special_tokens_mask=_SCREAMING_SNAKE_CASE						,return_offsets_mapping=_SCREAMING_SNAKE_CASE						,return_length=_SCREAMING_SNAKE_CASE						,verbose=_SCREAMING_SNAKE_CASE						,return_tensors=_SCREAMING_SNAKE_CASE						,**_SCREAMING_SNAKE_CASE						,)

						# add pixel values
						A	 =      features.pop('pixel_values'		)
						if return_overflowing_tokens is True:
										A	 =      self.get_overflowing_images(_SCREAMING_SNAKE_CASE						,encoded_inputs['overflow_to_sample_mapping']		)
						A	 =      images

						return encoded_inputs
		def       A(  self		:       Dict						,_SCREAMING_SNAKE_CASE		:       Optional[Any]						,_SCREAMING_SNAKE_CASE		:       Optional[Any]		)    ->   Dict:


						'''simple docstring'''
						# in case there's an overflow, ensure each `input_ids` sample is mapped to its corresponding image
						A	 =      []
						for sample_idx in overflow_to_sample_mapping:
										images_with_overflow.append(images[sample_idx]		)

						if len(_SCREAMING_SNAKE_CASE		) != len(_SCREAMING_SNAKE_CASE		):
										raise ValueError(
										    'Expected length of images to be the same as the length of `overflow_to_sample_mapping`, but got'
										    f' {len(_SCREAMING_SNAKE_CASE		)} and {len(_SCREAMING_SNAKE_CASE		)}'		)

						return images_with_overflow
		def       A(  self		:       List[str]						,*_SCREAMING_SNAKE_CASE		:       str						,**_SCREAMING_SNAKE_CASE		:       Union[str, Any]		)    ->   Tuple:


						'''simple docstring'''
						return self.tokenizer.batch_decode(*_SCREAMING_SNAKE_CASE						,**_SCREAMING_SNAKE_CASE		)
		def       A(  self		:       Dict						,*_SCREAMING_SNAKE_CASE		:       Tuple						,**_SCREAMING_SNAKE_CASE		:       int		)    ->   int:


						'''simple docstring'''
						return self.tokenizer.decode(*_SCREAMING_SNAKE_CASE						,**_SCREAMING_SNAKE_CASE		)
		@property
		def       A(  self		:       Any		)    ->   Union[str, Any]:


						'''simple docstring'''
						return ["input_ids", "bbox", "attention_mask", "image"]
		@property
		def       A(  self		:       Dict		)    ->   int:


						'''simple docstring'''
						warnings.warn(
						    '`feature_extractor_class` is deprecated and will be removed in v5. Use `image_processor_class` instead.'						,_SCREAMING_SNAKE_CASE						,)
						return self.image_processor_class







		@property
		def       A(  self		:       Optional[int]		)    ->   Union[str, Any]:


						'''simple docstring'''
						warnings.warn(
						    '`feature_extractor` is deprecated and will be removed in v5. Use `image_processor` instead.'						,_SCREAMING_SNAKE_CASE						,)
						return self.image_processor





