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<GraphModel<Adapter> > model;
118  const RCP<Teuchos::ParameterList> pl;
119  const RCP<const Teuchos::Comm<int> > comm;
120 
121  public:
122 
124  const RCP<GraphModel<Adapter> > &model__,
125  const RCP<Teuchos::ParameterList> &pl__,
126  const RCP<const Teuchos::Comm<int> > &comm__
127  ) : model(model__), pl(pl__), comm(comm__)
128  { }
129 
131  const RCP<GlobalOrderingSolution<typename Adapter::gno_t> > &/* solution */) {
132  throw std::logic_error("AlgAMD does not yet support global ordering.");
133  }
134 
137  {
138 #ifndef HAVE_ZOLTAN2_AMD
139  (void)solution; // remove unused parameter warning
140  throw std::runtime_error(
141  "BUILD ERROR: AMD requested but not compiled into Zoltan2.\n"
142  "Please set CMake flag Zoltan2_ENABLE_AMD:BOOL=ON.");
143 #else
144  typedef typename Adapter::gno_t gno_t;
145  typedef typename Adapter::lno_t lno_t;
146  typedef typename Adapter::offset_t offset_t;
147  typedef typename Adapter::scalar_t scalar_t;
148 
149  int ierr= 0;
150 
151  const size_t nVtx = model->getLocalNumVertices();
152 
153  //cout << "Local num vertices" << nVtx << endl;
154  ArrayView<const gno_t> edgeIds;
155  ArrayView<const offset_t> offsets;
156  ArrayView<StridedData<lno_t, scalar_t> > wgts;
157 
158  // wgts are ignored in AMD
159  model->getEdgeList(edgeIds, offsets, wgts);
160 
161  // We will always call AMD with SuiteSparse_long
162  AMDTraits<SuiteSparse_long> AMDobj;
163  double Control[AMD_CONTROL];
164  double Info[AMD_INFO];
165 
166  amd_defaults(Control);
167  amd_control(Control);
168 
169  // We will use the lno_t for local ordering
170  lno_t *perm;
171  perm = (lno_t *) (solution->getPermutationRCP().getRawPtr());
172 
173  SuiteSparse_long *amd_offsets, *amd_edgeIds;
175  offsets);
176  // This might throw depending on how SuiteSparse was compiled
177  // with long or long long and the size of both of them
179  edgeIds);
180 
181  SuiteSparse_long amd_nVtx=0;
183 
184  // Allocate a SuiteSparse_long perm
185  SuiteSparse_long *amd_perm = new SuiteSparse_long[amd_nVtx];
186 
187  lno_t result = AMDobj.order(amd_nVtx, amd_offsets,
188  amd_edgeIds, amd_perm, Control, Info);
189 
190  if (result != AMD_OK && result != AMD_OK_BUT_JUMBLED)
191  ierr = -1;
192 
193  // SR: This conversion might throw as we are going from SuiteSparse_long
194  // to lno_t. Another option is to change local ordering solution
195  // to use gno_t everywhere
196  for (size_t i = 0; i < nVtx; i++)
197  TPL_Traits<lno_t, SuiteSparse_long>::ASSIGN(perm[i], amd_perm[i]);
198 
199  // Delete copies
202  delete [] amd_perm;
203 
204  solution->setHavePerm(true);
205  return ierr;
206 #endif
207  }
208 };
209 
210 }
211 
212 
213 
214 #endif
Defines the OrderingSolution class.
AlgAMD(const RCP< GraphModel< Adapter > > &model__, const RCP< Teuchos::ParameterList > &pl__, const RCP< const Teuchos::Comm< int > > &comm__)
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.
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.