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 adapter_t::part_t part_t;
126 
127  adapter_t adapter(zlno_t(numMyIdentifiers),myIds,weightValues,weightStrides);
128 
129  // Set up the parameters and problem
130  bool useWeights = true;
131  Teuchos::CommandLineProcessor cmdp (false, false);
132  cmdp.setOption("weights", "no-weights", &useWeights,
133  "Indicated whether to use identifier weights in partitioning");
134  cmdp.parse(narg, arg);
135 
136  Teuchos::ParameterList params("test parameters");
137  params.set("compute_metrics", "true");
138  params.set("num_global_parts", nprocs);
139  params.set("algorithm", "block");
140  params.set("partitioning_approach", "partition");
141  if (!useWeights) params.set("partitioning_objective", "balance_object_count");
142 
143  Zoltan2::PartitioningProblem<adapter_t> problem(&adapter, &params);
144 
145  problem.solve();
146 
148 
149  // Some output
150  zscalar_t *totalWeight = new zscalar_t [nprocs];
151  zscalar_t *sumWeight = new zscalar_t [nprocs];
152  memset(totalWeight, 0, nprocs * sizeof(zscalar_t));
153  int *totalCnt = new int [nprocs];
154  int *sumCnt = new int [nprocs];
155  memset(totalCnt, 0, nprocs * sizeof(int));
156 
157  const part_t *partList = solution.getPartListView();
158  const zscalar_t libImbalance = problem.getWeightImbalance();
159 
160  for (int i=0; i < numMyIdentifiers; i++){
161  totalCnt[partList[i]]++;
162  totalWeight[partList[i]] += myWeights[i];
163  }
164 
165  Teuchos::reduceAll<int, int>(*comm, Teuchos::REDUCE_SUM, nprocs,
166  totalCnt, sumCnt);
167  Teuchos::reduceAll<int, zscalar_t>(*comm, Teuchos::REDUCE_SUM, nprocs,
168  totalWeight, sumWeight);
169 
170  double epsilon = 10e-6;
171 
172  if (rank == 0){
173  std::cout << "AFTER PART CNTS: ";
174  for (int i=0; i < nprocs; i++)
175  std::cout << sumCnt[i] << " ";
176  std::cout << std::endl;
177 
178  zscalar_t total = 0;
179  std::cout << "AFTER PART WGTS: ";
180  for (int i=0; i < nprocs; i++){
181  std::cout << sumWeight[i] << " ";
182  total += sumWeight[i];
183  }
184  std::cout << std::endl;
185 
186  zscalar_t avg = total / zscalar_t(nprocs);
187 
188  zscalar_t imbalance = -1.0;
189 
190  for (int i=0; i < nprocs; i++){
191  zscalar_t imb = 0;
192  if (sumWeight[i] > avg)
193  imb = (sumWeight[i] - avg) / avg;
194  else
195  imb = (avg - sumWeight[i]) / avg;
196 
197  if (imb > imbalance)
198  imbalance = imb;
199  }
200  imbalance += 1.0;
201 
202  std::cout << "Computed imbalance: " << imbalance << std::endl;
203  std::cout << "Library's imbalance: " << libImbalance << std::endl;
204 
205  double err;
206  if (imbalance > libImbalance)
207  err = imbalance - libImbalance;
208  else
209  err = libImbalance - imbalance;
210 
211  if (err > epsilon)
212  fail = 1;
213  }
214  else{
215  fail = 0;
216  }
217 
218  gfail = globalFail(comm, fail);
219 
220  if (gfail){
221  if (rank==0){
222  std::cout << "failure in solution's imbalance data" << std::endl;
223  std::cout << "FAIL" << std:: endl;
224  }
225  return 1;
226  }
227 
228  if (rank==0)
229  std::cout << "PASS" << std:: endl;
230 
231  delete [] myWeights;
232  delete [] myIds;
233  delete [] sumCnt;
234  delete [] totalCnt;
235  delete [] sumWeight;
236  delete [] totalWeight;
237 
238  return 0;
239 }
const scalar_t getWeightImbalance(int idx=0) const
Returns the imbalance of the solution.
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.
const part_t * getPartListView() const
Returns the part list corresponding to the global ID list.
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.
Defines the PartitioningProblem class.
#define epsilon
void solve(bool updateInputData=true)
Direct the problem to create a solution.