code: def make_attn(in_channels, attn_type="vanilla", attn_kwargs=None):
      assert attn_type in [
          "vanilla",
          "vanilla-xformers",
          "memory-efficient-cross-attn",
          "linear",
          "none",
      ], f"attn_type {attn_type} unknown"
      if (
          version.parse(torch.__version__) < version.parse("2.0.0")
          and attn_type != "none"
      ):
          assert XFORMERS_IS_AVAILABLE, (
              f"We do not support vanilla attention in {torch.__version__} anymore, "
              f"as it is too expensive. Please install xformers via e.g. 'pip install xformers==0.0.16'"
          )
          attn_type = "vanilla-xformers"
      logpy.info(
          f"making attention of type '{attn_type}' with {in_channels} in_channels"
      )
      if attn_type == "vanilla":
          assert attn_kwargs is None
          return AttnBlock(in_channels)
      elif attn_type == "vanilla-xformers":
          logpy.info(
              f"building MemoryEfficientAttnBlock with {in_channels} in_channels..."
          )
          return MemoryEfficientAttnBlock(in_channels)
      elif type == "memory-efficient-cross-attn":
          attn_kwargs["query_dim"] = in_channels
          return MemoryEfficientCrossAttentionWrapper(**attn_kwargs)
      elif attn_type == "none":
          return nn.Identity(in_channels)
      else:
          return LinAttnBlock(in_channels)
  
imports: import logging
  import math
  from typing import Any, Callable, Optional
  import numpy
  import torch
  import torch.nn
  from einops import rearrange
  from packaging import version
  from ...modules.attention import LinearAttention, MemoryEfficientCrossAttention
label_desc: Use image node_id 4 for calling a global function with example usage: make_attn(in_channels, attn_type, attn_kwargs) and returns: AttnBlock, MemoryEfficientAttnBlock, MemoryEfficientCrossAttentionWrapper, nn, LinAttnBlock