



import argparse
import os
import shutil
from pathlib import Path

import onnx
import torch
from packaging import version
from torch.onnx import export

from diffusers import OnnxRuntimeModel, OnnxStableDiffusionPipeline, StableDiffusionPipeline


a__    =	version.parse(version.parse(torch.__version__).base_version) < version.parse("""1.11""")



def       lowercase       (   SCREAMING_SNAKE_CASE__       :	Optional[Any]				,       SCREAMING_SNAKE_CASE__       :	tuple				,       SCREAMING_SNAKE_CASE__       :	Path				,       SCREAMING_SNAKE_CASE__       :	Union[str, Any]				,       SCREAMING_SNAKE_CASE__       :	Tuple				,       SCREAMING_SNAKE_CASE__       :	List[str]				,       SCREAMING_SNAKE_CASE__       :	Tuple				,       SCREAMING_SNAKE_CASE__       :	Optional[Any]=False				,       )  ->     Optional[int]:
 output_path.parent.mkdir(parents=SCREAMING_SNAKE_CASE__				,       exist_ok=SCREAMING_SNAKE_CASE__				)
 # PyTorch deprecated the `enable_onnx_checker` and `use_external_data_format` arguments in v1.11,
 # so we check the torch version for backwards compatibility
 if is_torch_less_than_1_11:
  export(
      SCREAMING_SNAKE_CASE__				,       SCREAMING_SNAKE_CASE__				,       f=output_path.as_posix()				,       input_names=SCREAMING_SNAKE_CASE__				,       output_names=SCREAMING_SNAKE_CASE__				,       dynamic_axes=SCREAMING_SNAKE_CASE__				,       do_constant_folding=SCREAMING_SNAKE_CASE__				,       use_external_data_format=SCREAMING_SNAKE_CASE__				,       enable_onnx_checker=SCREAMING_SNAKE_CASE__				,       opset_version=SCREAMING_SNAKE_CASE__				,       )
 else:
  export(
      SCREAMING_SNAKE_CASE__				,       SCREAMING_SNAKE_CASE__				,       f=output_path.as_posix()				,       input_names=SCREAMING_SNAKE_CASE__				,       output_names=SCREAMING_SNAKE_CASE__				,       dynamic_axes=SCREAMING_SNAKE_CASE__				,       do_constant_folding=SCREAMING_SNAKE_CASE__				,       opset_version=SCREAMING_SNAKE_CASE__				,       )



