From c4cec0ed0d2ce47914ee21f9fa4dd458f4ebaa2d Mon Sep 17 00:00:00 2001 From: Turquet Date: Tue, 18 Jun 2019 11:17:33 +0200 Subject: [PATCH 01/10] Addition of a different heuristic for the recommemdation of 3D signals. --- sizeOptimizer.cpp | 161 +++++++++++++++++++++++++++++++++++++++------- sizeOptimizer.h | 12 ++++ 2 files changed, 149 insertions(+), 24 deletions(-) diff --git a/sizeOptimizer.cpp b/sizeOptimizer.cpp index 0670a96..12f09e6 100644 --- a/sizeOptimizer.cpp +++ b/sizeOptimizer.cpp @@ -1,4 +1,5 @@ #include "sizeOptimizer.h" +#include namespace cuFFTAdvisor { @@ -13,7 +14,7 @@ SizeOptimizer::SizeOptimizer(CudaVersion::CudaVersion version, log_5(1.0 / std::log(5)), log_7(1.0 / std::log(7)) { if (Tristate::BOTH == tr.isFloat) { - // if user is not sure if he/she needs double, then he/she doesn't need it + // if user is not sure if they needs double, then they doesn't need it tr.isFloat = Tristate::TRUE; } @@ -166,20 +167,32 @@ std::vector *SizeOptimizer::optimizeXYZ(GeneralTransform &tr, int maxPercIncrease, bool squareOnly, bool crop) { + + bool rank = (tr.Z != 1 && tr.Y != 1 && tr.X != 1); //rank define if it is a 3D signal or not std::vector *polysX = generatePolys(tr.X, tr.isFloat, crop); std::vector *polysY; std::vector *polysZ; - std::set *recPolysX = filterOptimal(polysX, crop); + std::set *recPolysX; std::set *recPolysY; std::set *recPolysZ; + if(!rank){ + recPolysX = filterOptimal(polysX, crop); + }else{ + polysX = cutN(polysX, nBest); + } + if ((tr.X == tr.Y) || (squareOnly && (tr.Y != 1))) { polysY = polysX; recPolysY = recPolysX; } else { polysY = generatePolys(tr.Y, tr.isFloat, crop); - recPolysY = filterOptimal(polysY, crop); + if(!rank){ + recPolysY = filterOptimal(polysY, crop); + }else{ + polysY = cutN(polysY, nBest); + } } if ((tr.X == tr.Z) @@ -191,43 +204,131 @@ std::vector *SizeOptimizer::optimizeXYZ(GeneralTransform &tr, recPolysZ = recPolysY; } else { polysZ = generatePolys(tr.Z, tr.isFloat, crop); - recPolysZ = filterOptimal(polysZ, crop); + if(!rank){ + recPolysZ = filterOptimal(polysZ, crop); + }else{ + polysZ = cutN(polysZ, nBest); + } } + size_t minSize = getMinSize(tr, maxPercIncrease, crop); size_t maxSize = getMaxSize(tr, maxPercIncrease, squareOnly, crop); std::vector *result = new std::vector; - size_t found = 0; - for (auto& x : *recPolysX) { - for (auto& y : *recPolysY) { - if (squareOnly && (x.value != y.value) && (y.value != 1)) continue; - size_t xy = x.value * y.value; - if (xy > maxSize) - break; // polynoms are sorted by size, we're already above the limit - for (auto& z : *recPolysZ) { - if (squareOnly && (x.value != z.value) && (z.value != 1)) continue; - size_t xyz = xy * z.value; - if ((found < nBest) && (xyz >= minSize) && (xyz <= maxSize)) { - // we can take nbest only, as others very probably won't be faster - found++; - GeneralTransform t((int)x.value, (int)y.value, (int)z.value, tr); - result->push_back(t); + if(!rank){ + size_t found = 0; + for (auto& x : *recPolysX) { + for (auto& y : *recPolysY) { + if (squareOnly && (x.value != y.value) && (y.value != 1)) continue; + size_t xy = x.value * y.value; + if (xy > maxSize) + break; // polynoms are sorted by size, we're already above the limit + for (auto& z : *recPolysZ) { + if (squareOnly && (x.value != z.value) && (z.value != 1)) continue; + size_t xyz = xy * z.value; + if ((found < nBest) && (xyz >= minSize) && (xyz <= maxSize)) { + // we can take nbest only, as others very probably won't be faster + found++; + GeneralTransform t((int)x.value, (int)y.value, (int)z.value, tr); + result->push_back(t); + } + } + } + } + }else{ + //Definition of the max performence possible + Polynom minimunX = polysX->at(0); + for (size_t i = 1; i < polysX->size(); i++) { + if(polysX->at(i).invocations == 1){ + minimunX = polysX->at(i); + break; + } + if(polysX->at(i).invocations < minimunX.invocations){ + minimunX = polysX->at(i); + } + } + + Polynom minimunY = polysY->at(0); + for (size_t i = 1; i < polysY->size(); i++) { + if(polysY->at(i).invocations == 1){ + minimunY = polysY->at(i); + break; + } + if(polysY->at(i).invocations < minimunY.invocations){ + minimunY = polysY->at(i); + } + } + + Polynom minimunZ = polysZ->at(0); + for (size_t i = 1; i < polysZ->size(); i++) { + if(polysZ->at(i).invocations == 1){ + minimunZ = polysZ->at(i); + break; + } + if(polysZ->at(i).invocations < minimunZ.invocations){ + minimunZ = polysZ->at(i); + } + } + + + Transform transfo = Transform(0, minimunX.value, minimunY.value, minimunZ.value, 1, Tristate::FALSE, + Tristate::TRUE, Tristate::BOTH, Tristate::FALSE, false); + float maxPerfTime = Benchmarker::benchmark(&transfo)->execTimeMS; + + //Add the less incovation less padding transformation + GeneralTransform t(minimunX.value, minimunY.value, minimunZ.value, tr); + + result->push_back(t); + + //Add the transformation with the less padding possible + size_t found = 0; + int i = 0; + for (Polynom x : *polysX) { + for (Polynom y : *polysY) { + if (squareOnly && (x.value != y.value) && (y.value != 1)) continue; + size_t xy = x.value * y.value; + if (xy > maxSize) + break; // polynoms are sorted by size, we're already above the limit + for (Polynom z : *polysZ) { + i++; + if (Benchmarker::benchmark(new Transform(0, x.value, y.value, z.value, 1, Tristate::FALSE, + Tristate::TRUE, Tristate::BOTH, Tristate::FALSE, false))->execTimeMS > maxPerfTime + && found > nBest){ + break; + } + if (squareOnly && (x.value != z.value) && (z.value != 1)) continue; + size_t xyz = xy * z.value; + if ((found < nBest) && (xyz >= minSize) && (xyz <= maxSize)) { + // we can take nbest only, as others very probably won't be faster + found++; + GeneralTransform t((int)x.value, (int)y.value, (int)z.value, tr); + + result->push_back(t); + + } } } } + } - if (polysZ != polysY) { + if ((polysZ != polysY) && (polysZ != polysX)) { delete polysZ; - delete recPolysZ; + if (!rank){ + delete recPolysZ; + } } if (polysY != polysX) { delete polysY; - delete recPolysY; + if (!rank){ + delete recPolysY; + } } delete polysX; - delete recPolysX; + if (!rank){ + delete recPolysX; + } return result; } @@ -316,6 +417,18 @@ std::vector *SizeOptimizer::generatePolys( return result; } +std::vector *SizeOptimizer::cutN(std::vector* polys, size_t nBest){ + //This function return the n smaller polynom of the vector + //It is use to limit the nomber of trqnsformation created + std::sort (polys->begin(), polys->end()); + if(polys->size() > nBest){ + while(polys->size() > nBest){ + polys->pop_back(); + } + } + return polys; +} + std::set *SizeOptimizer::filterOptimal(std::vector *input, bool crop) { @@ -338,7 +451,7 @@ std::set // update min kernel invocations needed minInv = tmp; } - if (closest.value > tmp.value) { + if (closest > tmp) { closest = tmp; } } diff --git a/sizeOptimizer.h b/sizeOptimizer.h index 2cdc536..9047bb0 100644 --- a/sizeOptimizer.h +++ b/sizeOptimizer.h @@ -5,6 +5,7 @@ #include #include #include +#include #include "benchmarker.h" #include "generalTransform.h" #include "transformGenerator.h" @@ -22,6 +23,16 @@ class SizeOptimizer { size_t exponent3; size_t exponent5; size_t exponent7; + + bool operator < (const Polynom& cmp) const + { + return (value < cmp.value); + } + + bool operator > (const Polynom& cmp) const + { + return (value > cmp.value); + } }; struct valueComparator { @@ -56,6 +67,7 @@ class SizeOptimizer { int getInvocations(Polynom &poly, bool isFloat); int getInvocationsV8(Polynom &poly, bool isFloat); + std::vector *cutN(std::vector* polys , size_t nBest); std::set *filterOptimal( std::vector *input, bool crop); std::vector *generatePolys(size_t num, bool isFloat, bool crop); From d571398280f759d663c78d84536cc9968e083d5a Mon Sep 17 00:00:00 2001 From: Turquet Date: Wed, 19 Jun 2019 10:02:09 +0200 Subject: [PATCH 02/10] Add the "rank" attribute to "GeneralTransform" and suppretion of the "rank" variable in sizeOptimizer --- generalTransform.cpp | 20 ++++++++++++++++++-- generalTransform.h | 9 +++++++++ sizeOptimizer.cpp | 15 +++++++-------- 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/generalTransform.cpp b/generalTransform.cpp index ee47051..eba67f3 100644 --- a/generalTransform.cpp +++ b/generalTransform.cpp @@ -17,7 +17,9 @@ GeneralTransform::GeneralTransform(int device, int X, int Y, int Z, int N, isFloat(isFloat), isForward(isForward), isInPlace(isInPlace), - isReal(isReal) {} + isReal(isReal) { + setRankInfo(); + } GeneralTransform::GeneralTransform(int X, int Y, int Z, const GeneralTransform &tr) @@ -30,7 +32,9 @@ GeneralTransform::GeneralTransform(int X, int Y, int Z, isFloat(tr.isFloat), isForward(tr.isForward), isInPlace(tr.isInPlace), - isReal(tr.isReal) {} + isReal(tr.isReal) { + setRankInfo(); + } GeneralTransform::GeneralTransform(const GeneralTransform &tr) { *this = tr; } @@ -46,8 +50,20 @@ GeneralTransform &GeneralTransform::operator=(const GeneralTransform &tr) { this->isForward = tr.isForward; this->isInPlace = tr.isInPlace; this->isReal = tr.isReal; + setRankInfo(); } return *this; } +void GeneralTransform::setRankInfo() { + rank = RANK_3D; + if (1 == Z) { + if (1 == Y) { + rank = RANK_1D; + } else { + rank = RANK_2D; + } + } +} + } // namespace cuFFTAdvisor diff --git a/generalTransform.h b/generalTransform.h index 9e5b913..ecb0a6f 100644 --- a/generalTransform.h +++ b/generalTransform.h @@ -7,6 +7,9 @@ namespace cuFFTAdvisor { class GeneralTransform { public: + + enum Rank { RANK_1D = 1, RANK_2D = 2, RANK_3D = 3 }; + GeneralTransform(int device, int X, int Y, int Z, int N, Tristate::Tristate isBatched, Tristate::Tristate isFloat, Tristate::Tristate isForward, Tristate::Tristate isInPlace, @@ -30,6 +33,12 @@ class GeneralTransform { Tristate::Tristate isForward; // otherwise inverse Tristate::Tristate isInPlace; // otherwise out-of-place Tristate::Tristate isReal; // otherwise C2C + Rank rank; + + /** + * Sets fields that describe rank (dimensionality) + */ + void setRankInfo(); }; } // namespace cuFFTAdvisor diff --git a/sizeOptimizer.cpp b/sizeOptimizer.cpp index 12f09e6..6fe5e9d 100644 --- a/sizeOptimizer.cpp +++ b/sizeOptimizer.cpp @@ -168,7 +168,6 @@ std::vector *SizeOptimizer::optimizeXYZ(GeneralTransform &tr, bool squareOnly, bool crop) { - bool rank = (tr.Z != 1 && tr.Y != 1 && tr.X != 1); //rank define if it is a 3D signal or not std::vector *polysX = generatePolys(tr.X, tr.isFloat, crop); std::vector *polysY; std::vector *polysZ; @@ -176,7 +175,7 @@ std::vector *SizeOptimizer::optimizeXYZ(GeneralTransform &tr, std::set *recPolysY; std::set *recPolysZ; - if(!rank){ + if(tr.rank != 3){ recPolysX = filterOptimal(polysX, crop); }else{ polysX = cutN(polysX, nBest); @@ -188,7 +187,7 @@ std::vector *SizeOptimizer::optimizeXYZ(GeneralTransform &tr, recPolysY = recPolysX; } else { polysY = generatePolys(tr.Y, tr.isFloat, crop); - if(!rank){ + if(tr.rank != 3){ recPolysY = filterOptimal(polysY, crop); }else{ polysY = cutN(polysY, nBest); @@ -204,7 +203,7 @@ std::vector *SizeOptimizer::optimizeXYZ(GeneralTransform &tr, recPolysZ = recPolysY; } else { polysZ = generatePolys(tr.Z, tr.isFloat, crop); - if(!rank){ + if(tr.rank != 3){ recPolysZ = filterOptimal(polysZ, crop); }else{ polysZ = cutN(polysZ, nBest); @@ -216,7 +215,7 @@ std::vector *SizeOptimizer::optimizeXYZ(GeneralTransform &tr, size_t maxSize = getMaxSize(tr, maxPercIncrease, squareOnly, crop); std::vector *result = new std::vector; - if(!rank){ + if(tr.rank != 3){ size_t found = 0; for (auto& x : *recPolysX) { for (auto& y : *recPolysY) { @@ -315,18 +314,18 @@ std::vector *SizeOptimizer::optimizeXYZ(GeneralTransform &tr, if ((polysZ != polysY) && (polysZ != polysX)) { delete polysZ; - if (!rank){ + if (tr.rank != 3){ delete recPolysZ; } } if (polysY != polysX) { delete polysY; - if (!rank){ + if (tr.rank != 3){ delete recPolysY; } } delete polysX; - if (!rank){ + if (tr.rank != 3){ delete recPolysX; } return result; From 514fc9e0cb4b5edda675e4afa162ebddb6f95f1a Mon Sep 17 00:00:00 2001 From: Turquet Date: Wed, 19 Jun 2019 12:25:34 +0200 Subject: [PATCH 03/10] Put the repository back at its original state except for a fixed bug of double free in sizeOptimizer --- generalTransform.cpp | 24 ++------- generalTransform.h | 1 - sizeOptimizer.cpp | 113 ++----------------------------------------- sizeOptimizer.h | 11 ----- 4 files changed, 7 insertions(+), 142 deletions(-) diff --git a/generalTransform.cpp b/generalTransform.cpp index eba67f3..0f0e712 100644 --- a/generalTransform.cpp +++ b/generalTransform.cpp @@ -17,9 +17,7 @@ GeneralTransform::GeneralTransform(int device, int X, int Y, int Z, int N, isFloat(isFloat), isForward(isForward), isInPlace(isInPlace), - isReal(isReal) { - setRankInfo(); - } + isReal(isReal) {} GeneralTransform::GeneralTransform(int X, int Y, int Z, const GeneralTransform &tr) @@ -32,9 +30,7 @@ GeneralTransform::GeneralTransform(int X, int Y, int Z, isFloat(tr.isFloat), isForward(tr.isForward), isInPlace(tr.isInPlace), - isReal(tr.isReal) { - setRankInfo(); - } + isReal(tr.isReal) {} GeneralTransform::GeneralTransform(const GeneralTransform &tr) { *this = tr; } @@ -49,21 +45,7 @@ GeneralTransform &GeneralTransform::operator=(const GeneralTransform &tr) { this->isFloat = tr.isFloat; this->isForward = tr.isForward; this->isInPlace = tr.isInPlace; - this->isReal = tr.isReal; - setRankInfo(); - } - return *this; -} - -void GeneralTransform::setRankInfo() { - rank = RANK_3D; - if (1 == Z) { - if (1 == Y) { - rank = RANK_1D; - } else { - rank = RANK_2D; - } - } + this->isReal = tr.isReareturn *this; } } // namespace cuFFTAdvisor diff --git a/generalTransform.h b/generalTransform.h index ecb0a6f..2c6c543 100644 --- a/generalTransform.h +++ b/generalTransform.h @@ -33,7 +33,6 @@ class GeneralTransform { Tristate::Tristate isForward; // otherwise inverse Tristate::Tristate isInPlace; // otherwise out-of-place Tristate::Tristate isReal; // otherwise C2C - Rank rank; /** * Sets fields that describe rank (dimensionality) diff --git a/sizeOptimizer.cpp b/sizeOptimizer.cpp index 6fe5e9d..5e7ab69 100644 --- a/sizeOptimizer.cpp +++ b/sizeOptimizer.cpp @@ -1,5 +1,4 @@ #include "sizeOptimizer.h" -#include namespace cuFFTAdvisor { @@ -171,27 +170,17 @@ std::vector *SizeOptimizer::optimizeXYZ(GeneralTransform &tr, std::vector *polysX = generatePolys(tr.X, tr.isFloat, crop); std::vector *polysY; std::vector *polysZ; - std::set *recPolysX; + std::set *recPolysX = filterOptimal(polysX, crop); std::set *recPolysY; std::set *recPolysZ; - if(tr.rank != 3){ - recPolysX = filterOptimal(polysX, crop); - }else{ - polysX = cutN(polysX, nBest); - } - if ((tr.X == tr.Y) || (squareOnly && (tr.Y != 1))) { polysY = polysX; recPolysY = recPolysX; } else { polysY = generatePolys(tr.Y, tr.isFloat, crop); - if(tr.rank != 3){ - recPolysY = filterOptimal(polysY, crop); - }else{ - polysY = cutN(polysY, nBest); - } + recPolysY = filterOptimal(polysY, crop); } if ((tr.X == tr.Z) @@ -203,19 +192,13 @@ std::vector *SizeOptimizer::optimizeXYZ(GeneralTransform &tr, recPolysZ = recPolysY; } else { polysZ = generatePolys(tr.Z, tr.isFloat, crop); - if(tr.rank != 3){ - recPolysZ = filterOptimal(polysZ, crop); - }else{ - polysZ = cutN(polysZ, nBest); - } + recPolysZ = filterOptimal(polysZ, crop); } - size_t minSize = getMinSize(tr, maxPercIncrease, crop); size_t maxSize = getMaxSize(tr, maxPercIncrease, squareOnly, crop); std::vector *result = new std::vector; - if(tr.rank != 3){ size_t found = 0; for (auto& x : *recPolysX) { for (auto& y : *recPolysY) { @@ -235,82 +218,6 @@ std::vector *SizeOptimizer::optimizeXYZ(GeneralTransform &tr, } } } - }else{ - //Definition of the max performence possible - Polynom minimunX = polysX->at(0); - for (size_t i = 1; i < polysX->size(); i++) { - if(polysX->at(i).invocations == 1){ - minimunX = polysX->at(i); - break; - } - if(polysX->at(i).invocations < minimunX.invocations){ - minimunX = polysX->at(i); - } - } - - Polynom minimunY = polysY->at(0); - for (size_t i = 1; i < polysY->size(); i++) { - if(polysY->at(i).invocations == 1){ - minimunY = polysY->at(i); - break; - } - if(polysY->at(i).invocations < minimunY.invocations){ - minimunY = polysY->at(i); - } - } - - Polynom minimunZ = polysZ->at(0); - for (size_t i = 1; i < polysZ->size(); i++) { - if(polysZ->at(i).invocations == 1){ - minimunZ = polysZ->at(i); - break; - } - if(polysZ->at(i).invocations < minimunZ.invocations){ - minimunZ = polysZ->at(i); - } - } - - - Transform transfo = Transform(0, minimunX.value, minimunY.value, minimunZ.value, 1, Tristate::FALSE, - Tristate::TRUE, Tristate::BOTH, Tristate::FALSE, false); - float maxPerfTime = Benchmarker::benchmark(&transfo)->execTimeMS; - - //Add the less incovation less padding transformation - GeneralTransform t(minimunX.value, minimunY.value, minimunZ.value, tr); - - result->push_back(t); - - //Add the transformation with the less padding possible - size_t found = 0; - int i = 0; - for (Polynom x : *polysX) { - for (Polynom y : *polysY) { - if (squareOnly && (x.value != y.value) && (y.value != 1)) continue; - size_t xy = x.value * y.value; - if (xy > maxSize) - break; // polynoms are sorted by size, we're already above the limit - for (Polynom z : *polysZ) { - i++; - if (Benchmarker::benchmark(new Transform(0, x.value, y.value, z.value, 1, Tristate::FALSE, - Tristate::TRUE, Tristate::BOTH, Tristate::FALSE, false))->execTimeMS > maxPerfTime - && found > nBest){ - break; - } - if (squareOnly && (x.value != z.value) && (z.value != 1)) continue; - size_t xyz = xy * z.value; - if ((found < nBest) && (xyz >= minSize) && (xyz <= maxSize)) { - // we can take nbest only, as others very probably won't be faster - found++; - GeneralTransform t((int)x.value, (int)y.value, (int)z.value, tr); - - result->push_back(t); - - } - } - } - } - - } if ((polysZ != polysY) && (polysZ != polysX)) { delete polysZ; @@ -416,18 +323,6 @@ std::vector *SizeOptimizer::generatePolys( return result; } -std::vector *SizeOptimizer::cutN(std::vector* polys, size_t nBest){ - //This function return the n smaller polynom of the vector - //It is use to limit the nomber of trqnsformation created - std::sort (polys->begin(), polys->end()); - if(polys->size() > nBest){ - while(polys->size() > nBest){ - polys->pop_back(); - } - } - return polys; -} - std::set *SizeOptimizer::filterOptimal(std::vector *input, bool crop) { @@ -450,7 +345,7 @@ std::set // update min kernel invocations needed minInv = tmp; } - if (closest > tmp) { + if (closest.value > tmp.value) { closest = tmp; } } diff --git a/sizeOptimizer.h b/sizeOptimizer.h index 9047bb0..e848d91 100644 --- a/sizeOptimizer.h +++ b/sizeOptimizer.h @@ -5,7 +5,6 @@ #include #include #include -#include #include "benchmarker.h" #include "generalTransform.h" #include "transformGenerator.h" @@ -23,16 +22,6 @@ class SizeOptimizer { size_t exponent3; size_t exponent5; size_t exponent7; - - bool operator < (const Polynom& cmp) const - { - return (value < cmp.value); - } - - bool operator > (const Polynom& cmp) const - { - return (value > cmp.value); - } }; struct valueComparator { From c86ff2398f7d5bc06805526715f4323e677af63a Mon Sep 17 00:00:00 2001 From: Turquet Date: Wed, 19 Jun 2019 12:32:42 +0200 Subject: [PATCH 04/10] Typo fixing --- generalTransform.cpp | 4 +++- generalTransform.h | 6 ------ sizeOptimizer.cpp | 12 +++--------- 3 files changed, 6 insertions(+), 16 deletions(-) diff --git a/generalTransform.cpp b/generalTransform.cpp index 0f0e712..ee47051 100644 --- a/generalTransform.cpp +++ b/generalTransform.cpp @@ -45,7 +45,9 @@ GeneralTransform &GeneralTransform::operator=(const GeneralTransform &tr) { this->isFloat = tr.isFloat; this->isForward = tr.isForward; this->isInPlace = tr.isInPlace; - this->isReal = tr.isReareturn *this; + this->isReal = tr.isReal; + } + return *this; } } // namespace cuFFTAdvisor diff --git a/generalTransform.h b/generalTransform.h index 2c6c543..8e1a6f9 100644 --- a/generalTransform.h +++ b/generalTransform.h @@ -8,8 +8,6 @@ namespace cuFFTAdvisor { class GeneralTransform { public: - enum Rank { RANK_1D = 1, RANK_2D = 2, RANK_3D = 3 }; - GeneralTransform(int device, int X, int Y, int Z, int N, Tristate::Tristate isBatched, Tristate::Tristate isFloat, Tristate::Tristate isForward, Tristate::Tristate isInPlace, @@ -34,10 +32,6 @@ class GeneralTransform { Tristate::Tristate isInPlace; // otherwise out-of-place Tristate::Tristate isReal; // otherwise C2C - /** - * Sets fields that describe rank (dimensionality) - */ - void setRankInfo(); }; } // namespace cuFFTAdvisor diff --git a/sizeOptimizer.cpp b/sizeOptimizer.cpp index 5e7ab69..80ad414 100644 --- a/sizeOptimizer.cpp +++ b/sizeOptimizer.cpp @@ -221,20 +221,14 @@ std::vector *SizeOptimizer::optimizeXYZ(GeneralTransform &tr, if ((polysZ != polysY) && (polysZ != polysX)) { delete polysZ; - if (tr.rank != 3){ - delete recPolysZ; - } + delete recPolysZ; } if (polysY != polysX) { delete polysY; - if (tr.rank != 3){ - delete recPolysY; - } + delete recPolysY; } delete polysX; - if (tr.rank != 3){ - delete recPolysX; - } + delete recPolysX; return result; } From b70fb384093a45222473888d92f2842dffe322e1 Mon Sep 17 00:00:00 2001 From: Turquet Date: Wed, 26 Jun 2019 14:59:06 +0200 Subject: [PATCH 05/10] Add the rank attribut to GeneralTransform --- generalTransform.cpp | 20 ++++++++++++++++++-- generalTransform.h | 9 +++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/generalTransform.cpp b/generalTransform.cpp index ee47051..f440ab3 100644 --- a/generalTransform.cpp +++ b/generalTransform.cpp @@ -17,7 +17,9 @@ GeneralTransform::GeneralTransform(int device, int X, int Y, int Z, int N, isFloat(isFloat), isForward(isForward), isInPlace(isInPlace), - isReal(isReal) {} + isReal(isReal) { + setRankInfo(); + } GeneralTransform::GeneralTransform(int X, int Y, int Z, const GeneralTransform &tr) @@ -30,7 +32,9 @@ GeneralTransform::GeneralTransform(int X, int Y, int Z, isFloat(tr.isFloat), isForward(tr.isForward), isInPlace(tr.isInPlace), - isReal(tr.isReal) {} + isReal(tr.isReal) { + setRankInfo(); + } GeneralTransform::GeneralTransform(const GeneralTransform &tr) { *this = tr; } @@ -46,8 +50,20 @@ GeneralTransform &GeneralTransform::operator=(const GeneralTransform &tr) { this->isForward = tr.isForward; this->isInPlace = tr.isInPlace; this->isReal = tr.isReal; + setRankInfo(); } return *this; } +void Transform::setRankInfo() { + rank = RANK_3D; + if (1 == Z) { + if (1 == Y) { + rank = RANK_1D; + } else { + rank = RANK_2D; + } + } +} + } // namespace cuFFTAdvisor diff --git a/generalTransform.h b/generalTransform.h index 8e1a6f9..415271d 100644 --- a/generalTransform.h +++ b/generalTransform.h @@ -8,6 +8,8 @@ namespace cuFFTAdvisor { class GeneralTransform { public: + enum Rank { RANK_1D = 1, RANK_2D = 2, RANK_3D = 3 }; + GeneralTransform(int device, int X, int Y, int Z, int N, Tristate::Tristate isBatched, Tristate::Tristate isFloat, Tristate::Tristate isForward, Tristate::Tristate isInPlace, @@ -32,6 +34,13 @@ class GeneralTransform { Tristate::Tristate isInPlace; // otherwise out-of-place Tristate::Tristate isReal; // otherwise C2C + Rank rank; + +private: + /** + * Sets fields that describe rank (dimensionality) + */ + void setRankInfo(); }; } // namespace cuFFTAdvisor From dd1b9fd132972a83fe5557cb0fc4a7935ebbacfe Mon Sep 17 00:00:00 2001 From: Turquet Date: Mon, 1 Jul 2019 14:53:45 +0200 Subject: [PATCH 06/10] Creation of a 'optimizeXYZ' twin function for the 3D signals. --- sizeOptimizer.cpp | 80 +++++++++++++++++++++++++++++++++++++++++++++-- sizeOptimizer.h | 5 ++- 2 files changed, 81 insertions(+), 4 deletions(-) diff --git a/sizeOptimizer.cpp b/sizeOptimizer.cpp index 80ad414..525455a 100644 --- a/sizeOptimizer.cpp +++ b/sizeOptimizer.cpp @@ -40,8 +40,13 @@ std::vector *SizeOptimizer::optimize(size_t nBest, bool crop) { std::vector preoptimized; for (auto in : input) { - std::vector *tmp = - optimizeXYZ(in, nBest, maxPercIncrease, squareOnly, crop); + if(){ + std::vector *tmp = + optimizeXYZ_3D(in, nBest, maxPercIncrease, squareOnly, crop); + }else{ + std::vector *tmp = + optimizeXYZ_1D_2D(in, nBest, maxPercIncrease, squareOnly, crop); + } preoptimized.insert(preoptimized.end(), tmp->begin(), tmp->end()); delete tmp; } @@ -161,7 +166,76 @@ size_t SizeOptimizer::getMinSize(GeneralTransform &tr, int maxPercDecrease, bool return std::max(0.f, afterPercInc); } -std::vector *SizeOptimizer::optimizeXYZ(GeneralTransform &tr, +std::vector *SizeOptimizer::optimizeXYZ_3D(GeneralTransform &tr, + size_t nBest, + int maxPercIncrease, + bool squareOnly, + bool crop) { + + std::vector *polysX = generatePolys(tr.X, tr.isFloat, crop); + std::sort (polysX->begin(), polysX->end()); + polysX.resize(nBest); + std::vector *polysY; + std::vector *polysZ; + + if ((tr.X == tr.Y) + || (squareOnly && (tr.Y != 1))) { + polysY = polysX; + } else { + polysY = generatePolys(tr.Y, tr.isFloat, crop); + std::sort (polysY->begin(), polysY->end()); + polysY.resize(nBest); + } + + if ((tr.X == tr.Z) + || (squareOnly && (tr.Z != 1))) { + polysZ = polysX; + } else if (tr.Y == tr.Z) { + polysZ = polysY; + } else { + polysZ = generatePolys(tr.Z, tr.isFloat, crop); + std::sort (polysZ->begin(), polysZ->end()); + polysZ.resize(nBest); + } + + size_t minSize = getMinSize(tr, maxPercIncrease, crop); + size_t maxSize = getMaxSize(tr, maxPercIncrease, squareOnly, crop); + + std::vector *result = new std::vector; + size_t found = 0; + for (auto& x : *recPolysX) { + for (auto& y : *recPolysY) { + if (squareOnly && (x.value != y.value) && (y.value != 1)) continue; + size_t xy = x.value * y.value; + if (xy > maxSize) + break; // polynoms are sorted by size, we're already above the limit + for (auto& z : *recPolysZ) { + if (squareOnly && (x.value != z.value) && (z.value != 1)) continue; + size_t xyz = xy * z.value; + if ((found < nBest) && (xyz >= minSize) && (xyz <= maxSize)) { + // we can take nbest only, as others very probably won't be faster + found++; + GeneralTransform t((int)x.value, (int)y.value, (int)z.value, tr); + result->push_back(t); + } + } + } + } + + if ((polysZ != polysY) && (polysZ != polysX)) { + delete polysZ; + delete recPolysZ; + } + if (polysY != polysX) { + delete polysY; + delete recPolysY; + } + delete polysX; + delete recPolysX; + return result; +} + +std::vector *SizeOptimizer::optimizeXYZ_1D_2D(GeneralTransform &tr, size_t nBest, int maxPercIncrease, bool squareOnly, diff --git a/sizeOptimizer.h b/sizeOptimizer.h index e848d91..2afe612 100644 --- a/sizeOptimizer.h +++ b/sizeOptimizer.h @@ -60,7 +60,10 @@ class SizeOptimizer { std::set *filterOptimal( std::vector *input, bool crop); std::vector *generatePolys(size_t num, bool isFloat, bool crop); - std::vector *optimizeXYZ(GeneralTransform &tr, size_t nBest, + std::vector *optimizeXYZ_3D(GeneralTransform &tr, size_t nBest, + int maxPercIncrease, bool squareOnly, + bool crop); + std::vector *optimizeXYZ_1D_2D(GeneralTransform &tr, size_t nBest, int maxPercIncrease, bool squareOnly, bool crop); std::vector *optimizeN( From 29a85b9ba1226f84c6ee985dc76370430ee1132b Mon Sep 17 00:00:00 2001 From: Turquet Date: Tue, 9 Jul 2019 11:16:17 +0200 Subject: [PATCH 07/10] Addition of greater and less operator for Polynom and implementation of the crop case in optimizeXYZ_3D --- advisor.cpp | 2 +- generalTransform.cpp | 2 +- sizeOptimizer.cpp | 44 ++++++++++++++++++++++++++------------------ sizeOptimizer.h | 12 +++++++++++- 4 files changed, 39 insertions(+), 21 deletions(-) diff --git a/advisor.cpp b/advisor.cpp index 43ea01b..7346efb 100644 --- a/advisor.cpp +++ b/advisor.cpp @@ -37,7 +37,7 @@ std::vector *Advisor::recommend( SizeOptimizer optimizer(CudaVersion::V_8, tr, allowTransposition); std::vector *result = - optimizer.optimize(howMany, maxSignalInc, maxMemory, squareOnly, crop); + optimizer.optimize(howMany, maxSignalInc, maxMemory, squareOnly, crop, tr.rank); resetDevice(); return result; } diff --git a/generalTransform.cpp b/generalTransform.cpp index f440ab3..eba67f3 100644 --- a/generalTransform.cpp +++ b/generalTransform.cpp @@ -55,7 +55,7 @@ GeneralTransform &GeneralTransform::operator=(const GeneralTransform &tr) { return *this; } -void Transform::setRankInfo() { +void GeneralTransform::setRankInfo() { rank = RANK_3D; if (1 == Z) { if (1 == Y) { diff --git a/sizeOptimizer.cpp b/sizeOptimizer.cpp index 525455a..49d4fdf 100644 --- a/sizeOptimizer.cpp +++ b/sizeOptimizer.cpp @@ -37,15 +37,14 @@ std::vector *SizeOptimizer::optimize(size_t nBest, int maxPercIncrease, int maxMemMB, bool squareOnly, - bool crop) { + bool crop, int rank) { std::vector preoptimized; for (auto in : input) { - if(){ - std::vector *tmp = - optimizeXYZ_3D(in, nBest, maxPercIncrease, squareOnly, crop); + std::vector *tmp; + if(rank == 3){ + tmp = optimizeXYZ_3D(in, nBest, maxPercIncrease, squareOnly, crop); }else{ - std::vector *tmp = - optimizeXYZ_1D_2D(in, nBest, maxPercIncrease, squareOnly, crop); + tmp = optimizeXYZ_1D_2D(in, nBest, maxPercIncrease, squareOnly, crop); } preoptimized.insert(preoptimized.end(), tmp->begin(), tmp->end()); delete tmp; @@ -173,8 +172,12 @@ std::vector *SizeOptimizer::optimizeXYZ_3D(GeneralTransform &t bool crop) { std::vector *polysX = generatePolys(tr.X, tr.isFloat, crop); - std::sort (polysX->begin(), polysX->end()); - polysX.resize(nBest); + if(!crop){ + std::sort (polysX->begin(), polysX->end()); + }else{ + std::sort (polysX->begin(), polysX->end(), std::less()); + } + polysX->resize(nBest); std::vector *polysY; std::vector *polysZ; @@ -183,8 +186,12 @@ std::vector *SizeOptimizer::optimizeXYZ_3D(GeneralTransform &t polysY = polysX; } else { polysY = generatePolys(tr.Y, tr.isFloat, crop); - std::sort (polysY->begin(), polysY->end()); - polysY.resize(nBest); + if(!crop){ + std::sort (polysY->begin(), polysY->end()); + }else{ + std::sort (polysY->begin(), polysY->end(), std::less()); + } + polysY->resize(nBest); } if ((tr.X == tr.Z) @@ -194,8 +201,12 @@ std::vector *SizeOptimizer::optimizeXYZ_3D(GeneralTransform &t polysZ = polysY; } else { polysZ = generatePolys(tr.Z, tr.isFloat, crop); - std::sort (polysZ->begin(), polysZ->end()); - polysZ.resize(nBest); + if(!crop){ + std::sort (polysZ->begin(), polysZ->end()); + }else{ + std::sort (polysZ->begin(), polysZ->end(), std::less()); + } + polysZ->resize(nBest); } size_t minSize = getMinSize(tr, maxPercIncrease, crop); @@ -203,13 +214,13 @@ std::vector *SizeOptimizer::optimizeXYZ_3D(GeneralTransform &t std::vector *result = new std::vector; size_t found = 0; - for (auto& x : *recPolysX) { - for (auto& y : *recPolysY) { + for (auto& x : *polysX) { + for (auto& y : *polysY) { if (squareOnly && (x.value != y.value) && (y.value != 1)) continue; size_t xy = x.value * y.value; if (xy > maxSize) break; // polynoms are sorted by size, we're already above the limit - for (auto& z : *recPolysZ) { + for (auto& z : *polysZ) { if (squareOnly && (x.value != z.value) && (z.value != 1)) continue; size_t xyz = xy * z.value; if ((found < nBest) && (xyz >= minSize) && (xyz <= maxSize)) { @@ -224,14 +235,11 @@ std::vector *SizeOptimizer::optimizeXYZ_3D(GeneralTransform &t if ((polysZ != polysY) && (polysZ != polysX)) { delete polysZ; - delete recPolysZ; } if (polysY != polysX) { delete polysY; - delete recPolysY; } delete polysX; - delete recPolysX; return result; } diff --git a/sizeOptimizer.h b/sizeOptimizer.h index 2afe612..aa4af3e 100644 --- a/sizeOptimizer.h +++ b/sizeOptimizer.h @@ -22,6 +22,16 @@ class SizeOptimizer { size_t exponent3; size_t exponent5; size_t exponent7; + + bool operator < (const Polynom& cmp) const + { + return (value < cmp.value); + } + + bool operator > (const Polynom& cmp) const + { + return (value > cmp.value); + } }; struct valueComparator { @@ -46,7 +56,7 @@ class SizeOptimizer { bool allowTrans); std::vector *optimize(size_t nBest, int maxPercIncrease, int maxMemMB, bool squareOnly, - bool crop); + bool crop, int rank); private: int getNoOfPrimes(Polynom &poly); From 6188cbd551dc19efe25f8d49bc29f5a080de91a6 Mon Sep 17 00:00:00 2001 From: Turquet Date: Wed, 10 Jul 2019 11:15:24 +0200 Subject: [PATCH 08/10] Deletion of useless tests and unused function headers --- sizeOptimizer.cpp | 10 ++++------ sizeOptimizer.h | 1 - 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/sizeOptimizer.cpp b/sizeOptimizer.cpp index 49d4fdf..1aa8cc9 100644 --- a/sizeOptimizer.cpp +++ b/sizeOptimizer.cpp @@ -181,8 +181,7 @@ std::vector *SizeOptimizer::optimizeXYZ_3D(GeneralTransform &t std::vector *polysY; std::vector *polysZ; - if ((tr.X == tr.Y) - || (squareOnly && (tr.Y != 1))) { + if ((tr.X == tr.Y) || squareOnly) { polysY = polysX; } else { polysY = generatePolys(tr.Y, tr.isFloat, crop); @@ -194,8 +193,7 @@ std::vector *SizeOptimizer::optimizeXYZ_3D(GeneralTransform &t polysY->resize(nBest); } - if ((tr.X == tr.Z) - || (squareOnly && (tr.Z != 1))) { + if ((tr.X == tr.Z) || squareOnly) { polysZ = polysX; } else if (tr.Y == tr.Z) { polysZ = polysY; @@ -216,12 +214,12 @@ std::vector *SizeOptimizer::optimizeXYZ_3D(GeneralTransform &t size_t found = 0; for (auto& x : *polysX) { for (auto& y : *polysY) { - if (squareOnly && (x.value != y.value) && (y.value != 1)) continue; + if (squareOnly && (x.value != y.value)) continue; size_t xy = x.value * y.value; if (xy > maxSize) break; // polynoms are sorted by size, we're already above the limit for (auto& z : *polysZ) { - if (squareOnly && (x.value != z.value) && (z.value != 1)) continue; + if (squareOnly && (x.value != z.value)) continue; size_t xyz = xy * z.value; if ((found < nBest) && (xyz >= minSize) && (xyz <= maxSize)) { // we can take nbest only, as others very probably won't be faster diff --git a/sizeOptimizer.h b/sizeOptimizer.h index aa4af3e..4d1d560 100644 --- a/sizeOptimizer.h +++ b/sizeOptimizer.h @@ -66,7 +66,6 @@ class SizeOptimizer { int getInvocations(Polynom &poly, bool isFloat); int getInvocationsV8(Polynom &poly, bool isFloat); - std::vector *cutN(std::vector* polys , size_t nBest); std::set *filterOptimal( std::vector *input, bool crop); std::vector *generatePolys(size_t num, bool isFloat, bool crop); From 0626cca23b10427a9389eb458bcdc5af2414f41e Mon Sep 17 00:00:00 2001 From: Turquet Date: Mon, 15 Jul 2019 13:14:48 +0200 Subject: [PATCH 09/10] Suppresion of the rank enumeration of transform.h and better use of the enumeration --- sizeOptimizer.cpp | 2 +- transform.h | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/sizeOptimizer.cpp b/sizeOptimizer.cpp index 1aa8cc9..f6e32a9 100644 --- a/sizeOptimizer.cpp +++ b/sizeOptimizer.cpp @@ -41,7 +41,7 @@ std::vector *SizeOptimizer::optimize(size_t nBest, std::vector preoptimized; for (auto in : input) { std::vector *tmp; - if(rank == 3){ + if(rank == GeneralTransform::RANK_3D){ tmp = optimizeXYZ_3D(in, nBest, maxPercIncrease, squareOnly, crop); }else{ tmp = optimizeXYZ_1D_2D(in, nBest, maxPercIncrease, squareOnly, crop); diff --git a/transform.h b/transform.h index 4497f1d..01962ad 100644 --- a/transform.h +++ b/transform.h @@ -5,6 +5,7 @@ #include #include #include "utils.h" +#include "generalTransform.h" namespace cuFFTAdvisor { @@ -13,8 +14,6 @@ class Transform { void print(FILE *stream = stdout) const; static void printHeader(FILE *stream = stdout); - enum Rank { RANK_1D = 1, RANK_2D = 2, RANK_3D = 3 }; - Transform(int device, int X, int Y, int Z, int N, bool isBatched, bool isFloat, bool isForward, bool isInPlace, bool isReal) : device(device), @@ -48,7 +47,7 @@ class Transform { bool isForward; // otherwise inverse // derived - Rank rank; + GeneralTransform::Rank rank; size_t elems; // of the transform // FIXME remove size_t inTypeSize; size_t outTypeSize; From d36168ed752d84400548c506fcf199ec920c3192 Mon Sep 17 00:00:00 2001 From: Turquet Date: Thu, 18 Jul 2019 15:05:42 +0200 Subject: [PATCH 10/10] Refactorisation of the sorting in sizeOptimizer_3D --- sizeOptimizer.cpp | 31 +++++++++++++------------------ sizeOptimizer.h | 1 + 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/sizeOptimizer.cpp b/sizeOptimizer.cpp index f6e32a9..47585fa 100644 --- a/sizeOptimizer.cpp +++ b/sizeOptimizer.cpp @@ -165,6 +165,16 @@ size_t SizeOptimizer::getMinSize(GeneralTransform &tr, int maxPercDecrease, bool return std::max(0.f, afterPercInc); } +void SizeOptimizer::cutter(std::vector* polys, GeneralTransform &tr, bool crop, size_t nBest){ + //This function generate Polynom, sort them resize the vector + if(crop){ + std::sort (polys->begin(), polys->end(), std::greater()); + }else{ + std::sort (polys->begin(), polys->end(), std::less()); + } + polys->resize(nBest); +} + std::vector *SizeOptimizer::optimizeXYZ_3D(GeneralTransform &tr, size_t nBest, int maxPercIncrease, @@ -172,12 +182,7 @@ std::vector *SizeOptimizer::optimizeXYZ_3D(GeneralTransform &t bool crop) { std::vector *polysX = generatePolys(tr.X, tr.isFloat, crop); - if(!crop){ - std::sort (polysX->begin(), polysX->end()); - }else{ - std::sort (polysX->begin(), polysX->end(), std::less()); - } - polysX->resize(nBest); + cutter(polysX, tr, crop, nBest); std::vector *polysY; std::vector *polysZ; @@ -185,12 +190,7 @@ std::vector *SizeOptimizer::optimizeXYZ_3D(GeneralTransform &t polysY = polysX; } else { polysY = generatePolys(tr.Y, tr.isFloat, crop); - if(!crop){ - std::sort (polysY->begin(), polysY->end()); - }else{ - std::sort (polysY->begin(), polysY->end(), std::less()); - } - polysY->resize(nBest); + cutter(polysY, tr, crop, nBest); } if ((tr.X == tr.Z) || squareOnly) { @@ -199,12 +199,7 @@ std::vector *SizeOptimizer::optimizeXYZ_3D(GeneralTransform &t polysZ = polysY; } else { polysZ = generatePolys(tr.Z, tr.isFloat, crop); - if(!crop){ - std::sort (polysZ->begin(), polysZ->end()); - }else{ - std::sort (polysZ->begin(), polysZ->end(), std::less()); - } - polysZ->resize(nBest); + cutter(polysZ, tr, crop, nBest); } size_t minSize = getMinSize(tr, maxPercIncrease, crop); diff --git a/sizeOptimizer.h b/sizeOptimizer.h index 4d1d560..6ecd492 100644 --- a/sizeOptimizer.h +++ b/sizeOptimizer.h @@ -69,6 +69,7 @@ class SizeOptimizer { std::set *filterOptimal( std::vector *input, bool crop); std::vector *generatePolys(size_t num, bool isFloat, bool crop); + void cutter(std::vector* polys, GeneralTransform &tr, bool crop, size_t nBest); std::vector *optimizeXYZ_3D(GeneralTransform &tr, size_t nBest, int maxPercIncrease, bool squareOnly, bool crop);