forked from tile-ai/TileOPs
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_mhc_pre.py
More file actions
94 lines (71 loc) · 3.56 KB
/
Copy pathtest_mhc_pre.py
File metadata and controls
94 lines (71 loc) · 3.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
"""Test ManifoldConstrainedHyperConnection Pre operation."""
import math
import pytest
import torch
import torch.nn.functional as F
from tests.test_base import FixtureBase, TestBase
from tileops.ops import MHCPreOp
from workloads.mhc import MHCPreTest as _MHCPreTestWorkload
class MHCPreTest(_MHCPreTestWorkload, TestBase):
def ref_program(self, phi: torch.Tensor, x: torch.Tensor, b: torch.Tensor,
alpha_pre, alpha_post, alpha_res,
sinkhorn_repeat: int, eps: float) -> tuple[torch.Tensor, torch.Tensor]:
batch = self.batch
n_expand = self.n_expand
c_x = self.c_x
xsqr = x * x
norm_eps = 0.0001
r_ref = torch.sqrt(xsqr.sum(dim=1)) / math.sqrt(n_expand * c_x) + norm_eps
H = torch.zeros([batch, n_expand * n_expand + 2 * n_expand],
device=x.device, dtype=torch.float)
for i in range(batch):
H[i, :] = x[i, :].float() @ phi
H_pre_ref = H[:, :n_expand]
H_res_ref = H[:, 2 * n_expand:]
H_res_ref = H_res_ref.reshape(batch, n_expand, n_expand)
b_pre_ref = b[:n_expand]
b_res_ref = b[2 * n_expand:]
b_res_ref = b_res_ref.reshape([n_expand, n_expand])
H_pre_ref = torch.sigmoid(alpha_pre * H_pre_ref / r_ref.unsqueeze(-1) + b_pre_ref)
H_res_ref = alpha_res * H_res_ref / r_ref.unsqueeze(-1).unsqueeze(-1) + b_res_ref
H_res_ref_tmp = H_res_ref.max(dim=-1, keepdim=True).values
H_res_ref = torch.exp(H_res_ref - H_res_ref_tmp)
for _i in range(sinkhorn_repeat):
H_res_ref = H_res_ref / (H_res_ref.sum(dim=-1, keepdim=True) + eps)
H_res_ref = H_res_ref / (H_res_ref.sum(dim=-2, keepdim=True) + eps)
x_in_reshaped = x.reshape([batch, n_expand, c_x])
x_res_ref = torch.zeros([batch, n_expand, c_x], device=x.device, dtype=torch.bfloat16)
x_layer_ref = torch.zeros([batch, c_x], device=x.device, dtype=torch.bfloat16)
h_res_ref = H_res_ref
h_pre_ref = H_pre_ref
for i in range(batch):
h_res_tmp = h_res_ref[i, :, :].float()
h_pre_tmp = h_pre_ref[i, :].float()
x_in_reshaped_tmp = x_in_reshaped[i, :, :].float()
x_res_ref[i, :, :] = h_res_tmp @ x_in_reshaped_tmp
x_layer_ref[i, :] = h_pre_tmp @ x_in_reshaped_tmp
x_res_ref = x_res_ref.reshape(batch, n_expand * c_x)
x_res_ref = x_res_ref.bfloat16()
x_layer_ref = x_layer_ref.bfloat16()
return x_res_ref, x_layer_ref
class MHCPreFixture(FixtureBase):
PARAMS = [
("batch, n_expand, c_x, dtype, tune", [
pytest.param(1, 4, 1280, torch.bfloat16, False, marks=pytest.mark.smoke),
pytest.param(2, 4, 1920, torch.bfloat16, False, marks=pytest.mark.full),
pytest.param(4, 4, 2560, torch.bfloat16, False, marks=pytest.mark.full),
]),
]
def _cosine_compare(output: torch.Tensor, output_ref: torch.Tensor) -> None:
"""Compare using cosine similarity (mhc pre uses bf16 and needs looser checks)."""
cos_sim = F.cosine_similarity(output_ref, output, dim=-1, eps=1e-8)
assert cos_sim.min() > 0.99, \
f"cosine similarity too low: {cos_sim.min().item()}"
@MHCPreFixture
def test_mhc_pre_op(batch: int, n_expand: int, c_x: int, dtype: torch.dtype,
tune: bool) -> None:
test = MHCPreTest(batch, n_expand, c_x, dtype)
op = MHCPreOp(batch, n_expand, c_x, dtype=dtype, tune=tune)
test.check(op, *test.gen_inputs(), compare=_cosine_compare)
if __name__ == "__main__":
pytest.main([__file__, "-vvs"])