class_docstr: Core ML version of
  `diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.StableDiffusionPipeline`
class_docstr_tok: ["Core","ML","version","of","`","diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.StableDiffusionPipeline","`"]
code: def _encode_prompt(
      self,
      prompt,
      prompt_2: Optional[str] = None,
      do_classifier_free_guidance: bool = True,
      negative_prompt: Optional[str] = None,
      negative_prompt_2: Optional[str] = None,
  ):
      batch_size = len(prompt) if isinstance(prompt, list) else 1
  
      if self.xl is True:
          prompts = (
              [prompt, prompt_2]
              if prompt_2 is not None
              else [prompt, prompt]
          )
  
          # refiner uses only one tokenizer and text encoder (tokenizer_2 and text_encoder_2)
          tokenizers = (
              [self.tokenizer, self.tokenizer_2]
              if self.tokenizer is not None
              else [self.tokenizer_2]
          )
  
          text_encoders = (
              [self.text_encoder, self.text_encoder_2]
              if self.text_encoder is not None
              else [self.text_encoder_2]
          )
          hidden_state_key = "hidden_embeds"
      else:
          prompts = [prompt]
          tokenizers = [self.tokenizer]
          text_encoders = [self.text_encoder]
          hidden_state_key = "last_hidden_state"
  
      prompt_embeds_list = []
      for prompt, tokenizer, text_encoder in zip(
          prompts, tokenizers, text_encoders
      ):
          text_inputs = tokenizer(
              prompt,
              padding="max_length",
              max_length=tokenizer.model_max_length,
              truncation=True,
              return_tensors="np",
          )
  
          text_input_ids = text_inputs.input_ids
  
          # tokenize without max_length to catch any truncation
          untruncated_ids = tokenizer(
              prompt, padding="longest", return_tensors="np"
          ).input_ids
  
          if untruncated_ids.shape[-1] >= text_input_ids.shape[
              -1
          ] and not np.equal(text_input_ids, untruncated_ids):
              removed_text = tokenizer.batch_decode(
                  untruncated_ids[
                      :, tokenizer.model_max_length - 1 : -1
                  ]
              )
              logger.warning(
                  "The following part of your input was truncated because CLIP can only handle sequences up to"
                  f" {tokenizer.model_max_length} tokens: {removed_text}"
              )
  
          embeddings = text_encoder(
              input_ids=text_input_ids.astype(np.float32)
          )
  
          prompt_embeds_list.append(embeddings[hidden_state_key])
  
          # We are only ALWAYS interested in the pooled output of the final text encoder
          if self.xl:
              pooled_prompt_embeds = embeddings["pooled_outputs"]
  
      prompt_embeds = np.concatenate(prompt_embeds_list, axis=-1)
  
      if (
          do_classifier_free_guidance
          and negative_prompt is None
          and self.force_zeros_for_empty_prompt
      ):
          negative_prompt_embeds = np.zeros_like(prompt_embeds)
  
          if self.xl:
              negative_pooled_prompt_embeds = np.zeros_like(
                  pooled_prompt_embeds
              )
      elif do_classifier_free_guidance:
          negative_prompt = negative_prompt or ""
          negative_prompt_2 = negative_prompt_2 or negative_prompt
  
          # normalize str to list
          negative_prompt = (
              batch_size * [negative_prompt]
              if isinstance(negative_prompt, str)
              else negative_prompt
          )
          negative_prompt_2 = (
              batch_size * [negative_prompt_2]
              if isinstance(negative_prompt_2, str)
              else negative_prompt_2
          )
  
          uncond_tokens: List[str]
          if prompts is not None and type(prompts) is not type(
              negative_prompt
          ):
              raise TypeError(
                  f"`negative_prompt` should be the same type to `prompt`, but got {type(negative_prompt)} !="
                  f" {type(prompt)}."
              )
          elif batch_size != len(negative_prompt):
              raise ValueError(
                  f"`negative_prompt`: {negative_prompt} has batch size {len(negative_prompt)}, but `prompt`:"
                  f" {prompt} has batch size {batch_size}. Please make sure that passed `negative_prompt` matches"
                  " the batch size of `prompt`."
              )
          else:
              uncond_tokens = [negative_prompt, negative_prompt_2]
  
          negative_prompt_embeds_list = []
          for negative_prompt, tokenizer, text_encoder in zip(
              uncond_tokens, tokenizers, text_encoders
          ):
              max_length = prompt_embeds.shape[1]
  
              uncond_input = tokenizer(
                  negative_prompt,
                  padding="max_length",
                  max_length=max_length,
                  truncation=True,
                  return_tensors="np",
              )
              uncond_input_ids = uncond_input.input_ids
  
              negative_embeddings = text_encoder(
                  input_ids=uncond_input_ids.astype(np.float32)
              )
  
              negative_text_embeddings = negative_embeddings[
                  hidden_state_key
              ]
  
              negative_prompt_embeds_list.append(
                  negative_text_embeddings
              )
  
              # We are only ALWAYS interested in the pooled output of the final text encoder
              if self.xl:
                  negative_pooled_prompt_embeds = negative_embeddings[
                      "pooled_outputs"
                  ]
  
          negative_prompt_embeds = np.concatenate(
              negative_prompt_embeds_list, axis=-1
          )
  
      if do_classifier_free_guidance:
          # For classifier free guidance, we need to do two forward passes.
          # Here we concatenate the unconditional and text embeddings into a single batch
          # to avoid doing two forward passes
          prompt_embeds = np.concatenate(
              [negative_prompt_embeds, prompt_embeds]
          )
  
          if self.xl:
              pooled_prompt_embeds = np.concatenate(
                  [negative_pooled_prompt_embeds, pooled_prompt_embeds]
              )
  
      prompt_embeddings = prompt_embeds.transpose(0, 2, 1)[
          :, :, None, :
      ]
  
      if self.xl:
          return prompt_embeddings, pooled_prompt_embeds
      else:
          return prompt_embeddings, None
  
imports: import argparse
  from diffusers import StableDiffusionPipeline, StableDiffusionXLPipeline
  from diffusers.pipelines.pipeline_utils import DiffusionPipeline
  from diffusers.pipelines.stable_diffusion import StableDiffusionPipelineOutput
  from diffusers.schedulers import DDIMScheduler, DPMSolverMultistepScheduler, EulerAncestralDiscreteScheduler, EulerDiscreteScheduler, LMSDiscreteScheduler, PNDMScheduler
  from diffusers.schedulers.scheduling_utils import SchedulerMixin
  import gc
  import inspect
  import logging
  import numpy
  import os
  from python_coreml_stable_diffusion.coreml_model import CoreMLModel, _load_mlpackage, _load_mlpackage_controlnet, get_available_compute_units
  import time
  import torch
  from transformers import CLIPFeatureExtractor, CLIPTokenizer
  from typing import List, Optional, Union, Tuple
  from PIL import Image
label_desc: Use image node_id 2 for calling the CoreMLStableDiffusionPipeline obj's underlying member method code with example usage: obj._encode_prompt(prompt, prompt_2, do_classifier_free_guidance, negative_prompt, negative_prompt_2) and returns: prompt_embeddings,  pooled_prompt_embeds, prompt_embeddings,  None