diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index 3255493e..78245655 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -46,4 +46,5 @@ jobs: run: | ./cpp_test "--success" ./sketch_test "--success" - ./crs_test "--success" \ No newline at end of file + ./crs_test "--success" + ./weighted_cr_test "--success" \ No newline at end of file diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index f1fa57db..0d709fd6 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -21,6 +21,6 @@ endmacro() add_catch_test(cpp_test SystemTest/SimpleTest.cpp IntelliStream) add_catch_test(sketch_test SystemTest/SketchTest.cpp IntelliStream) add_catch_test(crs_test SystemTest/CRSTest.cpp IntelliStream) - +add_catch_test(weighted_cr_test SystemTest/WeightedCRTest.cpp IntelliStream) diff --git a/test/SystemTest/WeightedCRTest.cpp b/test/SystemTest/WeightedCRTest.cpp new file mode 100644 index 00000000..80e03641 --- /dev/null +++ b/test/SystemTest/WeightedCRTest.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/WeightedCR.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_WeightedCR.csv"); + // place your test here + REQUIRE(a == 0); +} \ No newline at end of file diff --git a/test/scripts/config_WeightedCR.csv b/test/scripts/config_WeightedCR.csv new file mode 100644 index 00000000..b6afe1ef --- /dev/null +++ b/test/scripts/config_WeightedCR.csv @@ -0,0 +1,6 @@ +key,value,type +aRow,100,U64 +aCol,1000,U64 +bCol,500,U64 +sketchDimension,25,U64 +ptFile,torchscripts/CRS.pt,String \ No newline at end of file diff --git a/test/torchscripts/WeightedCR.py b/test/torchscripts/WeightedCR.py new file mode 100644 index 00000000..e0a869b6 --- /dev/null +++ b/test/torchscripts/WeightedCR.py @@ -0,0 +1,113 @@ +import torch +import time + +@torch.jit.script +def CR(A: torch.Tensor, B: torch.Tensor, c: int) -> torch.Tensor: + """CR algorithm https://www.stat.berkeley.edu/~mmahoney/pubs/matrix1_SICOMP.pdf + + Args: + A (torch.Tensor): matrix A + B (torch.Tensor): matrix B + c (int): number of sampling + + Returns: + torch.Tensor: CR approximation matrix + """ + torch.manual_seed(0) + + _, n = A.shape + + # probability distribution + probability_distribution = torch.zeros((n)) + for i in range(n): + probability_distribution[i] = torch.norm(A.T[i], p='fro')*torch.norm(B[i], p='fro') + probability_distribution /= probability_distribution.sum() + + # S + S = torch.zeros((n, c)) + sample_indices = torch.multinomial(probability_distribution, c, replacement=True) + + for trial, index in enumerate(sample_indices): + S[int(index.item())][trial]=1 + + # D + D = torch.diag(1/torch.sqrt(c*probability_distribution[sample_indices])) + + # ASD(SD)^TB + SS = torch.matmul(S, D) + C = torch.matmul(A, SS) + R = torch.matmul(SS.T, B) + CR = torch.matmul(C, R) + + return CR + + +@torch.jit.script +def weighted_CR(A: torch.Tensor, B: torch.Tensor, c: int): + """weighted CR algorithm https://arxiv.org/abs/2011.09709 + + Args: + A (torch.Tensor): matrix A + B (torch.Tensor): matrix B + c (int): number of sampling + + Returns: + torch.Tensor: weighted CR approximation matrix + """ + torch.manual_seed(0) + + _, n = A.shape + + # probability distribution + probability_distribution = torch.zeros((n)) + for i in range(n): + probability_distribution[i] = torch.norm(A.T[i], p='fro')*torch.norm(B[i], p='fro') + probability_distribution /= probability_distribution.sum() + + # S + sample_indices = torch.multinomial(probability_distribution, c, replacement=True) + unique_indices, occurences = torch.unique(sample_indices, return_counts=True) + + S = torch.zeros((n, len(unique_indices))) + + for trial, index in enumerate(unique_indices): + S[int(index.item())][trial]=1 + + # D + D = torch.diag(torch.sqrt(occurences)/torch.sqrt(c*probability_distribution[unique_indices])) + + # ASD(SD)^TB + SS = torch.matmul(S, D) + C = torch.matmul(A, SS) + R = torch.matmul(SS.T, B) + weighted_CR = torch.matmul(C, R) + + return weighted_CR + + +def main(): + A = torch.rand(10000, 1000) + B = torch.rand(1000, 5000) + c = 100 + + t = time.time() + AB = torch.matmul(A, B) + print("AB time: ", time.time() - t) + print("AB fro: ", torch.norm(AB, p='fro')) + + t = time.time() + + CR_result = CR(A, B, c) + print("CR time: ", time.time() - t) + print("CR error: ", torch.norm(AB-CR_result, p='fro')) + + t = time.time() + weighted_CR_result = weighted_CR(A, B, c) + print("weighted_CR time: ", time.time() - t) + print("weighted_CR error: ", torch.norm(AB-weighted_CR_result, p='fro')) + + # CR.save("CR.pt") + weighted_CR.save("weighted_CR.pt") + +if __name__ == '__main__': + main() diff --git a/test/torchscripts/weightedCR.pt b/test/torchscripts/weightedCR.pt new file mode 100644 index 00000000..0c897ec3 Binary files /dev/null and b/test/torchscripts/weightedCR.pt differ