import argparse
import json
import os

import numpy as np
import PIL
import requests
import tensorflow.keras.applications.efficientnet as efficientnet
import torch
from huggingface_hub import hf_hub_download
from PIL import Image
from tensorflow.keras.preprocessing import image

from transformers import (
    EfficientNetConfig,
    EfficientNetForImageClassification,
    EfficientNetImageProcessor,
)
from transformers.utils import logging


logging.set_verbosity_info()
lowercase_     :   Optional[int] 				=				logging.get_logger(__name__)

lowercase_     :   Union[str, Any] 				=				{
    'b0': efficientnet.EfficientNetBa,
    'b1': efficientnet.EfficientNetBa,
    'b2': efficientnet.EfficientNetBa,
    'b3': efficientnet.EfficientNetBa,
    'b4': efficientnet.EfficientNetBa,
    'b5': efficientnet.EfficientNetBa,
    'b6': efficientnet.EfficientNetBa,
    'b7': efficientnet.EfficientNetBa,
}

lowercase_     :   Dict 				=				{
    'b0': {
        'hidden_dim': 1_2_8_0,
        'width_coef': 1.0,
        'depth_coef': 1.0,
        'image_size': 2_2_4,
        'dropout_rate': 0.2,
        'dw_padding': [],
    },
    'b1': {
        'hidden_dim': 1_2_8_0,
        'width_coef': 1.0,
        'depth_coef': 1.1,
        'image_size': 2_4_0,
        'dropout_rate': 0.2,
        'dw_padding': [1_6],
    },
    'b2': {
        'hidden_dim': 1_4_0_8,
        'width_coef': 1.1,
        'depth_coef': 1.2,
        'image_size': 2_6_0,
        'dropout_rate': 0.3,
        'dw_padding': [5, 8, 1_6],
    },
    'b3': {
        'hidden_dim': 1_5_3_6,
        'width_coef': 1.2,
        'depth_coef': 1.4,
        'image_size': 3_0_0,
        'dropout_rate': 0.3,
        'dw_padding': [5, 1_8],
    },
    'b4': {
        'hidden_dim': 1_7_9_2,
        'width_coef': 1.4,
        'depth_coef': 1.8,
        'image_size': 3_8_0,
        'dropout_rate': 0.4,
        'dw_padding': [6],
    },
    'b5': {
        'hidden_dim': 2_0_4_8,
        'width_coef': 1.6,
        'depth_coef': 2.2,
        'image_size': 4_5_6,
        'dropout_rate': 0.4,
        'dw_padding': [1_3, 2_7],
    },
    'b6': {
        'hidden_dim': 2_3_0_4,
        'width_coef': 1.8,
        'depth_coef': 2.6,
        'image_size': 5_2_8,
        'dropout_rate': 0.5,
        'dw_padding': [3_1],
    },
    'b7': {
        'hidden_dim': 2_5_6_0,
        'width_coef': 2.0,
        'depth_coef': 3.1,
        'image_size': 6_0_0,
        'dropout_rate': 0.5,
        'dw_padding': [1_8],
    },
}







def 			A__      (	snake_case_ :		Optional[int]      ):
 SCREAMING_SNAKE_CASE__:   Optional[Any]=      EfficientNetConfig()
 SCREAMING_SNAKE_CASE__:   str=      CONFIG_MAP[model_name]['''hidden_dim''']
 SCREAMING_SNAKE_CASE__:   Any=      CONFIG_MAP[model_name]['''width_coef''']
 SCREAMING_SNAKE_CASE__:   List[str]=      CONFIG_MAP[model_name]['''depth_coef''']
 SCREAMING_SNAKE_CASE__:   str=      CONFIG_MAP[model_name]['''image_size''']
 SCREAMING_SNAKE_CASE__:   int=      CONFIG_MAP[model_name]['''dropout_rate''']
 SCREAMING_SNAKE_CASE__:   Optional[int]=      CONFIG_MAP[model_name]['''dw_padding''']

 SCREAMING_SNAKE_CASE__:   Union[str, Any]=      '''huggingface/label-files'''
 SCREAMING_SNAKE_CASE__:   List[Any]=      '''imagenet-1k-id2label.json'''
 SCREAMING_SNAKE_CASE__:   Dict=      1_000
 SCREAMING_SNAKE_CASE__:   Union[str, Any]=      json.load(open(hf_hub_download(snake_case_       ,				snake_case_       ,				repo_type='''dataset'''      )       ,				'''r'''      )      )
 SCREAMING_SNAKE_CASE__:   List[str]=      {int(snake_case_      ): v for k, v in idalabel.items()}

 SCREAMING_SNAKE_CASE__:   Optional[int]=      idalabel
 SCREAMING_SNAKE_CASE__:   Union[str, Any]=      {v: k for k, v in idalabel.items()}
 return config







