16#include <Matrice_Morse.h>
18#include <unordered_map>
19#include <Matrice_Morse_Sym.h>
20#include <Check_espace_virtuel.h>
24#include <Array_tools.h>
64 for(
int i=0; i<n; i++)
67 s <<
"--------------------------------" << finl;
71 <<
" k= " << k << finl;
85 int numerotation_fortran=(
tab1_[0]==1);
90 s <<
"Matrix morse on the processor " << proc <<
" : " << finl;
94 for(
int i=0; i<n; i++)
105 for (
int j=0; j<i; j++)
107 for (
auto k=
tab1_(j)-numerotation_fortran; k<
tab1_(j+1)-numerotation_fortran; k++)
108 if (
tab2_(k)-numerotation_fortran==i)
111 int ligne=
tab2_(
tab1_(i)-numerotation_fortran)-numerotation_fortran;
114 Cerr <<
"Problem detected on this Matrice_Morse_Sym." << finl;
115 Cerr <<
"The diagonal of the line " << ligne <<
" must be stored even if it is null." << finl;
119 for (
auto k=
tab1_(i)-numerotation_fortran; k<
tab1_(i+1)-numerotation_fortran; k++)
120 if (
tab2_(k)+!numerotation_fortran==0)
121 Cerr<<
"Line " <<i<<
" no coefficient "<<k<<finl;
125 tab_imp[
tab2_(k)-numerotation_fortran]=
" ";
127 tab_imp[
tab2_(k)-numerotation_fortran]=
"";
147 int numerotation_fortran=(
tab1_[0]==1);
152 s <<
"Matrix morse on the processor " << proc <<
" : " << finl;
156 for(
int i=0; i<n; i++)
159 tab_imp[k]=
"\u2588\u2588";
167 for (
int j=0; j<i; j++)
169 for (
auto k=
tab1_(j)-numerotation_fortran; k<
tab1_(j+1)-numerotation_fortran; k++)
170 if (
tab2_(k)-numerotation_fortran==i)
171 tab_imp[j] = (std::abs(
coeff_(k)) < 1e-20) ?
" " :
"\u2592\u2592";
173 int ligne=
tab2_(
tab1_(i)-numerotation_fortran)-numerotation_fortran;
176 Cerr <<
"Problem detected on this Matrice_Morse_Sym." << finl;
177 Cerr <<
"The diagonal of the line " << ligne <<
" must be stored even if it is null." << finl;
181 for (
auto k=
tab1_(i)-numerotation_fortran; k<
tab1_(i+1)-numerotation_fortran; k++)
182 if (
tab2_(k)+!numerotation_fortran==0)
183 Cerr<<
"Line " <<i<<
" no coefficient "<<k<<finl;
185 tab_imp[
tab2_(k)-numerotation_fortran] = (std::abs(
coeff_(k)) < 1e-20) ?
" " :
"\u2592\u2592";
201 Cerr <<
"Warning, matrix market format is not available yet in parallel." << finl;
210 mtx.
setf(ios::scientific);
212 Cerr <<
"Matrix (" << rows <<
" lines) written into file: " << filename <<
" ... " << finl;
213 mtx <<
"%%MatrixMarket matrix coordinate real " << (sub_type(
Matrice_Morse_Sym, *
this) ?
"symmetric" :
"general") << finl;
214 Cerr <<
"Matrix (" << rows <<
" lines) written into file: " << filename << finl;
215 mtx <<
"%%matrix" << finl;
216 mtx << rows <<
" " << rows <<
" " <<
get_tab1()[rows] << finl;
217 for (
int row=0; row<rows; row++)
246template<
typename _SIZE_>
271template<
typename _SIZE_>
281 const DoubleLists& valeurs,
282 const DoubleVect& terme_diag)
286 remplir(voisins, valeurs, terme_diag);
303template<
typename _SIZE_>
323 if (Ind.
size()==0)
return;
326 assert(Ind.
nb_dim() == 2);
338 for (
int i=0; i<nInd; i++)
340 if (n < Ind(i,0)) n = Ind(i,0);
341 if (m < Ind(i,1)) m = Ind(i,1);
345 if (n < n_ancien) n = n_ancien;
346 if (m < m_ancien) m = m_ancien;
350 auto tab1_temp(
tab1_);
357 for (
int i=1; i<=n_ancien; i++)
358 tab1_[i] = tab1_temp[i] - tab1_temp[i-1];
359 for (
int i=n_ancien+1; i<=n; i++)
366 for (
int i=0; i<nInd; i++)
369 int i1 = Ind(i,1) + 1;
371 int test_present = 0;
375 auto kmin = tab1_temp[i0]-1;
376 auto kmax = tab1_temp[i0+1]-1;
377 for (
auto k=kmin; k<kmax; k++)
398 for (
int i=1; i<=n; i++)
401 auto nnz_ancien =
tab2_.size_array();
402 auto nnz = nnz_ancien + i_nouveaux;
404 auto tab2_temp(
tab2_);
413 for (
int i=0; i<n_ancien; i++)
415 for (
auto j1 = tab1_temp[i]-1, j2 =
tab1_[i]-1;
416 j1 < tab1_temp[i+1]-1;
419 tab2_[j2] = tab2_temp[j1];
420 coeff_[j2] = coeff_temp[j1];
424 for (
int i=0; i<nInd; i++)
427 int j1 = Ind(i,1) + 1;
445 for(
int i=0; i<nbis; i++)
449 for (
auto k2=k; k2<
tab1_(i+1)-1; k2++)
468template<
typename _SIZE_>
476 if (
tab1_.size_array()!=(n+1) || (
tab1_[n]-1)!=nnz )
495 operator()(i,i) = 1.0;
523 int coeff_quasi_nuls=0;
524 auto tab_elim_coeff(
tab2_);
528 ArrOfDouble tab_coeff_max(n);
534 auto tab1 =
tab1_.view_ro();
535 CDoubleArrView coeff =
coeff_.view_ro();
536 DoubleArrView coeff_max = tab_coeff_max.view_rw();
537 auto elim_coeff = tab_elim_coeff.view_rw();
538 IntArrView cnt = tab_cnt.view_rw();
539 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), range_1D(0, n), KOKKOS_LAMBDA(
const int i)
542 auto k2 = tab1(i+1)-1;
543 for (
auto k = k1; k < k2; k++)
545 double abs_c = Kokkos::fabs(coeff(k));
546 if (abs_c > coeff_max(i)) coeff_max(i) = abs_c;
549 Kokkos::atomic_add(&cnt(0), 1);
554 end_gpu_timer(__KERNEL_NAME__);
555 coeff_nuls = tab_cnt(0);
558 if (elim_coeff_nul==2)
564 auto tab1 =
tab1_.view_ro();
565 CDoubleArrView coeff =
coeff_.view_ro();
566 CDoubleArrView coeff_max = tab_coeff_max.view_ro();
567 IntArrView elim_coeff = tab_elim_coeff.view_rw();
568 IntArrView cnt = tab_cnt.view_rw();
569 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), range_1D(0, n), KOKKOS_LAMBDA(
const int i)
571 double cm = coeff_max(i);
572 if (!est_egal(cm, 0., eps) && cm < 1e10)
574 auto k1 = tab1(i) - 1;
575 auto k2 = tab1(i + 1) - 1;
576 for (
auto k = k1; k < k2; k++)
577 if (coeff(k) != 0 && est_egal(Kokkos::fabs(coeff(k)) / cm, 0., eps))
579 Kokkos::atomic_add(&cnt(0), 1);
584 end_gpu_timer(__KERNEL_NAME__);
585 coeff_quasi_nuls = tab_cnt(0);
591 auto tab1 =
tab1_.view_ro();
592 CIntArrView tab2 =
tab2_.view_ro();
593 CDoubleArrView coeff =
coeff_.view_ro();
594 IntArrView elim_coeff = tab_elim_coeff.view_rw();
595 ArrOfInt tab_doublons(1);
597 ArrOfInt tab_error(1);
599 IntArrView doublons = tab_doublons.view_rw();
600 IntArrView error = tab_error.view_rw();
601 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), range_1D(0, n), KOKKOS_LAMBDA(
const int i)
604 auto k2 = tab1(i+1)-1;
606 for (
auto k = k1; k < k2; k++)
614 for (
auto kk = k-1; kk >= k1; kk--)
620 Kokkos::atomic_add(&doublons(0), 1);
623 if (coeff(kk) != coeff(k))
624 Kokkos::atomic_add(&error(0), 1);
631 end_gpu_timer(__KERNEL_NAME__);
632 nb_doublons = tab_doublons(0);
635 Cerr <<
"Error in a Matrix Morse: duplicate entries with different values!" << finl;
642 if (nb_doublons || coeff_nuls || coeff_quasi_nuls)
645 ArrOfInt tab_kept_per_row(n);
647 auto tab1 =
tab1_.view_ro();
648 CIntArrView elim_coeff = tab_elim_coeff.view_ro();
649 IntArrView kept_per_row = tab_kept_per_row.view_wo();
650 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), range_1D(0, n), KOKKOS_LAMBDA(
const int i)
654 auto k2 = tab1(i+1)-1;
655 for (
auto k = k1; k < k2; k++)
656 if (!elim_coeff(k)) count++;
657 kept_per_row(i) = count;
659 end_gpu_timer(__KERNEL_NAME__);
663 auto old_tab1(
tab1_);
666 using tab1_scan_t =
decltype(nnz);
668 auto tab1 =
tab1_.view_rw();
669 CIntArrView kept_per_row = tab_kept_per_row.view_ro();
670 Kokkos::parallel_scan(start_gpu_timer(__KERNEL_NAME__), range_1D(0, n), KOKKOS_LAMBDA(
const int i, tab1_scan_t& update,
const bool final)
672 update += kept_per_row(i);
673 if (
final) tab1(i+1) = update + 1;
675 end_gpu_timer(__KERNEL_NAME__);
682 auto new_tab2(
tab2_);
684 auto tab1 =
tab1_.view_ro();
685 auto old_tab1_ro = old_tab1.view_ro();
686 CDoubleArrView coeff_src =
coeff_.view_ro();
687 CIntArrView tab2_src =
tab2_.view_ro();
688 DoubleArrView coeff_dst = new_coeff.view_wo();
689 IntArrView tab2_dst = new_tab2.view_wo();
690 CIntArrView elim_coeff = tab_elim_coeff.view_ro();
691 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), range_1D(0, n), KOKKOS_LAMBDA(
const int i)
693 auto new_pos = tab1(i) - 1;
694 auto k1 = old_tab1_ro(i)-1;
695 auto k2 = old_tab1_ro(i+1)-1;
696 for (
auto k = k1; k < k2; k++)
699 coeff_dst(new_pos) = coeff_src(k);
700 tab2_dst(new_pos) = tab2_src(k);
704 end_gpu_timer(__KERNEL_NAME__);
709 auto tab2 =
tab2_.view_rw();
710 auto coeff =
coeff_.view_rw();
711 CIntArrView new_tab2_ro = new_tab2.view_ro();
712 CDoubleArrView new_coeff_ro = new_coeff.view_ro();
713 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), range_1D(0, nnz), KOKKOS_LAMBDA(
const int i)
715 tab2(i) = new_tab2_ro(i);
716 coeff(i) = new_coeff_ro(i);
718 end_gpu_timer(__KERNEL_NAME__);
763 Cerr <<
"Matrice_Morse::transpose bad dimensions" << finl;
770 Cerr <<
"Matrice_Morse::transpose bad dimensions" << finl;
774 for(
int i=0; i<=jk; i++ )
tab1_[i] = 0 ;
775 for(
int i=0; i<n; i++)
777 for(
auto k=a.
tab1_[i]-1; k<a.
tab1_[i+1]-1; k++)
785 for(
int i=0; i<n; i++)
787 for(
auto k=a.
tab1_[i]-1; k<a.
tab1_[i+1]-1; k++)
789 int j = a.
tab2_[k]-1 ;
790 auto next =
tab1_[j] ;
792 tab2_[next-1] = i+1 ;
796 for(
int i=jk-1; i>=0; i--)
tab1_[i+1] =
tab1_[i] ;
814 Cerr <<
"Matrice_Morse::diagmulmat bad dimensions" << finl;
817 F77NAME(DIAMUA)(&m ,&l,
831 Cerr <<
"Matrice_Morse::partie_sup : bad dimensions m!=n." << finl;
839 for(
int i=0; i< n; i++)
843 for(
auto k = a.
tab1_[i]-1; k< a.
tab1_[i+1]-1; k++)
845 if (a.
tab2_[k]-1 >= i)
850 if (a.
tab2_[k] == i) kdiag = ko ;
853 if (kdiag != -1 && kdiag != kfirst)
860 tab1_[i] = kfirst+1 ;
862 auto nnz = (ko + 1) ;
864 tab1_[n] = (nnz) + 1 ;
879 const int n =
tab1_.size_array() - 1;
888 auto tab1 =
tab1_.view_ro();
889 CIntArrView tab2 =
tab2_.view_ro();
890 CDoubleArrView coeff =
coeff_.view_ro();
891 CDoubleArrView x = tab_x.view_ro();
892 DoubleArrView resu = tab_resu.view_rw();
893 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__),
894 Kokkos::RangePolicy<>(0, n), KOKKOS_LAMBDA(
897 auto start = tab1(i)-1;
898 auto end = tab1(i + 1)-1;
901 for (
auto k = start; k < end; k++)
904 tmp+= coeff(k) * x(j);
908 end_gpu_timer(__KERNEL_NAME__);
914 coeff_.ensureDataOnHost();
916 const DoubleVect& x = tab_x;
917 DoubleVect& resu = tab_resu;
918 const auto *tab1_ptr =
tab1_.addr() + 1;
919 const int *tab2_ptr =
tab2_.addr();
920 const double *coeff_ptr =
coeff_.addr();
921 const double *x_fortran = x.
addr() - 1;
923 for (
int i = 0; i < n; i++, tab1_ptr++)
925 const auto kmax = *tab1_ptr;
926 assert(kmax >= k_fortran && kmax <=
tab2_.size_array() + 1);
928 assert(k_fortran ==
tab1_[i] && tab2_ptr ==
tab2_.addr() + (k_fortran - 1));
929 for (; k_fortran < kmax; k_fortran++, tab2_ptr++, coeff_ptr++)
931 int colonne = *tab2_ptr;
933 t += (*coeff_ptr) * x_fortran[colonne];
944 ToDo_Kokkos(
"critical ?");
950 for(
int i=0; i<n; i++)
956 if (est_reel_pas_com[j]) t +=
coeff_(k)*x[j];
984 double* t=
new double[nb_comp];
987 for(
int i=0; i<n; i++)
989 for (ncomp=0; ncomp<nb_comp; ncomp++)
992 for (ncomp=0; ncomp<nb_comp; ncomp++)
994 for (ncomp=0; ncomp<nb_comp; ncomp++)
995 resu(i,ncomp) += t[ncomp] ;
1015 for(
int i=0; i<n; i++)
1032 for(
int i=0; i<n; i++)
1034 if (est_reel_pas_com[i])
1061#ifndef TRUST_USE_GPU
1069 &nzmax, iw.
addr(), &ierr);
1091 using idx_t = std::remove_reference_t<
decltype(c_tab1[0])>;
1095 std::unordered_map<int, idx_t> col_to_pos;
1096 col_to_pos.reserve(256);
1097 for (
int i = 0; i < nrow; ++i)
1102 for (
auto k = a_tab1[i] - 1; k < a_tab1[i + 1] - 1; ++k)
1104 c_tab2[nnz_c] = (int) a_tab2[k];
1105 c_coeff[nnz_c] = a_coeff[k];
1106 col_to_pos[(int) a_tab2[k]] = nnz_c;
1111 for (
auto k = b_tab1[i] - 1; k < b_tab1[i + 1] - 1; ++k)
1113 const int col = (int) b_tab2[k];
1114 auto it = col_to_pos.find(col);
1115 if (it != col_to_pos.end())
1116 c_coeff[it->second] += b_coeff[k];
1119 c_tab2[nnz_c] = col;
1120 c_coeff[nnz_c] = b_coeff[k];
1121 col_to_pos[col] = nnz_c;
1126 c_tab1[i + 1] = nnz_c + 1;
1129 const auto nnz = C.
tab1_[nrow] - 1;
1139 for (
int i = 0; i < nrow; i++)
1143 if (ncoeff != ncoeff_A)
return false;
1145 for (
auto i = 0; i < ncoeff; i++)
1170 double coeff_seuil)
const
1172 return inverse(secmem, solution, coeff_seuil, -1);
1179 double coeff_seuil,
int max_iter)
const
1183 Cerr <<
"Matrice_Morse::inverse has never been tested in parallel" << finl;
1184 Cerr <<
"Try 'Solveur Gmres { diag }' or 'Solveur Petsc Gmres { precond diag { } }'" << finl;
1185 Cerr <<
"instead of 'Solveur Gmres { }' which is not parallelized yet." << finl;
1189 const bool retry_on_failure = (max_iter < 0);
1191 DoubleVect toto(secmem);
1194 int lf = std::min(lf_min,
ordre()/2);
1196 int ima = std::min(lf_min,
ordre()/2);
1199 DoubleVect Resini(toto);
1204 double r, coeff_seuilr;
1209 int iw = (int)(n2 + 2);
1225 Cerr <<
"Error in ilut 'matrix may be wrong' dixit SAAD" << finl;
1229 Cerr <<
"Error in ilut : overflow in L" << finl;
1233 Cerr <<
"Error in ilut : overflow in U" << finl;
1237 Cerr <<
"Illegal value for lfil : it may be a memory trouble" << finl;
1241 Cerr <<
"Empty line met" << finl;
1245 Cerr <<
"Pivot null met ! at step " << ie << finl;
1253 assert_espace_virtuel_vect(solution);
1256 r = mp_prodscal(Resini, Resini);
1258 Cout <<
" Initial residu : " << r << finl;
1259 coeff_seuilr = (r == 0) ? DMAXFLOAT : coeff_seuil/r;
1262 int maxits = std::max(minits, retry_on_failure ? nn : max_iter);
1264 F77NAME(PGMRES)(&nn, &ima, toto.
addr(), solution.
addr(), vv.
addr(), &coeff_seuilr,
1270 Cout <<
" ** PGMRES has converged **" << finl;
1273 Cout <<
" ** No convergence after " << maxits <<
" iterations **" << finl;
1274 if (retry_on_failure)
1280 Cerr <<
" The degree of the preconditioning matrix LU is increased: " << lf << finl;
1281 n2 = (int)
tab2_.size_array()+(2*lf*nn);
1290 Cerr <<
"Convergence after 0 iterations !! 'stationnary state may be obtained'" << finl;
1293 Cerr <<
"Something abnormal has happened : it is preferable to stop." << finl;
1312 for(
auto k =
tab1_(i)-1; k<
tab1_(i+1)-1; k++)
1333 tab1_.resize(nrow+1);
1340 tab2_.resize(nzmax);
1348 if (job != 0) values = 1 ;
1352 for(ii=0; ii< nrow; ii++)
1354 for(
auto ka=a.
tab1_[ii]-1; ka < a.
tab1_[ii+1]-1; ka++)
1356 if (values == 1) scal = a.
coeff_[ka] ;
1357 jj = a.
tab2_[ka] - 1 ;
1358 for (
auto kb=b.
tab1_[jj]-1; kb < b.
tab1_[jj+1]-1; kb++)
1360 int jcol = b.
tab2_[kb] -1 ;
1361 int jpos = iw[jcol] ;
1370 tab2_.resize(nzmax);
1372 tab2_[len] = jcol + 1 ;
1373 iw[jcol]= (int)len ;
1383 for (
auto k=
tab1_[ii]-1; k < len+1 ; k++) iw[
tab2_[k]-1] = -1 ;
1384 tab1_[ii+1] = (len+1) + 1 ;
1417 return((-1)*(*
this));
1434 for (
auto i=0; i<size; i++)
1476 auto nnz =
tab2_.size_array();
1483 decltype(nnz) compteur = 0;
1486 for (
int i=0; i<nb_lines; ++i )
1488 auto k0 =
tab1_( i ) - 1;
1489 auto k1 =
tab1_( i + 1 ) - 1;
1490 const auto size = k1 - k0;
1491 const int size_int = (int)size;
1496 for (
int k=0; k<size_int; ++k )
1498 tmp[ k ] =
tab2_( k + k0 ) - 1;
1503 for (
int k=0; k<size_int; ++k )
1505 stencil( k+compteur , 0 ) = i;
1506 stencil( k+compteur , 1 ) = tmp[ k ];
1517template<
typename _T_>
static inline void _fill_slot(_T_& dest,
const double& src);
1518template<>
inline void _fill_slot<double>(
double& dest,
const double& src)
1522template<>
inline void _fill_slot<const double *>(
const double*& dest,
const double& src)
1529template<
typename _TAB_T_,
typename _VALUE_T_>
1532 auto nnz =
tab2_.size_array();
1533 coeffs_span.resize(nnz);
1535 decltype(nnz) compteur = 0;
1537 for (
int i=0; i<nb_lines; ++i )
1539 const auto k0 =
tab1_( i ) - 1;
1540 const auto k1 =
tab1_( i + 1 ) - 1;
1541 const int size_int = (int)(k1 - k0);
1542 for (
int k=0; k<size_int; ++k )
1544 stencil( compteur + k , 0 ) = i;
1545 stencil( compteur + k , 1 ) =
tab2_( k + k0 ) - 1;
1546 ::_fill_slot<_VALUE_T_>(coeffs_span[ compteur + k ],
coeff_(k+k0));
1548 compteur += size_int;
1556 std::vector<const double *>& coeff_ptr)
const
1562 Cerr <<
"Error in Matrice_Morse::get_symmetric_stencil_and_coeff_ptrs( )"<<finl;
1563 Cerr <<
" stencil up to date - function not impl. in this case."<<finl;
1564 Cerr <<
" Aborting..." << finl;
1570 assert( (trustIdType)coeff_ptr.size( ) == stencil.
dimension( 0 ));
1575 StencilCoeffs& coefficients )
const
1579 if(
coeff_.size( ) == 0 )
1581 Cerr <<
"Error in Matrice_Morse::get_stencil_and_coefficients( )"<<finl;
1582 Cerr <<
" The coefficients are not filled."<<finl;
1583 Cerr <<
" Aborting..." << finl;
1587 {
const auto sz =
coeff_.size_array(); coefficients.
resize(sz);
for (
auto k=sz-sz; k<sz; k++) coefficients[k] =
coeff_[k]; }
1613 const DoubleLists& valeurs,
1614 const DoubleVect& terme_diag)
1618 int compteur,rang =0;
1621 auto* p_tab1 =
tab1_.addr();
1622 int* p_tab2 =
tab2_.addr();
1623 double* p_coeff =
coeff_.addr();
1625 int* tab2_ptr = p_tab2;
1628 for (num_elem=0; num_elem<n; num_elem++)
1631 IntList_Curseur liste_vois(voisins[num_elem]);
1632 DoubleList_Curseur liste_val(valeurs[num_elem]);
1636 *tab2_ptr++=num_elem;
1637 *p_coeff++ = terme_diag[num_elem];
1641 *tab2_ptr++ = liste_vois.
valeur();
1642 *p_coeff++ = liste_val.
valeur();
1648 rang += (compteur + 1);
1650 tab1_(num_elem)=rang;
1657 const DoubleLists& valeurs)
1661 int compteur,rang =0;
1664 auto* p_tab1 =
tab1_.addr();
1665 int* p_tab2 =
tab2_.addr();
1666 double* p_coeff =
coeff_.addr();
1668 int* tab2_ptr = p_tab2;
1671 for (num_elem=0; num_elem<n; num_elem++)
1674 IntList_Curseur liste_vois(voisins[num_elem]);
1675 DoubleList_Curseur liste_val(valeurs[num_elem]);
1681 *tab2_ptr++ = liste_vois.
valeur();
1682 *p_coeff++ = liste_val.
valeur();
1690 tab1_(num_elem)=rang;
1713 int lordre = L.
ordre();
1714 for (
int i=0; i<lordre; i++)
1717 matrice_locale += L;
1721 auto nnz=matrice_locale.
nb_coeff();
1726 int mon_nb_lignes=matrice_locale.
nb_lignes();
1727 assert(mon_nb_lignes+ideb<=n);
1728 for (
int i=0; i<ideb; i++)
1730 for (
int i=0; i<mon_nb_lignes; i++)
1732 for (
int i=mon_nb_lignes+ideb; i<n+1; i++)
1733 tab1_(i)=matrice_locale.
tab1_(mon_nb_lignes);
1736 for (
auto i=0; i<nnz; i++)
1740 for (
auto i=0; i<nnz; i++)
1750 for(
int ii=0; ii<=n; ii++)
1752 for(
int ii=0; ii<n; ii++)
1763 for(
int ii=0; ii<=n; ii++)
1778int Matrice_Morse_test()
1798 const auto* p_tab1_ =
get_tab1().addr();
1799 const int* p_tab2_ =
get_tab2().addr();
1802 for(
int i=0; i<N; i++)
1803 for(
auto k = p_tab1_[i]; k < p_tab1_[i+1]; k++)
1805 if (p_tab2_[k-1]-1<N)
1807 ldist = p_tab2_[k-1] - i;
1808 if( min < ldist ) min = ldist;
1818 const auto nb_coefficients =
tab1_( nb_lines ) - 1;
1820 if (
tab2_.size_array( ) != nb_coefficients )
1822 Cerr <<
"invalid tab2 size" << finl;
1826 if (
coeff_.size_array( ) != nb_coefficients )
1828 Cerr <<
"invalid coeff size" << finl;
1832 ArrOfBit flags( nb_columns );
1834 for (
int i=0; i<nb_lines; ++i )
1838 auto k0 =
tab1_( i ) - 1;
1839 auto k1 =
tab1_( i + 1 ) - 1;
1841 for (
auto k=k0; k<k1; ++k )
1843 int j =
tab2_( k ) - 1;
1847 Cerr <<
"invalid column index (<0): " << j << finl;
1851 if ( j >= nb_columns )
1853 Cerr <<
"invalid column index (>nb_cols): " << j <<
" > " << nb_columns << finl;
1859 Cerr <<
"invalid coefficient ( " << i <<
", " << j <<
" ): already defined ( " << k <<
" )" << finl;
1874 const auto nb_coefficients =
tab1_( nb_lines ) - 1;
1876 if (
tab2_.size_array( ) != nb_coefficients )
1878 Cerr <<
"invalid tab2 size" << finl;
1882 if (
coeff_.size_array( ) != nb_coefficients )
1884 Cerr <<
"invalid coeff size" << finl;
1888 ArrOfBit flags( nb_columns );
1890 for (
int i=0; i<nb_lines; ++i )
1894 auto k0 =
tab1_( i ) - 1;
1895 auto k1 =
tab1_( i + 1 ) - 1;
1897 int j0 =
tab2_( k0 ) - 1 - 1;
1899 for (
auto k=k0; k<k1; ++k )
1901 int j =
tab2_( k ) - 1;
1905 Cerr <<
"invalid column index (<0): " << j << finl;
1909 if ( j >= nb_columns )
1911 Cerr <<
"invalid column index (>nb_cols): " << j <<
" > " << nb_columns << finl;
1917 Cerr <<
"invalid coefficient ( " << i <<
", " << j <<
" ): already defined ( " << k <<
" )" << finl;
1923 Cerr <<
"unsorted coefficient: ( " << i <<
", " << j <<
" ) after ( " << i <<
", " << j0 <<
" ) " << finl;;
1942 Cerr <<
"Error in 'Matrice_Morse::assert_check_morse_matrix_structure( )':" << finl;
1943 Cerr <<
" Exiting..." << finl;
1957 Cerr <<
"Error in 'Matrice_Morse::assert_check_sorted_morse_matrix_structure( )':" << finl;
1958 Cerr <<
" Exiting..." << finl;
1979 IntTab loca((
int)max_nnz, 2);
1980 DoubleTab sub_coeffs((
int)max_nnz);
1981 for (
int li=nl0; li <= nl1; li++)
1983 auto idx_coeff =
tab1_(li)-1;
1984 int nb_coeff_on_line = (int)(
tab1_(li+1)-
tab1_(li));
1985 for (
int j=0; j < nb_coeff_on_line; j++)
1987 int col_idx =
tab2_(j+idx_coeff)-1;
1988 if (col_idx >= nc0 && col_idx <= nc1)
1990 loca(tot, 0) = li - nl0;
1991 loca(tot, 1) = col_idx - nc0;
1992 sub_coeffs(tot) =
coeff_(j+idx_coeff);
2002 for (
int i =0 ; i < tot; i++)
2004 int il = loca(i, 0);
2005 int ic = loca(i, 1);
2006 result.
coef(il, ic) = sub_coeffs(i);
2013 for (
int i = 0; i + 1 <
tab1_.size_array(); i++)
2024 for (
int i = 0; i < n; i++)
2026 const auto k0 =
tab1_( i ) - 1;
2027 const auto k1 =
tab1_( i + 1 ) - 1;
2028 for (
auto k=k0; k<k1-1; k++)
2046 for (
int i = 0; i < n; i++)
2049 const auto k2 =
get_tab1()(i + 1) - 1;
2050 for (
auto k = k1; k < k2; k++)
void setbit(int_t i) const
Set bit e to 1.
Class defining operators and methods for all reading operation in an input flow (file,...
Matrice_Base class - Base class of the matrix hierarchy.
bool is_stencil_up_to_date_
virtual DoubleVect & multvect(const DoubleVect &, DoubleVect &) const
Multiplication of a vector by the matrix.
virtual DoubleVect & ajouter_multvect(const DoubleVect &x, DoubleVect &r) const
Matrix-vector multiply-accumulate operation (saxpy).
bool is_stencil_up_to_date() const
Matrice_Morse_Sym class - Represents a sparse symmetric matrix M stored in Morse format.
Matrice_Morse class - Represents a (sparse) matrix M, not necessarily square,.
void clean() override
Remplit la matrice avec des zeros.
friend Matrice_Morse operator+(const Matrice_Morse &, const Matrice_Morse &)
Friend function (outside the class) of the Matrice_Morse class. Addition of 2 Morse-format matrices.
int largeur_de_bande() const
Computes the bandwidth of a Morse matrix.
int morse_matrix_structure_has_changed_
Matrice_Morse & affecte_prod(const Matrice_Morse &A, const Matrice_Morse &B)
Assigns the product of 2 Morse matrices A and B to this object.
void get_stencil_and_coeff_ptrs(Stencil &stencil, std::vector< const double * > &coeff_ptr) const override
void get_stencil(Stencil &stencil) const override
bool check_morse_matrix_structure() const
Sortie & imprimer_image(Sortie &s) const
Matrice_Morse & operator*=(double)
Operator multiplying all elements of a matrix by a scalar.
void WriteFileMTX(const Nom &) const
bool check_sorted_morse_matrix_structure() const
Matrice_Morse & operator=(const Matrice_Morse &)
Assignment operator from one Matrice_Morse to another.
void assert_check_morse_matrix_structure() const
void scale(const double x) override
virtual Matrice_Morse & diagmulmat(const DoubleVect &x)
Matrice_Morse & operator/=(double)
Operator dividing all elements of a matrix by a scalar.
void get_stencil_and_coefficients(Stencil &stencil, StencilCoeffs &coefficients) const override
const auto & get_tab2() const
int ordre() const override
Returns the order of the matrix: - the number of rows if the matrix is square.
bool is_sorted_stencil() const
Sortie & imprimer_formatte(Sortie &s) const override
virtual int inverse(const DoubleVect &, DoubleVect &, double) const
Computes the solution of the linear system: A * solution = secmem.
virtual Matrice_Morse & transpose(const Matrice_Morse &a)
*this = transpose of a.
const IntVect & get_tab1_int32() const
Sortie & imprimer(Sortie &s) const override
void dimensionner(int n, _SIZE_ nnz)
Size the matrix with n lines and n columns and nnz zero-values coefficients.
const auto & get_tab1() const
void set_nb_columns(const int)
DoubleVect & ajouter_multvect_(const DoubleVect &, DoubleVect &) const override
Operation de multiplication-accumulation (saxpy) matrice vecteur.
DoubleVect & ajouter_multvectT_(const DoubleVect &, DoubleVect &) const override
Matrix-vector multiply-accumulate operation (saxpy), by the transposed matrix.
void get_stencil_coeff_templ(Stencil &stencil, _TAB_T_ &coeffs_span) const
void assert_check_sorted_morse_matrix_structure() const
Matrice_Morse & operator+=(const Matrice_Morse &)
DOES NOTHING.
double coef(int i, int j) const
int nb_colonnes() const override
Return local number of columns (=size on the current proc).
bool has_same_morse_matrix_structure(const Matrice_Morse &) const
Matrice_Morse operator-() const
Unary negation operator, returns the opposite of the matrix: - A. Calls operator*(double,...
const auto & get_coeff() const
void set_symmetric(const int)
void remplir(const IntLists &, const DoubleLists &, const DoubleVect &)
virtual Matrice_Morse & partie_sup(const Matrice_Morse &a)
int nb_lignes() const override
Return local number of lines (=size on the current proc).
void compacte(int elim_coeff_nul=0)
Method to check/clean the Matrice_Morse matrix: -Suppress coefficient defined several times.
void construire_sous_bloc(int nl0, int nc0, int nl1, int nc1, Matrice_Morse &result) const
void unite()
Initialize to the identity matrix (modif MT).
void set_tab1_int32() const
DoubleTab & ajouter_multTab_(const DoubleTab &, DoubleTab &) const override
Matrix-matrix multiply-accumulate operation (saxpy) (matrix X represented by an array).
class Nom: a character string for naming TRUST objects.
An array of character strings (VECT(Nom)).
virtual Entree & readOn(Entree &)
Reads an Objet_U from an input stream. Virtual method to override.
static double precision_geom
static const Nom & nom_du_cas()
Returns a constant reference to the case name. This method is static.
virtual Sortie & printOn(Sortie &) const
Writes the object to an output stream. Virtual method to override.
static bool is_parallel()
static void abort()
Abort routine for TRUST on a fatal error.
static int nproc()
Returns the number of processors in the current group. See Comm_Group::nproc() and PE_Groups::current...
static void barrier()
Synchronizes all processors in the current group (waits until all processors have reached the barrier...
static int me()
Returns the rank of the local processor in the current communication group. See Comm_Group::rank() an...
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
SFichier is to the C++ ofstream class what Sortie is to the C++ ostream class.
void precision(int pre) override
void setf(IOS_FORMAT code) override
Base class for output streams.
_SIZE_ size_array() const
void resize_array(_SIZE_ new_size, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
void resize(_SIZE_ new_size, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
bool isDataOnDevice() const
void resize(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
_SIZE_ dimension(int d) const
void resize(_SIZE_, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)