steady-rans-surrogates / code /ezflow_v3 /baselines /Transolver-main /PDE-Solving-StandardBenchmark /model /Embedding.py
| import math | |
| import torch | |
| import torch.nn as nn | |
| from einops import rearrange | |
| class RotaryEmbedding(nn.Module): | |
| def __init__(self, dim, min_freq=1 / 2, scale=1.): | |
| super().__init__() | |
| inv_freq = 1. / (10000 ** (torch.arange(0, dim, 2).float() / dim)) | |
| self.min_freq = min_freq | |
| self.scale = scale | |
| self.register_buffer('inv_freq', inv_freq) | |
| def forward(self, coordinates, device): | |
| # coordinates [b, n] | |
| t = coordinates.to(device).type_as(self.inv_freq) | |
| t = t * (self.scale / self.min_freq) | |
| freqs = torch.einsum('... i , j -> ... i j', t, self.inv_freq) # [b, n, d//2] | |
| return torch.cat((freqs, freqs), dim=-1) # [b, n, d] | |
| def rotate_half(x): | |
| x = rearrange(x, '... (j d) -> ... j d', j=2) | |
| x1, x2 = x.unbind(dim=-2) | |
| return torch.cat((-x2, x1), dim=-1) | |
| def apply_rotary_pos_emb(t, freqs): | |
| return (t * freqs.cos()) + (rotate_half(t) * freqs.sin()) | |
| def apply_2d_rotary_pos_emb(t, freqs_x, freqs_y): | |
| # split t into first half and second half | |
| # t: [b, h, n, d] | |
| # freq_x/y: [b, n, d] | |
| d = t.shape[-1] | |
| t_x, t_y = t[..., :d // 2], t[..., d // 2:] | |
| return torch.cat((apply_rotary_pos_emb(t_x, freqs_x), | |
| apply_rotary_pos_emb(t_y, freqs_y)), dim=-1) | |
| class PositionalEncoding(nn.Module): | |
| "Implement the PE function." | |
| def __init__(self, d_model, dropout, max_len=421 * 421): | |
| super(PositionalEncoding, self).__init__() | |
| self.dropout = nn.Dropout(p=dropout) | |
| # Compute the positional encodings once in log space. | |
| pe = torch.zeros(max_len, d_model) | |
| position = torch.arange(0, max_len).unsqueeze(1) | |
| div_term = torch.exp( | |
| torch.arange(0, d_model, 2) * -(math.log(10000.0) / d_model) | |
| ) | |
| pe[:, 0::2] = torch.sin(position * div_term) | |
| pe[:, 1::2] = torch.cos(position * div_term) | |
| pe = pe.unsqueeze(0) | |
| self.register_buffer("pe", pe) | |
| def forward(self, x): | |
| x = x + self.pe[:, : x.size(1)].requires_grad_(False) | |
| return self.dropout(x) | |
| def timestep_embedding(timesteps, dim, max_period=10000, repeat_only=False): | |
| """ | |
| Create sinusoidal timestep embeddings. | |
| :param timesteps: a 1-D Tensor of N indices, one per batch element. | |
| These may be fractional. | |
| :param dim: the dimension of the output. | |
| :param max_period: controls the minimum frequency of the embeddings. | |
| :return: an [N x dim] Tensor of positional embeddings. | |
| """ | |
| half = dim // 2 | |
| freqs = torch.exp( | |
| -math.log(max_period) * torch.arange(start=0, end=half, dtype=torch.float32) / half | |
| ).to(device=timesteps.device) | |
| args = timesteps[:, None].float() * freqs[None] | |
| embedding = torch.cat([torch.cos(args), torch.sin(args)], dim=-1) | |
| if dim % 2: | |
| embedding = torch.cat([embedding, torch.zeros_like(embedding[:, :1])], dim=-1) | |
| return embedding | |