50 #ifndef _ZOLTAN2_HYPERGRAPHMODEL_HPP_ 51 #define _ZOLTAN2_HYPERGRAPHMODEL_HPP_ 64 #include <unordered_map> 66 #include <Teuchos_Hashtable.hpp> 89 template <
typename Adapter>
94 #ifndef DOXYGEN_SHOULD_SKIP_THIS 95 typedef typename Adapter::scalar_t scalar_t;
96 typedef typename Adapter::gno_t gno_t;
97 typedef typename Adapter::lno_t lno_t;
98 typedef typename Adapter::node_t node_t;
99 typedef typename Adapter::user_t user_t;
100 typedef typename Adapter::userCoord_t userCoord_t;
101 typedef Tpetra::Map<lno_t, gno_t> map_t;
120 const RCP<const Environment> &env,
const RCP<
const Comm<int> > &comm,
123 throw std::runtime_error(
"Building HyperGraphModel from MatrixAdapter not implemented yet");
127 const RCP<const Environment> &env,
const RCP<
const Comm<int> > &comm,
130 throw std::runtime_error(
"Building HyperGraphModel from GraphAdapter not implemented yet");
134 const RCP<const Environment> &env,
const RCP<
const Comm<int> > &comm,
138 const RCP<const Environment> &env,
const RCP<
const Comm<int> > &comm,
141 throw std::runtime_error(
"cannot build HyperGraphModel from VectorAdapter");
145 const RCP<const Environment> &env,
const RCP<
const Comm<int> > &comm,
148 throw std::runtime_error(
"cannot build HyperGraphModel from IdentifierAdapter");
210 ArrayView<const gno_t> &Ids,
211 ArrayView<input_t> &wgts)
const 213 size_t nv = gids_.size();
215 wgts = vWeights_.view(0, numWeightsPerVertex_);
226 size_t nv = gids_.size();
227 xyz = vCoords_.view(0, vCoordDim_);
239 size_t nv = isOwner_.size();
240 isOwner = isOwner_(0, nv);
251 void getVertexMaps(Teuchos::RCP<const map_t>& copiesMap, Teuchos::RCP<const map_t>& onetooneMap)
const {
252 copiesMap = mapWithCopies;
253 onetooneMap = oneToOneMap;
264 ArrayView<const gno_t> &Ids,
265 ArrayView<input_t> &wgts)
const 267 size_t nv = edgeGids_.size();
268 Ids = edgeGids_(0, nv);
269 wgts = eWeights_.view(0, nWeightsPerEdge_);
286 ArrayView<const lno_t> &offsets,
287 ArrayView<input_t> &wgts)
const 289 pinIds = pinGids_(0, numLocalPins_);
290 offsets = offsets_.view(0, offsets_.size());
291 wgts = pWeights_.view(0, nWeightsPerPin_);
292 return pinGids_.size();
310 GhostCell(lno_t l,gno_t g,
unsigned int d) {lid=l;gid=g;dist=d;}
311 bool operator<(
const struct GhostCell& other)
const {
return dist>other.dist;}
313 template <
typename AdapterWithCoords>
314 void shared_GetVertexCoords(
const AdapterWithCoords *ia);
317 const RCP<const Environment > env_;
318 const RCP<const Comm<int> > comm_;
322 ArrayRCP<const gno_t> gids_;
324 ArrayRCP<bool> isOwner_;
326 int numWeightsPerVertex_;
327 ArrayRCP<input_t> vWeights_;
330 ArrayRCP<input_t> vCoords_;
332 ArrayRCP<const gno_t> edgeGids_;
334 int nWeightsPerEdge_;
335 ArrayRCP<input_t> eWeights_;
337 ArrayRCP<const gno_t> pinGids_;
338 ArrayRCP<const lno_t> offsets_;
341 ArrayRCP<input_t> pWeights_;
345 size_t numLocalVertices_;
346 size_t numOwnedVertices_;
347 size_t numGlobalVertices_;
348 size_t numLocalEdges_;
349 size_t numGlobalEdges_;
350 size_t numLocalPins_;
353 Teuchos::RCP<const map_t> mapWithCopies;
354 Teuchos::RCP<const map_t> oneToOneMap;
367 template <
typename Adapter>
370 const RCP<const Environment> &env,
371 const RCP<
const Comm<int> > &comm,
379 numWeightsPerVertex_(0),
390 numLocalVertices_(0),
391 numGlobalVertices_(0),
396 env_->timerStart(
MACRO_TIMERS,
"HyperGraphModel constructed from MeshAdapter");
406 std::string model_type(
"traditional");
407 const Teuchos::ParameterList &pl = env->getParameters();
408 const Teuchos::ParameterEntry *pe2 = pl.getEntryPtr(
"hypergraph_model_type");
410 model_type = pe2->getValue<std::string>(&model_type);
418 gno_t
const *vtxIds=NULL;
420 numLocalVertices_ = ia->getLocalNumOf(primaryEType);
421 ia->getIDsViewOf(primaryEType, vtxIds);
422 size_t maxId = *(std::max_element(vtxIds,vtxIds+numLocalVertices_));
423 reduceAll(*comm_,Teuchos::REDUCE_MAX,1,&maxId,&numGlobalVertices_);
427 gids_ = arcp<const gno_t>(vtxIds, 0, numLocalVertices_,
false);
430 std::unordered_map<gno_t,lno_t> lid_mapping;
431 for (
size_t i=0;i<numLocalVertices_;i++)
432 lid_mapping[gids_[i]]=i;
439 unique = ia->areEntityIDsUnique(ia->getPrimaryEntityType());
440 numOwnedVertices_=numLocalVertices_;
441 isOwner_ = ArrayRCP<bool>(numLocalVertices_,
true);
445 Teuchos::OrdinalTraits<Tpetra::global_size_t>::invalid();
446 mapWithCopies = rcp(
new map_t(numGlobalCoords, gids_(), 0, comm));
447 oneToOneMap = Tpetra::createOneToOne<lno_t, gno_t>(mapWithCopies);
449 numOwnedVertices_=oneToOneMap->getNodeNumElements();
450 for (
size_t i=0;i<numLocalVertices_;i++) {
451 isOwner_[i] = oneToOneMap->isNodeGlobalElement(gids_[i]);
456 if (model_type==
"traditional") {
460 gno_t
const *edgeIds=NULL;
462 numLocalEdges_ = ia->getLocalNumOf(adjacencyEType);
463 ia->getIDsViewOf(adjacencyEType, edgeIds);
464 size_t maxId = *(std::max_element(edgeIds,edgeIds+numLocalEdges_));
465 reduceAll(*comm_,Teuchos::REDUCE_MAX,1,&maxId,&numGlobalEdges_);
469 edgeGids_ = arcp<const gno_t>(edgeIds, 0, numLocalEdges_,
false);
471 else if (model_type==
"ghosting") {
473 numLocalEdges_ = numLocalVertices_;
474 edgeGids_ = arcp<const gno_t>(vtxIds, 0, numLocalVertices_,
false);
475 numGlobalEdges_ = numGlobalVertices_;
481 size_t numPrimaryPins = numLocalVertices_;
483 primaryPinType = adjacencyEType;
484 adjacencyPinType = primaryEType;
485 numPrimaryPins = numLocalEdges_;
487 if (model_type==
"traditional") {
489 gno_t
const *nborIds=NULL;
490 lno_t
const *offsets=NULL;
493 ia->getAdjsView(primaryPinType,adjacencyPinType,offsets,nborIds);
497 numLocalPins_ = offsets[numPrimaryPins];
499 pinGids_ = arcp<const gno_t>(nborIds, 0, numLocalPins_,
false);
500 offsets_ = arcp<const lno_t>(offsets, 0, numPrimaryPins + 1,
false);
502 else if (model_type==
"ghosting") {
507 typedef std::set<gno_t> ghost_t;
510 typedef std::unordered_map<gno_t,ghost_t> ghost_map_t;
512 primaryPinType=primaryEType;
513 adjacencyPinType =ia->getSecondAdjacencyEntityType();
516 unsigned int layers=2;
517 const Teuchos::ParameterEntry *pe3 = pl.getEntryPtr(
"ghost_layers");
520 l = pe3->getValue<
int>(&l);
521 layers =
static_cast<unsigned int>(l);
524 typedef int nonzero_t;
525 typedef Tpetra::CrsMatrix<nonzero_t,lno_t,gno_t,node_t> sparse_matrix_type;
530 RCP<sparse_matrix_type> secondAdj;
531 if (!ia->avail2ndAdjs(primaryPinType,adjacencyPinType)) {
532 secondAdj=Zoltan2::get2ndAdjsMatFromAdjs<user_t>(ia,comm_,primaryPinType, adjacencyPinType);
535 const lno_t* offsets;
536 const gno_t* adjacencyIds;
537 ia->get2ndAdjsView(primaryPinType,adjacencyPinType,offsets,adjacencyIds);
540 Teuchos::OrdinalTraits<Tpetra::global_size_t>::invalid();
541 oneToOneMap = rcp(
new map_t(numGlobalCoords, gids_(), 0, comm));
543 secondAdj = rcp(
new sparse_matrix_type(oneToOneMap,0));
544 for (
size_t i=0; i<numLocalVertices_;i++) {
547 gno_t row = gids_[i];
548 lno_t num_adjs = offsets[i+1]-offsets[i];
549 ArrayRCP<nonzero_t> ones(num_adjs,1);
550 ArrayRCP<const gno_t> cols(adjacencyIds,offsets[i],num_adjs,
false);
551 secondAdj->insertGlobalValues(row,cols(),ones());
553 secondAdj->fillComplete();
560 Array<gno_t> Indices;
561 Array<nonzero_t> Values;
562 for (
unsigned int i=0;i<numLocalEdges_;i++) {
565 gno_t gid = edgeGids_[i];
566 size_t NumEntries = secondAdj->getNumEntriesInGlobalRow (gid);
567 Indices.resize (NumEntries);
568 Values.resize (NumEntries);
569 secondAdj->getGlobalRowCopy(gid,Indices(),Values(),NumEntries);
570 for (
size_t j = 0; j < NumEntries; ++j) {
571 if(gid != Indices[j]) {
572 ghosts[gid].insert(Indices[j]);
580 RCP<sparse_matrix_type> mat_old = secondAdj;
581 for (
unsigned int i=1;i<layers;i++) {
582 RCP<sparse_matrix_type> mat_new =
583 rcp (
new sparse_matrix_type(secondAdj->getRowMap(),0));
584 Tpetra::MatrixMatrix::Multiply(*mat_old,
false,*secondAdj,
false,*mat_new);
585 for (
unsigned int j=0;j<numLocalEdges_;j++) {
588 gno_t gid = edgeGids_[j];
589 size_t NumEntries = mat_new->getNumEntriesInGlobalRow (gid);
590 Indices.resize(NumEntries);
591 Values.resize(NumEntries);
592 mat_new->getGlobalRowCopy(gid,Indices(),Values(),NumEntries);
593 for (
size_t k = 0; k < NumEntries; ++k)
594 if(gid != Indices[k])
595 ghosts[gid].insert(Indices[k]);
602 for (
size_t i=0;i<numLocalVertices_;i++) {
603 numLocalPins_+=ghosts[gids_[i]].size();
605 gno_t* temp_pins =
new gno_t[numLocalPins_];
606 lno_t* temp_offsets =
new lno_t[numLocalVertices_+1];
608 for (
size_t i=0;i<numLocalVertices_;i++) {
612 typename ghost_t::iterator itr;
613 for (itr=ghosts[gids_[i]].begin();itr!=ghosts[gids_[i]].end();itr++) {
619 temp_offsets[numLocalVertices_]=numLocalPins_;
620 pinGids_ = arcp<const gno_t>(temp_pins,0,numLocalPins_,
true);
621 offsets_ = arcp<const lno_t>(temp_offsets,0,numLocalVertices_+1,
true);
628 numWeightsPerVertex_ = ia->getNumWeightsPerID();
630 if (numWeightsPerVertex_ > 0){
631 input_t *weightInfo =
new input_t [numWeightsPerVertex_];
632 env_->localMemoryAssertion(__FILE__, __LINE__, numWeightsPerVertex_,
635 for (
int idx=0; idx < numWeightsPerVertex_; idx++){
636 bool useNumNZ = ia->useDegreeAsWeight(idx);
638 scalar_t *wgts =
new scalar_t [numLocalVertices_];
639 env_->localMemoryAssertion(__FILE__, __LINE__, numLocalVertices_, wgts);
640 ArrayRCP<const scalar_t> wgtArray =
641 arcp(wgts, 0, numLocalVertices_,
true);
642 for (
size_t i=0; i < numLocalVertices_; i++){
643 wgts[i] = offsets_[i+1] - offsets_[i];
645 weightInfo[idx] = input_t(wgtArray, 1);
650 ia->getWeightsView(
weights, stride, idx);
651 ArrayRCP<const scalar_t> wgtArray = arcp(
weights, 0,
652 stride*numLocalVertices_,
654 weightInfo[idx] = input_t(wgtArray, stride);
658 vWeights_ = arcp<input_t>(weightInfo, 0, numWeightsPerVertex_,
true);
665 shared_GetVertexCoords<adapterWithCoords_t>(&(*ia));
667 env_->timerStop(
MACRO_TIMERS,
"HyperGraphModel constructed from MeshAdapter");
673 template <
typename Adapter>
674 template <
typename AdapterWithCoords>
679 vCoordDim_ = ia->getDimension();
682 input_t *coordInfo =
new input_t [vCoordDim_];
683 env_->localMemoryAssertion(__FILE__, __LINE__, vCoordDim_, coordInfo);
685 for (
int dim=0; dim < vCoordDim_; dim++){
686 const scalar_t *coords=NULL;
688 ia->getCoordinatesView(coords, stride, dim);
689 ArrayRCP<const scalar_t> coordArray = arcp(coords, 0,
690 stride*numLocalVertices_,
692 coordInfo[dim] = input_t(coordArray, stride);
695 vCoords_ = arcp<input_t>(coordInfo, 0, vCoordDim_,
true);
700 template <
typename Adapter>
701 void HyperGraphModel<Adapter>::print()
707 std::ostream *os = env_->getDebugOStream();
709 int me = comm_->getRank();
713 <<
" Nvtx " << gids_.size()
714 <<
" Nedge " << edgeGids_.size()
715 <<
" NPins " << numLocalPins_
716 <<
" NVWgt " << numWeightsPerVertex_
717 <<
" NEWgt " << nWeightsPerEdge_
718 <<
" NPWgt " << nWeightsPerPin_
719 <<
" CDim " << vCoordDim_
722 for (lno_t i = 0; i < gids_.size(); i++) {
723 *os << me << fn << i <<
" VTXGID " << gids_[i]<<
" isOwner: "<<isOwner_[i];
724 if (numWeightsPerVertex_==1)
725 *os <<
" weight: " << vWeights_[0][i];
728 for (lno_t j = offsets_[i]; j< offsets_[i+1];j++)
729 *os <<
" "<<pinGids_[j];
733 for (lno_t i = 0; i<edgeGids_.size();i++) {
734 *os << me << fn << i <<
" EDGEGID " << edgeGids_[i];
737 for (lno_t j = offsets_[i]; j< offsets_[i+1];j++)
738 *os <<
" "<<pinGids_[j];
743 for (lno_t i = 0; i < gids_.size(); i++) {
744 *os << me << fn << i <<
" COORDS " << gids_[i] <<
": ";
745 for (
int j = 0; j < vCoordDim_; j++)
746 *os << vCoords_[j][i] <<
" ";
751 *os << me << fn <<
"NO COORDINATES AVAIL " << std::endl;
Time an algorithm (or other entity) as a whole.
size_t getEdgeList(ArrayView< const gno_t > &Ids, ArrayView< input_t > &wgts) const
Sets pointers to this process' hyperedge Ids and their weights.
size_t getLocalNumVertices() const
Returns the number vertices on this process.
IdentifierAdapter defines the interface for identifiers.
#define Z2_FORWARD_EXCEPTIONS
Forward an exception back through call stack.
MatrixAdapter defines the adapter interface for matrices.
Defines the Model interface.
int getNumWeightesPerPin() const
Returns the number (0 or greater) of weights per pins.
GraphAdapter defines the interface for graph-based user data.
Defines the MeshAdapter interface.
size_t getGlobalNumObjects() const
Return the global number of objects.
MeshAdapter defines the interface for mesh input.
std::bitset< NUM_MODEL_FLAGS > modelFlag_t
HyperGraphModel(const RCP< const VectorAdapter< userCoord_t > > &ia, const RCP< const Environment > &env, const RCP< const Comm< int > > &comm, modelFlag_t &flags, CentricView view)
size_t getLocalNumOwnedVertices() const
Returns the number vertices on this process that are owned.
Defines the IdentifierAdapter interface.
Defines the VectorAdapter interface.
HyperGraphModel(const RCP< const MatrixAdapter< user_t, userCoord_t > > &ia, const RCP< const Environment > &env, const RCP< const Comm< int > > &comm, modelFlag_t &modelFlags, CentricView view)
Constructor.
HyperGraphModel(const RCP< const GraphAdapter< user_t, userCoord_t > > &ia, const RCP< const Environment > &env, const RCP< const Comm< int > > &comm, modelFlag_t &modelFlags, CentricView view)
size_t getVertexList(ArrayView< const gno_t > &Ids, ArrayView< input_t > &wgts) const
Sets pointers to this process' vertex Ids and their weights.
Defines helper functions for use in the models.
size_t getGlobalNumHyperEdges() const
Returns the global number hyper edges.
size_t getLocalNumPins() const
Returns the local number of pins.
size_t getOwnedList(ArrayView< bool > &isOwner) const
Sets pointer to the ownership of this processes vertices.
VectorAdapter defines the interface for vector input.
The StridedData class manages lists of weights or coordinates.
size_t getLocalNumObjects() const
Return the local number of objects.
int getNumWeightsPerVertex() const
Returns the number (0 or greater) of weights per vertex.
int getNumWeightsPerHyperEdge() const
Returns the number (0 or greater) of weights per edge.
int getCoordinateDim() const
Returns the dimension (0 to 3) of vertex coordinates.
size_t getGlobalNumVertices() const
Returns the global number vertices.
CentricView
Enumerate the views for the pins: HYPEREDGE_CENTRIC: pins are the global ids of the vertices as seen ...
size_t getPinList(ArrayView< const gno_t > &pinIds, ArrayView< const lno_t > &offsets, ArrayView< input_t > &wgts) const
Sets pointers to this process' pins global Ids based on the centric view given by getCentricView() ...
MeshEntityType
Enumerate entity types for meshes: Regions, Faces, Edges, or Vertices.
Defines the MatrixAdapter interface.
void getVertexMaps(Teuchos::RCP< const map_t > &copiesMap, Teuchos::RCP< const map_t > &onetooneMap) const
Sets pointers to the vertex map with copies and the vertex map without copies Note: the pointers will...
The base class for all model classes.
size_t getLocalNumHyperEdges() const
Returns the number of hyper edges on this process. These are all hyper edges that have an adjacency t...
~HyperGraphModel()
Destructor.
Defines the GraphAdapter interface.
include more detail about sub-steps
bool areVertexIDsUnique() const
Returns true if the vertices are unique false otherwise.
HyperGraphModel defines the interface required for hyper graph models.
CentricView getCentricView() const
Returns the centric view of the hypergraph.
This file defines the StridedData class.
HyperGraphModel(const RCP< const IdentifierAdapter< user_t > > &ia, const RCP< const Environment > &env, const RCP< const Comm< int > > &comm, modelFlag_t &flags, CentricView view)
size_t getVertexCoords(ArrayView< input_t > &xyz) const
Sets pointers to this process' vertex coordinates, if available.