





from typing import Optional, Tuple

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

from transformers import FLAX_MODEL_MAPPING, FlaxCLIPVisionModel
from transformers.modeling_flax_utils import FlaxPreTrainedModel
from transformers.models.clip.modeling_flax_clip import FlaxCLIPOutput
from transformers.utils import logging


__lowercase				    =      logging.get_logger(__name__)

class 	__snake_case					(      nn.Module ):






    '''simple docstring'''
    _lowerCAmelCase  =						42
    _lowerCAmelCase  =						jnp.floataa





    def 						A		( self    :		Optional[Any]				):

      """simple docstring"""





      __lowerCAmelCase								=					self.config.text_config
      __lowerCAmelCase								=					self.config.vision_config

      __lowerCAmelCase								=					self.config.projection_dim
      __lowerCAmelCase								=					text_config.hidden_size
      __lowerCAmelCase								=					vision_config.hidden_size

      __lowerCAmelCase								=					FLAX_MODEL_MAPPING[self.config.text_config.__class__].module_class
      __lowerCAmelCase								=					FLAX_MODEL_MAPPING.get(self.config.vision_config.__class__      ,    snake_case				).module_class

      __lowerCAmelCase								=					text_module(snake_case      ,    dtype=self.dtype				)
      __lowerCAmelCase								=					vision_module(snake_case      ,    dtype=self.dtype				)

      __lowerCAmelCase								=					nn.Dense(
          self.projection_dim      ,    dtype=self.dtype      ,    kernel_init=jax.nn.initializers.normal(0.02				)      ,    use_bias=snake_case      ,    )
      __lowerCAmelCase								=					nn.Dense(
          self.projection_dim      ,    dtype=self.dtype      ,    kernel_init=jax.nn.initializers.normal(0.02				)      ,    use_bias=snake_case      ,    )
      __lowerCAmelCase								=					self.param('''logit_scale'''      ,    jax.nn.initializers.ones      ,    []				)





    def __call__( self    :		Optional[int]      ,    snake_case    :		str=None      ,    snake_case    :		Dict=None      ,    snake_case    :		int=None      ,    snake_case    :		Any=None      ,    snake_case    :		List[str]=None      ,    snake_case    :		bool = True      ,    snake_case    :		Dict=None      ,    snake_case    :		List[Any]=None      ,    snake_case    :		Any=None      ,    ):

      """simple docstring"""





      __lowerCAmelCase								=					return_dict if return_dict is not None else self.config.return_dict

      __lowerCAmelCase								=					self.vision_model(
          pixel_values=snake_case      ,    deterministic=snake_case      ,    output_attentions=snake_case      ,    output_hidden_states=snake_case      ,    return_dict=snake_case      ,    )

      __lowerCAmelCase								=					self.text_model(
          input_ids=snake_case      ,    attention_mask=snake_case      ,    token_type_ids=snake_case      ,    position_ids=snake_case      ,    deterministic=snake_case      ,    output_attentions=snake_case      ,    output_hidden_states=snake_case      ,    return_dict=snake_case      ,    )

      __lowerCAmelCase								=					vision_outputs[1]
      __lowerCAmelCase								=					self.visual_projection(snake_case				)

      __lowerCAmelCase								=					text_outputs[1]
      __lowerCAmelCase								=					self.text_projection(snake_case				)

      # normalized features
      __lowerCAmelCase								=					image_embeds / jnp.linalg.norm(snake_case      ,    axis=-1      ,    keepdims=snake_case				)
      __lowerCAmelCase								=					text_embeds / jnp.linalg.norm(snake_case      ,    axis=-1      ,    keepdims=snake_case				)

      # cosine similarity as logits
      __lowerCAmelCase								=					jnp.exp(self.logit_scale				)
      __lowerCAmelCase								=					jnp.matmul(snake_case      ,    image_embeds.T				) * logit_scale
      __lowerCAmelCase								=					logits_per_text.T

      if not return_dict:
        return (logits_per_image, logits_per_text, text_embeds, image_embeds, text_outputs, vision_outputs)

      return FlaxCLIPOutput(
          logits_per_image=snake_case      ,    logits_per_text=snake_case      ,    text_embeds=snake_case      ,    image_embeds=snake_case      ,    text_model_output=snake_case      ,    vision_model_output=snake_case      ,    )