def 			A__      (	):
 SCREAMING_SNAKE_CASE__:   Optional[Any]=      '''http://images.cocodataset.org/val2017/000000039769.jpg'''
 SCREAMING_SNAKE_CASE__:   List[Any]=      Image.open(requests.get(snake_case_       ,				stream=snake_case_      ).raw      )
 return im







def 			A__      (	snake_case_ :		str      ):
 SCREAMING_SNAKE_CASE__:   Union[str, Any]=      CONFIG_MAP[model_name]['''image_size''']
 SCREAMING_SNAKE_CASE__:   int=      EfficientNetImageProcessor(
     size={'''height''': size, '''width''': size}       ,				image_mean=[0.4_85, 0.4_56, 0.4_06]       ,				image_std=[0.47_85_39_44, 0.4_73_28_64, 0.47_43_41_63]       ,				do_center_crop=snake_case_       ,				)
 return preprocessor







def 			A__      (	snake_case_ :		Optional[int]      ):
 SCREAMING_SNAKE_CASE__:   Any=      [v.split('''_'''      )[0].split('''block'''      )[1] for v in original_param_names if v.startswith('''block'''      )]
 SCREAMING_SNAKE_CASE__:   Any=      sorted(set(snake_case_      )      )
 SCREAMING_SNAKE_CASE__:   int=      len(snake_case_      )
 SCREAMING_SNAKE_CASE__:   Dict=      {b: str(snake_case_      ) for b, i in zip(snake_case_       ,				range(snake_case_      )      )}

 SCREAMING_SNAKE_CASE__:   Tuple=      []
 rename_keys.append(('''stem_conv/kernel:0''', '''embeddings.convolution.weight''')      )
 rename_keys.append(('''stem_bn/gamma:0''', '''embeddings.batchnorm.weight''')      )
 rename_keys.append(('''stem_bn/beta:0''', '''embeddings.batchnorm.bias''')      )
 rename_keys.append(('''stem_bn/moving_mean:0''', '''embeddings.batchnorm.running_mean''')      )
 rename_keys.append(('''stem_bn/moving_variance:0''', '''embeddings.batchnorm.running_var''')      )

 for b in block_names:
  SCREAMING_SNAKE_CASE__:   Optional[int]=      block_name_mapping[b]
  rename_keys.append((F'block{b}_expand_conv/kernel:0', F'encoder.blocks.{hf_b}.expansion.expand_conv.weight')      )
  rename_keys.append((F'block{b}_expand_bn/gamma:0', F'encoder.blocks.{hf_b}.expansion.expand_bn.weight')      )
  rename_keys.append((F'block{b}_expand_bn/beta:0', F'encoder.blocks.{hf_b}.expansion.expand_bn.bias')      )
  rename_keys.append(
      (F'block{b}_expand_bn/moving_mean:0', F'encoder.blocks.{hf_b}.expansion.expand_bn.running_mean')      )
  rename_keys.append(
      (F'block{b}_expand_bn/moving_variance:0', F'encoder.blocks.{hf_b}.expansion.expand_bn.running_var')      )
  rename_keys.append(
      (F'block{b}_dwconv/depthwise_kernel:0', F'encoder.blocks.{hf_b}.depthwise_conv.depthwise_conv.weight')      )
  rename_keys.append((F'block{b}_bn/gamma:0', F'encoder.blocks.{hf_b}.depthwise_conv.depthwise_norm.weight')      )
  rename_keys.append((F'block{b}_bn/beta:0', F'encoder.blocks.{hf_b}.depthwise_conv.depthwise_norm.bias')      )
  rename_keys.append(
      (F'block{b}_bn/moving_mean:0', F'encoder.blocks.{hf_b}.depthwise_conv.depthwise_norm.running_mean')      )
  rename_keys.append(
      (F'block{b}_bn/moving_variance:0', F'encoder.blocks.{hf_b}.depthwise_conv.depthwise_norm.running_var')      )

  rename_keys.append((F'block{b}_se_reduce/kernel:0', F'encoder.blocks.{hf_b}.squeeze_excite.reduce.weight')      )
  rename_keys.append((F'block{b}_se_reduce/bias:0', F'encoder.blocks.{hf_b}.squeeze_excite.reduce.bias')      )
  rename_keys.append((F'block{b}_se_expand/kernel:0', F'encoder.blocks.{hf_b}.squeeze_excite.expand.weight')      )
  rename_keys.append((F'block{b}_se_expand/bias:0', F'encoder.blocks.{hf_b}.squeeze_excite.expand.bias')      )
  rename_keys.append(
      (F'block{b}_project_conv/kernel:0', F'encoder.blocks.{hf_b}.projection.project_conv.weight')      )
  rename_keys.append((F'block{b}_project_bn/gamma:0', F'encoder.blocks.{hf_b}.projection.project_bn.weight')      )
  rename_keys.append((F'block{b}_project_bn/beta:0', F'encoder.blocks.{hf_b}.projection.project_bn.bias')      )
  rename_keys.append(
      (F'block{b}_project_bn/moving_mean:0', F'encoder.blocks.{hf_b}.projection.project_bn.running_mean')      )
  rename_keys.append(
      (F'block{b}_project_bn/moving_variance:0', F'encoder.blocks.{hf_b}.projection.project_bn.running_var')      )

 rename_keys.append(('''top_conv/kernel:0''', '''encoder.top_conv.weight''')      )
 rename_keys.append(('''top_bn/gamma:0''', '''encoder.top_bn.weight''')      )
 rename_keys.append(('''top_bn/beta:0''', '''encoder.top_bn.bias''')      )
 rename_keys.append(('''top_bn/moving_mean:0''', '''encoder.top_bn.running_mean''')      )
 rename_keys.append(('''top_bn/moving_variance:0''', '''encoder.top_bn.running_var''')      )

 SCREAMING_SNAKE_CASE__:   Union[str, Any]=      {}
 for item in rename_keys:
  if item[0] in original_param_names:
   SCREAMING_SNAKE_CASE__:   Optional[int]=      '''efficientnet.''' + item[1]

 SCREAMING_SNAKE_CASE__:   List[str]=      '''classifier.weight'''
 SCREAMING_SNAKE_CASE__:   Tuple=      '''classifier.bias'''
 return key_mapping







