Zoltan2
blockTest.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
48 #include <Zoltan2_TestHelpers.hpp>
49 
50 #include <Teuchos_GlobalMPISession.hpp>
51 #include <Teuchos_DefaultComm.hpp>
52 #include <Teuchos_CommandLineProcessor.hpp>
53 #include <Teuchos_ParameterList.hpp>
54 
55 using namespace std;
56 using Teuchos::Comm;
57 using Teuchos::RCP;
58 
59 int main(int narg, char **arg)
60 {
61  int fail=0, gfail=0;
62  Teuchos::GlobalMPISession session(&narg, &arg);
63  RCP<const Comm<int> > comm = Teuchos::DefaultComm<int>::getComm();
64 
65  int rank = comm->getRank();
66  int nprocs = comm->getSize();
67 
68  // Construct the user input
69  int numGlobalIdentifiers = 100;
70  int numMyIdentifiers = numGlobalIdentifiers / nprocs;
71  if (rank < numGlobalIdentifiers % nprocs)
72  numMyIdentifiers += 1;
73 
74  zgno_t myBaseId = zgno_t(numGlobalIdentifiers * rank);
75 
76  zgno_t *myIds = new zgno_t[numMyIdentifiers];
77  zscalar_t *myWeights = new zscalar_t[numMyIdentifiers];
78 
79  if (!myIds || !myWeights){
80  fail = 1;
81  }
82 
83  gfail = globalFail(comm, fail);
84 
85  if (gfail){
86  if (rank==0){
87  std::cout << "Memory allocation failure" << std::endl;
88  std::cout << "FAIL" << std:: endl;
89  }
90  return 1;
91  }
92 
93  zscalar_t origsumwgts = 0;
94  for (int i=0; i < numMyIdentifiers; i++){
95  myIds[i] = myBaseId+i;
96  myWeights[i] = rank%3 + 1;
97  origsumwgts += myWeights[i];
98  }
99 
100  // Some output
101  int *origcnt = new int[nprocs];
102  zscalar_t *origwgts = new zscalar_t[nprocs];
103  Teuchos::gather<int, int>(&numMyIdentifiers, 1, origcnt, 1, 0, *comm);
104  Teuchos::gather<int, zscalar_t>(&origsumwgts, 1, origwgts, 1, 0, *comm);
105  if (rank == 0) {
106  cout << "BEFORE PART CNTS: ";
107  for (int i = 0; i < nprocs; i++)
108  cout << origcnt[i] << " ";
109  cout << endl;
110  cout << "BEFORE PART WGTS: ";
111  for (int i = 0; i < nprocs; i++)
112  cout << origwgts[i] << " ";
113  cout << endl;
114  }
115  delete [] origcnt;
116  delete [] origwgts;
117 
118  // Building Zoltan2 adapters
119  std::vector<const zscalar_t *> weightValues;
120  std::vector<int> weightStrides; // default is one
121  weightValues.push_back(const_cast<const zscalar_t *>(myWeights));
122 
125  typedef Zoltan2::EvaluatePartition<adapter_t> quality_t;
126  typedef adapter_t::part_t part_t;
128 
129  adapter_t *adapter =
130  new adapter_t(zlno_t(numMyIdentifiers),myIds,weightValues,weightStrides);
131 
132  // Set up the parameters and problem
133  bool useWeights = true;
134  Teuchos::CommandLineProcessor cmdp (false, false);
135  cmdp.setOption("weights", "no-weights", &useWeights,
136  "Indicated whether to use identifier weights in partitioning");
137  cmdp.parse(narg, arg);
138 
139  Teuchos::ParameterList params("test parameters");
140  //params.set("compute_metrics", true); // bool parameter
141  params.set("num_global_parts", nprocs);
142  params.set("algorithm", "block");
143  params.set("partitioning_approach", "partition");
144  if (!useWeights) params.set("partitioning_objective", "balance_object_count");
145 
146  Zoltan2::PartitioningProblem<adapter_t> problem(adapter, &params);
147 
148  problem.solve();
149 
151 
152  // create metric object
153 
154  quality_t *metricObject = new quality_t(adapter, &params, comm, &solution);
155 
156  // Some output
157  zscalar_t *totalWeight = new zscalar_t [nprocs];
158  zscalar_t *sumWeight = new zscalar_t [nprocs];
159  memset(totalWeight, 0, nprocs * sizeof(zscalar_t));
160  int *totalCnt = new int [nprocs];
161  int *sumCnt = new int [nprocs];
162  memset(totalCnt, 0, nprocs * sizeof(int));
163 
164  const part_t *partList = solution.getPartListView();
165  zscalar_t libImbalance = metricObject->getWeightImbalance(0);
166  delete metricObject;
167  delete adapter;
168 
169  for (int i=0; i < numMyIdentifiers; i++){
170  totalCnt[partList[i]]++;
171  totalWeight[partList[i]] += myWeights[i];
172  }
173 
174  Teuchos::reduceAll<int, int>(*comm, Teuchos::REDUCE_SUM, nprocs,
175  totalCnt, sumCnt);
176  Teuchos::reduceAll<int, zscalar_t>(*comm, Teuchos::REDUCE_SUM, nprocs,
177  totalWeight, sumWeight);
178 
179  double epsilon = 10e-6;
180 
181  if (rank == 0){
182  std::cout << "AFTER PART CNTS: ";
183  for (int i=0; i < nprocs; i++)
184  std::cout << sumCnt[i] << " ";
185  std::cout << std::endl;
186 
187  zscalar_t total = 0;
188  std::cout << "AFTER PART WGTS: ";
189  for (int i=0; i < nprocs; i++){
190  std::cout << sumWeight[i] << " ";
191  total += sumWeight[i];
192  }
193  std::cout << std::endl;
194 
195  zscalar_t avg = total / zscalar_t(nprocs);
196 
197  zscalar_t imbalance = -1.0;
198 
199  for (int i=0; i < nprocs; i++){
200  zscalar_t imb = 0;
201  if (sumWeight[i] > avg)
202  imb = (sumWeight[i] - avg) / avg;
203  else
204  imb = (avg - sumWeight[i]) / avg;
205 
206  if (imb > imbalance)
207  imbalance = imb;
208  }
209  imbalance += 1.0;
210 
211  std::cout << "Computed imbalance: " << imbalance << std::endl;
212  std::cout << "Library's imbalance: " << libImbalance << std::endl;
213 
214  double err;
215  if (imbalance > libImbalance)
216  err = imbalance - libImbalance;
217  else
218  err = libImbalance - imbalance;
219 
220  if (err > epsilon)
221  fail = 1;
222  }
223  else{
224  fail = 0;
225  }
226 
227  gfail = globalFail(comm, fail);
228 
229  if (gfail){
230  if (rank==0){
231  std::cout << "failure in solution's imbalance data" << std::endl;
232  std::cout << "FAIL" << std:: endl;
233  }
234  return 1;
235  }
236 
237  if (rank==0)
238  std::cout << "PASS" << std:: endl;
239 
240  delete [] myWeights;
241  delete [] myIds;
242  delete [] sumCnt;
243  delete [] totalCnt;
244  delete [] sumWeight;
245  delete [] totalWeight;
246 
247  return 0;
248 }
Zoltan2::BaseAdapter< userTypes_t > base_adapter_t
int globalFail(const RCP< const Comm< int > > &comm, int fail)
int main(int narg, char **arg)
Definition: blockTest.cpp:59
double zscalar_t
A simple class that can be the User template argument for an InputAdapter.
int zlno_t
Defines the PartitioningSolution class.
common code used by tests
This class represents a collection of global Identifiers and their associated weights, if any.
A PartitioningSolution is a solution to a partitioning problem.
static const std::string fail
int zgno_t
Defines the BasicIdentifierAdapter class.
const PartitioningSolution< Adapter > & getSolution()
Get the solution to the problem.
PartitioningProblem sets up partitioning problems for the user.
const part_t * getPartListView() const
Returns the part list corresponding to the global ID list.
Defines the PartitioningProblem class.
A class that computes and returns quality metrics.
#define epsilon
void solve(bool updateInputData=true)
Direct the problem to create a solution.