14 #ifndef _ZOLTAN2_HYPERGRAPHMODEL_HPP_
15 #define _ZOLTAN2_HYPERGRAPHMODEL_HPP_
28 #include <unordered_map>
30 #include <Teuchos_Hashtable.hpp>
53 template <
typename Adapter>
58 #ifndef DOXYGEN_SHOULD_SKIP_THIS
59 typedef typename Adapter::scalar_t scalar_t;
60 typedef typename Adapter::offset_t offset_t;
65 typedef typename Adapter::userCoord_t userCoord_t;
66 typedef Tpetra::Map<lno_t, gno_t>
map_t;
85 const RCP<const Environment> &env,
const RCP<
const Comm<int> > &comm,
88 throw std::runtime_error(
"Building HyperGraphModel from MatrixAdapter not implemented yet");
92 const RCP<const Environment> &env,
const RCP<
const Comm<int> > &comm,
95 throw std::runtime_error(
"Building HyperGraphModel from GraphAdapter not implemented yet");
99 const RCP<const Environment> &env,
const RCP<
const Comm<int> > &comm,
103 const RCP<const Environment> &env,
const RCP<
const Comm<int> > &comm,
106 throw std::runtime_error(
"cannot build HyperGraphModel from VectorAdapter");
110 const RCP<const Environment> &env,
const RCP<
const Comm<int> > &comm,
113 throw std::runtime_error(
"cannot build HyperGraphModel from IdentifierAdapter");
175 ArrayView<const gno_t> &Ids,
176 ArrayView<input_t> &wgts)
const
178 size_t nv = gids_.size();
180 wgts = vWeights_.view(0, numWeightsPerVertex_);
191 size_t nv = gids_.size();
192 xyz = vCoords_.view(0, vCoordDim_);
204 size_t nv = isOwner_.size();
205 isOwner = isOwner_(0, nv);
217 Teuchos::RCP<const map_t>& onetooneMap)
const
219 copiesMap = mapWithCopies;
220 onetooneMap = oneToOneMap;
231 ArrayView<const gno_t> &Ids,
232 ArrayView<input_t> &wgts)
const
234 size_t nv = edgeGids_.size();
235 Ids = edgeGids_(0, nv);
236 wgts = eWeights_.view(0, nWeightsPerEdge_);
253 ArrayView<const offset_t> &offsets,
254 ArrayView<input_t> &wgts)
const
256 pinIds = pinGids_(0, numLocalPins_);
257 offsets = offsets_.view(0, offsets_.size());
258 wgts = pWeights_.view(0, nWeightsPerPin_);
259 return pinGids_.size();
277 GhostCell(
lno_t l,
gno_t g,
unsigned int d) {lid=l;gid=g;dist=d;}
278 bool operator<(
const struct GhostCell& other)
const {
return dist>other.dist;}
280 template <
typename AdapterWithCoords>
281 void shared_GetVertexCoords(
const AdapterWithCoords *ia);
284 const RCP<const Environment > env_;
285 const RCP<const Comm<int> > comm_;
289 ArrayRCP<const gno_t> gids_;
291 ArrayRCP<bool> isOwner_;
293 int numWeightsPerVertex_;
294 ArrayRCP<input_t> vWeights_;
297 ArrayRCP<input_t> vCoords_;
299 ArrayRCP<const gno_t> edgeGids_;
301 int nWeightsPerEdge_;
302 ArrayRCP<input_t> eWeights_;
304 ArrayRCP<const gno_t> pinGids_;
305 ArrayRCP<const offset_t> offsets_;
308 ArrayRCP<input_t> pWeights_;
312 size_t numLocalVertices_;
313 size_t numOwnedVertices_;
314 size_t numGlobalVertices_;
315 size_t numLocalEdges_;
316 size_t numGlobalEdges_;
317 size_t numLocalPins_;
320 Teuchos::RCP<const map_t> mapWithCopies;
321 Teuchos::RCP<const map_t> oneToOneMap;
334 template <
typename Adapter>
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);
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);
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");
652 template <
typename Adapter>
653 template <
typename AdapterWithCoords>
658 vCoordDim_ = ia->getDimension();
661 input_t *coordInfo =
new input_t [vCoordDim_];
662 env_->localMemoryAssertion(__FILE__, __LINE__, vCoordDim_, coordInfo);
664 for (
int dim=0; dim < vCoordDim_; dim++){
665 const scalar_t *coords=NULL;
668 ArrayRCP<const scalar_t> coordArray = arcp(coords, 0,
669 stride*numLocalVertices_,
671 coordInfo[dim] = input_t(coordArray, stride);
674 vCoords_ = arcp<input_t>(coordInfo, 0, vCoordDim_,
true);
679 template <
typename Adapter>
680 void HyperGraphModel<Adapter>::print()
686 std::ostream *os = env_->getDebugOStream();
688 int me = comm_->getRank();
692 <<
" Nvtx " << gids_.size()
693 <<
" Nedge " << edgeGids_.size()
694 <<
" NPins " << numLocalPins_
695 <<
" NVWgt " << numWeightsPerVertex_
696 <<
" NEWgt " << nWeightsPerEdge_
697 <<
" NPWgt " << nWeightsPerPin_
698 <<
" CDim " << vCoordDim_
701 for (
lno_t i = 0; i < gids_.size(); i++) {
702 *os << me << fn << i <<
" VTXGID " << gids_[i]<<
" isOwner: "<<isOwner_[i];
703 if (numWeightsPerVertex_==1)
704 *os <<
" weight: " << vWeights_[0][i];
707 for (offset_t j = offsets_[i]; j< offsets_[i+1];j++)
708 *os <<
" "<<pinGids_[j];
712 for (
lno_t i = 0; i<edgeGids_.size();i++) {
713 *os << me << fn << i <<
" EDGEGID " << edgeGids_[i];
716 for (offset_t j = offsets_[i]; j< offsets_[i+1];j++)
717 *os <<
" "<<pinGids_[j];
722 for (
lno_t i = 0; i < gids_.size(); i++) {
723 *os << me << fn << i <<
" COORDS " << gids_[i] <<
": ";
724 for (
int j = 0; j < vCoordDim_; j++)
725 *os << vCoords_[j][i] <<
" ";
730 *os << me << fn <<
"NO COORDINATES AVAIL " << std::endl;
Time an algorithm (or other entity) as a whole.
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.
size_t getVertexCoords(ArrayView< input_t > &xyz) const
Sets pointers to this process' vertex coordinates, if available.
GraphAdapter defines the interface for graph-based user data.
int getNumWeightsPerHyperEdge() const
Returns the number (0 or greater) of weights per edge.
Defines the MeshAdapter interface.
CentricView getCentricView() const
Returns the centric view of the hypergraph.
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)
map_t::global_ordinal_type gno_t
size_t getLocalNumObjects() const
Return the local number of objects.
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 getOwnedList(ArrayView< bool > &isOwner) const
Sets pointer to the ownership of this processes vertices.
Defines helper functions for use in the models.
bool areVertexIDsUnique() const
Returns true if the vertices are unique false otherwise.
size_t getEdgeList(ArrayView< const gno_t > &Ids, ArrayView< input_t > &wgts) const
Sets pointers to this process' hyperedge Ids and their weights.
int getNumWeightesPerPin() const
Returns the number (0 or greater) of weights per pins.
size_t getLocalNumHyperEdges() const
Returns the number of hyper edges on this process. These are all hyper edges that have an adjacency t...
VectorAdapter defines the interface for vector input.
The StridedData class manages lists of weights or coordinates.
map_t::local_ordinal_type lno_t
size_t getGlobalNumObjects() const
Return the global number of objects.
size_t getLocalNumPins() const
Returns the local number of pins.
size_t getVertexList(ArrayView< const gno_t > &Ids, ArrayView< input_t > &wgts) const
Sets pointers to this process' vertex Ids and their weights.
int getCoordinateDim() const
Returns the dimension (0 to 3) of vertex coordinates.
CentricView
Enumerate the views for the pins: HYPEREDGE_CENTRIC: pins are the global ids of the vertices as seen ...
MeshEntityType
Enumerate entity types for meshes: Regions, Faces, Edges, or Vertices.
Defines the MatrixAdapter interface.
The base class for all model classes.
size_t getPinList(ArrayView< const gno_t > &pinIds, ArrayView< const offset_t > &offsets, ArrayView< input_t > &wgts) const
Sets pointers to this process' pins global Ids based on the centric view given by getCentricView() ...
Tpetra::global_size_t global_size_t
size_t getGlobalNumHyperEdges() const
Returns the global number hyper edges.
size_t getLocalNumVertices() const
Returns the number vertices on this process.
~HyperGraphModel()
Destructor.
Defines the GraphAdapter interface.
include more detail about sub-steps
HyperGraphModel defines the interface required for hyper graph models.
size_t getGlobalNumVertices() const
Returns the global number vertices.
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...
int getNumWeightsPerVertex() const
Returns the number (0 or greater) of weights per vertex.
size_t getLocalNumOwnedVertices() const
Returns the number vertices on this process that are owned.
virtual void getCoordinatesView(const scalar_t *&coords, int &stride, int coordDim) const =0
This file defines the StridedData class.
Zoltan2::BasicUserTypes< zscalar_t, zlno_t, zgno_t > user_t
HyperGraphModel(const RCP< const IdentifierAdapter< user_t > > &ia, const RCP< const Environment > &env, const RCP< const Comm< int > > &comm, modelFlag_t &flags, CentricView view)