From 0c0fb4ccbdcb0d809f7005d16676226bafb1232a Mon Sep 17 00:00:00 2001 From: tony <292224750@qq.com> Date: Wed, 24 May 2023 20:25:32 +0800 Subject: [PATCH 1/2] 1. TRY PARALLELIZATION (NOT COMPLETE) --- benchmark/src/Benchmark.cpp | 47 ++++-- .../torchscripts/WeightedCR.pt | Bin benchmark/torchscripts/WeightedCR.py | 113 ++++++++++++++ commit.sh | 2 +- commit_info | 2 +- include/AMMBench.h | 11 ++ .../Parallelization/BlockPartitionRunner.h | 142 ++++++++++++++++++ include/Utils/AbstractC20Thread.hpp | 2 +- include/Utils/UtilityFunctions.h | 2 +- src/CMakeLists.txt | 1 + src/Parallelization/BlockPartitionRunner.cpp | 106 +++++++++++++ src/Parallelization/CMakeLists.txt | 3 + src/Utils/UtilityFunctions.cpp | 10 +- test/CMakeLists.txt | 2 +- test/SystemTest/BlockPartitionTest.cpp | 73 +++++++++ test/torchscripts/WeightedCR.pt | Bin 0 -> 10592 bytes 16 files changed, 497 insertions(+), 19 deletions(-) rename test/torchscripts/weightedCR.pt => benchmark/torchscripts/WeightedCR.pt (100%) create mode 100644 benchmark/torchscripts/WeightedCR.py create mode 100644 include/Parallelization/BlockPartitionRunner.h create mode 100644 src/Parallelization/BlockPartitionRunner.cpp create mode 100644 src/Parallelization/CMakeLists.txt create mode 100644 test/SystemTest/BlockPartitionTest.cpp create mode 100644 test/torchscripts/WeightedCR.pt diff --git a/benchmark/src/Benchmark.cpp b/benchmark/src/Benchmark.cpp index 82093ee9..dc81374a 100644 --- a/benchmark/src/Benchmark.cpp +++ b/benchmark/src/Benchmark.cpp @@ -38,9 +38,8 @@ void runSingleThreadTest(std::string configName) { } } - UtilityFunctions::bind2Core((int) coreBind); - torch::set_num_threads(1); + //torch::set_num_threads(1); std::string ptFile = cfg->tryString("ptFile", "torchscripts/FDAMM.pt", true); //uint64_t customResultName = cfg->tryU64("customResultName", 0, true); @@ -62,17 +61,39 @@ void runSingleThreadTest(std::string configName) { auto A = torch::rand({(long) aRow, (long) aCol}); auto B = torch::rand({(long) aCol, (long) bCol});*/ INTELLI_INFO("Generation done, conducting..."); - if (eMeter != nullptr) { - eMeter->startMeter(); - } - ThreadPerf pef((int) coreBind); + uint64_t threads=cfg->tryU64("threads", 0, true); + ThreadPerf pef(-1); pef.setPerfList(); - pef.start(); - auto C =module.forward({A, B, (long) sketchDimension}).toTensor(); - pef.end(); - if (eMeter != nullptr) { - eMeter->stopMeter(); + AMMBench::BlockPartitionRunner br; + if(threads>1) + { + INTELLI_WARNING("use multithread"); + br.setConfig(cfg); + br.createABC(A,B); + if (eMeter != nullptr) { + eMeter->startMeter(); + } + pef.start(); + auto c= br.parallelForward(); + pef.end(); + if (eMeter != nullptr) { + eMeter->stopMeter(); + } } + else{ + INTELLI_WARNING("single thread"); + if (eMeter != nullptr) { + eMeter->startMeter(); + } + pef.start(); + auto C =module.forward({A, B, (long) sketchDimension}).toTensor(); + pef.end(); + if (eMeter != nullptr) { + eMeter->stopMeter(); + } + + } + std::string ruName = "default"; auto resultCsv = pef.resultToConfigMap(); @@ -84,6 +105,10 @@ auto B = torch::rand({(long) aCol, (long) bCol});*/ resultCsv->edit("energyAll", (double) energyConsumption); resultCsv->edit("energyOnlyMe", (double) pureEnergy); } + if(threads>1) + { INTELLI_WARNING("consider multithread elapsed time"); + resultCsv->edit("perfElapsedTime", (uint64_t)br.getElapsedTime()); + } resultCsv->toFile(ruName + ".csv"); INTELLI_INFO("Done. here is result"); std::cout << resultCsv->toString() << endl; diff --git a/test/torchscripts/weightedCR.pt b/benchmark/torchscripts/WeightedCR.pt similarity index 100% rename from test/torchscripts/weightedCR.pt rename to benchmark/torchscripts/WeightedCR.pt diff --git a/benchmark/torchscripts/WeightedCR.py b/benchmark/torchscripts/WeightedCR.py new file mode 100644 index 00000000..e0a869b6 --- /dev/null +++ b/benchmark/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/commit.sh b/commit.sh index 59577c88..38f37374 100755 --- a/commit.sh +++ b/commit.sh @@ -1,4 +1,4 @@ -BRANCH=REFINE_SCAN +BRANCH=NIGHTY_TEST git init git checkout -b $BRANCH git add . diff --git a/commit_info b/commit_info index 96ec0c65..a67a9773 100644 --- a/commit_info +++ b/commit_info @@ -1 +1 @@ -1. changed the scan scripts in benchmark/scripts/scanARow +1. TRY PARALLELIZATION (NOT COMPLETE) diff --git a/include/AMMBench.h b/include/AMMBench.h index 6ab70a6e..af8778af 100755 --- a/include/AMMBench.h +++ b/include/AMMBench.h @@ -65,6 +65,17 @@ #include #include #include +/** + * @} + */ +/** +* @subsection code_stru_parallelization Parallelization +* This folder contains the parallelizationapproaches +* @defgroup AMMBENCH_PARALLELIZATION The parallelization classes +* @{ +* We define the parallelization classes of AMM. here +**/ +#include /** * @} */ diff --git a/include/Parallelization/BlockPartitionRunner.h b/include/Parallelization/BlockPartitionRunner.h new file mode 100644 index 00000000..029fd4d6 --- /dev/null +++ b/include/Parallelization/BlockPartitionRunner.h @@ -0,0 +1,142 @@ +/*! \file BlockPartitionRunner.h*/ +// +// Created by tony on 24/05/23. +// + +#ifndef INTELLISTREAM_INCLUDE_PARALLELIZATION_BLOCKPARTITIONRUNNER_H_ +#define INTELLISTREAM_INCLUDE_PARALLELIZATION_BLOCKPARTITIONRUNNER_H_ +#include +#include +#include +#include +#include +#include +namespace AMMBench { + +#define newTensor make_shared +typedef std::shared_ptr TensorPtr; +/** + * @ingroup AMMBENCH_PARALLELIZATION + * @{ + * @defgroup PARTITION_RUNNER The partition-based parallelization + */ + /** + * @class BlockPartitionWorker Parallelization/BlockPartitionRunner.h + * @ingroup PARTITION_RUNNER + * @brief The basic partition worker + */ + class BlockPartitionWorker:public INTELLI::AbstractC20Thread{ + protected: + virtual void inlineMain(); + struct timeval tstart, tend; + /** + * @brief Input matrix A + */ + TensorPtr matA= nullptr; // Input matrix A + /** + * @brief Input matrix B + */ + TensorPtr matB=nullptr; // Input matrix B + /** + * @brief OUTput matrix C + */ + TensorPtr matC=nullptr; // Output matrix C + + INTELLI::ConfigMapPtr cfg; + torch::jit::script::Module module; + uint64_t sketchDimension=0; + int coreBind; + public: + torch::Tensor irC,subA; + uint64_t startRow=0; // Start row index for the assigned range + uint64_t endRow=0; // End row index (exclusive) for the assigned range + + BlockPartitionWorker(){ + + } + /** + * @brief set the config map + * @param _cfg + */ + void setConfig(INTELLI::ConfigMapPtr _cfg); + /** + * @brief set the pointer to A,B matrix + */ + void setAB(TensorPtr A,TensorPtr B); + void setWorkParameters(uint64_t aStart,uint64_t aEnd,int mycore); + ~BlockPartitionWorker() + { + + } + uint64_t getElapsedTime(); + +}; +/** +* @ingroup PARTITION_RUNNER +* @def newBlockPartitionWorker +* @brief (Macro) To creat a new @ref BlockPartitionWorker under shared pointer. +*/ +#define newBlockPartitionWorker std::make_shared +typedef std::shared_ptr BlockPartitionWorkerPtr; +/** + * @class BlockPartitionRunner Parallelization/BlockPartitionRunner.h + * @ingroup PARTITION_RUNNER + * @brief The top entity to control all workers, see also @ref BlockPartitionWorker + * @note parameters + * - threads, U64, the number of worker threads, default 2 + * + */ +class BlockPartitionRunner { + + protected: + INTELLI::ConfigMapPtr cfg; + uint64_t threads=0; + /** + * @brief Input matrix A + */ + TensorPtr matA=nullptr; // Input matrix A + /** + * @brief Input matrix B + */ + TensorPtr matB=nullptr; // Input matrix B + /** + * @brief OUTput matrix C + */ + TensorPtr matC=nullptr; // Output matrix C + std::vector workers; + public:BlockPartitionRunner(){} + ~BlockPartitionRunner(){} + /** + * @brief set the config map + * @param _cfg + */ + void setConfig(INTELLI::ConfigMapPtr _cfg); + /** + * @brief create the A,B,C matrix and pass it to all workers + * @param A The A matrix + * @param B The B matrix + * @warnning call after @ref setConfig + */ + void createABC(torch::Tensor A,torch::Tensor B); + /** + * @brief conducte the multithread AMM and return + * @param A The A matrix + * @param B The B matrix + * @return The AMM(A,B) + * @warnning call after @ref setConfig + */ + /** + * @brief run a parallel forward of A,B, and return C + * @return C=matA*matB + * @warnning call after @ref createABC + */ + torch::Tensor parallelForward(); + torch::Tensor runAMM(torch::Tensor A,torch::Tensor B); + uint64_t getElapsedTime(); +}; + +} // AMMBench +/** + * @} + */ +#endif //INTELLISTREAM_INCLUDE_PARALLELIZATION_BLOCKPARTITIONRUNNER_H_ diff --git a/include/Utils/AbstractC20Thread.hpp b/include/Utils/AbstractC20Thread.hpp index 3d2f2c35..41c10b1a 100644 --- a/include/Utils/AbstractC20Thread.hpp +++ b/include/Utils/AbstractC20Thread.hpp @@ -69,7 +69,7 @@ typedef std::shared_ptr AbstractC20ThreadPtr; * @def newAbstractC20Thread * @brief (Macro) To creat a new @ref newAbstractC20Thread under shared pointer. */ -#define newAbstractC20Thread make_shared +#define newAbstractC20Thread std::make_shared typedef std::shared_ptr> BarrierPtr; } diff --git a/include/Utils/UtilityFunctions.h b/include/Utils/UtilityFunctions.h index cab76c8b..090d5275 100755 --- a/include/Utils/UtilityFunctions.h +++ b/include/Utils/UtilityFunctions.h @@ -37,7 +37,7 @@ class UtilityFunctions { //static void timerEnd(Result &result); - static size_t timeLast(size_t past, size_t unitTime); + static size_t timeLast(struct timeval past, struct timeval now); static size_t timeLastUs(struct timeval past); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c0ba5ee2..898d56d6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,5 +1,6 @@ add_subdirectory(Utils) add_subdirectory(MatrixLoader) +add_subdirectory(Parallelization) add_sources( myVecAdd.cpp ) \ No newline at end of file diff --git a/src/Parallelization/BlockPartitionRunner.cpp b/src/Parallelization/BlockPartitionRunner.cpp new file mode 100644 index 00000000..92b7ea68 --- /dev/null +++ b/src/Parallelization/BlockPartitionRunner.cpp @@ -0,0 +1,106 @@ +// +// Created by tony on 24/05/23. +// + +#include +#include +void AMMBench::BlockPartitionWorker::setConfig(INTELLI::ConfigMapPtr _cfg) +{ + cfg = _cfg; + sketchDimension = cfg->tryU64("sketchDimension", 50, true); + std::string ptFile = cfg->tryString("ptFile", "torchscripts/FDAMM.pt", true); + module = torch::jit::load(ptFile); +} +void AMMBench::BlockPartitionWorker::setWorkParameters(uint64_t aStart,uint64_t aEnd,int mycore){ + startRow=aStart; + endRow=aEnd; + coreBind=mycore; + //matC=newTensor(torch::zeros({(long)(endRow+1-startRow),matB->size(1)})); + subA = matA->slice(0, startRow, endRow); +} +void AMMBench::BlockPartitionWorker::setAB(AMMBench::TensorPtr A, AMMBench::TensorPtr B) { + matA=newTensor(*A); + matB=newTensor(*B);; + //assert(C); +} +void AMMBench::BlockPartitionWorker::inlineMain() { + //std::cout<<"thread at "+ to_string(coreBind)+" start\r\n"; + /** + * @brief 1. bind core and torch setting + */ + // Perform matrix multiplication for the assigned rows + INTELLI::UtilityFunctions::bind2Core((int) coreBind); + //torch::set_num_threads(1); + /** + * @brief 2. multiply sub-matrix of A + */ + gettimeofday(&tstart, NULL); + //torch::Tensor + //torch::Tensor subC = module.forward({subA, *matB, (long) sketchDimension}).toTensor(); + // Copy the results back to the output matrix C + //matC->slice(0, startRow, endRow) = subC; + irC=module.forward({subA, *matB, (long) sketchDimension}).toTensor(); + gettimeofday(&tend, NULL); + //std::cout<tryU64("threads", 2, true); + workers=std::vector(threads); + for(uint64_t i=0;isetConfig(cfg); + } + INTELLI_INFO("set up "+ to_string(threads)+"workers."); +} +void AMMBench::BlockPartitionRunner::createABC(torch::Tensor A, torch::Tensor B) { + + matA=newTensor(A); + matB=newTensor(B); + matC=newTensor(torch::zeros({A.size(0), B.size(1)})); + for(uint64_t i=0;isetAB(matA,matB); + workers[i]->setWorkParameters(start_row,end_row,i); + } +} +torch::Tensor AMMBench::BlockPartitionRunner::parallelForward() { + for(uint64_t i=0;istartThread(); + } + INTELLI_INFO("start "+ to_string(threads)+"workers."); + for(uint64_t i=0;ijoinThread(); + } + for(uint64_t i=0;islice(0, workers[i]->startRow, workers[i]->endRow) = workers[i]->irC; + } + return *matC; +} +torch::Tensor AMMBench::BlockPartitionRunner::runAMM(torch::Tensor A,torch::Tensor B) +{ + createABC(A,B); + return parallelForward(); +} +uint64_t AMMBench::BlockPartitionRunner::getElapsedTime() { + uint64_t maxTime=0; + uint64_t ti=0; + for(uint64_t i=0;igetElapsedTime(); + if(ti>maxTime) + { + maxTime=ti; + } + } + return maxTime; +} \ No newline at end of file diff --git a/src/Parallelization/CMakeLists.txt b/src/Parallelization/CMakeLists.txt new file mode 100644 index 00000000..eafe2cb6 --- /dev/null +++ b/src/Parallelization/CMakeLists.txt @@ -0,0 +1,3 @@ +add_sources( + BlockPartitionRunner.cpp +) \ No newline at end of file diff --git a/src/Utils/UtilityFunctions.cpp b/src/Utils/UtilityFunctions.cpp index b56dd580..7f9bbc2b 100755 --- a/src/Utils/UtilityFunctions.cpp +++ b/src/Utils/UtilityFunctions.cpp @@ -66,9 +66,13 @@ vector INTELLI::UtilityFunctions::weightedPartitionSizeFinal(size_t inS, return partitionSizeFinals; } -size_t INTELLI::UtilityFunctions::timeLast(size_t past, size_t unitTime) { - size_t te = clock(); - return (te - past) * unitTime / CLOCKS_PER_SEC; +size_t INTELLI::UtilityFunctions::timeLast(struct timeval ts,struct timeval te) { + int64_t s0, e0, s1, e1; + s0 = ts.tv_sec; + s1 = ts.tv_usec; + e0 = te.tv_sec; + e1 = te.tv_usec; + return 1000000 * (e0 - s0) + (e1 - s1); } size_t INTELLI::UtilityFunctions::timeLastUs(struct timeval ts) { diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 0d709fd6..d5433de2 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -22,5 +22,5 @@ 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) - +add_catch_test(block_partition_test SystemTest/BlockPartitionTest.cpp IntelliStream) diff --git a/test/SystemTest/BlockPartitionTest.cpp b/test/SystemTest/BlockPartitionTest.cpp new file mode 100644 index 00000000..60e35c43 --- /dev/null +++ b/test/SystemTest/BlockPartitionTest.cpp @@ -0,0 +1,73 @@ +// +// Created by tony on 24/05/23. +// +#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 parallelization, thread=2", "[short]") +{ + int a = 0; + ConfigMapPtr cfg = newConfigMap(); + cfg->edit("ptFile","torchscripts/RAWMM.pt"); + cfg->edit("threads",(uint64_t)2); + torch::manual_seed(114514); + auto A = torch::rand({(long) 4, (long) 4}); + auto B = torch::rand({(long) 4, (long) 4}); + AMMBench::BlockPartitionRunner br; + br.setConfig(cfg); + auto C1=br.runAMM(A,B); + auto C2=torch::matmul(A,B); + std::cout<<"parallel MM"<FYs%p5Z_Gseu!6f?!l`7^Woc4uby-?#6) zx<{wGucS|<(^XQd>Qj^fhX4VAfdTm!!2m%5aW}KFuyipqH4s&1GBt8BVsx~zl@Ngg z(f)_{gP9l@xHveOSQ;3>DcTyDm{~g5nwmMuIheZIn!y1q1Hl*-WuRfWL5#kC_*M5?QT(L|#xG6&RTTmd-alz#;$UjV^p8;)9X%vOxc;Eh zKXm(VZjw|-?AMr4IuGf>GpYSK_8FWI3WP9k=MkmsLxrbjsY!(5;lzvNy1Gnev{mrV z2d^DBz3Lr9OVQNCeQD$S>XmSo9Vl<$EFZ;A*+jURLI9B5HGsqYNZY2nCzM2zfVfi*4+uRRyzz{@w5o`CM$#Ms zqL`&SmROcB`L=g?r)m|dXiV!q25tuqh3KWKG8#}7nDdZbfRMxY(xlb1FAwsfQspEgm{|U!pw7?jR1p#*tl*$+4Jm-vHbjgz85UohX*mTVdf7OXdcq zQLgv!AJ`E%@k&8CIaLaHI*I}&`+Us@nemqr;A95DWw|VU4swyVR6$@w7@`;9BO> zWb;mzjte+LFiuLq)Du~+E&1^e>>9fxQ;{gZzn(iVKfm2+cRdoW7nC;Vp8hOpE)zy3 zqO31f3MdkdIAU&ib?TlcXM);uO4+5WSSS< zP8mZ1XT0E`-0(I4{rt(g-OVli=0}gb5{4*8^~Be)^T7|R8z$h()$!A-+&lihgHo%n z)cxu9eRwS!taUi|Rjp%I&E~Eu@^Tas)|yg&M$CJVr^U-_$29f^t1iz~-_R6}Wc!{( zxk5u6y$Cl~^{zHz^p+5Q^tub)BN9mkvpAvW?)VUWb--zjoqYf02GB5cdbRcOU?3nn zQ2)s-s6cT4vs*Blni;!V82s+DnE#7|ge2?P>PP{;*%?sDIn1)ZNv1bgu{~KjXMJ#+ zb;(%VFx?|RH%~*dBw!+-)^fH}IB&Nxc=7$jr3ES?V*KelVy`mhfHei22p{n_s6Hl% z0C^nBnW$EtI3F=#Bm|naRU_Rw&dX35(2PRb_UGkg=FjoWG@i*6G8c9XxQ%z!(1QBb z_9?Swr?r)F=Nxa&6uIiH*6+axaNPUB$5NkkZfxxHGCz%6qwDuJo^)M^9m#=+yAgGc zRw%Dn46aKINfs;8v5(nS9}LZS9tMfPX*Cha9LGp#^n&(I&Ckzw!LAMy*DIH`CL2_J zt-D<6RAselYhR>`NY{~0_h9lcGXk>II+}RwgkFeQVavJ{hn)mytulCQZ^{%0K~IDY z#}%W>PNGscb?WT5UEI##(A4=y9Z1J*lpLgewtk4WP(KBXF&9%q%5iB*Lkt%#(=$4w$gjmHmC4{G+M|D?m{2OkY8rSH7-4AQejCy z;Btt~54h6BU$KNNMAu)bVB5ec;0K+_+H)a&55JZ!iYZ2J+!hxk#b2-d$js_05z%3<6rIw%ZgWsn3+-_;T zEMDGpM+<*J!~C+nab-DkU=i?@xA=%HY=XCSHi@D`VgV#&?z~SS-);k^CZxmjzn z?z4J;$GMd{9$>4^Ms2JDd!u8Aa3Fr{1W?~oHh!;BXCKt7Nyd(z%4Iud)iAMFqE5}O zYd!|vD1zXM+oz7-qMNr^LuR&RY{up$dlQ!llle}1PVwGL;|FR?UD0Jt z6W$n3k~GVrw^sP(O8I9y$b}7`aI>|9|)M&qAk5^F61&4RLmgw`OVO6Wm`LwDHsyja< zxPu=?%YN-Tl%2Z~E)UyPLqsoBoW`GdEjv1>*u_hCu_Jk_7SR#rVh5h&g0Ft9aKAQ(^Bp+GHMu%+e)5g=)8w0g&__?$hWr|Gn@ zZM|lrq)jBRrFla)iL8ec3@fmA8x(p^c}7QgP-Ud-S^)#kXUpn^qTfb(B2YpNQ9eE~ z&S@8XGh5?J7cIKbwaQ2x+})v+$)ZdN8BzPt?uWa)L#QxAvS8vQo~mn;!F=eL_+36R zsc7Wx-l;?4-7y94w&D!U+o2{QKDJRk+4==gse$y+E=84d>#Wrq_*uh$6S--kOz@nS z4hji?^d2_4P}w&IC_2PbFN9$j!AenaSC1wLdcwi)Be~$4^G5If$pr7;&mG8tKgi#L zMbztabxgeo6eRRl_;y7s5EFI<>y4HJ=7Wp8hx$nn+%NwVg8tO5^VNr#sXh2lU}WJr z10*cV7}?>MS%DP(6;_AI~W{D`xc~*OVq}_Rreg7i4|OG0d5U z0d>R06;d?@SE6uGG|vw_x7t7L3FT>}ulMLpmGA|%4NhERT~l6Z&L558S3K4c>8k3L z<`L*0S+l;XR(r-HA+p?WC;qr|0r$io{fe@WP35O@+-`lb1^&bqXR*Ur3hq-dyP2(i z2;cZ}_n|}hh)15%llbK(+TCI0;X4tET(eb)%oDlXt zK%(d?zJep`{2CkpO&A_hcLi)i6bo=E>*MPW`?YMjC z=qC+YuXYXX??jL<@?ZEMILAi3&~CEivLCU3+r9BaOez(iK|mT&{?qQw2m<&IyEoJC zpVUm|uJ$G_Ru1+?w!eSnqW z;3+CrgpmN3j`?(%MnV(e`N?i;H^|5;^ycv(V~2Z>iWJ^88%|5zTtNU>3J>5%dHmw_ zHTr|Bd|7G>R~q-_$W|e0i0nf`Q$K9}`9qe1ifGzlCQ; z!V&)bX=F#=BS8^@A>kkW^Ajf|9orXrXtWeYI0}DQW0jJ@hFn{KQSa_S!%~pQCw@9;JtT45OkiP9OH9tw5BRBNmId?G`Sp`0=H<~G{Rbbd ziq7V$eAn~749)fjGvnH$M~GBX<;jW;sdT@rWGOLv9-lr99Gj&|Kf_qJ{uD`n0}$ z%08>r@0x9(Kdm{i#S61jq%#kRRPvs}{9@OO*vvpC_8ZY!QI)5D_8z?Fs^(F;-Wy$^ z*q7a<+FXr2PiPi@mNeKl%y*~7n0Jm2k}SNARscdlxYev?gdSRHIi+dE!p>UopK>?s zi>z3}H4c3rt<9x*)@n*5uSq?tY9MyTKjXm9UN^27v1eDl;y^3uu2RIs{`y0YWO)zT zg&8JvXu?#Bw58k-(-zvBa2mZTK+1n&0>UTk>j)t79(X!^EAe$x-3t1yEMV0jogf!l z+$}5_b4~54iKv0$laonr*32D4JbR=3kcoDfp2WFq;n?SCQqS9i`&Q)T^Y&xSDXbqG z%Pq}ISB367?d@c_Q05;9SM4DV@2GY5%zSMr{W73|jAOey&RedE+C!(Hv*we%olYweu0tLNQxoV0IwoeVtK z$?X8aZM7O;v8#Kap0nDKn9jSzOGTM!SF^VNQEw!~$uN zIL-iT9;s!oT*pE+YKrh`uHt~h)N$d7oH$Juzct3je>G#)Wd3!qM*S#S4XzV0bD^te z;qKE1_zD#Ts1vEm>;^w>-Pc=2rwy!oFJKh&RbcB%zrt@zktC356!+Kp-UazTEk)cQ zLjR9T(H~D1eE+&A{Wk~izqhIU02_zD;Mx|O3?W(5j%HC0X62TawLtg*TeJ5>%-ct* zLS4DPZv1}o_KZFKI9tG6qu&mRD=Zk<);6fs7Rebq2oxMBD>>-4B1H>K$|@^RE^VPL zRYgn5Qq@f=Kx-epeB0W%@tZo6PR6maIJkTH`R4xfVJqha)6(W}BBS|m8-{>zf?$oy zQ}p8MXt)d9%Q?TF_x{rDppac?%K5RBQX$p)&y=`!W-nqsM%+dc(t?bfBvLT~UOw`L4M6`dep2lhZ>HaEJ)SOMcH)^JRQ zo?Mx1XEW*uuqbtl5K@_XA+~Nss+Y^P)|LQW)GLaHGl}^Wn$ECT;q4aqS)G%ilW&kb zQ?frW+uin(KI<2h zZD`JvPgvvQn3}+EB8z9A{uE##uk}I27j-d&ikOx$V)YKgB7~EE8j|1B%(-kos144% z*0RMACbdAP(sEE9@7@ceJnyvL7SONS2!#Re@CAc2-mbj3UO*Wqz>$;WZXQQ+j=_akuB?H;1kt}Mc zf0Q+;2_2InhMpKhC`*{r_Op~}MPVBz5W`2-OSDr9^L~k$I0oy_sXp!tFN4ED+D*t~ zag4NT4C{0V_HITMsL&=9IHP^e(TCCylDBIHQE&2y882y%`ifL%z7PS+X$SW81k8@O z7xr0khB4(F=S$>ARYE>MfkP@LU#(m_Ba3r*=hvyDq~O7n-3FTsG*y4Adm3|XZ&;El zZi3aJ0d`7M?+f6$R6nbYK6icbN8lo7tb|W5mABBS%buF!Z5w4T(mZWqu4GTy>{z*) z^7c?Ey57b{4`)a5Gi&Fg9FTDysY$V-#ekg#;8bSgmD+vMgRO&R3!Q;Az*+=w{QS9~ zgHS1nzm5g8cxI?1Zqz&b7qPIMB}LJ8R7j4vI{Q)C*Ww6uL+L$qfUk zG_-jLWOr4voMZs!0p?N~}6HQFn9R)asx(q8k`x#C{iggR)+9i`i z-81M+|MY&7T2*sXI}nUhP3W1e$@Wg3fld)pH5KUP)r@B~*l=fX!IVGUAj_Y1L}>3BWo@DC{COQYpCKPLIkH~qG;Lz0)8!0Z zmUUtB(B_DcMyjWVT}>siNiR8p>zCTOT4>cz(TE!=dFE_lA++)-O>Dj4HdleNW~ERM zvozC?P#w0P^OiBN_af&i?d&=;>N@LLv{$7yjiPl%)K=Y$nl`9q(;q05$m4kjrMM`z zR&cVTc?XYY?ju0^xxU+WRe0&EqF;mMMKlKPqz%jD;|l3mkbCAu?#P0Gn~+3~jEc|? zd|JJo-eC6k%s3h`gC8J=a9eQ9Bd!SMz;Lu~sqn;_k3|dW$Y^lJ{RUst5@7LJfM)5! z{4gOwFN3yL3|Ac_K4+@y)X~Vh8A?sJ`^%m9Tk;G2;qihs z4tk8kw@E&5v&>xtN%3`hEyw#Hho9ep$+r+xBb$bji}bk(ZiE&=dT9~P;CCK_KYHla=}$g zlE$9|77ZlbY-P`7%HMLsf81&!dx!iC+S{|1X{4R3aeF#L*!L(0RjU&{wZ=56U}9V5 zg0Z=?c!qB35y@c7*ycdmbI%6d5WsGh!Nr;(0Fk-1gB)Ue3wqOu+qAd)btEnm^+EjV zMa~r!Za-46z<@*Eq_L_Jr%7@gx~6?Xci-^N{t7P5WvMYasUG0`MN*)6B33sS?H z+{VD5sN0WCWixt}!&#AF?TdQ-m0t%PgW%=oY&xWwHb}TqN0u%O`8~%La@J-89ZY%u z0@4t7iuOJ zlGOKnHIi&l-f=6dt`fQ0ZSlV$4sHr3hypEjG<^|();N#ZU}ti*HWgv?M<#Z|?s)28 zbd!?0GU>J%J(Y;fBu!*%uN8#--lu>ZRS%633k4yTu*R{0P$<=E!ut@H;eHyF$s0Y@ zEz7w890~Ou)6%+7qA2dK8>!eN)F0ek6pFCzqfD{&pb+m!g_7J;EA1+? zr{4X9=N#Q!T{`!pKD8Nqtp!uaCG2E;e%l8&xV=bc=ZfAt5}7jywd=RCl=Jhfz=?X! zv;YZlhsH@=&UbeHYV%K>;NUvVcljQl4`BJ=Hqjo+7Q^gh^uGzABRYwL#u7pade!Eq zg+OB+kX0!$oO%RZF7fJaFdCjixK8^jA~aZh+m&iL&OUMLn!}d_4t!)yMJSC5X9o<{<(7YSYfzg%ro>N< zH8ybIA`Dc{@~*m&uO)O5Bd_51;A*E%iptu)S5fZg*(aqcz&Fe#KW~E-hXoFRAzP-e z4o4a9m5yKq|86md`vj>W$n_k>KHEWN)8tQCFF| zt+1nPnwmClQpK4n+bL@*AFMIe-)o>)$!I*aJZF#$!F9`MGqY%pDbcI`F5nEsZgGQb z!21e|hM`qi%gegbL&h-{CJM&|tW6{U=7Kt4GPBfVVBCVla=>}W0MKoh^+VU;da@SU zXBOuYGB`dSM5#Vb5F}CUMy<~poU9f)7vwum6Ub%kuj74Ru}g5b{x0YZXeH*|NN~3* zR4^VHW|D7S-_SlsPre#o>I&Ovy-hxgoYARHa%pe2?MLmz@+3AVTwQw>sy34I>g@k= zpFAN&FC^UrDehGbU8tg%jBAL8QI-+;;>;_ansCfo zG=KU?GHmxi7Ty{#70wu2=rPlOREFce@Ur_ZNp7(Yw#P5<NGQ2@TOE(jKjPl8wgWebOfWx`jXuDT1 zqq@4nKCmbp*?m4}ut0bSZN0~1kZ*p*jGP&XFq7BJDs)v$@3sLqsCreNuVCarjSBAA zfs_~^9_mF(O)fH7#2YKjK@`Jgj*2j(&xUW+FOfGTszy(< zaKyFI;_$(IE{C-THJ%Wj)}R9x(Jzk0U`<4GQIt*Yi@N)$Zq1HwSs&dHO{$}9a(~dl zgz~zOM;L$1aTK+=bp;$2aMIK;Mnvm5 z6QVkGjRd>ybbr7*uyn~;+w1y;)Mu3weushJ5b@J{lxh@}UuK*O_ux~-eAf5O>opW? zU-~xiT0A(pHkM5YPmiE2uevq+!Kci5=7FUGr2$?6LTzrem}NdZ(5ajh zaf;X(QP;@=a(0DtvMd0H5k-Carl|(w87j-YNO!&GO63wqk4_|Cu;?fa@8D-0s0(C) zl$oJq@k;kH@bbFAu9C(^bF5@=v1ot2q-eK18#7j@V29e1*%Z&cd`1rv z0(7&imS~J`;npUZu(3VkMb*7I{p8@b{rgMRkuT?b2y_x+W)|rdh@D`i-ddpTQB>>n z9NH}&Y0XQ0brW}Xu)9p1Lw$y37y45LVm~A8k0x;AGDT({r9qFPK^$7(Q(@7vIREL3 zvF(o{DmQ~%9E7jpSekhtkvF#R>A=@aMon5zz#D@I>wv2C9@#hJ zyqY&<@J%(RM-^5YdCz77Y`Yce~>snrq6d7FNLvMMBcQ`b9`Rh9Ke*&Qkv#!=(B1y zI|Iu%iQ1_@c+8lc5ul8DjS6DxTA3Fc#9|xec6zQXx`5H}_&gRDm$q2^C2t^49Jo3A zti!pGzuNw!$~K_D=^)cRlr|_jkdKj>)-M8At%-5CmJl{nh<0@=|H@`$G!}Ar$*Jcz z+($dLwd>?l2 z${@YD&YV9l${A6cc>PhAC%ZWA1WNhXGD15^R6L{-DkyRg?-6jre;@F3ijCGm*lS#+#9BEJ8%Rr#Z-Xwk1ztYpm}jsT0`H()*GTSw5Va!+6(5}c8A4ZUh`&Wrd*2A>C7k<)W8mB&Ux!4!3h8JKhR`-27hyt# zk3M1i!GiVv<$9fnlzY(RI^F-BBe1!7h8MI0vrqKkc+2dJX}`5w>f5^nRQFX85*XU+cD7;M$}MyP0}4s(w4lecQSuour}D_AE z?ZnJxXYi!xei1DitH)vfYXs9b$*&*>Fz;nq@5m^t z@NnW+OZXk2?9?VV*Sg@n6nsjT@Roqy?*z9ZAPxwYHL9}%Cam`bd=Ef~Iec=l?W@v7MtX3Da5IM)WWH#VVAZR>+ zQ|{ACMpwQ5MP|wwrnWhJ?jXHHuG8I+XC%u_re}L&5b!?8z$_ap!EO7%330+U^VWgg zZ6_mhRN$Nqjy-uUVc=ckt#GObcP=tR%A=3ikO1uzf5bMt&GDK)LC6_{i62FkXGGwW z6M-IL3)waxlD(ly@-m?)%27IO@yh|U zSkQjEa_Y-It-youHOdn^tl>fb)dP$N#wHON)dYf*seXDD=YXpyEzK_{dOmWrm)rnaB#+MY=tR9d8-NO22Tl!?xY)8>3&y*hM z+iw*EFPI+iU0c$dlv|XSaqc5t`@H);)MEl5+<^j7rq4H!0XHl@9u)je@fzXg3^lP=m703aYMJbw%N{(E{C4hZdEg1+|7E=Kk) z&VS>0QT~@vU4Jl|-Q7L4;Qtq>f5zPZ3i`(=KjWW34dDM1=)X%c{uTR=#>D+6?2}(Ph5vo-{|@`F zGx+B_`lI#W{ArXeiocHX2Q&Sfvj2qnqZy$82}YIj&oF;CJVhBODEhxQBm`&pN0(pO v+u!B?T{eElzx3>QSVBZN$ literal 0 HcmV?d00001 From 9c26df9129ffd0148c55f65f1603dac742a5ca55 Mon Sep 17 00:00:00 2001 From: tony <292224750@qq.com> Date: Thu, 25 May 2023 11:24:56 +0800 Subject: [PATCH 2/2] 1. experimental support of parallelization 2. example scripts at benchmark/scripts/scanThreads --- .github/workflows/cmake.yml | 3 +- Doxyfile | 2 +- README.md | 5 +- benchmark/scripts/scanARow/config_WCR.csv | 6 + benchmark/scripts/scanARow/drawTogether.py | 76 ++-- benchmark/scripts/scanThreads/OoOCommon.py | 125 ++++++ benchmark/scripts/scanThreads/accuBar.py | 328 ++++++++++++++++ benchmark/scripts/scanThreads/autoParase.py | 87 +++++ .../scripts/scanThreads/config_BCoAMM.csv | 8 + benchmark/scripts/scanThreads/config_CRS.csv | 6 + .../scripts/scanThreads/config_CoAMM.csv | 8 + .../scripts/scanThreads/config_FDAMM.csv | 8 + .../scripts/scanThreads/config_RAWMM.csv | 8 + benchmark/scripts/scanThreads/drawTogether.py | 177 +++++++++ benchmark/scripts/scanThreads/groupBar.py | 236 +++++++++++ benchmark/scripts/scanThreads/groupBar2.py | 232 +++++++++++ benchmark/scripts/scanThreads/groupLine.py | 366 ++++++++++++++++++ benchmark/scripts/scanThreads/perfRu.csv | 7 + benchmark/src/Benchmark.cpp | 18 +- benchmark/torchscripts/BernoulliCRS.py | 108 +++--- benchmark/torchscripts/ColumnRowSampling.py | 111 +++--- .../torchscripts/ColumnRowSamplingVer2.py | 116 +++--- benchmark/torchscripts/E2E_Minist.py | 104 ++--- benchmark/torchscripts/ElementWiseSampling.py | 100 +++-- benchmark/torchscripts/WeightedCR.py | 40 +- commit_info | 3 +- .../Parallelization/BlockPartitionRunner.h | 129 +++--- src/Parallelization/BlockPartitionRunner.cpp | 97 +++-- src/Parallelization/CMakeLists.txt | 2 +- src/Utils/UtilityFunctions.cpp | 2 +- test/SystemTest/BlockPartitionTest.cpp | 16 +- test/torchscripts/BernoulliCRS.py | 108 +++--- test/torchscripts/ColumnRowSampling.py | 111 +++--- test/torchscripts/ColumnRowSamplingVer2.py | 116 +++--- test/torchscripts/E2E_Minist.py | 104 ++--- test/torchscripts/ElementWiseSampling.py | 100 +++-- test/torchscripts/WeightedCR.py | 40 +- 37 files changed, 2381 insertions(+), 732 deletions(-) create mode 100644 benchmark/scripts/scanARow/config_WCR.csv create mode 100755 benchmark/scripts/scanThreads/OoOCommon.py create mode 100755 benchmark/scripts/scanThreads/accuBar.py create mode 100755 benchmark/scripts/scanThreads/autoParase.py create mode 100644 benchmark/scripts/scanThreads/config_BCoAMM.csv create mode 100644 benchmark/scripts/scanThreads/config_CRS.csv create mode 100644 benchmark/scripts/scanThreads/config_CoAMM.csv create mode 100644 benchmark/scripts/scanThreads/config_FDAMM.csv create mode 100644 benchmark/scripts/scanThreads/config_RAWMM.csv create mode 100755 benchmark/scripts/scanThreads/drawTogether.py create mode 100755 benchmark/scripts/scanThreads/groupBar.py create mode 100755 benchmark/scripts/scanThreads/groupBar2.py create mode 100755 benchmark/scripts/scanThreads/groupLine.py create mode 100644 benchmark/scripts/scanThreads/perfRu.csv diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index 78245655..90742372 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -47,4 +47,5 @@ jobs: ./cpp_test "--success" ./sketch_test "--success" ./crs_test "--success" - ./weighted_cr_test "--success" \ No newline at end of file + ./weighted_cr_test "--success" + ./block_partition_test "--success" \ No newline at end of file diff --git a/Doxyfile b/Doxyfile index 28a2a745..f369e258 100755 --- a/Doxyfile +++ b/Doxyfile @@ -38,7 +38,7 @@ PROJECT_NAME = "AMMBench" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 0.1.2 +PROJECT_NUMBER = 0.1.3 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/README.md b/README.md index 18cc23fa..672e35ff 100644 --- a/README.md +++ b/README.md @@ -123,12 +123,14 @@ mkdir build && cd build ``` Build for release by default: + ```shell cmake -DCMAKE_PREFIX_PATH=`python3 -c 'import torch;print(torch.utils.cmake_prefix_path)'` .. make ``` Or you can build with debug mode to debug cpp dynamic lib: + ```shell cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_PREFIX_PATH=`python3 -c 'import torch;print(torch.utils.cmake_prefix_path)'` .. make @@ -213,4 +215,5 @@ You will find the figures then. 2. Some pytorch version can not work well with liblog4cxx and googletest, so we diabled it. 3. Clion may fail to render and highlight the torch apis. In this case, kindly type a random line of "555" to validate the highlight when you need it, and comment it during a compile. :) -4. When setting up torch for cpu under python version > 3.10, torch == 1.13.0 would conflict with torchaudio according to https://pytorch.org/audio/stable/installation.html. Use Python version <= 3.10 for smooth installation. \ No newline at end of file +4. When setting up torch for cpu under python version > 3.10, torch == 1.13.0 would conflict with torchaudio according + to https://pytorch.org/audio/stable/installation.html. Use Python version <= 3.10 for smooth installation. \ No newline at end of file diff --git a/benchmark/scripts/scanARow/config_WCR.csv b/benchmark/scripts/scanARow/config_WCR.csv new file mode 100644 index 00000000..d9b055fb --- /dev/null +++ b/benchmark/scripts/scanARow/config_WCR.csv @@ -0,0 +1,6 @@ +key,value,type +aRow,100,U64 +aCol,1000,U64 +bCol,500,U64 +sketchDimension,25,U64 +ptFile,torchscripts/WeightedCR.pt,String \ No newline at end of file diff --git a/benchmark/scripts/scanARow/drawTogether.py b/benchmark/scripts/scanARow/drawTogether.py index 602ab5d2..8078984b 100755 --- a/benchmark/scripts/scanARow/drawTogether.py +++ b/benchmark/scripts/scanARow/drawTogether.py @@ -98,65 +98,75 @@ def readResultVector(singleValueVec, resultPath): cacheRefVec.append(float(cacheRefs)) return np.array(elapseTimeVec), np.array(cacheMissVec), np.array(cacheRefVec) -def compareMethod(exeSpace,commonPathBase,resultPaths,csvTemplates,periodVec,reRun=1): - elapsedTimeAll=[] - cacheMissAll=[] - cacheRefAll=[] - periodAll=[] + +def compareMethod(exeSpace, commonPathBase, resultPaths, csvTemplates, periodVec, reRun=1): + elapsedTimeAll = [] + cacheMissAll = [] + cacheRefAll = [] + periodAll = [] for i in range(len(csvTemplates)): - resultPath=commonPathBase+resultPaths[i] - if(reRun==1): + resultPath = commonPathBase + resultPaths[i] + if (reRun == 1): os.system("sudo rm -rf " + resultPath) os.system("sudo mkdir " + resultPath) - runScanVector(exeSpace, periodVec, resultPath,csvTemplates[i]) - elapsedTime,cacheMiss,cacheRef = readResultVector(periodVec, resultPath) + runScanVector(exeSpace, periodVec, resultPath, csvTemplates[i]) + elapsedTime, cacheMiss, cacheRef = readResultVector(periodVec, resultPath) elapsedTimeAll.append(elapsedTime) cacheMissAll.append(cacheMiss) cacheRefAll.append(cacheRef) periodAll.append(periodVec) - cacheMissRateAll=np.array(cacheMissAll)/np.array(cacheRefAll)*100.0 - #periodAll.append(periodVec) - return np.array(elapsedTimeAll),cacheMissRateAll,periodAll + cacheMissRateAll = np.array(cacheMissAll) / np.array(cacheRefAll) * 100.0 + # periodAll.append(periodVec) + return np.array(elapsedTimeAll), cacheMissRateAll, periodAll + + def main(): exeSpace = os.path.abspath(os.path.join(os.getcwd(), "../..")) + "/" - commonBase = os.path.abspath(os.path.join(os.getcwd(), "../..")) + "/results/" + scanTag+"/" + commonBase = os.path.abspath(os.path.join(os.getcwd(), "../..")) + "/results/" + scanTag + "/" figPath = os.path.abspath(os.path.join(os.getcwd(), "../..")) + "/figures/" + scanTag - methodTags=["FD-AMM","Co-AMM","BCo-AMM","Couter-sketch","MM"] - resultPaths=["fd","co","co","cs","mm"] - csvTemplates=["config_FDAMM.csv","config_CoAMM.csv","config_BCoAMM.csv","config_CounterSketch.csv","config_RAWMM.csv"] + methodTags = ["FD-AMM", "Co-AMM", "BCo-AMM", "Couter-sketch", "MM"] + resultPaths = ["fd", "co", "co", "cs", "mm"] + csvTemplates = ["config_FDAMM.csv", "config_CoAMM.csv", "config_BCoAMM.csv", "config_CounterSketch.csv", + "config_RAWMM.csv"] valueVec = [100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000] valueVecDisp = np.array(valueVec) # run - reRun=0 + reRun = 0 if (len(sys.argv) < 2): os.system("mkdir ../../results") os.system("mkdir ../../figures") os.system("mkdir " + figPath) os.system("sudo rm -rf " + commonBase) os.system("sudo mkdir " + commonBase) - reRun=1 - #skech - elapsedTimeAll,cacheMissAll,periodAll=compareMethod(exeSpace,commonBase,resultPaths,csvTemplates,valueVec,reRun) - groupLine.DrawFigure(periodAll,elapsedTimeAll, + reRun = 1 + # skech + elapsedTimeAll, cacheMissAll, periodAll = compareMethod(exeSpace, commonBase, resultPaths, csvTemplates, valueVec, + reRun) + groupLine.DrawFigure(periodAll, elapsedTimeAll, methodTags, - "#elements in A's row", "elapsed time (ms)", 0, 1, figPath +"/"+ scanTag + "sketch_elapsedTime", + "#elements in A's row", "elapsed time (ms)", 0, 1, + figPath + "/" + scanTag + "sketch_elapsedTime", True) - groupLine.DrawFigureYnormal(periodAll,cacheMissAll, + groupLine.DrawFigureYnormal(periodAll, cacheMissAll, methodTags, - "#elements in A's row", "cacheMiss (%)", 0, 1, figPath + "/"+scanTag + "sketch_cacheMiss", + "#elements in A's row", "cacheMiss (%)", 0, 1, + figPath + "/" + scanTag + "sketch_cacheMiss", True) - #sampling - resultPaths=["crs","bcrs","ews","mm"] - csvTemplates=["config_CRS.csv","config_BerCRS.csv","config_EWS.csv","config_RAWMM.csv"] - methodTags=["CRS","Ber-CRS","EWS","MM"] - elapsedTimeAll,cacheMissAll,periodAll=compareMethod(exeSpace,commonBase,resultPaths,csvTemplates,valueVec,reRun) - groupLine.DrawFigure(periodAll,elapsedTimeAll, + # sampling + resultPaths = ["crs", "bcrs", "ews", "mm"] + csvTemplates = ["config_CRS.csv", "config_BerCRS.csv", "config_EWS.csv", "config_RAWMM.csv"] + methodTags = ["CRS", "Ber-CRS", "EWS", "MM"] + elapsedTimeAll, cacheMissAll, periodAll = compareMethod(exeSpace, commonBase, resultPaths, csvTemplates, valueVec, + reRun) + groupLine.DrawFigure(periodAll, elapsedTimeAll, methodTags, - "#elements in A's row", "elapsed time (ms)", 0, 1, figPath +"/"+ scanTag + "sampling_elapsedTime", + "#elements in A's row", "elapsed time (ms)", 0, 1, + figPath + "/" + scanTag + "sampling_elapsedTime", True) - groupLine.DrawFigureYnormal(periodAll,cacheMissAll, + groupLine.DrawFigureYnormal(periodAll, cacheMissAll, methodTags, - "#elements in A's row", "cacheMiss (%)", 0, 1, figPath + "/"+scanTag + "sampling_cacheMiss", + "#elements in A's row", "cacheMiss (%)", 0, 1, + figPath + "/" + scanTag + "sampling_cacheMiss", True) # draw2yLine("watermark time (ms)",singleValueVecDisp,lat95Vec,errVec,"95% Latency (ms)","Error","ms","",figPath+"wm_lat") # draw2yLine("watermark time (ms)",singleValueVecDisp,thrVec,errVec,"Throughput (KTp/s)","Error","KTp/s","",figPath+"wm_thr") diff --git a/benchmark/scripts/scanThreads/OoOCommon.py b/benchmark/scripts/scanThreads/OoOCommon.py new file mode 100755 index 00000000..70f4cf33 --- /dev/null +++ b/benchmark/scripts/scanThreads/OoOCommon.py @@ -0,0 +1,125 @@ +import csv +import numpy as np +import matplotlib.pyplot as plt +import itertools as it +import os + +import matplotlib +import matplotlib.pyplot as plt +import numpy as np +import pylab +from matplotlib.font_manager import FontProperties +from matplotlib.ticker import LogLocator, LinearLocator +import os +import pandas as pd +import sys +import matplotlib.ticker as mtick + +OPT_FONT_NAME = 'Helvetica' +TICK_FONT_SIZE = 22 +LABEL_FONT_SIZE = 28 +LEGEND_FONT_SIZE = 30 +LABEL_FP = FontProperties(style='normal', size=LABEL_FONT_SIZE) +LEGEND_FP = FontProperties(style='normal', size=LEGEND_FONT_SIZE) +TICK_FP = FontProperties(style='normal', size=TICK_FONT_SIZE) + +MARKERS = (['*', '|', 'v', "^", "", "h", "<", ">", "+", "d", "<", "|", "", "+", "_"]) +# you may want to change the color map for different figures +COLOR_MAP = ( + '#B03A2E', '#2874A6', '#239B56', '#7D3C98', '#FFFFFF', '#F1C40F', '#F5CBA7', '#82E0AA', '#AEB6BF', '#AA4499') +# you may want to change the patterns for different figures +PATTERNS = (["////", "o", "", "||", "-", "//", "\\", "o", "O", "////", ".", "|||", "o", "---", "+", "\\\\", "*"]) +LABEL_WEIGHT = 'bold' +LINE_COLORS = COLOR_MAP +LINE_WIDTH = 3.0 +MARKER_SIZE = 15.0 +MARKER_FREQUENCY = 1000 + + +def editConfig(src, dest, key, value): + df = pd.read_csv(src, header=None) + rowIdx = 0 + idxt = 0 + for cell in df[0]: + # print(cell) + if (cell == key): + rowIdx = idxt + break + idxt = idxt + 1 + df[1][rowIdx] = str(value) + df.to_csv(dest, index=False, header=False) + + +def readConfig(src, key): + df = pd.read_csv(src, header=None) + rowIdx = 0 + idxt = 0 + for cell in df[0]: + # print(cell) + if (cell == key): + rowIdx = idxt + break + idxt = idxt + 1 + return df[1][rowIdx] + + +def draw2yLine(NAME, Com, R1, R2, l1, l2, m1, m2, fname): + fig, ax1 = plt.subplots(figsize=(10, 6.4)) + lines = [None] * 2 + # ax1.set_ylim(0, 1) + print(Com) + print(R1) + lines[0], = ax1.plot(Com, R1, color=LINE_COLORS[0], \ + linewidth=LINE_WIDTH, marker=MARKERS[0], \ + markersize=MARKER_SIZE + # + ) + + # plt.show() + ax1.set_ylabel(m1, fontproperties=LABEL_FP) + ax1.set_xlabel(NAME, fontproperties=LABEL_FP) + # ax1.set_xticklabels(ax1.get_xticklabels()) # 设置共用的x轴 + plt.xticks(rotation=0, size=TICK_FONT_SIZE) + plt.yticks(rotation=0, size=TICK_FONT_SIZE) + plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号 + ax2 = ax1.twinx() + + # ax2.set_ylabel('latency/us') + # ax2.set_ylim(0, 0.5) + lines[1], = ax2.plot(Com, R2, color=LINE_COLORS[1], \ + linewidth=LINE_WIDTH, marker=MARKERS[1], \ + markersize=MARKER_SIZE) + + ax2.set_ylabel(m2, fontproperties=LABEL_FP) + # ax2.vlines(192000, min(R2)-1, max(R2)+1, colors = "GREEN", linestyles = "dashed",label='total L1 size') + # plt.grid(axis='y', color='gray') + + # style = dict(size=10, color='black') + # ax2.hlines(tset, 0, x2_list[len(x2_list)-1]+width, colors = "r", linestyles = "dashed",label="tset") + # ax2.text(4, tset, "$T_{set}$="+str(tset)+"us", ha='right', **style) + + # plt.xlabel('batch', fontproperties=LABEL_FP) + + # plt.xscale('log') + # figure.xaxis.set_major_locator(LinearLocator(5)) + ax1.yaxis.set_major_locator(LinearLocator(5)) + ax2.yaxis.set_major_locator(LinearLocator(5)) + ax1.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1f')) + ax2.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1f')) + ax1.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1f')) + ax2.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1f')) + plt.legend(lines, + [l1, l2], + prop=LEGEND_FP, + loc='upper center', + ncol=1, + bbox_to_anchor=(0.55, 1.3 + ), shadow=False, + columnspacing=0.1, + frameon=True, borderaxespad=-1.5, handlelength=1.2, + handletextpad=0.1, + labelspacing=0.1) + plt.yticks(rotation=0, size=TICK_FONT_SIZE) + plt.tight_layout() + + plt.savefig(fname + ".pdf") diff --git a/benchmark/scripts/scanThreads/accuBar.py b/benchmark/scripts/scanThreads/accuBar.py new file mode 100755 index 00000000..638c8a60 --- /dev/null +++ b/benchmark/scripts/scanThreads/accuBar.py @@ -0,0 +1,328 @@ +import getopt +import os +import sys + +import matplotlib +import matplotlib.pyplot as plt +import numpy as np +import pylab +from matplotlib.font_manager import FontProperties +from matplotlib.ticker import LinearLocator, LogLocator, MaxNLocator, ScalarFormatter +from numpy import double + +OPT_FONT_NAME = 'Helvetica' +TICK_FONT_SIZE = 24 +LABEL_FONT_SIZE = 28 +LEGEND_FONT_SIZE = 26 +TITLE_FRONT_SIZE = 32 +LABEL_FP = FontProperties(style='normal', size=LABEL_FONT_SIZE) +LEGEND_FP = FontProperties(style='normal', size=LEGEND_FONT_SIZE) +TICK_FP = FontProperties(style='normal', size=TICK_FONT_SIZE) +TITLE_FP = FontProperties(style='normal', size=TITLE_FRONT_SIZE) +MARKERS = (['o', 's', 'v', "^", "h", "v", ">", "x", "d", "<", "|", "", "|", "_"]) +# you may want to change the color map for different figures +COLOR_MAP = ('#B03A2E', '#2874A6', '#239B56', '#7D3C98', '#F1C40F', '#F5CBA7', '#82E0AA', '#AEB6BF', '#AA4499') +# you may want to change the patterns for different figures +PATTERNS = (["\\", "///", "o", "||", "\\\\", "\\\\", "//////", "//////", ".", "\\\\\\", "\\\\\\"]) +LABEL_WEIGHT = 'bold' +LINE_COLORS = COLOR_MAP +LINE_WIDTH = 3.0 +MARKER_SIZE = 0.0 +MARKER_FREQUENCY = 1000 + +matplotlib.rcParams['ps.useafm'] = True +matplotlib.rcParams['pdf.use14corefonts'] = True +matplotlib.rcParams['xtick.labelsize'] = TICK_FONT_SIZE +matplotlib.rcParams['ytick.labelsize'] = TICK_FONT_SIZE +matplotlib.rcParams['font.family'] = OPT_FONT_NAME +matplotlib.rcParams['pdf.fonttype'] = 42 + +exp_dir = "/data1/xtra" + +FIGURE_FOLDER = exp_dir + '/results/figure' + + +# there are some embedding problems if directly exporting the pdf figure using matplotlib. +# so we generate the eps format first and convert it to pdf. +def ConvertEpsToPdf(dir_filename): + os.system("epstopdf --outfile " + dir_filename + ".pdf " + dir_filename + ".eps") + os.system("rm -rf " + dir_filename + ".eps") + + +class ScalarFormatterForceFormat(ScalarFormatter): + def _set_format(self): # Override function that finds format to use. + self.format = "%1.1f" # Give format here + + +# draw a line chart +def DrawFigure(x_values, y_values, legend_labels, x_label, y_label, filename, allow_legend, title): + # you may change the figure size on your own. + + fig = plt.figure(figsize=(16, 9)) + figure = fig.add_subplot(111) + + FIGURE_LABEL = legend_labels + + # if not os.path.exists(FIGURE_FOLDER): + # os.makedirs(FIGURE_FOLDER) + + # values in the x_xis + index = np.arange(len(x_values)) + # the bar width. + # you may need to tune it to get the best figure. + width = 0.5 + # draw the bars + bottom_base = np.zeros(len(y_values[0])) + bars = [None] * (len(FIGURE_LABEL)) + for i in range(len(y_values)): + bars[i] = plt.bar(index + width / 2, y_values[i], width, hatch=PATTERNS[i], color=LINE_COLORS[i], + label=FIGURE_LABEL[i], bottom=bottom_base, edgecolor='black', linewidth=3) + bottom_base = np.array(y_values[i]) + bottom_base + + # sometimes you may not want to draw legends. + if allow_legend == True: + plt.legend(bars, FIGURE_LABEL + # mode='expand', + # shadow=False, + # columnspacing=0.25, + # labelspacing=-2.2, + # borderpad=5, + # bbox_transform=ax.transAxes, + # frameon=False, + # columnspacing=5.5, + # handlelength=2, + ) + if allow_legend == True: + handles, labels = figure.get_legend_handles_labels() + if allow_legend == True: + leg = plt.legend(handles[::-1], labels[::-1], + loc='upper center', + # prop=#LEGEND_FP, + # ncol=3, + # bbox_to_anchor=(0.5, 1.25), + # bbox_to_anchor=(1.17, 0.5), + # handletextpad=0.1, + # borderaxespad=0.0, + # handlelength=1.8, + # labelspacing=0.3, + # columnspacing=0.3, + ) + leg.get_frame().set_linewidth(2) + leg.get_frame().set_edgecolor("black") + + # you may need to tune the xticks position to get the best figure. + plt.xticks(index + 0.6 * width, x_values) + yfmt = ScalarFormatterForceFormat() + yfmt.set_powerlimits((0, 0)) + figure.get_yaxis().set_major_formatter(yfmt) + plt.ticklabel_format(axis="y", style="sci", scilimits=(0, 0), useMathText=True) + plt.grid(axis='y', color='gray') + figure.yaxis.set_major_locator(LinearLocator(3)) + # figure.yaxis.set_major_locator(LogLocator(base=10)) + # figure.yaxis.set_major_locator(LinearLocator(6)) + + figure.get_xaxis().set_tick_params(direction='in', pad=10) + figure.get_yaxis().set_tick_params(direction='in', pad=10) + + plt.xlabel(x_label, fontproperties=LABEL_FP) + plt.ylabel(y_label, fontproperties=LABEL_FP) + + size = fig.get_size_inches() + dpi = fig.get_dpi() + plt.title(title, fontproperties=TITLE_FP) + plt.savefig(filename + ".pdf", bbox_inches='tight', format='pdf') + + +def DrawLegend(legend_labels, filename): + fig = pylab.figure() + ax1 = fig.add_subplot(111) + FIGURE_LABEL = legend_labels + LEGEND_FP = FontProperties(style='normal', size=26) + + bars = [None] * (len(FIGURE_LABEL)) + data = [1] + x_values = [1] + + width = 0.3 + for i in range(len(FIGURE_LABEL)): + bars[i] = ax1.bar(x_values, data, width, hatch=PATTERNS[i], color=LINE_COLORS[i], + linewidth=0.2) + + # LEGEND + figlegend = pylab.figure(figsize=(11, 0.5)) + figlegend.legend(bars, FIGURE_LABEL, prop=LEGEND_FP, \ + loc=9, + bbox_to_anchor=(0, 0.4, 1, 1), + ncol=len(FIGURE_LABEL), mode="expand", shadow=False, \ + frameon=False, handlelength=1.1, handletextpad=0.2, columnspacing=0.1) + + figlegend.savefig(FIGURE_FOLDER + '/' + filename + '.pdf') + + +def normalize(y_values): + y_total_values = np.zeros(len(y_values[0])) + + for i in range(len(y_values)): + y_total_values += np.array(y_values[i]) + y_norm_values = [] + + for i in range(len(y_values)): + y_norm_values.append(np.array(y_values[i]) / (y_total_values) * 100) + return y_norm_values + + +# example for reading csv file +def ReadFile(id): + # Creates a list containing w lists, each of h items, all set to 0 + w, h = 5, 3 + y = [[0 for x in range(w)] for y in range(h)] + # print(matches) + max_value = 0 + j = 0 + bound = id + 1 * w + for i in range(id, bound, 1): + cnt = 0 + print(i) + f = open(exp_dir + "/results/breakdown/PMJ_JBCR_NP_{}.txt".format(i), "r") + read = f.readlines() + others = 0 + for x in read: + value = double(x.strip("\n")) + if value > max_value: + max_value = value + elif cnt == 3: # sort + y[0][j] = value + elif cnt == 4: # merge + y[1][j] = value + elif cnt == 5: # join + y[2][j] = value + else: + others += value + # if cnt == 6: + # y[2][j] = others + cnt += 1 + j += 1 + print(y) + return y, max_value + + +if __name__ == "__main__": + id = 119 + try: + opts, args = getopt.getopt(sys.argv[1:], '-i:h', ['test id', 'help']) + except getopt.GetoptError: + print('breakdown.py -id testid') + sys.exit(2) + for opt, opt_value in opts: + if opt in ('-h', '--help'): + print("[*] Help info") + exit() + elif opt == '-i': + print('Test ID:', opt_value) + id = (int)(opt_value) + + x_values = ['10%', '20%', '30%', '40%', '50%'] # sorting step size + + y_values, max_value = ReadFile(id) # 55 + + # y_norm_values = normalize(y_values) + + # break into 4 parts + legend_labels = ['sort', 'merge', 'join'] # , 'others' + + DrawFigure(x_values, y_values, legend_labels, + 'sorting step size', 'cycles per input tuple', + 'breakdown_sort_figure', True) + + # DrawLegend(legend_labels, 'breakdown_radix_legend') + + +def DrawPercentageFigure(x_values, y_values, legend_labels, x_label, y_label, filename, allow_legend, title): + # you may change the figure size on your own. + fig = plt.figure(figsize=(9, 3)) + figure = fig.add_subplot(111) + + FIGURE_LABEL = legend_labels + + # values in the x_xis + index = np.arange(len(x_values)) + # the bar width. + # you may need to tune it to get the best figure. + width = 0.5 + # draw the bars + bottom_base = np.zeros(len(y_values[0])) + bars = [None] * (len(FIGURE_LABEL)) + for i in range(len(y_values)): + bars[i] = plt.bar(index + width / 2, y_values[i], width, hatch=PATTERNS[i], color=LINE_COLORS[i], + label=FIGURE_LABEL[i], bottom=bottom_base, edgecolor='black', linewidth=3) + bottom_base = np.array(y_values[i]) + bottom_base + + # sometimes you may not want to draw legends. + if allow_legend == True: + plt.legend(bars, FIGURE_LABEL + # mode='expand', + # shadow=False, + # columnspacing=0.25, + # labelspacing=-2.2, + # borderpad=5, + # bbox_transform=ax.transAxes, + # frameon=False, + # columnspacing=5.5, + # handlelength=2, + ) + if allow_legend == True: + handles, labels = figure.get_legend_handles_labels() + if allow_legend == True: + print(handles[::-1], labels[::-1]) + leg = plt.legend(handles[::-1], labels[::-1], + loc='center', + prop=LEGEND_FP, + ncol=3, + bbox_to_anchor=(0.5, 1.2), + handletextpad=0.1, + borderaxespad=0.0, + handlelength=1.8, + labelspacing=0.3, + columnspacing=0.3, + ) + leg.get_frame().set_linewidth(2) + leg.get_frame().set_edgecolor("black") + + # sometimes you may not want to draw legends. + # if allow_legend == True: + # leg=plt.legend(bars, + # FIGURE_LABEL, + # prop=LEGEND_FP, + # loc='right', + # ncol=1, + # # mode='expand', + # bbox_to_anchor=(0.45, 1.1), shadow=False, + # columnspacing=0.1, + # frameon=True, borderaxespad=0.0, handlelength=1.5, + # handletextpad=0.1, + # labelspacing=0.1) + # leg.get_frame().set_linewidth(2) + # leg.get_frame().set_edgecolor("black") + + plt.ylim(0, 100) + + # you may need to tune the xticks position to get the best figure. + plt.xticks(index + 0.5 * width, x_values) + plt.xticks(rotation=30) + + # plt.xlim(0,) + # plt.ylim(0,1) + + plt.grid(axis='y', color='gray') + figure.yaxis.set_major_locator(LinearLocator(6)) + + figure.get_xaxis().set_tick_params(direction='in', pad=10) + figure.get_yaxis().set_tick_params(direction='in', pad=10) + + plt.xlabel(x_label, fontproperties=LABEL_FP) + plt.ylabel(y_label, fontproperties=LABEL_FP) + + size = fig.get_size_inches() + dpi = fig.get_dpi() + + plt.savefig(filename + ".pdf", bbox_inches='tight', format='pdf') diff --git a/benchmark/scripts/scanThreads/autoParase.py b/benchmark/scripts/scanThreads/autoParase.py new file mode 100755 index 00000000..9375c8e0 --- /dev/null +++ b/benchmark/scripts/scanThreads/autoParase.py @@ -0,0 +1,87 @@ +import csv + + +def paraseValidStageNames(a): + nameList = [] + with open(a, 'r') as f: + reader = csv.reader(f) + # reader = [each for each in csv.DictReader(f, delimiter=',')] + result = list(reader) + rows = len(result) + # print('rows=',rows) + firstRow = result[0] + # print(firstRow) + index = 0 + # define what may attract our interest + idxCpu = 0 + idxName = 0 + for i in firstRow: + # print(i) + if (i == 'cpu'): + idxCpu = index + if (i == 'name'): + idxName = index + index = index + 1 + # read the valid stages + vdataEntries = 0 + + for k in range(1, rows): + if (result[k][idxCpu] != 'NA'): + R1 = ((result[k][idxName])) + nameList.append(R1) + return nameList + + +def paraseValidColums(a, nameList, colTitle): + with open(a, 'r') as f: + reader = csv.reader(f) + # reader = [each for each in csv.DictReader(f, delimiter=',')] + result = list(reader) + rows = len(result) + # print('rows=',rows) + firstRow = result[0] + # print(firstRow) + index = 0 + # define what may attract our interest + idxCpu = 0 + idxName = 0 + idxTitle = 0 + for i in firstRow: + # print(i) + if (i == 'cpu'): + idxCpu = index + if (i == 'name'): + idxName = index + if (i == colTitle): + idxTitle = index + index = index + 1 + # read the valid stages + vdataEntries = 0 + ru = [] + for k in range(1, rows): + if (result[k][idxCpu] != 'NA'): + R1 = ((result[k][idxName])) + for j in range(len(nameList)): + if (R1 == nameList[j]): + s = int(result[k][idxTitle]) + ru.append(s) + break + return ru + + +def maxInList(a): + # a in [[1,2] [3,4]] + inLen = len(a[0]) + ru = [] + index = [] + ti = 0 + for i in range(len(a[0])): + ts = 0 + ti = 0 + for k in range(len(a)): + if (a[k][i] > ts): + ts = a[k][i] + ti = k + ru.append(ts) + index.append(ti) + return ru, index diff --git a/benchmark/scripts/scanThreads/config_BCoAMM.csv b/benchmark/scripts/scanThreads/config_BCoAMM.csv new file mode 100644 index 00000000..6777ad23 --- /dev/null +++ b/benchmark/scripts/scanThreads/config_BCoAMM.csv @@ -0,0 +1,8 @@ +key,value,type +aRow,1000,U64 +aCol,1000,U64 +bCol,500,U64 +aReduce,10,U64 +sketchDimension,25,U64 +threads,1,U64 +ptFile,torchscripts/BetaCoOccurringFD.pt,String \ No newline at end of file diff --git a/benchmark/scripts/scanThreads/config_CRS.csv b/benchmark/scripts/scanThreads/config_CRS.csv new file mode 100644 index 00000000..b6afe1ef --- /dev/null +++ b/benchmark/scripts/scanThreads/config_CRS.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/benchmark/scripts/scanThreads/config_CoAMM.csv b/benchmark/scripts/scanThreads/config_CoAMM.csv new file mode 100644 index 00000000..984ebb29 --- /dev/null +++ b/benchmark/scripts/scanThreads/config_CoAMM.csv @@ -0,0 +1,8 @@ +key,value,type +aRow,1000,U64 +aCol,1000,U64 +bCol,500,U64 +aReduce,10,U64 +sketchDimension,25,U64 +threads,1,U64 +ptFile,torchscripts/CoOccurringFD.pt,String \ No newline at end of file diff --git a/benchmark/scripts/scanThreads/config_FDAMM.csv b/benchmark/scripts/scanThreads/config_FDAMM.csv new file mode 100644 index 00000000..a513cad8 --- /dev/null +++ b/benchmark/scripts/scanThreads/config_FDAMM.csv @@ -0,0 +1,8 @@ +key,value,type +aRow,1000,U64 +aCol,1000,U64 +bCol,500,U64 +aReduce,10,U64 +sketchDimension,25,U64 +threads,1,U64 +ptFile,torchscripts/FDAMM.pt,String \ No newline at end of file diff --git a/benchmark/scripts/scanThreads/config_RAWMM.csv b/benchmark/scripts/scanThreads/config_RAWMM.csv new file mode 100644 index 00000000..32600e72 --- /dev/null +++ b/benchmark/scripts/scanThreads/config_RAWMM.csv @@ -0,0 +1,8 @@ +key,value,type +aRow,10000,U64 +aCol,1000,U64 +bCol,500,U64 +aReduce,10,U64 +sketchDimension,25,U64 +threads,1,U64 +ptFile,torchscripts/RAWMM.pt,String \ No newline at end of file diff --git a/benchmark/scripts/scanThreads/drawTogether.py b/benchmark/scripts/scanThreads/drawTogether.py new file mode 100755 index 00000000..0537294e --- /dev/null +++ b/benchmark/scripts/scanThreads/drawTogether.py @@ -0,0 +1,177 @@ +#!/usr/bin/env python3 +import csv +import numpy as np +import accuBar as accuBar +import groupBar as groupBar +import groupBar2 as groupBar2 +import groupLine as groupLine +from autoParase import * +import itertools as it +import os + +import matplotlib +import numpy as np +import pylab +import matplotlib.font_manager as fm +from matplotlib.font_manager import FontProperties +from matplotlib.ticker import LogLocator, LinearLocator +import os +import pandas as pd +import sys +from OoOCommon import * +import time + +# OPT_FONT_NAME = 'Helvetica' +TICK_FONT_SIZE = 22 +LABEL_FONT_SIZE = 28 +LEGEND_FONT_SIZE = 30 +LABEL_FP = FontProperties(style='normal', size=LABEL_FONT_SIZE) +LEGEND_FP = FontProperties(style='normal', size=LEGEND_FONT_SIZE) +TICK_FP = FontProperties(style='normal', size=TICK_FONT_SIZE) + +MARKERS = (['*', '|', 'v', "^", "", "h", "<", ">", "+", "d", "<", "|", "", "+", "_"]) +# you may want to change the color map for different figures +COLOR_MAP = ( + '#B03A2E', '#2874A6', '#239B56', '#7D3C98', '#FFFFFF', '#F1C40F', '#F5CBA7', '#82E0AA', '#AEB6BF', '#AA4499') +# you may want to change the patterns for different figures +PATTERNS = (["////", "o", "", "||", "-", "//", "\\", "o", "O", "////", ".", "|||", "o", "---", "+", "\\\\", "*"]) +LABEL_WEIGHT = 'bold' +LINE_COLORS = COLOR_MAP +LINE_WIDTH = 3.0 +MARKER_SIZE = 15.0 +MARKER_FREQUENCY = 1000 + +matplotlib.rcParams['ps.useafm'] = True +matplotlib.rcParams['pdf.use14corefonts'] = True +matplotlib.rcParams['xtick.labelsize'] = TICK_FONT_SIZE +matplotlib.rcParams['ytick.labelsize'] = TICK_FONT_SIZE +matplotlib.rcParams['font.family'] = OPT_FONT_NAME +matplotlib.rcParams['pdf.fonttype'] = 42 + +scanTag = "threads" + + +def singleRun(exePath, singleValue, resultPath, configTemplate): + # resultFolder="singleValueTests" + configFname = "config_" + scanTag + str(singleValue) + ".csv" + # configTemplate = "config.csv" + # clear old files + os.system("cd " + exePath + "&& sudo rm *.csv") + + # editConfig(configTemplate, exePath + configFname, "earlierEmitMs", 0) + editConfig(configTemplate, exePath + configFname, scanTag, singleValue) + # prepare new file + # run + os.system("cd " + exePath + "&& sudo ./benchmark " + configFname) + # copy result + os.system("sudo rm -rf " + resultPath + "/" + str(singleValue)) + os.system("sudo mkdir " + resultPath + "/" + str(singleValue)) + os.system("cd " + exePath + "&& sudo cp *.csv " + resultPath + "/" + str(singleValue)) + + +def runScanVector(exePath, singleValueVec, resultPath, templateName="config.csv"): + for i in singleValueVec: + singleRun(exePath, i, resultPath, templateName) + + +def readResultSingle(singleValue, resultPath): + resultFname = resultPath + "/" + str(singleValue) + "/default.csv" + elapsedTime = readConfig(resultFname, "perfElapsedTime") + cacheMiss = readConfig(resultFname, "cacheMiss") + cacheRefs = readConfig(resultFname, "cacheRefs") + return elapsedTime, cacheMiss, cacheRefs + + +def cleanPath(path): + os.system("sudo rm -rf " + path) + os.system("sudo mkdir " + path) + + +def readResultVector(singleValueVec, resultPath): + elapseTimeVec = [] + cacheMissVec = [] + cacheRefVec = [] + for i in singleValueVec: + elapsedTime, cacheMiss, cacheRefs = readResultSingle(i, resultPath) + elapseTimeVec.append(float(elapsedTime) / 1000.0) + cacheMissVec.append(float(cacheMiss)) + cacheRefVec.append(float(cacheRefs)) + return np.array(elapseTimeVec), np.array(cacheMissVec), np.array(cacheRefVec) + + +def compareMethod(exeSpace, commonPathBase, resultPaths, csvTemplates, periodVec, reRun=1): + elapsedTimeAll = [] + cacheMissAll = [] + cacheRefAll = [] + periodAll = [] + for i in range(len(csvTemplates)): + resultPath = commonPathBase + resultPaths[i] + if (reRun == 1): + os.system("sudo rm -rf " + resultPath) + os.system("sudo mkdir " + resultPath) + runScanVector(exeSpace, periodVec, resultPath, csvTemplates[i]) + elapsedTime, cacheMiss, cacheRef = readResultVector(periodVec, resultPath) + elapsedTimeAll.append(elapsedTime) + cacheMissAll.append(cacheMiss) + cacheRefAll.append(cacheRef) + periodAll.append(periodVec) + cacheMissRateAll = np.array(cacheMissAll) / np.array(cacheRefAll) * 100.0 + # periodAll.append(periodVec) + return np.array(elapsedTimeAll), cacheMissRateAll, periodAll + + +def main(): + exeSpace = os.path.abspath(os.path.join(os.getcwd(), "../..")) + "/" + resultPath = os.path.abspath(os.path.join(os.getcwd(), "../..")) + "/results/" + scanTag + figPath = os.path.abspath(os.path.join(os.getcwd(), "../..")) + "/figures/" + scanTag + configTemplate = exeSpace + "config.csv" + commonBase = resultPath + "/" + resultPaths = ["MM"] + csvTemplates = ["config_RAWMM.csv"] + evaTypes = ['mm'] + valueVec = [2, 4, 6, 8, 10, 12, 14, 16] + valueVecRun = valueVec + print(configTemplate) + reRun = 0 + # run + if (len(sys.argv) < 2): + os.system("mkdir ../../results") + os.system("mkdir ../../figures") + os.system("mkdir " + figPath) + os.system("sudo rm -rf " + resultPath) + os.system("sudo mkdir " + resultPath) + # + reRun = 1 + tRows = len(resultPaths) + tCols = len(valueVec) + elapseTimeAllSum = np.zeros((tRows, tCols)) + rounds = 1 + for i in range(rounds): + elapseTimeAll, ch, periodAll = compareMethod(exeSpace, commonBase, resultPaths, csvTemplates, valueVec, reRun) + elapseTimeAllSum = elapseTimeAllSum + elapseTimeAll + elapseTimeAllSum = elapseTimeAllSum / float(rounds) + # evaTypes = ['FDAMM', 'MM', 'Co-FD', 'BCO-FD'] + + # elapseTimeVecFD, cacheMissVecFD, cacheRefVecFD = readResultVector(valueVecRun, resultPathFDAMM) + # elapseTimeVecCoFD, cacheMissVecCoFD, cacheRefVecCoFD = readResultVector(valueVecRun, resultPathCoFD) + # elapseTimeVeCB, cacheMissVecB, cacheRefVecB = readResultVector(valueVecRun, resultPathBetaCoFD) + + # os.system("mkdir " + figPath) + groupLine.DrawFigureXYnormal(periodAll, + elapseTimeAllSum, + evaTypes, + "#threads", "elapsed time (ms)", 0, 1, figPath + "threads" + "_elapsedTime", + True) + + # draw2yLine("watermark time (ms)",singleValueVecDisp,lat95Vec,errVec,"95% Latency (ms)","Error","ms","",figPath+"wm_lat") + # draw2yLine("watermark time (ms)",singleValueVecDisp,thrVec,errVec,"Throughput (KTp/s)","Error","KTp/s","",figPath+"wm_thr") + # draw2yLine("watermark time (ms)",singleValueVecDisp,lat95Vec,compVec,"95% Latency (ms)","Completeness","ms","",figPath+"wm_omp") + # groupLine.DrawFigureYnormal([singleValueVec,singleValueVec],[errVec,aqpErrVec],['w/o aqp',"w/ MeanAqp"],"watermark time (ms)","Error",0,1,figPath+"wm_MeanAqp",True) + # print(errVec) + # print(aqpErrVec) + # print(elapseTimeVecFD) + # readResultsingleValue(50,resultPath) + + +if __name__ == "__main__": + main() diff --git a/benchmark/scripts/scanThreads/groupBar.py b/benchmark/scripts/scanThreads/groupBar.py new file mode 100755 index 00000000..ef2d9842 --- /dev/null +++ b/benchmark/scripts/scanThreads/groupBar.py @@ -0,0 +1,236 @@ +import itertools as it +import os + +import matplotlib +import matplotlib.pyplot as plt +import numpy as np +import pylab +from matplotlib.font_manager import FontProperties +from matplotlib.ticker import LogLocator, LinearLocator + +OPT_FONT_NAME = 'Helvetica' +TICK_FONT_SIZE = 24 +LABEL_FONT_SIZE = 28 +LEGEND_FONT_SIZE = 15 +LABEL_FP = FontProperties(style='normal', size=LABEL_FONT_SIZE) +LEGEND_FP = FontProperties(style='normal', size=LEGEND_FONT_SIZE) +TICK_FP = FontProperties(style='normal', size=TICK_FONT_SIZE) + +MARKERS = (["", 'o', 's', 'v', "^", "", "h", "<", ">", "+", "d", "<", "|", "", "+", "_"]) +# you may want to change the color map for different figures +COLOR_MAP = ( + '#7FFFFF', '#B03A2E', '#2874A6', '#FFFFFF', '#7FFFFF', '#B03A2E', '#2874A6', '#FFFFFF', '#F5CBA7', '#82E0AA', + '#AEB6BF', + '#AA4499') +# you may want to change the patterns for different figures +PATTERNS = ( + ["////", "\\\\", "//", "o", "*", "||", "-", "//", "\\", "o", "O", "////", ".", "|||", "o", "---", "+", "\\\\", "*"]) +LABEL_WEIGHT = 'bold' +LINE_COLORS = COLOR_MAP +LINE_WIDTH = 3.0 +MARKER_SIZE = 15.0 +MARKER_FREQUENCY = 1000 + +matplotlib.rcParams['ps.useafm'] = True +matplotlib.rcParams['pdf.use14corefonts'] = True +matplotlib.rcParams['xtick.labelsize'] = TICK_FONT_SIZE +matplotlib.rcParams['ytick.labelsize'] = TICK_FONT_SIZE +matplotlib.rcParams['font.family'] = OPT_FONT_NAME +matplotlib.rcParams['pdf.fonttype'] = 42 + +exp_dir = "/data1/xtra" + +FIGURE_FOLDER = exp_dir + '/results/figure' + + +def DrawLegend(legend_labels, filename): + fig = pylab.figure() + ax1 = fig.add_subplot(111) + FIGURE_LABEL = legend_labels + LEGEND_FP = FontProperties(style='normal', size=26) + figlegend = pylab.figure(figsize=(16, 0.5)) + bars = [None] * (len(FIGURE_LABEL)) + data = [1] + x_values = [1] + + width = 0.3 + for i in range(len(FIGURE_LABEL)): + bars[i] = ax1.bar(x_values, data, width, + hatch=PATTERNS[i], + color=LINE_COLORS[i], + label=FIGURE_LABEL[i], + edgecolor='black', linewidth=3) + + # LEGEND + + figlegend.legend(bars, FIGURE_LABEL, prop=LEGEND_FP, \ + loc=1, ncol=len(FIGURE_LABEL), mode="expand", shadow=True, \ + frameon=True, handlelength=2, handletextpad=0.3, columnspacing=0.5, + borderaxespad=-0.2, fancybox=True + ) + figlegend.savefig(FIGURE_FOLDER + '/' + filename + '.pdf') + + +# draw a bar chart +def DrawFigure(x_values, y_values, legend_labels, x_label, y_label, y_min, y_max, filename, allow_legend): + # you may change the figure size on your own. + fig = plt.figure(figsize=(10, 3)) + figure = fig.add_subplot(111) + + FIGURE_LABEL = legend_labels + + # values in the x_xis + index = np.arange(len(x_values)) + # the bar width. + # you may need to tune it to get the best figure. + width = 0.08 + # draw the bars + bars = [] + ts = 0 + pos = 0 + gl = len(y_values[0]) + for i in range(len(y_values)): + pos = pos + 3 * width + for j in range(len(y_values[i])): + pos = pos + width + bar = plt.bar(pos, y_values[i][j], width, hatch=PATTERNS[j], color=LINE_COLORS[j], label=FIGURE_LABEL[j], + edgecolor='black', linewidth=3) + bars.append(bar) + ts = ts + 1 + + # sometimes you may not want to draw legends. + if allow_legend == True: + plt.legend(bars, FIGURE_LABEL, + prop=LEGEND_FP, + ncol=4, + loc='upper center', + # mode='expand', + shadow=False, + bbox_to_anchor=(0.45, 1.6), + columnspacing=0.1, + handletextpad=0.2, + # bbox_transform=ax.transAxes, + # frameon=True, + # columnspacing=5.5, + # handlelength=2, + ) + + # you may need to tune the xticks position to get the best figure. + plt.xticks(index, x_values) + # plt.ticklabel_format(axis="y", style="sci", scilimits=(0, 0)) + # plt.grid(axis='y', color='gray') + # figure.get_xaxis().set_major_formatter(matplotlib.ticker.ScalarFormatter()) + + # you may need to tune the xticks position to get the best figure. + # plt.yscale('log') + # + # plt.grid(axis='y', color='gray') + figure.yaxis.set_major_locator(LinearLocator(5)) + # figure.xaxis.set_major_locator(LinearLocator(5)) + figure.get_xaxis().set_tick_params(direction='in', pad=10) + figure.get_yaxis().set_tick_params(direction='in', pad=10) + + plt.xlabel(x_label, fontproperties=LABEL_FP) + plt.ylabel(y_label, fontproperties=LABEL_FP) + plt.ylim(y_min, y_max) + plt.savefig(filename + ".pdf", bbox_inches='tight') + + +# example for reading csv file +def ReadFile(): + y = [] + col1 = [] + col2 = [] + col3 = [] + col4 = [] + col5 = [] + col6 = [] + col7 = [] + col8 = [] + col9 = [] + + for id in it.chain(range(38, 42)): + col9.append(0) + y.append(col9) # this is a lz4_pipe2 empty line to separate eager and lazy. + + for id in it.chain(range(38, 42)): + file = exp_dir + '/results/latency/NPJ_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(int(len(read) * 0.95)).strip("\n")) # get the 99th timestamp + col1.append(x) + y.append(col1) + + for id in it.chain(range(38, 42)): + file = exp_dir + '/results/latency/PRJ_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(int(len(read) * 0.95)).strip("\n")) # get the 99th timestamp + col2.append(x) + y.append(col2) + + for id in it.chain(range(38, 42)): + file = exp_dir + '/results/latency/MWAY_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(int(len(read) * 0.95)).strip("\n")) # get the 99th timestamp + col3.append(x) + y.append(col3) + + for id in it.chain(range(38, 42)): + file = exp_dir + '/results/latency/MPASS_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(int(len(read) * 0.95)).strip("\n")) # get the 99th timestamp + col4.append(x) + y.append(col4) + + y.append(col9) # this is a lz4_pipe2 empty line to separate eager and lazy. + + for id in it.chain(range(38, 42)): + file = exp_dir + '/results/latency/SHJ_JM_NP_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(int(len(read) * 0.95)).strip("\n")) # get last timestamp + col5.append(x) + y.append(col5) + + for id in it.chain(range(38, 42)): + file = exp_dir + '/results/latency/SHJ_JBCR_NP_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(int(len(read) * 0.95)).strip("\n")) # get last timestamp + col6.append(x) + y.append(col6) + + for id in it.chain(range(38, 42)): + file = exp_dir + '/results/latency/PMJ_JM_NP_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(int(len(read) * 0.95)).strip("\n")) # get last timestamp + col7.append(x) + y.append(col7) + + for id in it.chain(range(38, 42)): + file = exp_dir + '/results/latency/PMJ_JBCR_NP_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(int(len(read) * 0.95)).strip("\n")) # get last timestamp + col8.append(x) + y.append(col8) + return y + + +if __name__ == "__main__": + x_values = ["Stock", "Rovio", "YSB", "DEBS"] + + y_values = ReadFile() + + legend_labels = ['Lazy:', 'NPJ', 'PRJ', 'MWAY', 'MPASS', + 'Eager:', 'SHJ$^{JM}$', 'SHJ$^{JB}$', 'PMJ$^{JM}$', 'PMJ$^{JB}$'] + print(y_values) + DrawFigure(x_values, y_values, legend_labels, + '', 'Latency (ms)', 0, + 400, 'latency_figure_app', False) + + # DrawLegend(legend_labels, 'latency_legend') diff --git a/benchmark/scripts/scanThreads/groupBar2.py b/benchmark/scripts/scanThreads/groupBar2.py new file mode 100755 index 00000000..31155695 --- /dev/null +++ b/benchmark/scripts/scanThreads/groupBar2.py @@ -0,0 +1,232 @@ +import itertools as it +import os + +import matplotlib +import matplotlib.pyplot as plt +import numpy as np +import pylab +from matplotlib.font_manager import FontProperties +from matplotlib.ticker import LogLocator, LinearLocator + +OPT_FONT_NAME = 'Helvetica' +TICK_FONT_SIZE = 24 +LABEL_FONT_SIZE = 28 +LEGEND_FONT_SIZE = 30 +LABEL_FP = FontProperties(style='normal', size=LABEL_FONT_SIZE) +LEGEND_FP = FontProperties(style='normal', size=LEGEND_FONT_SIZE) +TICK_FP = FontProperties(style='normal', size=TICK_FONT_SIZE) + +MARKERS = (["", 'o', 's', 'v', "^", "", "h", "<", ">", "+", "d", "<", "|", "", "+", "_"]) +# you may want to change the color map for different figures +COLOR_MAP = ( + '#FFFFFF', '#B03A2E', '#2874A6', '#239B56', '#7D3C98', '#00FFFF', '#F1C40F', '#F5CBA7', '#82E0AA', '#AEB6BF', + '#AA4499') +# you may want to change the patterns for different figures +PATTERNS = ( + ["", "////", "\\\\", "//", "o", "", "||", "-", "//", "\\", "o", "O", "////", ".", "|||", "o", "---", "+", "\\\\", + "*"]) +LABEL_WEIGHT = 'bold' +LINE_COLORS = COLOR_MAP +LINE_WIDTH = 3.0 +MARKER_SIZE = 15.0 +MARKER_FREQUENCY = 1000 + +matplotlib.rcParams['ps.useafm'] = True +matplotlib.rcParams['pdf.use14corefonts'] = True +matplotlib.rcParams['xtick.labelsize'] = TICK_FONT_SIZE +matplotlib.rcParams['ytick.labelsize'] = TICK_FONT_SIZE +matplotlib.rcParams['font.family'] = OPT_FONT_NAME +matplotlib.rcParams['pdf.fonttype'] = 42 + +exp_dir = "/data1/xtra" + +FIGURE_FOLDER = exp_dir + '/results/figure' + + +def DrawLegend(legend_labels, filename): + fig = pylab.figure() + ax1 = fig.add_subplot(111) + FIGURE_LABEL = legend_labels + LEGEND_FP = FontProperties(style='normal', size=26) + figlegend = pylab.figure(figsize=(16, 0.5)) + bars = [None] * (len(FIGURE_LABEL)) + data = [1] + x_values = [1] + + width = 0.3 + for i in range(len(FIGURE_LABEL)): + bars[i] = ax1.bar(x_values, data, width, + hatch=PATTERNS[i], + color=LINE_COLORS[i], + label=FIGURE_LABEL[i], + edgecolor='black', linewidth=3) + + # LEGEND + + figlegend.legend(bars, FIGURE_LABEL, prop=LEGEND_FP, \ + loc=1, ncol=len(FIGURE_LABEL), mode="expand", shadow=True, \ + frameon=True, handlelength=2, handletextpad=0.3, columnspacing=0.5, + borderaxespad=-0.2, fancybox=True + ) + figlegend.savefig(FIGURE_FOLDER + '/' + filename + '.pdf') + + +# draw a bar chart +def DrawFigure(x_values, y_values, legend_labels, x_label, y_label, y_min, y_max, filename, allow_legend): + # you may change the figure size on your own. + fig = plt.figure(figsize=(10, 3)) + figure = fig.add_subplot(111) + + FIGURE_LABEL = legend_labels + + # values in the x_xis + index = np.arange(len(x_values)) + # the bar width. + # you may need to tune it to get the best figure. + width = 0.12 + # draw the bars + bars = [None] * (len(FIGURE_LABEL)) + for i in range(len(y_values)): + bars[i] = plt.bar(index + i * width + width / 2, + y_values[i], width, + hatch=PATTERNS[i], + color=LINE_COLORS[i], + label=FIGURE_LABEL[i], edgecolor='black', linewidth=3) + + # sometimes you may not want to draw legends. + if allow_legend == True: + plt.legend(bars, FIGURE_LABEL, + prop=LEGEND_FP, + ncol=3, + loc='upper center', + # mode='expand', + shadow=False, + bbox_to_anchor=(0.45, 1.7), + columnspacing=0.1, + handletextpad=0.2, + # bbox_transform=ax.transAxes, + # frameon=True, + # columnspacing=5.5, + # handlelength=2, + ) + + # you may need to tune the xticks position to get the best figure. + plt.xticks(index + 3 * width, x_values, rotation=30) + + # plt.ticklabel_format(axis="y", style="sci", scilimits=(0, 0)) + # plt.grid(axis='y', color='gray') + # figure.get_xaxis().set_major_formatter(matplotlib.ticker.ScalarFormatter()) + + # you may need to tune the xticks position to get the best figure. + # plt.yscale('log') + # + # plt.grid(axis='y', color='gray') + figure.yaxis.set_major_locator(LinearLocator(10)) + # figure.xaxis.set_major_locator(LinearLocator(5)) + figure.get_xaxis().set_tick_params(direction='in', pad=10) + figure.get_yaxis().set_tick_params(direction='in', pad=10) + + plt.xlabel(x_label, fontproperties=LABEL_FP) + plt.ylabel(y_label, fontproperties=LABEL_FP) + + plt.savefig(filename + ".pdf", bbox_inches='tight') + + +# example for reading csv file +def ReadFile(): + y = [] + col1 = [] + col2 = [] + col3 = [] + col4 = [] + col5 = [] + col6 = [] + col7 = [] + col8 = [] + col9 = [] + + for id in it.chain(range(38, 42)): + col9.append(0) + y.append(col9) # this is a fake empty line to separate eager and lazy. + + for id in it.chain(range(38, 42)): + file = exp_dir + '/results/latency/NPJ_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(int(len(read) * 0.95)).strip("\n")) # get the 99th timestamp + col1.append(x) + y.append(col1) + + for id in it.chain(range(38, 42)): + file = exp_dir + '/results/latency/PRJ_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(int(len(read) * 0.95)).strip("\n")) # get the 99th timestamp + col2.append(x) + y.append(col2) + + for id in it.chain(range(38, 42)): + file = exp_dir + '/results/latency/MWAY_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(int(len(read) * 0.95)).strip("\n")) # get the 99th timestamp + col3.append(x) + y.append(col3) + + for id in it.chain(range(38, 42)): + file = exp_dir + '/results/latency/MPASS_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(int(len(read) * 0.95)).strip("\n")) # get the 99th timestamp + col4.append(x) + y.append(col4) + + y.append(col9) # this is a fake empty line to separate eager and lazy. + + for id in it.chain(range(38, 42)): + file = exp_dir + '/results/latency/SHJ_JM_NP_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(int(len(read) * 0.95)).strip("\n")) # get last timestamp + col5.append(x) + y.append(col5) + + for id in it.chain(range(38, 42)): + file = exp_dir + '/results/latency/SHJ_JBCR_NP_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(int(len(read) * 0.95)).strip("\n")) # get last timestamp + col6.append(x) + y.append(col6) + + for id in it.chain(range(38, 42)): + file = exp_dir + '/results/latency/PMJ_JM_NP_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(int(len(read) * 0.95)).strip("\n")) # get last timestamp + col7.append(x) + y.append(col7) + + for id in it.chain(range(38, 42)): + file = exp_dir + '/results/latency/PMJ_JBCR_NP_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(int(len(read) * 0.95)).strip("\n")) # get last timestamp + col8.append(x) + y.append(col8) + return y + + +if __name__ == "__main__": + x_values = ["Stock", "Rovio", "YSB", "DEBS"] + + y_values = ReadFile() + + legend_labels = ['Lazy:', 'NPJ', 'PRJ', 'MWAY', 'MPASS', + 'Eager:', 'SHJ$^{JM}$', 'SHJ$^{JB}$', 'PMJ$^{JM}$', 'PMJ$^{JB}$'] + print(y_values) + DrawFigure(x_values, y_values, legend_labels, + '', 'Latency (ms)', 0, + 400, 'latency_figure_app', False) + + # DrawLegend(legend_labels, 'latency_legend') diff --git a/benchmark/scripts/scanThreads/groupLine.py b/benchmark/scripts/scanThreads/groupLine.py new file mode 100755 index 00000000..8110fd3b --- /dev/null +++ b/benchmark/scripts/scanThreads/groupLine.py @@ -0,0 +1,366 @@ +import itertools as it +import os +import matplotlib.pyplot as plt +import matplotlib.font_manager as fm +import matplotlib +import numpy as np +import pylab +from matplotlib.font_manager import FontProperties +from matplotlib.ticker import MaxNLocator +from matplotlib.font_manager import FontProperties +from matplotlib.ticker import LinearLocator, LogLocator, MaxNLocator, ScalarFormatter +from numpy import double + +# 获取系统中可用的字体路径 +# font_paths = fm.findSystemFonts() +# OPT_FONT_NAME = 'Helvetica' +TICK_FONT_SIZE = 20 +LABEL_FONT_SIZE = 20 +LEGEND_FONT_SIZE = 20 +LABEL_FP = FontProperties(style='normal', size=LABEL_FONT_SIZE) +LEGEND_FP = FontProperties(style='normal', size=LEGEND_FONT_SIZE) +TICK_FP = FontProperties(style='normal', size=TICK_FONT_SIZE) + +MARKERS = (['o', 's', 'v', "^", "h", "v", ">", "x", "d", "<", "|", "p", "+", "_", "%", "|", "|", "|", "|", "|"]) +# you may want to change the color map for different figures +COLOR_MAP = ( + '#F15854', '#5DA5DA', '#60BD68', '#B276B2', '#DECF3F', '#F17CB0', '#B2912F', '#FAA43A', '#AFAFAF', '#087878', + '#783456', + '#560012', '#431256', "#00AABB", "#AA00BB") +# you may want to change the patterns for different figures +PATTERNS = (["|", "\\", "/", "+", "-", ".", "*", "x", "o", "O", "////", ".", "|||", "o", "---", "+", "\\\\", "*"]) +LABEL_WEIGHT = 'bold' +LINE_COLORS = COLOR_MAP +LINE_WIDTH = 3.0 +MARKER_SIZE = 13.0 +MARKER_FREQUENCY = 1000 + +# matplotlib.rcParams['ps.useafm'] = True +# matplotlib.rcParams['pdf.use14corefonts'] = True +# matplotlib.rcParams['xtick.labelsize'] = TICK_FONT_SIZE +# matplotlib.rcParams['ytick.labelsize'] = TICK_FONT_SIZE +# 创建字体列表 +# Explicitly specify the font path +# 获取系统中可用的字体路径 +font_paths = fm.findSystemFonts() + +# 创建字体列表 +font_list = [] +for font_path in font_paths: + try: + font_name = fm.FontProperties(fname=font_path).get_name() + if font_name not in font_list: + font_list.append(font_name) + except: + pass + +# 配置 matplotlib 使用系统中可用的字体 +plt.rcParams['font.family'] = font_list[0] + +FIGURE_FOLDER = '/data1/xtra/results/figure' + + +# there are some embedding problems if directly exporting the pdf figure using matplotlib. +# so we generate the eps format first and convert it to pdf. +def ConvertEpsToPdf(dir_filename): + os.system("epstopdf --outfile " + dir_filename + ".pdf " + dir_filename + ".eps") + os.system("rm -rf " + dir_filename + ".eps") + + +def DrawLegend(legend_labels, filename): + fig = pylab.figure() + ax1 = fig.add_subplot(111) + FIGURE_LABEL = legend_labels + LINE_WIDTH = 8.0 + MARKER_SIZE = 12.0 + LEGEND_FP = FontProperties(style='normal', size=26) + + figlegend = pylab.figure(figsize=(12, 0.5)) + idx = 0 + lines = [None] * (len(FIGURE_LABEL)) + data = [1] + x_values = [1] + + idx = 0 + for group in range(len(FIGURE_LABEL)): + lines[idx], = ax1.plot(x_values, data, + color=LINE_COLORS[idx], linewidth=LINE_WIDTH, + marker=MARKERS[idx], markersize=MARKER_SIZE, label=str(group)) + idx = idx + 1 + + # LEGEND + figlegend.legend(lines, FIGURE_LABEL, prop=LEGEND_FP, + loc=1, ncol=len(FIGURE_LABEL), mode="expand", shadow=False, + frameon=False, borderaxespad=0.0, handlelength=2) + + if not os.path.exists(FIGURE_FOLDER): + os.makedirs(FIGURE_FOLDER) + # no need to export eps in this case. + figlegend.savefig(filename + '.pdf') + + +# draw a line chart +def DrawFigure(xvalues, yvalues, legend_labels, x_label, y_label, y_min, y_max, filename, allow_legend): + # you may change the figure size on your own. + fig = plt.figure(figsize=(10, 3)) + figure = fig.add_subplot(111) + + FIGURE_LABEL = legend_labels + + x_values = xvalues + y_values = yvalues + + lines = [None] * (len(FIGURE_LABEL)) + for i in range(len(y_values)): + lines[i], = figure.plot(x_values[i], y_values[i], color=LINE_COLORS[i], \ + linewidth=LINE_WIDTH, marker=MARKERS[i], \ + markersize=MARKER_SIZE, label=FIGURE_LABEL[i]) + + # sometimes you may not want to draw legends. + if allow_legend == True: + plt.legend(lines, + FIGURE_LABEL, + prop=LEGEND_FP, + loc='upper center', + ncol=3, + # mode='expand', + bbox_to_anchor=(0.55, 1.6), shadow=False, + columnspacing=0.1, + frameon=True, borderaxespad=0.0, handlelength=1.5, + handletextpad=0.1, + labelspacing=0.1) + plt.xscale('log') + plt.yscale('log') + # plt.yscale('log') + + # you may control the limits on your own. + + # plt.ylim(y_min, y_max) + + plt.grid(axis='y', color='gray') + figure.yaxis.set_major_locator(LogLocator(base=10)) + figure.xaxis.set_major_locator(LogLocator(base=10)) + + figure.get_xaxis().set_tick_params(direction='in', pad=10) + figure.get_yaxis().set_tick_params(direction='in', pad=10) + + plt.xlabel(x_label, fontproperties=LABEL_FP) + plt.ylabel(y_label, fontproperties=LABEL_FP) + + size = fig.get_size_inches() + dpi = fig.get_dpi() + + # plt.show() + plt.savefig(filename + ".pdf", bbox_inches='tight') + + +# draw a line chart +def DrawFigureXYnormal(xvalues, yvalues, legend_labels, x_label, y_label, y_min, y_max, filename, allow_legend): + # you may change the figure size on your own. + fig = plt.figure(figsize=(10, 3)) + figure = fig.add_subplot(111) + + FIGURE_LABEL = legend_labels + + x_values = xvalues + y_values = yvalues + + lines = [None] * (len(FIGURE_LABEL)) + for i in range(len(y_values)): + lines[i], = figure.plot(x_values[i], y_values[i], color=LINE_COLORS[i], \ + linewidth=LINE_WIDTH, marker=MARKERS[i], \ + markersize=MARKER_SIZE, label=FIGURE_LABEL[i], markeredgecolor='k') + + # sometimes you may not want to draw legends. + if allow_legend == True: + plt.legend(lines, + FIGURE_LABEL, + prop=LEGEND_FP, + loc='upper center', + ncol=3, + bbox_to_anchor=(0.55, 1.5), shadow=False, + columnspacing=0.1, + frameon=True, borderaxespad=0, handlelength=1.2, + handletextpad=0.1, + labelspacing=0.1) + # plt.xscale('log') + # plt.yscale('log') + # plt.yscale('log') + + # you may control the limits on your own. + + # plt.ylim(y_min, y_max) + + plt.grid(axis='y', color='gray') + plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号 + # figure.yaxis.set_major_locator(LogLocator(base=10)) + # figure.xaxis.set_major_locator(LogLocator(base=10)) + plt.xticks(rotation=0, fontsize=TICK_FONT_SIZE) + figure.get_xaxis().set_tick_params(direction='in', pad=10) + figure.get_yaxis().set_tick_params(direction='in', pad=10) + + plt.xlabel(x_label, fontproperties=LABEL_FP) + plt.ylabel(y_label, fontproperties=LABEL_FP) + + size = fig.get_size_inches() + dpi = fig.get_dpi() + + # plt.show() + plt.savefig(filename + ".pdf", bbox_inches='tight') + + +# draw a line chart +def DrawFigureYnormal(xvalues, yvalues, legend_labels, x_label, y_label, y_min, y_max, filename, allow_legend): + # you may change the figure size on your own. + fig = plt.figure(figsize=(10, 3)) + figure = fig.add_subplot(111) + + FIGURE_LABEL = legend_labels + + x_values = xvalues + y_values = yvalues + + lines = [None] * (len(FIGURE_LABEL)) + for i in range(len(y_values)): + lines[i], = figure.plot(x_values[i], y_values[i], color=LINE_COLORS[i], \ + linewidth=LINE_WIDTH, marker=MARKERS[i], \ + markersize=MARKER_SIZE, label=FIGURE_LABEL[i], markeredgecolor='k') + + # sometimes you may not want to draw legends. + if allow_legend == True: + plt.legend(lines, + FIGURE_LABEL, + prop=LEGEND_FP, + loc='upper center', + ncol=3, + bbox_to_anchor=(0.55, 1.5), shadow=False, + columnspacing=0.1, + frameon=True, borderaxespad=0, handlelength=1.2, + handletextpad=0.1, + labelspacing=0.1) + plt.xscale('log') + # plt.yscale('log') + # plt.yscale('log') + + # you may control the limits on your own. + + # plt.ylim(y_min, y_max) + + plt.grid(axis='y', color='gray') + plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号 + # figure.yaxis.set_major_locator(LogLocator(base=10)) + # figure.xaxis.set_major_locator(LogLocator(base=10)) + plt.xticks(rotation=0, fontsize=TICK_FONT_SIZE) + figure.get_xaxis().set_tick_params(direction='in', pad=10) + figure.get_yaxis().set_tick_params(direction='in', pad=10) + + plt.xlabel(x_label, fontproperties=LABEL_FP) + plt.ylabel(y_label, fontproperties=LABEL_FP) + + size = fig.get_size_inches() + dpi = fig.get_dpi() + + # plt.show() + plt.savefig(filename + ".pdf", bbox_inches='tight') + + +# example for reading csv file +def ReadFile(): + y = [] + col1 = [] + col2 = [] + col3 = [] + col4 = [] + col5 = [] + col6 = [] + col7 = [] + col8 = [] + + for id in it.chain(range(28, 32)): + file = '/data1/xtra/results/timestamps/PRJ_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(len(read) - 1).strip("\n")) # get last timestamp + value = len(read) / x # get throughput (#items/ms) + col1.append(value) + y.append(col1) + + for id in it.chain(range(28, 32)): + file = '/data1/xtra/results/timestamps/NPJ_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(len(read) - 1).strip("\n")) # get last timestamp + value = len(read) / x # get throughput (#items/ms) + col2.append(value) + y.append(col2) + + for id in it.chain(range(28, 32)): + file = '/data1/xtra/results/timestamps/MPASS_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(len(read) - 1).strip("\n")) # get last timestamp + value = len(read) / x # get throughput (#items/ms) + col3.append(value) + y.append(col3) + + for id in it.chain(range(28, 32)): + file = '/data1/xtra/results/timestamps/MWAY_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(len(read) - 1).strip("\n")) # get last timestamp + value = len(read) / x # get throughput (#items/ms) + col4.append(value) + y.append(col4) + + for id in it.chain(range(28, 32)): + file = '/data1/xtra/results/timestamps/SHJ_JM_NP_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(len(read) - 1).strip("\n")) # get last timestamp + value = len(read) / x # get throughput (#items/ms) + col5.append(value) + y.append(col5) + + for id in it.chain(range(28, 32)): + file = '/data1/xtra/results/timestamps/SHJ_JBCR_NP_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(len(read) - 1).strip("\n")) # get last timestamp + value = len(read) / x # get throughput (#items/ms) + col6.append(value) + y.append(col6) + + for id in it.chain(range(28, 32)): + file = '/data1/xtra/results/timestamps/PMJ_JM_NP_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(len(read) - 1).strip("\n")) # get last timestamp + value = len(read) / x # get throughput (#items/ms) + col7.append(value) + y.append(col7) + + for id in it.chain(range(28, 32)): + file = '/data1/xtra/results/timestamps/PMJ_JBCR_NP_{}.txt'.format(id) + f = open(file, "r") + read = f.readlines() + x = float(read.pop(len(read) - 1).strip("\n")) # get last timestamp + value = len(read) / x # get throughput (#items/ms) + col8.append(value) + y.append(col8) + return y + + +if __name__ == "__main__": + # x_values = ['Unique', 'Zipf(0)', 'Zipf(0.2)', 'Zipf(0.4)', 'Zipf(0.8)', 'Zipf(1)'] + x_values = [1600, 3200, 6400, 12800, 25600] + + y_values = ReadFile() + + legend_labels = ['NPJ', 'PRJ', 'MWAY', 'MPASS', 'SHJ$^{JM}$', 'SHJ$^{JB}$', 'PMJ$^{JM}$', + 'PMJ$^{JB}$'] + + DrawFigure(x_values, y_values, legend_labels, + 'Input arrival rate of R (e/ms)', 'Tpt. (#matches/ms)', x_values[0], + x_values[4], 'throughput_figure1_1', False) + +# DrawLegend(legend_labels, 'factor_legend') diff --git a/benchmark/scripts/scanThreads/perfRu.csv b/benchmark/scripts/scanThreads/perfRu.csv new file mode 100644 index 00000000..9ee43623 --- /dev/null +++ b/benchmark/scripts/scanThreads/perfRu.csv @@ -0,0 +1,7 @@ +key,value,type +cacheMiss,12491377,U64 +cacheRefs,35327177,U64 +cpuClock,2478812100,U64 +cpuCycle,9889422467,U64 +instructions,16997458033,U64 +taskClock,2478813000,U64 diff --git a/benchmark/src/Benchmark.cpp b/benchmark/src/Benchmark.cpp index dc81374a..064e46b0 100644 --- a/benchmark/src/Benchmark.cpp +++ b/benchmark/src/Benchmark.cpp @@ -61,26 +61,24 @@ void runSingleThreadTest(std::string configName) { auto A = torch::rand({(long) aRow, (long) aCol}); auto B = torch::rand({(long) aCol, (long) bCol});*/ INTELLI_INFO("Generation done, conducting..."); - uint64_t threads=cfg->tryU64("threads", 0, true); + uint64_t threads = cfg->tryU64("threads", 0, true); ThreadPerf pef(-1); pef.setPerfList(); AMMBench::BlockPartitionRunner br; - if(threads>1) - { + if (threads > 1) { INTELLI_WARNING("use multithread"); br.setConfig(cfg); - br.createABC(A,B); + br.createABC(A, B); if (eMeter != nullptr) { eMeter->startMeter(); } pef.start(); - auto c= br.parallelForward(); + auto c = br.parallelForward(); pef.end(); if (eMeter != nullptr) { eMeter->stopMeter(); } - } - else{ + } else { INTELLI_WARNING("single thread"); if (eMeter != nullptr) { eMeter->startMeter(); @@ -105,9 +103,9 @@ auto B = torch::rand({(long) aCol, (long) bCol});*/ resultCsv->edit("energyAll", (double) energyConsumption); resultCsv->edit("energyOnlyMe", (double) pureEnergy); } - if(threads>1) - { INTELLI_WARNING("consider multithread elapsed time"); - resultCsv->edit("perfElapsedTime", (uint64_t)br.getElapsedTime()); + if (threads > 1) { + INTELLI_WARNING("consider multithread elapsed time"); + resultCsv->edit("perfElapsedTime", (uint64_t) br.getElapsedTime()); } resultCsv->toFile(ruName + ".csv"); INTELLI_INFO("Done. here is result"); diff --git a/benchmark/torchscripts/BernoulliCRS.py b/benchmark/torchscripts/BernoulliCRS.py index 25b5859a..7ca14f21 100644 --- a/benchmark/torchscripts/BernoulliCRS.py +++ b/benchmark/torchscripts/BernoulliCRS.py @@ -1,66 +1,68 @@ import torch -import time +import time import os + def get_first_element(tensor): - if tensor.numel() == 1: - return tensor.item() - else: - return tensor[0].item() - + if tensor.numel() == 1: + return tensor.item() + else: + return tensor[0].item() + + def is_empty_tensor(tensor): - return tensor.numel() == 0 + return tensor.numel() == 0 + @torch.jit.script def BernoulliCRS(A: torch.Tensor, B: torch.Tensor, k: int): - # Get the dimension of A - A = A.t() - n, m = A.shape - - assert n == B.shape[0] - assert k < n - - # probability distribution - sample = torch.rand(n) # default: uniform - sample = torch.div(sample, sample.sum() / k) # sum = k as per the paper - - # diagonal scaling matrix P (nxn) - P = torch.diag(1.0 / torch.sqrt(sample)) - - # random diagonal sampling matrix K (nxn) - sample = (torch.rand(n) < sample).float() - K = torch.diag(sample) - - a = torch.matmul(torch.matmul(A.t(), P), K) - b = torch.matmul(torch.matmul(a, K), P) - - return torch.matmul(b, B) + # Get the dimension of A + A = A.t() + n, m = A.shape + + assert n == B.shape[0] + assert k < n + + # probability distribution + sample = torch.rand(n) # default: uniform + sample = torch.div(sample, sample.sum() / k) # sum = k as per the paper + + # diagonal scaling matrix P (nxn) + P = torch.diag(1.0 / torch.sqrt(sample)) + + # random diagonal sampling matrix K (nxn) + sample = (torch.rand(n) < sample).float() + K = torch.diag(sample) + + a = torch.matmul(torch.matmul(A.t(), P), K) + b = torch.matmul(torch.matmul(a, K), P) + + return torch.matmul(b, B) def main(): - - width = 1000 - A = torch.rand(2000, width) - B = torch.rand(width, 2000) - - t = time.time() - - aResult = BernoulliCRS(A, B, 500) - 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) - - print("\nerror: " + str(torch.norm(aResult - eResult, p='fro').item())) - - script = BernoulliCRS.save("BernoulliCRS.pt") + width = 1000 + A = torch.rand(2000, width) + B = torch.rand(width, 2000) + + t = time.time() + + aResult = BernoulliCRS(A, B, 500) + 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) + + print("\nerror: " + str(torch.norm(aResult - eResult, p='fro').item())) + + script = BernoulliCRS.save("BernoulliCRS.pt") + if __name__ == '__main__': - main() - \ No newline at end of file + main() diff --git a/benchmark/torchscripts/ColumnRowSampling.py b/benchmark/torchscripts/ColumnRowSampling.py index 9e7d57c3..2a7b19aa 100644 --- a/benchmark/torchscripts/ColumnRowSampling.py +++ b/benchmark/torchscripts/ColumnRowSampling.py @@ -3,68 +3,69 @@ import os import math + def get_first_element(tensor): - if tensor.numel() == 1: - return tensor.item() - else: - return tensor[0].item() - + if tensor.numel() == 1: + return tensor.item() + else: + return tensor[0].item() + + def is_empty_tensor(tensor): - return tensor.numel() == 0 + return tensor.numel() == 0 + @torch.jit.script def CRS(A: torch.Tensor, B: torch.Tensor, k: int): - # Get the dimension of A - A = A.t() - n, m = A.shape - - assert n == B.shape[0] - assert k < n - - # probability distribution - probs = torch.ones(n) / n # default: uniform - - # sample k indices from range 0 to n for given probability distribution - indices = torch.multinomial(probs, k, replacement=True) - - # Sample k columns from A - A_sampled = A[indices, :] - ratio = math.ceil(n / k) - A_sampled = torch.div((A_sampled / k).t(), probs[::ratio]) - - # Sample k rows from B - B_sampled = B[indices, :] - - # Compute the matrix product - result = A_sampled.matmul(B_sampled) - return result + # Get the dimension of A + A = A.t() + n, m = A.shape + + assert n == B.shape[0] + assert k < n + + # probability distribution + probs = torch.ones(n) / n # default: uniform + + # sample k indices from range 0 to n for given probability distribution + indices = torch.multinomial(probs, k, replacement=True) + + # Sample k columns from A + A_sampled = A[indices, :] + ratio = math.ceil(n / k) + A_sampled = torch.div((A_sampled / k).t(), probs[::ratio]) + + # Sample k rows from B + B_sampled = B[indices, :] + + # Compute the matrix product + result = A_sampled.matmul(B_sampled) + return result def main(): - - width = 2000 - A = torch.rand(5000, width) - B = torch.rand(width, 5000) - - - t = time.time() - - aResult = CRS(A, B, 500) - 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) - - print("\nerror: " + str(torch.norm(aResult - eResult, p='fro').item())) - - FDAMM_script = CRS.save("CRS.pt") + width = 2000 + A = torch.rand(5000, width) + B = torch.rand(width, 5000) + + t = time.time() + + aResult = CRS(A, B, 500) + 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) + + print("\nerror: " + str(torch.norm(aResult - eResult, p='fro').item())) + + FDAMM_script = CRS.save("CRS.pt") + if __name__ == '__main__': - main() - \ No newline at end of file + main() diff --git a/benchmark/torchscripts/ColumnRowSamplingVer2.py b/benchmark/torchscripts/ColumnRowSamplingVer2.py index ef67b4e2..c15a83b3 100644 --- a/benchmark/torchscripts/ColumnRowSamplingVer2.py +++ b/benchmark/torchscripts/ColumnRowSamplingVer2.py @@ -1,71 +1,71 @@ import torch -import time +import time import os + def get_first_element(tensor): - if tensor.numel() == 1: - return tensor.item() - else: - return tensor[0].item() - + if tensor.numel() == 1: + return tensor.item() + else: + return tensor[0].item() + + def is_empty_tensor(tensor): - return tensor.numel() == 0 + return tensor.numel() == 0 + @torch.jit.script def CRS(A: torch.Tensor, B: torch.Tensor, k: int): - # Get the dimension of A - A = A.t() - n, m = A.shape - - assert n == B.shape[0] - assert k < n - - # probability distribution - # dist = torch.distributions.Uniform(0, 1) - sample = torch.rand(n) # default: uniform - - # diagonal scaling matrix D (nxn) - sample = torch.div(sample, sample.sum()) - D = torch.diag(1.0 / torch.sqrt(k * sample)) - - # sampling matrix S (kxn) - column_indices = torch.multinomial(sample, k, replacement=True) - S = torch.zeros(k, n) - for row, col in enumerate(column_indices): - S[row, col] = 1 - - a = torch.matmul(torch.matmul(A.t(), D), S.t()) - b = torch.matmul(torch.matmul(a, S), D) - - - return torch.matmul(b, B) + # Get the dimension of A + A = A.t() + n, m = A.shape + + assert n == B.shape[0] + assert k < n + + # probability distribution + # dist = torch.distributions.Uniform(0, 1) + sample = torch.rand(n) # default: uniform + + # diagonal scaling matrix D (nxn) + sample = torch.div(sample, sample.sum()) + D = torch.diag(1.0 / torch.sqrt(k * sample)) + + # sampling matrix S (kxn) + column_indices = torch.multinomial(sample, k, replacement=True) + S = torch.zeros(k, n) + for row, col in enumerate(column_indices): + S[row, col] = 1 + + a = torch.matmul(torch.matmul(A.t(), D), S.t()) + b = torch.matmul(torch.matmul(a, S), D) + + return torch.matmul(b, B) def main(): - - - width = 2000 - A = torch.rand(1000, width) - B = torch.rand(width, 1000) - - t = time.time() - - aResult = CRS(A, B, 500) - 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) - - print("\nerror: " + str(torch.norm(aResult - eResult, p='fro').item())) - - script = CRS.save("CRSV2.pt") + width = 2000 + A = torch.rand(1000, width) + B = torch.rand(width, 1000) + + t = time.time() + + aResult = CRS(A, B, 500) + 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) + + print("\nerror: " + str(torch.norm(aResult - eResult, p='fro').item())) + + script = CRS.save("CRSV2.pt") + if __name__ == '__main__': - main() - \ No newline at end of file + main() diff --git a/benchmark/torchscripts/E2E_Minist.py b/benchmark/torchscripts/E2E_Minist.py index 3f3da3d8..234b5f45 100644 --- a/benchmark/torchscripts/E2E_Minist.py +++ b/benchmark/torchscripts/E2E_Minist.py @@ -5,15 +5,18 @@ import torchvision.transforms as transforms import os import CoOccurringFD + + # Define your custom matrix multiplication function def my_matmul(x, y): - rows,cols=x.shape - if cols>20: - sketchSize=cols/10 + rows, cols = x.shape + if cols > 20: + sketchSize = cols / 10 else: - sketchSize=10 + sketchSize = 10 # Your implementation here - return CoOccurringFD.FDAMM(x,y,int(sketchSize)) + return CoOccurringFD.FDAMM(x, y, int(sketchSize)) + # Define a custom Linear layer that uses your custom matrix multiplication function class CustomLinear(nn.Module): @@ -27,9 +30,11 @@ def __init__(self, in_features, out_features, bias=True): else: self.register_parameter('bias', None) self.reset_parameters() - def mySqrt(self,a:float): + + def mySqrt(self, a: float): y = torch.sqrt(torch.tensor(a, dtype=torch.float32)) return y.item() + def reset_parameters(self): nn.init.kaiming_uniform_(self.weight, a=self.mySqrt(5.0)) if self.bias is not None: @@ -44,6 +49,7 @@ def forward(self, input): output += self.bias return output + # Define your neural network architecture class MyNet(nn.Module): def __init__(self): @@ -51,36 +57,41 @@ def __init__(self): self.fc1 = nn.Linear(784, 128) self.fc2 = nn.Linear(128, 128) self.fc3 = nn.Linear(128, 10) + def forward(self, x): x = x.view(-1, 784) x = nn.functional.relu(self.fc1(x)) x = self.fc2(x) x = nn.functional.relu(self.fc3(x)) return x -def testNN(net,test_loader): - #first, load parameters - pretrained_params = torch.load('pretrained_model.pt') - custom_params = net.state_dict() - - for name in custom_params: - if name in pretrained_params: - custom_params[name] = pretrained_params[name] - net.load_state_dict(custom_params) - correct = 0 - total = 0 - #then, run test - net2=net - for data in test_loader: - images, labels = data - outputs = net2(images) - _, predicted = torch.max(outputs.data, 1) - total += labels.size(0) - correct += (predicted == labels).sum().item() - print(f"Accuracy on test set: {correct / total}") + + +def testNN(net, test_loader): + # first, load parameters + pretrained_params = torch.load('pretrained_model.pt') + custom_params = net.state_dict() + + for name in custom_params: + if name in pretrained_params: + custom_params[name] = pretrained_params[name] + net.load_state_dict(custom_params) + correct = 0 + total = 0 + # then, run test + net2 = net + for data in test_loader: + images, labels = data + outputs = net2(images) + _, predicted = torch.max(outputs.data, 1) + total += labels.size(0) + correct += (predicted == labels).sum().item() print(f"Accuracy on test set: {correct / total}") - return correct / total + print(f"Accuracy on test set: {correct / total}") + return correct / total + + def main(): - device='cuda' + device = 'cuda' # Load the MNIST dataset train_dataset = datasets.MNIST(root='./data', train=True, transform=transforms.ToTensor(), download=True) test_dataset = datasets.MNIST(root='./data', train=False, transform=transforms.ToTensor()) @@ -96,51 +107,48 @@ def main(): if os.path.exists('pretrained_model.pt'): print('find pretrained model, run test') print('first run default version') - accuracy0=testNN(net,test_loader) + accuracy0 = testNN(net, test_loader) print('then run coocuuring 1 version') # Replace the Linear layers with your custom Linear layers and load the pre-trained weights net.fc1 = CustomLinear(784, 128) - accuracy1=testNN(net,test_loader) + accuracy1 = testNN(net, test_loader) print('next run coocuuring 2 version') - net.fc1=nn.Linear(784,128) + net.fc1 = nn.Linear(784, 128) net.fc2 = CustomLinear(128, 128) - accuracy2=testNN(net,test_loader) + accuracy2 = testNN(net, test_loader) print('finally run coocuuring 3 version') net.fc2 = nn.Linear(128, 128) net.fc3 = CustomLinear(128, 10) - accuracy3=testNN(net,test_loader) - print('default accuracy=',accuracy0) - print('co-occuring 1 accuracy=',accuracy1) - print('co-occuring 2 accuracy=',accuracy2) - print('co-occuring 3 accuracy=',accuracy3) - - + accuracy3 = testNN(net, test_loader) + print('default accuracy=', accuracy0) + print('co-occuring 1 accuracy=', accuracy1) + print('co-occuring 2 accuracy=', accuracy2) + print('co-occuring 3 accuracy=', accuracy3) + + else: print('build pretrain model first') criterion = nn.CrossEntropyLoss() optimizer = optim.SGD(net.parameters(), lr=0.1) - net=net.to(device) + net = net.to(device) for epoch in range(10): running_loss = 0.0 for i, data in enumerate(train_loader, 0): inputs, labels = data - inputs=inputs.to(device) - labels=labels.to(device) + inputs = inputs.to(device) + labels = labels.to(device) optimizer.zero_grad() outputs = net(inputs) loss = criterion(outputs, labels) loss.backward() optimizer.step() running_loss += loss.item() - print(f"Epoch {epoch+1}: loss = {running_loss / len(train_loader)}") - net=net.to('cpu') + print(f"Epoch {epoch + 1}: loss = {running_loss / len(train_loader)}") + net = net.to('cpu') # Save the pre-trained model torch.save(net.state_dict(), 'pretrained_model.pt') - - - # Evaluate if __name__ == '__main__': - main() \ No newline at end of file + main() diff --git a/benchmark/torchscripts/ElementWiseSampling.py b/benchmark/torchscripts/ElementWiseSampling.py index 32724758..0b2c1965 100644 --- a/benchmark/torchscripts/ElementWiseSampling.py +++ b/benchmark/torchscripts/ElementWiseSampling.py @@ -3,61 +3,59 @@ import os import math + @torch.jit.script def EWS(A: torch.Tensor, B: torch.Tensor, k: int): - # Get the dimension of A - m, n = A.shape - - assert n == B.shape[0] - assert k < n - - p = B.shape[1] - - # probability distribution - probs = torch.rand(m, n) - - # S matrix that samples A with scaling - mask = torch.rand_like(probs) < probs - S = torch.zeros_like(A) - S[mask] = A[mask] / probs[mask] - - # R matrix that samples B with scaling - probs = torch.rand(n, p) # a diffrent probabilistic distribution - mask = torch.rand_like(probs) < probs - R = torch.zeros_like(B) - R[mask] = B[mask] / probs[mask] - - return torch.matmul(S, R) + # Get the dimension of A + m, n = A.shape + + assert n == B.shape[0] + assert k < n + + p = B.shape[1] + + # probability distribution + probs = torch.rand(m, n) + + # S matrix that samples A with scaling + mask = torch.rand_like(probs) < probs + S = torch.zeros_like(A) + S[mask] = A[mask] / probs[mask] + + # R matrix that samples B with scaling + probs = torch.rand(n, p) # a diffrent probabilistic distribution + mask = torch.rand_like(probs) < probs + R = torch.zeros_like(B) + R[mask] = B[mask] / probs[mask] + + return torch.matmul(S, R) def main(): - - width = 2000 - A = torch.rand(5000, width) - B = torch.rand(width, 5000) - - - t = time.time() - - aResult = EWS(A, B, 500) - 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())) - - FDAMM_script = EWS.save("EWS.pt") + width = 2000 + A = torch.rand(5000, width) + B = torch.rand(width, 5000) + + t = time.time() + + aResult = EWS(A, B, 500) + 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())) + + FDAMM_script = EWS.save("EWS.pt") + if __name__ == '__main__': - main() - \ No newline at end of file + main() diff --git a/benchmark/torchscripts/WeightedCR.py b/benchmark/torchscripts/WeightedCR.py index e0a869b6..8be1a0db 100644 --- a/benchmark/torchscripts/WeightedCR.py +++ b/benchmark/torchscripts/WeightedCR.py @@ -1,6 +1,7 @@ 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 @@ -16,29 +17,29 @@ def CR(A: torch.Tensor, B: torch.Tensor, c: int) -> torch.Tensor: 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[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 - + S[int(index.item())][trial] = 1 + # D - D = torch.diag(1/torch.sqrt(c*probability_distribution[sample_indices])) + 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 @@ -57,11 +58,11 @@ def weighted_CR(A: torch.Tensor, B: torch.Tensor, c: int): 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[i] = torch.norm(A.T[i], p='fro') * torch.norm(B[i], p='fro') probability_distribution /= probability_distribution.sum() # S @@ -71,17 +72,17 @@ def weighted_CR(A: torch.Tensor, B: torch.Tensor, c: int): S = torch.zeros((n, len(unique_indices))) for trial, index in enumerate(unique_indices): - S[int(index.item())][trial]=1 + S[int(index.item())][trial] = 1 # D - D = torch.diag(torch.sqrt(occurences)/torch.sqrt(c*probability_distribution[unique_indices])) + 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 @@ -89,25 +90,26 @@ 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')) + 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')) - + 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/commit_info b/commit_info index a67a9773..41cad1f1 100644 --- a/commit_info +++ b/commit_info @@ -1 +1,2 @@ -1. TRY PARALLELIZATION (NOT COMPLETE) +1. experimental support of parallelization +2. example scripts at benchmark/scripts/scanThreads diff --git a/include/Parallelization/BlockPartitionRunner.h b/include/Parallelization/BlockPartitionRunner.h index 029fd4d6..eb9a5edf 100644 --- a/include/Parallelization/BlockPartitionRunner.h +++ b/include/Parallelization/BlockPartitionRunner.h @@ -20,52 +20,57 @@ typedef std::shared_ptr TensorPtr; * @{ * @defgroup PARTITION_RUNNER The partition-based parallelization */ - /** - * @class BlockPartitionWorker Parallelization/BlockPartitionRunner.h - * @ingroup PARTITION_RUNNER - * @brief The basic partition worker - */ - class BlockPartitionWorker:public INTELLI::AbstractC20Thread{ +/** + * @class BlockPartitionWorker Parallelization/BlockPartitionRunner.h + * @ingroup PARTITION_RUNNER + * @brief The basic partition worker + */ +class BlockPartitionWorker : public INTELLI::AbstractC20Thread { protected: - virtual void inlineMain(); - struct timeval tstart, tend; + virtual void inlineMain(); + struct timeval tstart, tend; /** * @brief Input matrix A */ - TensorPtr matA= nullptr; // Input matrix A + TensorPtr matA = nullptr; // Input matrix A /** * @brief Input matrix B */ - TensorPtr matB=nullptr; // Input matrix B + TensorPtr matB = nullptr; // Input matrix B /** * @brief OUTput matrix C */ - TensorPtr matC=nullptr; // Output matrix C + TensorPtr matC = nullptr; // Output matrix C INTELLI::ConfigMapPtr cfg; torch::jit::script::Module module; - uint64_t sketchDimension=0; + uint64_t sketchDimension = 0; int coreBind; public: - torch::Tensor irC,subA; - uint64_t startRow=0; // Start row index for the assigned range - uint64_t endRow=0; // End row index (exclusive) for the assigned range + torch::Tensor irC, subA; + uint64_t startRow = 0; // Start row index for the assigned range + uint64_t endRow = 0; // End row index (exclusive) for the assigned range - BlockPartitionWorker(){ + BlockPartitionWorker() { } - /** - * @brief set the config map - * @param _cfg - */ + /** + * @brief set the config map + * @param _cfg + */ void setConfig(INTELLI::ConfigMapPtr _cfg); /** - * @brief set the pointer to A,B matrix + * @brief set the pointer to A,B,C matrix */ - void setAB(TensorPtr A,TensorPtr B); - void setWorkParameters(uint64_t aStart,uint64_t aEnd,int mycore); - ~BlockPartitionWorker() - { + void setABC(TensorPtr A, TensorPtr B, TensorPtr C); + /** + * @brief set work parmeters + * @param aStart The start row in A + * @param aEnd The end row in A + * @param mycore the core to be binded + */ + void setWorkParameters(uint64_t aStart, uint64_t aEnd, int mycore); + ~BlockPartitionWorker() { } uint64_t getElapsedTime(); @@ -81,57 +86,69 @@ typedef std::shared_ptr BlockPartitionWorkerPtr; /** * @class BlockPartitionRunner Parallelization/BlockPartitionRunner.h * @ingroup PARTITION_RUNNER - * @brief The top entity to control all workers, see also @ref BlockPartitionWorker + * @brief The top entity to control all workers, see also @ref BlockPartitionWorker. This one works under a + * simple row partition parallelization * @note parameters * - threads, U64, the number of worker threads, default 2 - * + * @note default behaviors + * - create + * - call @ref setConfig + * - call @ref runAMM and return result + * - call @ref getElapsedTime */ class BlockPartitionRunner { protected: INTELLI::ConfigMapPtr cfg; - uint64_t threads=0; + uint64_t threads = 0; /** * @brief Input matrix A */ - TensorPtr matA=nullptr; // Input matrix A + TensorPtr matA = nullptr; // Input matrix A /** * @brief Input matrix B */ - TensorPtr matB=nullptr; // Input matrix B + TensorPtr matB = nullptr; // Input matrix B /** * @brief OUTput matrix C */ - TensorPtr matC=nullptr; // Output matrix C + TensorPtr matC = nullptr; // Output matrix C std::vector workers; - public:BlockPartitionRunner(){} - ~BlockPartitionRunner(){} - /** - * @brief set the config map - * @param _cfg - */ - void setConfig(INTELLI::ConfigMapPtr _cfg); - /** - * @brief create the A,B,C matrix and pass it to all workers - * @param A The A matrix - * @param B The B matrix - * @warnning call after @ref setConfig + public: + BlockPartitionRunner() {} + ~BlockPartitionRunner() {} + /** + * @brief set the config map + * @param _cfg + */ + void setConfig(INTELLI::ConfigMapPtr _cfg); + /** + * @brief create the A,B,C matrix and pass it to all workers + * @param A The A matrix + * @param B The B matrix + * @warnning call after @ref setConfig + */ + void createABC(torch::Tensor A, torch::Tensor B); + + /** +* @brief run a parallel forward of A,B, and return C +* @return C=matA*matB +* @warnning call after @ref createABC +*/ + torch::Tensor parallelForward(); + /** + * @brief conducte the multithread AMM and return + * @param A The A matrix + * @param B The B matrix + * @return The AMM(A,B) + * @warnning call after @ref setConfig */ - void createABC(torch::Tensor A,torch::Tensor B); + torch::Tensor runAMM(torch::Tensor A, torch::Tensor B); /** - * @brief conducte the multithread AMM and return - * @param A The A matrix - * @param B The B matrix - * @return The AMM(A,B) - * @warnning call after @ref setConfig + * @brief get the elapsed time of multithread running + * @return the elapsed time + * @note Exclude the overhead of cleaning thread states such as loaded module */ - /** - * @brief run a parallel forward of A,B, and return C - * @return C=matA*matB - * @warnning call after @ref createABC - */ - torch::Tensor parallelForward(); - torch::Tensor runAMM(torch::Tensor A,torch::Tensor B); uint64_t getElapsedTime(); }; diff --git a/src/Parallelization/BlockPartitionRunner.cpp b/src/Parallelization/BlockPartitionRunner.cpp index 92b7ea68..4b46d206 100644 --- a/src/Parallelization/BlockPartitionRunner.cpp +++ b/src/Parallelization/BlockPartitionRunner.cpp @@ -4,23 +4,24 @@ #include #include -void AMMBench::BlockPartitionWorker::setConfig(INTELLI::ConfigMapPtr _cfg) -{ +void AMMBench::BlockPartitionWorker::setConfig(INTELLI::ConfigMapPtr _cfg) { cfg = _cfg; sketchDimension = cfg->tryU64("sketchDimension", 50, true); std::string ptFile = cfg->tryString("ptFile", "torchscripts/FDAMM.pt", true); module = torch::jit::load(ptFile); } -void AMMBench::BlockPartitionWorker::setWorkParameters(uint64_t aStart,uint64_t aEnd,int mycore){ - startRow=aStart; - endRow=aEnd; - coreBind=mycore; +void AMMBench::BlockPartitionWorker::setWorkParameters(uint64_t aStart, uint64_t aEnd, int mycore) { + startRow = aStart; + endRow = aEnd; + coreBind = mycore; //matC=newTensor(torch::zeros({(long)(endRow+1-startRow),matB->size(1)})); subA = matA->slice(0, startRow, endRow); + } -void AMMBench::BlockPartitionWorker::setAB(AMMBench::TensorPtr A, AMMBench::TensorPtr B) { - matA=newTensor(*A); - matB=newTensor(*B);; +void AMMBench::BlockPartitionWorker::setABC(AMMBench::TensorPtr A, AMMBench::TensorPtr B, AMMBench::TensorPtr C) { + matA = newTensor(*A); + matB = newTensor(*B);; + matC = C; //assert(C); } void AMMBench::BlockPartitionWorker::inlineMain() { @@ -30,7 +31,7 @@ void AMMBench::BlockPartitionWorker::inlineMain() { */ // Perform matrix multiplication for the assigned rows INTELLI::UtilityFunctions::bind2Core((int) coreBind); - //torch::set_num_threads(1); + torch::set_num_threads(1); /** * @brief 2. multiply sub-matrix of A */ @@ -39,68 +40,62 @@ void AMMBench::BlockPartitionWorker::inlineMain() { //torch::Tensor subC = module.forward({subA, *matB, (long) sketchDimension}).toTensor(); // Copy the results back to the output matrix C //matC->slice(0, startRow, endRow) = subC; - irC=module.forward({subA, *matB, (long) sketchDimension}).toTensor(); + + //irC=module.forward({subA, *matB, (long) sketchDimension}).toTensor(); + matC->slice(0, startRow, endRow) =module.forward({subA, *matB, (long) sketchDimension}).toTensor(); gettimeofday(&tend, NULL); //std::cout<tryU64("threads", 2, true); - workers=std::vector(threads); - for(uint64_t i=0;itryU64("threads", 2, true); + workers = std::vector(threads); + for (uint64_t i = 0; i < threads; i++) { + workers[i] = newBlockPartitionWorker(); workers[i]->setConfig(cfg); } - INTELLI_INFO("set up "+ to_string(threads)+"workers."); + INTELLI_INFO("set up " + to_string(threads) + "workers."); } -void AMMBench::BlockPartitionRunner::createABC(torch::Tensor A, torch::Tensor B) { +void AMMBench::BlockPartitionRunner::createABC(torch::Tensor A, torch::Tensor B) { - matA=newTensor(A); - matB=newTensor(B); - matC=newTensor(torch::zeros({A.size(0), B.size(1)})); - for(uint64_t i=0;isetAB(matA,matB); - workers[i]->setWorkParameters(start_row,end_row,i); + uint64_t end_row = (i == threads - 1) ? A.size(0) : start_row + rows_per_worker; + workers[i]->setABC(matA, matB, matC); + workers[i]->setWorkParameters(start_row, end_row, i); } } torch::Tensor AMMBench::BlockPartitionRunner::parallelForward() { - for(uint64_t i=0;istartThread(); } - INTELLI_INFO("start "+ to_string(threads)+"workers."); - for(uint64_t i=0;ijoinThread(); } - for(uint64_t i=0;islice(0, workers[i]->startRow, workers[i]->endRow) = workers[i]->irC; - } + /* for(uint64_t i=0;islice(0, workers[i]->startRow, workers[i]->endRow) = workers[i]->irC; + }*/ return *matC; } -torch::Tensor AMMBench::BlockPartitionRunner::runAMM(torch::Tensor A,torch::Tensor B) -{ - createABC(A,B); +torch::Tensor AMMBench::BlockPartitionRunner::runAMM(torch::Tensor A, torch::Tensor B) { + createABC(A, B); return parallelForward(); } -uint64_t AMMBench::BlockPartitionRunner::getElapsedTime() { - uint64_t maxTime=0; - uint64_t ti=0; - for(uint64_t i=0;igetElapsedTime(); - if(ti>maxTime) - { - maxTime=ti; - } +uint64_t AMMBench::BlockPartitionRunner::getElapsedTime() { + //uint64_t maxTime=workers[0]->getElapsedTime(); + uint64_t ti = 0; + for (uint64_t i = 0; i < threads; i++) { + ti += workers[i]->getElapsedTime(); + } - return maxTime; + return ti / threads; } \ No newline at end of file diff --git a/src/Parallelization/CMakeLists.txt b/src/Parallelization/CMakeLists.txt index eafe2cb6..0c046607 100644 --- a/src/Parallelization/CMakeLists.txt +++ b/src/Parallelization/CMakeLists.txt @@ -1,3 +1,3 @@ add_sources( - BlockPartitionRunner.cpp + BlockPartitionRunner.cpp ) \ No newline at end of file diff --git a/src/Utils/UtilityFunctions.cpp b/src/Utils/UtilityFunctions.cpp index 7f9bbc2b..816c1716 100755 --- a/src/Utils/UtilityFunctions.cpp +++ b/src/Utils/UtilityFunctions.cpp @@ -66,7 +66,7 @@ vector INTELLI::UtilityFunctions::weightedPartitionSizeFinal(size_t inS, return partitionSizeFinals; } -size_t INTELLI::UtilityFunctions::timeLast(struct timeval ts,struct timeval te) { +size_t INTELLI::UtilityFunctions::timeLast(struct timeval ts, struct timeval te) { int64_t s0, e0, s1, e1; s0 = ts.tv_sec; s1 = ts.tv_usec; diff --git a/test/SystemTest/BlockPartitionTest.cpp b/test/SystemTest/BlockPartitionTest.cpp index 60e35c43..64edf7f8 100644 --- a/test/SystemTest/BlockPartitionTest.cpp +++ b/test/SystemTest/BlockPartitionTest.cpp @@ -54,19 +54,19 @@ TEST_CASE("Test the parallelization, thread=2", "[short]") { int a = 0; ConfigMapPtr cfg = newConfigMap(); - cfg->edit("ptFile","torchscripts/RAWMM.pt"); - cfg->edit("threads",(uint64_t)2); + cfg->edit("ptFile", "torchscripts/RAWMM.pt"); + cfg->edit("threads", (uint64_t) 2); torch::manual_seed(114514); auto A = torch::rand({(long) 4, (long) 4}); auto B = torch::rand({(long) 4, (long) 4}); AMMBench::BlockPartitionRunner br; br.setConfig(cfg); - auto C1=br.runAMM(A,B); - auto C2=torch::matmul(A,B); - std::cout<<"parallel MM"<20: - sketchSize=cols/10 + rows, cols = x.shape + if cols > 20: + sketchSize = cols / 10 else: - sketchSize=10 + sketchSize = 10 # Your implementation here - return CoOccurringFD.FDAMM(x,y,int(sketchSize)) + return CoOccurringFD.FDAMM(x, y, int(sketchSize)) + # Define a custom Linear layer that uses your custom matrix multiplication function class CustomLinear(nn.Module): @@ -27,9 +30,11 @@ def __init__(self, in_features, out_features, bias=True): else: self.register_parameter('bias', None) self.reset_parameters() - def mySqrt(self,a:float): + + def mySqrt(self, a: float): y = torch.sqrt(torch.tensor(a, dtype=torch.float32)) return y.item() + def reset_parameters(self): nn.init.kaiming_uniform_(self.weight, a=self.mySqrt(5.0)) if self.bias is not None: @@ -44,6 +49,7 @@ def forward(self, input): output += self.bias return output + # Define your neural network architecture class MyNet(nn.Module): def __init__(self): @@ -51,36 +57,41 @@ def __init__(self): self.fc1 = nn.Linear(784, 128) self.fc2 = nn.Linear(128, 128) self.fc3 = nn.Linear(128, 10) + def forward(self, x): x = x.view(-1, 784) x = nn.functional.relu(self.fc1(x)) x = self.fc2(x) x = nn.functional.relu(self.fc3(x)) return x -def testNN(net,test_loader): - #first, load parameters - pretrained_params = torch.load('pretrained_model.pt') - custom_params = net.state_dict() - - for name in custom_params: - if name in pretrained_params: - custom_params[name] = pretrained_params[name] - net.load_state_dict(custom_params) - correct = 0 - total = 0 - #then, run test - net2=net - for data in test_loader: - images, labels = data - outputs = net2(images) - _, predicted = torch.max(outputs.data, 1) - total += labels.size(0) - correct += (predicted == labels).sum().item() - print(f"Accuracy on test set: {correct / total}") + + +def testNN(net, test_loader): + # first, load parameters + pretrained_params = torch.load('pretrained_model.pt') + custom_params = net.state_dict() + + for name in custom_params: + if name in pretrained_params: + custom_params[name] = pretrained_params[name] + net.load_state_dict(custom_params) + correct = 0 + total = 0 + # then, run test + net2 = net + for data in test_loader: + images, labels = data + outputs = net2(images) + _, predicted = torch.max(outputs.data, 1) + total += labels.size(0) + correct += (predicted == labels).sum().item() print(f"Accuracy on test set: {correct / total}") - return correct / total + print(f"Accuracy on test set: {correct / total}") + return correct / total + + def main(): - device='cuda' + device = 'cuda' # Load the MNIST dataset train_dataset = datasets.MNIST(root='./data', train=True, transform=transforms.ToTensor(), download=True) test_dataset = datasets.MNIST(root='./data', train=False, transform=transforms.ToTensor()) @@ -96,51 +107,48 @@ def main(): if os.path.exists('pretrained_model.pt'): print('find pretrained model, run test') print('first run default version') - accuracy0=testNN(net,test_loader) + accuracy0 = testNN(net, test_loader) print('then run coocuuring 1 version') # Replace the Linear layers with your custom Linear layers and load the pre-trained weights net.fc1 = CustomLinear(784, 128) - accuracy1=testNN(net,test_loader) + accuracy1 = testNN(net, test_loader) print('next run coocuuring 2 version') - net.fc1=nn.Linear(784,128) + net.fc1 = nn.Linear(784, 128) net.fc2 = CustomLinear(128, 128) - accuracy2=testNN(net,test_loader) + accuracy2 = testNN(net, test_loader) print('finally run coocuuring 3 version') net.fc2 = nn.Linear(128, 128) net.fc3 = CustomLinear(128, 10) - accuracy3=testNN(net,test_loader) - print('default accuracy=',accuracy0) - print('co-occuring 1 accuracy=',accuracy1) - print('co-occuring 2 accuracy=',accuracy2) - print('co-occuring 3 accuracy=',accuracy3) - - + accuracy3 = testNN(net, test_loader) + print('default accuracy=', accuracy0) + print('co-occuring 1 accuracy=', accuracy1) + print('co-occuring 2 accuracy=', accuracy2) + print('co-occuring 3 accuracy=', accuracy3) + + else: print('build pretrain model first') criterion = nn.CrossEntropyLoss() optimizer = optim.SGD(net.parameters(), lr=0.1) - net=net.to(device) + net = net.to(device) for epoch in range(10): running_loss = 0.0 for i, data in enumerate(train_loader, 0): inputs, labels = data - inputs=inputs.to(device) - labels=labels.to(device) + inputs = inputs.to(device) + labels = labels.to(device) optimizer.zero_grad() outputs = net(inputs) loss = criterion(outputs, labels) loss.backward() optimizer.step() running_loss += loss.item() - print(f"Epoch {epoch+1}: loss = {running_loss / len(train_loader)}") - net=net.to('cpu') + print(f"Epoch {epoch + 1}: loss = {running_loss / len(train_loader)}") + net = net.to('cpu') # Save the pre-trained model torch.save(net.state_dict(), 'pretrained_model.pt') - - - # Evaluate if __name__ == '__main__': - main() \ No newline at end of file + main() diff --git a/test/torchscripts/ElementWiseSampling.py b/test/torchscripts/ElementWiseSampling.py index 32724758..0b2c1965 100644 --- a/test/torchscripts/ElementWiseSampling.py +++ b/test/torchscripts/ElementWiseSampling.py @@ -3,61 +3,59 @@ import os import math + @torch.jit.script def EWS(A: torch.Tensor, B: torch.Tensor, k: int): - # Get the dimension of A - m, n = A.shape - - assert n == B.shape[0] - assert k < n - - p = B.shape[1] - - # probability distribution - probs = torch.rand(m, n) - - # S matrix that samples A with scaling - mask = torch.rand_like(probs) < probs - S = torch.zeros_like(A) - S[mask] = A[mask] / probs[mask] - - # R matrix that samples B with scaling - probs = torch.rand(n, p) # a diffrent probabilistic distribution - mask = torch.rand_like(probs) < probs - R = torch.zeros_like(B) - R[mask] = B[mask] / probs[mask] - - return torch.matmul(S, R) + # Get the dimension of A + m, n = A.shape + + assert n == B.shape[0] + assert k < n + + p = B.shape[1] + + # probability distribution + probs = torch.rand(m, n) + + # S matrix that samples A with scaling + mask = torch.rand_like(probs) < probs + S = torch.zeros_like(A) + S[mask] = A[mask] / probs[mask] + + # R matrix that samples B with scaling + probs = torch.rand(n, p) # a diffrent probabilistic distribution + mask = torch.rand_like(probs) < probs + R = torch.zeros_like(B) + R[mask] = B[mask] / probs[mask] + + return torch.matmul(S, R) def main(): - - width = 2000 - A = torch.rand(5000, width) - B = torch.rand(width, 5000) - - - t = time.time() - - aResult = EWS(A, B, 500) - 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())) - - FDAMM_script = EWS.save("EWS.pt") + width = 2000 + A = torch.rand(5000, width) + B = torch.rand(width, 5000) + + t = time.time() + + aResult = EWS(A, B, 500) + 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())) + + FDAMM_script = EWS.save("EWS.pt") + if __name__ == '__main__': - main() - \ No newline at end of file + main() diff --git a/test/torchscripts/WeightedCR.py b/test/torchscripts/WeightedCR.py index e0a869b6..8be1a0db 100644 --- a/test/torchscripts/WeightedCR.py +++ b/test/torchscripts/WeightedCR.py @@ -1,6 +1,7 @@ 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 @@ -16,29 +17,29 @@ def CR(A: torch.Tensor, B: torch.Tensor, c: int) -> torch.Tensor: 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[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 - + S[int(index.item())][trial] = 1 + # D - D = torch.diag(1/torch.sqrt(c*probability_distribution[sample_indices])) + 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 @@ -57,11 +58,11 @@ def weighted_CR(A: torch.Tensor, B: torch.Tensor, c: int): 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[i] = torch.norm(A.T[i], p='fro') * torch.norm(B[i], p='fro') probability_distribution /= probability_distribution.sum() # S @@ -71,17 +72,17 @@ def weighted_CR(A: torch.Tensor, B: torch.Tensor, c: int): S = torch.zeros((n, len(unique_indices))) for trial, index in enumerate(unique_indices): - S[int(index.item())][trial]=1 + S[int(index.item())][trial] = 1 # D - D = torch.diag(torch.sqrt(occurences)/torch.sqrt(c*probability_distribution[unique_indices])) + 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 @@ -89,25 +90,26 @@ 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')) + 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')) - + 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()