

'''simple docstring'''







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


__lowerCamelCase						    =      version.parse(version.parse(torch.__version__).base_version) < version.parse('''1.11''')
def  UpperCAmelCase__      ( UpperCAmelCase__,    UpperCAmelCase__,    UpperCAmelCase__,    UpperCAmelCase__,    UpperCAmelCase__,    UpperCAmelCase__,    UpperCAmelCase__,    UpperCAmelCase__=False,    )     ->     List[str]:
       output_path.parent.mkdir(parents=UpperCAmelCase__,    exist_ok=UpperCAmelCase__			)
       # 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(
                  UpperCAmelCase__,    UpperCAmelCase__,    f=output_path.as_posix(),    input_names=UpperCAmelCase__,    output_names=UpperCAmelCase__,    dynamic_axes=UpperCAmelCase__,    do_constant_folding=UpperCAmelCase__,    use_external_data_format=UpperCAmelCase__,    enable_onnx_checker=UpperCAmelCase__,    opset_version=UpperCAmelCase__,    )
       else:
              export(
                  UpperCAmelCase__,    UpperCAmelCase__,    f=output_path.as_posix(),    input_names=UpperCAmelCase__,    output_names=UpperCAmelCase__,    dynamic_axes=UpperCAmelCase__,    do_constant_folding=UpperCAmelCase__,    opset_version=UpperCAmelCase__,    )
