






import contextlib
from multiprocessing import Pool, RLock

from tqdm.auto import tqdm

from ..utils import experimental, logging


__lowerCamelCase	:		Optional[Any]										=   logging.get_logger(__name__)







class  _lowercase   :
      _a							:						str										=							None







@experimental
def 			__lowercase							(      _a  :					List[Any]		,  _a  :					Any		,  _a  :					List[Any]		,  _a  :					Union[str, Any]		,  _a  :					Tuple		,  _a  :					Optional[Any]		,  _a  :					str	):





 '''simple docstring'''







 if ParallelBackendConfig.backend_name is None:
  return _map_with_multiprocessing_pool(
      _a		,  _a		,  _a		,  _a		,  _a		,  _a		,  _a	)

 return _map_with_joblib(_a		,  _a		,  _a		,  _a		,  _a		,  _a		,  _a	)







def 			__lowercase							(      _a  :					Tuple		,  _a  :					List[str]		,  _a  :					Any		,  _a  :					Union[str, Any]		,  _a  :					Optional[Any]		,  _a  :					List[str]		,  _a  :					List[Any]	):





 '''simple docstring'''







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

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

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

 return mapped







def 			__lowercase							(      _a  :					Dict		,  _a  :					List[Any]		,  _a  :					str		,  _a  :					Optional[int]		,  _a  :					Dict		,  _a  :					Optional[int]		,  _a  :					List[Any]	):





 '''simple docstring'''







 import joblib

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







@experimental
@contextlib.contextmanager
def 			__lowercase							(      _a  :					str	):





 '''simple docstring'''







 snake_case__  :    Union[str, Any]							       =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:
  snake_case__  :    int							       =None













def 			A__							(      _a  :					Any		,  _a  :					Optional[Any]		,  _a  :					int		,  _a  :					Any	):





 '''simple docstring'''







 if height >= 1:
  move_tower(height - 1		,  _a		,  _a		,  _a	)
  move_disk(_a		,  _a	)
  move_tower(height - 1		,  _a		,  _a		,  _a	)







def 			A__							(      _a  :					Optional[int]		,  _a  :					str	):





 '''simple docstring'''







 print("""moving disk from"""		,  _a		,  """to"""		,  _a	)







def 			A__							(      ):





 '''simple docstring'''







 snake_case__  :    Dict							       =int(input("""Height of hanoi: """	).strip()	)
 move_tower(_a		,  """A"""		,  """B"""		,  """C"""	)


if __name__ == "__main__":
       main()





