Salome HOME
Parallel partitionner compile fix ...
[tools/medcoupling.git] / src / MEDPartitioner / MEDPARTITIONER_ParMetisGraph.cxx
1 // Copyright (C) 2007-2020  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, or (at your option) any later version.
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_ParMetisGraph.hxx"
21 #include "MEDPARTITIONER_ParaDomainSelector.hxx"
22 #include "MEDPARTITIONER_Utils.hxx"
23
24 #include "MEDCouplingSkyLineArray.hxx"
25 #include "InterpKernelException.hxx"
26
27 #include <iostream>
28
29 #ifdef MED_ENABLE_PARMETIS
30 #include <parmetis.h>
31 // #if PARMETIS_MAJOR_VERSION == 4
32 //    #define ParMETIS_PartKway ParMETIS_V3_PartKway
33 // #endif
34 #endif
35
36 using namespace MEDPARTITIONER;
37
38 ParMETISGraph::ParMETISGraph():Graph()
39 {
40 }
41
42 ParMETISGraph::ParMETISGraph(MEDCoupling::MEDCouplingSkyLineArray* graph, int* edgeweight)
43   :Graph(graph,edgeweight)
44 {
45 }
46
47 ParMETISGraph::~ParMETISGraph()
48 {
49 }
50
51 void ParMETISGraph::partGraph(int ndomain,
52                            const std::string& options_string,
53                            ParaDomainSelector *parallelizer)
54 {
55   using std::vector;
56   vector<int> ran,vx,va; //for randomize
57   
58   if (MyGlobals::_Verbose>10)
59     std::cout << "proc " << MyGlobals::_Rank << " : ParMETISGraph::partGraph" << std::endl;
60   
61   // number of graph vertices
62   int n=FromIdType<int>(_graph->getNumberOf());
63   //graph
64 #ifdef MEDCOUPLING_USE_64BIT_IDS
65   std::vector<int> indexVec( _graph->getIndex(), _graph->getIndexArray()->end() );
66   std::vector<int> valueVec( _graph->getValues(), _graph->getValuesArray()->end() );
67   int * xadj=indexVec.data();
68   int * adjncy=valueVec.data();
69 #else
70   int * xadj=const_cast<int*>(_graph->getIndex());
71   int * adjncy=const_cast<int*>(_graph->getValues());
72 #endif
73   //constraints
74   int * vwgt=_cell_weight;
75   int * adjwgt=_edge_weight;
76   int wgtflag=(_edge_weight!=0)?1:0+(_cell_weight!=0)?2:0;
77   //base 0 or 1
78   int base=0;
79   //ndomain
80   int nparts=ndomain;
81   //options
82   /*
83     (0=default_option,option,random_seed) see defs.h
84     #define PMV3_OPTION_DBGLVL 1
85     #define PMV3_OPTION_SEED 2
86     #define PMV3_OPTION_IPART 3
87     #define PMV3_OPTION_PSR 3
88     seems no changes int options[4]={1,0,33,0}; //test for a random seed of 33
89   */
90   int options[4]={0,0,0,0};
91   // output parameters
92   int edgecut;
93 #if !defined(MED_ENABLE_PARMETIS)
94   throw INTERP_KERNEL::Exception("ParMETISGraph::partGraph : PARMETIS is not available. Check your products, please.");
95 #else
96   int* partition=new int[n];
97   
98   if (MyGlobals::_Verbose>10) 
99     std::cout << "proc " << MyGlobals::_Rank << " : ParMETISGraph::partGraph ParMETIS_PartKway new" << std::endl;
100   int * vtxdist=parallelizer->getProcVtxdist();
101   MPI_Comm comm=MPI_COMM_WORLD;
102   ParMETIS_PartKway(vtxdist, xadj, adjncy, vwgt, 
103                                     adjwgt, &wgtflag, &base, &nparts, options, 
104                                     &edgecut, partition, &comm );
105
106
107   /*doc from parmetis.h
108     void __cdecl ParMETIS_PartKway(
109     idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, 
110     idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, 
111     int *edgecut, idxtype *part, MPI_Comm *comm);
112
113     void __cdecl ParMETIS_V3_PartKway(
114     idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, 
115     idxtype *adjwgt, int *wgtflag, int *numflag, int *ncon, int *nparts, 
116     float *tpwgts, float *ubvec, int *options, int *edgecut, idxtype *part, 
117     MPI_Comm *comm);
118   */
119
120   vector<mcIdType> index(n+1);
121   vector<mcIdType> value(n);
122   index[0]=0;
123   if (ran.size()>0 && MyGlobals::_Atomize==0) //there is randomize
124     {
125       if (MyGlobals::_Is0verbose>100)
126         std::cout << "randomize" << std::endl;
127       for (int i=0; i<n; i++)
128         {
129           index[i+1]=index[i]+1;
130           value[ran[i]]=ToIdType(partition[i]);
131         }
132     }
133   else
134     {
135       for (int i=0; i<n; i++)
136         {
137           index[i+1]=index[i]+1;
138           value[i]=ToIdType(partition[i]);
139         }
140     }
141   delete [] partition;
142
143   //creating a skylinearray with no copy of the index and partition array
144   //the fifth argument true specifies that only the pointers are passed 
145   //to the object
146   
147   _partition = MEDCoupling::MEDCouplingSkyLineArray::New(index,value);
148 #endif
149 }
150