code: def __init__(
      self,
      query_dim,
      context_dim=None,
      heads=8,
      dim_head=64,
      dropout=0.0,
  ):
      super().__init__()
      print(
          f"Setting up {self.__class__.__name__}. Query dim is {query_dim}, context_dim is {context_dim} and using "
          f"{heads} heads."
      )
      inner_dim = dim_head * heads
      context_dim = default(context_dim, query_dim)
  
      self.heads = heads
      self.dim_head = dim_head
  
      self.to_q = nn.Linear(query_dim, inner_dim, bias=False)
      self.to_k = nn.Linear(context_dim, inner_dim, bias=False)
      self.to_v = nn.Linear(context_dim, inner_dim, bias=False)
  
      self.to_out = nn.Sequential(
          nn.Linear(inner_dim, query_dim), nn.Dropout(dropout)
      )
      self.attention_op: Optional[Any] = None
  
imports: from inspect import isfunction
  import math
  import torch
  import torch.nn.functional
  from torch import nn, einsum
  from einops import rearrange, repeat
  from typing import Optional, Any
  from ldm.modules.diffusionmodules.util import checkpoint
  import os
label_desc: Use image node_id 1 to create a new MemoryEfficientCrossAttention object from inherited base classes: nn with example: obj = MemoryEfficientCrossAttention(query_dim, context_dim, heads, dim_head, dropout)