60 #ifndef _ZOLTAN2_COMMGRAPHMODEL_HPP_
61 #define _ZOLTAN2_COMMGRAPHMODEL_HPP_
73 #include <unordered_map>
90 template <
typename Adapter>
95 #ifndef DOXYGEN_SHOULD_SKIP_THIS
96 typedef typename Adapter::scalar_t scalar_t;
99 typedef typename Adapter::node_t node_t;
101 typedef typename Adapter::userCoord_t userCoord_t;
103 typedef typename Adapter::offset_t offset_t;
119 const RCP<const Environment> &env,
const RCP<
const Comm<int> > &comm)
121 throw std::runtime_error(
"CommGraphModel is not implemented for MatrixAdapter yet.");
125 const RCP<const Environment> &env,
const RCP<
const Comm<int> > &comm);
128 const RCP<const Environment> &env,
const RCP<
const Comm<int> > &comm)
130 throw std::runtime_error(
"CommGraphModel is not implemented for MeshAdapter yet.");
134 const RCP<const Environment> &,
const RCP<
const Comm<int> > &)
136 throw std::runtime_error(
"cannot build CommGraphModel from VectorAdapter");
140 const RCP<const Environment> &env,
const RCP<
const Comm<int> > &comm)
142 throw std::runtime_error(
"cannot build GraphModel from IdentifierAdapter");
147 const RCP<const Comm<int> >
getComm() {
return comm_; }
184 ArrayView<const gno_t> &Ids,
185 ArrayView<input_t> &wgts)
const
187 Ids = vGids_.view(0, nLocalVertices_);
188 wgts = vWeights_.view(0, nWeightsPerVertex_);
189 return nLocalVertices_;
197 ArrayView<const offset_t> &offsets,
198 ArrayView<input_t> &wgts)
const
200 edgeIds = eGids_.view(0, nLocalEdges_);
201 offsets = eOffsets_.view(0, nLocalVertices_+1);
202 wgts = eWeights_.view(0, nWeightsPerEdge_);
212 vtxdist = vtxDist_();
213 if (vtxDist_.size() == 0) {
214 throw std::runtime_error(
"getVertexDist is available only "
215 "when consecutiveIdsRequired");
244 const RCP<const Environment > env_;
245 const RCP<const Comm<int> > comm_;
249 int destRank_, startRank_, endRank_;
252 size_t nLocalVertices_;
253 size_t nGlobalVertices_;
254 ArrayRCP<gno_t> vGids_;
258 int nWeightsPerVertex_;
259 ArrayRCP<input_t> vWeights_;
266 size_t nGlobalEdges_;
267 ArrayRCP<gno_t> eGids_;
268 ArrayRCP<offset_t> eOffsets_;
274 int nWeightsPerEdge_;
275 ArrayRCP<input_t> eWeights_;
280 ArrayRCP<size_t> vtxDist_;
289 template <
typename Adapter>
292 const RCP<const Environment> &env,
293 const RCP<
const Comm<int> > &comm):
299 nWeightsPerVertex_(0),
309 int commSize = comm_->getSize();
312 RCP<XpetraCrsGraphAdapter<user_t, userCoord_t>> ia;
314 RCP<GraphAdapter<user_t, userCoord_t>> tmp =
315 rcp_const_cast<GraphAdapter<user_t, userCoord_t>>(bia);
316 ia = rcp_dynamic_cast<XpetraCrsGraphAdapter<user_t, userCoord_t>>(tmp);
321 auto inGraph = ia->getXpetraGraph();
324 auto imp = inGraph->getImporter();
327 std::map<int,double> exportpidmap;
328 auto exportpids = imp->getExportPIDs();
329 size_t nexportpids = imp->getNumExportIDs();
330 for (
size_t i = 0; i < nexportpids; i++) {
331 int k = exportpids[i];
332 if (exportpidmap.find(k) != exportpidmap.end())
333 exportpidmap[k] = exportpidmap[k] + 1.;
335 exportpidmap[k] = 1.;
341 nLocalEdges_ = exportpidmap.size();
344 vGids_ = arcp(
new gno_t[nLocalVertices_],
345 0, nLocalVertices_,
true);
346 eGids_ = arcp(
new gno_t[nLocalEdges_],
347 0, nLocalEdges_,
true);
348 eOffsets_ = arcp(
new offset_t[nLocalVertices_+1],
349 0, nLocalVertices_+1,
true);
350 scalar_t *wgts2 =
new scalar_t [nLocalEdges_];
353 vGids_[0] = comm->getRank();
358 for (std::map<int,double>::iterator it = exportpidmap.begin();
359 it != exportpidmap.end(); it++) {
360 eGids_[ptr] = it->first;
361 wgts2[ptr++] = it->second;
363 eOffsets_[nLocalVertices_] = ptr;
366 nWeightsPerEdge_ = 1;
367 input_t *wgts =
new input_t [nWeightsPerEdge_];
368 eWeights_ = arcp(wgts, 0, nWeightsPerEdge_,
true);
370 for (
int w=0; w < nWeightsPerEdge_; w++){
372 ArrayRCP<const scalar_t> wgtArray = arcp(wgts2, 0, nLocalEdges_,
true);
373 eWeights_[w] = input_t(wgtArray, stride);
377 nWeightsPerVertex_ = 1;
378 input_t *weightInfo =
new input_t [nWeightsPerVertex_];
380 for (
int idx=0; idx < nWeightsPerVertex_; idx++){
381 scalar_t *wgt =
new scalar_t [nLocalVertices_];
382 wgt[0] = inGraph->getNodeNumEntries();
383 ArrayRCP<const scalar_t> wgtArray = arcp(wgt, 0, nLocalVertices_,
true);
384 weightInfo[idx] = input_t(wgtArray, 1);
387 vWeights_ = arcp<input_t>(weightInfo, 0, nWeightsPerVertex_,
true);
389 reduceAll<int, size_t>(*comm_, Teuchos::REDUCE_SUM, 1,
390 &nLocalVertices_, &nGlobalVertices_);
391 reduceAll<int, size_t>(*comm_, Teuchos::REDUCE_SUM, 1,
392 &nLocalEdges_, &nGlobalEdges_);
395 vtxDist_ = arcp(
new size_t[commSize+1], 0, commSize+1,
true);
397 Teuchos::gatherAll(*comm_, 1, &nLocalVertices_, commSize, &vtxDist_[1]);
398 for (
int i = 0; i < commSize; i++)
399 vtxDist_[i+1] += vtxDist_[i];
405 template <
typename Adapter>
413 const ParameterList &pl = env_->getParameters();
414 const Teuchos::ParameterEntry *pe = pl.getEntryPtr(
"quotient_threshold");
416 threshold_ = pe->getValue<
int>(&threshold_);
419 nActiveRanks_ = std::ceil((
double) nGlobalVertices_ / threshold_);
420 size_t avgVertexShare = nGlobalVertices_ / nActiveRanks_;
421 size_t myVertexShare = 0;
423 int me = comm_->getRank();
424 int commSize = comm_->getSize();
427 ArrayRCP<offset_t> old_eOffsets_ = eOffsets_;
428 ArrayRCP<gno_t> old_eGids_ = eGids_;
429 size_t old_nLocalEdges_ = nLocalEdges_;
430 ArrayRCP<input_t> old_vWeights_ = vWeights_;
431 ArrayRCP<input_t> old_eWeights_ = eWeights_;
434 destRank_ = me / (int) avgVertexShare;
435 if(destRank_ >= nActiveRanks_)
436 destRank_ = nActiveRanks_ - 1;
439 RCP<CommRequest<int>> *requests;
440 if(me < nActiveRanks_) {
444 startRank_ = me *
static_cast<int>(avgVertexShare);
445 endRank_ = (me+1) *
static_cast<int>(avgVertexShare);
446 if(me == nActiveRanks_ - 1 )
447 endRank_ =
static_cast<int>(nGlobalVertices_);
448 myVertexShare = endRank_ - startRank_;
450 eOffsets_ = arcp(
new offset_t[myVertexShare+1], 0, myVertexShare+1,
true);
454 requests =
new RCP<CommRequest<int>>[myVertexShare];
455 for(
int i = startRank_; i < endRank_; i++) {
456 requests[i-startRank_] = Teuchos::ireceive<int, offset_t>(*comm_,
457 arcp(&eOffsets_[i-startRank_+1], 0, 1,
false),
462 Teuchos::send<int, offset_t>(*comm_, 1, &old_eOffsets_[nLocalVertices_], destRank_);
465 Teuchos::waitAll<int>(*comm_, Teuchos::arrayView(requests, myVertexShare));
468 for(
size_t i = 1; i <= myVertexShare; i++)
469 eOffsets_[i] += eOffsets_[i-1];
472 nLocalEdges_ = eOffsets_[myVertexShare];
475 eGids_ = arcp(
new gno_t[nLocalEdges_], 0, nLocalEdges_,
true);
479 for(
int i = startRank_; i < endRank_; i++) {
480 offset_t adjStartRank_ = eOffsets_[i-startRank_];
481 offset_t adjSize = eOffsets_[i-startRank_+1] - adjStartRank_;
482 requests[i-startRank_] = Teuchos::ireceive<int, gno_t>(*comm_,
483 arcp(&eGids_[adjStartRank_], 0, adjSize,
false),
488 Teuchos::send<int, gno_t>(*comm_, old_nLocalEdges_, &old_eGids_[0], destRank_);
489 Teuchos::waitAll<int>(*comm_, Teuchos::arrayView(requests, myVertexShare));
493 scalar_t *wgts =
new scalar_t [myVertexShare];
494 for(
int i = startRank_; i < endRank_; i++) {
495 requests[i-startRank_] = Teuchos::ireceive<int, scalar_t>(*comm_,
496 arcp(&wgts[i-startRank_], 0, 1,
false),
500 const scalar_t *wPtr;
503 old_vWeights_[0].getStridedList(wLen, wPtr, stride);
504 Teuchos::send<int, scalar_t>(*comm_, nLocalVertices_, wPtr, destRank_);
506 Teuchos::waitAll<int>(*comm_, Teuchos::arrayView(requests, myVertexShare));
508 input_t *weightInfo =
new input_t [nWeightsPerVertex_];
509 for (
int idx=0; idx < nWeightsPerVertex_; idx++){
510 ArrayRCP<const scalar_t> wgtArray = arcp(wgts, 0, myVertexShare,
true);
511 weightInfo[idx] = input_t(wgtArray, 1);
513 vWeights_ = arcp<input_t>(weightInfo, 0, nWeightsPerVertex_,
true);
516 scalar_t *ewgts =
new scalar_t [nLocalEdges_];
517 for(
int i = startRank_; i < endRank_; i++) {
518 offset_t adjStartRank_ = eOffsets_[i-startRank_];
519 offset_t adjSize = eOffsets_[i-startRank_+1] - adjStartRank_;
520 requests[i-startRank_] = Teuchos::ireceive<int, scalar_t>(*comm_,
521 arcp(&ewgts[adjStartRank_], 0, adjSize,
false),
525 old_eWeights_[0].getStridedList(wLen, wPtr, stride);
526 Teuchos::send<int, scalar_t>(*comm_, old_nLocalEdges_, wPtr, destRank_);
528 Teuchos::waitAll<int>(*comm_, Teuchos::arrayView(requests, myVertexShare));
530 input_t *eweightInfo =
new input_t [nWeightsPerEdge_];
531 for (
int idx=0; idx < nWeightsPerEdge_; idx++){
532 ArrayRCP<const scalar_t> ewgtArray = arcp(ewgts, 0, nLocalEdges_,
true);
533 eweightInfo[idx] = input_t(ewgtArray, 1);
535 eWeights_ = arcp<input_t>(eweightInfo, 0, nWeightsPerEdge_,
true);
539 vGids_ = arcp(
new gno_t[myVertexShare], 0, myVertexShare,
true);
540 for(
int i = startRank_; i < endRank_; i++)
541 vGids_[i-startRank_] = i;
543 nLocalVertices_ = myVertexShare;
550 Teuchos::send<int, offset_t>(*comm_, 1, &eOffsets_[nLocalVertices_], destRank_);
553 Teuchos::send<int, gno_t>(*comm_, nLocalEdges_, &eGids_[0], destRank_);
556 const scalar_t *wPtr;
559 vWeights_[0].getStridedList(wLen, wPtr, stride);
560 Teuchos::send<int, scalar_t>(*comm_, nLocalVertices_, wPtr, destRank_);
563 eWeights_[0].getStridedList(wLen, wPtr, stride);
564 Teuchos::send<int, scalar_t>(*comm_, nLocalEdges_, wPtr, destRank_);
569 for (
int i = 0; i <= commSize; i++)
572 Teuchos::gatherAll(*comm_, 1, &nLocalVertices_, commSize, &vtxDist_[1]);
573 for (
int i = 0; i < commSize; i++)
574 vtxDist_[i+1] += vtxDist_[i];
579 template <
typename Adapter>
580 void CommGraphModel<Adapter>::print()
582 std::ostream *os = env_->getDebugOStream();
584 int me = comm_->getRank();
587 <<
" Nvtx " << nLocalVertices_
588 <<
" Nedge " << nLocalEdges_
589 <<
" NVWgt " << nWeightsPerVertex_
590 <<
" NEWgt " << nWeightsPerEdge_
593 for (
size_t i = 0; i < nLocalVertices_; i++) {
594 *os << me <<
" " << i <<
" GID " << vGids_[i] <<
": ";
595 for (offset_t j = eOffsets_[i]; j < eOffsets_[i+1]; j++)
596 *os << eGids_[j] <<
" " ;
600 if (nWeightsPerVertex_) {
601 for (
size_t i = 0; i < nLocalVertices_; i++) {
602 *os << me <<
" " << i <<
" VWGTS " << vGids_[i] <<
": ";
603 for (
int j = 0; j < nWeightsPerVertex_; j++)
604 *os << vWeights_[j][i] <<
" ";
609 if (nWeightsPerEdge_) {
610 for (
size_t i = 0; i < nLocalVertices_; i++) {
611 *os << me <<
" " << i <<
" EWGTS " << vGids_[i] <<
": ";
612 for (offset_t j = eOffsets_[i]; j < eOffsets_[i+1]; j++) {
613 *os << eGids_[j] <<
" (";
614 for (
int w = 0; w < nWeightsPerEdge_; w++)
615 *os << eWeights_[w][j] <<
" ";
Zoltan2::BasicUserTypes< zscalar_t, zlno_t, zgno_t > user_t
#define Z2_FORWARD_EXCEPTIONS
Forward an exception back through call stack.
Defines the GraphAdapter interface.
Defines the IdentifierAdapter interface.
Defines the MatrixAdapter interface.
Defines the MeshAdapter interface.
Defines helper functions for use in the models.
Defines the Model interface.
This file defines the StridedData class.
Defines the VectorAdapter interface.
Defines XpetraCrsGraphAdapter class.
CommGraphModel defines the interface required for communication graph.
CommGraphModel(const RCP< const VectorAdapter< userCoord_t > > &, const RCP< const Environment > &, const RCP< const Comm< int > > &)
size_t getVertexList(ArrayView< const gno_t > &Ids, ArrayView< input_t > &wgts) const
Sets pointers to this process' vertex Ids and their weights.
size_t getGlobalNumEdges() const
Returns the global number edges. For local graphs, the number of global edges is the number of local ...
int getNumActiveRanks() const
size_t getGlobalNumObjects() const
Return the global number of objects.
size_t getLocalNumEdges() const
Returns the number of edges on this process. In global or subset graphs, includes off-process edges.
size_t getLocalNumVertices() const
Returns the number vertices on this process.
int getNumWeightsPerEdge() const
Returns the number (0 or greater) of weights per edge.
int getDestinationRank() const
~CommGraphModel()
Destructor.
CommGraphModel(const RCP< const MatrixAdapter< user_t, userCoord_t > > &ia, const RCP< const Environment > &env, const RCP< const Comm< int > > &comm)
Constructor.
void getVertexDist(ArrayView< size_t > &vtxdist) const
Return the vtxDist array Array of size comm->getSize() + 1 Array[n+1] - Array[n] is number of vertice...
CommGraphModel(const RCP< const IdentifierAdapter< user_t > > &ia, const RCP< const Environment > &env, const RCP< const Comm< int > > &comm)
size_t getGlobalNumVertices() const
Returns the global number vertices.
CommGraphModel(const RCP< const MeshAdapter< user_t > > &ia, const RCP< const Environment > &env, const RCP< const Comm< int > > &comm)
const RCP< const Comm< int > > getComm()
Return the communicator used by the model.
int getNumWeightsPerVertex() const
Returns the number (0 or greater) of weights per vertex.
size_t getLocalNumObjects() const
Return the local number of objects.
size_t getEdgeList(ArrayView< const gno_t > &edgeIds, ArrayView< const offset_t > &offsets, ArrayView< input_t > &wgts) const
GraphAdapter defines the interface for graph-based user data.
IdentifierAdapter defines the interface for identifiers.
MatrixAdapter defines the adapter interface for matrices.
MeshAdapter defines the interface for mesh input.
The base class for all model classes.
The StridedData class manages lists of weights or coordinates.
VectorAdapter defines the interface for vector input.
map_t::local_ordinal_type lno_t
map_t::global_ordinal_type gno_t
Created by mbenlioglu on Aug 31, 2020.