Salome HOME
Merge from V6_main_20120808 08Aug12
[modules/med.git] / src / MEDPartitioner / MEDPARTITIONER_ParMetisGraph.cxx
1 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include "MEDPARTITIONER_MetisGraph.hxx"
21 #include "MEDPARTITIONER_ParaDomainSelector.hxx"
22 #include "MEDPARTITIONER_Utils.hxx"
23
24 #include "InterpKernelException.hxx"
25
26 #include <iostream>
27
28 #ifdef MED_ENABLE_PARMETIS
29 #include <mpi.h>
30 #include "parmetis.h"
31 #endif
32
33 using namespace MEDPARTITIONER;
34
35 METISGraph::METISGraph():Graph()
36 {
37 }
38
39 METISGraph::METISGraph(MEDPARTITIONER::SkyLineArray* graph, int* edgeweight)
40   :Graph(graph,edgeweight)
41 {
42 }
43
44 METISGraph::~METISGraph()
45 {
46 }
47
48 void METISGraph::partGraph(int ndomain,
49                            const std::string& options_string,
50                            ParaDomainSelector *parallelizer)
51 {
52   using std::vector;
53   vector<int> ran,vx,va; //for randomize
54   
55   if (MyGlobals::_Verbose>10)
56     std::cout << "proc " << MyGlobals::_Rank << " : METISGraph::partGraph" << std::endl;
57   
58   // number of graph vertices
59   int n=_graph->getNumberOf();
60   //graph
61   int * xadj=const_cast<int*>(_graph->getIndex());
62   int * adjncy=const_cast<int*>(_graph->getValue());
63   //constraints
64   int * vwgt=_cell_weight;
65   int * adjwgt=_edge_weight;
66   int wgtflag=(_edge_weight!=0)?1:0+(_cell_weight!=0)?2:0;
67   //base 0 or 1
68   int base=0;
69   //ndomain
70   int nparts=ndomain;
71   //options
72   /*
73     (0=default_option,option,random_seed) see defs.h
74     #define PMV3_OPTION_DBGLVL 1
75     #define PMV3_OPTION_SEED 2
76     #define PMV3_OPTION_IPART 3
77     #define PMV3_OPTION_PSR 3
78     seems no changes int options[4]={1,0,33,0}; //test for a random seed of 33
79   */
80   int options[4]={0,0,0,0};
81   // output parameters
82   int edgecut;
83 #if !defined(MED_ENABLE_PARMETIS)
84   throw INTERP_KERNEL::Exception("METISGraph::partGraph : PARMETIS is not available. Check your products, please.");
85 #else
86   int* partition=new int[n];
87   
88   if (MyGlobals::_Verbose>10) 
89     std::cout << "proc " << MyGlobals::_Rank << " : METISGraph::partGraph ParMETIS_PartKway new" << std::endl;
90   int * vtxdist=parallelizer->getProcVtxdist();
91   MPI_Comm comm=MPI_COMM_WORLD;
92   ParMETIS_PartKway(vtxdist, xadj, adjncy, vwgt, 
93                                     adjwgt, &wgtflag, &base, &nparts, options, 
94                                     &edgecut, partition, &comm );
95
96
97   /*doc from parmetis.h
98     void __cdecl ParMETIS_PartKway(
99     idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, 
100     idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, 
101     int *edgecut, idxtype *part, MPI_Comm *comm);
102
103     void __cdecl ParMETIS_V3_PartKway(
104     idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, 
105     idxtype *adjwgt, int *wgtflag, int *numflag, int *ncon, int *nparts, 
106     float *tpwgts, float *ubvec, int *options, int *edgecut, idxtype *part, 
107     MPI_Comm *comm);
108   */
109
110   vector<int> index(n+1);
111   vector<int> value(n);
112   index[0]=0;
113   if (ran.size()>0 && MyGlobals::_Atomize==0) //there is randomize
114     {
115       if (MyGlobals::_Is0verbose>100)
116         std::cout << "randomize" << std::endl;
117       for (int i=0; i<n; i++)
118         {
119           index[i+1]=index[i]+1;
120           value[ran[i]]=partition[i];
121         }
122     }
123   else
124     {
125       for (int i=0; i<n; i++)
126         {
127           index[i+1]=index[i]+1;
128           value[i]=partition[i];
129         }
130     }
131   delete [] partition;
132
133   //creating a skylinearray with no copy of the index and partition array
134   //the fifth argument true specifies that only the pointers are passed 
135   //to the object
136   
137   _partition = new MEDPARTITIONER::SkyLineArray(index,value);
138 #endif
139 }
140