class 	__snake_case					(      _a ):






    '''simple docstring'''
    _lowerCAmelCase  =						HybridCLIPConfig
    _lowerCAmelCase  =						FlaxHybridCLIPModule





    def __init__( self    :		Tuple      ,    snake_case    :		HybridCLIPConfig      ,    snake_case    :		Optional[Tuple] = None      ,    snake_case    :		int = 0      ,    snake_case    :		jnp.dtype = jnp.floataa      ,    **snake_case    :		Tuple      ,    ):

      """simple docstring"""





      if input_shape is None:
        __lowerCAmelCase								=					((1, 1), (1, config.vision_config.image_size, config.vision_config.image_size, 3))

      __lowerCAmelCase								=					self.module_class(config=snake_case      ,    dtype=snake_case      ,    **snake_case				)
      super().__init__(snake_case      ,    snake_case      ,    input_shape=snake_case      ,    seed=snake_case      ,    dtype=snake_case				)





    def 						A		( self    :		Optional[Any]      ,    snake_case    :		jax.random.PRNGKey      ,    snake_case    :		Tuple      ,    snake_case    :		FrozenDict = None				):

      """simple docstring"""





      __lowerCAmelCase								=					jnp.zeros(input_shape[0]      ,    dtype='''i4'''				)
      __lowerCAmelCase								=					jnp.broadcast_to(jnp.arange(jnp.atleast_ad(snake_case				).shape[-1]				)      ,    input_shape[0]				)
      __lowerCAmelCase								=					jnp.ones_like(snake_case				)
      __lowerCAmelCase								=					jnp.ones_like(snake_case				)

      __lowerCAmelCase								=					jax.random.normal(snake_case      ,    input_shape[1]				)

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

      return self.module.init(snake_case      ,    snake_case      ,    snake_case      ,    snake_case      ,    snake_case      ,    snake_case				)["params"]





    def __call__( self    :		List[str]      ,    snake_case    :		Optional[Any]      ,    snake_case    :		Union[str, Any]      ,    snake_case    :		Tuple=None      ,    snake_case    :		Union[str, Any]=None      ,    snake_case    :		Tuple=None      ,    snake_case    :		dict = None      ,    snake_case    :		jax.random.PRNGKey = None      ,    snake_case    :		bool = False      ,    snake_case    :		Optional[bool] = None      ,    snake_case    :		Optional[bool] = None      ,    snake_case    :		Optional[bool] = None      ,    ):

      """simple docstring"""





      __lowerCAmelCase								=					output_attentions if output_attentions is not None else self.config.output_attentions
      __lowerCAmelCase								=					(
          output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
      )
      __lowerCAmelCase								=					return_dict if return_dict is not None else self.config.return_dict

      if position_ids is None:
        __lowerCAmelCase								=					jnp.broadcast_to(jnp.arange(jnp.atleast_ad(snake_case				).shape[-1]				)      ,    input_ids.shape				)

      if token_type_ids is None:
        __lowerCAmelCase								=					jnp.zeros_like(snake_case				)

      if attention_mask is None:
        __lowerCAmelCase								=					jnp.ones_like(snake_case				)

      # Handle any PRNG if needed
      __lowerCAmelCase								=					{}
      if dropout_rng is not None:
        __lowerCAmelCase								=					dropout_rng

      return self.module.apply(
          {'''params''': params or self.params}      ,    jnp.array(snake_case      ,    dtype='''i4'''				)      ,    jnp.array(snake_case      ,    dtype=jnp.floataa				)      ,    jnp.array(snake_case      ,    dtype='''i4'''				)      ,    jnp.array(snake_case      ,    dtype='''i4'''				)      ,    jnp.array(snake_case      ,    dtype='''i4'''				)      ,    not train      ,    snake_case      ,    snake_case      ,    snake_case      ,    rngs=snake_case      ,    )





    def 						A		( self    :		Optional[Any]      ,    snake_case    :		Optional[Any]      ,    snake_case    :		Dict=None      ,    snake_case    :		List[str]=None      ,    snake_case    :		Tuple=None      ,    snake_case    :		dict = None      ,    snake_case    :		jax.random.PRNGKey = None      ,    snake_case    :		str=False      ,    ):

      """simple docstring"""





      if position_ids is None:
        __lowerCAmelCase								=					jnp.broadcast_to(jnp.arange(jnp.atleast_ad(snake_case				).shape[-1]				)      ,    input_ids.shape				)

      if token_type_ids is None:
        __lowerCAmelCase								=					jnp.zeros_like(snake_case				)

      if attention_mask is None:
        __lowerCAmelCase								=					jnp.ones_like(snake_case				)

      # Handle any PRNG if needed
      __lowerCAmelCase								=					{}
      if dropout_rng is not None:
        __lowerCAmelCase								=					dropout_rng

      def _get_features(snake_case    :		int      ,    snake_case    :		Optional[int]      ,    snake_case    :		Optional[int]      ,    snake_case    :		List[str]      ,    snake_case    :		int      ,    snake_case    :		Optional[Any]				):
        __lowerCAmelCase								=					module.text_model(
            input_ids=snake_case      ,    attention_mask=snake_case      ,    position_ids=snake_case      ,    token_type_ids=snake_case      ,    deterministic=snake_case      ,    )
        __lowerCAmelCase								=					text_outputs[1]
        __lowerCAmelCase								=					module.text_projection(snake_case				)
        return text_features

      return self.module.apply(
          {'''params''': params or self.params}      ,    jnp.array(snake_case      ,    dtype='''i4'''				)      ,    jnp.array(snake_case      ,    dtype='''i4'''				)      ,    jnp.array(snake_case      ,    dtype='''i4'''				)      ,    jnp.array(snake_case      ,    dtype='''i4'''				)      ,    not train      ,    method=_get_features      ,    rngs=snake_case      ,    )





    def 						A		( self    :		Union[str, Any]      ,    snake_case    :		List[str]      ,    snake_case    :		dict = None      ,    snake_case    :		jax.random.PRNGKey = None      ,    snake_case    :		str=False				):

      """simple docstring"""





      __lowerCAmelCase								=					{}
      if dropout_rng is not None:
        __lowerCAmelCase								=					dropout_rng

      def _get_features(snake_case    :		str      ,    snake_case    :		Any      ,    snake_case    :		Union[str, Any]				):
        __lowerCAmelCase								=					module.vision_model(pixel_values=snake_case      ,    deterministic=snake_case				)
        __lowerCAmelCase								=					vision_outputs[1]  # pooled_output
        __lowerCAmelCase								=					module.visual_projection(snake_case				)
        return image_features

      return self.module.apply(
          {'''params''': params or self.params}      ,    jnp.array(snake_case      ,    dtype=jnp.floataa				)      ,    not train      ,    method=_get_features      ,    rngs=snake_case      ,    )





    @classmethod
    def 						A		( cls    :		Dict      ,    snake_case    :		str = None      ,    snake_case    :		str = None      ,    *snake_case    :		List[str]      ,    **snake_case    :		Optional[int]      ,    ):

      """simple docstring"""





      __lowerCAmelCase								=					{
          argument[len('''text_'''				) :]: value for argument, value in kwargs.items() if argument.startswith('''text_'''				)
      }

      __lowerCAmelCase								=					{
          argument[len('''vision_'''				) :]: value for argument, value in kwargs.items() if argument.startswith('''vision_'''				)
      }

      # remove text, vision kwargs from kwargs
      for key in kwargs_text.keys():
        del kwargs["text_" + key]
      for key in kwargs_vision.keys():
        del kwargs["vision_" + key]

      # Load and initialize the text and vision model
      __lowerCAmelCase								=					kwargs_text.pop('''model'''      ,    snake_case				)
      if text_model is None:
        assert (
            text_model_name_or_path is not None
        ), "If `model` is not defined as an argument, a `text_model_name_or_path` has to be defined"
        from transformers import FlaxAutoModel

        if "config" not in kwargs_text:
          from transformers import AutoConfig

          __lowerCAmelCase								=					AutoConfig.from_pretrained(snake_case				)
          __lowerCAmelCase								=					text_config

        __lowerCAmelCase								=					FlaxAutoModel.from_pretrained(snake_case      ,    *snake_case      ,    **snake_case				)

      __lowerCAmelCase								=					kwargs_vision.pop('''model'''      ,    snake_case				)
      if vision_model is None:
        assert (
            vision_model_name_or_path is not None
        ), "If `model` is not defined as an argument, a `vision_model_name_or_path` has to be defined"
        from transformers import FlaxAutoModel

        if "config" not in kwargs_vision:
          from transformers import AutoConfig

          __lowerCAmelCase								=					AutoConfig.from_pretrained(snake_case				)
          __lowerCAmelCase								=					vision_config

        __lowerCAmelCase								=					FlaxAutoModel.from_pretrained(snake_case      ,    *snake_case      ,    **snake_case				)

      # instantiate config with corresponding kwargs
      __lowerCAmelCase								=					kwargs.pop('''dtype'''      ,    jnp.floataa				)
      __lowerCAmelCase								=					HybridCLIPConfig.from_text_vision_configs(text_model.config      ,    vision_model.config      ,    **snake_case				)

      # init model
      __lowerCAmelCase								=					cls(snake_case      ,    *snake_case      ,    dtype=snake_case      ,    **snake_case				)

      if vision_config.model_type == "clip":
        __lowerCAmelCase								=					vision_model.params['''vision_model''']
        __lowerCAmelCase								=					vision_model.params['''visual_projection''']['''kernel''']
      else:
        __lowerCAmelCase								=					vision_model.params

      __lowerCAmelCase								=					text_model.params

      return model







