37 #include "SBDTree.hpp"
38 #include "Triplet.hpp"
48 template<
typename T >
59 std::vector< std::vector< Triplet< T > > >
nonzeroes;
100 for(
unsigned long int k=0; k<
p->size(); ++k )
106 for(
unsigned long int k=0; k<
p->size(); ++k )
118 const unsigned long int P =
p->parent[
walk ];
119 const unsigned long int l =
p->left_child[
walk ];
120 const unsigned long int r =
p->right_child[
walk ];
129 }
while(
walk !=
p->parent[
ID ] );
165 while( this->
walk != this->
p->parent[ this->ID ] ) {
168 !this->p_processed->operator[]( this->p->left_child[ this->walk ] ) )
169 this->
walk = this->
p->left_child[ this->
walk ];
172 if( this->
p_processed->operator[]( this->walk ) ) {
175 !this->p_processed->operator[]( this->p->right_child[ this->walk ] ) ) {
176 this->
walk = this->
p->right_child[ this->
walk ];
179 this->
walk = this->
p->parent[ this->
walk ];
215 while( this->
walk != this->
p->parent[ this->ID ] ) {
218 !this->p_processed->operator[]( this->p->left_child[ this->walk ] ) )
219 this->
walk = this->
p->left_child[ this->
walk ];
223 !this->p_processed->operator[]( this->p->right_child[ this->walk ] ) )
224 this->
walk = this->
p->right_child[ this->
walk ];
225 else if( !this->
p_processed->operator[]( this->walk ) ) {
232 this->
walk = this->
p->parent[ this->
walk ];
253 const unsigned long int min_i,
const unsigned long int min_j,
254 std::vector< bool > &emptyRows, std::vector< bool > &emptyCols,
257 for(
unsigned long int k = 0; k <
nonzeroes.size(); ++k ) {
259 const unsigned long int i =
nonzeroes[ k ].i();
260 const unsigned long int j =
nonzeroes[ k ].j();
261 assert( i - min_i < emptyRows.size() );
262 assert( j - min_j < emptyCols.size() );
263 if( emptyRows[ i - min_i ] ) emptyRows[ i - min_i ] =
false;
264 if( emptyCols[ j - min_j ] ) emptyCols[ j - min_j ] =
false;
265 if( empty ) empty =
false;
270 void updateMinMax(
const unsigned long int walk,
const unsigned long int s,
271 unsigned long int &min_i,
unsigned long int &max_i,
272 unsigned long int &min_j,
unsigned long int &max_j ) {
273 for(
unsigned long int k = 0; k <
nonzeroes[ walk ].size(); k++ )
275 const unsigned long int i =
nonzeroes[ walk ][ k ].i();
276 const unsigned long int j =
nonzeroes[ walk ][ k ].j();
277 if( i < min_i ) min_i = i;
278 if( i > max_i ) max_i = i;
279 if( j < min_j ) min_j = j;
280 if( j > max_j ) max_j = j;
289 unsigned long int &min_i,
unsigned long int &max_i,
290 unsigned long int &min_j,
unsigned long int &max_j ) {
292 min_i = min_j = ULONG_MAX;
295 unsigned long int walk = ID;
309 const unsigned long int from,
const unsigned long int s,
310 const std::map< unsigned long int, unsigned long int > &rowGlobalToLocal,
311 const std::map< unsigned long int, unsigned long int > &colGlobalToLocal ) {
312 for(
unsigned long int i=0; i<
nonzeroes[ from ].size(); i++ ) {
315 const unsigned long int old_i =
nonzeroes[ from ][ i ].i();
316 const unsigned long int old_j =
nonzeroes[ from ][ i ].j();
317 assert( rowGlobalToLocal.find( old_i ) != rowGlobalToLocal.end() );
318 assert( colGlobalToLocal.find( old_j ) != colGlobalToLocal.end() );
319 const unsigned long int new_i = rowGlobalToLocal.find( old_i )->second;
320 const unsigned long int new_j = colGlobalToLocal.find( old_j )->second;
322 into.back().meta = s;
345 const unsigned long int s,
348 std::vector< unsigned long int > &upscaled_hierarchy,
349 std::vector< unsigned long int > &upscaled_row_bounds,
350 std::vector< unsigned long int > &upscaled_column_bounds,
351 std::vector< unsigned long int > &rowLocalToGlobal,
352 std::vector< unsigned long int > &columnLocalToGlobal,
353 std::map< unsigned long int, unsigned long int > &rowGlobalToLocal,
354 std::map< unsigned long int, unsigned long int > &colGlobalToLocal ) {
357 unsigned long int min_i, min_j, max_i, max_j;
364 std::cout <<
"Processor " << s <<
" has global ranges \t( " << min_i <<
", " << max_i <<
" ) x ( " << min_j <<
", " << max_j <<
" )" << std::endl;
367 std::vector< bool > emptyRows, emptyCols, emptyNodes;
368 for(
unsigned long int i = min_i; i < max_i; ++i )
369 emptyRows.push_back(
true );
370 for(
unsigned long int j = min_j; j < max_j; ++j )
371 emptyCols.push_back(
true );
372 for(
unsigned long int k = 0; k <
size(); k++ )
373 emptyNodes.push_back(
true );
374 assert( emptyRows.size() == max_i - min_i );
375 assert( emptyCols.size() == max_j - min_j );
382 emptyNodes[ it.position() ] = empty;
383 }
while( it.next() );
386 unsigned long int walk = ID;
387 while( walk !=
root ) {
391 emptyNodes[ walk ] = empty;
395 for(
unsigned long int i = 0; i < max_i - min_i; ++i )
396 if( !emptyRows[ i ] ) {
397 rowGlobalToLocal[ i + min_i ] = rowLocalToGlobal.size();
398 rowLocalToGlobal.push_back( i + min_i );
400 for(
unsigned long int j = 0; j < max_j - min_j; ++j )
401 if( !emptyCols[ j ] ) {
402 colGlobalToLocal[ j + min_j ] = columnLocalToGlobal.size();
403 columnLocalToGlobal.push_back( j + min_j );
407 unsigned long int lowest_index, highest_index;
409 lowest_index = ULONG_MAX;
412 const unsigned long int pos = it2.
position();
413 if( emptyNodes[ pos ] )
continue;
414 if( pos < lowest_index ) lowest_index = pos;
415 if( pos > highest_index ) highest_index = pos;
416 }
while( it2.
next() );
419 unsigned long int numEmptyRows, numEmptyCols;
420 numEmptyRows = numEmptyCols = 0;
421 for(
unsigned long int i = 0; i < emptyRows.size(); i++ )
422 if( emptyRows[ i ] ) numEmptyRows++;
423 for(
unsigned long int j = 0; j < emptyCols.size(); j++ )
424 if( emptyCols[ j ] ) numEmptyCols++;
427 std::cout <<
"Processor " << s <<
" has local size \t" << (max_i-numEmptyRows-min_i) <<
" x " << (max_j-numEmptyCols-min_j) << std::endl;
431 std::map< unsigned long int, unsigned long int >::iterator glob2loc;
433 const unsigned long int pos = in_it.
position();
436 if( pos < lowest_index || pos > highest_index )
continue;
438 addNonzeroes( local_nonzeroes, pos, s, rowGlobalToLocal, colGlobalToLocal );
440 glob2loc = rowGlobalToLocal.lower_bound( this->
r_lo[ pos ] );
441 assert( glob2loc->first >= this->r_lo[ pos ] );
442 upscaled_row_bounds.push_back( glob2loc->second );
444 glob2loc = colGlobalToLocal.lower_bound( this->
c_lo[ pos ] );
445 assert( glob2loc->first >= this->c_lo[ pos ] );
446 upscaled_column_bounds.push_back( glob2loc->second );
448 upscaled_hierarchy.push_back ( pos == ID ? 0 :
parent[ pos ] - lowest_index );
449 }
while( in_it.
next() );
452 std::vector< unsigned long int >::iterator loc2glob;
453 loc2glob = std::lower_bound( rowLocalToGlobal.begin(), rowLocalToGlobal.end(), this->
r_hi[ highest_index ] );
454 upscaled_row_bounds.push_back( loc2glob - rowLocalToGlobal.begin() );
456 loc2glob = std::lower_bound( columnLocalToGlobal.begin(), columnLocalToGlobal.end(), this->
c_hi[ highest_index ] );
457 upscaled_column_bounds.push_back( loc2glob - columnLocalToGlobal.begin() );
462 addNonzeroes( remote_nonzeroes, walk, s, rowGlobalToLocal, colGlobalToLocal );
472 std::vector< unsigned long int > &r_hierarchy,
473 std::vector< unsigned long int > &c_hierarchy,
474 std::vector< unsigned long int > &r_bounds,
475 std::vector< unsigned long int > &c_bounds,
476 unsigned long int *row_perm = NULL,
477 unsigned long int *col_perm = NULL,
478 unsigned long int *proc2proc = NULL ) :
SBDTree( r_hierarchy, c_hierarchy, r_bounds, c_bounds ) {
480 const unsigned long int trueP = r_bounds.
size() / 2;
481 if( floor(log2(trueP)) != log2(trueP) && trueP != P ) {
482 std::cout <<
"P=" << trueP <<
" is not a power of 2. Current Upscaler cannot handle incomplete binary trees, exiting." << std::endl;
489 for(
unsigned long int i=0; i<this->
size(); ++i )
490 for(
unsigned long int s=0; s<P; ++s )
496 std::map< unsigned long int, unsigned long int > rowMap, colMap;
499 for(
unsigned long int i=r_bounds.size()-1; i>0; --i ) {
500 rowMap[ r_bounds[ i ] ] = i - 1;
503 for(
unsigned long int j=c_bounds.size()-1; j>0; --j ) {
504 colMap[ c_bounds[ j ] ] = j - 1;
507 for(
unsigned long int k=0; k<
nonzeroes.size(); ++k ) {
508 const unsigned long int i = row_perm == NULL ?
nonzeroes[ k ].i() : row_perm[
nonzeroes[ k ].i() ];
509 const unsigned long int j = col_perm == NULL ? nonzeroes[ k ].j() : col_perm[ nonzeroes[ k ].j() ];
510 const unsigned long int s = proc2proc == NULL ? nonzeroes[ k ].meta : proc2proc[ nonzeroes[ k ].meta ];
511 const unsigned long int u = rowMap.upper_bound( i )->second;
512 const unsigned long int v = colMap.upper_bound( j )->second;
515 assert( u < r_hierarchy.size() );
516 assert( v < c_hierarchy.size() );
517 assert(
r_lo[ u ] <= i && i <
r_hi[ u ] );
518 assert(
c_lo[ v ] <= j && j <
c_hi[ v ] );
521 this->nonzeroes[ u ].push_back( newTriplet );
522 }
else if( u ==
root || v ==
root ) {
524 this->nonzeroes[
root ].push_back( newTriplet );
525 }
else if( (u && 1) == 1 || (v && 1 ) == 1) {
526 unsigned long int walk = (u && 1) == 1 ?
parent[ u ] :
parent[ v ];
527 const unsigned long int compare = (u && 1) == 1 ? v : u;
528 while( walk !=
root && walk != compare )
531 this->nonzeroes[ walk ].push_back( newTriplet );
533 std::cerr <<
"Nonzero in two different pure SBD blocks, which is impossible." << std::endl <<
534 "Quitting on account of a bad SBD hierarchy input." << std::endl;
535 exit( EXIT_FAILURE );
540 unsigned long int newnnz = 0;
541 for(
unsigned long int t = 0; t <
size(); ++t )
571 std::vector< unsigned long int > &upscaled_hierarchy,
572 std::vector< unsigned long int > &upscaled_row_bounds,
573 std::vector< unsigned long int > &upscaled_column_bounds,
574 std::vector< unsigned long int > &rowLocalToGlobal,
575 std::vector< unsigned long int > &columnLocalToGlobal,
576 std::map< unsigned long int, unsigned long int > &rowGlobalToLocal,
577 std::map< unsigned long int, unsigned long int > &colGlobalToLocal,
578 const unsigned long int P,
const unsigned long int Pref ) {
581 std::vector< bool > empty;
582 for(
unsigned long int i = 0; i <
size(); ++i ) empty.push_back(
true );
585 for(
unsigned long int i = 0; i <
size(); ++i ) {
586 for(
unsigned long int k = 0; k <
nonzeroes[ i ].size(); ++k ) {
597 const unsigned long int pos = post_it.
position();
604 if( empty[ pos ] ) empty[ pos ] =
false;
606 if( empty[ pos ] ) empty[ pos ] =
false;
609 }
while( post_it.
next() );
612 unsigned long int root = ULONG_MAX;
615 const unsigned long int pos = pre_it.
position();
619 if( root == ULONG_MAX )
622 std::cout <<
"There seem to be multiple leaf nodes beloning to target processor, yet there are no shared separators?" << std::endl;
634 }
while( pre_it.
next() );
636 if( root == ULONG_MAX ) {
637 std::cerr <<
"No root found! Error in hierarchy, exiting..." << std::endl;
643 remote_nonzeroes, upscaled_hierarchy,
644 upscaled_row_bounds, upscaled_column_bounds,
645 rowLocalToGlobal, columnLocalToGlobal,
646 rowGlobalToLocal, colGlobalToLocal );
651 std::cout <<
"Index: ";
652 for(
unsigned long int i=0; i<
size(); ++i )
653 std::cout << i <<
" ";
654 std::cout << std::endl;
655 std::cout <<
"Hierarchy: ";
656 for(
unsigned long int i=0; i<
size(); ++i )
658 std::cout << std::endl;
659 std::cout <<
"Left: ";
660 for(
unsigned long int i=0; i<
size(); ++i )
662 std::cout << std::endl;
663 std::cout <<
"Right: ";
664 for(
unsigned long int i=0; i<
size(); ++i )
666 std::cout << std::endl;
treeInOrderIterator(Upscaler< T > *_p, const unsigned long int initial, std::vector< bool > *_pp=NULL)
Base constructor.
Definition: Upscaler.hpp:153
unsigned long int root
Which node ID corresponds to the root.
Definition: SBDTree.hpp:70
std::vector< std::vector< Triplet< T > > > nonzeroes
All nonzeroes, stored block-by-block.
Definition: Upscaler.hpp:59
unsigned long int * right_child
Array s.t.
Definition: SBDTree.hpp:55
unsigned long int * left_child
Array s.t.
Definition: SBDTree.hpp:52
void updateMinMax(const unsigned long int walk, const unsigned long int s, unsigned long int &min_i, unsigned long int &max_i, unsigned long int &min_j, unsigned long int &max_j)
Determine min/max of nonzeroes owned by processor s inside node walk.
Definition: Upscaler.hpp:270
unsigned long int * c_lo
Array s.t.
Definition: SBDTree.hpp:64
std::vector< bool > * p_processed
Pointer to the `processed'-vector actually used.
Definition: Upscaler.hpp:84
void getSubTree(const unsigned long int s, std::vector< Triplet< T > > &local_nonzeroes, std::vector< Triplet< T > > &remote_nonzeroes, std::vector< unsigned long int > &upscaled_hierarchy, std::vector< unsigned long int > &upscaled_row_bounds, std::vector< unsigned long int > &upscaled_column_bounds, std::vector< unsigned long int > &rowLocalToGlobal, std::vector< unsigned long int > &columnLocalToGlobal, std::map< unsigned long int, unsigned long int > &rowGlobalToLocal, std::map< unsigned long int, unsigned long int > &colGlobalToLocal, const unsigned long int P, const unsigned long int Pref)
Reads out a subtree corresponding to only the nonzeroes owned by processor s, and returns the upscale...
Definition: Upscaler.hpp:568
void getSubTree(const unsigned long int ID, const unsigned long int s, std::vector< Triplet< T > > &local_nonzeroes, std::vector< Triplet< T > > &remote_nonzeroes, std::vector< unsigned long int > &upscaled_hierarchy, std::vector< unsigned long int > &upscaled_row_bounds, std::vector< unsigned long int > &upscaled_column_bounds, std::vector< unsigned long int > &rowLocalToGlobal, std::vector< unsigned long int > &columnLocalToGlobal, std::map< unsigned long int, unsigned long int > &rowGlobalToLocal, std::map< unsigned long int, unsigned long int > &colGlobalToLocal)
Reads out a subtree and returns the upscaled version.
Definition: Upscaler.hpp:344
Upscaler(const std::vector< Triplet< T > > &nonzeroes, const unsigned long int P, std::vector< unsigned long int > &r_hierarchy, std::vector< unsigned long int > &c_hierarchy, std::vector< unsigned long int > &r_bounds, std::vector< unsigned long int > &c_bounds, unsigned long int *row_perm=NULL, unsigned long int *col_perm=NULL, unsigned long int *proc2proc=NULL)
Base constructor.
Definition: Upscaler.hpp:471
unsigned long int * r_lo
Array s.t.
Definition: SBDTree.hpp:58
unsigned long int * c_hi
Array s.t.
Definition: SBDTree.hpp:67
unsigned long int * parent
Array s.t.
Definition: SBDTree.hpp:49
Transforms SBD-structures over q parts into an SBD structure over p parts, with q>p, and q,p both powers of two.
Definition: Upscaler.hpp:49
treeIterator(Upscaler< T > *_p, const unsigned long int initial, std::vector< bool > *_pp=NULL)
Base constructor.
Definition: Upscaler.hpp:97
void readout()
Reads out SBD data and prints to std::cout.
Definition: Upscaler.hpp:650
unsigned long int position()
Definition: Upscaler.hpp:113
virtual bool next()
Definition: Upscaler.hpp:116
virtual bool next()
Moves iterator to next position.
Definition: Upscaler.hpp:214
unsigned long int size()
Gets the number of nodes.
Definition: SBDTree.cpp:222
std::vector< bool > processed
Processed[ i ] is true when this iterator has visited its i-th child.
Definition: Upscaler.hpp:78
unsigned long int * r_hi
Array s.t.
Definition: SBDTree.hpp:61
~Upscaler()
Base deconstructor.
Definition: Upscaler.hpp:547
virtual bool next()
Moves iterator to its next position.
Definition: Upscaler.hpp:164
Same as treeIterator, but does post-order traversal instead of pre-order.
Definition: Upscaler.hpp:193
void determineMinMax(const unsigned long int ID, const unsigned long int s, unsigned long int &min_i, unsigned long int &max_i, unsigned long int &min_j, unsigned long int &max_j)
Determine min/max of nonzeroes owned by processor s, contained in the subtree with root ID...
Definition: Upscaler.hpp:288
Upscaler< T > * p
Class this iterator works on.
Definition: Upscaler.hpp:87
unsigned long int walk
Current position of the iterator.
Definition: Upscaler.hpp:69
void determineEmpty(const std::vector< Triplet< T > > &nonzeroes, const unsigned long int s, const unsigned long int min_i, const unsigned long int min_j, std::vector< bool > &emptyRows, std::vector< bool > &emptyCols, bool &empty)
Determines, given a collection of nonzeroes, which rows and columns nonzeroes owned by s reside on...
Definition: Upscaler.hpp:252
void addNonzeroes(std::vector< Triplet< T > > &into, const unsigned long int from, const unsigned long int s, const std::map< unsigned long int, unsigned long int > &rowGlobalToLocal, const std::map< unsigned long int, unsigned long int > &colGlobalToLocal)
adds nonzeroes from a given node into a given vector
Definition: Upscaler.hpp:308
static const unsigned long int NO_SUCH_NODE
Integer corresponding to non-existing nodes.
Definition: SBDTree.hpp:79
unsigned long int ID
Starting position of the iterator.
Definition: Upscaler.hpp:72
Models a Separated Block Diagonal tree structure.
Definition: SBDTree.hpp:44
A single triplet value.
Definition: Triplet.hpp:52
Pre-order tree iterator.
Definition: Upscaler.hpp:65
treePostOrderIterator(Upscaler< T > *_p, const unsigned long int initial, std::vector< bool > *_pp=NULL)
Base constructor.
Definition: Upscaler.hpp:203
Same as treeIterator, but does in-order traversal instead of pre-order.
Definition: Upscaler.hpp:143
std::vector< std::vector< bool > > containsPID
Keeps track which processes are represented in which blocks.
Definition: Upscaler.hpp:62