From 37e5d3afb9d0dacedfd6c2fe95ba082a80461294 Mon Sep 17 00:00:00 2001 From: darthnoward Date: Sun, 25 Jun 2023 21:44:44 +0800 Subject: [PATCH 1/2] add raw PQ, using Euclidean distance to find matching prototypes. --- benchmark/torchscripts/prototypes.pt | Bin 0 -> 66519 bytes include/AMMBench.h | 2 +- include/CPPAlgos/ProductQuantizationRaw.h | 57 +++++++++++++++++++ src/CPPAlgos/CMakeLists.txt | 1 + src/CPPAlgos/CPPAlgoTable.cpp | 3 +- src/CPPAlgos/ProductQuantizationRaw.cpp | 65 ++++++++++++++++++++++ src/MatrixLoader/BinomialMatrixLoader.cpp | 4 +- test/CMakeLists.txt | 2 +- test/SystemTest/PQTest.cpp | 24 ++++++++ test/torchscripts/prototypes.pt | Bin 0 -> 66519 bytes 10 files changed, 153 insertions(+), 5 deletions(-) create mode 100644 benchmark/torchscripts/prototypes.pt create mode 100644 include/CPPAlgos/ProductQuantizationRaw.h create mode 100644 src/CPPAlgos/ProductQuantizationRaw.cpp create mode 100644 test/SystemTest/PQTest.cpp create mode 100644 test/torchscripts/prototypes.pt diff --git a/benchmark/torchscripts/prototypes.pt b/benchmark/torchscripts/prototypes.pt new file mode 100644 index 0000000000000000000000000000000000000000..f9c12cb6a18889fb20f76586623f7005d9d62d45 GIT binary patch literal 66519 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 I{vY@KAEo^Y!~g&Q literal 0 HcmV?d00001 diff --git a/include/AMMBench.h b/include/AMMBench.h index 427653aa..30ee9627 100755 --- a/include/AMMBench.h +++ b/include/AMMBench.h @@ -124,7 +124,7 @@ #include #include #include - +#include #include #include diff --git a/include/CPPAlgos/ProductQuantizationRaw.h b/include/CPPAlgos/ProductQuantizationRaw.h new file mode 100644 index 00000000..23342529 --- /dev/null +++ b/include/CPPAlgos/ProductQuantizationRaw.h @@ -0,0 +1,57 @@ +// +// Created by haolan on 22/6/23. +// + +#ifndef AMMBENCH_PRODUCTQUANTIZATIONRAW_H +#define AMMBENCH_PRODUCTQUANTIZATIONRAW_H +#include + +namespace AMMBench { +/** + * @ingroup AMMBENCH_CppAlgos The algorithms written in c++ + * @{ + */ +/** + * @class ProductQuantizationRawAlgo CPPAlgos/ProductQuantizationRaw.h + * @brief The Product Quantization AMM class of c++ algos, using Euclidean distance + * + */ + class ProductQuantizationRaw : public AMMBench::AbstractCPPAlgo { + public: + ProductQuantizationRaw() { + + } + + ~ProductQuantizationRaw() { + + } + + /** + * @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, uint64_t sketchSize); + + }; + +/** + * @ingroup AMMBENCH_CppAlgos + * @typedef AbstractMatrixCppAlgoPtr + * @brief The class to describe a shared pointer to @ref ProductQuantizationRawAlgo + + */ + typedef std::shared_ptr ProductQuantizationRawPtr; +/** + * @ingroup AMMBENCH_CppAlgos + * @def newProductQuantizationRawAlgo + * @brief (Macro) To creat a new @ref ProductQuantizationRawAlgounder shared pointer. + */ +#define newProductQuantizationRawAlgo std::make_shared +} +/** + * @} + */ +#endif //AMMBENCH_PRODUCTQUANTIZATIONRAW_H diff --git a/src/CPPAlgos/CMakeLists.txt b/src/CPPAlgos/CMakeLists.txt index 139ce09d..bb701f31 100644 --- a/src/CPPAlgos/CMakeLists.txt +++ b/src/CPPAlgos/CMakeLists.txt @@ -12,5 +12,6 @@ add_sources( INT8CPPAlgo.cpp TugOfWarCPPAlgo.cpp SMPPCACPPAlgo.cpp + ProductQuantizationRaw.cpp ) diff --git a/src/CPPAlgos/CPPAlgoTable.cpp b/src/CPPAlgos/CPPAlgoTable.cpp index 757cd422..38818d43 100644 --- a/src/CPPAlgos/CPPAlgoTable.cpp +++ b/src/CPPAlgos/CPPAlgoTable.cpp @@ -7,7 +7,7 @@ #include #include - +#include #include #include #include @@ -30,6 +30,7 @@ AMMBench::CPPAlgoTable::CPPAlgoTable() { algoMap["tugOfWar"] = newTugOfWarCPPAlgo(); algoMap["weighted-cr"] = newWeightedCRCPPAlgo(); algoMap["smp-pca"] = newSMPPCACPPAlgo(); + algoMap["pq-raw"] = newProductQuantizationRawAlgo(); } } // AMMBench diff --git a/src/CPPAlgos/ProductQuantizationRaw.cpp b/src/CPPAlgos/ProductQuantizationRaw.cpp new file mode 100644 index 00000000..56680fc1 --- /dev/null +++ b/src/CPPAlgos/ProductQuantizationRaw.cpp @@ -0,0 +1,65 @@ +// +// Created by haolan on 22/6/23. +// +#include +torch::Tensor AMMBench::ProductQuantizationRaw::amm(torch::Tensor A, torch::Tensor B, uint64_t sketchSize) { + const int D = A.size(1); + int C; + if (sketchSize < 50) C = (int) sketchSize; + C = 10; + const int D_c = D / C; + + torch::Tensor prototypes; + + torch::serialize::InputArchive archive; + archive.load_from("torchscripts/prototypes.pt"); + archive.read("prototypes", prototypes); + + std::vector A_encoded; + + for (int i = 0; i < A.size(0); ++i) { + torch::Tensor a = A[i]; + std::vector a_encoded; + for (int c = 0; c < C; ++c) { + auto prototypes_c = prototypes[c]; + auto a_subvector = a.slice(0, c * D_c, (c + 1) * D_c); + + auto distances = torch::norm(prototypes_c - a_subvector.expand_as(prototypes_c), 1); + auto closest_prototype_index = torch::argmin(distances); + a_encoded.push_back(closest_prototype_index.unsqueeze(0)); + } + A_encoded.push_back(torch::cat(a_encoded)); + } + torch::Tensor A_encoded_tensor = torch::stack(A_encoded); + + std::vector tables; + + for (int c = 0; c < C; ++c) { + auto prototypes_c = prototypes[c]; + auto B_subspace = B.slice(0, c * D_c, (c + 1) * D_c); + + std::vector table_c; + for (int i = 0; i < prototypes_c.size(0); ++i) { + auto prototype = prototypes_c[i]; + auto dot_products = prototype.matmul(B_subspace); + table_c.push_back(dot_products); + } + tables.push_back(torch::stack(table_c)); + } + + std::vector result; + + for (int i = 0; i < A_encoded_tensor.size(0); ++i) { + auto a_encoded = A_encoded_tensor[i]; + auto row_sum = torch::zeros({B.size(1)}); + for (int c = 0; c < C; ++c) { + int prototype_index = a_encoded[c].item(); + auto table_c = tables[c]; + auto dot_products = table_c[prototype_index]; + row_sum += dot_products; + } + result.push_back(row_sum); + } + + return torch::stack(result); +} \ No newline at end of file diff --git a/src/MatrixLoader/BinomialMatrixLoader.cpp b/src/MatrixLoader/BinomialMatrixLoader.cpp index a29e4bbe..7ea4934e 100644 --- a/src/MatrixLoader/BinomialMatrixLoader.cpp +++ b/src/MatrixLoader/BinomialMatrixLoader.cpp @@ -19,7 +19,7 @@ void AMMBench::BinomialMatrixLoader::generateAB() { A = torch::zeros({(long) aRow, (long) aCol}); B = torch::zeros({(long) aCol, (long) bCol}); - for(int i = 0; i < trials; i++) { + for(uint64_t i = 0; i < trials; i++) { // Create a tensor filled with random numbers between 0 and 1 torch::Tensor rand_tensor = torch::rand({(long) aRow, (long) aCol}); @@ -27,7 +27,7 @@ void AMMBench::BinomialMatrixLoader::generateAB() { A += (rand_tensor < probability).to(torch::kInt); } - for(int i = 0; i < trials; i++) { + for(uint64_t i = 0; i < trials; i++) { // Create a tensor filled with random numbers between 0 and 1 torch::Tensor rand_tensor = torch::rand({(long) aCol, (long) bCol}); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index e708c62b..30ca7ca0 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -27,4 +27,4 @@ add_catch_test(smp_pca_test SystemTest/SMPPCATest.cpp IntelliStream) add_catch_test(block_partition_test SystemTest/BlockPartitionTest.cpp IntelliStream) add_catch_test(tug_of_war_test SystemTest/TugOfWarTest.cpp IntelliStream) add_catch_test(int8_test SystemTest/INT8Test.cpp IntelliStream) - +add_catch_test(pq_test SystemTest/PQTest.cpp IntelliStream) diff --git a/test/SystemTest/PQTest.cpp b/test/SystemTest/PQTest.cpp new file mode 100644 index 00000000..3d884549 --- /dev/null +++ b/test/SystemTest/PQTest.cpp @@ -0,0 +1,24 @@ +// +// Created by haolan on 25/6/23. +// +#include + +#define CATCH_CONFIG_MAIN +#include "catch.hpp" +#include +#include +TEST_CASE("Test PQ", "[short]") +{ + torch::manual_seed(114514); + AMMBench::ProductQuantizationRaw pqRaw; + auto A = torch::rand({1000, 1000}); + auto B = torch::rand({1000, 1000}); + auto realC = torch::matmul(A, B); + auto ammC = pqRaw.amm(A, B, 20); + std::cout << "PQ:" << std::endl; + std::cout << ammC << std::endl; + std::cout << "exact:" << std::endl; + std::cout << realC << std::endl; + double froError = INTELLI::UtilityFunctions::relativeFrobeniusNorm(realC, ammC); + REQUIRE(froError < 0.5); +} \ No newline at end of file diff --git a/test/torchscripts/prototypes.pt b/test/torchscripts/prototypes.pt new file mode 100644 index 0000000000000000000000000000000000000000..f9c12cb6a18889fb20f76586623f7005d9d62d45 GIT binary patch literal 66519 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 I{vY@KAEo^Y!~g&Q literal 0 HcmV?d00001 From 9f102ec267159fdf6c15f48869ce7655fe96edc4 Mon Sep 17 00:00:00 2001 From: darthnoward Date: Sun, 25 Jun 2023 21:53:32 +0800 Subject: [PATCH 2/2] add PQ Hash, using hash function to find matching prototypes --- include/AMMBench.h | 1 + include/CPPAlgos/ProductQuantizationHash.h | 57 ++++++++++++++ src/CPPAlgos/CMakeLists.txt | 1 + src/CPPAlgos/CPPAlgoTable.cpp | 2 + src/CPPAlgos/ProductQuantizationHash.cpp | 92 ++++++++++++++++++++++ test/SystemTest/PQTest.cpp | 15 ++++ 6 files changed, 168 insertions(+) create mode 100644 include/CPPAlgos/ProductQuantizationHash.h create mode 100644 src/CPPAlgos/ProductQuantizationHash.cpp diff --git a/include/AMMBench.h b/include/AMMBench.h index 30ee9627..1f68ef41 100755 --- a/include/AMMBench.h +++ b/include/AMMBench.h @@ -125,6 +125,7 @@ #include #include #include +#include #include #include diff --git a/include/CPPAlgos/ProductQuantizationHash.h b/include/CPPAlgos/ProductQuantizationHash.h new file mode 100644 index 00000000..cc121dc6 --- /dev/null +++ b/include/CPPAlgos/ProductQuantizationHash.h @@ -0,0 +1,57 @@ +// +// Created by haolan on 25/6/23. +// + +#ifndef INTELLISTREAM_PRODUCTQUANTIZATIONHASH_H +#define INTELLISTREAM_PRODUCTQUANTIZATIONHASH_H +#include + +namespace AMMBench { +/** + * @ingroup AMMBENCH_CppAlgos The algorithms written in c++ + * @{ + */ +/** + * @class ProductQuantizationRawAlgo CPPAlgos/ProductQuantizationRaw.h + * @brief The Product Quantization AMM class of c++ algos, using hash function to find matching prototypes + * + */ + class ProductQuantizationHash : public AMMBench::AbstractCPPAlgo { + public: + ProductQuantizationHash() { + + } + + ~ProductQuantizationHash() { + + } + + /** + * @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, uint64_t sketchSize); + + }; + +/** + * @ingroup AMMBENCH_CppAlgos + * @typedef AbstractMatrixCppAlgoPtr + * @brief The class to describe a shared pointer to @ref ProductQuantizationHashAlgo + + */ + typedef std::shared_ptr ProductQuantizationHashPtr; +/** + * @ingroup AMMBENCH_CppAlgos + * @def newProductQuantizationHashAlgo + * @brief (Macro) To creat a new @ref ProductQuantizationHashAlgounder shared pointer. + */ +#define newProductQuantizationHashAlgo std::make_shared +} +/** + * @} + */ +#endif //INTELLISTREAM_PRODUCTQUANTIZATIONHASH_H diff --git a/src/CPPAlgos/CMakeLists.txt b/src/CPPAlgos/CMakeLists.txt index bb701f31..b31e0a0f 100644 --- a/src/CPPAlgos/CMakeLists.txt +++ b/src/CPPAlgos/CMakeLists.txt @@ -13,5 +13,6 @@ add_sources( TugOfWarCPPAlgo.cpp SMPPCACPPAlgo.cpp ProductQuantizationRaw.cpp + ProductQuantizationHash.cpp ) diff --git a/src/CPPAlgos/CPPAlgoTable.cpp b/src/CPPAlgos/CPPAlgoTable.cpp index 38818d43..146f7c9e 100644 --- a/src/CPPAlgos/CPPAlgoTable.cpp +++ b/src/CPPAlgos/CPPAlgoTable.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -31,6 +32,7 @@ AMMBench::CPPAlgoTable::CPPAlgoTable() { algoMap["weighted-cr"] = newWeightedCRCPPAlgo(); algoMap["smp-pca"] = newSMPPCACPPAlgo(); algoMap["pq-raw"] = newProductQuantizationRawAlgo(); + algoMap["pq-hash"] = newProductQuantizationHashAlgo(); } } // AMMBench diff --git a/src/CPPAlgos/ProductQuantizationHash.cpp b/src/CPPAlgos/ProductQuantizationHash.cpp new file mode 100644 index 00000000..222989f6 --- /dev/null +++ b/src/CPPAlgos/ProductQuantizationHash.cpp @@ -0,0 +1,92 @@ +// +// Created by haolan on 25/6/23. +// +#include + +int compute_hash_bucket(const std::vector& split_indices, const std::vector& split_thresholds, const torch::Tensor& x); +torch::Tensor AMMBench::ProductQuantizationHash::amm(torch::Tensor A, torch::Tensor B, uint64_t sketchSize) { + const int D = A.size(1); + int C; + if (sketchSize < 50) C = (int) sketchSize; + C = 10; + const int D_c = D / C; + + torch::Tensor prototypes; + + torch::serialize::InputArchive archive; + archive.load_from("torchscripts/prototypes.pt"); + archive.read("prototypes", prototypes); + + std::vector A_encoded; + + std::vector split_indices = {59, 54, 24, 79}; + torch::Tensor v1; + torch::Tensor v2; + torch::Tensor v3; + torch::Tensor v4; + + v1 = torch::tensor({{2.4377}}); + v2 = torch::tensor({{2.0435, 0.0047}}); + v3 = torch::tensor({{2.5292, -0.2861, 0.5683, 0.5683}}); + v4 = torch::tensor({{2.3362, -0.2747, -1.0972, -1.0972, 0.4769, 0.4769, 0.4769, 0.4769}}); + std::vector split_thresholds = {v1, v2, v3, v4}; + + + for (int i = 0; i < A.size(0); ++i) { + torch::Tensor a = A[i]; + std::vector a_encoded; + for (int c = 0; c < C; ++c) { + auto prototypes_c = prototypes[c]; + auto a_subvector = a.slice(0, c * D_c, (c + 1) * D_c); + + auto closest_prototype_index = compute_hash_bucket(split_indices, split_thresholds, a_subvector); + + a_encoded.push_back(torch::tensor(closest_prototype_index).unsqueeze(0)); + } + A_encoded.push_back(torch::cat(a_encoded)); + } + torch::Tensor A_encoded_tensor = torch::stack(A_encoded); + + std::vector tables; + + for (int c = 0; c < C; ++c) { + auto prototypes_c = prototypes[c]; + auto B_subspace = B.slice(0, c * D_c, (c + 1) * D_c); + + std::vector table_c; + for (int i = 0; i < prototypes_c.size(0); ++i) { + auto prototype = prototypes_c[i]; + auto dot_products = prototype.matmul(B_subspace); + table_c.push_back(dot_products); + } + tables.push_back(torch::stack(table_c)); + } + + std::vector result; + + for (int i = 0; i < A_encoded_tensor.size(0); ++i) { + auto a_encoded = A_encoded_tensor[i]; + auto row_sum = torch::zeros({B.size(1)}); + for (int c = 0; c < C; ++c) { + int prototype_index = a_encoded[c].item(); + auto table_c = tables[c]; + auto dot_products = table_c[prototype_index]; + row_sum += dot_products; + } + result.push_back(row_sum); + } + + return torch::stack(result); +} + +int compute_hash_bucket(const std::vector& split_indices, const std::vector& split_thresholds, const torch::Tensor& x) { + int i = 0; + for (int t = 0; t < 4; t++) { + int j_t = split_indices[t]; + torch::Tensor v_t = split_thresholds[t]; + float v = v_t[0][i].item(); + int b = (x[j_t].item() >= v) ? 1 : 0; + i = 2 * i - 1 + b; + } + return i; +} \ No newline at end of file diff --git a/test/SystemTest/PQTest.cpp b/test/SystemTest/PQTest.cpp index 3d884549..5ad7036f 100644 --- a/test/SystemTest/PQTest.cpp +++ b/test/SystemTest/PQTest.cpp @@ -21,4 +21,19 @@ TEST_CASE("Test PQ", "[short]") std::cout << realC << std::endl; double froError = INTELLI::UtilityFunctions::relativeFrobeniusNorm(realC, ammC); REQUIRE(froError < 0.5); +} +TEST_CASE("Test PQ Hash", "[short]") +{ + torch::manual_seed(114514); + AMMBench::ProductQuantizationHash pqHash; + auto A = torch::rand({1000, 1000}); + auto B = torch::rand({1000, 1000}); + auto realC = torch::matmul(A, B); + auto ammC = pqHash.amm(A, B, 20); + std::cout << "PQ:" << std::endl; + std::cout << ammC << std::endl; + std::cout << "exact:" << std::endl; + std::cout << realC << std::endl; + double froError = INTELLI::UtilityFunctions::relativeFrobeniusNorm(realC, ammC); + REQUIRE(froError < 0.5); } \ No newline at end of file