diff --git a/include/AMMBench.h b/include/AMMBench.h index 84e5da35..757fffea 100755 --- a/include/AMMBench.h +++ b/include/AMMBench.h @@ -99,6 +99,7 @@ #include #include #include +#include /** * @} * diff --git a/include/CPPAlgos/CRSV2CPPAlgo.h b/include/CPPAlgos/CRSV2CPPAlgo.h new file mode 100644 index 00000000..c83fedc5 --- /dev/null +++ b/include/CPPAlgos/CRSV2CPPAlgo.h @@ -0,0 +1,58 @@ +// +// Created by haolan on 5/26/23. +// + +#ifndef INTELLISTREAM_CRSV2CPPALGO_H +#define INTELLISTREAM_CRSV2CPPALGO_H + +#include + +namespace AMMBench { +/** + * @ingroup AMMBENCH_CppAlgos The algorithms writtrn in c++ + * @{ + */ +/** + * @class CRSCPPlgo CPPAlgos/CRSV2CPPAlgo.h + * @brief The cloumn row sampling (CRS) class of c++ algos + * + */ + class CRSV2CPPAlgo : public AMMBench::AbstractCPPAlgo { + public: + CRSV2CPPAlgo() { + + } + + ~CRSV2CPPAlgo() { + + } + + /** + * @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); + + }; + +/** + * @ingroup AMMBENCH_CppAlgos + * @typedef AbstractMatrixCppAlgoPtr + * @brief The class to describe a shared pointer to @ref CRSV2CppAlgo + + */ + typedef std::shared_ptr CRSV2CPPAlgoPtr; +/** + * @ingroup AMMBENCH_CppAlgos + * @def newCRSV2CppAlgo + * @brief (Macro) To creat a new @ref CRSV2CppAlgounder shared pointer. + */ +#define newCRSV2CPPAlgo std::make_shared +} +/** + * @} + */ +#endif //INTELLISTREAM_CRSV2CPPALGO_H diff --git a/src/CPPAlgos/CMakeLists.txt b/src/CPPAlgos/CMakeLists.txt index f8805edd..79f5a9d4 100644 --- a/src/CPPAlgos/CMakeLists.txt +++ b/src/CPPAlgos/CMakeLists.txt @@ -2,4 +2,5 @@ add_sources( AbstractCPPAlgo.cpp CRSCPPAlgo.cpp CPPAlgoTable.cpp + CRSV2CPPAlgo.cpp ) \ No newline at end of file diff --git a/src/CPPAlgos/CPPAlgoTable.cpp b/src/CPPAlgos/CPPAlgoTable.cpp index 572856a0..af137843 100644 --- a/src/CPPAlgos/CPPAlgoTable.cpp +++ b/src/CPPAlgos/CPPAlgoTable.cpp @@ -4,10 +4,12 @@ #include #include +#include namespace AMMBench { AMMBench::CPPAlgoTable::CPPAlgoTable() { algoMap["mm"] = newAbstractCPPAlgo(); algoMap["crs"] = newCRSCPPAlgo(); + algoMap["crsV2"] = newCRSV2CPPAlgo(); } } // AMMBench \ No newline at end of file diff --git a/src/CPPAlgos/CRSV2CPPAlgo.cpp b/src/CPPAlgos/CRSV2CPPAlgo.cpp new file mode 100644 index 00000000..01378f76 --- /dev/null +++ b/src/CPPAlgos/CRSV2CPPAlgo.cpp @@ -0,0 +1,40 @@ +// +// Created by haolan on 5/26/23. +// + +#include + +namespace AMMBench { + torch::Tensor AMMBench::CRSV2CPPAlgo::amm(torch::Tensor A, torch::Tensor B, int k) { + A = A.t(); + auto A_size = A.sizes(); + int64_t n = A_size[0]; + // int64_t m = A_size[1]; + + assert(n == B.size(0)); + //TORCH_CHECK(n == B.size(0)); + //TORCH_CHECK(k < n); + + //INTELLI_INFO("Running CRS V2 CPP"); + + // probability distribution + torch::Tensor sample = torch::rand({n}); // default: uniform + + // diagonal scaling matrix D (nxn) + sample = sample.div(sample.sum()); + torch::Tensor D = torch::diag(1.0 / torch::sqrt(k * sample)); + + // sampling matrix S (kxn) + torch::Tensor column_indices = torch::multinomial(sample, k, true); + torch::Tensor S = torch::zeros({k, n}); + for (int64_t row = 0; row < k; row++) { + int64_t col = column_indices[row].item(); + S[row][col] = 1; + } + + torch::Tensor a = torch::matmul(torch::matmul(A.t(), D), S.t()); + torch::Tensor b = torch::matmul(torch::matmul(a, S), D); + + return torch::matmul(b, B); + } +} // AMMBench \ No newline at end of file diff --git a/test/SystemTest/CRSTest.cpp b/test/SystemTest/CRSTest.cpp index 168cdd85..33c4add2 100644 --- a/test/SystemTest/CRSTest.cpp +++ b/test/SystemTest/CRSTest.cpp @@ -61,7 +61,7 @@ TEST_CASE("Test the COLUMN ROW SAMPLINGS, V2", "[short]") // place your test here REQUIRE(a == 0); } -TEST_CASE("Test pure cpp versiom", "[short]") +TEST_CASE("Test CRS in cpp", "[short]") { torch::manual_seed(114514); AMMBench::CRSCPPAlgo crs; @@ -71,4 +71,15 @@ TEST_CASE("Test pure cpp versiom", "[short]") auto ammC = crs.amm(A, B, 20); double froError = INTELLI::UtilityFunctions::relativeFrobeniusNorm(realC, ammC); REQUIRE(froError < 0.5); +} +TEST_CASE("Test CRS v2 in cpp", "[short]") +{ + torch::manual_seed(114514); + AMMBench::CRSV2CPPAlgo crs; + auto A = torch::rand({400, 400}); + auto B = torch::rand({400, 400}); + auto realC = torch::matmul(A, B); + auto ammC = crs.amm(A, B, 20); + double froError = INTELLI::UtilityFunctions::relativeFrobeniusNorm(realC, ammC); + REQUIRE(froError < 0.5); } \ No newline at end of file