





import inspect
from typing import Optional, Union

import numpy as np
import PIL
import torch
from torch.nn import functional as F
from torchvision import transforms
from transformers import CLIPFeatureExtractor, CLIPModel, CLIPTextModel, CLIPTokenizer

from diffusers import (
    AutoencoderKL,
    DDIMScheduler,
    DiffusionPipeline,
    DPMSolverMultistepScheduler,
    LMSDiscreteScheduler,
    PNDMScheduler,
    UNetaDConditionModel,
)
from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion import StableDiffusionPipelineOutput
from diffusers.utils import (
    PIL_INTERPOLATION,
    randn_tensor,
)







def    __lowerCamelCase					(							__a   :str    ,     __a   :List[str]    ,     __a   :List[str]    )		->				Optional[Any]:






		"""simple docstring"""

		if isinstance(__a    ,     torch.Tensor    ):
				return image
		elif isinstance(__a    ,     PIL.Image.Image    ):
				A__        =   [image]

		if isinstance(image[0]    ,     PIL.Image.Image    ):
				A__        =   [np.array(i.resize((w, h)    ,     resample=PIL_INTERPOLATION["""lanczos"""]    )    )[None, :] for i in image]
				A__        =   np.concatenate(__a    ,     axis=0    )
				A__        =   np.array(__a    ).astype(np.floataa    ) / 255.0
				A__        =   image.transpose(0    ,     3    ,     1    ,     2    )
				A__        =   2.0 * image - 1.0
				A__        =   torch.from_numpy(__a    )
		elif isinstance(image[0]    ,     torch.Tensor    ):
				A__        =   torch.cat(__a    ,     dim=0    )
		return image







def    __lowerCamelCase					(							__a   :Union[str, Any]    ,     __a   :Optional[int]    ,     __a   :Optional[Any]    ,     __a   :Optional[Any]=0.9995    )		->				int:






		"""simple docstring"""

		if not isinstance(__a    ,     np.ndarray    ):
				A__        =   True
				A__        =   va.device
				A__        =   va.cpu().numpy()
				A__        =   va.cpu().numpy()

		A__        =   np.sum(va * va / (np.linalg.norm(__a    ) * np.linalg.norm(__a    ))    )
		if np.abs(__a    ) > DOT_THRESHOLD:
				A__        =   (1 - t) * va + t * va
		else:
				A__        =   np.arccos(__a    )
				A__        =   np.sin(__a    )
				A__        =   theta_a * t
				A__        =   np.sin(__a    )
				A__        =   np.sin(theta_a - theta_t    ) / sin_theta_a
				A__        =   sin_theta_t / sin_theta_a
				A__        =   sa * va + sa * va

		if inputs_are_torch:
				A__        =   torch.from_numpy(__a    ).to(__a    )

		return va







def    __lowerCamelCase					(							__a   :int    ,     __a   :Union[str, Any]    )		->				Union[str, Any]:






		"""simple docstring"""

		A__        =   F.normalize(__a    ,     dim=-1    )
		A__        =   F.normalize(__a    ,     dim=-1    )
		return (x - y).norm(dim=-1    ).div(2    ).arcsin().pow(2    ).mul(2    )







def    __lowerCamelCase					(							__a   :Any    ,     __a   :Optional[int]    )		->				int:






		"""simple docstring"""

		for param in model.parameters():
				A__        =   value






