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