60 using Teuchos::ArrayRCP;
70 template<
class idInput_t>
71 void doTest(RCP<
const Comm<int> > comm,
int numLocalObj,
72 int nWeights,
int numLocalParts,
bool givePartSizes,
bool useDegreeAsWeight=
false);
80 typedef Tpetra::CrsGraph<zlno_t, zgno_t, znode_t>
tcrsGraph_t;
85 template<
class idInput_t>
void runTestSuite(RCP<
const Comm<int> > comm,
bool bCanTestDegreeAsWeights) {
86 doTest<idInput_t>(comm, 10, 0, -1,
false);
87 doTest<idInput_t>(comm, 10, 0, 1,
false);
88 doTest<idInput_t>(comm, 10, 0, 1,
true);
89 doTest<idInput_t>(comm, 10, 1, 1,
false);
90 doTest<idInput_t>(comm, 10, 1, 1,
true);
91 doTest<idInput_t>(comm, 10, 2, 1,
false);
92 doTest<idInput_t>(comm, 10, 2, 1,
true);
93 doTest<idInput_t>(comm, 10, 1, 2,
true);
94 doTest<idInput_t>(comm, 10, 1, 2,
false);
95 doTest<idInput_t>(comm, 10, 1, -1,
false);
96 doTest<idInput_t>(comm, 10, 1, -1,
true);
97 doTest<idInput_t>(comm, 10, 2, -1,
false);
99 if(bCanTestDegreeAsWeights) {
100 doTest<idInput_t>(comm, 10, 1, 1,
true,
true);
104 int main(
int narg,
char *arg[])
106 Tpetra::ScopeGuard tscope(&narg, &arg);
107 Teuchos::RCP<const Teuchos::Comm<int> > comm = Tpetra::getDefaultComm();
109 int rank = comm->getRank();
112 runTestSuite<basic_idInput_t>(comm,
false);
117 runTestSuite<graph_idInput_t>(comm,
true);
121 std::cout <<
"PASS" << std::endl;
130 template<
class idInput_t>
133 int nWeights,
int original_numLocalParts,
bool givePartSizes) {
135 int rank = comm->getRank();
139 object_count_imbalance = metricObject->getObjectCountImbalance();
141 cout <<
"Object imbalance: " << object_count_imbalance << endl;
144 catch (std::exception &e){
151 for (
int i=0; i < nWeights; i++){
152 zscalar_t imb = metricObject->getWeightImbalance(i);
154 cout <<
"Weight " << i <<
" imbalance: " << imb << endl;
158 catch (std::exception &e){
161 if (!fail && nWeights > 1){
163 zscalar_t imb = metricObject->getNormedImbalance();
165 cout <<
"Normed weight imbalance: " << imb << endl;
168 catch (std::exception &e){
176 template<
class idInput_t>
179 int nWeights,
int original_numLocalParts,
bool givePartSizes) {
180 throw std::logic_error(
"evaluate_result not implemented.");
185 RCP<Zoltan2::EvaluatePartition<graph_idInput_t>> metricObject,
int numLocalObj,
186 int nWeights,
int original_numLocalParts,
bool givePartSizes) {
188 int rank = comm->getRank();
190 int total_edge_cut = -1;
194 total_edge_cut =
static_cast<int>(metricObject->getTotalEdgeCut());
196 cout <<
"Total Edge Cut: " << total_edge_cut << endl;
199 catch (std::exception &e){
204 int max_edge_cut = -1;
206 max_edge_cut =
static_cast<int>(metricObject->getMaxEdgeCut());
208 cout <<
"Max Edge Cut: " << max_edge_cut << endl;
211 catch (std::exception &e){
216 int total_messages = -1;
218 total_messages =
static_cast<int>(metricObject->getTotalMessages());
220 cout <<
"Total Messages: " << total_messages << endl;
223 catch (std::exception &e){
228 int max_messages = -1;
230 max_messages =
static_cast<int>(metricObject->getMaxMessages());
232 cout <<
"Max Messages: " << max_messages << endl;
235 catch (std::exception &e){
251 int num_procs = comm->getSize();
252 int expected_total_edge_cuts = (num_procs == 1) ? 0 :
253 (2 * numLocalObj) + ((num_procs-2) * numLocalObj * 2);
255 "getTotalEdgeCut is not the expected ", 1);
262 int expected_max_edge_cuts = (num_procs == 1) ? 0 :
263 (num_procs == 2) ? numLocalObj : numLocalObj * 2;
265 "getMaxEdgeCut is not the expected value", 1);
269 int expected_total_messages = expected_total_edge_cuts / numLocalObj;
271 "getTotalMessages is not the expected value", 1);
275 int expected_max_messages = expected_max_edge_cuts / numLocalObj;
277 "getMaxMessages is not the expected value", 1);
280 numLocalObj, nWeights, original_numLocalParts, givePartSizes);
287 RCP<Zoltan2::EvaluatePartition<basic_idInput_t>> metricObject,
int numLocalObj,
288 int nWeights,
int original_numLocalParts,
bool givePartSizes) {
290 numLocalObj, nWeights, original_numLocalParts, givePartSizes);
293 template<
class idInput_t>
295 int numLocalObj,
zgno_t *myGids,
296 std::vector<const zscalar_t *> &
weights,
297 std::vector<int> & strides,
298 bool useDegreeAsWeight) {
299 throw std::logic_error(
"create_adapter not implemented.");
304 int numLocalObj,
zgno_t *myGids,
305 std::vector<const zscalar_t *> &
weights,
306 std::vector<int> & strides,
307 bool useDegreeAsWeight) {
309 typedef Tpetra::Map<zlno_t, zgno_t>
map_t;
310 typedef Tpetra::CrsMatrix<zscalar_t, zlno_t, zgno_t> matrix_t;
312 const zgno_t gNvtx = numLocalObj * comm->getSize();
313 const Teuchos::ArrayView<const zgno_t> indexList(myGids, numLocalObj);
314 Teuchos::RCP<const map_t> map = rcp(
new map_t(gNvtx, indexList, 0, comm));
317 size_t maxRowLen = 2;
318 Teuchos::RCP<matrix_t> matrix = rcp(
new matrix_t(map, maxRowLen));
331 Teuchos::Array<zgno_t> col(2);
332 Teuchos::Array<zscalar_t> val(2); val[0] = 1.; val[1] = 1.;
333 zgno_t first_id = map->getMinAllGlobalIndex();
334 zgno_t last_id = map->getMaxAllGlobalIndex();
335 for (
zlno_t i = 0; i < numLocalObj; i++) {
336 zgno_t id = map->getGlobalElement(i);
339 matrix->insertGlobalValues(
id, col(), val());
342 matrix->fillComplete(map, map);
344 size_t nVwgts =
weights.size();
348 for (
size_t j = 0; j < nVwgts; j++) {
353 if(useDegreeAsWeight) {
354 for (
size_t j = 0; j < nVwgts; j++) {
364 int numLocalObj,
zgno_t *myGids,
365 std::vector<const zscalar_t *> &
weights,
366 std::vector<int> & strides,
367 bool useDegreeAsWeight) {
373 template<
class idInput_t>
374 void doTest(RCP<
const Comm<int> > comm,
int numLocalObj,
375 int nWeights,
int numLocalParts,
bool givePartSizes,
bool useDegreeAsWeight)
381 int rank = comm->getRank();
383 int original_numLocalParts = numLocalParts;
385 int nprocs = comm->getSize();
388 bool testEmptyParts = (numLocalParts < 1);
389 int numGlobalParts = 0;
392 numGlobalParts = nprocs / 2;
393 if (numGlobalParts >= 1)
394 numLocalParts = (rank < numGlobalParts ? 1 : 0);
397 testEmptyParts =
false;
401 numGlobalParts = nprocs * numLocalParts;
406 <<
"Test: number of weights " << nWeights
407 <<
", desired number of parts " << numGlobalParts
408 <<
", calculated num local parts " << numLocalParts
409 <<
", original num local parts " << original_numLocalParts
410 << (givePartSizes ?
", with differing part sizes." :
411 ", with uniform part sizes.")
412 <<
", Number of procs " << nprocs
413 <<
", each with " << numLocalObj <<
" objects, part = rank."
414 << (useDegreeAsWeight ?
", use degree as weights" :
"")
420 Teuchos::ParameterList pl(
"test list");
421 pl.set(
"num_local_parts", numLocalParts);
423 RCP<const Zoltan2::Environment> env =
429 for (
int i=0, x=rank*numLocalObj; i < numLocalObj; i++, x++){
436 int partSizeDim = (givePartSizes ? (nWeights ? nWeights : 1) : 0);
437 ArrayRCP<ArrayRCP<part_t> > ids(partSizeDim);
438 ArrayRCP<ArrayRCP<zscalar_t> > sizes(partSizeDim);
440 if (givePartSizes && numLocalParts > 0){
441 part_t *myParts =
new part_t [numLocalParts];
442 myParts[0] = rank * numLocalParts;
443 for (
int i=1; i < numLocalParts; i++)
444 myParts[i] = myParts[i-1] + 1;
445 ArrayRCP<part_t> partNums(myParts, 0, numLocalParts,
true);
448 if (sizeFactor < 0) sizeFactor *= -1;
451 for (
int dim=0; dim < partSizeDim; dim++){
453 for (
int i=0; i < numLocalParts; i++)
454 psizes[i] = sizeFactor;
455 sizes[dim] = arcp(psizes, 0, numLocalParts,
true);
462 std::vector<const zscalar_t *>
weights;
463 std::vector<int> strides;
465 int len = numLocalObj*nWeights;
466 ArrayRCP<zscalar_t> wgtBuf;
471 wgtBuf = arcp(wgts, 0, len,
true);
472 for (
int i=0; i < len; i++)
476 for (
int i=0; i < nWeights; i++, wgts+=numLocalObj)
477 weights.push_back(wgts);
482 ia = create_adapter<idInput_t>(comm, numLocalObj, myGids,
weights, strides, useDegreeAsWeight);
484 catch (std::exception &e){
492 RCP<Zoltan2::PartitioningSolution<idInput_t> > solution;
498 ids.view(0,partSizeDim), sizes.view(0,partSizeDim)));
501 env, comm, nWeights));
503 catch (std::exception &e){
511 part_t *partNum =
new part_t [numLocalObj];
512 ArrayRCP<part_t> partAssignment(partNum, 0, numLocalObj,
true);
513 for (
int i=0; i < numLocalObj; i++)
516 solution->setParts(partAssignment);
520 RCP<quality_t> metricObject;
523 metricObject = rcp(
new quality_t(ia, &pl, comm, solution.getRawPtr()));
525 catch (std::exception &e){
532 metricObject->printMetrics(cout);
535 catch (std::exception &e){
541 evaluate_adapter_results<idInput_t>(comm, metricObject,
542 numLocalObj, nWeights, original_numLocalParts, givePartSizes);
idInput_t * create_adapter(RCP< const Comm< int > > comm, int numLocalObj, zgno_t *myGids, std::vector< const zscalar_t * > &weights, std::vector< int > &strides, bool useDegreeAsWeight)
basic_idInput_t * create_adapter< basic_idInput_t >(RCP< const Comm< int > > comm, int numLocalObj, zgno_t *myGids, std::vector< const zscalar_t * > &weights, std::vector< int > &strides, bool useDegreeAsWeight)
void doTest(RCP< const Comm< int > > comm, int numLocalObj, int nWeights, int numLocalParts, bool givePartSizes, bool useDegreeAsWeight=false)
void evaluate_adapter_results(RCP< const Comm< int > > comm, RCP< Zoltan2::EvaluatePartition< idInput_t >> metricObject, int numLocalObj, int nWeights, int original_numLocalParts, bool givePartSizes)
void setWeights(const scalar_t *val, int stride, int idx)
Provide a pointer to weights for the primary entity type.
#define TEST_FAIL_AND_EXIT(comm, ok, s, code)
Provides access for Zoltan2 to Xpetra::CrsGraph data.
Zoltan2::EvaluatePartition< matrixAdapter_t > quality_t
int main(int narg, char **arg)
graph_idInput_t * create_adapter< graph_idInput_t >(RCP< const Comm< int > > comm, int numLocalObj, zgno_t *myGids, std::vector< const zscalar_t * > &weights, std::vector< int > &strides, bool useDegreeAsWeight)
common code used by tests
Defines XpetraCrsGraphAdapter class.
SparseMatrixAdapter_t::part_t part_t
This class represents a collection of global Identifiers and their associated weights, if any.
A PartitioningSolution is a solution to a partitioning problem.
Defines the EvaluatePartition class.
void runTestSuite(RCP< const Comm< int > > comm, bool bCanTestDegreeAsWeights)
Zoltan2::BasicIdentifierAdapter< user_t > basic_idInput_t
void setWeightIsDegree(int idx)
Specify an index for which the weight should be the degree of the entity.
Zoltan2::XpetraCrsGraphAdapter< tcrsGraph_t, user_t > graph_idInput_t
The user parameters, debug, timing and memory profiling output objects, and error checking methods...
Tpetra::Map::local_ordinal_type zlno_t
static const std::string fail
InputTraits< User >::part_t part_t
Defines the BasicIdentifierAdapter class.
Tpetra::CrsGraph< zlno_t, zgno_t, znode_t > tcrsGraph_t
A class that computes and returns quality metrics.
void evaluate_adapter_results< graph_idInput_t >(RCP< const Comm< int > > comm, RCP< Zoltan2::EvaluatePartition< graph_idInput_t >> metricObject, int numLocalObj, int nWeights, int original_numLocalParts, bool givePartSizes)
Tpetra::Map::global_ordinal_type zgno_t
void evaluate_imbalance_results(RCP< const Comm< int > > comm, RCP< Zoltan2::EvaluatePartition< idInput_t >> metricObject, int numLocalObj, int nWeights, int original_numLocalParts, bool givePartSizes)
Zoltan2::BasicUserTypes< zscalar_t, zlno_t, zgno_t > user_t
void evaluate_adapter_results< basic_idInput_t >(RCP< const Comm< int > > comm, RCP< Zoltan2::EvaluatePartition< basic_idInput_t >> metricObject, int numLocalObj, int nWeights, int original_numLocalParts, bool givePartSizes)