


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 							lowercase  (						_UpperCAmelCase			):
     lowerCamelCase			:			jnp.ndarray
     lowerCamelCase			:			jnp.ndarray




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







     def 							lowercase__       (						self :						Union[str, Any]      ):
           SCREAMING_SNAKE_CASE__       :  Dict						     =		nn.Conv(
               self.block_out_channels[0]   ,   kernel_size=(3, 3)   ,   padding=((1, 1), (1, 1))   ,   dtype=self.dtype   ,   )

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

           SCREAMING_SNAKE_CASE__       :  List[str]						     =		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 :						Union[str, Any]   ,   _lowercase :						List[str]      ):
           SCREAMING_SNAKE_CASE__       :  Optional[Any]						     =		self.conv_in(_lowercase      )
           SCREAMING_SNAKE_CASE__       :  List[Any]						     =		nn.silu(_lowercase      )

           for block in self.blocks:
                 SCREAMING_SNAKE_CASE__       :  Dict						     =		block(_lowercase      )
                 SCREAMING_SNAKE_CASE__       :  Union[str, Any]						     =		nn.silu(_lowercase      )

           SCREAMING_SNAKE_CASE__       :  Optional[int]						     =		self.conv_out(_lowercase      )

           return embedding




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







     def 							lowercase__       (						self :						int   ,   _lowercase :						jax.random.KeyArray      ):
           # init input tensors
           SCREAMING_SNAKE_CASE__       :  Any						     =		(1, self.in_channels, self.sample_size, self.sample_size)
           SCREAMING_SNAKE_CASE__       :  Tuple						     =		jnp.zeros(_lowercase   ,   dtype=jnp.floataa      )
           SCREAMING_SNAKE_CASE__       :  Union[str, Any]						     =		jnp.ones((1,)   ,   dtype=jnp.intaa      )
           SCREAMING_SNAKE_CASE__       :  Union[str, Any]						     =		jnp.zeros((1, 1, self.cross_attention_dim)   ,   dtype=jnp.floataa      )
           SCREAMING_SNAKE_CASE__       :  Any						     =		(1, 3, self.sample_size * 8, self.sample_size * 8)
           SCREAMING_SNAKE_CASE__       :  List[Any]						     =		jnp.zeros(_lowercase   ,   dtype=jnp.floataa      )

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

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







     def 							lowercase__       (						self :						Optional[Any]      ):
           SCREAMING_SNAKE_CASE__       :  Tuple						     =		self.block_out_channels
           SCREAMING_SNAKE_CASE__       :  Optional[Any]						     =		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__       :  Optional[Any]						     =		self.num_attention_heads or self.attention_head_dim

           # input
           SCREAMING_SNAKE_CASE__       :  Optional[int]						     =		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__       :  Tuple						     =		FlaxTimesteps(
               block_out_channels[0]   ,   flip_sin_to_cos=self.flip_sin_to_cos   ,   freq_shift=self.config.freq_shift      )
           SCREAMING_SNAKE_CASE__       :  Union[str, Any]						     =		FlaxTimestepEmbedding(_lowercase   ,   dtype=self.dtype      )

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

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

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

           # down
           SCREAMING_SNAKE_CASE__       :  Any						     =		[]
           SCREAMING_SNAKE_CASE__       :  Optional[int]						     =		[]

           SCREAMING_SNAKE_CASE__       :  Optional[Any]						     =		block_out_channels[0]

           SCREAMING_SNAKE_CASE__       :  List[str]						     =		nn.Conv(
               _lowercase   ,   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(_lowercase      )

           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__       :  Union[str, Any]						     =		i == len(_lowercase      ) - 1

                 if down_block_type == "CrossAttnDownBlock2D":
                       SCREAMING_SNAKE_CASE__       :  int						     =		FlaxCrossAttnDownBlockaD(
                           in_channels=_lowercase   ,   out_channels=_lowercase   ,   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__       :  Dict						     =		FlaxDownBlockaD(
                           in_channels=_lowercase   ,   out_channels=_lowercase   ,   dropout=self.dropout   ,   num_layers=self.layers_per_block   ,   add_downsample=not is_final_block   ,   dtype=self.dtype   ,   )

                 down_blocks.append(_lowercase      )

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

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

           SCREAMING_SNAKE_CASE__       :  Union[str, Any]						     =		down_blocks
           SCREAMING_SNAKE_CASE__       :  List[str]						     =		controlnet_down_blocks

           # mid
           SCREAMING_SNAKE_CASE__       :  List[Any]						     =		block_out_channels[-1]
           SCREAMING_SNAKE_CASE__       :  List[Any]						     =		FlaxUNetMidBlockaDCrossAttn(
               in_channels=_lowercase   ,   dropout=self.dropout   ,   num_attention_heads=num_attention_heads[-1]   ,   use_linear_projection=self.use_linear_projection   ,   dtype=self.dtype   ,   )

           SCREAMING_SNAKE_CASE__       :  Union[str, Any]						     =		nn.Conv(
               _lowercase   ,   kernel_size=(1, 1)   ,   padding='''VALID'''   ,   kernel_init=nn.initializers.zeros_init()   ,   bias_init=nn.initializers.zeros_init()   ,   dtype=self.dtype   ,   )







     def __call__(						self :						Tuple   ,   _lowercase :						Dict   ,   _lowercase :						List[Any]   ,   _lowercase :						str   ,   _lowercase :						Union[str, Any]   ,   _lowercase :						float = 1.0   ,   _lowercase :						bool = True   ,   _lowercase :						bool = False   ,   ):
           SCREAMING_SNAKE_CASE__       :  Optional[Any]						     =		self.controlnet_conditioning_channel_order
           if channel_order == "bgr":
                 SCREAMING_SNAKE_CASE__       :  Optional[Any]						     =		jnp.flip(_lowercase   ,   axis=1      )

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

           SCREAMING_SNAKE_CASE__       :  Dict						     =		self.time_proj(_lowercase      )
           SCREAMING_SNAKE_CASE__       :  List[Any]						     =		self.time_embedding(_lowercase      )

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

           SCREAMING_SNAKE_CASE__       :  Any						     =		jnp.transpose(_lowercase   ,   (0, 2, 3, 1)      )
           SCREAMING_SNAKE_CASE__       :  Dict						     =		self.controlnet_cond_embedding(_lowercase      )
           sample += controlnet_cond

           # 3. down
           SCREAMING_SNAKE_CASE__       :  Dict						     =		(sample,)
           for down_block in self.down_blocks:
                 if isinstance(_lowercase   ,   _lowercase      ):
                       SCREAMING_SNAKE_CASE__     ,       SCREAMING_SNAKE_CASE__       :  Optional[Any]						     =		down_block(_lowercase   ,   _lowercase   ,   _lowercase   ,   deterministic=not train      )
                 else:
                       SCREAMING_SNAKE_CASE__     ,       SCREAMING_SNAKE_CASE__       :  Dict						     =		down_block(_lowercase   ,   _lowercase   ,   deterministic=not train      )
                 down_block_res_samples += res_samples

           # 4. mid
           SCREAMING_SNAKE_CASE__       :  List[str]						     =		self.mid_block(_lowercase   ,   _lowercase   ,   _lowercase   ,   deterministic=not train      )

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

           SCREAMING_SNAKE_CASE__       :  List[str]						     =		controlnet_down_block_res_samples

           SCREAMING_SNAKE_CASE__       :  Optional[Any]						     =		self.controlnet_mid_block(_lowercase      )

           # 6. scaling
           SCREAMING_SNAKE_CASE__       :  Union[str, Any]						     =		[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=_lowercase   ,   mid_block_res_sample=_lowercase      )










"""simple docstring"""






import math
import os
from copy import deepcopy

import datasets
import evaluate
import torch
import transformers
from datasets import load_dataset
from torch.utils.data import DataLoader
from transformers import AutoModelForSequenceClassification, AutoTokenizer

from accelerate import Accelerator
from accelerate.test_utils import RegressionDataset, RegressionModel
from accelerate.utils import is_tpu_available, set_seed


UpperCamelCase__				:Dict			   =	"""true"""





def 				A_       ( snake_case__       ,					snake_case__=82       ,					snake_case__=16		)					->  List[Any]:
			set_seed(42		)
			_UpperCamelCase					:Dict					     =	RegressionModel()
			_UpperCamelCase					:Dict					     =	deepcopy(snake_case__		)
			_UpperCamelCase					:List[Any]					     =	RegressionDataset(length=snake_case__		)
			_UpperCamelCase					:Optional[int]					     =	DataLoader(snake_case__       ,					batch_size=snake_case__		)
			model.to(accelerator.device		)
			_UpperCamelCase     ,      _UpperCamelCase					:List[str]					     =	accelerator.prepare(snake_case__       ,					snake_case__		)
			return model, ddp_model, dataloader





def 				A_       ( snake_case__       ,					snake_case__=False		)					->  Optional[int]:
			_UpperCamelCase					:Optional[Any]					     =	AutoTokenizer.from_pretrained('''hf-internal-testing/mrpc-bert-base-cased'''		)
			_UpperCamelCase					:int					     =	load_dataset('''glue'''       ,					'''mrpc'''       ,					split='''validation'''		)

			def tokenize_function(snake_case__		):
						_UpperCamelCase					:Optional[int]					     =	tokenizer(examples['''sentence1''']       ,					examples['''sentence2''']       ,					truncation=snake_case__       ,					max_length=snake_case__		)
						return outputs

			with accelerator.main_process_first():
						_UpperCamelCase					:Optional[int]					     =	dataset.map(
						    snake_case__       ,					batched=snake_case__       ,					remove_columns=['''idx''', '''sentence1''', '''sentence2''']       ,					)

			_UpperCamelCase					:Tuple					     =	tokenized_datasets.rename_column('''label'''       ,					'''labels'''		)

			def collate_fn(snake_case__		):
						if use_longest:
									return tokenizer.pad(snake_case__       ,					padding='''longest'''       ,					return_tensors='''pt'''		)
						return tokenizer.pad(snake_case__       ,					padding='''max_length'''       ,					max_length=1_28       ,					return_tensors='''pt'''		)

			return DataLoader(snake_case__       ,					shuffle=snake_case__       ,					collate_fn=snake_case__       ,					batch_size=16		)





def 				A_       ( snake_case__       ,					snake_case__		)					->  Tuple:
			_UpperCamelCase					:Union[str, Any]					     =	Accelerator(dispatch_batches=snake_case__       ,					split_batches=snake_case__		)
			_UpperCamelCase					:Any					     =	get_dataloader(snake_case__       ,					not dispatch_batches		)
			_UpperCamelCase					:Optional[int]					     =	AutoModelForSequenceClassification.from_pretrained(
			    '''hf-internal-testing/mrpc-bert-base-cased'''       ,					return_dict=snake_case__		)
			_UpperCamelCase     ,      _UpperCamelCase					:int					     =	accelerator.prepare(snake_case__       ,					snake_case__		)
			return {"ddp": [ddp_model, ddp_dataloader, "cuda:0"], "no": [model, dataloader, accelerator.device]}, accelerator





def 				A_       ( snake_case__       ,					snake_case__       ,					snake_case__		)					->  List[Any]:
			_UpperCamelCase					:Any					     =	[]
			for batch in dataloader:
						_UpperCamelCase     ,      _UpperCamelCase					:List[Any]					     =	batch.values()
						with torch.no_grad():
									_UpperCamelCase					:List[Any]					     =	model(snake_case__		)
									_UpperCamelCase     ,      _UpperCamelCase					:Optional[int]					     =	accelerator.gather_for_metrics((logit, target)		)
									logits_and_targets.append((logit, target)		)
			_UpperCamelCase     ,      _UpperCamelCase					:Optional[Any]					     =	[], []
			for logit, targ in logits_and_targets:
						logits.append(snake_case__		)
						targs.append(snake_case__		)
			_UpperCamelCase     ,      _UpperCamelCase					:List[str]					     =	torch.cat(snake_case__		), torch.cat(snake_case__		)
			return logits, targs





def 				A_       ( snake_case__       ,					snake_case__=82       ,					snake_case__=False       ,					snake_case__=False       ,					snake_case__=16		)					->  Dict:
			_UpperCamelCase     ,      _UpperCamelCase     ,      _UpperCamelCase					:List[str]					     =	get_basic_setup(snake_case__       ,					snake_case__       ,					snake_case__		)
			_UpperCamelCase     ,      _UpperCamelCase					:Tuple					     =	generate_predictions(snake_case__       ,					snake_case__       ,					snake_case__		)
			assert (
			    len(snake_case__		) == num_samples
			), f"Unexpected number of inputs:\n    Expected: {num_samples}\n    Actual: {len(snake_case__		)}"





def 				A_       ( snake_case__ = False       ,					snake_case__ = False		)					->  Optional[Any]:
			_UpperCamelCase					:Any					     =	evaluate.load('''glue'''       ,					'''mrpc'''		)
			_UpperCamelCase     ,      _UpperCamelCase					:Optional[int]					     =	get_mrpc_setup(snake_case__       ,					snake_case__		)
			# First do baseline
			_UpperCamelCase     ,      _UpperCamelCase     ,      _UpperCamelCase					:Tuple					     =	setup['''no''']
			model.to(snake_case__		)
			model.eval()
			for batch in dataloader:
						batch.to(snake_case__		)
						with torch.inference_mode():
									_UpperCamelCase					:str					     =	model(**snake_case__		)
						_UpperCamelCase					:Dict					     =	outputs.logits.argmax(dim=-1		)
						metric.add_batch(predictions=snake_case__       ,					references=batch['''labels''']		)
			_UpperCamelCase					:int					     =	metric.compute()

			# Then do distributed
			_UpperCamelCase     ,      _UpperCamelCase     ,      _UpperCamelCase					:Optional[int]					     =	setup['''ddp''']
			model.eval()
			for batch in dataloader:
						with torch.inference_mode():
									_UpperCamelCase					:Dict					     =	model(**snake_case__		)
						_UpperCamelCase					:str					     =	outputs.logits.argmax(dim=-1		)
						_UpperCamelCase					:Union[str, Any]					     =	batch['''labels''']
						_UpperCamelCase     ,      _UpperCamelCase					:Tuple					     =	accelerator.gather_for_metrics((preds, references)		)
						metric.add_batch(predictions=snake_case__       ,					references=snake_case__		)
			_UpperCamelCase					:Optional[Any]					     =	metric.compute()

			for key in "accuracy f1".split():
						assert math.isclose(
						    baseline[key]       ,					distributed[key]		), f"Baseline and Distributed are not the same for key {key}:\n\tBaseline: {baseline[key]}\n\tDistributed: {distributed[key]}\n"





def 				A_       ( )					->  Optional[Any]:
			_UpperCamelCase					:int					     =	Accelerator(split_batches=snake_case__       ,					dispatch_batches=snake_case__		)
			if accelerator.is_local_main_process:
						datasets.utils.logging.set_verbosity_warning()
						transformers.utils.logging.set_verbosity_warning()
			else:
						datasets.utils.logging.set_verbosity_error()
						transformers.utils.logging.set_verbosity_error()
			# These are a bit slower so they should only be ran on the GPU or TPU
			if torch.cuda.is_available() or is_tpu_available():
						if accelerator.is_local_main_process:
									print('''**Testing gather_for_metrics**'''		)
						for split_batches in [True, False]:
									for dispatch_batches in [True, False]:
												if accelerator.is_local_main_process:
															print(f"With: `split_batches={split_batches}`, `dispatch_batches={dispatch_batches}`"		)
												test_mrpc(snake_case__       ,					snake_case__		)
												accelerator.state._reset_state()
			if accelerator.is_local_main_process:
						print('''**Test torch metrics**'''		)
			for split_batches in [True, False]:
						for dispatch_batches in [True, False]:
									_UpperCamelCase					:Tuple					     =	Accelerator(split_batches=snake_case__       ,					dispatch_batches=snake_case__		)
									if accelerator.is_local_main_process:
												print(f"With: `split_batches={split_batches}`, `dispatch_batches={dispatch_batches}`, length=99"		)
									test_torch_metrics(snake_case__       ,					99		)
									accelerator.state._reset_state()
			if accelerator.is_local_main_process:
						print('''**Test last batch is not dropped when perfectly divisible**'''		)
			_UpperCamelCase					:Any					     =	Accelerator()
			test_torch_metrics(snake_case__       ,					5_12		)
			accelerator.state._reset_state()





def 				A_       ( snake_case__		)					->  Dict:
			# For xla_spawn (TPUs)
			main()


if __name__ == "__main__":
					main()