@torch.no_grad()
def       lowercase       (   SCREAMING_SNAKE_CASE__       :	str				,       SCREAMING_SNAKE_CASE__       :	str				,       SCREAMING_SNAKE_CASE__       :	int				,       SCREAMING_SNAKE_CASE__       :	bool = False				)  ->     Dict:
 _snake_case    :  List[str]					=					torch.floataa if fpaa else torch.floataa
 if fpaa and torch.cuda.is_available():
  _snake_case    :  List[str]					=					"""cuda"""
 elif fpaa and not torch.cuda.is_available():
  raise ValueError("""`float16` model export is only supported on GPUs with CUDA"""				)
 else:
  _snake_case    :  Dict					=					"""cpu"""
 _snake_case    :  int					=					StableDiffusionPipeline.from_pretrained(SCREAMING_SNAKE_CASE__				,       torch_dtype=SCREAMING_SNAKE_CASE__				).to(SCREAMING_SNAKE_CASE__				)
 _snake_case    :  List[Any]					=					Path(SCREAMING_SNAKE_CASE__				)

 # TEXT ENCODER
 _snake_case    :  Optional[Any]					=					pipeline.text_encoder.config.max_position_embeddings
 _snake_case    :  str					=					pipeline.text_encoder.config.hidden_size
 _snake_case    :  str					=					pipeline.tokenizer(
     """A sample prompt"""				,       padding="""max_length"""				,       max_length=pipeline.tokenizer.model_max_length				,       truncation=SCREAMING_SNAKE_CASE__				,       return_tensors="""pt"""				,       )
 onnx_export(
     pipeline.text_encoder				,       model_args=(text_input.input_ids.to(device=SCREAMING_SNAKE_CASE__				,       dtype=torch.intaa				))				,       output_path=output_path / """text_encoder""" / """model.onnx"""				,       ordered_input_names=["""input_ids"""]				,       output_names=["""last_hidden_state""", """pooler_output"""]				,       dynamic_axes={
         """input_ids""": {0: """batch""", 1: """sequence"""},
     }				,       opset=SCREAMING_SNAKE_CASE__				,       )
 del pipeline.text_encoder

 # UNET
 _snake_case    :  int					=					pipeline.unet.config.in_channels
 _snake_case    :  str					=					pipeline.unet.config.sample_size
 _snake_case    :  Union[str, Any]					=					output_path / """unet""" / """model.onnx"""
 onnx_export(
     pipeline.unet				,       model_args=(
         torch.randn(2				,       SCREAMING_SNAKE_CASE__				,       SCREAMING_SNAKE_CASE__				,       SCREAMING_SNAKE_CASE__				).to(device=SCREAMING_SNAKE_CASE__				,       dtype=SCREAMING_SNAKE_CASE__				),
         torch.randn(2				).to(device=SCREAMING_SNAKE_CASE__				,       dtype=SCREAMING_SNAKE_CASE__				),
         torch.randn(2				,       SCREAMING_SNAKE_CASE__				,       SCREAMING_SNAKE_CASE__				).to(device=SCREAMING_SNAKE_CASE__				,       dtype=SCREAMING_SNAKE_CASE__				),
         False,
     )				,       output_path=SCREAMING_SNAKE_CASE__				,       ordered_input_names=["""sample""", """timestep""", """encoder_hidden_states""", """return_dict"""]				,       output_names=["""out_sample"""]				,       dynamic_axes={
         """sample""": {0: """batch""", 1: """channels""", 2: """height""", 3: """width"""},
         """timestep""": {0: """batch"""},
         """encoder_hidden_states""": {0: """batch""", 1: """sequence"""},
     }				,       opset=SCREAMING_SNAKE_CASE__				,       use_external_data_format=SCREAMING_SNAKE_CASE__				,       )
 _snake_case    :  Tuple					=					str(unet_path.absolute().as_posix()				)
 _snake_case    :  Any					=					os.path.dirname(SCREAMING_SNAKE_CASE__				)
 _snake_case    :  str					=					onnx.load(SCREAMING_SNAKE_CASE__				)
 # clean up existing tensor files
 shutil.rmtree(SCREAMING_SNAKE_CASE__				)
 os.mkdir(SCREAMING_SNAKE_CASE__				)
 # collate external tensor files into one
 onnx.save_model(
     SCREAMING_SNAKE_CASE__				,       SCREAMING_SNAKE_CASE__				,       save_as_external_data=SCREAMING_SNAKE_CASE__				,       all_tensors_to_one_file=SCREAMING_SNAKE_CASE__				,       location="""weights.pb"""				,       convert_attribute=SCREAMING_SNAKE_CASE__				,       )
 del pipeline.unet

 # VAE ENCODER
 _snake_case    :  Optional[int]					=					pipeline.vae
 _snake_case    :  str					=					vae_encoder.config.in_channels
 _snake_case    :  int					=					vae_encoder.config.sample_size
 # need to get the raw tensor output (sample) from the encoder
 _snake_case    :  Any					=					lambda SCREAMING_SNAKE_CASE__				,       SCREAMING_SNAKE_CASE__				: vae_encoder.encode(SCREAMING_SNAKE_CASE__				,       SCREAMING_SNAKE_CASE__				)[0].sample()
 onnx_export(
     SCREAMING_SNAKE_CASE__				,       model_args=(
         torch.randn(1				,       SCREAMING_SNAKE_CASE__				,       SCREAMING_SNAKE_CASE__				,       SCREAMING_SNAKE_CASE__				).to(device=SCREAMING_SNAKE_CASE__				,       dtype=SCREAMING_SNAKE_CASE__				),
         False,
     )				,       output_path=output_path / """vae_encoder""" / """model.onnx"""				,       ordered_input_names=["""sample""", """return_dict"""]				,       output_names=["""latent_sample"""]				,       dynamic_axes={
         """sample""": {0: """batch""", 1: """channels""", 2: """height""", 3: """width"""},
     }				,       opset=SCREAMING_SNAKE_CASE__				,       )

 # VAE DECODER
 _snake_case    :  str					=					pipeline.vae
 _snake_case    :  Optional[int]					=					vae_decoder.config.latent_channels
 _snake_case    :  Union[str, Any]					=					vae_decoder.config.out_channels
 # forward only through the decoder part
 _snake_case    :  int					=					vae_encoder.decode
 onnx_export(
     SCREAMING_SNAKE_CASE__				,       model_args=(
         torch.randn(1				,       SCREAMING_SNAKE_CASE__				,       SCREAMING_SNAKE_CASE__				,       SCREAMING_SNAKE_CASE__				).to(device=SCREAMING_SNAKE_CASE__				,       dtype=SCREAMING_SNAKE_CASE__				),
         False,
     )				,       output_path=output_path / """vae_decoder""" / """model.onnx"""				,       ordered_input_names=["""latent_sample""", """return_dict"""]				,       output_names=["""sample"""]				,       dynamic_axes={
         """latent_sample""": {0: """batch""", 1: """channels""", 2: """height""", 3: """width"""},
     }				,       opset=SCREAMING_SNAKE_CASE__				,       )
 del pipeline.vae

 # SAFETY CHECKER
 if pipeline.safety_checker is not None:
  _snake_case    :  Tuple					=					pipeline.safety_checker
  _snake_case    :  Optional[int]					=					safety_checker.config.vision_config.num_channels
  _snake_case    :  Tuple					=					safety_checker.config.vision_config.image_size
  _snake_case    :  int					=					safety_checker.forward_onnx
  onnx_export(
      pipeline.safety_checker				,       model_args=(
          torch.randn(
              1				,       SCREAMING_SNAKE_CASE__				,       SCREAMING_SNAKE_CASE__				,       SCREAMING_SNAKE_CASE__				,       ).to(device=SCREAMING_SNAKE_CASE__				,       dtype=SCREAMING_SNAKE_CASE__				),
          torch.randn(1				,       SCREAMING_SNAKE_CASE__				,       SCREAMING_SNAKE_CASE__				,       SCREAMING_SNAKE_CASE__				).to(device=SCREAMING_SNAKE_CASE__				,       dtype=SCREAMING_SNAKE_CASE__				),
      )				,       output_path=output_path / """safety_checker""" / """model.onnx"""				,       ordered_input_names=["""clip_input""", """images"""]				,       output_names=["""out_images""", """has_nsfw_concepts"""]				,       dynamic_axes={
          """clip_input""": {0: """batch""", 1: """channels""", 2: """height""", 3: """width"""},
          """images""": {0: """batch""", 1: """height""", 2: """width""", 3: """channels"""},
      }				,       opset=SCREAMING_SNAKE_CASE__				,       )
  del pipeline.safety_checker
  _snake_case    :  Dict					=					OnnxRuntimeModel.from_pretrained(output_path / """safety_checker"""				)
  _snake_case    :  int					=					pipeline.feature_extractor
 else:
  _snake_case    :  Union[str, Any]					=					None
  _snake_case    :  List[Any]					=					None

 _snake_case    :  List[str]					=					OnnxStableDiffusionPipeline(
     vae_encoder=OnnxRuntimeModel.from_pretrained(output_path / """vae_encoder"""				)				,       vae_decoder=OnnxRuntimeModel.from_pretrained(output_path / """vae_decoder"""				)				,       text_encoder=OnnxRuntimeModel.from_pretrained(output_path / """text_encoder"""				)				,       tokenizer=pipeline.tokenizer				,       unet=OnnxRuntimeModel.from_pretrained(output_path / """unet"""				)				,       scheduler=pipeline.scheduler				,       safety_checker=SCREAMING_SNAKE_CASE__				,       feature_extractor=SCREAMING_SNAKE_CASE__				,       requires_safety_checker=safety_checker is not None				,       )

 onnx_pipeline.save_pretrained(SCREAMING_SNAKE_CASE__				)
 print("""ONNX pipeline saved to"""				,       SCREAMING_SNAKE_CASE__				)

 del pipeline
 del onnx_pipeline
 _snake_case    :  List[Any]					=					OnnxStableDiffusionPipeline.from_pretrained(SCREAMING_SNAKE_CASE__				,       provider="""CPUExecutionProvider"""				)
 print("""ONNX pipeline is loadable"""				)


