


from typing import Optional, Tuple, Union

import flax
import flax.linen as nn
import jax
import jax.numpy as jnp
from flax.core.frozen_dict import FrozenDict

from ..configuration_utils import ConfigMixin, flax_register_to_config
from ..utils import BaseOutput
from .embeddings_flax import FlaxTimestepEmbedding, FlaxTimesteps
from .modeling_flax_utils import FlaxModelMixin
from .unet_ad_blocks_flax import (
    FlaxCrossAttnDownBlockaD,
    FlaxDownBlockaD,
    FlaxUNetMidBlockaDCrossAttn,
)


@flax.struct.dataclass
class        _a							(			UpperCamelCase__			):
							_lowercase	:			jnp.ndarray
							_lowercase	:			jnp.ndarray


class        _a							(			nn.Module			):
							_lowercase	:			int
							_lowercase	:			Tuple[int]        = (16, 32, 96, 256)
							_lowercase	:			jnp.dtype        = jnp.floataa

							def       lowerCamelCase_ (							self:	List[Any]							)			->   Optional[int]:





									"""simple docstring"""







									lowercase__            =      nn.Conv(
									    self.block_out_channels[0]    ,						kernel_size=(3, 3)    ,						padding=((1, 1), (1, 1))    ,						dtype=self.dtype    ,						)

									lowercase__            =      []
									for i in range(len(self.block_out_channels							) - 1							):
											lowercase__            =      self.block_out_channels[i]
											lowercase__            =      self.block_out_channels[i + 1]
											lowercase__            =      nn.Conv(
											    UpperCamelCase_    ,						kernel_size=(3, 3)    ,						padding=((1, 1), (1, 1))    ,						dtype=self.dtype    ,						)
											blocks.append(UpperCamelCase_							)
											lowercase__            =      nn.Conv(
											    UpperCamelCase_    ,						kernel_size=(3, 3)    ,						strides=(2, 2)    ,						padding=((1, 1), (1, 1))    ,						dtype=self.dtype    ,						)
											blocks.append(UpperCamelCase_							)
									lowercase__            =      blocks

									lowercase__            =      nn.Conv(
									    self.conditioning_embedding_channels    ,						kernel_size=(3, 3)    ,						padding=((1, 1), (1, 1))    ,						kernel_init=nn.initializers.zeros_init()    ,						bias_init=nn.initializers.zeros_init()    ,						dtype=self.dtype    ,						)


							def __call__(							self:	Optional[int]    ,						UpperCamelCase_:	Optional[int]							)			->   List[Any]:





									"""simple docstring"""







									lowercase__            =      self.conv_in(UpperCamelCase_							)
									lowercase__            =      nn.silu(UpperCamelCase_							)

									for block in self.blocks:
											lowercase__            =      block(UpperCamelCase_							)
											lowercase__            =      nn.silu(UpperCamelCase_							)

									lowercase__            =      self.conv_out(UpperCamelCase_							)

									return embedding


