219 lines
5.6 KiB
Python
219 lines
5.6 KiB
Python
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
# Copyright (C) 2026 David (Corey) Herrera
|
|
"""
|
|
Comparison tests for matrix operations.
|
|
"""
|
|
|
|
import numpy as np
|
|
import torch
|
|
import torch.nn.functional as F
|
|
from compare_utils import ComparisonTest, TestRunner
|
|
|
|
|
|
class TestMatmul(ComparisonTest):
|
|
def __init__(self):
|
|
super().__init__("matmul", tolerance=1e-4)
|
|
|
|
def generate_input(self, seed=42):
|
|
np.random.seed(seed)
|
|
a = np.random.randn(64, 128).astype(np.float32)
|
|
b = np.random.randn(128, 64).astype(np.float32)
|
|
return (a, b)
|
|
|
|
def pytorch_forward(self, a, b):
|
|
return torch.matmul(a, b)
|
|
|
|
|
|
class TestMatmulSquare(ComparisonTest):
|
|
def __init__(self):
|
|
super().__init__("matmul_square", tolerance=1e-4)
|
|
|
|
def generate_input(self, seed=42):
|
|
np.random.seed(seed)
|
|
a = np.random.randn(64, 64).astype(np.float32)
|
|
b = np.random.randn(64, 64).astype(np.float32)
|
|
return (a, b)
|
|
|
|
def pytorch_forward(self, a, b):
|
|
return torch.matmul(a, b)
|
|
|
|
def foundry_operation(self):
|
|
return "matmul"
|
|
|
|
|
|
class TestBmm(ComparisonTest):
|
|
def __init__(self):
|
|
super().__init__("bmm", tolerance=1e-4)
|
|
|
|
def generate_input(self, seed=42):
|
|
np.random.seed(seed)
|
|
a = np.random.randn(8, 32, 64).astype(np.float32)
|
|
b = np.random.randn(8, 64, 32).astype(np.float32)
|
|
return (a, b)
|
|
|
|
def pytorch_forward(self, a, b):
|
|
return torch.bmm(a, b)
|
|
|
|
|
|
class TestMm(ComparisonTest):
|
|
def __init__(self):
|
|
super().__init__("mm", tolerance=1e-4)
|
|
|
|
def generate_input(self, seed=42):
|
|
np.random.seed(seed)
|
|
a = np.random.randn(128, 256).astype(np.float32)
|
|
b = np.random.randn(256, 128).astype(np.float32)
|
|
return (a, b)
|
|
|
|
def pytorch_forward(self, a, b):
|
|
return torch.mm(a, b)
|
|
|
|
|
|
class TestMv(ComparisonTest):
|
|
def __init__(self):
|
|
super().__init__("mv", tolerance=1e-4)
|
|
|
|
def generate_input(self, seed=42):
|
|
np.random.seed(seed)
|
|
mat = np.random.randn(128, 64).astype(np.float32)
|
|
vec = np.random.randn(64).astype(np.float32)
|
|
return (mat, vec)
|
|
|
|
def pytorch_forward(self, mat, vec):
|
|
return torch.mv(mat, vec)
|
|
|
|
|
|
class TestDot(ComparisonTest):
|
|
def __init__(self):
|
|
super().__init__("dot", tolerance=1e-5)
|
|
|
|
def generate_input(self, seed=42):
|
|
np.random.seed(seed)
|
|
a = np.random.randn(1000).astype(np.float32)
|
|
b = np.random.randn(1000).astype(np.float32)
|
|
return (a, b)
|
|
|
|
def pytorch_forward(self, a, b):
|
|
return torch.dot(a, b)
|
|
|
|
|
|
class TestOuter(ComparisonTest):
|
|
def __init__(self):
|
|
super().__init__("outer", tolerance=1e-6)
|
|
|
|
def generate_input(self, seed=42):
|
|
np.random.seed(seed)
|
|
a = np.random.randn(100).astype(np.float32)
|
|
b = np.random.randn(100).astype(np.float32)
|
|
return (a, b)
|
|
|
|
def pytorch_forward(self, a, b):
|
|
return torch.outer(a, b)
|
|
|
|
|
|
class TestLinear(ComparisonTest):
|
|
def __init__(self):
|
|
super().__init__("linear", tolerance=1e-4)
|
|
|
|
def generate_input(self, seed=42):
|
|
np.random.seed(seed)
|
|
x = np.random.randn(32, 128).astype(np.float32)
|
|
weight = np.random.randn(64, 128).astype(np.float32)
|
|
bias = np.random.randn(64).astype(np.float32)
|
|
return (x, weight, bias)
|
|
|
|
def pytorch_forward(self, x, weight, bias):
|
|
return F.linear(x, weight, bias)
|
|
|
|
|
|
class TestLinearNoBias(ComparisonTest):
|
|
def __init__(self):
|
|
super().__init__("linear_no_bias", tolerance=1e-4)
|
|
|
|
def generate_input(self, seed=42):
|
|
np.random.seed(seed)
|
|
x = np.random.randn(32, 128).astype(np.float32)
|
|
weight = np.random.randn(64, 128).astype(np.float32)
|
|
return (x, weight)
|
|
|
|
def pytorch_forward(self, x, weight):
|
|
return F.linear(x, weight, None)
|
|
|
|
def foundry_operation(self):
|
|
return "linear"
|
|
|
|
|
|
class TestAddmm(ComparisonTest):
|
|
def __init__(self):
|
|
super().__init__("addmm", tolerance=1e-4)
|
|
|
|
def generate_input(self, seed=42):
|
|
np.random.seed(seed)
|
|
bias = np.random.randn(64).astype(np.float32)
|
|
mat1 = np.random.randn(32, 128).astype(np.float32)
|
|
mat2 = np.random.randn(128, 64).astype(np.float32)
|
|
return (bias, mat1, mat2)
|
|
|
|
def pytorch_forward(self, bias, mat1, mat2):
|
|
return torch.addmm(bias, mat1, mat2)
|
|
|
|
|
|
class TestTranspose(ComparisonTest):
|
|
def __init__(self):
|
|
super().__init__("transpose", tolerance=0.0)
|
|
|
|
def generate_input(self, seed=42):
|
|
np.random.seed(seed)
|
|
return (np.random.randn(64, 128).astype(np.float32),)
|
|
|
|
def pytorch_forward(self, x):
|
|
return torch.transpose(x, 0, 1)
|
|
|
|
def foundry_params(self):
|
|
return {"dim0": 0, "dim1": 1}
|
|
|
|
|
|
class TestPermute(ComparisonTest):
|
|
def __init__(self):
|
|
super().__init__("permute", tolerance=0.0)
|
|
|
|
def generate_input(self, seed=42):
|
|
np.random.seed(seed)
|
|
return (np.random.randn(8, 16, 32, 64).astype(np.float32),)
|
|
|
|
def pytorch_forward(self, x):
|
|
return torch.permute(x, (0, 2, 1, 3))
|
|
|
|
def foundry_params(self):
|
|
return {"dims": "0,2,1,3"}
|
|
|
|
|
|
def get_all_tests():
|
|
"""Return all matrix operation tests."""
|
|
return [
|
|
TestMatmul(),
|
|
TestMatmulSquare(),
|
|
TestBmm(),
|
|
TestMm(),
|
|
TestMv(),
|
|
TestDot(),
|
|
TestOuter(),
|
|
TestLinear(),
|
|
TestLinearNoBias(),
|
|
TestAddmm(),
|
|
TestTranspose(),
|
|
TestPermute(),
|
|
]
|
|
|
|
|
|
if __name__ == "__main__":
|
|
import sys
|
|
debug = "--debug" in sys.argv
|
|
|
|
runner = TestRunner()
|
|
for test in get_all_tests():
|
|
runner.add_test(test)
|
|
|
|
runner.run_all(debug=debug)
|
|
runner.save_results()
|