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; ...@@ -67,10 +67,11 @@ const INMOST_DATA_ENUM_TYPE UNDEF = ENUMUNDEF, EOL = ENUMUNDEF - 1;
#define NNZ_GROWTH_PARAM 1.05 #define NNZ_GROWTH_PARAM 1.05
#if defined(REORDER_METIS_ND) #if defined(USE_SOLVER_METIS)
#define METIS_EXPORT #define METIS_EXPORT
#include "metis.h" #include "metis.h"
#endif #endif
#if defined(REORDER_ZOLTAN_HUND) #if defined(REORDER_ZOLTAN_HUND)
#include <zoltan.h> #include <zoltan.h>
#endif #endif
...@@ -1353,185 +1354,19 @@ const INMOST_DATA_ENUM_TYPE UNDEF = ENUMUNDEF, EOL = ENUMUNDEF - 1; ...@@ -1353,185 +1354,19 @@ const INMOST_DATA_ENUM_TYPE UNDEF = ENUMUNDEF, EOL = ENUMUNDEF - 1;
} }
bool MLMTILUC_preconditioner::isInitialized() { return init; } bool MLMTILUC_preconditioner::isInitialized() { return init; }
bool MLMTILUC_preconditioner::isFinalized() { 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
void MLMTILUC_preconditioner::MaximalTransversal( INMOST_DATA_ENUM_TYPE wbeg,
if (verbosity > 1) std::cout << __FILE__ << ":" << __LINE__ << " mem " << getCurrentRSS() << " peak " << getPeakRSS() << std::endl; INMOST_DATA_ENUM_TYPE wend,
//this scope is for reordering and rescaling interval<INMOST_DATA_ENUM_TYPE, Interval> & A_Address,
{ std::vector<Sparse::Row::entry> & A_Entries,
interval<INMOST_DATA_ENUM_TYPE, bool> donePQ(mobeg, moend, false); interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & localP,
interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> invP(wbeg, wend), invQ(wbeg, wend); interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & localQ,
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,
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,
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,
interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_REAL_TYPE> DL(wbeg,wend,1.0), DR(wbeg,wend,1.0); interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_REAL_TYPE> & DR)
//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 )
{ {
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 & U = DL;
//Sparse::Vector & V = DR; //Sparse::Vector & V = DR;
interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_REAL_TYPE> Cmax(wbeg,wend,0.0); 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; ...@@ -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(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(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()); //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; Perm[k] = ENUMUNDEF;
IPerm[k] = ENUMUNDEF; IPerm[k] = ENUMUNDEF;
...@@ -1561,22 +1396,22 @@ const INMOST_DATA_ENUM_TYPE UNDEF = ENUMUNDEF, EOL = ENUMUNDEF - 1; ...@@ -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; if (verbosity > 1) std::cout << __FILE__ << ":" << __LINE__ << " mem " << getCurrentRSS() << " peak " << getPeakRSS() << std::endl;
// Initial LOG transformation to dual problem and initial extreme match // 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) 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;
u = C_Entries[it] = fabs(A_Entries[it].second); INMOST_DATA_REAL_TYPE u = C_Entries[it] = fabs(A_Entries[it].second);
if( u > Cmax[i] ) Cmax[i] = u; if( u > Cmax[i] ) Cmax[i] = u;
//C_Entries.push_back(Sparse::Row::make_entry(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) 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 ) if( Cmax[i] == 0 || C_Entries[it] == 0 )
C_Entries[it] = std::numeric_limits<INMOST_DATA_REAL_TYPE>::max(); C_Entries[it] = std::numeric_limits<INMOST_DATA_REAL_TYPE>::max();
else else
...@@ -1586,20 +1421,20 @@ const INMOST_DATA_ENUM_TYPE UNDEF = ENUMUNDEF, EOL = ENUMUNDEF - 1; ...@@ -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) 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; if( u < V[k] ) V[k] = u;
} }
} }
/// Update cost and match /// 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) 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 ) if( u < 1.0e-30 && Perm[A_Entries[it].first] == ENUMUNDEF && IPerm[k] == ENUMUNDEF )
{ {
Perm[A_Entries[it].first] = k; Perm[A_Entries[it].first] = k;
...@@ -1609,16 +1444,16 @@ const INMOST_DATA_ENUM_TYPE UNDEF = ENUMUNDEF, EOL = ENUMUNDEF - 1; ...@@ -1609,16 +1444,16 @@ const INMOST_DATA_ENUM_TYPE UNDEF = ENUMUNDEF, EOL = ENUMUNDEF - 1;
} }
} }
/// 1-step augmentation /// 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 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) 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 ) if( u <= 1.0e-30 )
{ {
Li = Perm[A_Entries[it].first]; INMOST_DATA_ENUM_TYPE Li = Perm[A_Entries[it].first];
assert(Li != ENUMUNDEF); assert(Li != ENUMUNDEF);
// Search other row in C for 0 // Search other row in C for 0
for (INMOST_DATA_ENUM_TYPE Lit = A_Address[Li].first; Lit < A_Address[Li].last; ++Lit) 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; ...@@ -1640,25 +1475,25 @@ const INMOST_DATA_ENUM_TYPE UNDEF = ENUMUNDEF, EOL = ENUMUNDEF - 1;
} }
} }
/// Weighted bipartite matching /// 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 ) if( IPerm[k] != ENUMUNDEF )
continue; continue;
Li = k; INMOST_DATA_ENUM_TYPE Li = k;
ColumnBegin = EOL; INMOST_DATA_ENUM_TYPE ColumnBegin = EOL;
Parent[Li] = ENUMUNDEF; Parent[Li] = ENUMUNDEF;
PathEnd = ENUMUNDEF; INMOST_DATA_ENUM_TYPE PathEnd = ENUMUNDEF;
Trace = k; INMOST_DATA_ENUM_TYPE Trace = k;
ShortestPath = 0; INMOST_DATA_REAL_TYPE ShortestPath = 0;
AugmentPath = std::numeric_limits<INMOST_DATA_REAL_TYPE>::max(); INMOST_DATA_REAL_TYPE AugmentPath = std::numeric_limits<INMOST_DATA_REAL_TYPE>::max();
while(true) while(true)
{ {
for (INMOST_DATA_ENUM_TYPE Lit = A_Address[Li].first; Lit < A_Address[Li].last; ++Lit) 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] == k ) continue;
if( ColumnList[Ui] != ENUMUNDEF ) 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 ) 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 && l > -1.0e-8 ) l = 0;
if( l < 0.0 ) continue; if( l < 0.0 ) continue;
...@@ -1683,10 +1518,10 @@ const INMOST_DATA_ENUM_TYPE UNDEF = ENUMUNDEF, EOL = ENUMUNDEF - 1; ...@@ -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; if( pop_heap_pos == ENUMUNDEF ) break;
Ui = pop_heap_pos+wbeg; INMOST_DATA_ENUM_TYPE Ui = pop_heap_pos+wbeg;
ShortestPath = Dist[Ui]; ShortestPath = Dist[Ui];
if( AugmentPath <= ShortestPath ) if( AugmentPath <= ShortestPath )
...@@ -1705,7 +1540,7 @@ const INMOST_DATA_ENUM_TYPE UNDEF = ENUMUNDEF, EOL = ENUMUNDEF - 1; ...@@ -1705,7 +1540,7 @@ const INMOST_DATA_ENUM_TYPE UNDEF = ENUMUNDEF, EOL = ENUMUNDEF - 1;
} }
if( PathEnd != ENUMUNDEF ) if( PathEnd != ENUMUNDEF )
{ {
Ui = ColumnBegin; INMOST_DATA_ENUM_TYPE Ui = ColumnBegin;
while(Ui != EOL) while(Ui != EOL)
{ {
U[Ui] += Dist[Ui] - AugmentPath; U[Ui] += Dist[Ui] - AugmentPath;
...@@ -1719,7 +1554,7 @@ const INMOST_DATA_ENUM_TYPE UNDEF = ENUMUNDEF, EOL = ENUMUNDEF - 1; ...@@ -1719,7 +1554,7 @@ const INMOST_DATA_ENUM_TYPE UNDEF = ENUMUNDEF, EOL = ENUMUNDEF - 1;
Ui = PathEnd; Ui = PathEnd;
while(Trace != ENUMUNDEF) while(Trace != ENUMUNDEF)
{ {
IPermPrev = IPerm[Trace]; INMOST_DATA_ENUM_TYPE IPermPrev = IPerm[Trace];
Perm[Ui] = Trace; Perm[Ui] = Trace;
IPerm[Trace] = Ui; IPerm[Trace] = Ui;
...@@ -1734,14 +1569,12 @@ const INMOST_DATA_ENUM_TYPE UNDEF = ENUMUNDEF, EOL = ENUMUNDEF - 1; ...@@ -1734,14 +1569,12 @@ const INMOST_DATA_ENUM_TYPE UNDEF = ENUMUNDEF, EOL = ENUMUNDEF - 1;
} }
} }
#if defined(USE_OMP_FACT) #if defined(USE_OMP_FACT)
#pragma omp parallel for private(k,l,u,i,j) #pragma omp parallel for
#endif #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; INMOST_DATA_REAL_TYPE l = (V[k] == std::numeric_limits<INMOST_DATA_REAL_TYPE>::max() ? 1 : exp(V[k]));
else l = exp(V[k]); INMOST_DATA_REAL_TYPE u = (U[k] == std::numeric_limits<INMOST_DATA_REAL_TYPE>::max() ? 1 : exp(U[k])/Cmax[k]);
if( U[k] == std::numeric_limits<INMOST_DATA_REAL_TYPE>::max() || Cmax[k] == 0 ) u = 1;
else u = exp(U[k])/Cmax[k];
DL[k] = l; DL[k] = l;
DR[k] = u; DR[k] = u;
...@@ -1749,8 +1582,8 @@ const INMOST_DATA_ENUM_TYPE UNDEF = ENUMUNDEF, EOL = ENUMUNDEF - 1; ...@@ -1749,8 +1582,8 @@ const INMOST_DATA_ENUM_TYPE UNDEF = ENUMUNDEF, EOL = ENUMUNDEF - 1;
bool flip_sign = false; bool flip_sign = false;
for (INMOST_DATA_ENUM_TYPE jt = A_Address[k].first; jt < A_Address[k].last; ++jt) for (INMOST_DATA_ENUM_TYPE jt = A_Address[k].first; jt < A_Address[k].last; ++jt)
{ {
i = A_Entries[jt].first; INMOST_DATA_ENUM_TYPE i = A_Entries[jt].first;
j = Perm[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; if( U[i] == std::numeric_limits<INMOST_DATA_REAL_TYPE>::max() || Cmax[i] == 0 ) u = 1;
else u = exp(U[i])/Cmax[i]; else u = exp(U[i])/Cmax[i];
...@@ -1769,10 +1602,10 @@ const INMOST_DATA_ENUM_TYPE UNDEF = ENUMUNDEF, EOL = ENUMUNDEF - 1; ...@@ -1769,10 +1602,10 @@ const INMOST_DATA_ENUM_TYPE UNDEF = ENUMUNDEF, EOL = ENUMUNDEF - 1;
if( flip_sign ) DL[k] *= -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 { //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 ) if( Perm[k] != ENUMUNDEF )
{ {
...@@ -1781,122 +1614,84 @@ const INMOST_DATA_ENUM_TYPE UNDEF = ENUMUNDEF, EOL = ENUMUNDEF - 1; ...@@ -1781,122 +1614,84 @@ const INMOST_DATA_ENUM_TYPE UNDEF = ENUMUNDEF, EOL = ENUMUNDEF - 1;
} }
} }
std::vector<INMOST_DATA_ENUM_TYPE> gaps; 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 ) if( localP[k] == ENUMUNDEF )
gaps.push_back(k); gaps.push_back(k);
//~ std::cout << "@ gaps: " << gaps.size() << std::endl; //~ 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 ) if( Perm[k] == ENUMUNDEF )
{ {
Perm[k] = gaps.back(); Perm[k] = gaps.back();
gaps.pop_back(); gaps.pop_back();
} }
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;
}
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;
}
} }
/// 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];