@flax_register_to_config
class        _a							(			nn.Module     ,	UpperCamelCase__     ,	UpperCamelCase__			):
							_lowercase	:			int        = 32
							_lowercase	:			int        = 4
							_lowercase	:			Tuple[str]        = (
							    "CrossAttnDownBlock2D",
							    "CrossAttnDownBlock2D",
							    "CrossAttnDownBlock2D",
							    "DownBlock2D",
							)
							_lowercase	:			Union[bool, Tuple[bool]]        = False
							_lowercase	:			Tuple[int]        = (320, 640, 1280, 1280)
							_lowercase	:			int        = 2
							_lowercase	:			Union[int, Tuple[int]]        = 8
							_lowercase	:			Optional[Union[int, Tuple[int]]]        = None
							_lowercase	:			int        = 1280
							_lowercase	:			float        = 0.0
							_lowercase	:			bool        = False
							_lowercase	:			jnp.dtype        = jnp.floataa
							_lowercase	:			bool        = True
							_lowercase	:			int        = 0
							_lowercase	:			str        = "rgb"
							_lowercase	:			Tuple[int]        = (16, 32, 96, 256)

							def       lowerCamelCase_ (							self:	List[Any]    ,						UpperCamelCase_:	jax.random.KeyArray							)			->   FrozenDict:





									"""simple docstring"""







									lowercase__            =      (1, self.in_channels, self.sample_size, self.sample_size)
									lowercase__            =      jnp.zeros(UpperCamelCase_    ,						dtype=jnp.floataa							)
									lowercase__            =      jnp.ones((1,)    ,						dtype=jnp.intaa							)
									lowercase__            =      jnp.zeros((1, 1, self.cross_attention_dim)    ,						dtype=jnp.floataa							)
									lowercase__            =      (1, 3, self.sample_size * 8, self.sample_size * 8)
									lowercase__            =      jnp.zeros(UpperCamelCase_    ,						dtype=jnp.floataa							)

									lowercase__     ,		lowercase__            =      jax.random.split(UpperCamelCase_							)
									lowercase__            =      {'''params''': params_rng, '''dropout''': dropout_rng}

									return self.init(UpperCamelCase_    ,						UpperCamelCase_    ,						UpperCamelCase_    ,						UpperCamelCase_    ,						UpperCamelCase_							)["params"]

							def       lowerCamelCase_ (							self:	Optional[int]							)			->   List[str]:





									"""simple docstring"""







									lowercase__            =      self.block_out_channels
									lowercase__            =      block_out_channels[0] * 4

									# If `num_attention_heads` is not defined (which is the case for most models)
									# it will default to `attention_head_dim`. This looks weird upon first reading it and it is.
									# The reason for this behavior is to correct for incorrectly named variables that were introduced
									# when this library was created. The incorrect naming was only discovered much later in https://github.com/huggingface/diffusers/issues/2011#issuecomment-1547958131
									# Changing `attention_head_dim` to `num_attention_heads` for 40,000+ configurations is too backwards breaking
									# which is why we correct for the naming here.
									lowercase__            =      self.num_attention_heads or self.attention_head_dim

									# input
									lowercase__            =      nn.Conv(
									    block_out_channels[0]    ,						kernel_size=(3, 3)    ,						strides=(1, 1)    ,						padding=((1, 1), (1, 1))    ,						dtype=self.dtype    ,						)

									# time
									lowercase__            =      FlaxTimesteps(
									    block_out_channels[0]    ,						flip_sin_to_cos=self.flip_sin_to_cos    ,						freq_shift=self.config.freq_shift							)
									lowercase__            =      FlaxTimestepEmbedding(UpperCamelCase_    ,						dtype=self.dtype							)

									lowercase__            =      FlaxControlNetConditioningEmbedding(
									    conditioning_embedding_channels=block_out_channels[0]    ,						block_out_channels=self.conditioning_embedding_out_channels    ,						)

									lowercase__            =      self.only_cross_attention
									if isinstance(UpperCamelCase_    ,						UpperCamelCase_							):
											lowercase__            =      (only_cross_attention,) * len(self.down_block_types							)

									if isinstance(UpperCamelCase_    ,						UpperCamelCase_							):
											lowercase__            =      (num_attention_heads,) * len(self.down_block_types							)

									# down
									lowercase__            =      []
									lowercase__            =      []

									lowercase__            =      block_out_channels[0]

									lowercase__            =      nn.Conv(
									    UpperCamelCase_    ,						kernel_size=(1, 1)    ,						padding='''VALID'''    ,						kernel_init=nn.initializers.zeros_init()    ,						bias_init=nn.initializers.zeros_init()    ,						dtype=self.dtype    ,						)
									controlnet_down_blocks.append(UpperCamelCase_							)

									for i, down_block_type in enumerate(self.down_block_types							):
											lowercase__            =      output_channel
											lowercase__            =      block_out_channels[i]
											lowercase__            =      i == len(UpperCamelCase_							) - 1

											if down_block_type == "CrossAttnDownBlock2D":
													lowercase__            =      FlaxCrossAttnDownBlockaD(
													    in_channels=UpperCamelCase_    ,						out_channels=UpperCamelCase_    ,						dropout=self.dropout    ,						num_layers=self.layers_per_block    ,						num_attention_heads=num_attention_heads[i]    ,						add_downsample=not is_final_block    ,						use_linear_projection=self.use_linear_projection    ,						only_cross_attention=only_cross_attention[i]    ,						dtype=self.dtype    ,						)
											else:
													lowercase__            =      FlaxDownBlockaD(
													    in_channels=UpperCamelCase_    ,						out_channels=UpperCamelCase_    ,						dropout=self.dropout    ,						num_layers=self.layers_per_block    ,						add_downsample=not is_final_block    ,						dtype=self.dtype    ,						)

											down_blocks.append(UpperCamelCase_							)

											for _ in range(self.layers_per_block							):
													lowercase__            =      nn.Conv(
													    UpperCamelCase_    ,						kernel_size=(1, 1)    ,						padding='''VALID'''    ,						kernel_init=nn.initializers.zeros_init()    ,						bias_init=nn.initializers.zeros_init()    ,						dtype=self.dtype    ,						)
													controlnet_down_blocks.append(UpperCamelCase_							)

											if not is_final_block:
													lowercase__            =      nn.Conv(
													    UpperCamelCase_    ,						kernel_size=(1, 1)    ,						padding='''VALID'''    ,						kernel_init=nn.initializers.zeros_init()    ,						bias_init=nn.initializers.zeros_init()    ,						dtype=self.dtype    ,						)
													controlnet_down_blocks.append(UpperCamelCase_							)

									lowercase__            =      down_blocks
									lowercase__            =      controlnet_down_blocks

									# mid
									lowercase__            =      block_out_channels[-1]
									lowercase__            =      FlaxUNetMidBlockaDCrossAttn(
									    in_channels=UpperCamelCase_    ,						dropout=self.dropout    ,						num_attention_heads=num_attention_heads[-1]    ,						use_linear_projection=self.use_linear_projection    ,						dtype=self.dtype    ,						)

									lowercase__            =      nn.Conv(
									    UpperCamelCase_    ,						kernel_size=(1, 1)    ,						padding='''VALID'''    ,						kernel_init=nn.initializers.zeros_init()    ,						bias_init=nn.initializers.zeros_init()    ,						dtype=self.dtype    ,						)


							def __call__(							self:	Dict    ,						UpperCamelCase_:	Union[str, Any]    ,						UpperCamelCase_:	Any    ,						UpperCamelCase_:	Optional[Any]    ,						UpperCamelCase_:	List[Any]    ,						UpperCamelCase_:	float = 1.0    ,						UpperCamelCase_:	bool = True    ,						UpperCamelCase_:	bool = False    ,						)			->   Union[FlaxControlNetOutput, Tuple]:





									"""simple docstring"""







									lowercase__            =      self.controlnet_conditioning_channel_order
									if channel_order == "bgr":
											lowercase__            =      jnp.flip(UpperCamelCase_    ,						axis=1							)

									# 1. time
									if not isinstance(UpperCamelCase_    ,						jnp.ndarray							):
											lowercase__            =      jnp.array([timesteps]    ,						dtype=jnp.intaa							)
									elif isinstance(UpperCamelCase_    ,						jnp.ndarray							) and len(timesteps.shape							) == 0:
											lowercase__            =      timesteps.astype(dtype=jnp.floataa							)
											lowercase__            =      jnp.expand_dims(UpperCamelCase_    ,						0							)

									lowercase__            =      self.time_proj(UpperCamelCase_							)
									lowercase__            =      self.time_embedding(UpperCamelCase_							)

									# 2. pre-process
									lowercase__            =      jnp.transpose(UpperCamelCase_    ,						(0, 2, 3, 1)							)
									lowercase__            =      self.conv_in(UpperCamelCase_							)

									lowercase__            =      jnp.transpose(UpperCamelCase_    ,						(0, 2, 3, 1)							)
									lowercase__            =      self.controlnet_cond_embedding(UpperCamelCase_							)
									sample += controlnet_cond

									# 3. down
									lowercase__            =      (sample,)
									for down_block in self.down_blocks:
											if isinstance(UpperCamelCase_    ,						UpperCamelCase_							):
													lowercase__     ,		lowercase__            =      down_block(UpperCamelCase_    ,						UpperCamelCase_    ,						UpperCamelCase_    ,						deterministic=not train							)
											else:
													lowercase__     ,		lowercase__            =      down_block(UpperCamelCase_    ,						UpperCamelCase_    ,						deterministic=not train							)
											down_block_res_samples += res_samples

									# 4. mid
									lowercase__            =      self.mid_block(UpperCamelCase_    ,						UpperCamelCase_    ,						UpperCamelCase_    ,						deterministic=not train							)

									# 5. contronet blocks
									lowercase__            =      ()
									for down_block_res_sample, controlnet_block in zip(UpperCamelCase_    ,						self.controlnet_down_blocks							):
											lowercase__            =      controlnet_block(UpperCamelCase_							)
											controlnet_down_block_res_samples += (down_block_res_sample,)

									lowercase__            =      controlnet_down_block_res_samples

									lowercase__            =      self.controlnet_mid_block(UpperCamelCase_							)

									# 6. scaling
									lowercase__            =      [sample * conditioning_scale for sample in down_block_res_samples]
									mid_block_res_sample *= conditioning_scale

									if not return_dict:
											return (down_block_res_samples, mid_block_res_sample)

									return FlaxControlNetOutput(
									    down_block_res_samples=UpperCamelCase_    ,						mid_block_res_sample=UpperCamelCase_							)






