From c31c5235dae2e2c33e3df516208eccc773176108 Mon Sep 17 00:00:00 2001 From: Lutetium-Vanadium Date: Thu, 1 Jun 2023 15:08:17 +0800 Subject: [PATCH 1/3] Added CPP implementation of tug of war --- include/AMMBench.h | 1 + include/CPPAlgos/TugOfWarCPPAlgo.h | 61 ++++++++++++++++++++++++++++++ src/CPPAlgos/CMakeLists.txt | 1 + src/CPPAlgos/CPPAlgoTable.cpp | 1 + src/CPPAlgos/TugOfWarCPPAlgo.cpp | 50 ++++++++++++++++++++++++ test/SystemTest/TugOfWarTest.cpp | 11 ++++++ test/scripts/config_tugOfWar.csv | 2 +- 7 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 include/CPPAlgos/TugOfWarCPPAlgo.h create mode 100644 src/CPPAlgos/TugOfWarCPPAlgo.cpp diff --git a/include/AMMBench.h b/include/AMMBench.h index b77de81c..cfd147fb 100755 --- a/include/AMMBench.h +++ b/include/AMMBench.h @@ -105,6 +105,7 @@ #include #include #include +#include /** * @} * diff --git a/include/CPPAlgos/TugOfWarCPPAlgo.h b/include/CPPAlgos/TugOfWarCPPAlgo.h new file mode 100644 index 00000000..c396c27a --- /dev/null +++ b/include/CPPAlgos/TugOfWarCPPAlgo.h @@ -0,0 +1,61 @@ +// +// Created by luv on 5/30/23. +// + +#ifndef INTELLISTREAM_TUGOFWARCPPALGO_H +#define INTELLISTREAM_TUGOFWARCPPALGO_H + +#include + +namespace AMMBench { +/** + * @ingroup AMMBENCH_CppAlgos The algorithms writtrn in c++ + * @{ + */ +/** + * @class CRSCPPlgo CPPAlgos/TugOfWarCPPAlgo.h + * @brief The cloumn row sampling (CRS) class of c++ algos + * + */ + class TugOfWarCPPAlgo : public AMMBench::AbstractCPPAlgo { + public: + TugOfWarCPPAlgo() { + + } + + ~TugOfWarCPPAlgo() { + + } + + /** + * @brief the virtual function provided for outside callers, rewrite in children classes + * @param A the A matrix + * @param B the B matrix + * @param sketchSize the size of sketc or sampling + * @return the output c matrix + */ + virtual torch::Tensor amm(torch::Tensor A, torch::Tensor B, int sketchSize); + + private: + torch::Tensor generateTugOfWarMatrix(int64_t m, int64_t n); + + }; + +/** + * @ingroup AMMBENCH_CppAlgos + * @typedef AbstractMatrixCppAlgoPtr + * @brief The class to describe a shared pointer to @ref TugOfWarCppAlgo + + */ + typedef std::shared_ptr TugOfWarCPPAlgoPtr; +/** + * @ingroup AMMBENCH_CppAlgos + * @def newTugOfWarCppAlgo + * @brief (Macro) To creat a new @ref TugOfWarCppAlgounder shared pointer. + */ +#define newTugOfWarCPPAlgo std::make_shared +} +/** + * @} + */ +#endif //INTELLISTREAM_TUGOFWARCPPALGO_H diff --git a/src/CPPAlgos/CMakeLists.txt b/src/CPPAlgos/CMakeLists.txt index a8cd3898..88da1f7c 100644 --- a/src/CPPAlgos/CMakeLists.txt +++ b/src/CPPAlgos/CMakeLists.txt @@ -8,5 +8,6 @@ add_sources( CoOccurringFDCPPAlgo.cpp BetaCoOFDCPPAlgo.cpp CountSketchCPPAlgo.cpp + TugOfWarCPPAlgo.cpp ) diff --git a/src/CPPAlgos/CPPAlgoTable.cpp b/src/CPPAlgos/CPPAlgoTable.cpp index 458461e9..f303e327 100644 --- a/src/CPPAlgos/CPPAlgoTable.cpp +++ b/src/CPPAlgos/CPPAlgoTable.cpp @@ -23,6 +23,7 @@ AMMBench::CPPAlgoTable::CPPAlgoTable() { algoMap["ews"] = newEWSCPPAlgo(); algoMap["CoOFD"] = newCoOccurringFDCPPAlgo(); algoMap["bcoofd"] = newBetaCoOFDCPPAlgo(); + algoMap["tug-of-war"] = newTugOfWarCPPAlgo(); } } // AMMBench diff --git a/src/CPPAlgos/TugOfWarCPPAlgo.cpp b/src/CPPAlgos/TugOfWarCPPAlgo.cpp new file mode 100644 index 00000000..29db44df --- /dev/null +++ b/src/CPPAlgos/TugOfWarCPPAlgo.cpp @@ -0,0 +1,50 @@ +// +// Created by luv on 5/30/23. +// + +#include + +namespace AMMBench { + torch::Tensor TugOfWarCPPAlgo::generateTugOfWarMatrix(int64_t m, int64_t n) { + double e = 1.0 / std::sqrt(m); + torch::Tensor M = torch::randint(2, {m, n}); + return e * (2 * M - 1); + } + + torch::Tensor TugOfWarCPPAlgo::amm(torch::Tensor A, torch::Tensor B, int l) { + int n = A.size(1); + int p = B.size(1); + + double delta = 0.2; + + int i_iters = static_cast(-std::log(delta)); + int j_iters = static_cast(2 * (-std::log(delta) + std::log(-std::log(delta)))); + + torch::Tensor z = torch::empty({i_iters}); + std::vector AS; + std::vector SB; + + for (int i = 0; i < i_iters; ++i) { + torch::Tensor S = generateTugOfWarMatrix(l, n); + SB.push_back(S.matmul(B)); + AS.push_back(A.matmul(S.t())); + + torch::Tensor y = torch::empty({j_iters}); + + for (int j = 0; j < j_iters; ++j) { + torch::Tensor Q = generateTugOfWarMatrix(16, p); + torch::Tensor X = A.matmul(B.matmul(Q.t())); + torch::Tensor X_hat = AS[i].matmul(SB[i].matmul(Q.t())); + y[j] = torch::norm(X - X_hat).pow(2); + } + + + z[i] = at::median(y); + } + + torch::Tensor z_argmin = z.argmin(); + int i_star = z_argmin.item(); + + return AS[i_star].matmul(SB[i_star]); + } +} // AMMBench diff --git a/test/SystemTest/TugOfWarTest.cpp b/test/SystemTest/TugOfWarTest.cpp index 6e623525..ccdb7f81 100644 --- a/test/SystemTest/TugOfWarTest.cpp +++ b/test/SystemTest/TugOfWarTest.cpp @@ -54,3 +54,14 @@ TEST_CASE("Test the Tug of War", "[short]") // place your test here REQUIRE(a == 0); } +TEST_CASE("Test Tug of War in cpp", "[short]") +{ + torch::manual_seed(114514); + AMMBench::TugOfWarCPPAlgo tw; + auto A = torch::rand({400, 400}); + auto B = torch::rand({400, 400}); + auto realC = torch::matmul(A, B); + auto ammC = tw.amm(A, B, 20); + double froError = INTELLI::UtilityFunctions::relativeFrobeniusNorm(realC, ammC); + REQUIRE(froError < 0.5); +} diff --git a/test/scripts/config_tugOfWar.csv b/test/scripts/config_tugOfWar.csv index a63e79b2..d695764b 100644 --- a/test/scripts/config_tugOfWar.csv +++ b/test/scripts/config_tugOfWar.csv @@ -3,4 +3,4 @@ aRow,100,U64 aCol,1000,U64 bCol,500,U64 sketchDimension,25,U64 -ptFile,torchscripts/CRSV2.pt,String \ No newline at end of file +ptFile,torchscripts/TugOfWar.pt,String From 9ab553eadb808de18ea66205ecb69f8bdadfc54d Mon Sep 17 00:00:00 2001 From: Lutetium-Vanadium Date: Thu, 1 Jun 2023 15:13:40 +0800 Subject: [PATCH 2/3] Fix compilation error --- src/CPPAlgos/CPPAlgoTable.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/CPPAlgos/CPPAlgoTable.cpp b/src/CPPAlgos/CPPAlgoTable.cpp index f303e327..f4e4aac8 100644 --- a/src/CPPAlgos/CPPAlgoTable.cpp +++ b/src/CPPAlgos/CPPAlgoTable.cpp @@ -12,6 +12,7 @@ #include #include #include +#include namespace AMMBench { AMMBench::CPPAlgoTable::CPPAlgoTable() { From 9f6b6f58917bd349831570957bcebe08e519525b Mon Sep 17 00:00:00 2001 From: Lutetium-Vanadium Date: Fri, 2 Jun 2023 20:07:09 +0800 Subject: [PATCH 3/3] Make delta configurale during instantiation --- include/CPPAlgos/TugOfWarCPPAlgo.h | 6 ++++++ src/CPPAlgos/TugOfWarCPPAlgo.cpp | 2 -- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/include/CPPAlgos/TugOfWarCPPAlgo.h b/include/CPPAlgos/TugOfWarCPPAlgo.h index c396c27a..3ff12d98 100644 --- a/include/CPPAlgos/TugOfWarCPPAlgo.h +++ b/include/CPPAlgos/TugOfWarCPPAlgo.h @@ -18,11 +18,17 @@ namespace AMMBench { * */ class TugOfWarCPPAlgo : public AMMBench::AbstractCPPAlgo { + double delta = 0.2; + public: TugOfWarCPPAlgo() { } + TugOfWarCPPAlgo(double delta): delta(delta) { + + } + ~TugOfWarCPPAlgo() { } diff --git a/src/CPPAlgos/TugOfWarCPPAlgo.cpp b/src/CPPAlgos/TugOfWarCPPAlgo.cpp index 29db44df..db7a7a53 100644 --- a/src/CPPAlgos/TugOfWarCPPAlgo.cpp +++ b/src/CPPAlgos/TugOfWarCPPAlgo.cpp @@ -15,8 +15,6 @@ namespace AMMBench { int n = A.size(1); int p = B.size(1); - double delta = 0.2; - int i_iters = static_cast(-std::log(delta)); int j_iters = static_cast(2 * (-std::log(delta) + std::log(-std::log(delta))));