Commit ee6715b1 authored by Kirill Terekhov's avatar Kirill Terekhov
Browse files

some refactoring in MLMPTILUC2

parent 3231377a
......@@ -67,10 +67,11 @@ const INMOST_DATA_ENUM_TYPE UNDEF = ENUMUNDEF, EOL = ENUMUNDEF - 1;
#define NNZ_GROWTH_PARAM 1.05
#if defined(REORDER_METIS_ND)
#if defined(USE_SOLVER_METIS)
#define METIS_EXPORT
#include "metis.h"
#endif
#if defined(REORDER_ZOLTAN_HUND)
#include <zoltan.h>
#endif
......@@ -1353,185 +1354,19 @@ const INMOST_DATA_ENUM_TYPE UNDEF = ENUMUNDEF, EOL = ENUMUNDEF - 1;
}
bool MLMTILUC_preconditioner::isInitialized() { return init; }
bool MLMTILUC_preconditioner::isFinalized() { return !init; }
bool MLMTILUC_preconditioner::Initialize()
{
if (verbosity > 1) std::cout << __FILE__ << ":" << __LINE__ << " mem " << getCurrentRSS() << " peak " << getPeakRSS() << std::endl;
int nthreads = Threads();
const INMOST_DATA_REAL_TYPE subst = 1.0; (void)subst;
const INMOST_DATA_REAL_TYPE tol_modif = PIVOT_THRESHOLD_VALUE;
bool block_pivot = false;
INMOST_DATA_ENUM_TYPE wbeg, wend; //working interval
INMOST_DATA_ENUM_TYPE mobeg, moend; // total interval
INMOST_DATA_ENUM_TYPE vbeg, vend; // vector interval
INMOST_DATA_INTEGER_TYPE k;
INMOST_DATA_ENUM_TYPE i, j, Li, Ui, curr, next;
INMOST_DATA_REAL_TYPE l,u, max_diag = 0, min_diag = 0;
INMOST_DATA_ENUM_TYPE nzA, nzLU = 0, nzA0;
//Sparse::Vector DL, DR;
Sparse::Vector DL0,DR0;
info->GetOverlapRegion(info->GetRank(), mobeg, moend);
info->GetVectorRegion(vbeg,vend);
//prepare reordering vectors
ddP.set_interval_beg(mobeg);
ddP.set_interval_end(moend);
ddQ.set_interval_beg(mobeg);
ddQ.set_interval_end(moend);
//prepare rescaling vectors
//DL.SetInterval(mobeg, moend);
//DR.SetInterval(mobeg, moend);
DL0.SetInterval(mobeg, moend);
DR0.SetInterval(mobeg, moend);
for(k = mobeg; k < static_cast<INMOST_DATA_INTEGER_TYPE>(moend); ++k)
DL0[k] = DR0[k] = 1.0;
for (k = mobeg; k < static_cast<INMOST_DATA_INTEGER_TYPE>(moend); k++)
ddP[k] = ddQ[k] = k;
//interval<INMOST_DATA_ENUM_TYPE, bool> Pivot(mobeg,moend,false);
if (verbosity > 1) std::cout << __FILE__ << ":" << __LINE__ << " mem " << getCurrentRSS() << " peak " << getPeakRSS() << std::endl;
//supplimentary data structures for ILUC
INMOST_DATA_ENUM_TYPE L_Beg, U_Beg, Sbeg;
U_Address.set_interval_beg(mobeg);
U_Address.set_interval_end(moend);
L_Address.set_interval_beg(mobeg);
L_Address.set_interval_end(moend);
LU_Diag.set_interval_beg(mobeg);
LU_Diag.set_interval_end(moend);
std::vector<Sparse::Row::entry> A_Entries;
//std::vector<INMOST_DATA_ENUM_TYPE> sort_indeces;
interval<INMOST_DATA_ENUM_TYPE, Interval> A_Address(mobeg, moend);
#if defined(NNZ_PIVOT)
INMOST_DATA_ENUM_TYPE nnzL = 0, nnzU = 0, nnzL_max = 0, nnzU_max = 0;
#endif
INMOST_DATA_ENUM_TYPE nnzE = 0, nnzF = 0, nnzA = 0;
INMOST_DATA_REAL_TYPE NuU = 1, NuL = 1, NuD = 1, NuU_max = 1.0, NuL_max = 1.0;
INMOST_DATA_REAL_TYPE NuU_acc = 1, NuL_acc = 1, NuD_acc = 1;
//supplimentary data structures for returning values of dropped elements
//~ INMOST_DATA_REAL_TYPE DropLk, DropUk, SumLk, SumUk;
//~ interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_REAL_TYPE> DropU(mobeg,moend,0.0), DropL(mobeg,moend,0.0);
//~ #if defined(ILUC2)
//~ interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_REAL_TYPE> DropU2(mobeg,moend,0.0), DropL2(mobeg,moend,0.0);
//~ #endif
//data structure for linked list
//interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_REAL_TYPE> U(mobeg,moend,std::numeric_limits<INMOST_DATA_REAL_TYPE>::max());
//interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_REAL_TYPE> V(mobeg,moend,std::numeric_limits<INMOST_DATA_REAL_TYPE>::max());
//interval<INMOST_DATA_ENUM_TYPE, std::vector< std::pair<INMOST_DATA_ENUM_TYPE,INMOST_DATA_ENUM_TYPE> > > TransposeU(mobeg,moend), TransposeL(mobeg,moend);
double tfactor = 0.0, trescale = 0.0, treorder = 0.0, ttransversal = 0.0, treassamble = 0.0, ttotal, tt, testimator = 0.0, tschur = 0.0, tlocal;
#if defined(REORDER_METIS_ND)
double tmetisgraph = 0, tmetisnd = 0;
#endif
#if defined(REORDER_RCM) || defined(REORDER_WRCM) || defined(REORDER_BRCM)
double trcmgraph = 0, trcmorder = 0;
#endif
double tlfactor, tlrescale, tlreorder, tlreassamble, tlschur;
ttotal = Timer();
//(*Alink).Save("M.mtx");
//calculate number of nonzeros
nzA = 0;
for (k = mobeg; k < static_cast<INMOST_DATA_INTEGER_TYPE>(moend); ++k)
{
for (Sparse::Row::iterator r = (*Alink)[k].Begin(); r != (*Alink)[k].End(); ++r)
if (r->first >= mobeg && r->first < moend && fabs(r->second) > 0.0) nzA++;
}
nzA0 = nzA;
//sort_indeces.reserve(256);
A_Entries.resize(nzA);
//LU_Entries.reserve(nzA*4);
j = 0;
for (k = mobeg; k < static_cast<INMOST_DATA_INTEGER_TYPE>(moend); ++k)
{
A_Address[k].first = j;
for (Sparse::Row::iterator r = (*Alink)[k].Begin(); r != (*Alink)[k].End(); ++r)
{
if (r->first >= mobeg && r->first < moend && fabs(r->second) > 0 )//1.0e-30 )// != 0.0)
A_Entries[j++] = Sparse::Row::make_entry(r->first, r->second);
}
A_Address[k].last = j;
//assert(A_Address[k].Size() != 0); //singular matrix
}
if (verbosity > 1) std::cout << __FILE__ << ":" << __LINE__ << " mem " << getCurrentRSS() << " peak " << getPeakRSS() << std::endl;
INMOST_DATA_REAL_TYPE Unorm, Lnorm;
//~ INMOST_DATA_REAL_TYPE Unum, Lnum;
INMOST_DATA_ENUM_TYPE nzLU2 = 0, nzLU2tot = 0, ndrops = 0;
#if defined(ILUC2)
INMOST_DATA_REAL_TYPE tau2 = iluc2_tau;
#else
INMOST_DATA_REAL_TYPE tau2 = tau;
#endif
for(k = mobeg; k < static_cast<INMOST_DATA_INTEGER_TYPE>(moend); ++k)
{
U_Address[k].first = U_Address[k].last = ENUMUNDEF;
L_Address[k].first = L_Address[k].last = ENUMUNDEF;
}
if( verbosity > 1 )
std::cout << "nonzeros in A " << nzA << " pivot cond " << pivot_cond << " diag " << pivot_diag << " tau " << tau << " tau2 " << tau2 << std::endl;
int swaps = 0, totswaps = 0;
//set up working interval
wbeg = mobeg;
wend = moend;
while (wbeg < wend) //iterate into levels until all matrix is factored
{
//ddPQ reordering on current Schur complement
INMOST_DATA_ENUM_TYPE cbeg = wbeg, cend = wend; //next size of factored B block
if (verbosity > 1) std::cout << __FILE__ << ":" << __LINE__ << " mem " << getCurrentRSS() << " peak " << getPeakRSS() << std::endl;
//this scope is for reordering and rescaling
{
interval<INMOST_DATA_ENUM_TYPE, bool> donePQ(mobeg, moend, false);
interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> invP(wbeg, wend), invQ(wbeg, wend);
interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> localP(wbeg, wend, ENUMUNDEF), localQ(wbeg, wend, ENUMUNDEF);
interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_REAL_TYPE> U(wbeg,wend,std::numeric_limits<INMOST_DATA_REAL_TYPE>::max());
interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_REAL_TYPE> V(wbeg,wend,std::numeric_limits<INMOST_DATA_REAL_TYPE>::max());
interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_REAL_TYPE> DL(wbeg,wend,1.0), DR(wbeg,wend,1.0);
//this scope is for reorderings
{
//DumpMatrix(A_Address,A_Entries,cbeg,cend,"mat"+to_string(level_size.size())+".mtx");
/// MAXIMUM TRANSVERSE REORDERING
if( run_mpt )
void MLMTILUC_preconditioner::MaximalTransversal( INMOST_DATA_ENUM_TYPE wbeg,
INMOST_DATA_ENUM_TYPE wend,
interval<INMOST_DATA_ENUM_TYPE, Interval> & A_Address,
std::vector<Sparse::Row::entry> & A_Entries,
interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & localP,
interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & localQ,
interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_REAL_TYPE> & U,
interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_REAL_TYPE> & V,
interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_REAL_TYPE> & DL,
interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_REAL_TYPE> & DR)
{
if( verbosity > 1 )
std::cout << "Reordering with MPT\n";
ttransversal = Timer();
INMOST_DATA_ENUM_TYPE ColumnBegin;
INMOST_DATA_ENUM_TYPE pop_heap_pos;
INMOST_DATA_REAL_TYPE ShortestPath, AugmentPath;
INMOST_DATA_ENUM_TYPE PathEnd, Trace, IPermPrev;
//Sparse::Vector & U = DL;
//Sparse::Vector & V = DR;
interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_REAL_TYPE> Cmax(wbeg,wend,0.0);
......@@ -1550,7 +1385,7 @@ const INMOST_DATA_ENUM_TYPE UNDEF = ENUMUNDEF, EOL = ENUMUNDEF - 1;
//std::fill(V.begin() + wbeg - mobeg, V.begin() + wend - mobeg, std::numeric_limits<INMOST_DATA_REAL_TYPE>::max());
//std::fill(Cmax.begin() + wbeg - mobeg, Cmax.begin() + wend - mobeg, 0.0);
//std::fill(Dist.begin() + wbeg - mobeg, Dist.begin() + wend + 1 - mobeg, std::numeric_limits<INMOST_DATA_REAL_TYPE>::max());
for(k = wbeg; k < static_cast<INMOST_DATA_INTEGER_TYPE>(wend); ++k)
for(INMOST_DATA_INTEGER_TYPE k = wbeg; k < static_cast<INMOST_DATA_INTEGER_TYPE>(wend); ++k)
{
Perm[k] = ENUMUNDEF;
IPerm[k] = ENUMUNDEF;
......@@ -1561,22 +1396,22 @@ const INMOST_DATA_ENUM_TYPE UNDEF = ENUMUNDEF, EOL = ENUMUNDEF - 1;
if (verbosity > 1) std::cout << __FILE__ << ":" << __LINE__ << " mem " << getCurrentRSS() << " peak " << getPeakRSS() << std::endl;
// Initial LOG transformation to dual problem and initial extreme match
for(k = wbeg; k < static_cast<INMOST_DATA_INTEGER_TYPE>(wend); ++k)
for(INMOST_DATA_INTEGER_TYPE k = wbeg; k < static_cast<INMOST_DATA_INTEGER_TYPE>(wend); ++k)
{
for (INMOST_DATA_ENUM_TYPE it = A_Address[k].first; it < A_Address[k].last; ++it)
{
i = A_Entries[it].first;
u = C_Entries[it] = fabs(A_Entries[it].second);
INMOST_DATA_ENUM_TYPE i = A_Entries[it].first;
INMOST_DATA_REAL_TYPE u = C_Entries[it] = fabs(A_Entries[it].second);
if( u > Cmax[i] ) Cmax[i] = u;
//C_Entries.push_back(Sparse::Row::make_entry(i,u));
}
}
for(k = wbeg; k < static_cast<INMOST_DATA_INTEGER_TYPE>(wend); ++k)
for(INMOST_DATA_INTEGER_TYPE k = wbeg; k < static_cast<INMOST_DATA_INTEGER_TYPE>(wend); ++k)
{
for (INMOST_DATA_ENUM_TYPE it = A_Address[k].first; it < A_Address[k].last; ++it)
{
i = A_Entries[it].first;
INMOST_DATA_ENUM_TYPE i = A_Entries[it].first;
if( Cmax[i] == 0 || C_Entries[it] == 0 )
C_Entries[it] = std::numeric_limits<INMOST_DATA_REAL_TYPE>::max();
else
......@@ -1586,20 +1421,20 @@ const INMOST_DATA_ENUM_TYPE UNDEF = ENUMUNDEF, EOL = ENUMUNDEF - 1;
}
}
}
for(k = wbeg; k < static_cast<INMOST_DATA_INTEGER_TYPE>(wend); ++k)
for(INMOST_DATA_INTEGER_TYPE k = wbeg; k < static_cast<INMOST_DATA_INTEGER_TYPE>(wend); ++k)
{
for (INMOST_DATA_ENUM_TYPE it = A_Address[k].first; it < A_Address[k].last; ++it)
{
u = C_Entries[it] - U[A_Entries[it].first];
INMOST_DATA_REAL_TYPE u = C_Entries[it] - U[A_Entries[it].first];
if( u < V[k] ) V[k] = u;
}
}
/// Update cost and match
for(k = wbeg; k < static_cast<INMOST_DATA_INTEGER_TYPE>(wend); ++k)
for(INMOST_DATA_INTEGER_TYPE k = wbeg; k < static_cast<INMOST_DATA_INTEGER_TYPE>(wend); ++k)
{
for (INMOST_DATA_ENUM_TYPE it = A_Address[k].first; it < A_Address[k].last; ++it)
{
u = fabs(C_Entries[it] - V[k] - U[A_Entries[it].first]);
INMOST_DATA_REAL_TYPE u = fabs(C_Entries[it] - V[k] - U[A_Entries[it].first]);
if( u < 1.0e-30 && Perm[A_Entries[it].first] == ENUMUNDEF && IPerm[k] == ENUMUNDEF )
{
Perm[A_Entries[it].first] = k;
......@@ -1609,16 +1444,16 @@ const INMOST_DATA_ENUM_TYPE UNDEF = ENUMUNDEF, EOL = ENUMUNDEF - 1;
}
}
/// 1-step augmentation
for(k = wbeg; k < static_cast<INMOST_DATA_INTEGER_TYPE>(wend); ++k)
for(INMOST_DATA_INTEGER_TYPE k = wbeg; k < static_cast<INMOST_DATA_INTEGER_TYPE>(wend); ++k)
{
if( IPerm[k] == ENUMUNDEF ) //unmatched row
{
for (INMOST_DATA_ENUM_TYPE it = A_Address[k].first; it < A_Address[k].last && IPerm[k] == ENUMUNDEF; ++it)
{
u = fabs(C_Entries[it] - V[k] - U[A_Entries[it].first]);
INMOST_DATA_REAL_TYPE u = fabs(C_Entries[it] - V[k] - U[A_Entries[it].first]);
if( u <= 1.0e-30 )
{
Li = Perm[A_Entries[it].first];
INMOST_DATA_ENUM_TYPE Li = Perm[A_Entries[it].first];
assert(Li != ENUMUNDEF);
// Search other row in C for 0
for (INMOST_DATA_ENUM_TYPE Lit = A_Address[Li].first; Lit < A_Address[Li].last; ++Lit)
......@@ -1640,25 +1475,25 @@ const INMOST_DATA_ENUM_TYPE UNDEF = ENUMUNDEF, EOL = ENUMUNDEF - 1;
}
}
/// Weighted bipartite matching
for(k = wbeg; k < static_cast<INMOST_DATA_INTEGER_TYPE>(wend); ++k)
for(INMOST_DATA_INTEGER_TYPE k = wbeg; k < static_cast<INMOST_DATA_INTEGER_TYPE>(wend); ++k)
{
if( IPerm[k] != ENUMUNDEF )
continue;
Li = k;
ColumnBegin = EOL;
INMOST_DATA_ENUM_TYPE Li = k;
INMOST_DATA_ENUM_TYPE ColumnBegin = EOL;
Parent[Li] = ENUMUNDEF;
PathEnd = ENUMUNDEF;
Trace = k;
ShortestPath = 0;
AugmentPath = std::numeric_limits<INMOST_DATA_REAL_TYPE>::max();
INMOST_DATA_ENUM_TYPE PathEnd = ENUMUNDEF;
INMOST_DATA_ENUM_TYPE Trace = k;
INMOST_DATA_REAL_TYPE ShortestPath = 0;
INMOST_DATA_REAL_TYPE AugmentPath = std::numeric_limits<INMOST_DATA_REAL_TYPE>::max();
while(true)
{
for (INMOST_DATA_ENUM_TYPE Lit = A_Address[Li].first; Lit < A_Address[Li].last; ++Lit)
{
Ui = A_Entries[Lit].first;
INMOST_DATA_ENUM_TYPE Ui = A_Entries[Lit].first;
//if( ColumnList[Ui] == k ) continue;
if( ColumnList[Ui] != ENUMUNDEF ) continue;
l = fabs(ShortestPath + C_Entries[Lit] - V[Li] - U[Ui]);
INMOST_DATA_REAL_TYPE l = fabs(ShortestPath + C_Entries[Lit] - V[Li] - U[Ui]);
//if( l < 0.0 ) printf("row %d col %d negative l %g Augment %lf Shortest %lf C %lf V %lf U %lf\n",k,Ui,l,AugmentPath,ShortestPath,C_Entries[Lit],V[Li],U[Ui]);
if( l < 0.0 && l > -1.0e-8 ) l = 0;
if( l < 0.0 ) continue;
......@@ -1683,10 +1518,10 @@ const INMOST_DATA_ENUM_TYPE UNDEF = ENUMUNDEF, EOL = ENUMUNDEF - 1;
}
}
pop_heap_pos = Heap.PopHeap();
INMOST_DATA_ENUM_TYPE pop_heap_pos = Heap.PopHeap();
if( pop_heap_pos == ENUMUNDEF ) break;
Ui = pop_heap_pos+wbeg;
INMOST_DATA_ENUM_TYPE Ui = pop_heap_pos+wbeg;
ShortestPath = Dist[Ui];
if( AugmentPath <= ShortestPath )
......@@ -1705,7 +1540,7 @@ const INMOST_DATA_ENUM_TYPE UNDEF = ENUMUNDEF, EOL = ENUMUNDEF - 1;
}
if( PathEnd != ENUMUNDEF )
{
Ui = ColumnBegin;
INMOST_DATA_ENUM_TYPE Ui = ColumnBegin;
while(Ui != EOL)
{
U[Ui] += Dist[Ui] - AugmentPath;
......@@ -1719,7 +1554,7 @@ const INMOST_DATA_ENUM_TYPE UNDEF = ENUMUNDEF, EOL = ENUMUNDEF - 1;
Ui = PathEnd;
while(Trace != ENUMUNDEF)
{
IPermPrev = IPerm[Trace];
INMOST_DATA_ENUM_TYPE IPermPrev = IPerm[Trace];
Perm[Ui] = Trace;
IPerm[Trace] = Ui;
......@@ -1734,14 +1569,12 @@ const INMOST_DATA_ENUM_TYPE UNDEF = ENUMUNDEF, EOL = ENUMUNDEF - 1;
}
}
#if defined(USE_OMP_FACT)
#pragma omp parallel for private(k,l,u,i,j)
#pragma omp parallel for
#endif
for (k = cbeg; k < static_cast<INMOST_DATA_INTEGER_TYPE>(cend); ++k)
for (INMOST_DATA_INTEGER_TYPE k = wbeg; k < static_cast<INMOST_DATA_INTEGER_TYPE>(wend); ++k)
{
if( V[k] == std::numeric_limits<INMOST_DATA_REAL_TYPE>::max() ) l = 1;
else l = exp(V[k]);
if( U[k] == std::numeric_limits<INMOST_DATA_REAL_TYPE>::max() || Cmax[k] == 0 ) u = 1;
else u = exp(U[k])/Cmax[k];
INMOST_DATA_REAL_TYPE l = (V[k] == std::numeric_limits<INMOST_DATA_REAL_TYPE>::max() ? 1 : exp(V[k]));
INMOST_DATA_REAL_TYPE u = (U[k] == std::numeric_limits<INMOST_DATA_REAL_TYPE>::max() ? 1 : exp(U[k])/Cmax[k]);
DL[k] = l;
DR[k] = u;
......@@ -1749,8 +1582,8 @@ const INMOST_DATA_ENUM_TYPE UNDEF = ENUMUNDEF, EOL = ENUMUNDEF - 1;
bool flip_sign = false;
for (INMOST_DATA_ENUM_TYPE jt = A_Address[k].first; jt < A_Address[k].last; ++jt)
{
i = A_Entries[jt].first;
j = Perm[A_Entries[jt].first];
INMOST_DATA_ENUM_TYPE i = A_Entries[jt].first;
INMOST_DATA_ENUM_TYPE j = Perm[A_Entries[jt].first];
if( U[i] == std::numeric_limits<INMOST_DATA_REAL_TYPE>::max() || Cmax[i] == 0 ) u = 1;
else u = exp(U[i])/Cmax[i];
......@@ -1769,10 +1602,10 @@ const INMOST_DATA_ENUM_TYPE UNDEF = ENUMUNDEF, EOL = ENUMUNDEF - 1;
if( flip_sign ) DL[k] *= -1;
}
for(k = wbeg; k < static_cast<INMOST_DATA_INTEGER_TYPE>(wend); ++k) localP[k] = ENUMUNDEF;
for(INMOST_DATA_INTEGER_TYPE k = wbeg; k < static_cast<INMOST_DATA_INTEGER_TYPE>(wend); ++k) localP[k] = ENUMUNDEF;
{ //check that there are no gaps in Perm
for(k = cbeg; k < static_cast<INMOST_DATA_INTEGER_TYPE>(cend); ++k)
for(INMOST_DATA_INTEGER_TYPE k = wbeg; k < static_cast<INMOST_DATA_INTEGER_TYPE>(wend); ++k)
{
if( Perm[k] != ENUMUNDEF )
{
......@@ -1781,122 +1614,84 @@ const INMOST_DATA_ENUM_TYPE UNDEF = ENUMUNDEF, EOL = ENUMUNDEF - 1;
}
}
std::vector<INMOST_DATA_ENUM_TYPE> gaps;
for(k = cbeg; k < static_cast<INMOST_DATA_INTEGER_TYPE>(cend); ++k)
for(INMOST_DATA_INTEGER_TYPE k = wbeg; k < static_cast<INMOST_DATA_INTEGER_TYPE>(wend); ++k)
if( localP[k] == ENUMUNDEF )
gaps.push_back(k);
//~ std::cout << "@ gaps: " << gaps.size() << std::endl;
for(k = cbeg; k < static_cast<INMOST_DATA_INTEGER_TYPE>(cend); ++k)
for(INMOST_DATA_INTEGER_TYPE k = wbeg; k < static_cast<INMOST_DATA_INTEGER_TYPE>(wend); ++k)
if( Perm[k] == ENUMUNDEF )
{
Perm[k] = gaps.back();
gaps.pop_back();
}
for(k = wbeg; k < static_cast<INMOST_DATA_INTEGER_TYPE>(wend); ++k) localP[k] = ENUMUNDEF;
}
ttransversal = Timer() - ttransversal;
treorder += ttransversal;
if( verbosity > 1 )
std::cout << "Time " << ttransversal << "\n";
}
else
{
for(k = wbeg; k < static_cast<INMOST_DATA_INTEGER_TYPE>(wend); ++k)
{
localQ[k] = k;
DL[k] = DR[k] = 1;
}
for(INMOST_DATA_INTEGER_TYPE k = wbeg; k < static_cast<INMOST_DATA_INTEGER_TYPE>(wend); ++k) localP[k] = ENUMUNDEF;
}
/// END MAXIMUM TRANSVERSE REORDERING
tt = Timer();
#if defined(REORDER_METIS_ND)
{
idx_t nvtxs = wend-wbeg;
std::vector<idx_t> xadj(nvtxs+1), adjncy, perm(nvtxs),iperm(nvtxs);
//adjncy.reserve(nzA*2);
if( verbosity > 1 )
std::cout << "Reordering with METIS\n";
for (k = cbeg; k < cend; ++k) if( localQ[k] == ENUMUNDEF ) std::cout << __FILE__ << ":" << __LINE__ << " No column permutation for row " << k << ". Matrix is structurally singular\n";
for (k = cbeg; k < cend; ++k) localP[k] = k;
for (k = cbeg; k < cend; ++k) V[localQ[k]] = DR[k]; //if you expirience a bug here then the matrix is structurally singular
for (k = cbeg; k < cend; ++k) DR[k] = V[k];
for (k = cbeg; k < cend; ++k)
{
if( !(localQ[k] >= cbeg && localQ[k] < cend) )
std::cout << "Bad permutation: " << localQ[k] << " interval [" << cbeg << ":" << cend << "]" << std::endl;
V[localQ[k]] = DR0[k]; //if you expirience a bug here then the matrix is structurally singular
}
for (k = cbeg; k < cend; ++k) DR0[k] = V[k];
for(k = wbeg; k < wend; ++k)
{
for (INMOST_DATA_ENUM_TYPE jt = A_Address[k].first; jt < A_Address[k].last; ++jt)
void MLMTILUC_preconditioner::SymmetricGraphWeights(INMOST_DATA_ENUM_TYPE wbeg,
INMOST_DATA_ENUM_TYPE wend,
interval<INMOST_DATA_ENUM_TYPE, Interval> & A_Address,
std::vector<Sparse::Row::entry> & A_Entries,
interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_REAL_TYPE> & DL,
interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_REAL_TYPE> & DR,
std::vector<INMOST_DATA_ENUM_TYPE> & xadj,
std::vector<INMOST_DATA_REAL_TYPE> & wadj,
std::vector< INMOST_DATA_ENUM_TYPE > & adjncy)
{
xadj.resize(wend-wbeg+1);
wadj.resize(wend-wbeg);
{//graph assembly
interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> Apos(wbeg, wend), Anext(wbeg, wend), Afirst(wbeg,wend);
for(INMOST_DATA_INTEGER_TYPE k = wbeg; k < static_cast<INMOST_DATA_INTEGER_TYPE>(wend); ++k)
{
A_Entries[jt].first = localQ[A_Entries[jt].first];
//A_Entries[jt].second *= DL[k]*DR[A_Entries[jt].first];
}
std::sort(A_Entries.begin()+A_Address[k].first,A_Entries.begin()+A_Address[k].last);
Apos[k] = EOL;
Afirst[k] = EOL;
Anext[k] = EOL;
}
ReorderEF(wbeg, wend, donePQ, localP, localQ);
inversePQ(wbeg,wend,localP,localQ, invP,invQ);
applyPQ(wbeg, wend, localP, localQ, invP, invQ);
//DumpMatrix(A_Address,A_Entries,wbeg,wend,"a.mtx");
// setup indices for transposed traversal of B block
tmetisgraph = Timer();
{//graph assembly
interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> Apos(wbeg, wend,EOL), Anext(wbeg, wend,EOL), Afirst(wbeg,wend,EOL);
for (k = wend; k > wbeg; --k)
for (INMOST_DATA_INTEGER_TYPE k = wend; k > static_cast<INMOST_DATA_INTEGER_TYPE>(wbeg); --k)
{
//vwgt[k-1] = 1;
if (A_Address[k-1].Size() > 0)
{
i = A_Entries[A_Address[k-1].first].first;
INMOST_DATA_ENUM_TYPE i = A_Entries[A_Address[k-1].first].first;
Anext[k-1] = Afirst[i];
Afirst[i] = k-1;
}
Apos[k-1] = A_Address[k-1].first;
}
xadj[0] = 0;
for(i = wbeg; i < wend; ++i)
for(INMOST_DATA_ENUM_TYPE i = wbeg; i < wend; ++i)
{
wadj[i-wbeg] = 0;
for (INMOST_DATA_ENUM_TYPE jt = A_Address[i].first; jt < A_Address[i].last; ++jt)
{
if( A_Entries[jt].first != i )
adjncy.push_back(static_cast<idx_t>(A_Entries[jt].first-wbeg));
}
Li = Afirst[i];
if( A_Entries[jt].first != i )//&& fabs(DL[i]*A_Entries[jt].second*DR[A_Entries[jt].first]) > 0.1*std::min(Acolmax,Arowmax) )
{
adjncy.push_back(static_cast<INMOST_DATA_ENUM_TYPE>(A_Entries[jt].first));
wadj[i-wbeg] += fabs(DL[i]*A_Entries[jt].second*DR[A_Entries[jt].first]);
}
}
INMOST_DATA_ENUM_TYPE Li = Afirst[i];
while (Li != EOL)
{
if( Li != i )
adjncy.push_back(static_cast<idx_t>(Li-wbeg));
if( Li != i )//&& fabs(DL[A_Entries[A_Address[Li].first].first]*A_Entries[A_Address[Li].first].second*DR[i]) > 0.1*std::min(Acolmax,Arowmax) )
{
adjncy.push_back(static_cast<INMOST_DATA_ENUM_TYPE>(Li));
wadj[i-wbeg] += fabs(DL[A_Entries[A_Address[Li].first].first]*A_Entries[A_Address[Li].first].second*DR[i]);
}
Li = Anext[Li];
}
Li = Afirst[i];
while (Li != EOL)
{
Ui = Anext[Li];
INMOST_DATA_ENUM_TYPE Ui = Anext[Li];
Apos[Li]++;
if (A_Address[Li].last - Apos[Li] > 0)
if (A_Address[Li].Size() && A_Address[Li].last - Apos[Li] > 0)
{
k = A_Entries[Apos[Li]].first;
INMOST_DATA_ENUM_TYPE k = A_Entries[Apos[Li]].first;
Anext[Li] = Afirst[k];
Afirst[k] = Li;
}
......@@ -1907,141 +1702,49 @@ const INMOST_DATA_ENUM_TYPE UNDEF = ENUMUNDEF, EOL = ENUMUNDEF - 1;