def 			A__      (	snake_case_ :		Optional[Any]       ,				snake_case_ :		int       ,				snake_case_ :		Optional[int]      ):
 for key, value in tf_params.items():
  if "normalization" in key:
   continue

  SCREAMING_SNAKE_CASE__:   Optional[Any]=      key_mapping[key]
  if "_conv" in key and "kernel" in key:
   SCREAMING_SNAKE_CASE__:   Union[str, Any]=      torch.from_numpy(snake_case_      ).permute(3       ,				2       ,				0       ,				1      )
  elif "depthwise_kernel" in key:
   SCREAMING_SNAKE_CASE__:   List[str]=      torch.from_numpy(snake_case_      ).permute(2       ,				3       ,				0       ,				1      )
  elif "kernel" in key:
   SCREAMING_SNAKE_CASE__:   Optional[Any]=      torch.from_numpy(np.transpose(snake_case_      )      )
  else:
   SCREAMING_SNAKE_CASE__:   Tuple=      torch.from_numpy(snake_case_      )

  # Replace HF parameters with original TF model parameters
  assert hf_params[hf_key].shape == new_hf_value.shape
  hf_params[hf_key].copy_(snake_case_      )







@torch.no_grad()
def 			A__      (	snake_case_ :		Union[str, Any]       ,				snake_case_ :		Optional[int]       ,				snake_case_ :		List[Any]       ,				snake_case_ :		Union[str, Any]      ):
 SCREAMING_SNAKE_CASE__:   List[str]=      model_classes[model_name](
     include_top=snake_case_       ,				weights='''imagenet'''       ,				input_tensor=snake_case_       ,				input_shape=snake_case_       ,				pooling=snake_case_       ,				classes=1_000       ,				classifier_activation='''softmax'''       ,				)

 SCREAMING_SNAKE_CASE__:   List[Any]=      original_model.trainable_variables
 SCREAMING_SNAKE_CASE__:   List[str]=      original_model.non_trainable_variables
 SCREAMING_SNAKE_CASE__:   Optional[Any]=      {param.name: param.numpy() for param in tf_params}
 for param in tf_non_train_params:
  SCREAMING_SNAKE_CASE__:   Tuple=      param.numpy()
 SCREAMING_SNAKE_CASE__:   Optional[int]=      list(tf_params.keys()      )

 # Load HuggingFace model
 SCREAMING_SNAKE_CASE__:   int=      get_efficientnet_config(snake_case_      )
 SCREAMING_SNAKE_CASE__:   Optional[int]=      EfficientNetForImageClassification(snake_case_      ).eval()
 SCREAMING_SNAKE_CASE__:   Any=      hf_model.state_dict()

 # Create src-to-dst parameter name mapping dictionary
 print('''Converting parameters...'''      )
 SCREAMING_SNAKE_CASE__:   Tuple=      rename_keys(snake_case_      )
 replace_params(snake_case_       ,				snake_case_       ,				snake_case_      )

 # Initialize preprocessor and preprocess input image
 SCREAMING_SNAKE_CASE__:   Union[str, Any]=      convert_image_processor(snake_case_      )
 SCREAMING_SNAKE_CASE__:   int=      preprocessor(images=prepare_img()       ,				return_tensors='''pt'''      )

 # HF model inference
 hf_model.eval()
 with torch.no_grad():
  SCREAMING_SNAKE_CASE__:   Union[str, Any]=      hf_model(**snake_case_      )
 SCREAMING_SNAKE_CASE__:   Optional[int]=      outputs.logits.detach().numpy()

 # Original model inference
 SCREAMING_SNAKE_CASE__:   int=      False
 SCREAMING_SNAKE_CASE__:   int=      CONFIG_MAP[model_name]['''image_size''']
 SCREAMING_SNAKE_CASE__:   Dict=      prepare_img().resize((image_size, image_size)       ,				resample=PIL.Image.NEAREST      )
 SCREAMING_SNAKE_CASE__:   List[str]=      image.img_to_array(snake_case_      )
 SCREAMING_SNAKE_CASE__:   Union[str, Any]=      np.expand_dims(snake_case_       ,				axis=0      )
 SCREAMING_SNAKE_CASE__:   int=      original_model.predict(snake_case_      )

 # Check whether original and HF model outputs match  -> np.allclose
 assert np.allclose(snake_case_       ,				snake_case_       ,				atol=1E-3      ), "The predicted logits are not the same."
 print('''Model outputs match!'''      )

 if save_model:
  # Create folder to save model
  if not os.path.isdir(snake_case_      ):
   os.mkdir(snake_case_      )
  # Save converted model and image processor
  hf_model.save_pretrained(snake_case_      )
  preprocessor.save_pretrained(snake_case_      )

 if push_to_hub:
  # Push model and image processor to hub
  print(F'Pushing converted {model_name} to the hub...'      )
  SCREAMING_SNAKE_CASE__:   Dict=      F'efficientnet-{model_name}'
  preprocessor.push_to_hub(snake_case_      )
  hf_model.push_to_hub(snake_case_      )


