
"""simple docstring"""
import re

import jax.numpy as jnp
from flax.traverse_util import flatten_dict, unflatten_dict
from jax.random import PRNGKey

from ..utils import logging


lowerCamelCase_       =		logging.get_logger(__name__)



def 					__lowerCamelCase       (							a_					:		Tuple							)      ->				Dict:
      __SCREAMING_SNAKE_CASE       :Dict		    =  R'\w+[.]\d+'
      __SCREAMING_SNAKE_CASE       :int		    =  re.findall(a_			,       a_							)
      for pat in pats:
            __SCREAMING_SNAKE_CASE       :Optional[Any]		    =  key.replace(a_			,       '''_'''.join(pat.split('''.'''							)							)							)
      return key



def 					__lowerCamelCase       (							a_					:		Union[str, Any]			,       a_					:		Tuple			,       a_					:		str							)      ->				int:
      __SCREAMING_SNAKE_CASE       :Dict		    =  pt_tuple_key[:-1] + ('scale',)
      if (
          any('''norm''' in str_ for str_ in pt_tuple_key							)
          and (pt_tuple_key[-1] == "bias")
          and (pt_tuple_key[:-1] + ("bias",) not in random_flax_state_dict)
          and (pt_tuple_key[:-1] + ("scale",) in random_flax_state_dict)
      ):
            __SCREAMING_SNAKE_CASE       :List[Any]		    =  pt_tuple_key[:-1] + ('scale',)
            return renamed_pt_tuple_key, pt_tensor
      elif pt_tuple_key[-1] in ["weight", "gamma"] and pt_tuple_key[:-1] + ("scale",) in random_flax_state_dict:
            __SCREAMING_SNAKE_CASE       :Union[str, Any]		    =  pt_tuple_key[:-1] + ('scale',)
            return renamed_pt_tuple_key, pt_tensor

      # embedding
      if pt_tuple_key[-1] == "weight" and pt_tuple_key[:-1] + ("embedding",) in random_flax_state_dict:
            __SCREAMING_SNAKE_CASE       :List[Any]		    =  pt_tuple_key[:-1] + ('embedding',)
            return renamed_pt_tuple_key, pt_tensor

      # conv layer
      __SCREAMING_SNAKE_CASE       :Optional[Any]		    =  pt_tuple_key[:-1] + ('kernel',)
      if pt_tuple_key[-1] == "weight" and pt_tensor.ndim == 4:
            __SCREAMING_SNAKE_CASE       :str		    =  pt_tensor.transpose(2			,       3			,       1			,       0							)
            return renamed_pt_tuple_key, pt_tensor

      # linear layer
      __SCREAMING_SNAKE_CASE       :Optional[int]		    =  pt_tuple_key[:-1] + ('kernel',)
      if pt_tuple_key[-1] == "weight":
            __SCREAMING_SNAKE_CASE       :int		    =  pt_tensor.T
            return renamed_pt_tuple_key, pt_tensor

      # old PyTorch layer norm weight
      __SCREAMING_SNAKE_CASE       :Optional[int]		    =  pt_tuple_key[:-1] + ('weight',)
      if pt_tuple_key[-1] == "gamma":
            return renamed_pt_tuple_key, pt_tensor

      # old PyTorch layer norm bias
      __SCREAMING_SNAKE_CASE       :List[str]		    =  pt_tuple_key[:-1] + ('bias',)
      if pt_tuple_key[-1] == "beta":
            return renamed_pt_tuple_key, pt_tensor

      return pt_tuple_key, pt_tensor







def 					__lowerCamelCase       (							a_					:		Optional[Any]			,       a_					:		Tuple			,       a_					:		Tuple=42							)      ->				Any:
      # Step 1: Convert pytorch tensor to numpy
      __SCREAMING_SNAKE_CASE       :str		    =  {k: v.numpy() for k, v in pt_state_dict.items()}

      # Step 2: Since the model is stateless, get random Flax params
      __SCREAMING_SNAKE_CASE       :Tuple		    =  flax_model.init_weights(PRNGKey(a_							)							)

      __SCREAMING_SNAKE_CASE       :Optional[Any]		    =  flatten_dict(a_							)
      __SCREAMING_SNAKE_CASE       :Tuple		    =  {}

      # Need to change some parameters name to match Flax names
      for pt_key, pt_tensor in pt_state_dict.items():
            __SCREAMING_SNAKE_CASE       :Union[str, Any]		    =  rename_key(a_							)
            __SCREAMING_SNAKE_CASE       :Optional[int]		    =  tuple(renamed_pt_key.split('''.'''							)							)

            # Correctly rename weight parameters
            __SCREAMING_SNAKE_CASE       :Union[str, Any]		    =  rename_key_and_reshape_tensor(a_			,       a_			,       a_							)

            if flax_key in random_flax_state_dict:
                  if flax_tensor.shape != random_flax_state_dict[flax_key].shape:
                        raise ValueError(
                            f'''PyTorch checkpoint seems to be incorrect. Weight {pt_key} was expected to be of shape '''
                            f'''{random_flax_state_dict[flax_key].shape}, but is {flax_tensor.shape}.'''							)

                            # also add unexpected weight so that warning is thrown
            __SCREAMING_SNAKE_CASE       :Optional[Any]		    =  jnp.asarray(a_							)

      return unflatten_dict(a_							)






"""simple docstring"""
def 					__lowerCamelCase       (							a_					:		int			,       a_					:		int							)      ->				int:
      return int((input_a, input_a).count(0							) == 0							)



def 					__lowerCamelCase       (							)      ->				None:
      assert and_gate(0			,       0							) == 0
      assert and_gate(0			,       1							) == 0
      assert and_gate(1			,       0							) == 0
      assert and_gate(1			,       1							) == 1


if __name__ == "__main__":
  test_and_gate()
  print(and_gate(1, 0))
  print(and_gate(0, 0))
  print(and_gate(0, 1))
  print(and_gate(1, 1))