class   A			(SCREAMING_SNAKE_CASE    ):
			'''simple docstring'''




			def __init__(			self   :    Union[str, Any]							,	__lowerCAmelCase   :    AutoencoderKL							,	__lowerCAmelCase   :    CLIPTextModel							,	__lowerCAmelCase   :    CLIPModel							,	__lowerCAmelCase   :    CLIPTokenizer							,	__lowerCAmelCase   :    UNetaDConditionModel							,	__lowerCAmelCase   :    Union[PNDMScheduler, LMSDiscreteScheduler, DDIMScheduler, DPMSolverMultistepScheduler]							,	__lowerCAmelCase   :    CLIPFeatureExtractor							,	__lowerCAmelCase   :    Dict=None							,	__lowerCAmelCase   :    Optional[Any]=None							,	__lowerCAmelCase   :    List[str]=None							,	)	->	str:







					"""simple docstring"""






					super().__init__()
					self.register_modules(
					    vae=__lowerCAmelCase							,	text_encoder=__lowerCAmelCase							,	clip_model=__lowerCAmelCase							,	tokenizer=__lowerCAmelCase							,	unet=__lowerCAmelCase							,	scheduler=__lowerCAmelCase							,	feature_extractor=__lowerCAmelCase							,	coca_model=__lowerCAmelCase							,	coca_tokenizer=__lowerCAmelCase							,	coca_transform=__lowerCAmelCase							,	)
					A__        =   (
					    feature_extractor.size
					    if isinstance(feature_extractor.size							,	__lowerCAmelCase   )
					    else feature_extractor.size["""shortest_edge"""]
					)
					A__        =   transforms.Normalize(mean=feature_extractor.image_mean							,	std=feature_extractor.image_std   )
					set_requires_grad(self.text_encoder							,	__lowerCAmelCase   )
					set_requires_grad(self.clip_model							,	__lowerCAmelCase   )






			def    a_       (			self   :    int							,	__lowerCAmelCase   :    Optional[Union[str, int]] = "auto"   )	->	Tuple:







					"""simple docstring"""






					if slice_size == "auto":
							# half the attention head size is usually a good trade-off between
							# speed and memory
							A__        =   self.unet.config.attention_head_dim // 2
					self.unet.set_attention_slice(__lowerCAmelCase   )






			def    a_       (			self   :    int   )	->	str:







					"""simple docstring"""






					self.enable_attention_slicing(__lowerCAmelCase   )






			def    a_       (			self   :    int   )	->	Tuple:







					"""simple docstring"""






					set_requires_grad(self.vae							,	__lowerCAmelCase   )






			def    a_       (			self   :    List[Any]   )	->	Union[str, Any]:







					"""simple docstring"""






					set_requires_grad(self.vae							,	__lowerCAmelCase   )






			def    a_       (			self   :    Union[str, Any]   )	->	Optional[int]:







					"""simple docstring"""






					set_requires_grad(self.unet							,	__lowerCAmelCase   )






			def    a_       (			self   :    Any   )	->	Optional[Any]:







					"""simple docstring"""






					set_requires_grad(self.unet							,	__lowerCAmelCase   )






			def    a_       (			self   :    Dict							,	__lowerCAmelCase   :    int							,	__lowerCAmelCase   :    Optional[Any]							,	__lowerCAmelCase   :    Tuple   )	->	Dict:







					"""simple docstring"""






					A__        =   min(int(num_inference_steps * strength   )							,	__lowerCAmelCase   )

					A__        =   max(num_inference_steps - init_timestep							,	0   )
					A__        =   self.scheduler.timesteps[t_start:]

					return timesteps, num_inference_steps - t_start






			def    a_       (			self   :    Any							,	__lowerCAmelCase   :    Optional[Any]							,	__lowerCAmelCase   :    List[Any]							,	__lowerCAmelCase   :    int							,	__lowerCAmelCase   :    int							,	__lowerCAmelCase   :    Tuple							,	__lowerCAmelCase   :    Union[str, Any]=None   )	->	Optional[int]:







					"""simple docstring"""






					if not isinstance(__lowerCAmelCase							,	torch.Tensor   ):
							raise ValueError(f'`image` has to be of type `torch.Tensor` but is {type(__lowerCAmelCase   )}'   )

					A__        =   image.to(device=__lowerCAmelCase							,	dtype=__lowerCAmelCase   )

					if isinstance(__lowerCAmelCase							,	__lowerCAmelCase   ):
							A__        =   [
							    self.vae.encode(image[i : i + 1]   ).latent_dist.sample(generator[i]   ) for i in range(__lowerCAmelCase   )
							]
							A__        =   torch.cat(__lowerCAmelCase							,	dim=0   )
					else:
							A__        =   self.vae.encode(__lowerCAmelCase   ).latent_dist.sample(__lowerCAmelCase   )

					# Hardcode 0.18215 because stable-diffusion-2-base has not self.vae.config.scaling_factor
					A__        =   0.1_8_2_1_5 * init_latents
					A__        =   init_latents.repeat_interleave(__lowerCAmelCase							,	dim=0   )

					A__        =   randn_tensor(init_latents.shape							,	generator=__lowerCAmelCase							,	device=__lowerCAmelCase							,	dtype=__lowerCAmelCase   )

					# get latents
					A__        =   self.scheduler.add_noise(__lowerCAmelCase							,	__lowerCAmelCase							,	__lowerCAmelCase   )
					A__        =   init_latents

					return latents






			def    a_       (			self   :    Tuple							,	__lowerCAmelCase   :    Union[str, Any]   )	->	List[str]:







					"""simple docstring"""






					A__        =   self.coca_transform(__lowerCAmelCase   ).unsqueeze(0   )
					with torch.no_grad(), torch.cuda.amp.autocast():
							A__        =   self.coca_model.generate(transformed_image.to(device=self.device							,	dtype=self.coca_model.dtype   )   )
					A__        =   self.coca_tokenizer.decode(generated[0].cpu().numpy()   )
					return generated.split("""<end_of_text>"""   )[0].replace("""<start_of_text>"""							,	""""""   ).rstrip(""" .,"""   )






			def    a_       (			self   :    List[Any]							,	__lowerCAmelCase   :    Dict							,	__lowerCAmelCase   :    Optional[Any]   )	->	Union[str, Any]:







					"""simple docstring"""






					A__        =   self.feature_extractor.preprocess(__lowerCAmelCase   )
					A__        =   torch.from_numpy(clip_image_input["""pixel_values"""][0]   ).unsqueeze(0   ).to(self.device   ).half()
					A__        =   self.clip_model.get_image_features(__lowerCAmelCase   )
					A__        =   image_embeddings_clip / image_embeddings_clip.norm(p=2							,	dim=-1							,	keepdim=__lowerCAmelCase   )
					A__        =   image_embeddings_clip.repeat_interleave(__lowerCAmelCase							,	dim=0   )
					return image_embeddings_clip






			@torch.enable_grad()
			def    a_       (			self   :    Union[str, Any]							,	__lowerCAmelCase   :    str							,	__lowerCAmelCase   :    str							,	__lowerCAmelCase   :    List[str]							,	__lowerCAmelCase   :    int							,	__lowerCAmelCase   :    str							,	__lowerCAmelCase   :    List[Any]							,	__lowerCAmelCase   :    int							,	)	->	Tuple:







					"""simple docstring"""






					A__        =   latents.detach().requires_grad_()

					A__        =   self.scheduler.scale_model_input(__lowerCAmelCase							,	__lowerCAmelCase   )

					# predict the noise residual
					A__        =   self.unet(__lowerCAmelCase							,	__lowerCAmelCase							,	encoder_hidden_states=__lowerCAmelCase   ).sample

					if isinstance(self.scheduler							,	(PNDMScheduler, DDIMScheduler, DPMSolverMultistepScheduler)   ):
							A__        =   self.scheduler.alphas_cumprod[timestep]
							A__        =   1 - alpha_prod_t
							# compute predicted original sample from predicted noise also called
							# "predicted x_0" of formula (12) from https://arxiv.org/pdf/2010.02502.pdf
							A__        =   (latents - beta_prod_t ** 0.5 * noise_pred) / alpha_prod_t ** 0.5

							A__        =   torch.sqrt(__lowerCAmelCase   )
							A__        =   pred_original_sample * (fac) + latents * (1 - fac)
					elif isinstance(self.scheduler							,	__lowerCAmelCase   ):
							A__        =   self.scheduler.sigmas[index]
							A__        =   latents - sigma * noise_pred
					else:
							raise ValueError(f'scheduler type {type(self.scheduler   )} not supported'   )

					# Hardcode 0.18215 because stable-diffusion-2-base has not self.vae.config.scaling_factor
					A__        =   1 / 0.1_8_2_1_5 * sample
					A__        =   self.vae.decode(__lowerCAmelCase   ).sample
					A__        =   (image / 2 + 0.5).clamp(0							,	1   )

					A__        =   transforms.Resize(self.feature_extractor_size   )(__lowerCAmelCase   )
					A__        =   self.normalize(__lowerCAmelCase   ).to(latents.dtype   )

					A__        =   self.clip_model.get_image_features(__lowerCAmelCase   )
					A__        =   image_embeddings_clip / image_embeddings_clip.norm(p=2							,	dim=-1							,	keepdim=__lowerCAmelCase   )

					A__        =   spherical_dist_loss(__lowerCAmelCase							,	__lowerCAmelCase   ).mean() * clip_guidance_scale

					A__        =   -torch.autograd.grad(__lowerCAmelCase							,	__lowerCAmelCase   )[0]

					if isinstance(self.scheduler							,	__lowerCAmelCase   ):
							A__        =   latents.detach() + grads * (sigma**2)
							A__        =   noise_pred_original
					else:
							A__        =   noise_pred_original - torch.sqrt(__lowerCAmelCase   ) * grads
					return noise_pred, latents







			@torch.no_grad()
			def __call__(			self   :    List[Any]							,	__lowerCAmelCase   :    Union[torch.FloatTensor, PIL.Image.Image]							,	__lowerCAmelCase   :    Union[torch.FloatTensor, PIL.Image.Image]							,	__lowerCAmelCase   :    Optional[str] = None							,	__lowerCAmelCase   :    Optional[str] = None							,	__lowerCAmelCase   :    Optional[int] = 5_12							,	__lowerCAmelCase   :    Optional[int] = 5_12							,	__lowerCAmelCase   :    float = 0.6							,	__lowerCAmelCase   :    Optional[int] = 50							,	__lowerCAmelCase   :    Optional[float] = 7.5							,	__lowerCAmelCase   :    Optional[int] = 1							,	__lowerCAmelCase   :    float = 0.0							,	__lowerCAmelCase   :    Optional[float] = 1_00							,	__lowerCAmelCase   :    Optional[torch.Generator] = None							,	__lowerCAmelCase   :    Optional[str] = "pil"							,	__lowerCAmelCase   :    bool = True							,	__lowerCAmelCase   :    float = 0.8							,	__lowerCAmelCase   :    float = 0.1							,	__lowerCAmelCase   :    float = 0.1							,	)	->	Dict:







					"""simple docstring"""






					if isinstance(__lowerCAmelCase							,	__lowerCAmelCase   ) and len(__lowerCAmelCase   ) != batch_size:
							raise ValueError(f'You have passed {batch_size} batch_size, but only {len(__lowerCAmelCase   )} generators.'   )

					if height % 8 != 0 or width % 8 != 0:
							raise ValueError(f'`height` and `width` have to be divisible by 8 but are {height} and {width}.'   )

					if isinstance(__lowerCAmelCase							,	torch.Generator   ) and batch_size > 1:
							A__        =   [generator] + [None] * (batch_size - 1)

					A__        =   [
					    ("""model""", self.coca_model is None),
					    ("""tokenizer""", self.coca_tokenizer is None),
					    ("""transform""", self.coca_transform is None),
					]
					A__        =   [x[0] for x in coca_is_none if x[1]]
					A__        =   """, """.join(__lowerCAmelCase   )
					# generate prompts with coca model if prompt is None
					if content_prompt is None:
							if len(__lowerCAmelCase   ):
									raise ValueError(
									    f'Content prompt is None and CoCa [{coca_is_none_str}] is None.'
									    f'Set prompt or pass Coca [{coca_is_none_str}] to DiffusionPipeline.'   )
							A__        =   self.get_image_description(__lowerCAmelCase   )
					if style_prompt is None:
							if len(__lowerCAmelCase   ):
									raise ValueError(
									    f'Style prompt is None and CoCa [{coca_is_none_str}] is None.'
									    f' Set prompt or pass Coca [{coca_is_none_str}] to DiffusionPipeline.'   )
							A__        =   self.get_image_description(__lowerCAmelCase   )

					# get prompt text embeddings for content and style
					A__        =   self.tokenizer(
					    __lowerCAmelCase							,	padding="""max_length"""							,	max_length=self.tokenizer.model_max_length							,	truncation=__lowerCAmelCase							,	return_tensors="""pt"""							,	)
					A__        =   self.text_encoder(content_text_input.input_ids.to(self.device   )   )[0]

					A__        =   self.tokenizer(
					    __lowerCAmelCase							,	padding="""max_length"""							,	max_length=self.tokenizer.model_max_length							,	truncation=__lowerCAmelCase							,	return_tensors="""pt"""							,	)
					A__        =   self.text_encoder(style_text_input.input_ids.to(self.device   )   )[0]

					A__        =   slerp(__lowerCAmelCase							,	__lowerCAmelCase							,	__lowerCAmelCase   )

					# duplicate text embeddings for each generation per prompt
					A__        =   text_embeddings.repeat_interleave(__lowerCAmelCase							,	dim=0   )

					# set timesteps
					A__        =   """offset""" in set(inspect.signature(self.scheduler.set_timesteps   ).parameters.keys()   )
					A__        =   {}
					if accepts_offset:
							A__        =   1

					self.scheduler.set_timesteps(__lowerCAmelCase							,	**__lowerCAmelCase   )
					# Some schedulers like PNDM have timesteps as arrays
					# It's more optimized to move all timesteps to correct device beforehand
					self.scheduler.timesteps.to(self.device   )

					A__      ,			A__        =   self.get_timesteps(__lowerCAmelCase							,	__lowerCAmelCase							,	self.device   )
					A__        =   timesteps[:1].repeat(__lowerCAmelCase   )

					# Preprocess image
					A__        =   preprocess(__lowerCAmelCase							,	__lowerCAmelCase							,	__lowerCAmelCase   )
					A__        =   self.prepare_latents(
					    __lowerCAmelCase							,	__lowerCAmelCase							,	__lowerCAmelCase							,	text_embeddings.dtype							,	self.device							,	__lowerCAmelCase   )

					A__        =   preprocess(__lowerCAmelCase							,	__lowerCAmelCase							,	__lowerCAmelCase   )
					A__        =   self.prepare_latents(
					    __lowerCAmelCase							,	__lowerCAmelCase							,	__lowerCAmelCase							,	text_embeddings.dtype							,	self.device							,	__lowerCAmelCase   )

					A__        =   slerp(__lowerCAmelCase							,	__lowerCAmelCase							,	__lowerCAmelCase   )

					if clip_guidance_scale > 0:
							A__        =   self.get_clip_image_embeddings(__lowerCAmelCase							,	__lowerCAmelCase   )
							A__        =   self.get_clip_image_embeddings(__lowerCAmelCase							,	__lowerCAmelCase   )
							A__        =   slerp(
							    __lowerCAmelCase							,	__lowerCAmelCase							,	__lowerCAmelCase   )

					# here `guidance_scale` is defined analog to the guidance weight `w` of equation (2)
					# of the Imagen paper: https://arxiv.org/pdf/2205.11487.pdf . `guidance_scale = 1`
					# corresponds to doing no classifier free guidance.
					A__        =   guidance_scale > 1.0
					# get unconditional embeddings for classifier free guidance
					if do_classifier_free_guidance:
							A__        =   content_text_input.input_ids.shape[-1]
							A__        =   self.tokenizer([""""""]							,	padding="""max_length"""							,	max_length=__lowerCAmelCase							,	return_tensors="""pt"""   )
							A__        =   self.text_encoder(uncond_input.input_ids.to(self.device   )   )[0]
							# duplicate unconditional embeddings for each generation per prompt
							A__        =   uncond_embeddings.repeat_interleave(__lowerCAmelCase							,	dim=0   )

							# For classifier free guidance, we need to do two forward passes.
							# Here we concatenate the unconditional and text embeddings into a single batch
							# to avoid doing two forward passes
							A__        =   torch.cat([uncond_embeddings, text_embeddings]   )

					# get the initial random noise unless the user supplied it

					# Unlike in other pipelines, latents need to be generated in the target device
					# for 1-to-1 results reproducibility with the CompVis implementation.
					# However this currently doesn't work in `mps`.
					A__        =   (batch_size, self.unet.config.in_channels, height // 8, width // 8)
					A__        =   text_embeddings.dtype
					if latents is None:
							if self.device.type == "mps":
									# randn does not work reproducibly on mps
									A__        =   torch.randn(__lowerCAmelCase							,	generator=__lowerCAmelCase							,	device="""cpu"""							,	dtype=__lowerCAmelCase   ).to(
									    self.device   )
							else:
									A__        =   torch.randn(__lowerCAmelCase							,	generator=__lowerCAmelCase							,	device=self.device							,	dtype=__lowerCAmelCase   )
					else:
							if latents.shape != latents_shape:
									raise ValueError(f'Unexpected latents shape, got {latents.shape}, expected {latents_shape}'   )
							A__        =   latents.to(self.device   )

					# scale the initial noise by the standard deviation required by the scheduler
					A__        =   latents * self.scheduler.init_noise_sigma

					# prepare extra kwargs for the scheduler step, since not all schedulers have the same signature
					# eta (η) is only used with the DDIMScheduler, it will be ignored for other schedulers.
					# eta corresponds to η in DDIM paper: https://arxiv.org/abs/2010.02502
					# and should be between [0, 1]
					A__        =   """eta""" in set(inspect.signature(self.scheduler.step   ).parameters.keys()   )
					A__        =   {}
					if accepts_eta:
							A__        =   eta

					# check if the scheduler accepts generator
					A__        =   """generator""" in set(inspect.signature(self.scheduler.step   ).parameters.keys()   )
					if accepts_generator:
							A__        =   generator

					with self.progress_bar(total=__lowerCAmelCase   ):
							for i, t in enumerate(__lowerCAmelCase   ):
									# expand the latents if we are doing classifier free guidance
									A__        =   torch.cat([latents] * 2   ) if do_classifier_free_guidance else latents
									A__        =   self.scheduler.scale_model_input(__lowerCAmelCase							,	__lowerCAmelCase   )

									# predict the noise residual
									A__        =   self.unet(__lowerCAmelCase							,	__lowerCAmelCase							,	encoder_hidden_states=__lowerCAmelCase   ).sample

									# perform classifier free guidance
									if do_classifier_free_guidance:
											A__      ,			A__        =   noise_pred.chunk(2   )
											A__        =   noise_pred_uncond + guidance_scale * (noise_pred_text - noise_pred_uncond)

									# perform clip guidance
									if clip_guidance_scale > 0:
											A__        =   (
											    text_embeddings.chunk(2   )[1] if do_classifier_free_guidance else text_embeddings
											)
											A__      ,			A__        =   self.cond_fn(
											    __lowerCAmelCase							,	__lowerCAmelCase							,	__lowerCAmelCase							,	__lowerCAmelCase							,	__lowerCAmelCase							,	__lowerCAmelCase							,	__lowerCAmelCase							,	)

									# compute the previous noisy sample x_t -> x_t-1
									A__        =   self.scheduler.step(__lowerCAmelCase							,	__lowerCAmelCase							,	__lowerCAmelCase							,	**__lowerCAmelCase   ).prev_sample

        # Hardcode 0.18215 because stable-diffusion-2-base has not self.vae.config.scaling_factor
					A__        =   1 / 0.1_8_2_1_5 * latents
					A__        =   self.vae.decode(__lowerCAmelCase   ).sample

					A__        =   (image / 2 + 0.5).clamp(0							,	1   )
					A__        =   image.cpu().permute(0							,	2							,	3							,	1   ).numpy()

					if output_type == "pil":
							A__        =   self.numpy_to_pil(__lowerCAmelCase   )

					if not return_dict:
							return (image, None)

					return StableDiffusionPipelineOutput(images=__lowerCAmelCase							,	nsfw_content_detected=__lowerCAmelCase   )










import unittest

from transformers.utils.backbone_utils import (
    BackboneMixin,
    get_aligned_output_features_output_indices,
    verify_out_features_out_indices,
)


class   A			(unittest.TestCase    ):
			'''simple docstring'''




			def    a_       (			self   :    Any   )	->	Union[str, Any]:







					"""simple docstring"""






					A__        =   ["""a""", """b""", """c"""]

					# Defaults to last layer if both are None
					A__      ,			A__        =   get_aligned_output_features_output_indices(__lowerCAmelCase							,	__lowerCAmelCase							,	__lowerCAmelCase   )
					self.assertEqual(__lowerCAmelCase							,	["""c"""]   )
					self.assertEqual(__lowerCAmelCase							,	[2]   )

					# Out indices set to match out features
					A__      ,			A__        =   get_aligned_output_features_output_indices(["""a""", """c"""]							,	__lowerCAmelCase							,	__lowerCAmelCase   )
					self.assertEqual(__lowerCAmelCase							,	["""a""", """c"""]   )
					self.assertEqual(__lowerCAmelCase							,	[0, 2]   )

					# Out features set to match out indices
					A__      ,			A__        =   get_aligned_output_features_output_indices(__lowerCAmelCase							,	[0, 2]							,	__lowerCAmelCase   )
					self.assertEqual(__lowerCAmelCase							,	["""a""", """c"""]   )
					self.assertEqual(__lowerCAmelCase							,	[0, 2]   )

					# Out features selected from negative indices
					A__      ,			A__        =   get_aligned_output_features_output_indices(__lowerCAmelCase							,	[-3, -1]							,	__lowerCAmelCase   )
					self.assertEqual(__lowerCAmelCase							,	["""a""", """c"""]   )
					self.assertEqual(__lowerCAmelCase							,	[-3, -1]   )






			def    a_       (			self   :    Optional[Any]   )	->	Optional[Any]:







					"""simple docstring"""






					with self.assertRaises(__lowerCAmelCase   ):
							verify_out_features_out_indices(["""a""", """b"""]							,	(0, 1)							,	__lowerCAmelCase   )

					# Out features must be a list
					with self.assertRaises(__lowerCAmelCase   ):
							verify_out_features_out_indices(("""a""", """b""")							,	(0, 1)							,	["""a""", """b"""]   )

					# Out features must be a subset of stage names
					with self.assertRaises(__lowerCAmelCase   ):
							verify_out_features_out_indices(["""a""", """b"""]							,	(0, 1)							,	["""a"""]   )

					# Out indices must be a list or tuple
					with self.assertRaises(__lowerCAmelCase   ):
							verify_out_features_out_indices(__lowerCAmelCase							,	0							,	["""a""", """b"""]   )

					# Out indices must be a subset of stage names
					with self.assertRaises(__lowerCAmelCase   ):
							verify_out_features_out_indices(__lowerCAmelCase							,	(0, 1)							,	["""a"""]   )

					# Out features and out indices must be the same length
					with self.assertRaises(__lowerCAmelCase   ):
							verify_out_features_out_indices(["""a""", """b"""]							,	(0,)							,	["""a""", """b""", """c"""]   )

					# Out features should match out indices
					with self.assertRaises(__lowerCAmelCase   ):
							verify_out_features_out_indices(["""a""", """b"""]							,	(0, 2)							,	["""a""", """b""", """c"""]   )

					# Out features and out indices should be in order
					with self.assertRaises(__lowerCAmelCase   ):
							verify_out_features_out_indices(["""b""", """a"""]							,	(0, 1)							,	["""a""", """b"""]   )

					# Check passes with valid inputs
					verify_out_features_out_indices(["""a""", """b""", """d"""]							,	(0, 1, -1)							,	["""a""", """b""", """c""", """d"""]   )







			def    a_       (			self   :    Union[str, Any]   )	->	List[str]:







					"""simple docstring"""






					A__        =   BackboneMixin()

					A__        =   ["""a""", """b""", """c"""]
					A__        =   ["""a""", """c"""]
					A__        =   [0, 2]

					# Check that the output features and indices are set correctly
					self.assertEqual(backbone.out_features							,	["""a""", """c"""]   )
					self.assertEqual(backbone.out_indices							,	[0, 2]   )

					# Check out features and indices are updated correctly
					A__        =   ["""a""", """b"""]
					self.assertEqual(backbone.out_features							,	["""a""", """b"""]   )
					self.assertEqual(backbone.out_indices							,	[0, 1]   )

					A__        =   [-3, -1]
					self.assertEqual(backbone.out_features							,	["""a""", """c"""]   )
					self.assertEqual(backbone.out_indices							,	[-3, -1]   )



