Zoltan2
Loading...
Searching...
No Matches
Zoltan2_AlgAMD.hpp
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// Zoltan2: A package of combinatorial algorithms for scientific computing
4//
5// Copyright 2012 NTESS and the Zoltan2 contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
14#ifndef _ZOLTAN2_ALGAMD_HPP_
15#define _ZOLTAN2_ALGAMD_HPP_
16
17#include <Zoltan2_Algorithm.hpp>
20#include <Zoltan2_TPLTraits.hpp>
21
22
23#ifdef HAVE_ZOLTAN2_AMD
24#include "amd.h"
25#ifdef SUITESPARSE_MAIN_VERSION
26#if SUITESPARSE_MAIN_VERSION < 4
27typedef UF_long SuiteSparse_long;
28#endif
29#endif
30#endif
31
32
33
34namespace Zoltan2{
35
36
37#ifdef HAVE_ZOLTAN2_AMD
38template <typename Ordinal>
39class AMDTraits
40{
41 public:
42 Ordinal order(Ordinal n, const Ordinal *Ap, const Ordinal *Ai,
43 Ordinal *perm, double *control, double *info);
44};
45
46template <>
47class AMDTraits<int>
48{
49 public:
50 int order(int n, const int *Ap, const int *Ai, int *perm,
51 double *control, double *info)
52 {
53 return (amd_order(n, Ap, Ai, perm, control, info));
54 }
55};
56
57template <>
58class AMDTraits<SuiteSparse_long>
59{
60 public:
61 long order(SuiteSparse_long n, const SuiteSparse_long *Ap,
62 const SuiteSparse_long *Ai, SuiteSparse_long *perm,
63 double *control, double *info)
64 {
65 return (amd_l_order(n, Ap, Ai, perm, control, info));
66 }
67};
68
69#endif
70
71}
72
73
74namespace Zoltan2{
75
76template <typename Adapter>
77class AlgAMD : public Algorithm<Adapter>
78{
79 private:
80
81 const RCP<const typename Adapter::base_adapter_t> adapter;
82 const RCP<Teuchos::ParameterList> pl;
83 const RCP<const Teuchos::Comm<int> > comm;
84 RCP<const Environment> env;
85 modelFlag_t graphFlags;
86
87 public:
88
90 const RCP<const typename Adapter::base_adapter_t> &adapter__,
91 const RCP<Teuchos::ParameterList> &pl__,
92 const RCP<const Teuchos::Comm<int> > &comm__,
93 RCP<const Environment> &env__,
94 const modelFlag_t &graphFlags__
95 ) : adapter(adapter__), pl(pl__), comm(comm__), env(env__), graphFlags(graphFlags__)
96 { }
97
99 const RCP<GlobalOrderingSolution<typename Adapter::gno_t> > &/* solution */) {
100 throw std::logic_error("AlgAMD does not yet support global ordering.");
101 }
102
105 {
106#ifndef HAVE_ZOLTAN2_AMD
107 (void)solution; // remove unused parameter warning
108 throw std::runtime_error(
109 "BUILD ERROR: AMD requested but not compiled into Zoltan2.\n"
110 "Please set CMake flag Zoltan2_ENABLE_AMD:BOOL=ON.");
111#else
112 typedef typename Adapter::gno_t gno_t;
113 typedef typename Adapter::lno_t lno_t;
114 typedef typename Adapter::offset_t offset_t;
115 typedef typename Adapter::scalar_t scalar_t;
116
117 int ierr= 0;
118
119 const auto model = rcp(new GraphModel<Adapter>(adapter, env, comm, graphFlags));
120 const size_t nVtx = model->getLocalNumVertices();
121
122 //cout << "Local num vertices" << nVtx << endl;
123 ArrayView<const gno_t> edgeIds;
124 ArrayView<const offset_t> offsets;
125 ArrayView<StridedData<lno_t, scalar_t> > wgts;
126
127 // wgts are ignored in AMD
128 model->getEdgeList(edgeIds, offsets, wgts);
129
130 // We will always call AMD with SuiteSparse_long
131 AMDTraits<SuiteSparse_long> AMDobj;
132 double Control[AMD_CONTROL];
133 double Info[AMD_INFO];
134
135 amd_defaults(Control);
136 amd_control(Control);
137
138 // We will use the lno_t for local ordering
139 lno_t *perm;
140 perm = (lno_t *) (solution->getPermutationRCP().getRawPtr());
141
142 SuiteSparse_long *amd_offsets, *amd_edgeIds;
144 offsets);
145 // This might throw depending on how SuiteSparse was compiled
146 // with long or long long and the size of both of them
148 edgeIds);
149
150 SuiteSparse_long amd_nVtx=0;
152
153 // Allocate a SuiteSparse_long perm
154 SuiteSparse_long *amd_perm = new SuiteSparse_long[amd_nVtx];
155
156 lno_t result = AMDobj.order(amd_nVtx, amd_offsets,
157 amd_edgeIds, amd_perm, Control, Info);
158
159 if (result != AMD_OK && result != AMD_OK_BUT_JUMBLED)
160 ierr = -1;
161
162 // SR: This conversion might throw as we are going from SuiteSparse_long
163 // to lno_t. Another option is to change local ordering solution
164 // to use gno_t everywhere
165 for (size_t i = 0; i < nVtx; i++)
167
168 // Delete copies
171 delete [] amd_perm;
172
173 solution->setHavePerm(true);
174 return ierr;
175#endif
176 }
177};
178
179}
180
181
182
183#endif
Defines the GraphModel interface.
Defines the OrderingSolution class.
Traits class to handle conversions between gno_t/lno_t and TPL data types (e.g., ParMETIS's idx_t,...
int globalOrder(const RCP< GlobalOrderingSolution< typename Adapter::gno_t > > &)
Ordering method.
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__)
int localOrder(const RCP< LocalOrderingSolution< typename Adapter::lno_t > > &solution)
Ordering method.
Algorithm defines the base class for all algorithms.
Adapter::scalar_t scalar_t
GraphModel defines the interface required for graph models.
Created by mbenlioglu on Aug 31, 2020.
std::bitset< NUM_MODEL_FLAGS > modelFlag_t
static void DELETE_ARRAY(first_t **a)
static void ASSIGN_ARRAY(first_t **a, ArrayView< second_t > &b)
static void ASSIGN(first_t &a, second_t b)