Skip to content
Snippets Groups Projects
Commit b93616cd authored by Robert Klöfkorn's avatar Robert Klöfkorn
Browse files

some resorting of memory allocation to avoid out of memory states

although the memory is not needed.


git-svn-id: https://dune.mathematik.uni-freiburg.de/svn/alugrid/trunk@936 0d966ed9-3843-0410-af09-ebfb50bd7c74
parent 091b3270
No related branches found
No related tags found
No related merge requests found
...@@ -67,6 +67,7 @@ void LoadBalancer :: DataBase :: graphCollect (const MpAccessGlobal & mpa, ...@@ -67,6 +67,7 @@ void LoadBalancer :: DataBase :: graphCollect (const MpAccessGlobal & mpa,
const int np = mpa.psize () ; const int np = mpa.psize () ;
ObjectStream os ; ObjectStream os ;
{ {
int len = _vertexSet.size () ; int len = _vertexSet.size () ;
os.writeObject (len) ; os.writeObject (len) ;
...@@ -78,29 +79,50 @@ void LoadBalancer :: DataBase :: graphCollect (const MpAccessGlobal & mpa, ...@@ -78,29 +79,50 @@ void LoadBalancer :: DataBase :: graphCollect (const MpAccessGlobal & mpa,
i != _edgeSet.end () ; os.writeObject (*i++)) ;} i != _edgeSet.end () ; os.writeObject (*i++)) ;}
} }
try { try {
// exchange data
vector < ObjectStream > osv = mpa.gcollect (os) ; vector < ObjectStream > osv = mpa.gcollect (os) ;
{for (int i = 0 ; i < np ; i ++) {
int len ; // free memory
osv [i].readObject (len) ; os.reset ();
assert (len >= 0) ;
{for (int j = 0 ; j < len ; j ++) { {
GraphVertex x ; for (int i = 0 ; i < np ; i ++)
osv [i].readObject (x) ; {
* nodes ++ = pair < const GraphVertex, int > (x,i) ; int len ;
}} osv [i].readObject (len) ;
osv [i].readObject (len) ; assert (len >= 0) ;
assert (len >= 0) ; {
{for (int j = 0 ; j < len ; j ++) { for (int j = 0 ; j < len ; ++j)
GraphEdge x ; {
osv [i].readObject (x) ; GraphVertex x ;
* edges ++ = x ; osv [i].readObject (x) ;
* edges ++ = - x ; * nodes ++ = pair < const GraphVertex, int > (x,i) ;
}} }
}} }
} catch (ObjectStream :: EOFException) { osv [i].readObject (len) ;
assert (len >= 0) ;
{
for (int j = 0 ; j < len ; ++j)
{
GraphEdge x ;
osv [i].readObject (x) ;
* edges ++ = x ;
* edges ++ = - x ;
}
}
// free memory of osv[i]
osv[i].reset();
}
}
}
catch (ObjectStream :: EOFException)
{
cerr << "**FEHLER (FATAL) EOF gelesen in " << __FILE__ << " " << __LINE__ << endl ; cerr << "**FEHLER (FATAL) EOF gelesen in " << __FILE__ << " " << __LINE__ << endl ;
abort () ; abort () ;
} catch (ObjectStream :: OutOfMemoryException) { }
catch (ObjectStream :: OutOfMemoryException)
{
cerr << "**FEHLER (FATAL) Out Of Memory in " << __FILE__ << " " << __LINE__ << endl ; cerr << "**FEHLER (FATAL) Out Of Memory in " << __FILE__ << " " << __LINE__ << endl ;
abort () ; abort () ;
} }
...@@ -133,8 +155,6 @@ static void optimizeCoverage (const int nparts, const int len, const int * const ...@@ -133,8 +155,6 @@ static void optimizeCoverage (const int nparts, const int len, const int * const
int distance = (pos - covBegin); int distance = (pos - covBegin);
pair<int, int> val (i,distance); pair<int, int> val (i,distance);
max [*pos] = val; max [*pos] = val;
//pair < int, int > (i, distance);
//(pos - cov [i].begin ())) ;
} }
} }
vector < int > renumber (nparts, -1L) ; vector < int > renumber (nparts, -1L) ;
...@@ -230,11 +250,14 @@ bool LoadBalancer :: DataBase :: repartition (MpAccessGlobal & mpa, method mth) ...@@ -230,11 +250,14 @@ bool LoadBalancer :: DataBase :: repartition (MpAccessGlobal & mpa, method mth)
if (mth == NONE) return false ; if (mth == NONE) return false ;
// create maps for edges and vertices
ldb_edge_set_t edges ; ldb_edge_set_t edges ;
ldb_vertex_map_t nodes ; ldb_vertex_map_t nodes ;
graphCollect (mpa,insert_iterator < ldb_vertex_map_t > (nodes,nodes.begin ()), graphCollect (mpa,
insert_iterator < ldb_edge_set_t > (edges,edges.begin ())) ; insert_iterator < ldb_vertex_map_t > (nodes,nodes.begin ()),
insert_iterator < ldb_edge_set_t > (edges,edges.begin ())
) ;
// 'ned' ist die Anzahl der Kanten im Graphen, 'nel' die Anzahl der Knoten. // 'ned' ist die Anzahl der Kanten im Graphen, 'nel' die Anzahl der Knoten.
// Der Container 'nodes' enth"alt alle Knoten des gesamten Grobittergraphen // Der Container 'nodes' enth"alt alle Knoten des gesamten Grobittergraphen
...@@ -247,27 +270,31 @@ bool LoadBalancer :: DataBase :: repartition (MpAccessGlobal & mpa, method mth) ...@@ -247,27 +270,31 @@ bool LoadBalancer :: DataBase :: repartition (MpAccessGlobal & mpa, method mth)
const int ned = edges.size () ; const int ned = edges.size () ;
const int nel = nodes.size () ; const int nel = nodes.size () ;
if (edges.size ()) { if (edges.size ())
if (!((*edges.rbegin ()).leftNode () < nel)) { {
if (!((*edges.rbegin ()).leftNode () < nel))
{
cerr << "**WARNUNG (FEHLER IGNORIERT) Die Indexmenge ist nicht volls\"andig\n" ; cerr << "**WARNUNG (FEHLER IGNORIERT) Die Indexmenge ist nicht volls\"andig\n" ;
cerr << " \"uberdeckt zur Neupartitionierung. In " << __FILE__ << " " << __LINE__ << endl ; cerr << " \"uberdeckt zur Neupartitionierung. In " << __FILE__ << " " << __LINE__ << endl ;
return false ; return false ;
} }
// allocate edge memory for graph partitioners
int * const edge_p = new int [nel + 1] ; int * const edge_p = new int [nel + 1] ;
int * const edge = new int [ned] ; int * const edge = new int [ned] ;
int * const edge_w = new int [ned] ; int * const edge_w = new int [ned] ;
float * const vertex_w = new float [nel] ;
int * const vertex_wInt = new int [nel] ; assert ( edge_p && edge && edge_w ) ;
int * part = new int [nel] ;
assert (edge_p && edge && edge_w && vertex_w && vertex_wInt && part) ;
{ {
int * edge_pPos = edge_p ; int * edge_pPos = edge_p ;
int count = 0, index = -1 ; int count = 0, index = -1 ;
for (ldb_edge_set_t :: const_iterator i = edges.begin () ; i != edges.end () ; i ++) { for (ldb_edge_set_t :: const_iterator i = edges.begin () ;
if ((*i).leftNode () != index) { i != edges.end () ; i ++)
{
if ((*i).leftNode () != index)
{
assert ((*i).leftNode () < nel) ; assert ((*i).leftNode () < nel) ;
* edge_pPos ++ = count ; * edge_pPos ++ = count ;
index = (*i).leftNode () ; index = (*i).leftNode () ;
...@@ -278,28 +305,38 @@ bool LoadBalancer :: DataBase :: repartition (MpAccessGlobal & mpa, method mth) ...@@ -278,28 +305,38 @@ bool LoadBalancer :: DataBase :: repartition (MpAccessGlobal & mpa, method mth)
} }
* edge_pPos = count ; * edge_pPos = count ;
assert (edge_p [0] == 0 && edge_p [nel] == ned) ; assert (edge_p [0] == 0 && edge_p [nel] == ned) ;
// free memory, not needed anymore
edges.clear();
} }
// get vertex memory
float * const vertex_w = new float [nel] ;
int * const vertex_wInt = new int [nel] ;
int * part = new int [nel] ;
assert ( vertex_w && vertex_wInt && part) ;
{ {
vector < int > check (nel, 0L) ; vector < int > check (nel, 0L) ;
for (ldb_vertex_map_t :: const_iterator i = nodes.begin () ; i != nodes.end () ; i ++ ) { for (ldb_vertex_map_t :: const_iterator i = nodes.begin () ; i != nodes.end () ; i ++ )
{
int j = (*i).first.index () ; int j = (*i).first.index () ;
assert (0 <= j && j < nel) ; assert (0 <= j && j < nel) ;
assert (0 <= (*i).second && (*i).second < np) ; assert (0 <= (*i).second && (*i).second < np) ;
part [j] = (*i).second ; part [j] = (*i).second ;
check [j] = 1 ; check [j] = 1 ;
vertex_w [j] = vertex_wInt [j] = (*i).first.weight () ; vertex_w [j] = vertex_wInt [j] = (*i).first.weight () ;
// Hier besetht die M"oglichkeit auch die Schwerpunktskoordinaten
// der Grobgitterelemente auszulesen:
//
// double (&p)[3] = (*i).first.center () [0] ;
} }
// free memory, not needed anymore
nodes.clear();
if (nel != accumulate (check.begin (), check.end (), 0)) { if (nel != accumulate (check.begin (), check.end (), 0))
{
cerr << "**WARNUNG (IGNORIERT) Keine Neupartitionierung wegen fehlgeschlagenem Konsistenzcheck." ; cerr << "**WARNUNG (IGNORIERT) Keine Neupartitionierung wegen fehlgeschlagenem Konsistenzcheck." ;
cerr << " In Datei: " << __FILE__ << " Zeile: " << __LINE__ << endl ; cerr << " In Datei: " << __FILE__ << " Zeile: " << __LINE__ << endl ;
delete [] part ; delete [] part ;
delete [] vertex_wInt ; delete [] vertex_wInt ;
delete [] vertex_w ; delete [] vertex_w ;
delete [] edge_w ; delete [] edge_w ;
delete [] edge ; delete [] edge ;
...@@ -307,70 +344,75 @@ bool LoadBalancer :: DataBase :: repartition (MpAccessGlobal & mpa, method mth) ...@@ -307,70 +344,75 @@ bool LoadBalancer :: DataBase :: repartition (MpAccessGlobal & mpa, method mth)
return false ; return false ;
} }
} }
if (np > 1) {
if (np > 1)
// Abfangen, falls nur ein teilgebiet gebildet werden soll, {
// sonst Speicherallocationsfehler in den Partitionierern, // Abfangen, falls nur ein teilgebiet gebildet werden soll,
// zumindest bei PARTY 1.1. // sonst Speicherallocationsfehler in den Partitionierern,
// zumindest bei PARTY 1.1.
int * neu = new int [nel] ; int * neu = new int [nel] ;
assert (neu) ; assert (neu) ;
copy (part, part + nel, neu) ; copy (part, part + nel, neu) ;
switch (mth) { switch (mth)
{
// Die Methode 'collect' sammelt alle Elemente in einer Partition ein. // Die Methode 'collect' sammelt alle Elemente in einer Partition ein.
case COLLECT : case COLLECT :
fill (neu, neu + nel, 0L) ; fill (neu, neu + nel, 0L) ;
break ; break ;
case PARTY_linear : case PARTY_linear :
global_linear (nel, vertex_w, np, 0.0, neu) ; global_linear (nel, vertex_w, np, 0.0, neu) ;
break ; break ;
case PARTY_gain :
global_gain (nel, vertex_w, edge_p, edge, edge_w, np, 0.0, neu) ; case PARTY_gain :
break ; global_gain (nel, vertex_w, edge_p, edge, edge_w, np, 0.0, neu) ;
case PARTY_farhat : break ;
global_farhat (nel, vertex_w, edge_p, edge, edge_w, np, 0.0, neu) ;
break ; case PARTY_farhat :
global_farhat (nel, vertex_w, edge_p, edge, edge_w, np, 0.0, neu) ;
break ;
case PARTY_kernighanLin : case PARTY_kernighanLin :
// Die dreifache Anwendung der Helpful-Set bzw. Kenighan-Lin Heuristik
// Die dreifache Anwendung der Helpful-Set bzw. Kenighan-Lin Heuristik // basiert auf Erfahrungswerten und liefert einigermassen ausiterierte
// basiert auf Erfahrungswerten und liefert einigermassen ausiterierte // Partitionen.
// Partitionen.
local_kl (nel, vertex_w, edge_p, edge, edge_w, np, 3.0, neu, 0) ; local_kl (nel, vertex_w, edge_p, edge, edge_w, np, 3.0, neu, 0) ;
local_kl (nel, vertex_w, edge_p, edge, edge_w, np, 1.0, neu, 0) ; local_kl (nel, vertex_w, edge_p, edge, edge_w, np, 1.0, neu, 0) ;
local_kl (nel, vertex_w, edge_p, edge, edge_w, np, 0.0, neu, 0) ; local_kl (nel, vertex_w, edge_p, edge, edge_w, np, 0.0, neu, 0) ;
break ; break ;
case PARTY_helpfulSet :
local_hs (nel, vertex_w, edge_p, edge, edge_w, np, 2.0, neu, 0) ; case PARTY_helpfulSet :
local_hs (nel, vertex_w, edge_p, edge, edge_w, np, 1.0, neu, 0) ; local_hs (nel, vertex_w, edge_p, edge, edge_w, np, 2.0, neu, 0) ;
local_hs (nel, vertex_w, edge_p, edge, edge_w, np, 0.0, neu, 0) ; local_hs (nel, vertex_w, edge_p, edge, edge_w, np, 1.0, neu, 0) ;
break ; local_hs (nel, vertex_w, edge_p, edge, edge_w, np, 0.0, neu, 0) ;
break ;
case METIS_PartGraphKway :
{ case METIS_PartGraphKway :
int wgtflag = 3, numflag = 0, options = 0, edgecut, n = nel, npart = np ; {
:: METIS_PartGraphKway (&n, edge_p, edge, vertex_wInt, edge_w, int wgtflag = 3, numflag = 0, options = 0, edgecut, n = nel, npart = np ;
& wgtflag, & numflag, & npart, & options, & edgecut, neu) ; :: METIS_PartGraphKway (&n, edge_p, edge, vertex_wInt, edge_w,
} & wgtflag, & numflag, & npart, & options, & edgecut, neu) ;
break ; }
case METIS_PartGraphRecursive : break ;
{ case METIS_PartGraphRecursive :
int wgtflag = 3, numflag = 0, options = 0, edgecut, n = nel, npart = np ; {
:: METIS_PartGraphRecursive (&n, edge_p, edge, vertex_wInt, edge_w, int wgtflag = 3, numflag = 0, options = 0, edgecut, n = nel, npart = np ;
& wgtflag, & numflag, & npart, & options, & edgecut, neu) ; :: METIS_PartGraphRecursive (&n, edge_p, edge, vertex_wInt, edge_w,
} & wgtflag, & numflag, & npart, & options, & edgecut, neu) ;
break ; }
default : break ;
cerr << "**WARNUNG (FEHLER IGNORIERT) Ung\"ultige Methode [" << mth << "] zur\n" ; default :
cerr << " Neupartitionierung angegeben. In " << __FILE__ << " " << __LINE__ << endl ; cerr << "**WARNUNG (FEHLER IGNORIERT) Ung\"ultige Methode [" << mth << "] zur\n" ;
cerr << " Neupartitionierung angegeben. In " << __FILE__ << " " << __LINE__ << endl ;
delete [] neu ;
delete [] part ; delete [] neu ;
delete [] vertex_wInt ; delete [] part ;
delete [] vertex_wInt ;
delete [] vertex_w ; delete [] vertex_w ;
delete [] edge_w ; delete [] edge_w ;
delete [] edge ; delete [] edge ;
...@@ -378,33 +420,35 @@ bool LoadBalancer :: DataBase :: repartition (MpAccessGlobal & mpa, method mth) ...@@ -378,33 +420,35 @@ bool LoadBalancer :: DataBase :: repartition (MpAccessGlobal & mpa, method mth)
return false ; return false ;
} }
// collectInsulatedNodes () sucht alle isolierten Knoten im Graphen und klebt // collectInsulatedNodes () sucht alle isolierten Knoten im Graphen und klebt
// diese einfach mit dem Nachbarknoten "uber die Kante mit dem gr"ossten Gewicht // diese einfach mit dem Nachbarknoten "uber die Kante mit dem gr"ossten Gewicht
// zusammen. // zusammen.
collectInsulatedNodes (nel, vertex_w, edge_p, edge, edge_w, np, neu) ; collectInsulatedNodes (nel, vertex_w, edge_p, edge, edge_w, np, neu) ;
// optimizeCoverage () versucht, die Lastverschiebung durch Permutation der // optimizeCoverage () versucht, die Lastverschiebung durch Permutation der
// Gebietszuordnung zu beschleunigen. Wenn die alte Aufteilung von der neuen // Gebietszuordnung zu beschleunigen. Wenn die alte Aufteilung von der neuen
// abweicht, dann wird 'change'auf 'true' gestetzt, damit der Lastverschieber // abweicht, dann wird 'change'auf 'true' gestetzt, damit der Lastverschieber
// in Aktion tritt. // in Aktion tritt.
optimizeCoverage (np, nel, part, vertex_w, neu, me == 0 ? debugOption (4) : 0) ; optimizeCoverage (np, nel, part, vertex_w, neu, me == 0 ? debugOption (4) : 0) ;
// Vergleichen, ob sich die Aufteilung des Gebiets "uberhaupt ver"andert hat. // Vergleichen, ob sich die Aufteilung des Gebiets "uberhaupt ver"andert hat.
change = ! equal (neu, neu + nel, part) ; change = ! equal (neu, neu + nel, part) ;
if (change) { if (change)
{
// Hier die neue Zuordnung auf den eigenen Lastvertex-Container schreiben. // Hier die neue Zuordnung auf den eigenen Lastvertex-Container schreiben.
// Dadurch werden die Grobgitterelemente an das neue Teilgebiet zugewiesen. // Dadurch werden die Grobgitterelemente an das neue Teilgebiet zugewiesen.
for (ldb_vertex_map_t :: iterator i = _vertexSet.begin () ; i != _vertexSet.end () ; i ++) for (ldb_vertex_map_t :: iterator i = _vertexSet.begin () ; i != _vertexSet.end () ; i ++)
_connect.insert ((*i).second = neu [(*i).first.index ()]) ; _connect.insert ((*i).second = neu [(*i).first.index ()]) ;
} }
delete [] neu ; delete [] neu ;
} }
delete [] part ; delete [] part ;
delete [] vertex_wInt ; delete [] vertex_wInt ;
delete [] vertex_w ; delete [] vertex_w ;
...@@ -412,6 +456,8 @@ bool LoadBalancer :: DataBase :: repartition (MpAccessGlobal & mpa, method mth) ...@@ -412,6 +456,8 @@ bool LoadBalancer :: DataBase :: repartition (MpAccessGlobal & mpa, method mth)
delete [] edge ; delete [] edge ;
delete [] edge_p ; delete [] edge_p ;
} }
if (debugOption (3) && ! me) { if (debugOption (3) && ! me) {
cout << "**INFO LoadBalancerPll :: DataBase :: repartition ()\n" cout << "**INFO LoadBalancerPll :: DataBase :: repartition ()\n"
<< " globalen Graphen mit " << (ned/2) << " Kanten und " << nel << " Knoten erzeugt\n" << " globalen Graphen mit " << (ned/2) << " Kanten und " << nel << " Knoten erzeugt\n"
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment