



import contextlib
from multiprocessing import Pool, RLock

from tqdm.auto import tqdm

from ..utils import experimental, logging


_lowercase			:			List[str]										=						logging.get_logger(__name__)

class 	__SCREAMING_SNAKE_CASE     :


					'''simple docstring'''





					_a             =							None






@experimental
def 					snake_case__       (		__lowerCamelCase    :   List[Any]							,		__lowerCamelCase    :   Union[str, Any]							,		__lowerCamelCase    :   Dict							,		__lowerCamelCase    :   Union[str, Any]							,		__lowerCamelCase    :   List[str]							,		__lowerCamelCase    :   Union[str, Any]							,		__lowerCamelCase    :   List[Any]     ):
			"""simple docstring"""
			if ParallelBackendConfig.backend_name is None:
						return _map_with_multiprocessing_pool(
						    __lowerCamelCase							,		__lowerCamelCase							,		__lowerCamelCase							,		__lowerCamelCase							,		__lowerCamelCase							,		__lowerCamelCase							,		__lowerCamelCase     )

			return _map_with_joblib(__lowerCamelCase							,		__lowerCamelCase							,		__lowerCamelCase							,		__lowerCamelCase							,		__lowerCamelCase							,		__lowerCamelCase							,		__lowerCamelCase     )






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

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

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

			return mapped






def 					snake_case__       (		__lowerCamelCase    :   int							,		__lowerCamelCase    :   Dict							,		__lowerCamelCase    :   Dict							,		__lowerCamelCase    :   List[Any]							,		__lowerCamelCase    :   List[Any]							,		__lowerCamelCase    :   List[Any]							,		__lowerCamelCase    :   List[str]     ):
			"""simple docstring"""
			import joblib

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






@experimental
@contextlib.contextmanager
def 					snake_case__       (		__lowerCamelCase    :   str     ):
			"""simple docstring"""
			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__		:		Any		     =None









"""simple docstring"""






import numpy as np
from PIL import Image






def 					snake_case__       (		__lowerCamelCase    :   np.ndarray							,		__lowerCamelCase    :   int							,		__lowerCamelCase    :   int     ):
			"""simple docstring"""
			lowerCamelCase__		:		List[Any]		     =np.array(__lowerCamelCase     )
			if arr.shape[0] != arr.shape[1]:
						raise ValueError('''The input array is not a square matrix'''     )
			lowerCamelCase__		:		int		     =0
			lowerCamelCase__		:		int		     =0
			lowerCamelCase__		:		Optional[int]		     =0
			lowerCamelCase__		:		List[Any]		     =0

			# compute the shape of the output matrix
			lowerCamelCase__		:		Union[str, Any]		     =(arr.shape[0] - size) // stride + 1
			# initialize the output matrix with zeros of shape maxpool_shape
			lowerCamelCase__		:		Union[str, Any]		     =np.zeros((maxpool_shape, maxpool_shape)     )

			while i < arr.shape[0]:
						if i + size > arr.shape[0]:
									# if the end of the matrix is reached, break
									break
						while j < arr.shape[1]:
									# if the end of the matrix is reached, break
									if j + size > arr.shape[1]:
												break
									# compute the maximum of the pooling matrix
									lowerCamelCase__		:		str		     =np.max(arr[i : i + size, j : j + size]     )
									# shift the pooling matrix by stride of column pixels
									j += stride
									mat_j += 1

						# shift the pooling matrix by stride of row pixels
						i += stride
						mat_i += 1

						# reset the column index to 0
						lowerCamelCase__		:		Optional[int]		     =0
						lowerCamelCase__		:		Optional[int]		     =0

			return updated_arr






def 					snake_case__       (		__lowerCamelCase    :   np.ndarray							,		__lowerCamelCase    :   int							,		__lowerCamelCase    :   int     ):
			"""simple docstring"""
			lowerCamelCase__		:		List[Any]		     =np.array(__lowerCamelCase     )
			if arr.shape[0] != arr.shape[1]:
						raise ValueError('''The input array is not a square matrix'''     )
			lowerCamelCase__		:		str		     =0
			lowerCamelCase__		:		List[Any]		     =0
			lowerCamelCase__		:		Optional[int]		     =0
			lowerCamelCase__		:		List[Any]		     =0

			# compute the shape of the output matrix
			lowerCamelCase__		:		Dict		     =(arr.shape[0] - size) // stride + 1
			# initialize the output matrix with zeros of shape avgpool_shape
			lowerCamelCase__		:		Optional[Any]		     =np.zeros((avgpool_shape, avgpool_shape)     )

			while i < arr.shape[0]:
						# if the end of the matrix is reached, break
						if i + size > arr.shape[0]:
									break
						while j < arr.shape[1]:
									# if the end of the matrix is reached, break
									if j + size > arr.shape[1]:
												break
									# compute the average of the pooling matrix
									lowerCamelCase__		:		Optional[int]		     =int(np.average(arr[i : i + size, j : j + size]     )     )
									# shift the pooling matrix by stride of column pixels
									j += stride
									mat_j += 1

						# shift the pooling matrix by stride of row pixels
						i += stride
						mat_i += 1
						# reset the column index to 0
						lowerCamelCase__		:		Optional[Any]		     =0
						lowerCamelCase__		:		int		     =0

			return updated_arr


# Main Function
if __name__ == "__main__":
		from doctest import testmod

		testmod(name="avgpooling", verbose=True)

		# Loading the image
		_lowercase			:			int										=						Image.open("path_to_image")

		# Converting the image to numpy array and maxpooling, displaying the result
		# Ensure that the image is a square matrix

		Image.fromarray(maxpooling(np.array(image), size=3, stride=2)).show()

		# Converting the image to numpy array and averagepooling, displaying the result
		# Ensure that the image is a square matrix

		Image.fromarray(avgpooling(np.array(image), size=3, stride=2)).show()




