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;
101 typedef typename Adapter::userCoord_t userCoord_t;
103 typedef typename Adapter::offset_t offset_t;
120 const RCP<const Environment> &,
const RCP<
const Comm<int> > &,
123 throw std::runtime_error(
"CommGraphModel is not implemented for MatrixAdapter yet.");
127 const RCP<const Environment> &env,
const RCP<
const Comm<int> > &comm,
131 const RCP<const Environment> &,
const RCP<
const Comm<int> > &,
134 throw std::runtime_error(
"CommGraphModel is not implemented for MeshAdapter yet.");
138 const RCP<const Environment> &,
const RCP<
const Comm<int> > &,
141 throw std::runtime_error(
"cannot build CommGraphModel from VectorAdapter");
145 const RCP<const Environment> &,
const RCP<
const Comm<int> > &,
148 throw std::runtime_error(
"cannot build GraphModel from IdentifierAdapter");
153 const RCP<const Comm<int> >
getComm() {
return comm_; }
190 ArrayView<const gno_t> &Ids,
191 ArrayView<input_t> &wgts)
const
193 Ids = vGids_.view(0, nLocalVertices_);
194 wgts = vWeights_.view(0, nWeightsPerVertex_);
195 return nLocalVertices_;
203 ArrayView<const offset_t> &offsets,
204 ArrayView<input_t> &wgts)
const
206 edgeIds = eGids_.view(0, nLocalEdges_);
207 offsets = eOffsets_.view(0, nLocalVertices_+1);
208 wgts = eWeights_.view(0, nWeightsPerEdge_);
218 vtxdist = vtxDist_();
219 if (vtxDist_.size() == 0) {
220 throw std::runtime_error(
"getVertexDist is available only "
221 "when consecutiveIdsRequired");
250 const RCP<const Environment > env_;
251 const RCP<const Comm<int> > comm_;
255 int destRank_, startRank_, endRank_;
258 size_t nLocalVertices_;
259 size_t nGlobalVertices_;
260 ArrayRCP<gno_t> vGids_;
264 int nWeightsPerVertex_;
265 ArrayRCP<input_t> vWeights_;
272 size_t nGlobalEdges_;
273 ArrayRCP<gno_t> eGids_;
274 ArrayRCP<offset_t> eOffsets_;
280 int nWeightsPerEdge_;
281 ArrayRCP<input_t> eWeights_;
286 ArrayRCP<size_t> vtxDist_;
295 template <
typename Adapter>
298 const RCP<const Environment> &env,
299 const RCP<
const Comm<int> > &comm,
306 nWeightsPerVertex_(0),
316 int commSize = comm_->getSize();
319 RCP<XpetraCrsGraphAdapter<user_t, userCoord_t>> ia;
321 RCP<GraphAdapter<user_t, userCoord_t>> tmp =
328 auto inGraph = ia->getXpetraGraph();
331 auto imp = inGraph->getImporter();
334 std::map<int,double> exportpidmap;
335 auto exportpids = imp->getExportPIDs();
336 size_t nexportpids = imp->getNumExportIDs();
337 for (
size_t i = 0; i < nexportpids; i++) {
338 int k = exportpids[i];
339 if (exportpidmap.find(k) != exportpidmap.end())
340 exportpidmap[k] = exportpidmap[k] + 1.;
342 exportpidmap[k] = 1.;
348 nLocalEdges_ = exportpidmap.size();
351 vGids_ = arcp(
new gno_t[nLocalVertices_],
352 0, nLocalVertices_,
true);
353 eGids_ = arcp(
new gno_t[nLocalEdges_],
354 0, nLocalEdges_,
true);
355 eOffsets_ = arcp(
new offset_t[nLocalVertices_+1],
356 0, nLocalVertices_+1,
true);
357 scalar_t *wgts2 =
new scalar_t [nLocalEdges_];
360 vGids_[0] = comm->getRank();
365 for (std::map<int,double>::iterator it = exportpidmap.begin();
366 it != exportpidmap.end(); it++) {
367 eGids_[ptr] = it->first;
368 wgts2[ptr++] = it->second;
370 eOffsets_[nLocalVertices_] = ptr;
373 nWeightsPerEdge_ = 1;
374 input_t *wgts =
new input_t [nWeightsPerEdge_];
375 eWeights_ = arcp(wgts, 0, nWeightsPerEdge_,
true);
377 for (
int w=0; w < nWeightsPerEdge_; w++){
379 ArrayRCP<const scalar_t> wgtArray = arcp(wgts2, 0, nLocalEdges_,
true);
380 eWeights_[w] = input_t(wgtArray, stride);
384 nWeightsPerVertex_ = 1;
385 input_t *weightInfo =
new input_t [nWeightsPerVertex_];
387 for (
int idx=0; idx < nWeightsPerVertex_; idx++){
388 scalar_t *wgt =
new scalar_t [nLocalVertices_];
389 wgt[0] = inGraph->getLocalNumEntries();
390 ArrayRCP<const scalar_t> wgtArray = arcp(wgt, 0, nLocalVertices_,
true);
391 weightInfo[idx] = input_t(wgtArray, 1);
394 vWeights_ = arcp<input_t>(weightInfo, 0, nWeightsPerVertex_,
true);
396 reduceAll<int, size_t>(*comm_, Teuchos::REDUCE_SUM, 1,
397 &nLocalVertices_, &nGlobalVertices_);
398 reduceAll<int, size_t>(*comm_, Teuchos::REDUCE_SUM, 1,
399 &nLocalEdges_, &nGlobalEdges_);
402 vtxDist_ = arcp(
new size_t[commSize+1], 0, commSize+1,
true);
404 Teuchos::gatherAll(*comm_, 1, &nLocalVertices_, commSize, &vtxDist_[1]);
405 for (
int i = 0; i < commSize; i++)
406 vtxDist_[i+1] += vtxDist_[i];
412 template <
typename Adapter>
420 const ParameterList &pl = env_->getParameters();
421 const Teuchos::ParameterEntry *pe = pl.getEntryPtr(
"quotient_threshold");
423 threshold_ = pe->getValue<
int>(&threshold_);
426 nActiveRanks_ = std::ceil((
double) nGlobalVertices_ / threshold_);
427 size_t avgVertexShare = nGlobalVertices_ / nActiveRanks_;
428 size_t myVertexShare = 0;
430 int me = comm_->getRank();
431 int commSize = comm_->getSize();
434 ArrayRCP<offset_t> old_eOffsets_ = eOffsets_;
435 ArrayRCP<gno_t> old_eGids_ = eGids_;
436 size_t old_nLocalEdges_ = nLocalEdges_;
437 ArrayRCP<input_t> old_vWeights_ = vWeights_;
438 ArrayRCP<input_t> old_eWeights_ = eWeights_;
441 destRank_ = me / (int) avgVertexShare;
442 if(destRank_ >= nActiveRanks_)
443 destRank_ = nActiveRanks_ - 1;
446 RCP<CommRequest<int>> *requests;
447 if(me < nActiveRanks_) {
451 startRank_ = me *
static_cast<int>(avgVertexShare);
452 endRank_ = (me+1) * static_cast<int>(avgVertexShare);
453 if(me == nActiveRanks_ - 1 )
454 endRank_ =
static_cast<int>(nGlobalVertices_);
455 myVertexShare = endRank_ - startRank_;
457 eOffsets_ = arcp(
new offset_t[myVertexShare+1], 0, myVertexShare+1,
true);
461 requests =
new RCP<CommRequest<int>>[myVertexShare];
462 for(
int i = startRank_; i < endRank_; i++) {
463 requests[i-startRank_] = Teuchos::ireceive<int, offset_t>(*comm_,
464 arcp(&eOffsets_[i-startRank_+1], 0, 1,
false),
469 Teuchos::send<int, offset_t>(*comm_, 1, &old_eOffsets_[nLocalVertices_], destRank_);
472 Teuchos::waitAll<int>(*comm_, Teuchos::arrayView(requests, myVertexShare));
475 for(
size_t i = 1; i <= myVertexShare; i++)
476 eOffsets_[i] += eOffsets_[i-1];
479 nLocalEdges_ = eOffsets_[myVertexShare];
482 eGids_ = arcp(
new gno_t[nLocalEdges_], 0, nLocalEdges_,
true);
486 for(
int i = startRank_; i < endRank_; i++) {
487 offset_t adjStartRank_ = eOffsets_[i-startRank_];
488 offset_t adjSize = eOffsets_[i-startRank_+1] - adjStartRank_;
489 requests[i-startRank_] = Teuchos::ireceive<int, gno_t>(*comm_,
490 arcp(&eGids_[adjStartRank_], 0, adjSize,
false),
495 Teuchos::send<int, gno_t>(*comm_, old_nLocalEdges_, &old_eGids_[0], destRank_);
496 Teuchos::waitAll<int>(*comm_, Teuchos::arrayView(requests, myVertexShare));
500 scalar_t *wgts =
new scalar_t [myVertexShare];
501 for(
int i = startRank_; i < endRank_; i++) {
502 requests[i-startRank_] = Teuchos::ireceive<int, scalar_t>(*comm_,
503 arcp(&wgts[i-startRank_], 0, 1,
false),
507 const scalar_t *wPtr;
510 old_vWeights_[0].getStridedList(wLen, wPtr, stride);
511 Teuchos::send<int, scalar_t>(*comm_, nLocalVertices_, wPtr, destRank_);
513 Teuchos::waitAll<int>(*comm_, Teuchos::arrayView(requests, myVertexShare));
515 input_t *weightInfo =
new input_t [nWeightsPerVertex_];
516 for (
int idx=0; idx < nWeightsPerVertex_; idx++){
517 ArrayRCP<const scalar_t> wgtArray = arcp(wgts, 0, myVertexShare,
true);
518 weightInfo[idx] = input_t(wgtArray, 1);
520 vWeights_ = arcp<input_t>(weightInfo, 0, nWeightsPerVertex_,
true);
523 scalar_t *ewgts =
new scalar_t [nLocalEdges_];
524 for(
int i = startRank_; i < endRank_; i++) {
525 offset_t adjStartRank_ = eOffsets_[i-startRank_];
526 offset_t adjSize = eOffsets_[i-startRank_+1] - adjStartRank_;
527 requests[i-startRank_] = Teuchos::ireceive<int, scalar_t>(*comm_,
528 arcp(&ewgts[adjStartRank_], 0, adjSize,
false),
532 old_eWeights_[0].getStridedList(wLen, wPtr, stride);
533 Teuchos::send<int, scalar_t>(*comm_, old_nLocalEdges_, wPtr, destRank_);
535 Teuchos::waitAll<int>(*comm_, Teuchos::arrayView(requests, myVertexShare));
537 input_t *eweightInfo =
new input_t [nWeightsPerEdge_];
538 for (
int idx=0; idx < nWeightsPerEdge_; idx++){
539 ArrayRCP<const scalar_t> ewgtArray = arcp(ewgts, 0, nLocalEdges_,
true);
540 eweightInfo[idx] = input_t(ewgtArray, 1);
542 eWeights_ = arcp<input_t>(eweightInfo, 0, nWeightsPerEdge_,
true);
546 vGids_ = arcp(
new gno_t[myVertexShare], 0, myVertexShare,
true);
547 for(
int i = startRank_; i < endRank_; i++)
548 vGids_[i-startRank_] = i;
550 nLocalVertices_ = myVertexShare;
557 Teuchos::send<int, offset_t>(*comm_, 1, &eOffsets_[nLocalVertices_], destRank_);
560 Teuchos::send<int, gno_t>(*comm_, nLocalEdges_, &eGids_[0], destRank_);
563 const scalar_t *wPtr;
566 vWeights_[0].getStridedList(wLen, wPtr, stride);
567 Teuchos::send<int, scalar_t>(*comm_, nLocalVertices_, wPtr, destRank_);
570 eWeights_[0].getStridedList(wLen, wPtr, stride);
571 Teuchos::send<int, scalar_t>(*comm_, nLocalEdges_, wPtr, destRank_);
576 for (
int i = 0; i <= commSize; i++)
579 Teuchos::gatherAll(*comm_, 1, &nLocalVertices_, commSize, &vtxDist_[1]);
580 for (
int i = 0; i < commSize; i++)
581 vtxDist_[i+1] += vtxDist_[i];
586 template <
typename Adapter>
587 void CommGraphModel<Adapter>::print()
589 std::ostream *os = env_->getDebugOStream();
591 int me = comm_->getRank();
594 <<
" Nvtx " << nLocalVertices_
595 <<
" Nedge " << nLocalEdges_
596 <<
" NVWgt " << nWeightsPerVertex_
597 <<
" NEWgt " << nWeightsPerEdge_
600 for (
size_t i = 0; i < nLocalVertices_; i++) {
601 *os << me <<
" " << i <<
" GID " << vGids_[i] <<
": ";
602 for (offset_t j = eOffsets_[i]; j < eOffsets_[i+1]; j++)
603 *os << eGids_[j] <<
" " ;
607 if (nWeightsPerVertex_) {
608 for (
size_t i = 0; i < nLocalVertices_; i++) {
609 *os << me <<
" " << i <<
" VWGTS " << vGids_[i] <<
": ";
610 for (
int j = 0; j < nWeightsPerVertex_; j++)
611 *os << vWeights_[j][i] <<
" ";
616 if (nWeightsPerEdge_) {
617 for (
size_t i = 0; i < nLocalVertices_; i++) {
618 *os << me <<
" " << i <<
" EWGTS " << vGids_[i] <<
": ";
619 for (offset_t j = eOffsets_[i]; j < eOffsets_[i+1]; j++) {
620 *os << eGids_[j] <<
" (";
621 for (
int w = 0; w < nWeightsPerEdge_; w++)
622 *os << eWeights_[w][j] <<
" ";
size_t getGlobalNumEdges() const
Returns the global number edges. For local graphs, the number of global edges is the number of local ...
IdentifierAdapter defines the interface for identifiers.
size_t getLocalNumVertices() const
Returns the number vertices on this process.
#define Z2_FORWARD_EXCEPTIONS
Forward an exception back through call stack.
MatrixAdapter defines the adapter interface for matrices.
Defines the Model interface.
GraphAdapter defines the interface for graph-based user data.
Defines the MeshAdapter interface.
MeshAdapter defines the interface for mesh input.
std::bitset< NUM_MODEL_FLAGS > modelFlag_t
map_t::global_ordinal_type gno_t
Defines the IdentifierAdapter interface.
size_t getGlobalNumVertices() const
Returns the global number vertices.
Defines the VectorAdapter interface.
Provides access for Zoltan2 to Xpetra::CrsGraph data.
Defines XpetraCrsGraphAdapter class.
size_t getEdgeList(ArrayView< const gno_t > &edgeIds, ArrayView< const offset_t > &offsets, ArrayView< input_t > &wgts) const
Defines helper functions for use in the models.
CommGraphModel defines the interface required for communication graph.
int getDestinationRank() const
int getNumWeightsPerEdge() const
Returns the number (0 or greater) of weights per edge.
VectorAdapter defines the interface for vector input.
The StridedData class manages lists of weights or coordinates.
~CommGraphModel()
Destructor.
size_t getLocalNumEdges() const
Returns the number of edges on this process. In global or subset graphs, includes off-process edges...
map_t::local_ordinal_type lno_t
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 getLocalNumObjects() const
Return the local number of objects.
int getNumWeightsPerVertex() const
Returns the number (0 or greater) of weights per vertex.
CommGraphModel(const RCP< const MeshAdapter< user_t > > &, const RCP< const Environment > &, const RCP< const Comm< int > > &, const modelFlag_t &modelflags=modelFlag_t())
CommGraphModel(const RCP< const VectorAdapter< userCoord_t > > &, const RCP< const Environment > &, const RCP< const Comm< int > > &, const modelFlag_t &modelflags=modelFlag_t())
Defines the MatrixAdapter interface.
The base class for all model classes.
int getNumActiveRanks() const
CommGraphModel(const RCP< const IdentifierAdapter< user_t > > &, const RCP< const Environment > &, const RCP< const Comm< int > > &, const modelFlag_t &modelflags=modelFlag_t())
Defines the GraphAdapter interface.
CommGraphModel(const RCP< const MatrixAdapter< user_t, userCoord_t > > &, const RCP< const Environment > &, const RCP< const Comm< int > > &, const modelFlag_t &modelflags=modelFlag_t())
Constructor.
size_t getGlobalNumObjects() const
Return the global number of objects.
const RCP< const Comm< int > > getComm()
Return the communicator used by the model.
This file defines the StridedData class.
Zoltan2::BasicUserTypes< zscalar_t, zlno_t, zgno_t > user_t
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...