code: def forward(self, x):
      height, width, heads, wsz = (
          *x.shape[-2:],
          self.heads,
          self.window_size,
      )
  
      x = self.norm(x)
  
      wsz_h, wsz_w = default(wsz, height), default(wsz, width)
      assert (height % wsz_h) == 0 and (
          width % wsz_w
      ) == 0, f"height ({height}) or width ({width}) of feature map is not divisible by the window size ({wsz_h}, {wsz_w})"
  
      q, k, v = self.to_q(x), self.to_k(x), self.to_v(x)
  
      # get output of LIM
  
      local_out = self.local_interactive_module(v)
  
      # divide into window (and split out heads) for efficient self attention
  
      q, k, v = map(
          lambda t: rearrange(
              t,
              "b (h d) (x w1) (y w2) -> (b x y) h (w1 w2) d",
              h=heads,
              w1=wsz_h,
              w2=wsz_w,
          ),
          (q, k, v),
      )
  
      # similarity
  
      dots = torch.matmul(q, k.transpose(-1, -2)) * self.scale
  
      # attention
  
      attn = self.attend(dots)
      attn = self.dropout(attn)
  
      # aggregate values
  
      out = torch.matmul(attn, v)
  
      # reshape the windows back to full feature map (and merge heads)
  
      out = rearrange(
          out,
          "(b x y) h (w1 w2) d -> b (h d) (x w1) (y w2)",
          x=height // wsz_h,
          y=width // wsz_w,
          w1=wsz_h,
          w2=wsz_w,
      )
  
      # add LIM output
  
      out = out + local_out
  
      return self.to_out(out)
  
imports: from functools import partial
  import torch
  from torch import nn
  from einops import rearrange, repeat
  from einops.layers.torch import Rearrange, Reduce
label_desc: Use image node_id 2 for calling the InteractiveWindowedSelfAttention obj's underlying member method code with example usage: obj.forward(x) and returns: self