10 #ifndef _ZOLTAN2_ALGSCOTCH_HPP_
11 #define _ZOLTAN2_ALGSCOTCH_HPP_
32 pl.set(
"scotch_verbose",
false,
"verbose output",
35 RCP<Teuchos::EnhancedNumberValidator<int>> scotch_level_Validator =
36 Teuchos::rcp(
new Teuchos::EnhancedNumberValidator<int>(0, 1000, 1, 0) );
37 pl.set(
"scotch_level", 0,
"scotch ordering - Level of the subgraph in the "
38 "separators tree for the initial graph at the root of the tree",
39 scotch_level_Validator);
41 pl.set(
"scotch_imbalance_ratio", 0.2,
"scotch ordering - Dissection "
45 pl.set(
"scotch_ordering_default",
true,
"use default scotch ordering "
48 pl.set(
"scotch_ordering_strategy",
"",
"scotch ordering - Dissection "
54 #ifndef HAVE_ZOLTAN2_SCOTCH
61 template <
typename Adapter>
71 const RCP<
const Comm<int> > &,
72 const RCP<const base_adapter_t> &
75 throw std::runtime_error(
76 "BUILD ERROR: Scotch requested but not compiled into Zoltan2.\n"
77 "Please set CMake flag Zoltan2_ENABLE_Scotch:BOOL=ON.");
93 #ifdef HAVE_ZOLTAN2_SCOTCH
100 #ifndef HAVE_ZOLTAN2_MPI
103 #include "ptscotch.h"
107 #ifdef SHOW_ZOLTAN2_SCOTCH_MEMORY
120 #ifdef HAVE_SCOTCH_GETMEMORYMAX
122 extern size_t SCOTCH_getMemoryMax();
125 #error "Either turn off ZOLTAN2_ENABLE_SCOTCH_MEMORY_REPORT in cmake configure, or see SHOW_ZOLTAN2_SCOTCH_MEMORY comment in Zoltan2_AlgScotch.hpp"
126 #endif // HAVE_SCOTCH_GETMEMORYMAX
127 #endif // SHOW_ZOLTAN2_SCOTCH_MEMORY
129 template <
typename Adapter>
130 class AlgPTScotch :
public Algorithm<Adapter>
135 typedef GraphModel<typename Adapter::base_adapter_t> graphModel_t;
138 typedef typename Adapter::offset_t offset_t;
139 typedef typename Adapter::scalar_t
scalar_t;
142 typedef typename Adapter::userCoord_t userCoord_t;
174 const RCP<
const Comm<int> > &problemComm__,
175 const RCP<
const IdentifierAdapter<user_t> > &adapter__) :
176 env(env__), problemComm(problemComm__),
177 #ifdef HAVE_ZOLTAN2_MPI
178 mpicomm(Teuchos::getRawMpiComm(*problemComm__)),
182 std::string errStr =
"cannot build GraphModel from IdentifierAdapter, ";
183 errStr +=
"Scotch requires Graph, Matrix, or Mesh Adapter";
184 throw std::runtime_error(errStr);
188 const RCP<
const Comm<int> > &problemComm__,
189 const RCP<
const VectorAdapter<user_t> > &adapter__) :
190 env(env__), problemComm(problemComm__),
191 #ifdef HAVE_ZOLTAN2_MPI
192 mpicomm(Teuchos::getRawMpiComm(*problemComm__)),
196 std::string errStr =
"cannot build GraphModel from IdentifierAdapter, ";
197 errStr +=
"Scotch requires Graph, Matrix, or Mesh Adapter";
198 throw std::runtime_error(errStr);
202 const RCP<
const Comm<int> > &problemComm__,
203 const RCP<
const GraphAdapter<user_t, userCoord_t> > &adapter__) :
204 env(env__), problemComm(problemComm__),
205 #ifdef HAVE_ZOLTAN2_MPI
206 mpicomm(Teuchos::getRawMpiComm(*problemComm__)),
208 adapter(adapter__), model_flags()
210 this->model_flags.reset();
214 const RCP<
const Comm<int> > &problemComm__,
215 const RCP<
const MatrixAdapter<user_t, userCoord_t> > &adapter__) :
216 env(env__), problemComm(problemComm__),
217 #ifdef HAVE_ZOLTAN2_MPI
218 mpicomm(Teuchos::getRawMpiComm(*problemComm__)),
220 adapter(adapter__), model_flags()
222 this->model_flags.reset();
224 const ParameterList &pl = env->getParameters();
225 const Teuchos::ParameterEntry *pe;
227 std::string defString(
"default");
228 std::string objectOfInterest(defString);
229 pe = pl.getEntryPtr(
"objects_to_partition");
231 objectOfInterest = pe->getValue<std::string>(&objectOfInterest);
233 if (objectOfInterest == defString ||
234 objectOfInterest == std::string(
"matrix_rows") )
236 else if (objectOfInterest == std::string(
"matrix_columns"))
238 else if (objectOfInterest == std::string(
"matrix_nonzeros"))
243 const RCP<
const Comm<int> > &problemComm__,
244 const RCP<
const MeshAdapter<user_t> > &adapter__) :
245 env(env__), problemComm(problemComm__),
246 #ifdef HAVE_ZOLTAN2_MPI
247 mpicomm(Teuchos::getRawMpiComm(*problemComm__)),
249 adapter(adapter__), model_flags()
251 this->model_flags.reset();
253 const ParameterList &pl = env->getParameters();
254 const Teuchos::ParameterEntry *pe;
256 std::string defString(
"default");
257 std::string objectOfInterest(defString);
258 pe = pl.getEntryPtr(
"objects_to_partition");
260 objectOfInterest = pe->getValue<std::string>(&objectOfInterest);
262 if (objectOfInterest == defString ||
263 objectOfInterest == std::string(
"mesh_nodes") )
265 else if (objectOfInterest == std::string(
"mesh_elements"))
276 void partition(
const RCP<PartitioningSolution<Adapter> > &solution);
278 int localOrder(
const RCP<LocalOrderingSolution<lno_t> > &solution);
279 int globalOrder(
const RCP<GlobalOrderingSolution<gno_t> > &solution);
283 const RCP<const Environment> env;
284 const RCP<const Comm<int> > problemComm;
285 #ifdef HAVE_ZOLTAN2_MPI
286 const MPI_Comm mpicomm;
288 const RCP<const base_adapter_t> adapter;
290 RCP<graphModel_t > model;
292 void buildModel(
bool isLocal);
293 void scale_weights(
size_t n, StridedData<lno_t, scalar_t> &fwgts,
295 static int setStrategy(SCOTCH_Strat * c_strat_ptr,
const ParameterList &pList,
int procRank);
299 template <
typename Adapter>
300 void AlgPTScotch<Adapter>::buildModel(
bool isLocal) {
302 const ParameterList &pl = env->getParameters();
303 const Teuchos::ParameterEntry *pe;
305 std::string defString(
"default");
306 std::string symParameter(defString);
307 pe = pl.getEntryPtr(
"symmetrize_graph");
309 symParameter = pe->getValue<std::string>(&symParameter);
310 if (symParameter == std::string(
"transpose"))
312 else if (symParameter == std::string(
"bipartite"))
315 bool sgParameter =
false;
316 pe = pl.getEntryPtr(
"subset_graph");
318 sgParameter = pe->getValue(&sgParameter);
330 this->model = rcp(
new graphModel_t(this->adapter,
337 template <
typename Adapter>
339 const RCP<PartitioningSolution<Adapter> > &solution
343 this->buildModel(
false);
345 size_t numGlobalParts = solution->getTargetGlobalNumberOfParts();
347 SCOTCH_Num partnbr=0;
350 #ifdef HAVE_ZOLTAN2_MPI
352 int me = problemComm->getRank();
354 const SCOTCH_Num baseval = 0;
357 SCOTCH_Strat stratstr;
359 SCOTCH_stratInit(&stratstr);
362 SCOTCH_Dgraph *gr = SCOTCH_dgraphAlloc();
363 ierr = SCOTCH_dgraphInit(gr, mpicomm);
365 env->globalInputAssertion(__FILE__, __LINE__,
"SCOTCH_dgraphInit",
369 ArrayView<const gno_t> vtxID;
370 ArrayView<StridedData<lno_t, scalar_t> > vwgts;
371 size_t nVtx = model->getVertexList(vtxID, vwgts);
372 SCOTCH_Num vertlocnbr=0;
374 SCOTCH_Num vertlocmax = vertlocnbr;
377 ArrayView<const gno_t> edgeIds;
378 ArrayView<const offset_t> offsets;
379 ArrayView<StridedData<lno_t, scalar_t> > ewgts;
381 size_t nEdge = model->getEdgeList(edgeIds, offsets, ewgts);
383 SCOTCH_Num edgelocnbr=0;
385 const SCOTCH_Num edgelocsize = edgelocnbr;
387 SCOTCH_Num *vertloctab;
390 SCOTCH_Num *edgeloctab;
394 SCOTCH_Num *vendloctab = NULL;
395 SCOTCH_Num *vlblloctab = NULL;
396 SCOTCH_Num *edgegsttab = NULL;
399 SCOTCH_Num *velotab = NULL;
400 SCOTCH_Num *edlotab = NULL;
402 int nVwgts = model->getNumWeightsPerVertex();
403 int nEwgts = model->getNumWeightsPerEdge();
404 if (nVwgts > 1 && me == 0) {
405 std::cerr <<
"Warning: NumWeightsPerVertex is " << nVwgts
406 <<
" but Scotch allows only one weight. "
407 <<
" Zoltan2 will use only the first weight per vertex."
410 if (nEwgts > 1 && me == 0) {
411 std::cerr <<
"Warning: NumWeightsPerEdge is " << nEwgts
412 <<
" but Scotch allows only one weight. "
413 <<
" Zoltan2 will use only the first weight per edge."
418 velotab =
new SCOTCH_Num[nVtx+1];
420 scale_weights(nVtx, vwgts[0], velotab);
424 edlotab =
new SCOTCH_Num[nEdge+1];
426 scale_weights(nEdge, ewgts[0], edlotab);
430 ierr = SCOTCH_dgraphBuild(gr, baseval, vertlocnbr, vertlocmax,
431 vertloctab, vendloctab, velotab, vlblloctab,
432 edgelocnbr, edgelocsize,
433 edgeloctab, edgegsttab, edlotab);
435 env->globalInputAssertion(__FILE__, __LINE__,
"SCOTCH_dgraphBuild",
439 SCOTCH_Num *partloctab =
new SCOTCH_Num[nVtx+1];
444 float *partsizes =
new float[numGlobalParts];
445 if (!solution->criteriaHasUniformPartSizes(0))
446 for (
size_t i=0; i<numGlobalParts; i++)
447 partsizes[i] = solution->getCriteriaPartSize(0, i);
449 for (
size_t i=0; i<numGlobalParts; i++)
450 partsizes[i] = 1.0 /
float(numGlobalParts);
454 SCOTCH_archInit(&archdat);
456 SCOTCH_Num velosum = 0;
457 SCOTCH_dgraphSize (gr, &velosum, NULL, NULL, NULL);
458 SCOTCH_Num *goalsizes =
new SCOTCH_Num[partnbr];
464 for (SCOTCH_Num i = 0; i < partnbr; i++)
465 goalsizes[i] = SCOTCH_Num(ceil(velosum * partsizes[i]));
468 SCOTCH_archCmpltw(&archdat, partnbr, goalsizes);
471 ierr = SCOTCH_dgraphMap(gr, &archdat, &stratstr, partloctab);
473 env->globalInputAssertion(__FILE__, __LINE__,
"SCOTCH_dgraphMap",
476 SCOTCH_archExit(&archdat);
481 #ifdef SHOW_ZOLTAN2_SCOTCH_MEMORY
482 int me = env->comm_->getRank();
485 #ifdef HAVE_SCOTCH_ZOLTAN2_GETMEMORYMAX
487 size_t scotchBytes = SCOTCH_getMemoryMax();
488 std::cout <<
"Rank " << me <<
": Maximum bytes used by Scotch: ";
489 std::cout << scotchBytes << std::endl;
494 SCOTCH_dgraphExit(gr);
496 SCOTCH_stratExit(&stratstr);
500 ArrayRCP<part_t> partList;
505 solution->setParts(partList);
507 env->memory(
"Zoltan2-Scotch: After creating solution");
513 if (nVwgts)
delete [] velotab;
514 if (nEwgts)
delete [] edlotab;
516 #else // DO NOT HAVE MPI
524 ArrayView<const gno_t> vtxID;
525 ArrayView<StridedData<lno_t, scalar_t> > vwgts;
526 size_t nVtx = model->getVertexList(vtxID, vwgts);
528 ArrayRCP<part_t> partList(
new part_t[nVtx], 0, nVtx,
true);
529 for (
size_t i = 0; i < nVtx; i++) partList[i] = 0;
531 solution->setParts(partList);
533 #endif // DO NOT HAVE MPI
546 template <
typename Adapter>
547 void AlgPTScotch<Adapter>::scale_weights(
549 StridedData<typename Adapter::lno_t, typename Adapter::scalar_t> &fwgts,
553 const double INT_EPSILON = 1e-5;
555 SCOTCH_Num nonint, nonint_local = 0;
556 double sum_wgt, sum_wgt_local = 0.;
557 double max_wgt, max_wgt_local = 0.;
561 for (
size_t i = 0; i < n; i++) {
562 double fw = double(fwgts[i]);
564 SCOTCH_Num tmp = (SCOTCH_Num) floor(fw + .5);
565 if (fabs((
double)tmp-fw) > INT_EPSILON) {
570 if (fw > max_wgt_local) max_wgt_local = fw;
573 Teuchos::reduceAll<int,SCOTCH_Num>(*problemComm, Teuchos::REDUCE_MAX, 1,
574 &nonint_local, &nonint);
575 Teuchos::reduceAll<int,double>(*problemComm, Teuchos::REDUCE_SUM, 1,
576 &sum_wgt_local, &sum_wgt);
577 Teuchos::reduceAll<int,double>(*problemComm, Teuchos::REDUCE_MAX, 1,
578 &max_wgt_local, &max_wgt);
581 const double max_wgt_sum = double(SCOTCH_NUMMAX/8);
585 if (nonint || (max_wgt <= INT_EPSILON) || (sum_wgt > max_wgt_sum)) {
587 if (sum_wgt != 0.) scale = max_wgt_sum/sum_wgt;
591 for (
size_t i = 0; i < n; i++)
592 iwgts[i] = (SCOTCH_Num) ceil(
double(fwgts[i])*scale);
596 template <
typename Adapter>
597 int AlgPTScotch<Adapter>::setStrategy(SCOTCH_Strat * c_strat_ptr,
const ParameterList &pList,
int procRank) {
599 bool bPrintOutput =
false;
600 const Teuchos::ParameterEntry *pe;
603 pe = pList.getEntryPtr(
"scotch_verbose");
605 bPrintOutput = pe->getValue(&bPrintOutput);
610 bool scotch_ordering_default =
true;
611 pe = pList.getEntryPtr(
"scotch_ordering_default");
613 scotch_ordering_default = pe->getValue(&scotch_ordering_default);
617 "Scotch: Ordering default setting (parameter: scotch_ordering_default): "
618 << (scotch_ordering_default ?
"True" :
"False" ) << std::endl;
624 if (scotch_ordering_default) {
626 int scotch_level = 0;
627 pe = pList.getEntryPtr(
"scotch_level");
629 scotch_level = pe->getValue(&scotch_level);
632 std::cout <<
"Scotch: Ordering level (parameter: scotch_level): " <<
633 scotch_level << std::endl;
637 double scotch_imbalance_ratio = 0.2;
638 pe = pList.getEntryPtr(
"scotch_imbalance_ratio");
640 scotch_imbalance_ratio = pe->getValue(&scotch_imbalance_ratio);
643 std::cout <<
"Scotch: Ordering dissection imbalance ratio "
644 "(parameter: scotch_imbalance_ratio): "
645 << scotch_imbalance_ratio << std::endl;
648 SCOTCH_stratInit(c_strat_ptr);
650 ierr = SCOTCH_stratGraphOrderBuild( c_strat_ptr,
651 SCOTCH_STRATLEVELMAX | SCOTCH_STRATLEVELMIN |
652 SCOTCH_STRATLEAFSIMPLE | SCOTCH_STRATSEPASIMPLE,
653 scotch_level, scotch_imbalance_ratio);
657 std::string scotch_ordering_strategy_string(
"");
658 pe = pList.getEntryPtr(
"scotch_ordering_strategy");
660 scotch_ordering_strategy_string =
661 pe->getValue(&scotch_ordering_strategy_string);
664 std::cout <<
"Scotch ordering strategy"
665 " (parameter: scotch_ordering_strategy): " <<
666 scotch_ordering_strategy_string << std::endl;
669 SCOTCH_stratInit(c_strat_ptr);
670 ierr = SCOTCH_stratGraphOrder( c_strat_ptr,
671 scotch_ordering_strategy_string.c_str());
677 template <
typename Adapter>
679 const RCP<GlobalOrderingSolution<gno_t> > &solution) {
680 throw std::logic_error(
"AlgPTScotch does not yet support global ordering.");
683 template <
typename Adapter>
685 const RCP<LocalOrderingSolution<lno_t> > &solution) {
692 int me = problemComm->getRank();
693 const ParameterList &pl = env->getParameters();
694 const Teuchos::ParameterEntry *pe;
696 bool isVerbose =
false;
697 pe = pl.getEntryPtr(
"scotch_verbose");
699 isVerbose = pe->getValue(&isVerbose);
702 this->buildModel(
true);
703 if (isVerbose && me==0) {
704 std::cout <<
"Built local graph model." << std::endl;
708 SCOTCH_Strat c_strat_ptr;
709 SCOTCH_Graph c_graph_ptr;
712 ierr = SCOTCH_graphInit( &c_graph_ptr);
714 throw std::runtime_error(
"Failed to initialize Scotch graph!");
715 }
else if (isVerbose && me == 0) {
716 std::cout <<
"Initialized Scotch graph." << std::endl;
720 ArrayView<const gno_t> vtxID;
721 ArrayView<StridedData<lno_t, scalar_t> > vwgts;
722 size_t nVtx = model->getVertexList(vtxID, vwgts);
723 SCOTCH_Num vertnbr=0;
727 ArrayView<const gno_t> edgeIds;
728 ArrayView<const offset_t> offsets;
729 ArrayView<StridedData<lno_t, scalar_t> > ewgts;
731 size_t nEdge = model->getEdgeList(edgeIds, offsets, ewgts);
732 SCOTCH_Num edgenbr=0;
742 SCOTCH_Num *vendtab = NULL;
745 SCOTCH_Num *velotab = NULL;
746 SCOTCH_Num *vlbltab = NULL;
747 SCOTCH_Num *edlotab = NULL;
749 int nVwgts = model->getNumWeightsPerVertex();
750 int nEwgts = model->getNumWeightsPerEdge();
751 if (nVwgts > 1 && me == 0) {
752 std::cerr <<
"Warning: NumWeightsPerVertex is " << nVwgts
753 <<
" but Scotch allows only one weight. "
754 <<
" Zoltan2 will use only the first weight per vertex."
757 if (nEwgts > 1 && me == 0) {
758 std::cerr <<
"Warning: NumWeightsPerEdge is " << nEwgts
759 <<
" but Scotch allows only one weight. "
760 <<
" Zoltan2 will use only the first weight per edge."
765 velotab =
new SCOTCH_Num[nVtx+1];
767 scale_weights(nVtx, vwgts[0], velotab);
771 edlotab =
new SCOTCH_Num[nEdge+1];
773 scale_weights(nEdge, ewgts[0], edlotab);
779 ierr = SCOTCH_graphBuild( &c_graph_ptr, baseval,
780 vertnbr, verttab, vendtab, velotab, vlbltab,
781 edgenbr, edgetab, edlotab);
783 throw std::runtime_error(
"Failed to build Scotch graph!");
784 }
else if (isVerbose && me == 0) {
785 std::cout <<
"Built Scotch graph." << std::endl;
788 ierr = SCOTCH_graphCheck(&c_graph_ptr);
790 throw std::runtime_error(
"Graph is inconsistent!");
791 }
else if (isVerbose && me == 0) {
792 std::cout <<
"Graph is consistent." << std::endl;
796 ierr = AlgPTScotch<Adapter>::setStrategy(&c_strat_ptr, pl, me);
799 throw std::runtime_error(
"Can't build strategy!");
800 }
else if (isVerbose && me == 0) {
801 std::cout <<
"Graphing strategy built." << std::endl;
808 SCOTCH_Num *rangetab;
811 if (TPL_Traits<lno_t, SCOTCH_Num>::OK_TO_CAST()) {
812 permtab =
reinterpret_cast<SCOTCH_Num*
>(solution->getPermutationView(
false));
813 peritab =
reinterpret_cast<SCOTCH_Num*
>(solution->getPermutationView(
true));
814 rangetab =
reinterpret_cast<SCOTCH_Num*
>(solution->getSeparatorRangeView());
815 treetab =
reinterpret_cast<SCOTCH_Num*
>(solution->getSeparatorTreeView());
818 permtab =
new SCOTCH_Num[nVtx];
819 peritab =
new SCOTCH_Num[nVtx];
820 rangetab =
new SCOTCH_Num[nVtx+1];
821 treetab =
new SCOTCH_Num[nVtx];
824 ierr = SCOTCH_graphOrder(&c_graph_ptr, &c_strat_ptr, permtab, peritab,
825 &cblk, rangetab, treetab);
827 throw std::runtime_error(
"Could not compute ordering!!");
828 }
else if(isVerbose && me == 0) {
829 std::cout <<
"Ordering computed." << std::endl;
834 solution->setNumSeparatorBlocks(nSepBlocks);
836 if (!TPL_Traits<lno_t, SCOTCH_Num>::OK_TO_CAST()) {
838 const ArrayRCP<lno_t> arv_perm = solution->getPermutationRCP(
false);
839 for (
size_t i = 0; i < nVtx; i++)
840 TPL_Traits<lno_t, SCOTCH_Num>::ASSIGN(arv_perm[i], permtab[i]);
843 const ArrayRCP<lno_t> arv_peri = solution->getPermutationRCP(
true);
844 for (
size_t i = 0; i < nVtx; i++)
845 TPL_Traits<lno_t, SCOTCH_Num>::ASSIGN(arv_peri[i], peritab[i]);
848 const ArrayRCP<lno_t> arv_range = solution->getSeparatorRangeRCP();
849 for (
lno_t i = 0; i <= nSepBlocks; i++)
850 TPL_Traits<lno_t, SCOTCH_Num>::ASSIGN(arv_range[i], rangetab[i]);
853 const ArrayRCP<lno_t> arv_tree = solution->getSeparatorTreeRCP();
854 for (
lno_t i = 0; i < nSepBlocks; i++)
855 TPL_Traits<lno_t, SCOTCH_Num>::ASSIGN(arv_tree[i], treetab[i]);
859 solution->setHaveSeparator(
true);
866 if (nVwgts)
delete [] velotab;
867 if (nEwgts)
delete [] edlotab;
869 SCOTCH_stratExit(&c_strat_ptr);
870 SCOTCH_graphFree(&c_graph_ptr);
872 if (isVerbose && problemComm->getRank() == 0) {
873 std::cout <<
"Freed Scotch graph!" << std::endl;
880 #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
map_t::global_ordinal_type gno_t
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.
map_t::local_ordinal_type lno_t
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