372 const RCP<
const MeshAdapter<user_t> > &ia,
373 const RCP<const Environment> &env,
374 const RCP<
const Comm<int> > &comm,
382 numWeightsPerVertex_(0),
393 numLocalVertices_(0),
394 numGlobalVertices_(0),
399 env_->timerStart(MACRO_TIMERS,
"HyperGraphModel constructed from MeshAdapter");
409 std::string model_type(
"traditional");
410 const Teuchos::ParameterList &pl = env->getParameters();
411 const Teuchos::ParameterEntry *pe2 = pl.getEntryPtr(
"hypergraph_model_type");
413 model_type = pe2->getValue<std::string>(&model_type);
421 gno_t const *vtxIds=NULL;
423 numLocalVertices_ = ia->getLocalNumOf(primaryEType);
424 ia->getIDsViewOf(primaryEType, vtxIds);
425 size_t maxId = *(std::max_element(vtxIds,vtxIds+numLocalVertices_));
426 reduceAll(*comm_,Teuchos::REDUCE_MAX,1,&maxId,&numGlobalVertices_);
433 gids_ = arcp<const gno_t>(vtxIds, 0, numLocalVertices_,
false);
436 std::unordered_map<gno_t,lno_t> lid_mapping;
437 for (
size_t i=0;i<numLocalVertices_;i++)
438 lid_mapping[gids_[i]]=i;
445 unique = ia->areEntityIDsUnique(ia->getPrimaryEntityType());
446 numOwnedVertices_=numLocalVertices_;
447 isOwner_ = ArrayRCP<bool>(numLocalVertices_,
true);
450 Tpetra::global_size_t numGlobalCoords =
451 Teuchos::OrdinalTraits<Tpetra::global_size_t>::invalid();
452 mapWithCopies = rcp(
new map_t(numGlobalCoords, gids_(), 0, comm));
455 oneToOneMap = Tpetra::createOneToOne<lno_t, gno_t>(mapWithCopies);
457 numOwnedVertices_=oneToOneMap->getLocalNumElements();
458 for (
size_t i=0;i<numLocalVertices_;i++) {
459 isOwner_[i] = oneToOneMap->isNodeGlobalElement(gids_[i]);
464 if (model_type==
"traditional") {
468 gno_t const *edgeIds=NULL;
470 numLocalEdges_ = ia->getLocalNumOf(adjacencyEType);
471 ia->getIDsViewOf(adjacencyEType, edgeIds);
472 size_t maxId = *(std::max_element(edgeIds,edgeIds+numLocalEdges_));
473 reduceAll(*comm_,Teuchos::REDUCE_MAX,1,&maxId,&numGlobalEdges_);
477 edgeGids_ = arcp<const gno_t>(edgeIds, 0, numLocalEdges_,
false);
479 else if (model_type==
"ghosting") {
481 numLocalEdges_ = numLocalVertices_;
482 edgeGids_ = arcp<const gno_t>(vtxIds, 0, numLocalVertices_,
false);
483 numGlobalEdges_ = numGlobalVertices_;
489 size_t numPrimaryPins = numLocalVertices_;
491 primaryPinType = adjacencyEType;
492 adjacencyPinType = primaryEType;
493 numPrimaryPins = numLocalEdges_;
495 if (model_type==
"traditional") {
497 gno_t const *nborIds=NULL;
498 offset_t
const *offsets=NULL;
501 ia->getAdjsView(primaryPinType,adjacencyPinType,offsets,nborIds);
505 numLocalPins_ = offsets[numPrimaryPins];
507 pinGids_ = arcp<const gno_t>(nborIds, 0, numLocalPins_,
false);
508 offsets_ = arcp<const offset_t>(offsets, 0, numPrimaryPins + 1,
false);
510 else if (model_type==
"ghosting") {
515 typedef std::set<gno_t> ghost_t;
518 typedef std::unordered_map<gno_t,ghost_t> ghost_map_t;
520 primaryPinType=primaryEType;
521 adjacencyPinType =ia->getSecondAdjacencyEntityType();
524 unsigned int layers=2;
525 const Teuchos::ParameterEntry *pe3 = pl.getEntryPtr(
"ghost_layers");
528 l = pe3->getValue<
int>(&l);
529 layers =
static_cast<unsigned int>(l);
532 typedef int nonzero_t;
533 typedef Tpetra::CrsMatrix<nonzero_t,lno_t,gno_t,node_t> sparse_matrix_type;
538 RCP<sparse_matrix_type> secondAdj;
539 if (!ia->avail2ndAdjs(primaryPinType,adjacencyPinType)) {
540 secondAdj=Zoltan2::get2ndAdjsMatFromAdjs<user_t>(ia,comm_,primaryPinType, adjacencyPinType);
543 const offset_t* offsets;
544 const gno_t* adjacencyIds;
545 ia->get2ndAdjsView(primaryPinType,adjacencyPinType,offsets,adjacencyIds);
547 Tpetra::global_size_t numGlobalCoords =
548 Teuchos::OrdinalTraits<Tpetra::global_size_t>::invalid();
549 oneToOneMap = rcp(
new map_t(numGlobalCoords, gids_(), 0, comm));
553 Teuchos::Array<size_t> nPerRow(numLocalVertices_);
555 for (
size_t i=0; i<numLocalVertices_;i++) {
558 nPerRow[rowcnt++] = offsets[i+1]-offsets[i];
560 secondAdj = rcp(
new sparse_matrix_type(oneToOneMap,nPerRow(0,rowcnt)));
561 for (
size_t i=0; i<numLocalVertices_;i++) {
564 gno_t row = gids_[i];
565 offset_t num_adjs = offsets[i+1]-offsets[i];
566 ArrayRCP<nonzero_t> ones(num_adjs,1);
567 ArrayRCP<const gno_t> cols(adjacencyIds,offsets[i],num_adjs,
false);
568 secondAdj->insertGlobalValues(row,cols(),ones());
570 secondAdj->fillComplete();
577 for (
unsigned int i=0;i<numLocalEdges_;i++) {
580 gno_t gid = edgeGids_[i];
581 size_t NumEntries = secondAdj->getNumEntriesInGlobalRow (gid);
582 typename sparse_matrix_type::nonconst_global_inds_host_view_type Indices(
"Indices", NumEntries);
583 typename sparse_matrix_type::nonconst_values_host_view_type Values(
"Values", NumEntries);
584 secondAdj->getGlobalRowCopy(gid,Indices,Values,NumEntries);
585 for (
size_t j = 0; j < NumEntries; ++j) {
586 if(gid != Indices[j]) {
587 ghosts[gid].insert(Indices[j]);
595 RCP<sparse_matrix_type> mat_old = secondAdj;
596 for (
unsigned int i=1;i<layers;i++) {
597 RCP<sparse_matrix_type> mat_new =
598 rcp (
new sparse_matrix_type(secondAdj->getRowMap(),0));
599 Tpetra::MatrixMatrix::Multiply(*mat_old,
false,*secondAdj,
false,*mat_new);
600 for (
unsigned int j=0;j<numLocalEdges_;j++) {
603 gno_t gid = edgeGids_[j];
604 size_t NumEntries = mat_new->getNumEntriesInGlobalRow (gid);
605 typename sparse_matrix_type::nonconst_global_inds_host_view_type Indices(
"Indices", NumEntries);
606 typename sparse_matrix_type::nonconst_values_host_view_type Values(
"Values", NumEntries);
607 mat_new->getGlobalRowCopy(gid,Indices,Values,NumEntries);
608 for (
size_t k = 0; k < NumEntries; ++k)
609 if(gid != Indices[k])
610 ghosts[gid].insert(Indices[k]);
617 for (
size_t i=0;i<numLocalVertices_;i++) {
618 numLocalPins_+=ghosts[gids_[i]].size();
621 offset_t* temp_offsets =
new offset_t[numLocalVertices_+1];
623 for (
size_t i=0;i<numLocalVertices_;i++) {
627 typename ghost_t::iterator itr;
628 for (itr=ghosts[gids_[i]].begin();itr!=ghosts[gids_[i]].end();itr++) {
634 temp_offsets[numLocalVertices_]=numLocalPins_;
635 pinGids_ = arcp<const gno_t>(temp_pins,0,numLocalPins_,
true);
636 offsets_ = arcp<const offset_t>(temp_offsets,0,numLocalVertices_+1,
true);
643 numWeightsPerVertex_ = ia->getNumWeightsPerID();
645 if (numWeightsPerVertex_ > 0){
646 input_t *weightInfo =
new input_t [numWeightsPerVertex_];
647 env_->localMemoryAssertion(__FILE__, __LINE__, numWeightsPerVertex_,
650 for (
int idx=0; idx < numWeightsPerVertex_; idx++){
651 bool useNumNZ = ia->useDegreeAsWeight(idx);
653 scalar_t *wgts =
new scalar_t [numLocalVertices_];
654 env_->localMemoryAssertion(__FILE__, __LINE__, numLocalVertices_, wgts);
655 ArrayRCP<const scalar_t> wgtArray =
656 arcp(wgts, 0, numLocalVertices_,
true);
657 for (
size_t i=0; i < numLocalVertices_; i++){
658 wgts[i] = offsets_[i+1] - offsets_[i];
660 weightInfo[idx] = input_t(wgtArray, 1);
665 ia->getWeightsView(
weights, stride, idx);
666 ArrayRCP<const scalar_t> wgtArray = arcp(
weights, 0,
667 stride*numLocalVertices_,
669 weightInfo[idx] = input_t(wgtArray, stride);
673 vWeights_ = arcp<input_t>(weightInfo, 0, numWeightsPerVertex_,
true);
679 typedef MeshAdapter<user_t> adapterWithCoords_t;
680 shared_GetVertexCoords<adapterWithCoords_t>(&(*ia));
682 env_->timerStop(MACRO_TIMERS,
"HyperGraphModel constructed from MeshAdapter");