Zoltan2
Loading...
Searching...
No Matches
PartitioningSolution.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 PartitioningSolution class.
47//
48// Normally a Solution is created by a Problem.
49// We create a few Solutions in this unit test.
50
51// TODO test ::convertSolutionToImportList
52
56
60
61using Teuchos::ArrayRCP;
62using Teuchos::Array;
63using Teuchos::RCP;
64using Teuchos::rcp;
65using Teuchos::arcp;
66
67
68
69void makeArrays(int wdim, int *lens, zzpart_t **ids, zscalar_t **sizes,
70 ArrayRCP<ArrayRCP<zzpart_t> > &idList, ArrayRCP<ArrayRCP<zscalar_t> > &sizeList)
71{
72 ArrayRCP<zzpart_t> *idArrays = new ArrayRCP<zzpart_t> [wdim];
73 ArrayRCP<zscalar_t> *sizeArrays = new ArrayRCP<zscalar_t> [wdim];
74
75 for (int w=0; w < wdim; w++){
76 idArrays[w] = arcp(ids[w], 0, lens[w], false);
77 sizeArrays[w] = arcp(sizes[w], 0, lens[w], false);
78 }
79
80 idList = arcp(idArrays, 0, wdim, true);
81 sizeList = arcp(sizeArrays, 0, wdim, true);
82}
83
84int main(int narg, char *arg[])
85{
86 Tpetra::ScopeGuard tscope(&narg, &arg);
87 Teuchos::RCP<const Teuchos::Comm<int> > comm = Tpetra::getDefaultComm();
88
89 int nprocs = comm->getSize();
90 int rank = comm->getRank();
91 int fail=0, gfail=0;
92 double epsilon = 10e-6;
93
95 // Arrays to hold part Ids and part Sizes for each weight
96
97 int numIdsPerProc = 10;
98 int maxNumWeights = 3;
99 int maxNumPartSizes = nprocs;
100 int *lengths = new int [maxNumWeights];
101 zzpart_t **idLists = new zzpart_t * [maxNumWeights];
102 zscalar_t **sizeLists = new zscalar_t * [maxNumWeights];
103
104 for (int w=0; w < maxNumWeights; w++){
105 idLists[w] = new zzpart_t [maxNumPartSizes];
106 sizeLists[w] = new zscalar_t [maxNumPartSizes];
107 }
108
110 // A default environment
111 RCP<const Zoltan2::Environment> env = rcp(new Zoltan2::Environment(comm));
112
114 // A simple identifier map.
115
116 zgno_t *myGids = new zgno_t [numIdsPerProc];
117 for (int i=0, x=rank*numIdsPerProc; i < numIdsPerProc; i++)
118 myGids[i] = x++;
119
121 // TEST:
122 // One weight, one part per proc.
123 // Some part sizes are 2 and some are 1.
124
125 int numGlobalParts = nprocs;
126 int nWeights = 1;
127
128 ArrayRCP<ArrayRCP<zzpart_t> > ids;
129 ArrayRCP<ArrayRCP<zscalar_t> > sizes;
130
131 memset(lengths, 0, sizeof(int) * maxNumWeights);
132
133 lengths[0] = 1; // We give a size for 1 part.
134 idLists[0][0] = rank; // The part is my part.
135 sizeLists[0][0] = rank%2 + 1.0; // The size is 1.0 or 2.0
136
137 makeArrays(1, lengths, idLists, sizeLists, ids, sizes);
138
139 // Normalized part size for every part, for checking later on
140
141 zscalar_t *normalizedPartSizes = new zscalar_t [numGlobalParts];
142 zscalar_t sumSizes=0;
143 for (int i=0; i < numGlobalParts; i++){
144 normalizedPartSizes[i] = 1.0;
145 if (i % 2) normalizedPartSizes[i] = 2.0;
146 sumSizes += normalizedPartSizes[i];
147 }
148 for (int i=0; i < numGlobalParts; i++)
149 normalizedPartSizes[i] /= sumSizes;
150
152 // Create a solution object with part size information, and check it.
153
154 RCP<Zoltan2::PartitioningSolution<idInput_t> > solution;
155
156 try{
158 env, // application environment info
159 comm, // problem communicator
160 nWeights, // number of weights
161 ids.view(0,nWeights), // part ids
162 sizes.view(0,nWeights))); // part sizes
163 }
164 catch (std::exception &e){
165 fail=1;
166 }
167
168 TEST_FAIL_AND_EXIT(*comm, fail==0, "constructor call 1", 1);
169
170 // Test the Solution queries that are used by algorithms
171
172 if (solution->getTargetGlobalNumberOfParts() != size_t(numGlobalParts))
173 fail=2;
174
175 if (!fail && solution->getLocalNumberOfParts() != 1)
176 fail=3;
177
178 if (!fail && !solution->oneToOnePartDistribution())
179 fail=4;
180
181 if (!fail && solution->getPartDistribution() != NULL)
182 fail=5;
183
184 if (!fail && solution->getProcDistribution() != NULL)
185 fail=6;
186
187 if (!fail &&
188 ((nprocs>1 && solution->criteriaHasUniformPartSizes(0)) ||
189 (nprocs==1 && !solution->criteriaHasUniformPartSizes(0))) )
190 fail=8;
191
192 if (!fail){
193 for (int partId=0; !fail && partId < numGlobalParts; partId++){
194 zscalar_t psize = solution->getCriteriaPartSize(0, partId);
195
196 if ( psize < normalizedPartSizes[partId] - epsilon ||
197 psize > normalizedPartSizes[partId] + epsilon )
198 fail=9;
199 }
200 }
201
202 delete [] normalizedPartSizes;
203
204 gfail = globalFail(*comm, fail);
205 if (gfail){
206 printFailureCode(*comm, fail); // exits after printing "FAIL"
207 }
208
209 // Test the Solution set method that is called by algorithms
210
211 zzpart_t *partAssignments = new zzpart_t [numIdsPerProc];
212 for (int i=0; i < numIdsPerProc; i++){
213 partAssignments[i] = myGids[i] % numGlobalParts; // round robin
214 }
215 ArrayRCP<zzpart_t> partList = arcp(partAssignments, 0, numIdsPerProc);
216
217 try{
218 solution->setParts(partList);
219 }
220 catch (std::exception &e){
221 fail=10;
222 }
223
224 gfail = globalFail(*comm, fail);
225 if (gfail){
226 printFailureCode(*comm, fail); // exits after printing "FAIL"
227 }
228
229 // Test the Solution get methods that may be called by users
230 // or migration functions.
231
232 if (!fail){
233 const zzpart_t *parts = solution->getPartListView();
234 for (int i=0; !fail && i < numIdsPerProc; i++){
235 if (parts[i] != zzpart_t(myGids[i] % numGlobalParts))
236 fail = 13;
237 }
238 }
239
240 gfail = globalFail(*comm, fail);
241 if (gfail){
242 printFailureCode(*comm, fail); // exits after printing "FAIL"
243 }
244
245 if (rank==0)
246 std::cout << "PASS" << std::endl;
247
249 // TODO:
251 // Create a solution object without part size information, and check it.
253 // Test multiple weights.
255 // Test multiple parts per process.
257 // Specify a list of parts of size 0. (The rest should be uniform.)
258
259 delete [] lengths;
260 for (int w=0; w < maxNumWeights; w++){
261 delete [] idLists[w];
262 delete [] sizeLists[w];
263 }
264 delete [] idLists;
265 delete [] sizeLists;
266 delete [] myGids;
267}
int globalFail(const Comm< int > &comm, int fail)
void printFailureCode(const Comm< int > &comm, int fail)
#define TEST_FAIL_AND_EXIT(comm, ok, s, code)
idInput_t::part_t zzpart_t
void makeArrays(int wdim, int *lens, zzpart_t **ids, zscalar_t **sizes, ArrayRCP< ArrayRCP< zzpart_t > > &idList, ArrayRCP< ArrayRCP< zscalar_t > > &sizeList)
Zoltan2::BasicIdentifierAdapter< zzuser_t > idInput_t
Zoltan2::BasicUserTypes< zscalar_t, zlno_t, zgno_t > zzuser_t
Defines the BasicIdentifierAdapter class.
Defines the PartitioningSolution class.
common code used by tests
float zscalar_t
Tpetra::Map ::global_ordinal_type zgno_t
int main()
This class represents a collection of global Identifiers and their associated weights,...
A simple class that can be the User template argument for an InputAdapter.
The user parameters, debug, timing and memory profiling output objects, and error checking methods.
A PartitioningSolution is a solution to a partitioning problem.
static const std::string fail
#define epsilon
Definition: nd.cpp:82