





import contextlib
from multiprocessing import Pool, RLock

from tqdm.auto import tqdm

from ..utils import experimental, logging


_UpperCAmelCase             =							logging.get_logger(__name__)






class        snake_case_    :
  A_      							=   None






@experimental
def 	_SCREAMING_SNAKE_CASE		(      SCREAMING_SNAKE_CASE		:Dict   ,   SCREAMING_SNAKE_CASE		:Tuple   ,   SCREAMING_SNAKE_CASE		:List[str]   ,   SCREAMING_SNAKE_CASE		:Tuple   ,   SCREAMING_SNAKE_CASE		:Dict   ,   SCREAMING_SNAKE_CASE		:int   ,   SCREAMING_SNAKE_CASE		:int   )      ->   Dict:
 if ParallelBackendConfig.backend_name is None:
  return _map_with_multiprocessing_pool(
      SCREAMING_SNAKE_CASE   ,   SCREAMING_SNAKE_CASE   ,   SCREAMING_SNAKE_CASE   ,   SCREAMING_SNAKE_CASE   ,   SCREAMING_SNAKE_CASE   ,   SCREAMING_SNAKE_CASE   ,   SCREAMING_SNAKE_CASE   )

 return _map_with_joblib(SCREAMING_SNAKE_CASE   ,   SCREAMING_SNAKE_CASE   ,   SCREAMING_SNAKE_CASE   ,   SCREAMING_SNAKE_CASE   ,   SCREAMING_SNAKE_CASE   ,   SCREAMING_SNAKE_CASE   ,   SCREAMING_SNAKE_CASE   )






def 	_SCREAMING_SNAKE_CASE		(      SCREAMING_SNAKE_CASE		:int   ,   SCREAMING_SNAKE_CASE		:str   ,   SCREAMING_SNAKE_CASE		:Tuple   ,   SCREAMING_SNAKE_CASE		:int   ,   SCREAMING_SNAKE_CASE		:Any   ,   SCREAMING_SNAKE_CASE		:str   ,   SCREAMING_SNAKE_CASE		:Union[str, Any]   )      ->   Union[str, Any]:
 __lowerCAmelCase					:	int      =       num_proc if num_proc <= len(SCREAMING_SNAKE_CASE   ) else len(SCREAMING_SNAKE_CASE   )
 __lowerCAmelCase					:	int      =       []  # We organize the splits ourselve (contiguous splits)
 for index in range(SCREAMING_SNAKE_CASE   ):
  __lowerCAmelCase					:	Tuple      =       len(SCREAMING_SNAKE_CASE   ) // num_proc
  __lowerCAmelCase					:	Dict      =       len(SCREAMING_SNAKE_CASE   ) % num_proc
  __lowerCAmelCase					:	Optional[Any]      =       div * index + min(SCREAMING_SNAKE_CASE   ,   SCREAMING_SNAKE_CASE   )
  __lowerCAmelCase					:	Optional[int]      =       start + div + (1 if index < mod else 0)
  split_kwds.append((function, iterable[start:end], types, index, disable_tqdm, desc)   )

 if len(SCREAMING_SNAKE_CASE   ) != sum(len(i[1]   ) for i in split_kwds   ):
  raise ValueError(
      F'''Error dividing inputs iterable among processes. '''
      F'''Total number of objects {len(SCREAMING_SNAKE_CASE   )}, '''
      F'''length: {sum(len(i[1]   ) for i in split_kwds   )}'''   )

 logger.info(
     F'''Spawning {num_proc} processes for {len(SCREAMING_SNAKE_CASE   )} objects in slices of {[len(i[1]   ) for i in split_kwds]}'''   )
 __lowerCAmelCase					:	Dict      =       None, None
 if not disable_tqdm:
  __lowerCAmelCase					:	int      =       (RLock(),), tqdm.set_lock
 with Pool(SCREAMING_SNAKE_CASE   ,   initargs=SCREAMING_SNAKE_CASE   ,   initializer=SCREAMING_SNAKE_CASE   ) as pool:
  __lowerCAmelCase					:	Optional[Any]      =       pool.map(SCREAMING_SNAKE_CASE   ,   SCREAMING_SNAKE_CASE   )
 logger.info(F'''Finished {num_proc} processes'''   )
 __lowerCAmelCase					:	List[Any]      =       [obj for proc_res in mapped for obj in proc_res]
 logger.info(F'''Unpacked {len(SCREAMING_SNAKE_CASE   )} objects'''   )

 return mapped