if __name__ == "__main__":
      lowercase_     :   Optional[Any] 				=				argparse.ArgumentParser()
      # Required parameters
      parser.add_argument(
          '--model_name',
          default='b0',
          type=str,
          help='Version name of the EfficientNet model you want to convert, select from [b0, b1, b2, b3, b4, b5, b6, b7].',
      )
      parser.add_argument(
          '--pytorch_dump_folder_path',
          default='hf_model',
          type=str,
          help='Path to the output PyTorch model directory.',
      )
      parser.add_argument('--save_model', action='store_true', help='Save model to local')
      parser.add_argument('--push_to_hub', action='store_true', help='Push model and image processor to the hub')

      lowercase_     :   str 				=				parser.parse_args()
      convert_efficientnet_checkpoint(args.model_name, args.pytorch_dump_folder_path, args.save_model, args.push_to_hub)


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 		_lowerCamelCase		(   UpperCamelCase_    ):
    __a  =      42
    __a  =      42






class 		_lowerCamelCase		(   nn.Module    ):
    __a  =      42
    __a  =      (16, 32, 96, 256)
    __a  =      jnp.floataa
    def 						UpperCamelCase_				(  self   )       ->					Optional[int]:
     SCREAMING_SNAKE_CASE__:   List[str]=      nn.Conv(
         self.block_out_channels[0] , kernel_size=(3, 3) , padding=((1, 1), (1, 1)) , dtype=self.dtype , )

     SCREAMING_SNAKE_CASE__:   Optional[int]=      []
     for i in range(len(self.block_out_channels   ) - 1   ):
      SCREAMING_SNAKE_CASE__:   str=      self.block_out_channels[i]
      SCREAMING_SNAKE_CASE__:   List[str]=      self.block_out_channels[i + 1]
      SCREAMING_SNAKE_CASE__:   List[Any]=      nn.Conv(
          lowerCAmelCase , kernel_size=(3, 3) , padding=((1, 1), (1, 1)) , dtype=self.dtype , )
      blocks.append(lowerCAmelCase   )
      SCREAMING_SNAKE_CASE__:   str=      nn.Conv(
          lowerCAmelCase , kernel_size=(3, 3) , strides=(2, 2) , padding=((1, 1), (1, 1)) , dtype=self.dtype , )
      blocks.append(lowerCAmelCase   )
     SCREAMING_SNAKE_CASE__:   str=      blocks

     SCREAMING_SNAKE_CASE__:   Optional[Any]=      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 , lowerCAmelCase   )       ->					Optional[Any]:
     SCREAMING_SNAKE_CASE__:   Dict=      self.conv_in(lowerCAmelCase   )
     SCREAMING_SNAKE_CASE__:   Optional[int]=      nn.silu(lowerCAmelCase   )

     for block in self.blocks:
      SCREAMING_SNAKE_CASE__:   Optional[int]=      block(lowerCAmelCase   )
      SCREAMING_SNAKE_CASE__:   Optional[Any]=      nn.silu(lowerCAmelCase   )

     SCREAMING_SNAKE_CASE__:   Any=      self.conv_out(lowerCAmelCase   )

     return embedding