if __name__ == "__main__":
  a__    =	argparse.ArgumentParser()

  parser.add_argument(
      """--model_path""",
      type=str,
      required=True,
      help="""Path to the `diffusers` checkpoint to convert (either a local directory or on the Hub).""",
  )

  parser.add_argument("""--output_path""", type=str, required=True, help="""Path to the output model.""")

  parser.add_argument(
      """--opset""",
      default=14,
      type=int,
      help="""The version of the ONNX operator set to use.""",
  )
  parser.add_argument("""--fp16""", action="""store_true""", default=False, help="""Export the models in `float16` mode""")

  a__    =	parser.parse_args()

  convert_models(args.model_path, args.output_path, args.opset, args.fpaa)





import sys

a__    =	(
    """73167176531330624919225119674426574742355349194934"""
    """96983520312774506326239578318016984801869478851843"""
    """85861560789112949495459501737958331952853208805511"""
    """12540698747158523863050715693290963295227443043557"""
    """66896648950445244523161731856403098711121722383113"""
    """62229893423380308135336276614282806444486645238749"""
    """30358907296290491560440772390713810515859307960866"""
    """70172427121883998797908792274921901699720888093776"""
    """65727333001053367881220235421809751254540594752243"""
    """52584907711670556013604839586446706324415722155397"""
    """53697817977846174064955149290862569321978468622482"""
    """83972241375657056057490261407972968652414535100474"""
    """82166370484403199890008895243450658541227588666881"""
    """16427171479924442928230863465674813919123162824586"""
    """17866458359124566529476545682848912883142607690042"""
    """24219022671055626321111109370544217506941658960408"""
    """07198403850962455444362981230987879927244284909188"""
    """84580156166097919133875499200524063689912560717606"""
    """05886116467109405077541002256983155200055935729725"""
    """71636269561882670428252483600823257530420752963450"""
)



def       lowercase       (   SCREAMING_SNAKE_CASE__       :	str = N				)  ->     int:
 _snake_case    :  int					=					-sys.maxsize - 1
 for i in range(len(SCREAMING_SNAKE_CASE__				) - 12				):
  _snake_case    :  Optional[int]					=					1
  for j in range(13				):
   product *= int(n[i + j]				)
  if product > largest_product:
   _snake_case    :  List[str]					=					product
 return largest_product


if __name__ == "__main__":
  print(F'''{solution() = }''')
