Zoltan2
Metric.cpp
Go to the documentation of this file.
1 // @HEADER
2 //
3 // ***********************************************************************
4 //
5 // Zoltan2: A package of combinatorial algorithms for scientific computing
6 // Copyright 2012 Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact Karen Devine (kddevin@sandia.gov)
39 // Erik Boman (egboman@sandia.gov)
40 // Siva Rajamanickam (srajama@sandia.gov)
41 //
42 // ***********************************************************************
43 //
44 // @HEADER
45 //
46 // Test the following:
47 // EvaluatePartition class
48 // MetricValues class
49 // Metric related namespace methods
50 
51 
53 #include <Zoltan2_TestHelpers.hpp>
55 #include <stdlib.h>
56 #include <vector>
57 
58 
59 using Teuchos::ArrayRCP;
60 using Teuchos::Array;
61 using Teuchos::RCP;
62 using Teuchos::rcp;
63 using Teuchos::arcp;
64 
65 
66 void doTest(RCP<const Comm<int> > comm, int numLocalObj,
67  int nWeights, int numLocalParts, bool givePartSizes);
68 
69 int main(int narg, char *arg[])
70 {
71  Tpetra::ScopeGuard tscope(&narg, &arg);
72  Teuchos::RCP<const Teuchos::Comm<int> > comm = Tpetra::getDefaultComm();
73 
74  int rank = comm->getRank();
75 
76  doTest(comm, 10, 0, -1, false);
77  doTest(comm, 10, 0, 1, false);
78  doTest(comm, 10, 0, 1, true);
79  doTest(comm, 10, 1, 1, false);
80  doTest(comm, 10, 1, 1, true);
81  doTest(comm, 10, 2, 1, false);
82  doTest(comm, 10, 2, 1, true);
83  doTest(comm, 10, 1, 2, true);
84  doTest(comm, 10, 1, 2, false);
85  doTest(comm, 10, 1, -1, false);
86  doTest(comm, 10, 1, -1, true);
87  doTest(comm, 10, 2, -1, false);
88 
89  if (rank==0)
90  std::cout << "PASS" << std::endl;
91 }
92 
93 // Assumes numLocalObj is the same on every process.
94 
95 void doTest(RCP<const Comm<int> > comm, int numLocalObj,
96  int nWeights, int numLocalParts, bool givePartSizes)
97 {
100  typedef Zoltan2::EvaluatePartition<idInput_t> quality_t;
101  typedef idInput_t::part_t part_t;
102 
103  int rank = comm->getRank();
104  int nprocs = comm->getSize();
105  int fail=0;
106  srand(rank+1);
107  bool testEmptyParts = (numLocalParts < 1);
108  int numGlobalParts = 0;
109 
110  if (testEmptyParts){
111  numGlobalParts = nprocs / 2;
112  if (numGlobalParts >= 1)
113  numLocalParts = (rank < numGlobalParts ? 1 : 0);
114  else{
115  numLocalParts = 1;
116  testEmptyParts = false;
117  }
118  }
119  else{
120  numGlobalParts = nprocs * numLocalParts;
121  }
122 
123  if (rank == 0){
124  std::cout << std::endl;
125  std::cout << "Test: number of weights " << nWeights;
126  std::cout << ", desired number of parts " << numGlobalParts;
127  if (givePartSizes)
128  std::cout << ", with differing part sizes." << std::endl;
129  else
130  std::cout << ", with uniform part sizes." << std::endl;
131  std::cout << "Number of procs " << nprocs;
132  std::cout << ", each with " << numLocalObj << " objects, part = rank." << std::endl;
133  }
134 
135  // An environment. This is usually created by the problem.
136 
137  Teuchos::ParameterList pl("test list");
138  pl.set("num_local_parts", numLocalParts);
139 
140  RCP<const Zoltan2::Environment> env =
141  rcp(new Zoltan2::Environment(pl, comm));
142 
143  // A simple identifier map. Usually created by the model.
144 
145  zgno_t *myGids = new zgno_t [numLocalObj];
146  for (int i=0, x=rank*numLocalObj; i < numLocalObj; i++, x++){
147  myGids[i] = x;
148  }
149 
150  // Part sizes. Usually supplied by the user to the Problem.
151  // Then the problem supplies them to the Solution.
152 
153  int partSizeDim = (givePartSizes ? (nWeights ? nWeights : 1) : 0);
154  ArrayRCP<ArrayRCP<part_t> > ids(partSizeDim);
155  ArrayRCP<ArrayRCP<zscalar_t> > sizes(partSizeDim);
156 
157  if (givePartSizes && numLocalParts > 0){
158  part_t *myParts = new part_t [numLocalParts];
159  myParts[0] = rank * numLocalParts;
160  for (int i=1; i < numLocalParts; i++)
161  myParts[i] = myParts[i-1] + 1;
162  ArrayRCP<part_t> partNums(myParts, 0, numLocalParts, true);
163 
164  zscalar_t sizeFactor = nprocs/2 - rank;
165  if (sizeFactor < 0) sizeFactor *= -1;
166  sizeFactor += 1;
167 
168  for (int dim=0; dim < partSizeDim; dim++){
169  zscalar_t *psizes = new zscalar_t [numLocalParts];
170  for (int i=0; i < numLocalParts; i++)
171  psizes[i] = sizeFactor;
172  sizes[dim] = arcp(psizes, 0, numLocalParts, true);
173 
174  ids[dim] = partNums;
175  }
176  }
177 
178  // An input adapter with random weights. Created by the user.
179 
180  std::vector<const zscalar_t *> weights;
181  std::vector<int> strides; // default to 1
182 
183  int len = numLocalObj*nWeights;
184  ArrayRCP<zscalar_t> wgtBuf;
185  zscalar_t *wgts = NULL;
186 
187  if (len > 0){
188  wgts = new zscalar_t [len];
189  wgtBuf = arcp(wgts, 0, len, true);
190  for (int i=0; i < len; i++)
191  wgts[i] = (zscalar_t(rand()) / zscalar_t(RAND_MAX)) + 1.0;
192  }
193 
194  for (int i=0; i < nWeights; i++, wgts+=numLocalObj)
195  weights.push_back(wgts);
196 
197  idInput_t *ia = NULL;
198 
199  try{
200  ia = new idInput_t(numLocalObj, myGids, weights, strides);
201  }
202  catch (std::exception &e){
203  fail=1;
204  }
205 
206  TEST_FAIL_AND_EXIT(*comm, fail==0, "create adapter", 1);
207 
208  // A solution (usually created by a problem)
209 
210  RCP<Zoltan2::PartitioningSolution<idInput_t> > solution;
211 
212  try{
213  if (givePartSizes)
214  solution = rcp(new Zoltan2::PartitioningSolution<idInput_t>(
215  env, comm, nWeights,
216  ids.view(0,partSizeDim), sizes.view(0,partSizeDim)));
217  else
218  solution = rcp(new Zoltan2::PartitioningSolution<idInput_t>(
219  env, comm, nWeights));
220  }
221  catch (std::exception &e){
222  fail=1;
223  }
224 
225  TEST_FAIL_AND_EXIT(*comm, fail==0, "create solution", 1);
226 
227  // Part assignment for my objects: The algorithm usually calls this.
228 
229  part_t *partNum = new part_t [numLocalObj];
230  ArrayRCP<part_t> partAssignment(partNum, 0, numLocalObj, true);
231  for (int i=0; i < numLocalObj; i++)
232  partNum[i] = rank;
233 
234  solution->setParts(partAssignment);
235 
236  // create metric object (also usually created by a problem)
237 
238  RCP<quality_t> metricObject;
239 
240  try{
241  metricObject = rcp(new quality_t(ia, &pl, comm, solution.getRawPtr()));
242  }
243  catch (std::exception &e){
244  fail=1;
245  }
246 
247  TEST_FAIL_AND_EXIT(*comm, fail==0, "compute metrics", 1);
248 
249 
250  if (rank==0){
251  ;
252  try{
253  zscalar_t imb = metricObject->getObjectCountImbalance();
254  std::cout << "Object imbalance: " << imb << std::endl;
255  }
256  catch (std::exception &e){
257  fail=1;
258  }
259  }
260 
261  TEST_FAIL_AND_EXIT(*comm, fail==0, "getObjectCountImbalance", 1);
262 
263  if (rank==0 && nWeights > 0){
264  try{
265  for (int i=0; i < nWeights; i++){
266  zscalar_t imb = metricObject->getWeightImbalance(i);
267  std::cout << "Weight " << i << " imbalance: " << imb << std::endl;
268  }
269  }
270  catch (std::exception &e){
271  fail=10;
272  }
273  if (!fail && nWeights > 1){
274  try{
275  zscalar_t imb = metricObject->getNormedImbalance();
276  std::cout << "Normed weight imbalance: " << imb << std::endl;
277  }
278  catch (std::exception &e){
279  fail=11;
280  }
281  }
282  }
283 
284  TEST_FAIL_AND_EXIT(*comm, fail==0, "get imbalances", 1);
285 
286  if (rank==0){
287  try{
288  metricObject->printMetrics(std::cout);
289  }
290  catch (std::exception &e){
291  fail=1;
292  }
293  }
294 
295  TEST_FAIL_AND_EXIT(*comm, fail==0, "print metrics", 1);
296  delete ia;
297 }
Zoltan2::PartitioningSolution
A PartitioningSolution is a solution to a partitioning problem.
Definition: Zoltan2_PartitioningSolution.hpp:55
zscalar_t
double zscalar_t
Definition: Zoltan2_TestHelpers.hpp:141
doTest
void doTest(RCP< const Comm< int > > comm, int numLocalObj, int nWeights, int numLocalParts, bool givePartSizes)
Definition: Metric.cpp:95
part_t
SparseMatrixAdapter_t::part_t part_t
Definition: partitioningTree.cpp:74
Zoltan2::Environment
The user parameters, debug, timing and memory profiling output objects, and error checking methods.
Definition: Zoltan2_Environment.hpp:83
TEST_FAIL_AND_EXIT
#define TEST_FAIL_AND_EXIT(comm, ok, s, code)
Definition: ErrorHandlingForTests.hpp:70
zgno_t
int zgno_t
Definition: Zoltan2_TestHelpers.hpp:143
Zoltan2::BasicIdentifierAdapter
This class represents a collection of global Identifiers and their associated weights,...
Definition: Zoltan2_BasicIdentifierAdapter.hpp:82
Zoltan2::BasicUserTypes
A simple class that can be the User template argument for an InputAdapter.
Definition: Zoltan2_InputTraits.hpp:139
idInput_t
Zoltan2::BasicIdentifierAdapter< zzuser_t > idInput_t
Definition: PartitioningSolution.cpp:58
Zoltan2::BasicIdentifierAdapter::part_t
InputTraits< User >::part_t part_t
Definition: Zoltan2_BasicIdentifierAdapter.hpp:88
fail
static const std::string fail
Definition: findUniqueGids.cpp:80
weights
static ArrayRCP< ArrayRCP< zscalar_t > > weights
Definition: rcbPerformanceZ1.cpp:82
Zoltan2_TestHelpers.hpp
common code used by tests
Zoltan2_EvaluatePartition.hpp
Defines the EvaluatePartition class.
main
int main(int narg, char *arg[])
Definition: Metric.cpp:69
Zoltan2::EvaluatePartition
A class that computes and returns quality metrics.
Definition: Zoltan2_EvaluatePartition.hpp:114
Zoltan2_BasicIdentifierAdapter.hpp
Defines the BasicIdentifierAdapter class.