@flax_register_to_config
class 		_lowerCamelCase		(   nn.Module    ,     UpperCamelCase_    ,     UpperCamelCase_    ):
    __a  =      32
    __a  =      4
    __a  =      (
        "CrossAttnDownBlock2D",
        "CrossAttnDownBlock2D",
        "CrossAttnDownBlock2D",
        "DownBlock2D",
    )
    __a  =      False
    __a  =      (320, 640, 1280, 1280)
    __a  =      2
    __a  =      8
    __a  =      None
    __a  =      1280
    __a  =      0.0
    __a  =      False
    __a  =      jnp.floataa
    __a  =      True
    __a  =      0
    __a  =      "rgb"
    __a  =      (16, 32, 96, 256)
    def 						UpperCamelCase_				(  self , lowerCAmelCase   )       ->					FrozenDict:
     # init input tensors
     SCREAMING_SNAKE_CASE__:   Any=      (1, self.in_channels, self.sample_size, self.sample_size)
     SCREAMING_SNAKE_CASE__:   Union[str, Any]=      jnp.zeros(lowerCAmelCase , dtype=jnp.floataa   )
     SCREAMING_SNAKE_CASE__:   Union[str, Any]=      jnp.ones((1,) , dtype=jnp.intaa   )
     SCREAMING_SNAKE_CASE__:   Optional[Any]=      jnp.zeros((1, 1, self.cross_attention_dim) , dtype=jnp.floataa   )
     SCREAMING_SNAKE_CASE__:   int=      (1, 3, self.sample_size * 8, self.sample_size * 8)
     SCREAMING_SNAKE_CASE__:   Optional[int]=      jnp.zeros(lowerCAmelCase , dtype=jnp.floataa   )

     SCREAMING_SNAKE_CASE__,	SCREAMING_SNAKE_CASE__:   Any=      jax.random.split(lowerCAmelCase   )
     SCREAMING_SNAKE_CASE__:   Optional[int]=      {'''params''': params_rng, '''dropout''': dropout_rng}

     return self.init(lowerCAmelCase , lowerCAmelCase , lowerCAmelCase , lowerCAmelCase , lowerCAmelCase   )["params"]
    def 						UpperCamelCase_				(  self   )       ->					Optional[Any]:
     SCREAMING_SNAKE_CASE__:   Dict=      self.block_out_channels
     SCREAMING_SNAKE_CASE__:   str=      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.
     SCREAMING_SNAKE_CASE__:   int=      self.num_attention_heads or self.attention_head_dim

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

     # time
     SCREAMING_SNAKE_CASE__:   str=      FlaxTimesteps(
         block_out_channels[0] , flip_sin_to_cos=self.flip_sin_to_cos , freq_shift=self.config.freq_shift   )
     SCREAMING_SNAKE_CASE__:   Optional[Any]=      FlaxTimestepEmbedding(lowerCAmelCase , dtype=self.dtype   )

     SCREAMING_SNAKE_CASE__:   str=      FlaxControlNetConditioningEmbedding(
         conditioning_embedding_channels=block_out_channels[0] , block_out_channels=self.conditioning_embedding_out_channels , )

     SCREAMING_SNAKE_CASE__:   List[str]=      self.only_cross_attention
     if isinstance(lowerCAmelCase , lowerCAmelCase   ):
      SCREAMING_SNAKE_CASE__:   str=      (only_cross_attention,) * len(self.down_block_types   )

     if isinstance(lowerCAmelCase , lowerCAmelCase   ):
      SCREAMING_SNAKE_CASE__:   Dict=      (num_attention_heads,) * len(self.down_block_types   )

     # down
     SCREAMING_SNAKE_CASE__:   Optional[int]=      []
     SCREAMING_SNAKE_CASE__:   List[str]=      []

     SCREAMING_SNAKE_CASE__:   Union[str, Any]=      block_out_channels[0]

     SCREAMING_SNAKE_CASE__:   Dict=      nn.Conv(
         lowerCAmelCase , 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(lowerCAmelCase   )

     for i, down_block_type in enumerate(self.down_block_types   ):
      SCREAMING_SNAKE_CASE__:   Tuple=      output_channel
      SCREAMING_SNAKE_CASE__:   Any=      block_out_channels[i]
      SCREAMING_SNAKE_CASE__:   Optional[Any]=      i == len(lowerCAmelCase   ) - 1

      if down_block_type == "CrossAttnDownBlock2D":
       SCREAMING_SNAKE_CASE__:   Any=      FlaxCrossAttnDownBlockaD(
           in_channels=lowerCAmelCase , out_channels=lowerCAmelCase , 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:
       SCREAMING_SNAKE_CASE__:   Union[str, Any]=      FlaxDownBlockaD(
           in_channels=lowerCAmelCase , out_channels=lowerCAmelCase , dropout=self.dropout , num_layers=self.layers_per_block , add_downsample=not is_final_block , dtype=self.dtype , )

      down_blocks.append(lowerCAmelCase   )

      for _ in range(self.layers_per_block   ):
       SCREAMING_SNAKE_CASE__:   str=      nn.Conv(
           lowerCAmelCase , 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(lowerCAmelCase   )

      if not is_final_block:
       SCREAMING_SNAKE_CASE__:   str=      nn.Conv(
           lowerCAmelCase , 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(lowerCAmelCase   )

     SCREAMING_SNAKE_CASE__:   int=      down_blocks
     SCREAMING_SNAKE_CASE__:   int=      controlnet_down_blocks

     # mid
     SCREAMING_SNAKE_CASE__:   Optional[int]=      block_out_channels[-1]
     SCREAMING_SNAKE_CASE__:   int=      FlaxUNetMidBlockaDCrossAttn(
         in_channels=lowerCAmelCase , dropout=self.dropout , num_attention_heads=num_attention_heads[-1] , use_linear_projection=self.use_linear_projection , dtype=self.dtype , )

     SCREAMING_SNAKE_CASE__:   str=      nn.Conv(
         lowerCAmelCase , kernel_size=(1, 1) , padding='''VALID''' , kernel_init=nn.initializers.zeros_init() , bias_init=nn.initializers.zeros_init() , dtype=self.dtype , )



    def __call__(  self , lowerCAmelCase , lowerCAmelCase , lowerCAmelCase , lowerCAmelCase , lowerCAmelCase = 1.0 , lowerCAmelCase = True , lowerCAmelCase = False , )       ->					Union[FlaxControlNetOutput, Tuple]:
     SCREAMING_SNAKE_CASE__:   Dict=      self.controlnet_conditioning_channel_order
     if channel_order == "bgr":
      SCREAMING_SNAKE_CASE__:   Optional[Any]=      jnp.flip(lowerCAmelCase , axis=1   )

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

     SCREAMING_SNAKE_CASE__:   Dict=      self.time_proj(lowerCAmelCase   )
     SCREAMING_SNAKE_CASE__:   Dict=      self.time_embedding(lowerCAmelCase   )

     # 2. pre-process
     SCREAMING_SNAKE_CASE__:   int=      jnp.transpose(lowerCAmelCase , (0, 2, 3, 1)   )
     SCREAMING_SNAKE_CASE__:   str=      self.conv_in(lowerCAmelCase   )

     SCREAMING_SNAKE_CASE__:   Optional[Any]=      jnp.transpose(lowerCAmelCase , (0, 2, 3, 1)   )
     SCREAMING_SNAKE_CASE__:   str=      self.controlnet_cond_embedding(lowerCAmelCase   )
     sample += controlnet_cond

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

     # 4. mid
     SCREAMING_SNAKE_CASE__:   Optional[Any]=      self.mid_block(lowerCAmelCase , lowerCAmelCase , lowerCAmelCase , deterministic=not train   )

     # 5. contronet blocks
     SCREAMING_SNAKE_CASE__:   Optional[int]=      ()
     for down_block_res_sample, controlnet_block in zip(lowerCAmelCase , self.controlnet_down_blocks   ):
      SCREAMING_SNAKE_CASE__:   List[str]=      controlnet_block(lowerCAmelCase   )
      controlnet_down_block_res_samples += (down_block_res_sample,)

     SCREAMING_SNAKE_CASE__:   Optional[Any]=      controlnet_down_block_res_samples

     SCREAMING_SNAKE_CASE__:   Optional[int]=      self.controlnet_mid_block(lowerCAmelCase   )

     # 6. scaling
     SCREAMING_SNAKE_CASE__:   Tuple=      [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=lowerCAmelCase , mid_block_res_sample=lowerCAmelCase   )

