
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     :	List[str]       			=  version.parse(version.parse(torch.__version__).base_version) < version.parse('1.11')

def a__       (			A_,	A_,	A_,	A_,	A_,	A_,	A_,	A_=False,	):






  '''simple docstring'''





  output_path.parent.mkdir(parents=A_,	exist_ok=A_   )
  # 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(
        A_,	A_,	f=output_path.as_posix(),	input_names=A_,	output_names=A_,	dynamic_axes=A_,	do_constant_folding=A_,	use_external_data_format=A_,	enable_onnx_checker=A_,	opset_version=A_,	)
  else:
    export(
        A_,	A_,	f=output_path.as_posix(),	input_names=A_,	output_names=A_,	dynamic_axes=A_,	do_constant_folding=A_,	opset_version=A_,	)

@torch.no_grad()
def a__       (			A_,	A_,	A_,	A_ = False   ):






  '''simple docstring'''





  __magic_name__								=			torch.floataa if fpaa else torch.floataa
  if fpaa and torch.cuda.is_available():
    __magic_name__								=			"""cuda"""
  elif fpaa and not torch.cuda.is_available():
    raise ValueError("""`float16` model export is only supported on GPUs with CUDA"""   )
  else:
    __magic_name__								=			"""cpu"""
  __magic_name__								=			StableDiffusionPipeline.from_pretrained(A_,	torch_dtype=A_   ).to(A_   )
  __magic_name__								=			Path(A_   )

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

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

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

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

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

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

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

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


if __name__ == "__main__":
    __lowerCAmelCase     :	Optional[int]       			=  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     :	List[str]       			=  parser.parse_args()

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



def a__       (			A_=28123   ):






  '''simple docstring'''





  __magic_name__								=			[1] * (limit + 1)

  for i in range(2,	int(limit**0.5   ) + 1   ):
    sum_divs[i * i] += i
    for k in range(i + 1,	limit // i + 1   ):
      sum_divs[k * i] += k + i

  __magic_name__								=			set()
  __magic_name__								=			0

  for n in range(1,	limit + 1   ):
    if sum_divs[n] > n:
      abundants.add(A_   )

    if not any((n - a in abundants) for a in abundants   ):
      res += n

  return res


if __name__ == "__main__":
    print(solution())