@torch.no_grad()
def  UpperCAmelCase__      ( UpperCAmelCase__,    UpperCAmelCase__,    UpperCAmelCase__,    UpperCAmelCase__ = False			)     ->     str:
       A_		   = torch.floataa if fpaa else torch.floataa
       if fpaa and torch.cuda.is_available():
              A_		   = """cuda"""
       elif fpaa and not torch.cuda.is_available():
              raise ValueError("""`float16` model export is only supported on GPUs with CUDA"""			)
       else:
              A_		   = """cpu"""
       A_		   = StableDiffusionPipeline.from_pretrained(UpperCAmelCase__,    torch_dtype=UpperCAmelCase__			).to(UpperCAmelCase__			)
       A_		   = Path(UpperCAmelCase__			)

       # TEXT ENCODER
       A_		   = pipeline.text_encoder.config.max_position_embeddings
       A_		   = pipeline.text_encoder.config.hidden_size
       A_		   = pipeline.tokenizer(
           """A sample prompt""",    padding="""max_length""",    max_length=pipeline.tokenizer.model_max_length,    truncation=UpperCAmelCase__,    return_tensors="""pt""",    )
       onnx_export(
           pipeline.text_encoder,    model_args=(text_input.input_ids.to(device=UpperCAmelCase__,    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=UpperCAmelCase__,    )
       del pipeline.text_encoder

       # UNET
       A_		   = pipeline.unet.config.in_channels
       A_		   = pipeline.unet.config.sample_size
       A_		   = output_path / """unet""" / """model.onnx"""
       onnx_export(
           pipeline.unet,    model_args=(
               torch.randn(2,    UpperCAmelCase__,    UpperCAmelCase__,    UpperCAmelCase__			).to(device=UpperCAmelCase__,    dtype=UpperCAmelCase__			),
               torch.randn(2			).to(device=UpperCAmelCase__,    dtype=UpperCAmelCase__			),
               torch.randn(2,    UpperCAmelCase__,    UpperCAmelCase__			).to(device=UpperCAmelCase__,    dtype=UpperCAmelCase__			),
               False,
           ),    output_path=UpperCAmelCase__,    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=UpperCAmelCase__,    use_external_data_format=UpperCAmelCase__,    )
       A_		   = str(unet_path.absolute().as_posix()			)
       A_		   = os.path.dirname(UpperCAmelCase__			)
       A_		   = onnx.load(UpperCAmelCase__			)
       # clean up existing tensor files
       shutil.rmtree(UpperCAmelCase__			)
       os.mkdir(UpperCAmelCase__			)
       # collate external tensor files into one
       onnx.save_model(
           UpperCAmelCase__,    UpperCAmelCase__,    save_as_external_data=UpperCAmelCase__,    all_tensors_to_one_file=UpperCAmelCase__,    location="""weights.pb""",    convert_attribute=UpperCAmelCase__,    )
       del pipeline.unet

       # VAE ENCODER
       A_		   = pipeline.vae
       A_		   = vae_encoder.config.in_channels
       A_		   = vae_encoder.config.sample_size
       # need to get the raw tensor output (sample) from the encoder
       A_		   = lambda UpperCAmelCase__,    UpperCAmelCase__			: vae_encoder.encode(UpperCAmelCase__,    UpperCAmelCase__			)[0].sample()
       onnx_export(
           UpperCAmelCase__,    model_args=(
               torch.randn(1,    UpperCAmelCase__,    UpperCAmelCase__,    UpperCAmelCase__			).to(device=UpperCAmelCase__,    dtype=UpperCAmelCase__			),
               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=UpperCAmelCase__,    )

       # VAE DECODER
       A_		   = pipeline.vae
       A_		   = vae_decoder.config.latent_channels
       A_		   = vae_decoder.config.out_channels
       # forward only through the decoder part
       A_		   = vae_encoder.decode
       onnx_export(
           UpperCAmelCase__,    model_args=(
               torch.randn(1,    UpperCAmelCase__,    UpperCAmelCase__,    UpperCAmelCase__			).to(device=UpperCAmelCase__,    dtype=UpperCAmelCase__			),
               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=UpperCAmelCase__,    )
       del pipeline.vae

       # SAFETY CHECKER
       if pipeline.safety_checker is not None:
              A_		   = pipeline.safety_checker
              A_		   = safety_checker.config.vision_config.num_channels
              A_		   = safety_checker.config.vision_config.image_size
              A_		   = safety_checker.forward_onnx
              onnx_export(
                  pipeline.safety_checker,    model_args=(
                      torch.randn(
                          1,    UpperCAmelCase__,    UpperCAmelCase__,    UpperCAmelCase__,    ).to(device=UpperCAmelCase__,    dtype=UpperCAmelCase__			),
                      torch.randn(1,    UpperCAmelCase__,    UpperCAmelCase__,    UpperCAmelCase__			).to(device=UpperCAmelCase__,    dtype=UpperCAmelCase__			),
                  ),    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=UpperCAmelCase__,    )
              del pipeline.safety_checker
              A_		   = OnnxRuntimeModel.from_pretrained(output_path / """safety_checker"""			)
              A_		   = pipeline.feature_extractor
       else:
              A_		   = None
              A_		   = None

       A_		   = 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=UpperCAmelCase__,    feature_extractor=UpperCAmelCase__,    requires_safety_checker=safety_checker is not None,    )

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

       del pipeline
       del onnx_pipeline
       A_		   = OnnxStableDiffusionPipeline.from_pretrained(UpperCAmelCase__,    provider="""CPUExecutionProvider"""			)
       print("""ONNX pipeline is loadable"""			)


if __name__ == "__main__":
      __lowerCamelCase						    =      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''')

      __lowerCamelCase						    =      parser.parse_args()

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



'''simple docstring'''







import sys

__lowerCamelCase						    =      (
    '''73167176531330624919225119674426574742355349194934'''
    '''96983520312774506326239578318016984801869478851843'''
    '''85861560789112949495459501737958331952853208805511'''
    '''12540698747158523863050715693290963295227443043557'''
    '''66896648950445244523161731856403098711121722383113'''
    '''62229893423380308135336276614282806444486645238749'''
    '''30358907296290491560440772390713810515859307960866'''
    '''70172427121883998797908792274921901699720888093776'''
    '''65727333001053367881220235421809751254540594752243'''
    '''52584907711670556013604839586446706324415722155397'''
    '''53697817977846174064955149290862569321978468622482'''
    '''83972241375657056057490261407972968652414535100474'''
    '''82166370484403199890008895243450658541227588666881'''
    '''16427171479924442928230863465674813919123162824586'''
    '''17866458359124566529476545682848912883142607690042'''
    '''24219022671055626321111109370544217506941658960408'''
    '''07198403850962455444362981230987879927244284909188'''
    '''84580156166097919133875499200524063689912560717606'''
    '''05886116467109405077541002256983155200055935729725'''
    '''71636269561882670428252483600823257530420752963450'''
)
def  UpperCAmelCase__      ( UpperCAmelCase__ = N			)     ->     int:
       A_		   = -sys.maxsize - 1
       for i in range(len(UpperCAmelCase__			) - 12			):
              A_		   = 1
              for j in range(13			):
                     product *= int(n[i + j]			)
              if product > largest_product:
                     A_		   = product
       return largest_product


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