From b8a7fad482f2db6ac412c60dd1de0e80efa80d78 Mon Sep 17 00:00:00 2001 From: darthnoward Date: Thu, 25 May 2023 18:24:16 +0800 Subject: [PATCH] add pytorch script for Subsampled Randomized Hadamard Transform (SRHT) --- benchmark/torchscripts/SRHT.pt | Bin 0 -> 3451 bytes benchmark/torchscripts/SRHT.py | 64 +++++++++++++++++++++++++++++++++ test/SystemTest/SRHTTest.cpp | 56 +++++++++++++++++++++++++++++ test/scripts/config_SRHT.csv | 6 ++++ test/torchscripts/SRHT.pt | Bin 0 -> 3451 bytes test/torchscripts/SRHT.py | 64 +++++++++++++++++++++++++++++++++ 6 files changed, 190 insertions(+) create mode 100644 benchmark/torchscripts/SRHT.pt create mode 100644 benchmark/torchscripts/SRHT.py create mode 100644 test/SystemTest/SRHTTest.cpp create mode 100644 test/scripts/config_SRHT.csv create mode 100644 test/torchscripts/SRHT.pt create mode 100644 test/torchscripts/SRHT.py diff --git a/benchmark/torchscripts/SRHT.pt b/benchmark/torchscripts/SRHT.pt new file mode 100644 index 0000000000000000000000000000000000000000..970df09986e9bf3bf9544a97d5b3f6987ce03c0e GIT binary patch literal 3451 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 R1#SJ3003y~+1CH8`#%n9f|mdQ literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..970df09986e9bf3bf9544a97d5b3f6987ce03c0e GIT binary patch literal 3451 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 R1#SJ3003y~+1CH8`#%n9f|mdQ literal 0 HcmV?d00001 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