int SCOTCH_graphMapCompute ( SCOTCH_Graph * const grafptr, /*+ Graph to order +*/ SCOTCH_Mapping * const mappptr, /*+ Mapping to compute +*/ SCOTCH_Strat * const stratptr) /*+ Mapping strategy +*/ { Kgraph mapgrafdat; /* Effective mapping graph */ const Strat * mapstratptr; /* Pointer to mapping strategy */ LibMapping * restrict lmapptr; int o; #ifdef SCOTCH_DEBUG_GRAPH2 if (graphCheck ((Graph *) grafptr) != 0) { errorPrint ("SCOTCH_graphMapCompute: invalid input graph"); return (1); } #endif /* SCOTCH_DEBUG_GRAPH2 */ lmapptr = (LibMapping *) mappptr; if (*((Strat **) stratptr) == NULL) { /* Set default mapping strategy if necessary */ ArchDom archdomnorg; archDomFrst (&lmapptr->m.archdat, &archdomnorg); if (archVar (&lmapptr->m.archdat)) SCOTCH_stratGraphClusterBuild (stratptr, 0, 1, 0.0, 0.05); else SCOTCH_stratGraphMapBuild (stratptr, 0, archDomSize (&lmapptr->m.archdat, &archdomnorg), 0.05); } mapstratptr = *((Strat **) stratptr); if (mapstratptr->tabl != &kgraphmapststratab) { errorPrint ("SCOTCH_graphMapCompute: not a graph mapping strategy"); return (1); } if (kgraphInit (&mapgrafdat, (Graph *) grafptr, &lmapptr->m) != 0) return (1); o = kgraphMapSt (&mapgrafdat, mapstratptr); /* Perform mapping */ lmapptr->m.domnmax = mapgrafdat.m.domnmax; /* Do not free the mapping, as it has been cloned */ lmapptr->m.domnnbr = mapgrafdat.m.domnnbr; lmapptr->m.domntab = mapgrafdat.m.domntab; /* Update pointer to domntab in case it has changed */ mapgrafdat.m.parttax = NULL; /* Prevent mapping arrays from being freed by graph */ mapgrafdat.m.domntab = NULL; kgraphExit (&mapgrafdat); if (lmapptr->parttax != NULL) { /* Propagate mapping data to user partition array */ Gnum vertnum; Gnum vertnnd; for (vertnum = lmapptr->m.baseval, vertnnd = vertnum + lmapptr->m.vertnbr; vertnum < vertnnd; vertnum ++) lmapptr->parttax[vertnum] = archDomNum (&lmapptr->m.archdat, &lmapptr->m.domntab[lmapptr->m.parttax[vertnum]]); } return (o); }
static void run_scotch( Container &c, MapContainer &mapping, const std::size_t cores, weight_function_t weight_func, void *weight ) { #if 0 static_assert( std::is_signed< std::remove_reference< decltype( c.end() ) >::type >::value, "Container must have signed types so that -1 may signify no mapping" ); #endif raftgraph_t raft_graph; get_graph_info( c, raft_graph, weight_func, nullptr ); SCOTCH_Graph graph; if( SCOTCH_graphInit( &graph ) != 0 ) { /** TODO, add RaftLib Exception **/ std::cerr << "Failed to initialize graph!!\n"; exit( EXIT_FAILURE ); } auto table( raft_graph.getScotchTables() ); if( SCOTCH_graphBuild( &graph /** graph ptr **/, 0 /** base value **/, table.num_vertices /** vertex nmbr (zero indexed) **/, table.vtable /** vertex tab **/, &table.vtable[ 1 ] /** vendtab **/, nullptr /** velotab **/, nullptr /** vlbltab **/, table.num_edges /** edge number **/, table.etable /** edge tab **/, table.eweight /** edlotab **/ ) != 0 ) { /** TODO, add RaftLib Exception **/ std::cerr << "Failed to build graph\n"; exit( EXIT_FAILURE ); } if( SCOTCH_graphCheck( &graph ) != 0 ) { /** TODO, add RaftLib Exception **/ std::cerr << "Graph is inconsistent\n"; std::remove_reference< decltype( table ) >::type::print( std::cerr, table ); std::cerr << "\n"; raft_graph.print( std::cerr ); exit( EXIT_FAILURE ); } /** TODO, we can do much more with this arch file **/ SCOTCH_Arch archdat; if( SCOTCH_archInit( &archdat ) != 0 ) { /** TODO, add RaftLib Exception **/ std::cerr << "Architecture initialization failed\n"; exit( EXIT_FAILURE ); } /** core are equal **/ if( SCOTCH_archCmplt( &archdat, cores /** num cores **/) != 0 ) { /** TODO, add RaftLib Exception **/ std::cerr << "Failed to create architecture file\n"; exit( EXIT_FAILURE ); } /** strategy **/ SCOTCH_Strat stradat; if( SCOTCH_stratInit( &stradat ) != 0 ) { /** TODO, add RaftLib Exception **/ std::cerr << "Failed to init strategy!!\n"; exit( EXIT_FAILURE ); } /** build recursive strategy **/ if( SCOTCH_stratGraphClusterBuild( &stradat, SCOTCH_STRATSPEED, cores, .75, .01) != 0 ) { /** TODO, add RaftLib Exception **/ std::cerr << "Failed to map strategy graph!!\n"; exit( EXIT_FAILURE ); } if( SCOTCH_graphMap( &graph /** graph ptr **/, &archdat, &stradat, table.partition /** parttab **/ ) != 0 ) { /** TODO, add RaftLib Exception **/ std::cerr << "Failed to map!!\n"; exit( EXIT_FAILURE ); } /** * first case is for if we've mapped all vertices, * second is for when some of the kernels are innactive * in which case the number of vertices in the * table will be less than the size of c in which case * we need to get which vertices (the actual number id * from the application) are mapped and to where, the * returned table in mapping must include even the * vertices that aren't active (indicated by a -1) so * that the returning loop can be as simple as possible */ if( c.size() == table.num_vertices ) { /** copy mapping **/ for( auto i( 0 ); i < table.num_vertices; i++ ) { mapping.emplace_back( table.partition[ i ] ); } } else { const auto &vmapping( raft_graph.getVertexNumbersAtIndicies() ); auto it_map_index( vmapping.cbegin() ); auto table_index( 0 ); const auto size( c.size() ); for( auto i( 0 ); i < size; i++ ) { if( i == (*it_map_index) && it_map_index != vmapping.cend() ) { mapping.emplace_back( table.partition[ table_index++ ] ); ++it_map_index; } else { mapping.emplace_back( -1 ); } } } /** call exit graph **/ SCOTCH_graphExit( &graph ); SCOTCH_stratExit( &stradat ); SCOTCH_archExit ( &archdat ); return; }