import inspect
import unittest

from transformers import ConvNextVaConfig
from transformers.models.auto import get_values
from transformers.models.auto.modeling_auto import MODEL_FOR_BACKBONE_MAPPING_NAMES, MODEL_MAPPING_NAMES
from transformers.testing_utils import require_torch, require_vision, slow, torch_device
from transformers.utils import cached_property, is_torch_available, is_vision_available

from ...test_configuration_common import ConfigTester
from ...test_modeling_common import ModelTesterMixin, floats_tensor, ids_tensor
from ...test_pipeline_mixin import PipelineTesterMixin


if is_torch_available():
					import torch

					from transformers import ConvNextVaBackbone, ConvNextVaForImageClassification, ConvNextVaModel
					from transformers.models.convnextva.modeling_convnextva import CONVNEXTV2_PRETRAINED_MODEL_ARCHIVE_LIST


if is_vision_available():
					from PIL import Image

					from transformers import AutoImageProcessor



class   lowerCAmelCase_    :



				"""simple docstring"""

				def __init__(				self		,    lowerCAmelCase		,    lowerCAmelCase=13		,    lowerCAmelCase=32		,    lowerCAmelCase=3		,    lowerCAmelCase=4		,    lowerCAmelCase=[10, 20, 30, 40]		,    lowerCAmelCase=[2, 2, 3, 2]		,    lowerCAmelCase=True		,    lowerCAmelCase=True		,    lowerCAmelCase=37		,    lowerCAmelCase="gelu"		,    lowerCAmelCase=10		,    lowerCAmelCase=0.02		,    lowerCAmelCase=["stage2", "stage3", "stage4"]		,    lowerCAmelCase=[2, 3, 4]		,    lowerCAmelCase=None		,    ):






										"""simple docstring"""

										snake_case								=			parent
										snake_case								=			batch_size
										snake_case								=			image_size
										snake_case								=			num_channels
										snake_case								=			num_stages
										snake_case								=			hidden_sizes
										snake_case								=			depths
										snake_case								=			is_training
										snake_case								=			use_labels
										snake_case								=			intermediate_size
										snake_case								=			hidden_act
										snake_case								=			num_labels
										snake_case								=			initializer_range
										snake_case								=			out_features
										snake_case								=			out_indices
										snake_case								=			scope

				def 		snake_case (				self    ):






										"""simple docstring"""

										snake_case								=			floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size]    )

										snake_case								=			None
										if self.use_labels:
																snake_case								=			ids_tensor([self.batch_size]		,    self.num_labels    )

										snake_case								=			self.get_config()

										return config, pixel_values, labels

				def 		snake_case (				self    ):






										"""simple docstring"""

										return ConvNextVaConfig(
										    num_channels=self.num_channels		,    hidden_sizes=self.hidden_sizes		,    depths=self.depths		,    num_stages=self.num_stages		,    hidden_act=self.hidden_act		,    is_decoder=__lowerCamelCase		,    initializer_range=self.initializer_range		,    out_features=self.out_features		,    out_indices=self.out_indices		,    num_labels=self.num_labels		,    )

				def 		snake_case (				self		,    lowerCAmelCase		,    lowerCAmelCase		,    lowerCAmelCase    ):






										"""simple docstring"""

										snake_case								=			ConvNextVaModel(config=__lowerCamelCase    )
										model.to(__lowerCamelCase    )
										model.eval()
										snake_case								=			model(__lowerCamelCase    )
										# expected last hidden states: B, C, H // 32, W // 32
										self.parent.assertEqual(
										    result.last_hidden_state.shape		,    (self.batch_size, self.hidden_sizes[-1], self.image_size // 32, self.image_size // 32)		,    )

				def 		snake_case (				self		,    lowerCAmelCase		,    lowerCAmelCase		,    lowerCAmelCase    ):






										"""simple docstring"""

										snake_case								=			ConvNextVaForImageClassification(__lowerCamelCase    )
										model.to(__lowerCamelCase    )
										model.eval()
										snake_case								=			model(__lowerCamelCase		,    labels=__lowerCamelCase    )
										self.parent.assertEqual(result.logits.shape		,    (self.batch_size, self.num_labels)    )

				def 		snake_case (				self		,    lowerCAmelCase		,    lowerCAmelCase		,    lowerCAmelCase    ):






										"""simple docstring"""

										snake_case								=			ConvNextVaBackbone(config=__lowerCamelCase    )
										model.to(__lowerCamelCase    )
										model.eval()
										snake_case								=			model(__lowerCamelCase    )

										# verify hidden states
										self.parent.assertEqual(len(result.feature_maps    )		,    len(config.out_features    )    )
										self.parent.assertListEqual(list(result.feature_maps[0].shape    )		,    [self.batch_size, self.hidden_sizes[1], 4, 4]    )

										# verify channels
										self.parent.assertEqual(len(model.channels    )		,    len(config.out_features    )    )
										self.parent.assertListEqual(model.channels		,    config.hidden_sizes[1:]    )

										# verify backbone works with out_features=None
										snake_case								=			None
										snake_case								=			ConvNextVaBackbone(config=__lowerCamelCase    )
										model.to(__lowerCamelCase    )
										model.eval()
										snake_case								=			model(__lowerCamelCase    )

										# verify feature maps
										self.parent.assertEqual(len(result.feature_maps    )		,    1    )
										self.parent.assertListEqual(list(result.feature_maps[0].shape    )		,    [self.batch_size, self.hidden_sizes[-1], 1, 1]    )

										# verify channels
										self.parent.assertEqual(len(model.channels    )		,    1    )
										self.parent.assertListEqual(model.channels		,    [config.hidden_sizes[-1]]    )

				def 		snake_case (				self    ):






										"""simple docstring"""

										snake_case								=			self.prepare_config_and_inputs()
										snake_case								=			config_and_inputs
										snake_case								=			{'''pixel_values''': pixel_values}
										return config, inputs_dict

				def 		snake_case (				self    ):






										"""simple docstring"""

										snake_case								=			self.prepare_config_and_inputs()
										snake_case								=			config_and_inputs
										snake_case								=			{'''pixel_values''': pixel_values, '''labels''': labels}
										return config, inputs_dict





@require_torch
class   lowerCAmelCase_    (			lowerCamelCase__     ,    lowerCamelCase__     ,    unittest.TestCase					):



				"""simple docstring"""
				_lowerCAmelCase     :    Dict			  =						(
				    (
				        ConvNextVaModel,
				        ConvNextVaForImageClassification,
				        ConvNextVaBackbone,
				    )
				    if is_torch_available()
				    else ()
				)
				_lowerCAmelCase     :    Union[str, Any]			  =						(
				    {"""feature-extraction""": ConvNextVaModel, """image-classification""": ConvNextVaForImageClassification}
				    if is_torch_available()
				    else {}
				)

				_lowerCAmelCase     :    Optional[int]			  =						False
				_lowerCAmelCase     :    Optional[int]			  =						False
				_lowerCAmelCase     :    int			  =						False
				_lowerCAmelCase     :    Optional[Any]			  =						False
				_lowerCAmelCase     :    Optional[Any]			  =						False

				def 		snake_case (				self    ):






										"""simple docstring"""

										snake_case								=			ConvNextVaModelTester(self    )
										snake_case								=			ConfigTester(self		,    config_class=__lowerCamelCase		,    has_text_modality=__lowerCamelCase		,    hidden_size=37    )

				def 		snake_case (				self    ):






										"""simple docstring"""

										self.create_and_test_config_common_properties()
										self.config_tester.create_and_test_config_to_json_string()
										self.config_tester.create_and_test_config_to_json_file()
										self.config_tester.create_and_test_config_from_and_save_pretrained()
										self.config_tester.create_and_test_config_with_num_labels()
										self.config_tester.check_config_can_be_init_without_params()
										self.config_tester.check_config_arguments_init()

				def 		snake_case (				self    ):






										"""simple docstring"""

										return

				@unittest.skip(reason='ConvNextV2 does not use inputs_embeds'    )
				def 		snake_case (				self    ):






										"""simple docstring"""

										pass

				@unittest.skip(reason='ConvNextV2 does not support input and output embeddings'    )
				def 		snake_case (				self    ):






										"""simple docstring"""

										pass

				@unittest.skip(reason='ConvNextV2 does not use feedforward chunking'    )
				def 		snake_case (				self    ):






										"""simple docstring"""

										pass

				def 		snake_case (				self    ):






										"""simple docstring"""

										if not self.model_tester.is_training:
																return

										for model_class in self.all_model_classes:
																snake_case								=			self.model_tester.prepare_config_and_inputs_with_labels()
																snake_case								=			True

																if model_class.__name__ in [
																    *get_values(__lowerCamelCase    ),
																    *get_values(__lowerCamelCase    ),
																]:
																						continue

																snake_case								=			model_class(__lowerCamelCase    )
																model.to(__lowerCamelCase    )
																model.train()
																snake_case								=			self._prepare_for_class(__lowerCamelCase		,    __lowerCamelCase		,    return_labels=__lowerCamelCase    )
																snake_case								=			model(**__lowerCamelCase    ).loss
																loss.backward()

				def 		snake_case (				self    ):






										"""simple docstring"""

										if not self.model_tester.is_training:
																return

										for model_class in self.all_model_classes:
																snake_case								=			self.model_tester.prepare_config_and_inputs_with_labels()
																snake_case								=			False
																snake_case								=			True

																if (
																    model_class.__name__
																    in [*get_values(__lowerCamelCase    ), *get_values(__lowerCamelCase    )]
																    or not model_class.supports_gradient_checkpointing
																):
																						continue

																snake_case								=			model_class(__lowerCamelCase    )
																model.to(__lowerCamelCase    )
																model.gradient_checkpointing_enable()
																model.train()
																snake_case								=			self._prepare_for_class(__lowerCamelCase		,    __lowerCamelCase		,    return_labels=__lowerCamelCase    )
																snake_case								=			model(**__lowerCamelCase    ).loss
																loss.backward()

				def 		snake_case (				self    ):






										"""simple docstring"""

										snake_case								=			self.model_tester.prepare_config_and_inputs_for_common()

										for model_class in self.all_model_classes:
																snake_case								=			model_class(__lowerCamelCase    )
																snake_case								=			inspect.signature(model.forward    )
																# signature.parameters is an OrderedDict => so arg_names order is deterministic
																snake_case								=			[*signature.parameters.keys()]

																snake_case								=			['''pixel_values''']
																self.assertListEqual(arg_names[:1]		,    __lowerCamelCase    )

				def 		snake_case (				self    ):






										"""simple docstring"""

										snake_case								=			self.model_tester.prepare_config_and_inputs()
										self.model_tester.create_and_check_model(*__lowerCamelCase    )

				def 		snake_case (				self    ):






										"""simple docstring"""

										def check_hidden_states_output(lowerCAmelCase		,    lowerCAmelCase		,    lowerCAmelCase    ):
																snake_case								=			model_class(__lowerCamelCase    )
																model.to(__lowerCamelCase    )
																model.eval()

																with torch.no_grad():
																						snake_case								=			model(**self._prepare_for_class(__lowerCamelCase		,    __lowerCamelCase    )    )

																snake_case								=			outputs.encoder_hidden_states if config.is_encoder_decoder else outputs.hidden_states

																snake_case								=			self.model_tester.num_stages
																self.assertEqual(len(__lowerCamelCase    )		,    expected_num_stages + 1    )

																# ConvNextV2's feature maps are of shape (batch_size, num_channels, height, width)
																self.assertListEqual(
																    list(hidden_states[0].shape[-2:]    )		,    [self.model_tester.image_size // 4, self.model_tester.image_size // 4]		,    )

										snake_case								=			self.model_tester.prepare_config_and_inputs_for_common()

										for model_class in self.all_model_classes:
																snake_case								=			True
																check_hidden_states_output(__lowerCamelCase		,    __lowerCamelCase		,    __lowerCamelCase    )

																# check that output_hidden_states also work using config
																del inputs_dict["output_hidden_states"]
																snake_case								=			True

																check_hidden_states_output(__lowerCamelCase		,    __lowerCamelCase		,    __lowerCamelCase    )

				def 		snake_case (				self    ):






										"""simple docstring"""

										snake_case								=			self.model_tester.prepare_config_and_inputs()
										self.model_tester.create_and_check_for_image_classification(*__lowerCamelCase    )

				@slow
				def 		snake_case (				self    ):






										"""simple docstring"""

										for model_name in CONVNEXTV2_PRETRAINED_MODEL_ARCHIVE_LIST[:1]:
																snake_case								=			ConvNextVaModel.from_pretrained(__lowerCamelCase    )
																self.assertIsNotNone(__lowerCamelCase    )





def    lowerCAmelCase__    (			)					->				Optional[Any]:





						"""simple docstring"""






						snake_case								=			Image.open('./tests/fixtures/tests_samples/COCO/000000039769.png'					)
						return image



@require_torch
@require_vision
class   lowerCAmelCase_    (			unittest.TestCase					):



				"""simple docstring"""

				@cached_property
				def 		snake_case (				self    ):






										"""simple docstring"""

										return AutoImageProcessor.from_pretrained('facebook/convnextv2-tiny-1k-224'    ) if is_vision_available() else None

				@slow
				def 		snake_case (				self    ):






										"""simple docstring"""

										snake_case								=			ConvNextVaForImageClassification.from_pretrained('facebook/convnextv2-tiny-1k-224'    ).to(__lowerCamelCase    )

										snake_case								=			self.default_image_processor
										snake_case								=			prepare_img()
										snake_case								=			preprocessor(images=__lowerCamelCase		,    return_tensors='pt'    ).to(__lowerCamelCase    )

										# forward pass
										with torch.no_grad():
																snake_case								=			model(**__lowerCamelCase    )

										# verify the logits
										snake_case								=			torch.Size((1, 10_00)    )
										self.assertEqual(outputs.logits.shape		,    __lowerCamelCase    )

										snake_case								=			torch.tensor([0.99_96, 0.19_66, -0.43_86]    ).to(__lowerCamelCase    )
										self.assertTrue(torch.allclose(outputs.logits[0, :3]		,    __lowerCamelCase		,    atol=1E-4    )    )



"""simple docstring"""
import numpy as np
from PIL import Image





def    lowerCAmelCase__    (			_UpperCamelCase       :				np.ndarray ,			_UpperCamelCase       :				int ,			_UpperCamelCase       :				int					)					->				np.ndarray:





						"""simple docstring"""






						snake_case								=			np.array(_UpperCamelCase					)
						if arr.shape[0] != arr.shape[1]:
												raise ValueError('The input array is not a square matrix'					)
						snake_case								=			0
						snake_case								=			0
						snake_case								=			0
						snake_case								=			0

						# compute the shape of the output matrix
						snake_case								=			(arr.shape[0] - size) // stride + 1
						# initialize the output matrix with zeros of shape maxpool_shape
						snake_case								=			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
																		snake_case								=			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
												snake_case								=			0
												snake_case								=			0

						return updated_arr





def    lowerCAmelCase__    (			_UpperCamelCase       :				np.ndarray ,			_UpperCamelCase       :				int ,			_UpperCamelCase       :				int					)					->				np.ndarray:





						"""simple docstring"""






						snake_case								=			np.array(_UpperCamelCase					)
						if arr.shape[0] != arr.shape[1]:
												raise ValueError('The input array is not a square matrix'					)
						snake_case								=			0
						snake_case								=			0
						snake_case								=			0
						snake_case								=			0

						# compute the shape of the output matrix
						snake_case								=			(arr.shape[0] - size) // stride + 1
						# initialize the output matrix with zeros of shape avgpool_shape
						snake_case								=			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
																		snake_case								=			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
												snake_case								=			0
												snake_case								=			0

						return updated_arr


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

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

					# Loading the image
					SCREAMING_SNAKE_CASE__      						=  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()


