Zoltan2
 All Namespaces Files Functions Variables Pages
block.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 
50 #include <Zoltan2_BasicIdentifierAdapter.hpp>
51 #include <Zoltan2_PartitioningProblem.hpp>
52 #include <Zoltan2_PartitioningSolution.hpp>
53 
60 int main(int argc, char *argv[]) {
61 #ifdef HAVE_ZOLTAN2_MPI
62  MPI_Init(&argc, &argv);
63  int rank, nprocs;
64  MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
65  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
66 #else
67  int rank=0, nprocs=1;
68 #endif
69 
70  // For convenience, we'll use the Tpetra defaults for local/global ID types
71  // Users can substitute their preferred local/global ID types
72  typedef Tpetra::Map<> Map_t;
73  typedef Map_t::local_ordinal_type localId_t;
74  typedef Map_t::global_ordinal_type globalId_t;
75  typedef Tpetra::Details::DefaultTypes::scalar_type scalar_t;
76 
78  // Generate some input data.
79 
80  int localCount = 40*(rank+1);
81  int totalCount = 20*nprocs*(nprocs+1);
82  int targetCount = totalCount / nprocs;
83  globalId_t *globalIds = new globalId_t[localCount];
84 
85  if (rank==0) {
86  for (int i=0, num=40; i < nprocs ; i++, num+=40) {
87  std::cout << "Rank " << i << " generates " << num << " ids." << std::endl;
88  }
89  }
90 
91  globalId_t offset = 0;
92  for (int i=1; i <= rank; i++) {
93  offset += 40*i;
94  }
95 
96  for (int i=0; i < localCount; i++) {
97  globalIds[i] = offset++;
98  }
99 
101  // Create a Zoltan2 input adapter with no weights
102 
103  // TODO explain
104  typedef Zoltan2::BasicUserTypes<scalar_t, localId_t, globalId_t> myTypes;
105 
106  // TODO explain
107  typedef Zoltan2::BasicIdentifierAdapter<myTypes> inputAdapter_t;
108 
109  std::vector<const scalar_t *> noWeights;
110  std::vector<int> noStrides;
111 
112  inputAdapter_t ia(localCount, globalIds, noWeights, noStrides);
113 
115  // Create parameters for a Block problem
116 
117  Teuchos::ParameterList params("test params");
118  params.set("debug_level", "basic_status");
119  params.set("debug_procs", "0");
120  params.set("error_check_level", "debug_mode_assertions");
121 
122  params.set("algorithm", "block");
123  params.set("imbalance_tolerance", 1.1);
124  params.set("num_global_parts", nprocs);
125 
127  // Create a Zoltan2 partitioning problem
128 
129  Zoltan2::PartitioningProblem<inputAdapter_t> *problem =
130  new Zoltan2::PartitioningProblem<inputAdapter_t>(&ia, &params);
131 
133  // Solve the problem - do the partitioning
134 
135  problem->solve();
136 
138  // Check and print the solution.
139  // Count number of IDs assigned to each part; compare to targetCount
140 
141  const globalId_t *ids = NULL;
142  ia.getIDsView(ids);
143  std::vector<int> partCounts(nprocs, 0), globalPartCounts(nprocs, 0);
144 
145  for (size_t i = 0; i < ia.getLocalNumIDs(); i++) {
146  int pp = problem->getSolution().getPartListView()[i];
147  std::cout << rank << " LID " << i << " GID " << ids[i]
148  << " PART " << pp << std::endl;
149  partCounts[pp]++;
150  }
151 
152 #ifdef HAVE_ZOLTAN2_MPI
153  MPI_Allreduce(&(partCounts[0]), &(globalPartCounts[0]), nprocs,
154  MPI_INT, MPI_SUM, MPI_COMM_WORLD);
155 #else
156  for (int i = 0; i < nprocs; i++) globalPartCounts[i] = partCounts[i];
157 #endif
158 
159  if (rank == 0) {
160  int ierr = 0;
161  for (int i = 0; i < nprocs; i++) {
162  if (globalPartCounts[i] != targetCount) {
163  std::cout << "FAIL: part " << i << " has " << globalPartCounts[i]
164  << " != " << targetCount << "; " << ++ierr << " errors"
165  << std::endl;
166  }
167  }
168  if (ierr == 0) {
169  std::cout << "PASS" << std::endl;
170  }
171  }
172 
173  delete [] globalIds;
174  delete problem;
175 #ifdef HAVE_ZOLTAN2_MPI
176  MPI_Finalize();
177 #endif
178 }
int main(int argc, char *argv[])
Definition: block.cpp:60