~chaffra/+junk/trilinos

« back to all changes in this revision

Viewing changes to packages/isorropia/src/epetra/zoltanLib/Isorropia_Zoltan_Repartition.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Christophe Prud'homme, Christophe Prud'homme, Johannes Ring
  • Date: 2009-12-13 12:53:22 UTC
  • mfrom: (5.1.2 sid)
  • Revision ID: james.westby@ubuntu.com-20091213125322-in0nrdjc55deqsw9
Tags: 10.0.3.dfsg-1
[Christophe Prud'homme]
* New upstream release

[Johannes Ring]
* debian/patches/libname.patch: Add prefix 'libtrilinos_' to all
  libraries. 
* debian/patches/soname.patch: Add soversion to libraries.
* debian/watch: Update download URL.
* debian/control:
  - Remove python-numeric from Build-Depends (virtual package).
  - Remove automake and autotools from Build-Depends and add cmake to
    reflect switch to CMake.
  - Add python-support to Build-Depends.
* debian/rules: 
  - Cleanup and updates for switch to CMake.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//@HEADER
 
2
/*
 
3
************************************************************************
 
4
 
 
5
              Isorropia: Partitioning and Load Balancing Package
 
6
                Copyright (2006) Sandia Corporation
 
7
 
 
8
Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
 
9
license for use of this work by or on behalf of the U.S. Government.
 
10
 
 
11
This library is free software; you can redistribute it and/or modify
 
12
it under the terms of the GNU Lesser General Public License as
 
13
published by the Free Software Foundation; either version 2.1 of the
 
14
License, or (at your option) any later version.
 
15
 
 
16
This library is distributed in the hope that it will be useful, but
 
17
WITHOUT ANY WARRANTY; without even the implied warranty of
 
18
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
19
Lesser General Public License for more details.
 
20
 
 
21
You should have received a copy of the GNU Lesser General Public
 
22
License along with this library; if not, write to the Free Software
 
23
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 
24
USA
 
25
 
 
26
************************************************************************
 
27
*/
 
28
//@HEADER
 
29
 
 
30
#include <Isorropia_Zoltan_Repartition.hpp>
 
31
 
 
32
#ifdef HAVE_ISORROPIA_ZOLTAN
 
33
 
 
34
#ifndef HAVE_MPI
 
35
#error "Isorropia_Zoltan requires MPI."
 
36
#endif
 
37
 
 
38
#include <Isorropia_Exception.hpp>
 
39
 
 
40
#include <Teuchos_RefCountPtr.hpp>
 
41
 
 
42
#ifdef HAVE_EPETRA
 
43
#include <Epetra_Map.h>
 
44
#include <Epetra_RowMatrix.h>
 
45
#ifdef HAVE_MPI
 
46
#include <Epetra_MpiComm.h>
 
47
#endif
 
48
#include <Epetra_CrsGraph.h>
 
49
#endif
 
50
 
 
51
#include <QueryObject.hpp>
 
52
 
 
53
namespace Isorropia {
 
54
 
 
55
namespace Epetra {
 
56
 
 
57
namespace ZoltanLib {
 
58
 
 
59
static int me = 0;
 
60
 
 
61
//TODO do we need to add these functions for geometric partitioning? 
 
62
// Are these being used?
 
63
 
 
64
int
 
65
repartition(Teuchos::RefCountPtr<const Epetra_CrsGraph> input_graph,
 
66
            Teuchos::RefCountPtr<const Isorropia::Epetra::CostDescriber> costs,
 
67
            Teuchos::ParameterList& paramlist,
 
68
            std::vector<int>& myNewElements,
 
69
            std::map<int,int>& exports,
 
70
            std::map<int,int>& imports)
 
71
{
 
72
  int inputType = QueryObject::hgraph_input_;
 
73
  std::string lb_method_str("LB_METHOD");
 
74
  if (paramlist.isParameter(lb_method_str)){
 
75
    std::string lb_meth = paramlist.get(lb_method_str, "HYPERGRAPH");
 
76
    if (lb_meth == "GRAPH"){
 
77
      inputType = QueryObject::graph_input_;
 
78
    }
 
79
  }
 
80
 
 
81
  Teuchos::RefCountPtr<QueryObject> queryObject = 
 
82
      Teuchos::rcp(new QueryObject(input_graph, costs, inputType));
 
83
 
 
84
  const Epetra_Comm &ecomm = input_graph->RowMap().Comm();
 
85
#ifdef HAVE_MPI
 
86
  const Epetra_MpiComm &empicomm = dynamic_cast<const Epetra_MpiComm &>(ecomm);
 
87
 
 
88
  MPI_Comm mpicomm = empicomm.Comm();
 
89
 
 
90
  return( load_balance(mpicomm, paramlist, *queryObject,
 
91
                       myNewElements, exports, imports) );
 
92
#else
 
93
  return (1);
 
94
#endif
 
95
}
 
96
 
 
97
int
 
98
repartition(Teuchos::RefCountPtr<const Epetra_RowMatrix> input_matrix,
 
99
            Teuchos::RefCountPtr<const Isorropia::Epetra::CostDescriber> costs,
 
100
            Teuchos::ParameterList& paramlist,
 
101
            std::vector<int>& myNewElements,
 
102
            std::map<int,int>& exports,
 
103
            std::map<int,int>& imports)
 
104
{
 
105
  int inputType = QueryObject::hgraph_input_;
 
106
  std::string lb_method_str("LB_METHOD");
 
107
  if (paramlist.isParameter(lb_method_str)){
 
108
    std::string lb_meth = paramlist.get(lb_method_str, "HYPERGRAPH");
 
109
    if (lb_meth == "GRAPH"){
 
110
      inputType = QueryObject::graph_input_;
 
111
    }
 
112
  }
 
113
 
 
114
  Teuchos::RefCountPtr<QueryObject> queryObject = 
 
115
    Teuchos::rcp(new QueryObject(input_matrix, costs, inputType));
 
116
 
 
117
  const Epetra_Comm &ecomm = input_matrix->RowMatrixRowMap().Comm();
 
118
#ifdef HAVE_MPI
 
119
  const Epetra_MpiComm &empicomm = dynamic_cast<const Epetra_MpiComm &>(ecomm);
 
120
 
 
121
  MPI_Comm mpicomm = empicomm.Comm();
 
122
 
 
123
  return( load_balance(mpicomm, paramlist, *queryObject,
 
124
                       myNewElements, exports, imports) );
 
125
#else
 
126
  return (1);
 
127
#endif
 
128
}
 
129
 
 
130
#ifdef HAVE_MPI
 
131
int
 
132
load_balance(MPI_Comm &comm,
 
133
             Teuchos::ParameterList& paramlist,
 
134
             QueryObject& queryObject,
 
135
             std::vector<int>& myNewElements,
 
136
             std::map<int,int>& exports,
 
137
             std::map<int,int>& imports)
 
138
{
 
139
  float version;
 
140
  int argcTmp=0;
 
141
  char *argvTmp[1];
 
142
 
 
143
  // create a Zoltan problem
 
144
 
 
145
  argvTmp[0] = NULL;
 
146
  Zoltan_Initialize(argcTmp, argvTmp, &version);
 
147
 
 
148
  Zoltan *zz = new Zoltan(comm);
 
149
 
 
150
  if (zz == NULL){
 
151
    throw Isorropia::Exception("Error creating Zoltan object");
 
152
    return -1;    
 
153
  }
 
154
 
 
155
  // set problem parameters
 
156
 
 
157
  std::string dbg_level_str("DEBUG_LEVEL");
 
158
  if (!paramlist.isParameter(dbg_level_str)) {
 
159
    paramlist.set(dbg_level_str, "0");
 
160
  }
 
161
 
 
162
  std::string lb_approach_str("LB_APPROACH");
 
163
  if (!paramlist.isParameter(lb_approach_str)) {
 
164
    paramlist.set(lb_approach_str, "PARTITION");
 
165
  }
 
166
 
 
167
  std::string lb_method_str("LB_METHOD");
 
168
  std::string lb_meth = paramlist.get(lb_method_str, "HYPERGRAPH");
 
169
 
 
170
  if (!paramlist.isParameter(lb_method_str)) {
 
171
    paramlist.set(lb_method_str, lb_meth);  // set to HYPERGRAPH
 
172
  }
 
173
 
 
174
  // If no process set vertex weights, let Zoltan default to
 
175
  // unit weights for vertices
 
176
 
 
177
  if (queryObject.haveVertexWeights()) {
 
178
    if (!paramlist.isParameter("OBJ_WEIGHT_DIM")) {
 
179
      paramlist.set("OBJ_WEIGHT_DIM", "1");
 
180
    }
 
181
  }
 
182
 
 
183
  // If no process set graph or hypergraph edge weights, 
 
184
  // let Zoltan default to unit weights for edges
 
185
 
 
186
  if (queryObject.haveGraphEdgeWeights() ||
 
187
      queryObject.haveHypergraphEdgeWeights()) {
 
188
    if (!paramlist.isParameter("EDGE_WEIGHT_DIM")) {
 
189
      paramlist.set("EDGE_WEIGHT_DIM", "1");
 
190
    }
 
191
  }
 
192
 
 
193
  Teuchos::ParameterList::ConstIterator
 
194
    iter = paramlist.begin(),
 
195
    iter_end = paramlist.end();
 
196
 
 
197
  for(; iter != iter_end; ++iter) {
 
198
    const std::string& name = iter->first;
 
199
    const std::string& value = Teuchos::getValue<std::string>(iter->second);
 
200
    zz->Set_Param(name, value);
 
201
  }
 
202
 
 
203
  // Set the query functions
 
204
 
 
205
  zz->Set_Num_Obj_Fn(QueryObject::Number_Objects, (void *)&queryObject);
 
206
  zz->Set_Obj_List_Fn(QueryObject::Object_List, (void *)&queryObject);
 
207
 
 
208
  if (lb_meth == "HYPERGRAPH"){
 
209
    zz->Set_HG_Size_CS_Fn(QueryObject::HG_Size_CS, (void *)&queryObject);
 
210
    zz->Set_HG_CS_Fn(QueryObject::HG_CS, (void *)&queryObject);
 
211
    zz->Set_HG_Size_Edge_Wts_Fn(QueryObject::HG_Size_Edge_Weights , 
 
212
                                (void *)&queryObject);
 
213
    zz->Set_HG_Edge_Wts_Fn(QueryObject::HG_Edge_Weights, (void *)&queryObject);
 
214
  }
 
215
  else{
 
216
    zz->Set_Num_Edges_Multi_Fn(QueryObject::Number_Edges_Multi, (void *)&queryObject);
 
217
    zz->Set_Edge_List_Multi_Fn(QueryObject::Edge_List_Multi, (void *)&queryObject);
 
218
  }
 
219
 
 
220
  //Generate Load Balance
 
221
  int changes, num_gid_entries, num_lid_entries, num_import, num_export;
 
222
  ZOLTAN_ID_PTR import_global_ids, import_local_ids;
 
223
  ZOLTAN_ID_PTR export_global_ids, export_local_ids;
 
224
  int * import_procs, * export_procs;
 
225
  int *import_to_part, *export_to_part;
 
226
 
 
227
  int err = zz->LB_Partition(changes, num_gid_entries, num_lid_entries,
 
228
   num_import, import_global_ids, import_local_ids, import_procs, import_to_part,
 
229
   num_export, export_global_ids, export_local_ids, export_procs, export_to_part );
 
230
 
 
231
  if (err != ZOLTAN_OK){
 
232
    throw Isorropia::Exception("Error computing partitioning with Zoltan");
 
233
    return -1;
 
234
  }
 
235
 
 
236
  //Generate New Element List
 
237
  int numMyElements = queryObject.RowMap().NumMyElements();
 
238
  std::vector<int> elementList( numMyElements );
 
239
  queryObject.RowMap().MyGlobalElements( &elementList[0] );
 
240
 
 
241
  int newNumMyElements = numMyElements - num_export + num_import;
 
242
  myNewElements.resize( newNumMyElements );
 
243
 
 
244
  for( int i = 0; i < num_export; ++i ) {
 
245
    exports[export_global_ids[i]] = export_procs[i];
 
246
  }
 
247
 
 
248
  for( int i = 0; i < num_import; ++i ) {
 
249
    imports[import_global_ids[i]] = import_procs[i];
 
250
  }
 
251
 
 
252
  //Add unmoved indices to new list
 
253
  int loc = 0;
 
254
  for( int i = 0; i < numMyElements; ++i ) {
 
255
    if( !exports.count( elementList[i] ) ) {
 
256
      myNewElements[loc++] = elementList[i];
 
257
    }
 
258
  }
 
259
  
 
260
  //Add imports to end of list
 
261
  for( int i = 0; i < num_import; ++i ) {
 
262
    myNewElements[loc+i] = import_global_ids[i];
 
263
  }
 
264
 
 
265
  //Free Zoltan Data
 
266
  zz->LB_Free_Part(&import_global_ids, &import_local_ids, 
 
267
                     &import_procs, &import_to_part);
 
268
  zz->LB_Free_Part(&export_global_ids, &export_local_ids, 
 
269
                     &export_procs, &export_to_part);
 
270
 
 
271
  delete zz;
 
272
 
 
273
  return( 0 );
 
274
}
 
275
#endif
 
276
 
 
277
}//namespace ZoltanLib
 
278
}//namespace Epetra
 
279
}//namespace Isorropia
 
280
 
 
281
#endif
 
282