diff --git a/benchmark/torchscripts/SRHT.pt b/benchmark/torchscripts/SRHT.pt new file mode 100644 index 00000000..970df099 Binary files /dev/null and b/benchmark/torchscripts/SRHT.pt differ diff --git a/benchmark/torchscripts/SRHT.py b/benchmark/torchscripts/SRHT.py new file mode 100644 index 00000000..df271b0c --- /dev/null +++ b/benchmark/torchscripts/SRHT.py @@ -0,0 +1,64 @@ +import torch +import time + +@torch.jit.script +def SRHT(A: torch.Tensor, B: torch.Tensor, m: int): + # Get the dimension of A + A = A.t() + assert A.shape[0] == B.shape[0] + n = A.shape[0] + + # a diagonal matrix D with entries either -1 or 1 + diag_elements = torch.randint(2, (n,), dtype=torch.float32) * 2 - 1 + D = torch.diag(diag_elements) + + # unnormalized Hadamard transform matrix H + l = int(2 ** int(torch.ceil(torch.log2(torch.tensor(n))))) + H = torch.empty(l, l) + + for i in range(l): + for j in range(l): + H[i, j] = (-1) ** (bin(i & j).count('1') % 2) + H = H[:n, :n] + + # Random subsampling matrix S + S = torch.zeros((m, n)) + for i in range(m): + idx = torch.randint(n, (1,)).item() + S[i, int(idx)] = 1 + + Pi = (1 / torch.sqrt(torch.tensor(m).float())) * torch.matmul(torch.matmul(S, H), D) + A_transform = torch.matmul(Pi, A) + B_transform = torch.matmul(Pi, B) + return torch.matmul(A_transform.t(), B_transform) + +def main(): + + width = 500 + A = torch.rand(1000, width) + B = torch.rand(width, 1000) + + + t = time.time() + + aResult = SRHT(A, B, 100) + print("approximate: " + str(time.time() - t) + "s") + + print(aResult) + + # exact result + t = time.time() + eResult = torch.matmul(A, B) + print("\nExact: " + str(time.time() - t) + "s") + + print(eResult) + + difference = aResult - eResult + print("\nFrobenius norm error: " + str(torch.linalg.norm(difference, ord='fro').item())) + print("\nSpectral norm bound: " + str(torch.linalg.norm(difference, ord=2).item())) + + script = SRHT.save("SRHT.pt") + +if __name__ == '__main__': + main() + \ No newline at end of file diff --git a/test/SystemTest/SRHTTest.cpp b/test/SystemTest/SRHTTest.cpp new file mode 100644 index 00000000..c7caced7 --- /dev/null +++ b/test/SystemTest/SRHTTest.cpp @@ -0,0 +1,56 @@ +#include + +#define CATCH_CONFIG_MAIN +#include "catch.hpp" +#include +using namespace std; +using namespace INTELLI; +using namespace torch; +void runSingleThreadTest(std::string configName) { + ConfigMapPtr cfg = newConfigMap(); + cfg->fromFile(configName); + AMMBench::MatrixLoaderTable mLoaderTable; + uint64_t sketchDimension; + sketchDimension = cfg->tryU64("sketchDimension", 50, true); + uint64_t coreBind = cfg->tryU64("coreBind", 0, true); + UtilityFunctions::bind2Core((int) coreBind); + torch::set_num_threads(1); + std::string ptFile = cfg->tryString("ptFile", "torchscripts/FDAMM.pt", true); + + //uint64_t customResultName = cfg->tryU64("customResultName", 0, true); + INTELLI_INFO("Place me at core" + to_string(coreBind)); + INTELLI_INFO( + "with sketch" + to_string(sketchDimension)); + torch::jit::script::Module module; + INTELLI_INFO("Try pt file " + ptFile); + module = torch::jit::load(ptFile); + std::string matrixLoaderTag = cfg->tryString("matrixLoaderTag", "random", true); + auto matLoaderPtr = mLoaderTable.findMatrixLoader(matrixLoaderTag); + assert(matLoaderPtr); + matLoaderPtr->setConfig(cfg); + auto A = matLoaderPtr->getA(); + auto B = matLoaderPtr->getB(); + /*torch::manual_seed(114514); +//555 +auto A = torch::rand({(long) aRow, (long) aCol}); +auto B = torch::rand({(long) aCol, (long) bCol});*/ + INTELLI_INFO("Generation done, conducting..."); + ThreadPerf pef((int) coreBind); + pef.setPerfList(); + pef.start(); + auto C =module.forward({A, B, (long) sketchDimension}).toTensor(); + pef.end(); + std::string ruName = "default"; + + auto resultCsv = pef.resultToConfigMap(); + resultCsv->toFile(ruName + ".csv"); + INTELLI_INFO("Done. here is result"); + std::cout << resultCsv->toString() << endl; +} +TEST_CASE("Test the COLUMN ROW SAMPLINGS", "[short]") +{ + int a = 0; + runSingleThreadTest("scripts/config_SRHT.csv"); + // place your test here + REQUIRE(a == 0); +} diff --git a/test/scripts/config_SRHT.csv b/test/scripts/config_SRHT.csv new file mode 100644 index 00000000..71a5c9ef --- /dev/null +++ b/test/scripts/config_SRHT.csv @@ -0,0 +1,6 @@ +key,value,type +aRow,100,U64 +aCol,1000,U64 +bCol,500,U64 +sketchDimension,25,U64 +ptFile,torchscripts/SRHT.pt,String diff --git a/test/torchscripts/SRHT.pt b/test/torchscripts/SRHT.pt new file mode 100644 index 00000000..970df099 Binary files /dev/null and b/test/torchscripts/SRHT.pt differ diff --git a/test/torchscripts/SRHT.py b/test/torchscripts/SRHT.py new file mode 100644 index 00000000..df271b0c --- /dev/null +++ b/test/torchscripts/SRHT.py @@ -0,0 +1,64 @@ +import torch +import time + +@torch.jit.script +def SRHT(A: torch.Tensor, B: torch.Tensor, m: int): + # Get the dimension of A + A = A.t() + assert A.shape[0] == B.shape[0] + n = A.shape[0] + + # a diagonal matrix D with entries either -1 or 1 + diag_elements = torch.randint(2, (n,), dtype=torch.float32) * 2 - 1 + D = torch.diag(diag_elements) + + # unnormalized Hadamard transform matrix H + l = int(2 ** int(torch.ceil(torch.log2(torch.tensor(n))))) + H = torch.empty(l, l) + + for i in range(l): + for j in range(l): + H[i, j] = (-1) ** (bin(i & j).count('1') % 2) + H = H[:n, :n] + + # Random subsampling matrix S + S = torch.zeros((m, n)) + for i in range(m): + idx = torch.randint(n, (1,)).item() + S[i, int(idx)] = 1 + + Pi = (1 / torch.sqrt(torch.tensor(m).float())) * torch.matmul(torch.matmul(S, H), D) + A_transform = torch.matmul(Pi, A) + B_transform = torch.matmul(Pi, B) + return torch.matmul(A_transform.t(), B_transform) + +def main(): + + width = 500 + A = torch.rand(1000, width) + B = torch.rand(width, 1000) + + + t = time.time() + + aResult = SRHT(A, B, 100) + print("approximate: " + str(time.time() - t) + "s") + + print(aResult) + + # exact result + t = time.time() + eResult = torch.matmul(A, B) + print("\nExact: " + str(time.time() - t) + "s") + + print(eResult) + + difference = aResult - eResult + print("\nFrobenius norm error: " + str(torch.linalg.norm(difference, ord='fro').item())) + print("\nSpectral norm bound: " + str(torch.linalg.norm(difference, ord=2).item())) + + script = SRHT.save("SRHT.pt") + +if __name__ == '__main__': + main() + \ No newline at end of file