25 using Teuchos::ArrayRCP;
35 template<
class idInput_t>
36 void doTest(RCP<
const Comm<int> > comm,
int numLocalObj,
37 int nWeights,
int numLocalParts,
bool givePartSizes,
bool useDegreeAsWeight=
false);
45 typedef Tpetra::CrsGraph<zlno_t, zgno_t, znode_t>
tcrsGraph_t;
50 template<
class idInput_t>
void runTestSuite(RCP<
const Comm<int> > comm,
bool bCanTestDegreeAsWeights) {
51 doTest<idInput_t>(comm, 10, 0, -1,
false);
52 doTest<idInput_t>(comm, 10, 0, 1,
false);
53 doTest<idInput_t>(comm, 10, 0, 1,
true);
54 doTest<idInput_t>(comm, 10, 1, 1,
false);
55 doTest<idInput_t>(comm, 10, 1, 1,
true);
56 doTest<idInput_t>(comm, 10, 2, 1,
false);
57 doTest<idInput_t>(comm, 10, 2, 1,
true);
58 doTest<idInput_t>(comm, 10, 1, 2,
true);
59 doTest<idInput_t>(comm, 10, 1, 2,
false);
60 doTest<idInput_t>(comm, 10, 1, -1,
false);
61 doTest<idInput_t>(comm, 10, 1, -1,
true);
62 doTest<idInput_t>(comm, 10, 2, -1,
false);
64 if(bCanTestDegreeAsWeights) {
65 doTest<idInput_t>(comm, 10, 1, 1,
true,
true);
69 int main(
int narg,
char *arg[])
71 Tpetra::ScopeGuard tscope(&narg, &arg);
72 Teuchos::RCP<const Teuchos::Comm<int> > comm = Tpetra::getDefaultComm();
74 int rank = comm->getRank();
77 runTestSuite<basic_idInput_t>(comm,
false);
82 runTestSuite<graph_idInput_t>(comm,
true);
86 std::cout <<
"PASS" << std::endl;
95 template<
class idInput_t>
98 int nWeights,
int original_numLocalParts,
bool givePartSizes) {
100 int rank = comm->getRank();
104 object_count_imbalance = metricObject->getObjectCountImbalance();
106 cout <<
"Object imbalance: " << object_count_imbalance << endl;
109 catch (std::exception &e){
116 for (
int i=0; i < nWeights; i++){
117 zscalar_t imb = metricObject->getWeightImbalance(i);
119 cout <<
"Weight " << i <<
" imbalance: " << imb << endl;
123 catch (std::exception &e){
126 if (!fail && nWeights > 1){
128 zscalar_t imb = metricObject->getNormedImbalance();
130 cout <<
"Normed weight imbalance: " << imb << endl;
133 catch (std::exception &e){
141 template<
class idInput_t>
144 int nWeights,
int original_numLocalParts,
bool givePartSizes) {
145 throw std::logic_error(
"evaluate_result not implemented.");
150 RCP<Zoltan2::EvaluatePartition<graph_idInput_t>> metricObject,
int numLocalObj,
151 int nWeights,
int original_numLocalParts,
bool givePartSizes) {
153 int rank = comm->getRank();
155 int total_edge_cut = -1;
159 total_edge_cut =
static_cast<int>(metricObject->getTotalEdgeCut());
161 cout <<
"Total Edge Cut: " << total_edge_cut << endl;
164 catch (std::exception &e){
169 int max_edge_cut = -1;
171 max_edge_cut =
static_cast<int>(metricObject->getMaxEdgeCut());
173 cout <<
"Max Edge Cut: " << max_edge_cut << endl;
176 catch (std::exception &e){
181 int total_messages = -1;
183 total_messages =
static_cast<int>(metricObject->getTotalMessages());
185 cout <<
"Total Messages: " << total_messages << endl;
188 catch (std::exception &e){
193 int max_messages = -1;
195 max_messages =
static_cast<int>(metricObject->getMaxMessages());
197 cout <<
"Max Messages: " << max_messages << endl;
200 catch (std::exception &e){
216 int num_procs = comm->getSize();
217 int expected_total_edge_cuts = (num_procs == 1) ? 0 :
218 (2 * numLocalObj) + ((num_procs-2) * numLocalObj * 2);
220 "getTotalEdgeCut is not the expected ", 1);
227 int expected_max_edge_cuts = (num_procs == 1) ? 0 :
228 (num_procs == 2) ? numLocalObj : numLocalObj * 2;
230 "getMaxEdgeCut is not the expected value", 1);
234 int expected_total_messages = expected_total_edge_cuts / numLocalObj;
236 "getTotalMessages is not the expected value", 1);
240 int expected_max_messages = expected_max_edge_cuts / numLocalObj;
242 "getMaxMessages is not the expected value", 1);
245 numLocalObj, nWeights, original_numLocalParts, givePartSizes);
252 RCP<Zoltan2::EvaluatePartition<basic_idInput_t>> metricObject,
int numLocalObj,
253 int nWeights,
int original_numLocalParts,
bool givePartSizes) {
255 numLocalObj, nWeights, original_numLocalParts, givePartSizes);
258 template<
class idInput_t>
260 int numLocalObj,
zgno_t *myGids,
261 std::vector<const zscalar_t *> &
weights,
262 std::vector<int> & strides,
263 bool useDegreeAsWeight) {
264 throw std::logic_error(
"create_adapter not implemented.");
269 int numLocalObj,
zgno_t *myGids,
270 std::vector<const zscalar_t *> &
weights,
271 std::vector<int> & strides,
272 bool useDegreeAsWeight) {
274 typedef Tpetra::Map<zlno_t, zgno_t>
map_t;
275 typedef Tpetra::CrsMatrix<zscalar_t, zlno_t, zgno_t> matrix_t;
277 const zgno_t gNvtx = numLocalObj * comm->getSize();
278 const Teuchos::ArrayView<const zgno_t> indexList(myGids, numLocalObj);
279 Teuchos::RCP<const map_t> map = rcp(
new map_t(gNvtx, indexList, 0, comm));
282 size_t maxRowLen = 2;
283 Teuchos::RCP<matrix_t> matrix = rcp(
new matrix_t(map, maxRowLen));
296 Teuchos::Array<zgno_t> col(2);
297 Teuchos::Array<zscalar_t> val(2); val[0] = 1.; val[1] = 1.;
298 zgno_t first_id = map->getMinAllGlobalIndex();
299 zgno_t last_id = map->getMaxAllGlobalIndex();
300 for (
zlno_t i = 0; i < numLocalObj; i++) {
301 zgno_t id = map->getGlobalElement(i);
304 matrix->insertGlobalValues(
id, col(), val());
307 matrix->fillComplete(map, map);
309 size_t nVwgts =
weights.size();
313 for (
size_t j = 0; j < nVwgts; j++) {
318 if(useDegreeAsWeight) {
319 for (
size_t j = 0; j < nVwgts; j++) {
329 int numLocalObj,
zgno_t *myGids,
330 std::vector<const zscalar_t *> &
weights,
331 std::vector<int> & strides,
332 bool useDegreeAsWeight) {
338 template<
class idInput_t>
339 void doTest(RCP<
const Comm<int> > comm,
int numLocalObj,
340 int nWeights,
int numLocalParts,
bool givePartSizes,
bool useDegreeAsWeight)
346 int rank = comm->getRank();
348 int original_numLocalParts = numLocalParts;
350 int nprocs = comm->getSize();
353 bool testEmptyParts = (numLocalParts < 1);
354 int numGlobalParts = 0;
357 numGlobalParts = nprocs / 2;
358 if (numGlobalParts >= 1)
359 numLocalParts = (rank < numGlobalParts ? 1 : 0);
362 testEmptyParts =
false;
366 numGlobalParts = nprocs * numLocalParts;
371 <<
"Test: number of weights " << nWeights
372 <<
", desired number of parts " << numGlobalParts
373 <<
", calculated num local parts " << numLocalParts
374 <<
", original num local parts " << original_numLocalParts
375 << (givePartSizes ?
", with differing part sizes." :
376 ", with uniform part sizes.")
377 <<
", Number of procs " << nprocs
378 <<
", each with " << numLocalObj <<
" objects, part = rank."
379 << (useDegreeAsWeight ?
", use degree as weights" :
"")
385 Teuchos::ParameterList pl(
"test list");
386 pl.set(
"num_local_parts", numLocalParts);
388 RCP<const Zoltan2::Environment> env =
394 for (
int i=0, x=rank*numLocalObj; i < numLocalObj; i++, x++){
401 int partSizeDim = (givePartSizes ? (nWeights ? nWeights : 1) : 0);
402 ArrayRCP<ArrayRCP<part_t> > ids(partSizeDim);
403 ArrayRCP<ArrayRCP<zscalar_t> > sizes(partSizeDim);
405 if (givePartSizes && numLocalParts > 0){
406 part_t *myParts =
new part_t [numLocalParts];
407 myParts[0] = rank * numLocalParts;
408 for (
int i=1; i < numLocalParts; i++)
409 myParts[i] = myParts[i-1] + 1;
410 ArrayRCP<part_t> partNums(myParts, 0, numLocalParts,
true);
413 if (sizeFactor < 0) sizeFactor *= -1;
416 for (
int dim=0; dim < partSizeDim; dim++){
418 for (
int i=0; i < numLocalParts; i++)
419 psizes[i] = sizeFactor;
420 sizes[dim] = arcp(psizes, 0, numLocalParts,
true);
427 std::vector<const zscalar_t *>
weights;
428 std::vector<int> strides;
430 int len = numLocalObj*nWeights;
431 ArrayRCP<zscalar_t> wgtBuf;
436 wgtBuf = arcp(wgts, 0, len,
true);
437 for (
int i=0; i < len; i++)
441 for (
int i=0; i < nWeights; i++, wgts+=numLocalObj)
442 weights.push_back(wgts);
447 ia = create_adapter<idInput_t>(comm, numLocalObj, myGids,
weights, strides, useDegreeAsWeight);
449 catch (std::exception &e){
457 RCP<Zoltan2::PartitioningSolution<idInput_t> > solution;
463 ids.view(0,partSizeDim), sizes.view(0,partSizeDim)));
466 env, comm, nWeights));
468 catch (std::exception &e){
476 part_t *partNum =
new part_t [numLocalObj];
477 ArrayRCP<part_t> partAssignment(partNum, 0, numLocalObj,
true);
478 for (
int i=0; i < numLocalObj; i++)
481 solution->setParts(partAssignment);
485 RCP<quality_t> metricObject;
488 metricObject = rcp(
new quality_t(ia, &pl, comm, solution.getRawPtr()));
490 catch (std::exception &e){
497 metricObject->printMetrics(cout);
500 catch (std::exception &e){
506 evaluate_adapter_results<idInput_t>(comm, metricObject,
507 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)