# Copyright 2022 The HuggingFace Team. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from pathlib import Path

from .config_args import default_config_file, load_config_from_file
from .config_utils import SubcommandHelpFormatter


__lowercase				    =      """Update an existing config file with the latest defaults while maintaining the old configuration."""


def        __SCREAMING_SNAKE_CASE	(				__lowercase:		Optional[Any]):



  '''simple docstring'''






  __lowerCAmelCase								=					args.config_file
  if config_file is None and Path(__lowercase).exists():
    __lowerCAmelCase								=					default_config_file
  elif not Path(__lowercase).exists():
    raise ValueError(F'''The passed config file located at {config_file} doesn\'t exist.''')
  __lowerCAmelCase								=					load_config_from_file(__lowercase)

  if config_file.endswith('''.json'''):
    config.to_json_file(__lowercase)
  else:
    config.to_yaml_file(__lowercase)
  return config_file


def        __SCREAMING_SNAKE_CASE	(				__lowercase:		Tuple  ,				__lowercase:		int):



  '''simple docstring'''






  __lowerCAmelCase								=					parser.add_parser('''update'''  ,				parents=__lowercase  ,				help=__lowercase  ,				formatter_class=__lowercase)
  parser.add_argument(
      '''--config_file'''  ,				default=__lowercase  ,				help=(
          '''The path to the config file to update. Will default to a file named default_config.yaml in the cache '''
          '''location, which is the content of the environment `HF_HOME` suffixed with \'accelerate\', or if you don\'t have '''
          '''such an environment variable, your cache directory (\'~/.cache\' or the content of `XDG_CACHE_HOME`) suffixed '''
          '''with \'huggingface\'.'''
      )  ,				)

  parser.set_defaults(func=__lowercase)
  return parser




def        __SCREAMING_SNAKE_CASE	(				__lowercase:		Any):



  '''simple docstring'''






  __lowerCAmelCase								=					update_config(__lowercase)
  print(F'''Sucessfully updated the configuration file at {config_file}.''')