def 	_SCREAMING_SNAKE_CASE		(      SCREAMING_SNAKE_CASE		:Optional[Any]   ,   SCREAMING_SNAKE_CASE		:Any   ,   SCREAMING_SNAKE_CASE		:Tuple   ,   SCREAMING_SNAKE_CASE		:Dict   ,   SCREAMING_SNAKE_CASE		:List[str]   ,   SCREAMING_SNAKE_CASE		:Tuple   ,   SCREAMING_SNAKE_CASE		:str   )      ->   str:
 # progress bar is not yet supported for _map_with_joblib, because tqdm couldn't accurately be applied to joblib,
 # and it requires monkey-patching joblib internal classes which is subject to change
 import joblib

 with joblib.parallel_backend(ParallelBackendConfig.backend_name   ,   n_jobs=SCREAMING_SNAKE_CASE   ):
  return joblib.Parallel()(
      joblib.delayed(SCREAMING_SNAKE_CASE   )((function, obj, types, None, True, None)   ) for obj in iterable   )







@experimental
@contextlib.contextmanager
def 	_SCREAMING_SNAKE_CASE		(      SCREAMING_SNAKE_CASE		:str   )      ->   Union[str, Any]:
 __lowerCAmelCase					:	Optional[int]      =       backend_name

 if backend_name == "spark":
  from joblibspark import register_spark

  register_spark()

  # TODO: call create_cache_and_write_probe if "download" in steps
  # TODO: raise NotImplementedError when Dataset.map etc is called

 try:
  yield
 finally:
  __lowerCAmelCase					:	Tuple      =       None






import warnings

from ...processing_utils import ProcessorMixin
from ...tokenization_utils_base import BatchEncoding






class        snake_case_    (		__lowercase						):
  A_      							=   ['image_processor', 'tokenizer']
  A_      							=   'ChineseCLIPImageProcessor'
  A_      							=   ('BertTokenizer', 'BertTokenizerFast')






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






   '''simple docstring'''

   __lowerCAmelCase					:	str      =       None
   if "feature_extractor" in kwargs:
    warnings.warn(
        """The `feature_extractor` argument is deprecated and will be removed in v5, use `image_processor`"""
        """ instead."""       ,  _snake_case       ,  )
    __lowerCAmelCase					:	List[str]      =       kwargs.pop("""feature_extractor"""      )

   __lowerCAmelCase					:	Union[str, Any]      =       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__(_snake_case       ,  _snake_case      )
   __lowerCAmelCase					:	Any      =       self.image_processor






  def __call__(							self			:					Optional[Any]       ,  _snake_case			:					Tuple=None       ,  _snake_case			:					Tuple=None       ,  _snake_case			:					List[str]=None       ,  **_snake_case			:					Any      )->Union[str, Any]:






   '''simple docstring'''

   if text is None and images is None:
    raise ValueError("""You have to specify either text or images. Both cannot be none."""      )

   if text is not None:
    __lowerCAmelCase					:	List[Any]      =       self.tokenizer(_snake_case       ,  return_tensors=_snake_case       ,  **_snake_case      )

   if images is not None:
    __lowerCAmelCase					:	Tuple      =       self.image_processor(_snake_case       ,  return_tensors=_snake_case       ,  **_snake_case      )

   if text is not None and images is not None:
    __lowerCAmelCase					:	Optional[Any]      =       image_features.pixel_values
    return encoding
   elif text is not None:
    return encoding
   else:
    return BatchEncoding(data=dict(**_snake_case      )       ,  tensor_type=_snake_case      )






  def 				UpperCAmelCase__						(							self			:					Optional[int]       ,  *_snake_case			:					Union[str, Any]       ,  **_snake_case			:					int      )->Optional[Any]:






   '''simple docstring'''

   return self.tokenizer.batch_decode(*_snake_case       ,  **_snake_case      )






  def 				UpperCAmelCase__						(							self			:					Dict       ,  *_snake_case			:					Dict       ,  **_snake_case			:					Any      )->Dict:






   '''simple docstring'''

   return self.tokenizer.decode(*_snake_case       ,  **_snake_case      )






  @property
  def 				UpperCAmelCase__						(							self			:					Optional[int]      )->str:






   '''simple docstring'''

   __lowerCAmelCase					:	Tuple      =       self.tokenizer.model_input_names
   __lowerCAmelCase					:	Tuple      =       self.image_processor.model_input_names
   return list(dict.fromkeys(tokenizer_input_names + image_processor_input_names      )      )






  @property
  def 				UpperCAmelCase__						(							self			:					Dict      )->Union[str, Any]:






   '''simple docstring'''

   warnings.warn(
       """`feature_extractor_class` is deprecated and will be removed in v5. Use `image_processor_class` instead."""       ,  _snake_case       ,  )
   return self.image_processor_class