45 #ifndef _ZOLTAN2_ALGSCOTCH_HPP_
46 #define _ZOLTAN2_ALGSCOTCH_HPP_
67 pl.set(
"scotch_verbose",
false,
"verbose output",
70 RCP<Teuchos::EnhancedNumberValidator<int>> scotch_level_Validator =
71 Teuchos::rcp(
new Teuchos::EnhancedNumberValidator<int>(0, 1000, 1, 0) );
72 pl.set(
"scotch_level", 0,
"scotch ordering - Level of the subgraph in the "
73 "separators tree for the initial graph at the root of the tree",
74 scotch_level_Validator);
76 pl.set(
"scotch_imbalance_ratio", 0.2,
"scotch ordering - Dissection "
80 pl.set(
"scotch_ordering_default",
true,
"use default scotch ordering "
83 pl.set(
"scotch_ordering_strategy",
"",
"scotch ordering - Dissection "
89 #ifndef HAVE_ZOLTAN2_SCOTCH
96 template <
typename Adapter>
106 const RCP<
const Comm<int> > &,
107 const RCP<const base_adapter_t> &
110 throw std::runtime_error(
111 "BUILD ERROR: Scotch requested but not compiled into Zoltan2.\n"
112 "Please set CMake flag Zoltan2_ENABLE_Scotch:BOOL=ON.");
128 #ifdef HAVE_ZOLTAN2_SCOTCH
135 #ifndef HAVE_ZOLTAN2_MPI
138 #include "ptscotch.h"
142 #ifdef SHOW_ZOLTAN2_SCOTCH_MEMORY
155 #ifdef HAVE_SCOTCH_GETMEMORYMAX
157 extern size_t SCOTCH_getMemoryMax();
160 #error "Either turn off ZOLTAN2_ENABLE_SCOTCH_MEMORY_REPORT in cmake configure, or see SHOW_ZOLTAN2_SCOTCH_MEMORY comment in Zoltan2_AlgScotch.hpp"
161 #endif // HAVE_SCOTCH_GETMEMORYMAX
162 #endif // SHOW_ZOLTAN2_SCOTCH_MEMORY
164 template <
typename Adapter>
165 class AlgPTScotch :
public Algorithm<Adapter>
170 typedef GraphModel<typename Adapter::base_adapter_t> graphModel_t;
171 typedef typename Adapter::lno_t
lno_t;
172 typedef typename Adapter::gno_t
gno_t;
173 typedef typename Adapter::offset_t offset_t;
174 typedef typename Adapter::scalar_t
scalar_t;
177 typedef typename Adapter::userCoord_t userCoord_t;
209 const RCP<
const Comm<int> > &problemComm__,
210 const RCP<
const IdentifierAdapter<user_t> > &adapter__) :
211 env(env__), problemComm(problemComm__),
212 #ifdef HAVE_ZOLTAN2_MPI
213 mpicomm(Teuchos::getRawMpiComm(*problemComm__)),
217 std::string errStr =
"cannot build GraphModel from IdentifierAdapter, ";
218 errStr +=
"Scotch requires Graph, Matrix, or Mesh Adapter";
219 throw std::runtime_error(errStr);
223 const RCP<
const Comm<int> > &problemComm__,
224 const RCP<
const VectorAdapter<user_t> > &adapter__) :
225 env(env__), problemComm(problemComm__),
226 #ifdef HAVE_ZOLTAN2_MPI
227 mpicomm(Teuchos::getRawMpiComm(*problemComm__)),
231 std::string errStr =
"cannot build GraphModel from IdentifierAdapter, ";
232 errStr +=
"Scotch requires Graph, Matrix, or Mesh Adapter";
233 throw std::runtime_error(errStr);
237 const RCP<
const Comm<int> > &problemComm__,
238 const RCP<
const GraphAdapter<user_t, userCoord_t> > &adapter__) :
239 env(env__), problemComm(problemComm__),
240 #ifdef HAVE_ZOLTAN2_MPI
241 mpicomm(Teuchos::getRawMpiComm(*problemComm__)),
243 adapter(adapter__), model_flags()
245 this->model_flags.reset();
249 const RCP<
const Comm<int> > &problemComm__,
250 const RCP<
const MatrixAdapter<user_t, userCoord_t> > &adapter__) :
251 env(env__), problemComm(problemComm__),
252 #ifdef HAVE_ZOLTAN2_MPI
253 mpicomm(Teuchos::getRawMpiComm(*problemComm__)),
255 adapter(adapter__), model_flags()
257 this->model_flags.reset();
259 const ParameterList &pl = env->getParameters();
260 const Teuchos::ParameterEntry *pe;
262 std::string defString(
"default");
263 std::string objectOfInterest(defString);
264 pe = pl.getEntryPtr(
"objects_to_partition");
266 objectOfInterest = pe->getValue<std::string>(&objectOfInterest);
268 if (objectOfInterest == defString ||
269 objectOfInterest == std::string(
"matrix_rows") )
271 else if (objectOfInterest == std::string(
"matrix_columns"))
273 else if (objectOfInterest == std::string(
"matrix_nonzeros"))
278 const RCP<
const Comm<int> > &problemComm__,
279 const RCP<
const MeshAdapter<user_t> > &adapter__) :
280 env(env__), problemComm(problemComm__),
281 #ifdef HAVE_ZOLTAN2_MPI
282 mpicomm(Teuchos::getRawMpiComm(*problemComm__)),
284 adapter(adapter__), model_flags()
286 this->model_flags.reset();
288 const ParameterList &pl = env->getParameters();
289 const Teuchos::ParameterEntry *pe;
291 std::string defString(
"default");
292 std::string objectOfInterest(defString);
293 pe = pl.getEntryPtr(
"objects_to_partition");
295 objectOfInterest = pe->getValue<std::string>(&objectOfInterest);
297 if (objectOfInterest == defString ||
298 objectOfInterest == std::string(
"mesh_nodes") )
300 else if (objectOfInterest == std::string(
"mesh_elements"))
311 void partition(
const RCP<PartitioningSolution<Adapter> > &solution);
313 int localOrder(
const RCP<LocalOrderingSolution<lno_t> > &solution);
314 int globalOrder(
const RCP<GlobalOrderingSolution<gno_t> > &solution);
318 const RCP<const Environment> env;
319 const RCP<const Comm<int> > problemComm;
320 #ifdef HAVE_ZOLTAN2_MPI
321 const MPI_Comm mpicomm;
323 const RCP<const base_adapter_t> adapter;
325 RCP<graphModel_t > model;
327 void buildModel(
bool isLocal);
328 void scale_weights(
size_t n, StridedData<lno_t, scalar_t> &fwgts,
330 static int setStrategy(SCOTCH_Strat * c_strat_ptr,
const ParameterList &pList,
int procRank);
334 template <
typename Adapter>
335 void AlgPTScotch<Adapter>::buildModel(
bool isLocal) {
337 const ParameterList &pl = env->getParameters();
338 const Teuchos::ParameterEntry *pe;
340 std::string defString(
"default");
341 std::string symParameter(defString);
342 pe = pl.getEntryPtr(
"symmetrize_graph");
344 symParameter = pe->getValue<std::string>(&symParameter);
345 if (symParameter == std::string(
"transpose"))
347 else if (symParameter == std::string(
"bipartite"))
350 bool sgParameter =
false;
351 pe = pl.getEntryPtr(
"subset_graph");
353 sgParameter = pe->getValue(&sgParameter);
365 this->model = rcp(
new graphModel_t(this->adapter,
372 template <
typename Adapter>
374 const RCP<PartitioningSolution<Adapter> > &solution
378 this->buildModel(
false);
380 size_t numGlobalParts = solution->getTargetGlobalNumberOfParts();
382 SCOTCH_Num partnbr=0;
385 #ifdef HAVE_ZOLTAN2_MPI
387 int me = problemComm->getRank();
389 const SCOTCH_Num baseval = 0;
392 SCOTCH_Strat stratstr;
394 SCOTCH_stratInit(&stratstr);
397 SCOTCH_Dgraph *gr = SCOTCH_dgraphAlloc();
398 ierr = SCOTCH_dgraphInit(gr, mpicomm);
400 env->globalInputAssertion(__FILE__, __LINE__,
"SCOTCH_dgraphInit",
404 ArrayView<const gno_t> vtxID;
405 ArrayView<StridedData<lno_t, scalar_t> > vwgts;
406 size_t nVtx = model->getVertexList(vtxID, vwgts);
407 SCOTCH_Num vertlocnbr=0;
409 SCOTCH_Num vertlocmax = vertlocnbr;
412 ArrayView<const gno_t> edgeIds;
413 ArrayView<const offset_t> offsets;
414 ArrayView<StridedData<lno_t, scalar_t> > ewgts;
416 size_t nEdge = model->getEdgeList(edgeIds, offsets, ewgts);
418 SCOTCH_Num edgelocnbr=0;
420 const SCOTCH_Num edgelocsize = edgelocnbr;
422 SCOTCH_Num *vertloctab;
425 SCOTCH_Num *edgeloctab;
429 SCOTCH_Num *vendloctab = NULL;
430 SCOTCH_Num *vlblloctab = NULL;
431 SCOTCH_Num *edgegsttab = NULL;
434 SCOTCH_Num *velotab = NULL;
435 SCOTCH_Num *edlotab = NULL;
437 int nVwgts = model->getNumWeightsPerVertex();
438 int nEwgts = model->getNumWeightsPerEdge();
439 if (nVwgts > 1 && me == 0) {
440 std::cerr <<
"Warning: NumWeightsPerVertex is " << nVwgts
441 <<
" but Scotch allows only one weight. "
442 <<
" Zoltan2 will use only the first weight per vertex."
445 if (nEwgts > 1 && me == 0) {
446 std::cerr <<
"Warning: NumWeightsPerEdge is " << nEwgts
447 <<
" but Scotch allows only one weight. "
448 <<
" Zoltan2 will use only the first weight per edge."
453 velotab =
new SCOTCH_Num[nVtx+1];
455 scale_weights(nVtx, vwgts[0], velotab);
459 edlotab =
new SCOTCH_Num[nEdge+1];
461 scale_weights(nEdge, ewgts[0], edlotab);
465 ierr = SCOTCH_dgraphBuild(gr, baseval, vertlocnbr, vertlocmax,
466 vertloctab, vendloctab, velotab, vlblloctab,
467 edgelocnbr, edgelocsize,
468 edgeloctab, edgegsttab, edlotab);
470 env->globalInputAssertion(__FILE__, __LINE__,
"SCOTCH_dgraphBuild",
474 SCOTCH_Num *partloctab =
new SCOTCH_Num[nVtx+1];
479 float *partsizes =
new float[numGlobalParts];
480 if (!solution->criteriaHasUniformPartSizes(0))
481 for (
size_t i=0; i<numGlobalParts; i++)
482 partsizes[i] = solution->getCriteriaPartSize(0, i);
484 for (
size_t i=0; i<numGlobalParts; i++)
485 partsizes[i] = 1.0 /
float(numGlobalParts);
489 SCOTCH_archInit(&archdat);
491 SCOTCH_Num velosum = 0;
492 SCOTCH_dgraphSize (gr, &velosum, NULL, NULL, NULL);
493 SCOTCH_Num *goalsizes =
new SCOTCH_Num[partnbr];
499 for (SCOTCH_Num i = 0; i < partnbr; i++)
500 goalsizes[i] = SCOTCH_Num(ceil(velosum * partsizes[i]));
503 SCOTCH_archCmpltw(&archdat, partnbr, goalsizes);
506 ierr = SCOTCH_dgraphMap(gr, &archdat, &stratstr, partloctab);
508 env->globalInputAssertion(__FILE__, __LINE__,
"SCOTCH_dgraphMap",
511 SCOTCH_archExit(&archdat);
516 #ifdef SHOW_ZOLTAN2_SCOTCH_MEMORY
517 int me = env->comm_->getRank();
520 #ifdef HAVE_SCOTCH_ZOLTAN2_GETMEMORYMAX
522 size_t scotchBytes = SCOTCH_getMemoryMax();
523 std::cout <<
"Rank " << me <<
": Maximum bytes used by Scotch: ";
524 std::cout << scotchBytes << std::endl;
529 SCOTCH_dgraphExit(gr);
531 SCOTCH_stratExit(&stratstr);
535 ArrayRCP<part_t> partList;
540 solution->setParts(partList);
542 env->memory(
"Zoltan2-Scotch: After creating solution");
548 if (nVwgts)
delete [] velotab;
549 if (nEwgts)
delete [] edlotab;
551 #else // DO NOT HAVE MPI
559 ArrayView<const gno_t> vtxID;
560 ArrayView<StridedData<lno_t, scalar_t> > vwgts;
561 size_t nVtx = model->getVertexList(vtxID, vwgts);
563 ArrayRCP<part_t> partList(
new part_t[nVtx], 0, nVtx,
true);
564 for (
size_t i = 0; i < nVtx; i++) partList[i] = 0;
566 solution->setParts(partList);
568 #endif // DO NOT HAVE MPI
581 template <
typename Adapter>
582 void AlgPTScotch<Adapter>::scale_weights(
584 StridedData<typename Adapter::lno_t, typename Adapter::scalar_t> &fwgts,
588 const double INT_EPSILON = 1e-5;
590 SCOTCH_Num nonint, nonint_local = 0;
591 double sum_wgt, sum_wgt_local = 0.;
592 double max_wgt, max_wgt_local = 0.;
596 for (
size_t i = 0; i < n; i++) {
597 double fw = double(fwgts[i]);
599 SCOTCH_Num tmp = (SCOTCH_Num) floor(fw + .5);
600 if (fabs((
double)tmp-fw) > INT_EPSILON) {
605 if (fw > max_wgt_local) max_wgt_local = fw;
608 Teuchos::reduceAll<int,SCOTCH_Num>(*problemComm, Teuchos::REDUCE_MAX, 1,
609 &nonint_local, &nonint);
610 Teuchos::reduceAll<int,double>(*problemComm, Teuchos::REDUCE_SUM, 1,
611 &sum_wgt_local, &sum_wgt);
612 Teuchos::reduceAll<int,double>(*problemComm, Teuchos::REDUCE_MAX, 1,
613 &max_wgt_local, &max_wgt);
616 const double max_wgt_sum = double(SCOTCH_NUMMAX/8);
620 if (nonint || (max_wgt <= INT_EPSILON) || (sum_wgt > max_wgt_sum)) {
622 if (sum_wgt != 0.) scale = max_wgt_sum/sum_wgt;
626 for (
size_t i = 0; i < n; i++)
627 iwgts[i] = (SCOTCH_Num) ceil(
double(fwgts[i])*scale);
631 template <
typename Adapter>
632 int AlgPTScotch<Adapter>::setStrategy(SCOTCH_Strat * c_strat_ptr,
const ParameterList &pList,
int procRank) {
634 bool bPrintOutput =
false;
635 const Teuchos::ParameterEntry *pe;
638 pe = pList.getEntryPtr(
"scotch_verbose");
640 bPrintOutput = pe->getValue(&bPrintOutput);
645 bool scotch_ordering_default =
true;
646 pe = pList.getEntryPtr(
"scotch_ordering_default");
648 scotch_ordering_default = pe->getValue(&scotch_ordering_default);
652 "Scotch: Ordering default setting (parameter: scotch_ordering_default): "
653 << (scotch_ordering_default ?
"True" :
"False" ) << std::endl;
659 if (scotch_ordering_default) {
661 int scotch_level = 0;
662 pe = pList.getEntryPtr(
"scotch_level");
664 scotch_level = pe->getValue(&scotch_level);
667 std::cout <<
"Scotch: Ordering level (parameter: scotch_level): " <<
668 scotch_level << std::endl;
672 double scotch_imbalance_ratio = 0.2;
673 pe = pList.getEntryPtr(
"scotch_imbalance_ratio");
675 scotch_imbalance_ratio = pe->getValue(&scotch_imbalance_ratio);
678 std::cout <<
"Scotch: Ordering dissection imbalance ratio "
679 "(parameter: scotch_imbalance_ratio): "
680 << scotch_imbalance_ratio << std::endl;
683 SCOTCH_stratInit(c_strat_ptr);
685 ierr = SCOTCH_stratGraphOrderBuild( c_strat_ptr,
686 SCOTCH_STRATLEVELMAX | SCOTCH_STRATLEVELMIN |
687 SCOTCH_STRATLEAFSIMPLE | SCOTCH_STRATSEPASIMPLE,
688 scotch_level, scotch_imbalance_ratio);
692 std::string scotch_ordering_strategy_string(
"");
693 pe = pList.getEntryPtr(
"scotch_ordering_strategy");
695 scotch_ordering_strategy_string =
696 pe->getValue(&scotch_ordering_strategy_string);
699 std::cout <<
"Scotch ordering strategy"
700 " (parameter: scotch_ordering_strategy): " <<
701 scotch_ordering_strategy_string << std::endl;
704 SCOTCH_stratInit(c_strat_ptr);
705 ierr = SCOTCH_stratGraphOrder( c_strat_ptr,
706 scotch_ordering_strategy_string.c_str());
712 template <
typename Adapter>
714 const RCP<GlobalOrderingSolution<gno_t> > &solution) {
715 throw std::logic_error(
"AlgPTScotch does not yet support global ordering.");
718 template <
typename Adapter>
720 const RCP<LocalOrderingSolution<lno_t> > &solution) {
727 int me = problemComm->getRank();
728 const ParameterList &pl = env->getParameters();
729 const Teuchos::ParameterEntry *pe;
731 bool isVerbose =
false;
732 pe = pl.getEntryPtr(
"scotch_verbose");
734 isVerbose = pe->getValue(&isVerbose);
737 this->buildModel(
true);
738 if (isVerbose && me==0) {
739 std::cout <<
"Built local graph model." << std::endl;
743 SCOTCH_Strat c_strat_ptr;
744 SCOTCH_Graph c_graph_ptr;
747 ierr = SCOTCH_graphInit( &c_graph_ptr);
749 throw std::runtime_error(
"Failed to initialize Scotch graph!");
750 }
else if (isVerbose && me == 0) {
751 std::cout <<
"Initialized Scotch graph." << std::endl;
755 ArrayView<const gno_t> vtxID;
756 ArrayView<StridedData<lno_t, scalar_t> > vwgts;
757 size_t nVtx = model->getVertexList(vtxID, vwgts);
758 SCOTCH_Num vertnbr=0;
762 ArrayView<const gno_t> edgeIds;
763 ArrayView<const offset_t> offsets;
764 ArrayView<StridedData<lno_t, scalar_t> > ewgts;
766 size_t nEdge = model->getEdgeList(edgeIds, offsets, ewgts);
767 SCOTCH_Num edgenbr=0;
777 SCOTCH_Num *vendtab = NULL;
780 SCOTCH_Num *velotab = NULL;
781 SCOTCH_Num *vlbltab = NULL;
782 SCOTCH_Num *edlotab = NULL;
784 int nVwgts = model->getNumWeightsPerVertex();
785 int nEwgts = model->getNumWeightsPerEdge();
786 if (nVwgts > 1 && me == 0) {
787 std::cerr <<
"Warning: NumWeightsPerVertex is " << nVwgts
788 <<
" but Scotch allows only one weight. "
789 <<
" Zoltan2 will use only the first weight per vertex."
792 if (nEwgts > 1 && me == 0) {
793 std::cerr <<
"Warning: NumWeightsPerEdge is " << nEwgts
794 <<
" but Scotch allows only one weight. "
795 <<
" Zoltan2 will use only the first weight per edge."
800 velotab =
new SCOTCH_Num[nVtx+1];
802 scale_weights(nVtx, vwgts[0], velotab);
806 edlotab =
new SCOTCH_Num[nEdge+1];
808 scale_weights(nEdge, ewgts[0], edlotab);
814 ierr = SCOTCH_graphBuild( &c_graph_ptr, baseval,
815 vertnbr, verttab, vendtab, velotab, vlbltab,
816 edgenbr, edgetab, edlotab);
818 throw std::runtime_error(
"Failed to build Scotch graph!");
819 }
else if (isVerbose && me == 0) {
820 std::cout <<
"Built Scotch graph." << std::endl;
823 ierr = SCOTCH_graphCheck(&c_graph_ptr);
825 throw std::runtime_error(
"Graph is inconsistent!");
826 }
else if (isVerbose && me == 0) {
827 std::cout <<
"Graph is consistent." << std::endl;
831 ierr = AlgPTScotch<Adapter>::setStrategy(&c_strat_ptr, pl, me);
834 throw std::runtime_error(
"Can't build strategy!");
835 }
else if (isVerbose && me == 0) {
836 std::cout <<
"Graphing strategy built." << std::endl;
843 SCOTCH_Num *rangetab;
846 if (TPL_Traits<lno_t, SCOTCH_Num>::OK_TO_CAST()) {
847 permtab =
reinterpret_cast<SCOTCH_Num*
>(solution->getPermutationView(
false));
848 peritab =
reinterpret_cast<SCOTCH_Num*
>(solution->getPermutationView(
true));
849 rangetab =
reinterpret_cast<SCOTCH_Num*
>(solution->getSeparatorRangeView());
850 treetab =
reinterpret_cast<SCOTCH_Num*
>(solution->getSeparatorTreeView());
853 permtab =
new SCOTCH_Num[nVtx];
854 peritab =
new SCOTCH_Num[nVtx];
855 rangetab =
new SCOTCH_Num[nVtx+1];
856 treetab =
new SCOTCH_Num[nVtx];
859 ierr = SCOTCH_graphOrder(&c_graph_ptr, &c_strat_ptr, permtab, peritab,
860 &cblk, rangetab, treetab);
862 throw std::runtime_error(
"Could not compute ordering!!");
863 }
else if(isVerbose && me == 0) {
864 std::cout <<
"Ordering computed." << std::endl;
869 solution->setNumSeparatorBlocks(nSepBlocks);
871 if (!TPL_Traits<lno_t, SCOTCH_Num>::OK_TO_CAST()) {
873 const ArrayRCP<lno_t> arv_perm = solution->getPermutationRCP(
false);
874 for (
size_t i = 0; i < nVtx; i++)
875 TPL_Traits<lno_t, SCOTCH_Num>::ASSIGN(arv_perm[i], permtab[i]);
878 const ArrayRCP<lno_t> arv_peri = solution->getPermutationRCP(
true);
879 for (
size_t i = 0; i < nVtx; i++)
880 TPL_Traits<lno_t, SCOTCH_Num>::ASSIGN(arv_peri[i], peritab[i]);
883 const ArrayRCP<lno_t> arv_range = solution->getSeparatorRangeRCP();
884 for (lno_t i = 0; i <= nSepBlocks; i++)
885 TPL_Traits<lno_t, SCOTCH_Num>::ASSIGN(arv_range[i], rangetab[i]);
888 const ArrayRCP<lno_t> arv_tree = solution->getSeparatorTreeRCP();
889 for (lno_t i = 0; i < nSepBlocks; i++)
890 TPL_Traits<lno_t, SCOTCH_Num>::ASSIGN(arv_tree[i], treetab[i]);
894 solution->setHaveSeparator(
true);
901 if (nVwgts)
delete [] velotab;
902 if (nEwgts)
delete [] edlotab;
904 SCOTCH_stratExit(&c_strat_ptr);
905 SCOTCH_graphFree(&c_graph_ptr);
907 if (isVerbose && problemComm->getRank() == 0) {
908 std::cout <<
"Freed Scotch graph!" << std::endl;
915 #endif // HAVE_ZOLTAN2_SCOTCH
use columns as graph vertices
Zoltan2::BaseAdapter< userTypes_t > base_adapter_t
Adapter::base_adapter_t base_adapter_t
use mesh nodes as vertices
virtual void partition(const RCP< PartitioningSolution< Adapter > > &)
Partitioning method.
fast typical checks for valid arguments
static RCP< Teuchos::BoolParameterEntryValidator > getBoolValidator()
Exists to make setting up validators less cluttered.
algorithm requires consecutive ids
std::bitset< NUM_MODEL_FLAGS > modelFlag_t
model must symmetrize input
Defines the OrderingSolution class.
model must symmetrize input
Defines the PartitioningSolution class.
static RCP< Teuchos::AnyNumberParameterEntryValidator > getAnyDoubleValidator()
Exists to make setting up validators less cluttered.
static void SAVE_ARRAYRCP(ArrayRCP< first_t > *a, second_t *b, size_t size)
virtual int globalOrder(const RCP< GlobalOrderingSolution< gno_t > > &)
Ordering method.
sub-steps, each method's entry and exit
SparseMatrixAdapter_t::part_t part_t
use matrix rows as graph vertices
algorithm requires no self edges
static void getScotchParameters(Teuchos::ParameterList &pl)
Adapter::scalar_t scalar_t
use nonzeros as graph vertices
AlgPTScotch(const RCP< const Environment > &, const RCP< const Comm< int > > &, const RCP< const base_adapter_t > &)
Algorithm defines the base class for all algorithms.
static void ASSIGN(first_t &a, second_t b)
static void getValidParameters(ParameterList &pl)
Set up validators specific to this algorithm.
Traits class to handle conversions between gno_t/lno_t and TPL data types (e.g., ParMETIS's idx_t...
use mesh elements as vertices
static void ASSIGN_ARRAY(first_t **a, ArrayView< second_t > &b)
Defines the GraphModel interface.
virtual int localOrder(const RCP< LocalOrderingSolution< lno_t > > &)
Ordering method.
A gathering of useful namespace methods.
static void DELETE_ARRAY(first_t **a)
model represents graph within only one rank
Zoltan2::BasicUserTypes< zscalar_t, zlno_t, zgno_t > user_t