From 7c90b87febb43ade88d7289a484ee1b6ac265d07 Mon Sep 17 00:00:00 2001 From: Tom Date: Thu, 13 Jun 2024 15:26:31 +0200 Subject: [PATCH 1/9] wip --- benchmarks/benchmark-quasisep.C | 15 +- fflas-ffpack/utils/fflas_randommatrix.h | 293 +++++++++++++++++++++++- tests/test-quasisep.C | 2 +- 3 files changed, 306 insertions(+), 4 deletions(-) diff --git a/benchmarks/benchmark-quasisep.C b/benchmarks/benchmark-quasisep.C index d7d84d3f9..c644594af 100644 --- a/benchmarks/benchmark-quasisep.C +++ b/benchmarks/benchmark-quasisep.C @@ -49,8 +49,19 @@ void run_with_field(int q, size_t n, size_t m, size_t t, size_t r, size_t iter, Element_ptr A, TS; double time_gen = 0, time_cbxts =0; + double time_RPMGen = 0; for (size_t i=0;i (r); + size_t * cols = FFLAS::fflas_new (r); + + chrono.clear(); + chrono.start(); + RandomLTQSRankProfileMatrix_Tom (n, r, t, rows, cols); + chrono.stop(); + + time_RPMGen += chrono.usertime(); + A = FFLAS::fflas_new (F, n, n); size_t lda=n; TS = FFLAS::fflas_new (F, n, m); @@ -104,8 +115,8 @@ void run_with_field(int q, size_t n, size_t m, size_t t, size_t r, size_t iter, } // ----------- // Standard output for benchmark - Alexis Breust 2014/11/14 - std::cout << "Time: " << (time_gen + time_cbxts) / double(iter) << " Gfops: Irrelevant (Generator) Specific times: " << time_gen / double(iter)<<" (for construction)" << time_cbxts / double(iter)<<" (for CB x TS)" ; - + // std::cout << "Time: " << (time_gen + time_cbxts) / double(iter) << " Gfops: Irrelevant (Generator) Specific times: " << time_gen / double(iter)<<" (for construction)" << time_cbxts / double(iter)<<" (for CB x TS)" ; + std::cout << "Time : " << time_RPMGen / double(iter) << std::endl; } int main(int argc, char** argv) { diff --git a/fflas-ffpack/utils/fflas_randommatrix.h b/fflas-ffpack/utils/fflas_randommatrix.h index a5bce3f35..58b87e6de 100644 --- a/fflas-ffpack/utils/fflas_randommatrix.h +++ b/fflas-ffpack/utils/fflas_randommatrix.h @@ -467,6 +467,297 @@ namespace FFPACK{ FFLAS::fflas_delete (randcols,randrows); } + // O(l*len(L)) + // id = true if we consider the identity, else False + inline void compute_valid_moves(std::vector* valid_moves, size_t l, size_t* L, size_t length, bool id) { + valid_moves->clear(); + + // Base case: Identity + if (id) { + valid_moves->push_back(l); + } + + // Compute all the empty columns/lines + for (size_t i = 0; i < l; ++i) { + if (std::find(L, L + length, i) == L + length) { + valid_moves->push_back(i); + } + } + } + + // O(1) + size_t valuate(int ti, int r, int n, int h, int ih, int i, int Is_pivot, int nb_pivot_bf_i) { + // Compute the valuation of a given leading submatrix ti + if (i <= ih) { + return ti + std::min(i + 1 - nb_pivot_bf_i, r - h); + } else { + return ti + std::min(i + 1 - nb_pivot_bf_i, r - nb_pivot_bf_i) + + std::min(n - (i + 1) - r + nb_pivot_bf_i, nb_pivot_bf_i - h - Is_pivot); + } + } + + /** @brief genenration of an Rank Profile Matrix randomly + * @param n Dimension + * @param r rank of the n*n matrix + * @param t quasi-separability order + * @param rows + * @param cols + */ + void RandomLTQSRankProfileMatrix_Tom(size_t n, size_t r, size_t t, size_t* rows, size_t* cols) { + + if (r <= 0 || n <= 0 || t <= 0) { + std::cout << "care, all the arguments must be positive" << std::endl; + return; + } + + if (r >= n) { + std::cout << "care, you called the function with invalid arguments : r >= n IMPOSSIBLE" << std::endl; + return; + } + + if (t > r) { + std::cout << "care, you called the function with invalid arguments : t >= r IMPOSSIBLE" << std::endl; + return; + } + + if (r + t > n) { + std::cout << "care, you called the function with invalid arguments : r+t > n IMPOSSIBLE" << std::endl; + return; + } + + /// Initialisation + //std::vector H(n - 1, 0); + //std::vector T(n - 1, 0); + //std::vector nb_pivot_before_index(n - 1, 0); + + size_t* H = FFLAS::fflas_new(n-1); + size_t* T = FFLAS::fflas_new(n-1); + size_t* nb_pivot_before_index = FFLAS::fflas_new(n-1); + + for (size_t i = 0; i valid_moves_left, valid_moves_up; + int h = 0; + int prev_h = -1; + + while ((size_t) h < r) { + + int up_or_left = RandInt(0,2); + + size_t prev_i = rows[h]; + size_t prev_j = cols[h]; + + size_t new_i = prev_i; + size_t new_j = prev_j; + + /// computating valid_moves + if (prev_h != h) { + compute_valid_moves(& valid_moves_left, prev_j, cols, r,true); + compute_valid_moves(& valid_moves_up, prev_i, rows, r,false); + } + + //debug + //std::cout << "up: "; + //for (size_t i = 0; i < valid_moves_up.size(); ++i) { + // std::cout << valid_moves_up[i] << " "; + //} + //std::cout << std::endl; + //debug + //std::cout << "left: "; + //for (size_t i = 0; i < valid_moves_left.size(); ++i) { + // std::cout << valid_moves_left[i] << " "; + //} + //std::cout << std::endl; + + if (up_or_left == 0 && valid_moves_left.empty()) { + up_or_left = 1; + } + if (up_or_left == 1 && valid_moves_up.empty()) { + up_or_left = 0; + } + + /// choose and make the chosen move + if (up_or_left == 0) { + new_j = valid_moves_left[RandInt(0,valid_moves_left.size())]; + cols[h] = new_j; + + for (size_t k = prev_i + 1; k <= prev_i + (prev_j - new_j); ++k) { + T[k] += 1; + } + } else { + new_i = valid_moves_up[RandInt(0,valid_moves_up.size())]; + rows[h] = new_i; + + for (size_t k = new_i; k < prev_i; ++k) { + T[k] += 1; + nb_pivot_before_index[k] += 1; + } + } + + /// valutation + bool undo = true; + for (size_t k = 0; k < n - 1; ++k) { + if (valuate(T[k], r, n, h + 1, prev_i, k, H[k], nb_pivot_before_index[k]) >= t) { + undo = false; + break; + } + } + + /// limit testing + size_t klim = 0; + if (!undo) { + for (size_t k = 0; k < n - 1; ++k) { + if (T[k] > t) { + undo = true; + klim = k; + break; + } + } + } + + /// undo + if (undo) { + if (up_or_left == 1) { + rows[h] = prev_i; + valid_moves_up.erase(std::find(valid_moves_up.begin(), valid_moves_up.end(), new_i)); + + for (size_t k = new_i; k < prev_i; ++k) { + T[k] -= 1; + nb_pivot_before_index[k] -= 1; + } + //if (klim != 0) { + // size_t imax = klim; + // for (size_t i = 0; i<=imax; ++i) { + // auto it = std::find(valid_moves_up.begin(), valid_moves_up.end(), i); + // if (it != valid_moves_up.end()){ + // valid_moves_up.erase(it); + // } + // } + //} + if (klim != 0) { + size_t imax = klim; + for (auto it = valid_moves_up.begin(); it != valid_moves_up.end(); ){ + if (*it <= imax) { + it = valid_moves_up.erase(it); + } + else { + ++it; + } + } + } + } else { + cols[h] = prev_j; + valid_moves_left.erase(std::find(valid_moves_left.begin(), valid_moves_left.end(), new_j)); + + for (size_t k = prev_i + 1; k <= prev_i + (prev_j - new_j); ++k) { + T[k] -= 1; + } + //if (klim != 0) { + // size_t jmax = n-klim-2; + // for (size_t j = 0; j<=jmax; ++j) { + // auto it = std::find(valid_moves_left.begin(), valid_moves_left.end(), j); + // if (it != valid_moves_left.end()){ + // valid_moves_left.erase(it); + // } + // } + //} + if (klim != 0) { + size_t jmax = n-klim-2; + for (auto it = valid_moves_left.begin(); it != valid_moves_left.end(); ){ + if (*it <= jmax) { + it = valid_moves_left.erase(it); + } + else { + ++it; + } + } + } + } + + ++loop; + if (prev_h != h) { + prev_h = h; + }; + continue; + } + + //debug + //std::cout << "new rows: "; + //for (size_t i = 0; i < r; ++i) { + // std::cout << rows[i] << " "; + //} + //std::cout << std::endl; + //debug + //std::cout << "new cols: "; + //for (size_t i = 0; i < r; ++i) { + // std::cout << cols[i] << " "; + //} + //std::cout << std::endl; + //std::cout << std::endl; + /// set up for next loop turn + ++loop; + ++h; + } + FFLAS::fflas_delete (H); + FFLAS::fflas_delete (T); + FFLAS::fflas_delete(nb_pivot_before_index); + } + + /** @brief Random Matrix with prescribed rank and rank profile matrix * Creates an \c m x \c n matrix with random entries and rank \c r. * @param F field @@ -775,7 +1066,7 @@ namespace FFPACK{ size_t * pivot_r = FFLAS::fflas_new (r); size_t * pivot_c = FFLAS::fflas_new (r); - RandomLTQSRankProfileMatrix (n, r, t, pivot_r, pivot_c); + RandomLTQSRankProfileMatrix_Tom (n, r, t, pivot_r, pivot_c); // typename Field::Element_ptr R =FFLAS::fflas_new(F,n,n); // getLTBruhatGen(F, n, r, pivot_r, pivot_c, R, n); // FFLAS:: WriteMatrix (std::cerr<<"R = "<(r); size_t * cols = FFLAS::fflas_new(r); - RandomLTQSRankProfileMatrix (n, r, t, rows, cols); + RandomLTQSRankProfileMatrix_Tom (n, r, t, rows, cols); typename Field::Element_ptr A = fflas_new(F,n,n); getLTBruhatGen(F, n, r, rows, cols, A, n); From f41454d3d4a7a0f3cabbaba08a3e5d548ad457dd Mon Sep 17 00:00:00 2001 From: Tom Date: Fri, 14 Jun 2024 15:43:19 +0200 Subject: [PATCH 2/9] =?UTF-8?q?optimisation=20pour=20connaitres=20les=20d?= =?UTF-8?q?=C3=A9placements=20qui=20m=C3=A8ne=20=C3=A0=20un=20d=C3=A9passe?= =?UTF-8?q?ment=20de=20l'ordre=20de=20quasis=C3=A9parabilit=C3=A9=20et=20m?= =?UTF-8?q?ise=20en=20place=20des=20valid=5Fmoves=20dans=20une=20seule=20e?= =?UTF-8?q?t=20m=C3=AAme=20liste=20(avec=20index=20montrant=20le=20d=C3=A9?= =?UTF-8?q?but=20des=20moves=20vers=20le=20haut)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fflas-ffpack/utils/fflas_randommatrix.h | 191 +++++++----------------- 1 file changed, 53 insertions(+), 138 deletions(-) diff --git a/fflas-ffpack/utils/fflas_randommatrix.h b/fflas-ffpack/utils/fflas_randommatrix.h index 58b87e6de..3c843ebae 100644 --- a/fflas-ffpack/utils/fflas_randommatrix.h +++ b/fflas-ffpack/utils/fflas_randommatrix.h @@ -469,17 +469,25 @@ namespace FFPACK{ // O(l*len(L)) // id = true if we consider the identity, else False - inline void compute_valid_moves(std::vector* valid_moves, size_t l, size_t* L, size_t length, bool id) { + inline void compute_valid_moves(std::vector* valid_moves, size_t* start_up, size_t l, size_t* L, size_t lengthL, int llim, size_t m, size_t* M, size_t lengthM, int mlim) { valid_moves->clear(); // Base case: Identity - if (id) { - valid_moves->push_back(l); - } + valid_moves->push_back(l); // Compute all the empty columns/lines - for (size_t i = 0; i < l; ++i) { - if (std::find(L, L + length, i) == L + length) { + for (size_t j = (size_t) llim+1; j < l; ++j) { + if (std::find(L, L + lengthL, j) == L + lengthL) { + valid_moves->push_back(j); + } + } + + *start_up = valid_moves->size(); + + //std::cout << mlim << "//" << m << std::endl; + for (size_t i = (size_t) mlim+1; i < m; ++i) { + //std::cout << i << (std::find(M, M + lengthM, i) == M + lengthM) << std::endl; + if (std::find(M, M + lengthM, i) == M + lengthM) { valid_moves->push_back(i); } } @@ -526,9 +534,6 @@ namespace FFPACK{ } /// Initialisation - //std::vector H(n - 1, 0); - //std::vector T(n - 1, 0); - //std::vector nb_pivot_before_index(n - 1, 0); size_t* H = FFLAS::fflas_new(n-1); size_t* T = FFLAS::fflas_new(n-1); @@ -548,98 +553,71 @@ namespace FFPACK{ H[rows[i]] = 1; } - //debug - //std::cout << "Init rows: "; - //for (size_t i = 0; i < r; ++i) { - // std::cout << rows[i] << " "; - //} - //std::cout << std::endl; - - //debug - //std::cout << "Init cols: "; - //for (size_t i = 0; i < r; ++i) { - // std::cout << cols[i] << " "; - //} - //std::cout << std::endl; nb_pivot_before_index[0] = H[0]; for (size_t i = 1; i < n - 1; ++i) { nb_pivot_before_index[i] = nb_pivot_before_index[i - 1] + H[i]; } - //debug - //std::cout << "Init T: "; - //for (size_t i = 0; i < n-1; ++i) { - // std::cout << T[i] << " "; - //} - //std::cout << std::endl; - - //debug - //std::cout << "Init H: "; - //for (size_t i = 0; i < n-1; ++i) { - // std::cout << H[i] << " "; - //} - //std::cout << std::endl; - - //debug - //std::cout << "Init nb p bf index: "; - //for (size_t i = 0; i < n-1; ++i) { - // std::cout << nb_pivot_before_index[i] << " "; - //} - //std::cout << std::endl; - /// loop initialisation size_t loop = 0; - std::vector valid_moves_left, valid_moves_up; + std::vector valid_moves; + size_t start_up; + int ilim, jlim; int h = 0; int prev_h = -1; while ((size_t) h < r) { - - int up_or_left = RandInt(0,2); - + //std::cout << h << std::endl; size_t prev_i = rows[h]; size_t prev_j = cols[h]; size_t new_i = prev_i; size_t new_j = prev_j; + /// computating valid_moves if (prev_h != h) { - compute_valid_moves(& valid_moves_left, prev_j, cols, r,true); - compute_valid_moves(& valid_moves_up, prev_i, rows, r,false); + ilim = -1; + jlim = -1; + int k = rows[h]+1; + while ((size_t) k <= n-2) { + if (T[k] == t) { + jlim = n-k-2; + break; + } + ++k; + } + k = rows[h]-1; + while (k >= 0) { + if (T[k] == t) { + ilim = k; + break; + } + --k; + } + //std::cout << "ilim" << ilim << std::endl; + compute_valid_moves(& valid_moves, & start_up, prev_j, cols, r, jlim, prev_i, rows, r, ilim); } - //debug - //std::cout << "up: "; - //for (size_t i = 0; i < valid_moves_up.size(); ++i) { - // std::cout << valid_moves_up[i] << " "; - //} - //std::cout << std::endl; - //debug - //std::cout << "left: "; - //for (size_t i = 0; i < valid_moves_left.size(); ++i) { - // std::cout << valid_moves_left[i] << " "; - //} - //std::cout << std::endl; - - if (up_or_left == 0 && valid_moves_left.empty()) { - up_or_left = 1; + /// choose and make the chosen move + size_t rand_index; + if (valid_moves.size()>1){ + rand_index = RandInt(0, valid_moves.size()); } - if (up_or_left == 1 && valid_moves_up.empty()) { - up_or_left = 0; + else { + rand_index = 0; } - /// choose and make the chosen move - if (up_or_left == 0) { - new_j = valid_moves_left[RandInt(0,valid_moves_left.size())]; + if (rand_index < start_up) { + new_j = valid_moves[rand_index]; cols[h] = new_j; for (size_t k = prev_i + 1; k <= prev_i + (prev_j - new_j); ++k) { T[k] += 1; } } else { - new_i = valid_moves_up[RandInt(0,valid_moves_up.size())]; + new_i = valid_moves[rand_index]; rows[h] = new_i; for (size_t k = new_i; k < prev_i; ++k) { @@ -657,75 +635,23 @@ namespace FFPACK{ } } - /// limit testing - size_t klim = 0; - if (!undo) { - for (size_t k = 0; k < n - 1; ++k) { - if (T[k] > t) { - undo = true; - klim = k; - break; - } - } - } - /// undo if (undo) { - if (up_or_left == 1) { + if (rand_index >= start_up) { rows[h] = prev_i; - valid_moves_up.erase(std::find(valid_moves_up.begin(), valid_moves_up.end(), new_i)); + valid_moves.erase(valid_moves.begin()+rand_index); for (size_t k = new_i; k < prev_i; ++k) { T[k] -= 1; nb_pivot_before_index[k] -= 1; } - //if (klim != 0) { - // size_t imax = klim; - // for (size_t i = 0; i<=imax; ++i) { - // auto it = std::find(valid_moves_up.begin(), valid_moves_up.end(), i); - // if (it != valid_moves_up.end()){ - // valid_moves_up.erase(it); - // } - // } - //} - if (klim != 0) { - size_t imax = klim; - for (auto it = valid_moves_up.begin(); it != valid_moves_up.end(); ){ - if (*it <= imax) { - it = valid_moves_up.erase(it); - } - else { - ++it; - } - } - } } else { cols[h] = prev_j; - valid_moves_left.erase(std::find(valid_moves_left.begin(), valid_moves_left.end(), new_j)); - + valid_moves.erase(valid_moves.begin()+rand_index); + start_up--; for (size_t k = prev_i + 1; k <= prev_i + (prev_j - new_j); ++k) { T[k] -= 1; } - //if (klim != 0) { - // size_t jmax = n-klim-2; - // for (size_t j = 0; j<=jmax; ++j) { - // auto it = std::find(valid_moves_left.begin(), valid_moves_left.end(), j); - // if (it != valid_moves_left.end()){ - // valid_moves_left.erase(it); - // } - // } - //} - if (klim != 0) { - size_t jmax = n-klim-2; - for (auto it = valid_moves_left.begin(); it != valid_moves_left.end(); ){ - if (*it <= jmax) { - it = valid_moves_left.erase(it); - } - else { - ++it; - } - } - } } ++loop; @@ -736,18 +662,7 @@ namespace FFPACK{ } //debug - //std::cout << "new rows: "; - //for (size_t i = 0; i < r; ++i) { - // std::cout << rows[i] << " "; - //} - //std::cout << std::endl; - //debug - //std::cout << "new cols: "; - //for (size_t i = 0; i < r; ++i) { - // std::cout << cols[i] << " "; - //} - //std::cout << std::endl; - //std::cout << std::endl; + /// set up for next loop turn ++loop; ++h; From a096f542a01013fea8495041088497c97ad88c7b Mon Sep 17 00:00:00 2001 From: Tom Date: Tue, 18 Jun 2024 16:54:31 +0200 Subject: [PATCH 3/9] =?UTF-8?q?ajout=20d'al=C3=A9atoire=20en=20randomisant?= =?UTF-8?q?=20les=20pivots=20pris=20=C3=A0=20chaque=20it=C3=A9rations?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fflas-ffpack/utils/fflas_randommatrix.h | 44 +++++++++++++++++++------ 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/fflas-ffpack/utils/fflas_randommatrix.h b/fflas-ffpack/utils/fflas_randommatrix.h index 3c843ebae..40e9aad8a 100644 --- a/fflas-ffpack/utils/fflas_randommatrix.h +++ b/fflas-ffpack/utils/fflas_randommatrix.h @@ -494,14 +494,10 @@ namespace FFPACK{ } // O(1) - size_t valuate(int ti, int r, int n, int h, int ih, int i, int Is_pivot, int nb_pivot_bf_i) { + size_t valuate(int ti, int r, int n, int i, int Is_pivot_not_moved, int nb_pivot_bf_i, int nb_pivot_after_i_not_moved, int nb_pivot_before_i_not_moved) { // Compute the valuation of a given leading submatrix ti - if (i <= ih) { - return ti + std::min(i + 1 - nb_pivot_bf_i, r - h); - } else { - return ti + std::min(i + 1 - nb_pivot_bf_i, r - nb_pivot_bf_i) + - std::min(n - (i + 1) - r + nb_pivot_bf_i, nb_pivot_bf_i - h - Is_pivot); - } + return ti + std::min(i + 1 - nb_pivot_bf_i, nb_pivot_after_i_not_moved - Is_pivot_not_moved) + + std::min((n-1) - (i + 1) - r + nb_pivot_bf_i, nb_pivot_before_i_not_moved - Is_pivot_not_moved); } /** @brief genenration of an Rank Profile Matrix randomly @@ -538,6 +534,8 @@ namespace FFPACK{ size_t* H = FFLAS::fflas_new(n-1); size_t* T = FFLAS::fflas_new(n-1); size_t* nb_pivot_before_index = FFLAS::fflas_new(n-1); + size_t* nb_pivot_before_index_not_moved = FFLAS::fflas_new(n-1); + size_t* nb_pivot_after_index_not_moved = FFLAS::fflas_new(n-1); for (size_t i = 0; i= prev_i) { + nb_pivot_before_index_not_moved[k]--; + } + } + + H[prev_i] = 0; + /// valutation bool undo = true; for (size_t k = 0; k < n - 1; ++k) { - if (valuate(T[k], r, n, h + 1, prev_i, k, H[k], nb_pivot_before_index[k]) >= t) { + if (valuate(T[k], r, n, k, H[k], nb_pivot_before_index[k], nb_pivot_after_index_not_moved[k], nb_pivot_before_index_not_moved[k]) >= t) { undo = false; break; } @@ -654,10 +666,22 @@ namespace FFPACK{ } } + for (size_t k = 0; k= prev_i) { + nb_pivot_before_index_not_moved[k]--; + } + } + + H[prev_i] = 0; + ++loop; if (prev_h != h) { prev_h = h; - }; + } + continue; } From 58fc26ec5aac6834beaf915d1d3c16e9960d9b95 Mon Sep 17 00:00:00 2001 From: Tom Date: Thu, 20 Jun 2024 16:27:12 +0200 Subject: [PATCH 4/9] correction d'une inexactitude dans la fonction de valuation --- fflas-ffpack/utils/fflas_randommatrix.h | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/fflas-ffpack/utils/fflas_randommatrix.h b/fflas-ffpack/utils/fflas_randommatrix.h index 40e9aad8a..316e844a1 100644 --- a/fflas-ffpack/utils/fflas_randommatrix.h +++ b/fflas-ffpack/utils/fflas_randommatrix.h @@ -494,10 +494,10 @@ namespace FFPACK{ } // O(1) - size_t valuate(int ti, int r, int n, int i, int Is_pivot_not_moved, int nb_pivot_bf_i, int nb_pivot_after_i_not_moved, int nb_pivot_before_i_not_moved) { + size_t valuate(int ti, int r, int n, int i, int Is_pivot_not_moved,int nb_pivot_after_i, int nb_pivot_bf_i, int nb_pivot_after_i_not_moved, int nb_pivot_before_i_not_moved) { // Compute the valuation of a given leading submatrix ti return ti + std::min(i + 1 - nb_pivot_bf_i, nb_pivot_after_i_not_moved - Is_pivot_not_moved) + - std::min((n-1) - (i + 1) - r + nb_pivot_bf_i, nb_pivot_before_i_not_moved - Is_pivot_not_moved); + std::min(n - (i + 1) - nb_pivot_after_i, nb_pivot_before_i_not_moved - Is_pivot_not_moved); } /** @brief genenration of an Rank Profile Matrix randomly @@ -534,6 +534,7 @@ namespace FFPACK{ size_t* H = FFLAS::fflas_new(n-1); size_t* T = FFLAS::fflas_new(n-1); size_t* nb_pivot_before_index = FFLAS::fflas_new(n-1); + size_t* nb_pivot_after_index = FFLAS::fflas_new(n-1); size_t* nb_pivot_before_index_not_moved = FFLAS::fflas_new(n-1); size_t* nb_pivot_after_index_not_moved = FFLAS::fflas_new(n-1); @@ -552,10 +553,12 @@ namespace FFPACK{ nb_pivot_before_index[0] = H[0]; + nb_pivot_after_index[0] = r; nb_pivot_after_index_not_moved[0]=r; nb_pivot_before_index_not_moved[0]=H[0]; for (size_t i = 1; i < n - 1; ++i) { nb_pivot_before_index[i] = nb_pivot_before_index[i - 1] + H[i]; + nb_pivot_after_index[i] = r-nb_pivot_before_index[i-1]; nb_pivot_after_index_not_moved[i] = r-nb_pivot_before_index[i-1]; nb_pivot_before_index_not_moved[i] = nb_pivot_before_index[i]; } @@ -616,6 +619,7 @@ namespace FFPACK{ for (size_t k = prev_i + 1; k <= prev_i + (prev_j - new_j); ++k) { T[k] += 1; + nb_pivot_after_index[k] += 1; } } else { new_i = valid_moves[rand_index]; @@ -641,7 +645,7 @@ namespace FFPACK{ /// valutation bool undo = true; for (size_t k = 0; k < n - 1; ++k) { - if (valuate(T[k], r, n, k, H[k], nb_pivot_before_index[k], nb_pivot_after_index_not_moved[k], nb_pivot_before_index_not_moved[k]) >= t) { + if (valuate(T[k], r, n, k, H[k], nb_pivot_after_index[k], nb_pivot_before_index[k], nb_pivot_after_index_not_moved[k], nb_pivot_before_index_not_moved[k]) >= t) { undo = false; break; } @@ -663,6 +667,7 @@ namespace FFPACK{ start_up--; for (size_t k = prev_i + 1; k <= prev_i + (prev_j - new_j); ++k) { T[k] -= 1; + nb_pivot_after_index[k] -= 1; } } From bc9d347c304880a95709a0f712f17cac44a46713 Mon Sep 17 00:00:00 2001 From: Tom Date: Thu, 20 Jun 2024 16:42:07 +0200 Subject: [PATCH 5/9] =?UTF-8?q?ajout=20de=20commentaires=20dans=20l'algori?= =?UTF-8?q?thme=20pour=20la=20lisibilit=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fflas-ffpack/utils/fflas_randommatrix.h | 33 +++++++++++++------------ 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/fflas-ffpack/utils/fflas_randommatrix.h b/fflas-ffpack/utils/fflas_randommatrix.h index 316e844a1..8d0266ad2 100644 --- a/fflas-ffpack/utils/fflas_randommatrix.h +++ b/fflas-ffpack/utils/fflas_randommatrix.h @@ -467,8 +467,8 @@ namespace FFPACK{ FFLAS::fflas_delete (randcols,randrows); } - // O(l*len(L)) - // id = true if we consider the identity, else False + // O(l*len(L)+M*len(M)) + // compute all the valid moves in the array valid_moves depending on the free areas described in L and M inline void compute_valid_moves(std::vector* valid_moves, size_t* start_up, size_t l, size_t* L, size_t lengthL, int llim, size_t m, size_t* M, size_t lengthM, int mlim) { valid_moves->clear(); @@ -482,11 +482,10 @@ namespace FFPACK{ } } + // start_up point where the valid moves change direction *start_up = valid_moves->size(); - //std::cout << mlim << "//" << m << std::endl; for (size_t i = (size_t) mlim+1; i < m; ++i) { - //std::cout << i << (std::find(M, M + lengthM, i) == M + lengthM) << std::endl; if (std::find(M, M + lengthM, i) == M + lengthM) { valid_moves->push_back(i); } @@ -533,9 +532,9 @@ namespace FFPACK{ size_t* H = FFLAS::fflas_new(n-1); size_t* T = FFLAS::fflas_new(n-1); - size_t* nb_pivot_before_index = FFLAS::fflas_new(n-1); - size_t* nb_pivot_after_index = FFLAS::fflas_new(n-1); - size_t* nb_pivot_before_index_not_moved = FFLAS::fflas_new(n-1); + size_t* nb_pivot_before_index = FFLAS::fflas_new(n-1); // pivots that are on lines before line i + size_t* nb_pivot_after_index = FFLAS::fflas_new(n-1); // pivots that are on columns before the last column of the line i + size_t* nb_pivot_before_index_not_moved = FFLAS::fflas_new(n-1); // same idea with pivots that didn't move yet size_t* nb_pivot_after_index_not_moved = FFLAS::fflas_new(n-1); for (size_t i = 0; i= start_up) { + // undo the move and erase it from the valid moves rows[h] = prev_i; valid_moves.erase(valid_moves.begin()+rand_index); - + // undo of the arrays for valuation func for (size_t k = new_i; k < prev_i; ++k) { T[k] -= 1; nb_pivot_before_index[k] -= 1; } } else { + // undo the move and erase it from the valid moves cols[h] = prev_j; valid_moves.erase(valid_moves.begin()+rand_index); + // undo of the arrays for valuation func start_up--; for (size_t k = prev_i + 1; k <= prev_i + (prev_j - new_j); ++k) { T[k] -= 1; @@ -671,6 +673,7 @@ namespace FFPACK{ } } + // undo of the arrays for valuation func for (size_t k = 0; k Date: Fri, 21 Jun 2024 09:21:40 +0200 Subject: [PATCH 6/9] un peu de commentaire en plus --- fflas-ffpack/utils/fflas_randommatrix.h | 1 + 1 file changed, 1 insertion(+) diff --git a/fflas-ffpack/utils/fflas_randommatrix.h b/fflas-ffpack/utils/fflas_randommatrix.h index 8d0266ad2..461accf77 100644 --- a/fflas-ffpack/utils/fflas_randommatrix.h +++ b/fflas-ffpack/utils/fflas_randommatrix.h @@ -493,6 +493,7 @@ namespace FFPACK{ } // O(1) + // estimate what rank a submatrix is able to reach given the current configuration of the algorithm size_t valuate(int ti, int r, int n, int i, int Is_pivot_not_moved,int nb_pivot_after_i, int nb_pivot_bf_i, int nb_pivot_after_i_not_moved, int nb_pivot_before_i_not_moved) { // Compute the valuation of a given leading submatrix ti return ti + std::min(i + 1 - nb_pivot_bf_i, nb_pivot_after_i_not_moved - Is_pivot_not_moved) + From a3060c2ce228770ed51e1cdd9cd976c3bd9098fa Mon Sep 17 00:00:00 2001 From: Tom Date: Mon, 1 Jul 2024 15:50:38 +0200 Subject: [PATCH 7/9] benchmark changes for tests --- benchmarks/benchmark-quasisep.C | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/benchmarks/benchmark-quasisep.C b/benchmarks/benchmark-quasisep.C index c644594af..1c7f6d0c1 100644 --- a/benchmarks/benchmark-quasisep.C +++ b/benchmarks/benchmark-quasisep.C @@ -49,18 +49,35 @@ void run_with_field(int q, size_t n, size_t m, size_t t, size_t r, size_t iter, Element_ptr A, TS; double time_gen = 0, time_cbxts =0; - double time_RPMGen = 0; + double time_RPMGen_Tom = 0, time_RPMGen = 0; for (size_t i=0;i (r); - size_t * cols = FFLAS::fflas_new (r); + size_t * rows1 = FFLAS::fflas_new (r); + size_t * cols1 = FFLAS::fflas_new (r); + + if (r < 2000) { + chrono.clear(); + chrono.start(); + RandomLTQSRankProfileMatrix (n, r, t, rows1, cols1); + chrono.stop(); + + time_RPMGen += chrono.usertime(); + } + else { + time_RPMGen = -1; + } + + size_t * rows2 = FFLAS::fflas_new (r); + size_t * cols2 = FFLAS::fflas_new (r); chrono.clear(); chrono.start(); - RandomLTQSRankProfileMatrix_Tom (n, r, t, rows, cols); + RandomLTQSRankProfileMatrix_Tom (n, r, t, rows2, cols2); chrono.stop(); - time_RPMGen += chrono.usertime(); + time_RPMGen_Tom += chrono.usertime(); + + FFLAS::fflas_delete(rows1, rows2, cols1, cols2); A = FFLAS::fflas_new (F, n, n); size_t lda=n; @@ -116,7 +133,8 @@ void run_with_field(int q, size_t n, size_t m, size_t t, size_t r, size_t iter, // ----------- // Standard output for benchmark - Alexis Breust 2014/11/14 // std::cout << "Time: " << (time_gen + time_cbxts) / double(iter) << " Gfops: Irrelevant (Generator) Specific times: " << time_gen / double(iter)<<" (for construction)" << time_cbxts / double(iter)<<" (for CB x TS)" ; - std::cout << "Time : " << time_RPMGen / double(iter) << std::endl; + std::cout << "Time_stand : " << time_RPMGen / double(iter) << std::endl; + std::cout << "Time_Tom : " << time_RPMGen_Tom / double(iter) << std::endl; } int main(int argc, char** argv) { From 97d6149049eda2e4b2a5a67a630cd4c266640b93 Mon Sep 17 00:00:00 2001 From: Tom Date: Tue, 2 Jul 2024 15:55:00 +0200 Subject: [PATCH 8/9] optimisation du comput_valid_moves (plus de find = meilleur perf temporelles et changement du benchmark pour utiliser dans certains tests --- benchmarks/benchmark-quasisep.C | 48 +++++++++++++------------ fflas-ffpack/utils/fflas_randommatrix.h | 29 ++++++++++++--- 2 files changed, 50 insertions(+), 27 deletions(-) diff --git a/benchmarks/benchmark-quasisep.C b/benchmarks/benchmark-quasisep.C index 1c7f6d0c1..76947f423 100644 --- a/benchmarks/benchmark-quasisep.C +++ b/benchmarks/benchmark-quasisep.C @@ -49,35 +49,37 @@ void run_with_field(int q, size_t n, size_t m, size_t t, size_t r, size_t iter, Element_ptr A, TS; double time_gen = 0, time_cbxts =0; - double time_RPMGen_Tom = 0, time_RPMGen = 0; + //double time_RPMGen_Tom = 0, time_RPMGen = 0; for (size_t i=0;i (r); size_t * cols1 = FFLAS::fflas_new (r); - if (r < 2000) { - chrono.clear(); - chrono.start(); - RandomLTQSRankProfileMatrix (n, r, t, rows1, cols1); - chrono.stop(); + RandomLTQSRankProfileMatrix (n, r, t, rows1, cols1); - time_RPMGen += chrono.usertime(); + std::cout << "rows :"; + for ( size_t i = 0; i (r); - size_t * cols2 = FFLAS::fflas_new (r); + std::cout << std::endl; - chrono.clear(); - chrono.start(); - RandomLTQSRankProfileMatrix_Tom (n, r, t, rows2, cols2); - chrono.stop(); + std::cout << "cols :"; + for ( size_t j = 0; j (r); + //size_t * cols2 = FFLAS::fflas_new (r); +// + //chrono.clear(); + //chrono.start(); + //RandomLTQSRankProfileMatrix_Tom (n, r, t, rows2, cols2); + //chrono.stop(); +// + //time_RPMGen_Tom += chrono.usertime(); - FFLAS::fflas_delete(rows1, rows2, cols1, cols2); + FFLAS::fflas_delete(rows1,cols1); A = FFLAS::fflas_new (F, n, n); size_t lda=n; @@ -133,8 +135,8 @@ void run_with_field(int q, size_t n, size_t m, size_t t, size_t r, size_t iter, // ----------- // Standard output for benchmark - Alexis Breust 2014/11/14 // std::cout << "Time: " << (time_gen + time_cbxts) / double(iter) << " Gfops: Irrelevant (Generator) Specific times: " << time_gen / double(iter)<<" (for construction)" << time_cbxts / double(iter)<<" (for CB x TS)" ; - std::cout << "Time_stand : " << time_RPMGen / double(iter) << std::endl; - std::cout << "Time_Tom : " << time_RPMGen_Tom / double(iter) << std::endl; + //std::cout << "Time_stand : " << time_RPMGen / double(iter) << std::endl; + //std::cout << "Time_Tom : " << time_RPMGen_Tom / double(iter) << std::endl; } int main(int argc, char** argv) { @@ -166,8 +168,8 @@ int main(int argc, char** argv) { run_with_field >(q, n, m, t, r, iter, seed); - std::cout << "( "; - FFLAS::writeCommandString(std::cout, as) << ")" << std::endl; + //std::cout << "( "; + //FFLAS::writeCommandString(std::cout, as) << ")" << std::endl; return 0; } diff --git a/fflas-ffpack/utils/fflas_randommatrix.h b/fflas-ffpack/utils/fflas_randommatrix.h index 461accf77..57b56c5bb 100644 --- a/fflas-ffpack/utils/fflas_randommatrix.h +++ b/fflas-ffpack/utils/fflas_randommatrix.h @@ -469,7 +469,7 @@ namespace FFPACK{ // O(l*len(L)+M*len(M)) // compute all the valid moves in the array valid_moves depending on the free areas described in L and M - inline void compute_valid_moves(std::vector* valid_moves, size_t* start_up, size_t l, size_t* L, size_t lengthL, int llim, size_t m, size_t* M, size_t lengthM, int mlim) { + inline void compute_valid_moves(std::vector* valid_moves, size_t* start_up, size_t l, size_t* L, size_t lengthL, int llim, size_t m, size_t* M, size_t lengthM, int mlim, std::vector availrows, std::vector availcols) { valid_moves->clear(); // Base case: Identity @@ -477,7 +477,7 @@ namespace FFPACK{ // Compute all the empty columns/lines for (size_t j = (size_t) llim+1; j < l; ++j) { - if (std::find(L, L + lengthL, j) == L + lengthL) { + if (availcols[j]) { valid_moves->push_back(j); } } @@ -486,7 +486,7 @@ namespace FFPACK{ *start_up = valid_moves->size(); for (size_t i = (size_t) mlim+1; i < m; ++i) { - if (std::find(M, M + lengthM, i) == M + lengthM) { + if (availrows[i]) { valid_moves->push_back(i); } } @@ -538,6 +538,9 @@ namespace FFPACK{ size_t* nb_pivot_before_index_not_moved = FFLAS::fflas_new(n-1); // same idea with pivots that didn't move yet size_t* nb_pivot_after_index_not_moved = FFLAS::fflas_new(n-1); + std::vector availablerows (n-1, true); // indicate wether the row i is available or not + std::vector availablecols (n-1, true); // same idea with col j + for (size_t i = 0; i= t) { @@ -675,6 +684,7 @@ namespace FFPACK{ } // undo of the arrays for valuation func + // O(n) for (size_t k = 0; k Date: Thu, 11 Jul 2024 11:56:40 +0200 Subject: [PATCH 9/9] changement pratique pour faire des tests de performance sur le benchmark-quasisep --- benchmarks/benchmark-quasisep.C | 65 +++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 28 deletions(-) diff --git a/benchmarks/benchmark-quasisep.C b/benchmarks/benchmark-quasisep.C index 76947f423..713500afd 100644 --- a/benchmarks/benchmark-quasisep.C +++ b/benchmarks/benchmark-quasisep.C @@ -49,37 +49,46 @@ void run_with_field(int q, size_t n, size_t m, size_t t, size_t r, size_t iter, Element_ptr A, TS; double time_gen = 0, time_cbxts =0; - //double time_RPMGen_Tom = 0, time_RPMGen = 0; + double time_RPMGen_Tom = 0, time_RPMGen = 0; for (size_t i=0;i (r); - size_t * cols1 = FFLAS::fflas_new (r); - - RandomLTQSRankProfileMatrix (n, r, t, rows1, cols1); + if ( r >= 1000 && r <= 1400){ + size_t * rows1 = FFLAS::fflas_new (r); + size_t * cols1 = FFLAS::fflas_new (r); - std::cout << "rows :"; - for ( size_t i = 0; i (r); - //size_t * cols2 = FFLAS::fflas_new (r); -// - //chrono.clear(); - //chrono.start(); - //RandomLTQSRankProfileMatrix_Tom (n, r, t, rows2, cols2); - //chrono.stop(); -// - //time_RPMGen_Tom += chrono.usertime(); - FFLAS::fflas_delete(rows1,cols1); + //std::cout << "rows :"; + //for ( size_t i = 0; i (r); + size_t * cols2 = FFLAS::fflas_new (r); + + chrono.clear(); + chrono.start(); + RandomLTQSRankProfileMatrix_Tom (n, r, t, rows2, cols2); + chrono.stop(); + + time_RPMGen_Tom += chrono.usertime(); + + FFLAS::fflas_delete(rows2,cols2); A = FFLAS::fflas_new (F, n, n); size_t lda=n; @@ -135,8 +144,8 @@ void run_with_field(int q, size_t n, size_t m, size_t t, size_t r, size_t iter, // ----------- // Standard output for benchmark - Alexis Breust 2014/11/14 // std::cout << "Time: " << (time_gen + time_cbxts) / double(iter) << " Gfops: Irrelevant (Generator) Specific times: " << time_gen / double(iter)<<" (for construction)" << time_cbxts / double(iter)<<" (for CB x TS)" ; - //std::cout << "Time_stand : " << time_RPMGen / double(iter) << std::endl; - //std::cout << "Time_Tom : " << time_RPMGen_Tom / double(iter) << std::endl; + std::cout << "Time_stand : " << time_RPMGen / double(iter) << std::endl; + std::cout << "Time_Tom : " << time_RPMGen_Tom / double(iter) << std::endl; } int main(int argc, char** argv) { @@ -168,8 +177,8 @@ int main(int argc, char** argv) { run_with_field >(q, n, m, t, r, iter, seed); - //std::cout << "( "; - //FFLAS::writeCommandString(std::cout, as) << ")" << std::endl; + std::cout << "( "; + FFLAS::writeCommandString(std::cout, as) << ")" << std::endl; return 0; }