from pickle import UnpicklingError

import jax
import jax.numpy as jnp
import numpy as np
from flax.serialization import from_bytes
from flax.traverse_util import flatten_dict

from ..utils import logging


lowerCAmelCase       =							logging.get_logger(__name__)
def 			_a (      SCREAMING_SNAKE_CASE						,				SCREAMING_SNAKE_CASE     ):


		"""simple docstring"""




		try:
				with open(SCREAMING_SNAKE_CASE						,				'''rb'''     ) as flax_state_f:
						lowercase__            =      from_bytes(SCREAMING_SNAKE_CASE						,				flax_state_f.read()     )
		except UnpicklingError as e:
				try:
						with open(SCREAMING_SNAKE_CASE     ) as f:
								if f.read().startswith('''version'''     ):
										raise OSError(
										    '''You seem to have cloned a repository without having git-lfs installed. Please'''
										    ''' install git-lfs and run `git lfs install` followed by `git lfs pull` in the'''
										    ''' folder you cloned.'''     )
								else:
										raise ValueError from e
				except (UnicodeDecodeError, ValueError):
						raise EnvironmentError(f'Unable to convert {model_file} to Flax deserializable object. '     )

		return load_flax_weights_in_pytorch_model(SCREAMING_SNAKE_CASE						,				SCREAMING_SNAKE_CASE     )
