337 const RCP<const Environment> &env,
338 const RCP<
const Comm<int> > &comm,
346 numWeightsPerVertex_(0),
357 numLocalVertices_(0),
358 numGlobalVertices_(0),
363 env_->timerStart(
MACRO_TIMERS,
"HyperGraphModel constructed from MeshAdapter");
373 std::string model_type(
"traditional");
374 const Teuchos::ParameterList &pl = env->getParameters();
375 const Teuchos::ParameterEntry *pe2 = pl.getEntryPtr(
"hypergraph_model_type");
377 model_type = pe2->getValue<std::string>(&model_type);
385 gno_t const *vtxIds=NULL;
387 numLocalVertices_ = ia->getLocalNumOf(primaryEType);
388 ia->getIDsViewOf(primaryEType, vtxIds);
389 size_t maxId = *(std::max_element(vtxIds,vtxIds+numLocalVertices_));
390 reduceAll(*comm_,Teuchos::REDUCE_MAX,1,&maxId,&numGlobalVertices_);
397 gids_ = arcp<const gno_t>(vtxIds, 0, numLocalVertices_,
false);
400 std::unordered_map<gno_t,lno_t> lid_mapping;
401 for (
size_t i=0;i<numLocalVertices_;i++)
402 lid_mapping[gids_[i]]=i;
409 unique = ia->areEntityIDsUnique(ia->getPrimaryEntityType());
410 numOwnedVertices_=numLocalVertices_;
411 isOwner_ = ArrayRCP<bool>(numLocalVertices_,
true);
414 Tpetra::global_size_t numGlobalCoords =
415 Teuchos::OrdinalTraits<Tpetra::global_size_t>::invalid();
416 mapWithCopies = rcp(
new map_t(numGlobalCoords, gids_(), 0, comm));
419 oneToOneMap = Tpetra::createOneToOne<lno_t, gno_t>(mapWithCopies);
421 numOwnedVertices_=oneToOneMap->getLocalNumElements();
422 for (
size_t i=0;i<numLocalVertices_;i++) {
423 isOwner_[i] = oneToOneMap->isNodeGlobalElement(gids_[i]);
428 if (model_type==
"traditional") {
432 gno_t const *edgeIds=NULL;
434 numLocalEdges_ = ia->getLocalNumOf(adjacencyEType);
435 ia->getIDsViewOf(adjacencyEType, edgeIds);
436 size_t maxId = *(std::max_element(edgeIds,edgeIds+numLocalEdges_));
437 reduceAll(*comm_,Teuchos::REDUCE_MAX,1,&maxId,&numGlobalEdges_);
441 edgeGids_ = arcp<const gno_t>(edgeIds, 0, numLocalEdges_,
false);
443 else if (model_type==
"ghosting") {
445 numLocalEdges_ = numLocalVertices_;
446 edgeGids_ = arcp<const gno_t>(vtxIds, 0, numLocalVertices_,
false);
447 numGlobalEdges_ = numGlobalVertices_;
453 size_t numPrimaryPins = numLocalVertices_;
455 primaryPinType = adjacencyEType;
456 adjacencyPinType = primaryEType;
457 numPrimaryPins = numLocalEdges_;
459 if (model_type==
"traditional") {
461 gno_t const *nborIds=NULL;
462 offset_t
const *offsets=NULL;
465 ia->getAdjsView(primaryPinType,adjacencyPinType,offsets,nborIds);
469 numLocalPins_ = offsets[numPrimaryPins];
471 pinGids_ = arcp<const gno_t>(nborIds, 0, numLocalPins_,
false);
472 offsets_ = arcp<const offset_t>(offsets, 0, numPrimaryPins + 1,
false);
474 else if (model_type==
"ghosting") {
479 typedef std::set<gno_t> ghost_t;
482 typedef std::unordered_map<gno_t,ghost_t> ghost_map_t;
484 primaryPinType=primaryEType;
485 adjacencyPinType =ia->getSecondAdjacencyEntityType();
488 unsigned int layers=2;
489 const Teuchos::ParameterEntry *pe3 = pl.getEntryPtr(
"ghost_layers");
492 l = pe3->getValue<
int>(&l);
493 layers =
static_cast<unsigned int>(l);
496 typedef int nonzero_t;
497 typedef Tpetra::CrsMatrix<nonzero_t,lno_t,gno_t,node_t> sparse_matrix_type;
502 RCP<sparse_matrix_type> secondAdj;
503 if (!ia->avail2ndAdjs(primaryPinType,adjacencyPinType)) {
504 secondAdj=Zoltan2::get2ndAdjsMatFromAdjs<user_t>(ia,comm_,primaryPinType, adjacencyPinType);
507 const offset_t* offsets;
508 const gno_t* adjacencyIds;
509 ia->get2ndAdjsView(primaryPinType,adjacencyPinType,offsets,adjacencyIds);
511 Tpetra::global_size_t numGlobalCoords =
512 Teuchos::OrdinalTraits<Tpetra::global_size_t>::invalid();
513 oneToOneMap = rcp(
new map_t(numGlobalCoords, gids_(), 0, comm));
517 Teuchos::Array<size_t> nPerRow(numLocalVertices_);
519 for (
size_t i=0; i<numLocalVertices_;i++) {
522 nPerRow[rowcnt++] = offsets[i+1]-offsets[i];
524 secondAdj = rcp(
new sparse_matrix_type(oneToOneMap,nPerRow(0,rowcnt)));
525 for (
size_t i=0; i<numLocalVertices_;i++) {
528 gno_t row = gids_[i];
529 offset_t num_adjs = offsets[i+1]-offsets[i];
530 ArrayRCP<nonzero_t> ones(num_adjs,1);
531 ArrayRCP<const gno_t> cols(adjacencyIds,offsets[i],num_adjs,
false);
532 secondAdj->insertGlobalValues(row,cols(),ones());
534 secondAdj->fillComplete();
541 for (
unsigned int i=0;i<numLocalEdges_;i++) {
544 gno_t gid = edgeGids_[i];
545 size_t NumEntries = secondAdj->getNumEntriesInGlobalRow (gid);
546 typename sparse_matrix_type::nonconst_global_inds_host_view_type Indices(
"Indices", NumEntries);
547 typename sparse_matrix_type::nonconst_values_host_view_type Values(
"Values", NumEntries);
548 secondAdj->getGlobalRowCopy(gid,Indices,Values,NumEntries);
549 for (
size_t j = 0; j < NumEntries; ++j) {
550 if(gid != Indices[j]) {
551 ghosts[gid].insert(Indices[j]);
559 RCP<sparse_matrix_type> mat_old = secondAdj;
560 for (
unsigned int i=1;i<layers;i++) {
561 RCP<sparse_matrix_type> mat_new =
562 rcp (
new sparse_matrix_type(secondAdj->getRowMap(),0));
563 Tpetra::MatrixMatrix::Multiply(*mat_old,
false,*secondAdj,
false,*mat_new);
564 for (
unsigned int j=0;j<numLocalEdges_;j++) {
567 gno_t gid = edgeGids_[j];
568 size_t NumEntries = mat_new->getNumEntriesInGlobalRow (gid);
569 typename sparse_matrix_type::nonconst_global_inds_host_view_type Indices(
"Indices", NumEntries);
570 typename sparse_matrix_type::nonconst_values_host_view_type Values(
"Values", NumEntries);
571 mat_new->getGlobalRowCopy(gid,Indices,Values,NumEntries);
572 for (
size_t k = 0; k < NumEntries; ++k)
573 if(gid != Indices[k])
574 ghosts[gid].insert(Indices[k]);
581 for (
size_t i=0;i<numLocalVertices_;i++) {
582 numLocalPins_+=ghosts[gids_[i]].size();
585 offset_t* temp_offsets =
new offset_t[numLocalVertices_+1];
587 for (
size_t i=0;i<numLocalVertices_;i++) {
591 typename ghost_t::iterator itr;
592 for (itr=ghosts[gids_[i]].begin();itr!=ghosts[gids_[i]].end();itr++) {
598 temp_offsets[numLocalVertices_]=numLocalPins_;
599 pinGids_ = arcp<const gno_t>(temp_pins,0,numLocalPins_,
true);
600 offsets_ = arcp<const offset_t>(temp_offsets,0,numLocalVertices_+1,
true);
607 numWeightsPerVertex_ = ia->getNumWeightsPerID();
609 if (numWeightsPerVertex_ > 0){
610 input_t *weightInfo =
new input_t [numWeightsPerVertex_];
611 env_->localMemoryAssertion(__FILE__, __LINE__, numWeightsPerVertex_,
614 for (
int idx=0; idx < numWeightsPerVertex_; idx++){
615 bool useNumNZ = ia->useDegreeAsWeight(idx);
617 scalar_t *wgts =
new scalar_t [numLocalVertices_];
618 env_->localMemoryAssertion(__FILE__, __LINE__, numLocalVertices_, wgts);
619 ArrayRCP<const scalar_t> wgtArray =
620 arcp(wgts, 0, numLocalVertices_,
true);
621 for (
size_t i=0; i < numLocalVertices_; i++){
622 wgts[i] = offsets_[i+1] - offsets_[i];
624 weightInfo[idx] = input_t(wgtArray, 1);
629 ia->getWeightsView(
weights, stride, idx);
630 ArrayRCP<const scalar_t> wgtArray = arcp(
weights, 0,
631 stride*numLocalVertices_,
633 weightInfo[idx] = input_t(wgtArray, stride);
637 vWeights_ = arcp<input_t>(weightInfo, 0, numWeightsPerVertex_,
true);
644 shared_GetVertexCoords<adapterWithCoords_t>(&(*ia));
646 env_->timerStop(
MACRO_TIMERS,
"HyperGraphModel constructed from MeshAdapter");