Zoltan2
PartitionAndParMATest.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 
53 /**************************************************************/
54 /* Includes */
55 /**************************************************************/
56 
60 
61 //Tpetra includes
62 #include "Tpetra_DefaultPlatform.hpp"
63 
64 // Teuchos includes
65 #include "Teuchos_RCP.hpp"
66 #include "Teuchos_GlobalMPISession.hpp"
67 #include "Teuchos_XMLParameterListHelpers.hpp"
68 
69 // SCOREC includes
70 #ifdef HAVE_ZOLTAN2_PARMA
71 #include <parma.h>
72 #include <apf.h>
73 #include <apfMesh.h>
74 #include <apfMDS.h>
75 #include <apfMesh2.h>
76 #include <PCU.h>
77 #include <gmi_mesh.h>
78 #endif
79 
80 using namespace std;
81 using Teuchos::ParameterList;
82 using Teuchos::RCP;
83 
84 /*********************************************************/
85 /* Typedefs */
86 /*********************************************************/
87 //Tpetra typedefs
88 typedef Tpetra::DefaultPlatform::DefaultPlatformType Platform;
89 
90 #ifdef HAVE_ZOLTAN2_PARMA
91 
92 void runTest(RCP<const Teuchos::Comm<int> >& CommT, apf::Mesh2* m,std::string action,
93  std::string parma_method,int nParts, double imbalance, std::string output_title );
94 
95 #endif
96 /*****************************************************************************/
97 /******************************** MAIN ***************************************/
98 /*****************************************************************************/
99 
100 int main(int narg, char *arg[]) {
101 
102  Teuchos::GlobalMPISession mpiSession(&narg, &arg,0);
103  Platform &platform = Tpetra::DefaultPlatform::getDefaultPlatform();
104  RCP<const Teuchos::Comm<int> > CommT = platform.getComm();
105 
106  int me = CommT->getRank();
107  //int numProcs = CommT->getSize();
108 
109  if (me == 0){
110  cout
111  << "====================================================================\n"
112  << "| |\n"
113  << "| Example: Partition APF Mesh |\n"
114  << "| |\n"
115  << "| Questions? Contact Karen Devine (kddevin@sandia.gov), |\n"
116  << "| Erik Boman (egboman@sandia.gov), |\n"
117  << "| Siva Rajamanickam (srajama@sandia.gov). |\n"
118  << "| |\n"
119  << "| Pamgen's website: http://trilinos.sandia.gov/packages/pamgen |\n"
120  << "| Zoltan2's website: http://trilinos.sandia.gov/packages/zoltan2 |\n"
121  << "| Trilinos website: http://trilinos.sandia.gov |\n"
122  << "| |\n"
123  << "====================================================================\n";
124  }
125 
126 
127 #ifdef HAVE_MPI
128  if (me == 0) {
129  cout << "PARALLEL executable \n";
130  }
131 #else
132  if (me == 0) {
133  cout << "SERIAL executable \n";
134  }
135 #endif
136 
137  /***************************************************************************/
138  /******************************* GET INPUTS ********************************/
139  /***************************************************************************/
140 
141  // default values for command-line arguments
142  std::string meshFileName("4/");
143  std::string modelFileName("torus.dmg");
144  std::string action("zoltan_hg");
145  std::string parma_method("VtxElm");
146  std::string output_loc("");
147  int nParts = CommT->getSize();
148  double imbalance=1.1;
149 
150  // Read run-time options.
151  Teuchos::CommandLineProcessor cmdp (false, false);
152  cmdp.setOption("meshfile", &meshFileName,
153  "Mesh file with APF specifications (.smb file(s))");
154  cmdp.setOption("modelfile", &modelFileName,
155  "Model file with APF specifications (.dmg file)");
156  cmdp.setOption("action", &action,
157  "Method to use: mj, scotch, zoltan_rcb, parma or color");
158  cmdp.setOption("parma_method", &parma_method,
159  "Method to use: Vertex, Edge, Element, VtxElm, VtxEdgeElm, ElmLtVtx, Ghost, or Shape ");
160  cmdp.setOption("nparts", &nParts,
161  "Number of parts to create");
162  cmdp.setOption("imbalance", &imbalance,
163  "Target Imbalance for first partitioner");
164  cmdp.setOption("output", &output_loc,
165  "Location of new partitioned apf mesh. Ex: 4/torus.smb");
166  cmdp.parse(narg, arg);
167 
168 
169  /***************************************************************************/
170  /********************** GET CELL TOPOLOGY **********************************/
171  /***************************************************************************/
172 
173  // Get dimensions
174  //int dim = 3;
175 
176  /***************************************************************************/
177  /***************************** GENERATE MESH *******************************/
178  /***************************************************************************/
179 
180 #ifdef HAVE_ZOLTAN2_PARMA
181 
182  if (me == 0) cout << "Generating mesh ... \n\n";
183 
184  //Setup for SCOREC
185  PCU_Comm_Init();
186 
187  // Generate mesh with MDS
188  gmi_register_mesh();
189  apf::Mesh2* m = apf::loadMdsMesh(modelFileName.c_str(),meshFileName.c_str());
190 
191  runTest(CommT,m,action,parma_method,nParts,imbalance,"partition");
192 
193  runTest(CommT,m,"parma",parma_method,nParts,imbalance,"parma");
194 
195 
196 
197 
198  if (output_loc!="") {
199  m->writeNative(output_loc.c_str());
200  }
201 
202  // delete mesh
203  if (me == 0) cout << "Deleting the mesh ... \n\n";
204 
205  //Delete APF Mesh;
206  m->destroyNative();
207  apf::destroyMesh(m);
208  //End communications
209  PCU_Comm_Free();
210 
211 #endif
212  if (me == 0)
213  std::cout << "PASS" << std::endl;
214 
215  return 0;
216 
217 }
218 /*****************************************************************************/
219 /********************************* END MAIN **********************************/
220 /*****************************************************************************/
221 
222 #ifdef HAVE_ZOLTAN2_PARMA
223 
224 void runTest(RCP<const Teuchos::Comm<int> >& CommT, apf::Mesh2* m,std::string action,
225  std::string parma_method,int nParts, double imbalance,std::string output_title) {
226  //Get rank
227  int me = CommT->getRank();
228 
229  //Data for APF MeshAdapter
230  std::string primary="region";
231  std::string adjacency="face";
232  if (m->getDimension()==2) {
233  primary="face";
234  adjacency="edge";
235  }
236  bool needSecondAdj=false;
237 
238  // Set parameters for partitioning
239  if (me == 0) cout << "Creating parameter list ... \n\n";
240 
241  Teuchos::ParameterList params("test params");
242  params.set("timer_output_stream" , "std::cout");
243 
244  if (action == "mj") {
245  params.set("debug_level", "basic_status");
246  params.set("imbalance_tolerance", imbalance);
247  params.set("num_global_parts", nParts);
248  params.set("algorithm", "multijagged");
249  params.set("rectilinear", "yes");
250  }
251  else if (action == "scotch") {
252  params.set("debug_level", "no_status");
253  params.set("imbalance_tolerance", imbalance);
254  params.set("num_global_parts", nParts);
255  params.set("partitioning_approach", "partition");
256  params.set("algorithm", "scotch");
257  needSecondAdj=true;
258  }
259  else if (action == "zoltan_rcb") {
260  params.set("debug_level", "verbose_detailed_status");
261  params.set("imbalance_tolerance", imbalance);
262  params.set("num_global_parts", nParts);
263  params.set("partitioning_approach", "partition");
264  params.set("algorithm", "zoltan");
265  }
266  else if (action == "parma") {
267  params.set("debug_level", "no_status");
268  params.set("imbalance_tolerance", imbalance);
269  params.set("algorithm", "parma");
270  Teuchos::ParameterList &pparams = params.sublist("parma_parameters",false);
271  pparams.set("parma_method",parma_method);
272  pparams.set("step_size",1.1);
273  if (parma_method=="Ghost") {
274  pparams.set("ghost_layers",3);
275  pparams.set("ghost_bridge",m->getDimension()-1);
276  }
277  adjacency="vertex";
278  }
279  else if (action=="zoltan_hg") {
280  params.set("debug_level", "no_status");
281  params.set("imbalance_tolerance", imbalance);
282  params.set("algorithm", "zoltan");
283  params.set("num_global_parts", nParts);
284  Teuchos::ParameterList &zparams = params.sublist("zoltan_parameters",false);
285  zparams.set("LB_METHOD","HYPERGRAPH");
286  //params.set("compute_metrics","yes");
287  adjacency="vertex";
288  }
289 
290  //Print the stats of original mesh
291  Parma_PrintPtnStats(m,output_title+"_before");
292 
293  // Creating mesh adapter
294  if (me == 0) cout << "Creating mesh adapter ... \n\n";
295  typedef Zoltan2::APFMeshAdapter<apf::Mesh2*> inputAdapter_t;
297  typedef Zoltan2::MeshAdapter<apf::Mesh2*> baseMeshAdapter_t;
298 
299  double time_1 = PCU_Time();
300  inputAdapter_t *ia =
301  new inputAdapter_t(*CommT, m,primary,adjacency,needSecondAdj);
302  double time_2 = PCU_Time();
303 
304 
305  // create Partitioning problem
306  if (me == 0) cout << "Creating partitioning problem ... \n\n";
307  double time_3=PCU_Time();
308  Zoltan2::PartitioningProblem<inputAdapter_t> problem(ia, &params, CommT);
309 
310  // call the partitioner
311  if (me == 0) cout << "Calling the partitioner ... \n\n";
312 
313  problem.solve();
314 
315 
316  //apply the partitioning solution to the mesh
317  if (me==0) cout << "Applying Solution to Mesh\n\n";
318  apf::Mesh2** new_mesh = &m;
319  ia->applyPartitioningSolution(m,new_mesh,problem.getSolution());
320  new_mesh=NULL;
321  double time_4=PCU_Time();
322 
323  //create metric object
324  RCP<quality_t> metricObject =
325  rcp(new quality_t(ia, &params, CommT, &problem.getSolution()));
326 
327  if (!me) {
328  metricObject->printMetrics(cout);
329  }
330 
331  //Print the stats after partitioning
332  Parma_PrintPtnStats(m,output_title+"_after");
333  ia->destroy();
334 
335  time_4-=time_3;
336  time_2-=time_1;
337  PCU_Max_Doubles(&time_2,1);
338  PCU_Max_Doubles(&time_4,1);
339  if (!me) {
340  std::cout<<"\n"<<output_title<<"Construction time: "<<time_2<<"\n"
341  <<output_title<<"Problem time: " << time_4<<"\n\n";
342  }
343 
344 }
345 
346 #endif
Defines the ColoringProblem class.
MeshAdapter defines the interface for mesh input.
bool runTest(Adapter &ia, const RCP< const Teuchos::Comm< int > > &comm, std::string hi)
Definition: Mapping.cpp:341
Tpetra::DefaultPlatform::DefaultPlatformType Platform
Defines the APFMeshAdapter class.
Tpetra::DefaultPlatform::DefaultPlatformType Platform
int main(int narg, char *arg[])
PartitioningProblem sets up partitioning problems for the user.
#define nParts
Defines the PartitioningProblem class.
A class that computes and returns quality metrics.