Zoltan2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Zoltan2_AlgAMD.hpp
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 
50 #ifndef _ZOLTAN2_ALGAMD_HPP_
51 #define _ZOLTAN2_ALGAMD_HPP_
52 
53 #include <Zoltan2_Algorithm.hpp>
54 #include <Zoltan2_GraphModel.hpp>
56 #include <Zoltan2_TPLTraits.hpp>
57 
58 
59 #ifdef HAVE_ZOLTAN2_AMD
60 #include "amd.h"
61 #ifdef SUITESPARSE_MAIN_VERSION
62 #if SUITESPARSE_MAIN_VERSION < 4
63 typedef UF_long SuiteSparse_long;
64 #endif
65 #endif
66 #endif
67 
68 
69 
70 namespace Zoltan2{
71 
72 
73 #ifdef HAVE_ZOLTAN2_AMD
74 template <typename Ordinal>
75 class AMDTraits
76 {
77  public:
78  Ordinal order(Ordinal n, const Ordinal *Ap, const Ordinal *Ai,
79  Ordinal *perm, double *control, double *info);
80 };
81 
82 template <>
83 class AMDTraits<int>
84 {
85  public:
86  int order(int n, const int *Ap, const int *Ai, int *perm,
87  double *control, double *info)
88  {
89  return (amd_order(n, Ap, Ai, perm, control, info));
90  }
91 };
92 
93 template <>
94 class AMDTraits<SuiteSparse_long>
95 {
96  public:
97  long order(SuiteSparse_long n, const SuiteSparse_long *Ap,
98  const SuiteSparse_long *Ai, SuiteSparse_long *perm,
99  double *control, double *info)
100  {
101  return (amd_l_order(n, Ap, Ai, perm, control, info));
102  }
103 };
104 
105 #endif
106 
107 }
108 
109 
110 namespace Zoltan2{
111 
112 template <typename Adapter>
113 class AlgAMD : public Algorithm<Adapter>
114 {
115  private:
116 
117  const RCP<const typename Adapter::base_adapter_t> adapter;
118  const RCP<Teuchos::ParameterList> pl;
119  const RCP<const Teuchos::Comm<int> > comm;
120  RCP<const Environment> env;
121  modelFlag_t graphFlags;
122 
123  public:
124 
126  const RCP<const typename Adapter::base_adapter_t> &adapter__,
127  const RCP<Teuchos::ParameterList> &pl__,
128  const RCP<const Teuchos::Comm<int> > &comm__,
129  RCP<const Environment> &env__,
130  const modelFlag_t &graphFlags__
131  ) : adapter(adapter__), pl(pl__), comm(comm__), env(env__), graphFlags(graphFlags__)
132  { }
133 
135  const RCP<GlobalOrderingSolution<typename Adapter::gno_t> > &/* solution */) {
136  throw std::logic_error("AlgAMD does not yet support global ordering.");
137  }
138 
141  {
142 #ifndef HAVE_ZOLTAN2_AMD
143  (void)solution; // remove unused parameter warning
144  throw std::runtime_error(
145  "BUILD ERROR: AMD requested but not compiled into Zoltan2.\n"
146  "Please set CMake flag Zoltan2_ENABLE_AMD:BOOL=ON.");
147 #else
148  typedef typename Adapter::gno_t gno_t;
149  typedef typename Adapter::lno_t lno_t;
150  typedef typename Adapter::offset_t offset_t;
151  typedef typename Adapter::scalar_t scalar_t;
152 
153  int ierr= 0;
154 
155  const auto model = rcp(new GraphModel<Adapter>(adapter, env, comm, graphFlags));
156  const size_t nVtx = model->getLocalNumVertices();
157 
158  //cout << "Local num vertices" << nVtx << endl;
159  ArrayView<const gno_t> edgeIds;
160  ArrayView<const offset_t> offsets;
161  ArrayView<StridedData<lno_t, scalar_t> > wgts;
162 
163  // wgts are ignored in AMD
164  model->getEdgeList(edgeIds, offsets, wgts);
165 
166  // We will always call AMD with SuiteSparse_long
167  AMDTraits<SuiteSparse_long> AMDobj;
168  double Control[AMD_CONTROL];
169  double Info[AMD_INFO];
170 
171  amd_defaults(Control);
172  amd_control(Control);
173 
174  // We will use the lno_t for local ordering
175  lno_t *perm;
176  perm = (lno_t *) (solution->getPermutationRCP().getRawPtr());
177 
178  SuiteSparse_long *amd_offsets, *amd_edgeIds;
180  offsets);
181  // This might throw depending on how SuiteSparse was compiled
182  // with long or long long and the size of both of them
184  edgeIds);
185 
186  SuiteSparse_long amd_nVtx=0;
188 
189  // Allocate a SuiteSparse_long perm
190  SuiteSparse_long *amd_perm = new SuiteSparse_long[amd_nVtx];
191 
192  lno_t result = AMDobj.order(amd_nVtx, amd_offsets,
193  amd_edgeIds, amd_perm, Control, Info);
194 
195  if (result != AMD_OK && result != AMD_OK_BUT_JUMBLED)
196  ierr = -1;
197 
198  // SR: This conversion might throw as we are going from SuiteSparse_long
199  // to lno_t. Another option is to change local ordering solution
200  // to use gno_t everywhere
201  for (size_t i = 0; i < nVtx; i++)
202  TPL_Traits<lno_t, SuiteSparse_long>::ASSIGN(perm[i], amd_perm[i]);
203 
204  // Delete copies
207  delete [] amd_perm;
208 
209  solution->setHavePerm(true);
210  return ierr;
211 #endif
212  }
213 };
214 
215 }
216 
217 
218 
219 #endif
AlgAMD(const RCP< const typename Adapter::base_adapter_t > &adapter__, const RCP< Teuchos::ParameterList > &pl__, const RCP< const Teuchos::Comm< int > > &comm__, RCP< const Environment > &env__, const modelFlag_t &graphFlags__)
std::bitset< NUM_MODEL_FLAGS > modelFlag_t
map_t::global_ordinal_type gno_t
Definition: mapRemotes.cpp:18
Defines the OrderingSolution class.
Adapter::scalar_t scalar_t
int localOrder(const RCP< LocalOrderingSolution< typename Adapter::lno_t > > &solution)
Ordering method.
Algorithm defines the base class for all algorithms.
map_t::local_ordinal_type lno_t
Definition: mapRemotes.cpp:17
static void ASSIGN(first_t &a, second_t b)
Traits class to handle conversions between gno_t/lno_t and TPL data types (e.g., ParMETIS&#39;s idx_t...
GraphModel defines the interface required for graph models.
static void ASSIGN_ARRAY(first_t **a, ArrayView< second_t > &b)
Defines the GraphModel interface.
static void DELETE_ARRAY(first_t **a)
int globalOrder(const RCP< GlobalOrderingSolution< typename Adapter::gno_t > > &)
Ordering method.