def 			_a (      SCREAMING_SNAKE_CASE						,				SCREAMING_SNAKE_CASE     ):


		"""simple docstring"""




		try:
				import torch  # noqa: F401
		except ImportError:
				logger.error(
				    '''Loading Flax weights in PyTorch requires both PyTorch and Flax to be installed. Please see'''
				    ''' https://pytorch.org/ and https://flax.readthedocs.io/en/latest/installation.html for installation'''
				    ''' instructions.'''     )
				raise

		# check if we have bf16 weights
		lowercase__            =      flatten_dict(jax.tree_util.tree_map(lambda SCREAMING_SNAKE_CASE     : x.dtype == jnp.bfloataa						,				SCREAMING_SNAKE_CASE     )     ).values()
		if any(SCREAMING_SNAKE_CASE     ):
				# convert all weights to fp32 if they are bf16 since torch.from_numpy can-not handle bf16

				# and bf16 is not fully supported in PT yet.
				logger.warning(
				    '''Found ``bfloat16`` weights in Flax model. Casting all ``bfloat16`` weights to ``float32`` '''
				    '''before loading those in PyTorch model.'''     )
				lowercase__            =      jax.tree_util.tree_map(
				    lambda SCREAMING_SNAKE_CASE     : params.astype(np.floataa     ) if params.dtype == jnp.bfloataa else params						,				SCREAMING_SNAKE_CASE     )

		lowercase__            =      ''''''

		lowercase__            =      flatten_dict(SCREAMING_SNAKE_CASE						,				sep='''.'''     )
		lowercase__            =      pt_model.state_dict()

		# keep track of unexpected & missing keys
		lowercase__            =      []
		lowercase__            =      set(pt_model_dict.keys()     )

		for flax_key_tuple, flax_tensor in flax_state_dict.items():
				lowercase__            =      flax_key_tuple.split('''.'''     )

				if flax_key_tuple_array[-1] == "kernel" and flax_tensor.ndim == 4:
						lowercase__            =      flax_key_tuple_array[:-1] + ['''weight''']
						lowercase__            =      jnp.transpose(SCREAMING_SNAKE_CASE						,				(3, 2, 0, 1)     )
				elif flax_key_tuple_array[-1] == "kernel":
						lowercase__            =      flax_key_tuple_array[:-1] + ['''weight''']
						lowercase__            =      flax_tensor.T
				elif flax_key_tuple_array[-1] == "scale":
						lowercase__            =      flax_key_tuple_array[:-1] + ['''weight''']

				if "time_embedding" not in flax_key_tuple_array:
						for i, flax_key_tuple_string in enumerate(SCREAMING_SNAKE_CASE     ):
								lowercase__            =      (
								    flax_key_tuple_string.replace('''_0'''						,				'''.0'''     )
								    .replace('''_1'''						,				'''.1'''     )
								    .replace('''_2'''						,				'''.2'''     )
								    .replace('''_3'''						,				'''.3'''     )
								    .replace('''_4'''						,				'''.4'''     )
								    .replace('''_5'''						,				'''.5'''     )
								    .replace('''_6'''						,				'''.6'''     )
								    .replace('''_7'''						,				'''.7'''     )
								    .replace('''_8'''						,				'''.8'''     )
								    .replace('''_9'''						,				'''.9'''     )
								)

				lowercase__            =      '''.'''.join(SCREAMING_SNAKE_CASE     )

				if flax_key in pt_model_dict:
						if flax_tensor.shape != pt_model_dict[flax_key].shape:
								raise ValueError(
								    f'Flax checkpoint seems to be incorrect. Weight {flax_key_tuple} was expected '
								    f'to be of shape {pt_model_dict[flax_key].shape}, but is {flax_tensor.shape}.'     )
						else:
								# add weight to pytorch dict
								lowercase__            =      np.asarray(SCREAMING_SNAKE_CASE     ) if not isinstance(SCREAMING_SNAKE_CASE						,				np.ndarray     ) else flax_tensor
								lowercase__            =      torch.from_numpy(SCREAMING_SNAKE_CASE     )
								# remove from missing keys
								missing_keys.remove(SCREAMING_SNAKE_CASE     )
				else:
						# weight is not expected by PyTorch model
						unexpected_keys.append(SCREAMING_SNAKE_CASE     )

		pt_model.load_state_dict(SCREAMING_SNAKE_CASE     )

		# re-transform missing_keys to list
		lowercase__            =      list(SCREAMING_SNAKE_CASE     )

		if len(SCREAMING_SNAKE_CASE     ) > 0:
				logger.warning(
				    '''Some weights of the Flax model were not used when initializing the PyTorch model'''
				    f' {pt_model.__class__.__name__}: {unexpected_keys}\n- This IS expected if you are initializing'
				    f' {pt_model.__class__.__name__} from a Flax model trained on another task or with another architecture'
				    ''' (e.g. initializing a BertForSequenceClassification model from a FlaxBertForPreTraining model).\n- This'''
				    f' IS NOT expected if you are initializing {pt_model.__class__.__name__} from a Flax model that you expect'
				    ''' to be exactly identical (e.g. initializing a BertForSequenceClassification model from a'''
				    ''' FlaxBertForSequenceClassification model).'''     )
		if len(SCREAMING_SNAKE_CASE     ) > 0:
				logger.warning(
				    f'Some weights of {pt_model.__class__.__name__} were not initialized from the Flax model and are newly'
				    f' initialized: {missing_keys}\nYou should probably TRAIN this model on a down-stream task to be able to'
				    ''' use it for predictions and inference.'''     )

		return pt_model


