Zoltan2
Zoltan2_XpetraMultiVectorAdapter.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_XPETRAMULTIVECTORADAPTER_HPP_
51 #define _ZOLTAN2_XPETRAMULTIVECTORADAPTER_HPP_
52 
53 #include <Zoltan2_XpetraTraits.hpp>
55 #include <Zoltan2_StridedData.hpp>
57 
58 #if defined(HAVE_ZOLTAN2_EPETRA) && defined(HAVE_XPETRA_EPETRA)
59 #include <Xpetra_EpetraMultiVector.hpp>
60 #endif
61 #include <Xpetra_TpetraMultiVector.hpp>
62 
63 namespace Zoltan2 {
64 
82 template <typename User>
83  class XpetraMultiVectorAdapter : public VectorAdapter<User> {
84 public:
85 
86 #ifndef DOXYGEN_SHOULD_SKIP_THIS
87  typedef typename InputTraits<User>::scalar_t scalar_t;
88  typedef typename InputTraits<User>::lno_t lno_t;
89  typedef typename InputTraits<User>::gno_t gno_t;
90  typedef typename InputTraits<User>::part_t part_t;
91  typedef typename InputTraits<User>::node_t node_t;
92  typedef VectorAdapter<User> base_adapter_t;
93  typedef User user_t;
94  typedef User userCoord_t;
95 
96  typedef Xpetra::MultiVector<scalar_t, lno_t, gno_t, node_t> x_mvector_t;
97  typedef Xpetra::TpetraMultiVector<
98  scalar_t, lno_t, gno_t, node_t> xt_mvector_t;
99 #endif
100 
104 
120  XpetraMultiVectorAdapter(const RCP<const User> &invector,
121  std::vector<const scalar_t *> &weights, std::vector<int> &weightStrides);
122 
128  XpetraMultiVectorAdapter(const RCP<const User> &invector);
129 
130 
132  // The Adapter interface.
134 
135  size_t getLocalNumIDs() const { return vector_->getLocalLength();}
136 
137  void getIDsView(const gno_t *&ids) const
138  {
139  ids = map_->getNodeElementList().getRawPtr();
140  }
141 
142  int getNumWeightsPerID() const { return numWeights_;}
143 
144  void getWeightsView(const scalar_t *&weights, int &stride, int idx) const
145  {
146  env_->localInputAssertion(__FILE__, __LINE__, "invalid weight index",
147  idx >= 0 && idx < numWeights_, BASIC_ASSERTION);
148  size_t length;
149  weights_[idx].getStridedList(length, weights, stride);
150  }
151 
153  // The VectorAdapter interface.
155 
156  int getNumEntriesPerID() const {return vector_->getNumVectors();}
157 
158  void getEntriesView(const scalar_t *&elements, int &stride, int idx=0) const;
159 
160  template <typename Adapter>
161  void applyPartitioningSolution(const User &in, User *&out,
162  const PartitioningSolution<Adapter> &solution) const;
163 
164  template <typename Adapter>
165  void applyPartitioningSolution(const User &in, RCP<User> &out,
166  const PartitioningSolution<Adapter> &solution) const;
167 
168 private:
169 
170  RCP<const User> invector_;
171  RCP<const x_mvector_t> vector_;
172  RCP<const Xpetra::Map<lno_t, gno_t, node_t> > map_;
173  RCP<Environment> env_; // for error messages, etc.
174  lno_t base_;
175 
176  int numWeights_;
177  ArrayRCP<StridedData<lno_t, scalar_t> > weights_;
178 };
179 
181 // Definitions
183 
184 template <typename User>
186  const RCP<const User> &invector,
187  std::vector<const scalar_t *> &weights, std::vector<int> &weightStrides):
188  invector_(invector), vector_(), map_(),
189  env_(rcp(new Environment)), base_(),
190  numWeights_(weights.size()), weights_(weights.size())
191 {
192  typedef StridedData<lno_t, scalar_t> input_t;
193 
194  RCP<x_mvector_t> tmp =
195  XpetraTraits<User>::convertToXpetra(rcp_const_cast<User>(invector));
196  vector_ = rcp_const_cast<const x_mvector_t>(tmp);
197  map_ = vector_->getMap();
198  base_ = map_->getIndexBase();
199 
200  size_t length = vector_->getLocalLength();
201 
202  if (length > 0 && numWeights_ > 0){
203  int stride = 1;
204  for (int w=0; w < numWeights_; w++){
205  if (weightStrides.size())
206  stride = weightStrides[w];
207  ArrayRCP<const scalar_t> wgtV(weights[w], 0, stride*length, false);
208  weights_[w] = input_t(wgtV, stride);
209  }
210  }
211 }
212 
213 
215 template <typename User>
217  const RCP<const User> &invector):
218  invector_(invector), vector_(), map_(),
219  env_(rcp(new Environment)), base_(),
220  numWeights_(0), weights_()
221 {
222  RCP<x_mvector_t> tmp =
223  XpetraTraits<User>::convertToXpetra(rcp_const_cast<User>(invector));
224  vector_ = rcp_const_cast<const x_mvector_t>(tmp);
225  map_ = vector_->getMap();
226  base_ = map_->getIndexBase();
227 }
228 
230 template <typename User>
232  const scalar_t *&elements, int &stride, int idx) const
233 {
234  size_t vecsize;
235  stride = 1;
236  elements = NULL;
237  if (map_->lib() == Xpetra::UseTpetra){
238  const xt_mvector_t *tvector =
239  dynamic_cast<const xt_mvector_t *>(vector_.get());
240 
241  vecsize = tvector->getLocalLength();
242  if (vecsize > 0){
243  ArrayRCP<const scalar_t> data = tvector->getData(idx);
244  elements = data.get();
245  }
246  }
247  else if (map_->lib() == Xpetra::UseEpetra){
248 #if defined(HAVE_ZOLTAN2_EPETRA) && defined(HAVE_XPETRA_EPETRA)
249  typedef Xpetra::EpetraMultiVectorT<gno_t,node_t> xe_mvector_t;
250  const xe_mvector_t *evector =
251  dynamic_cast<const xe_mvector_t *>(vector_.get());
252 
253  vecsize = evector->getLocalLength();
254  if (vecsize > 0){
255  ArrayRCP<const double> data = evector->getData(idx);
256 
257  // Cast so this will compile when scalar_t is not double,
258  // a case when this code should never execute.
259  elements = reinterpret_cast<const scalar_t *>(data.get());
260  }
261 #else
262  throw std::logic_error("Epetra requested, but Trilinos is not "
263  "built with Epetra");
264 #endif
265  }
266  else{
267  throw std::logic_error("invalid underlying lib");
268  }
269 }
270 
272 template <typename User>
273  template <typename Adapter>
275  const User &in, User *&out,
276  const PartitioningSolution<Adapter> &solution) const
277 {
278  // Get an import list (rows to be received)
279  size_t numNewRows;
280  ArrayRCP<gno_t> importList;
281  try{
282  numNewRows = Zoltan2::getImportList<Adapter,
284  (solution, this, importList);
285  }
287 
288  // Move the rows, creating a new vector.
289  RCP<User> outPtr = XpetraTraits<User>::doMigration(in, numNewRows,
290  importList.getRawPtr());
291  out = outPtr.get();
292  outPtr.release();
293 }
294 
296 template <typename User>
297  template <typename Adapter>
299  const User &in, RCP<User> &out,
300  const PartitioningSolution<Adapter> &solution) const
301 {
302  // Get an import list (rows to be received)
303  size_t numNewRows;
304  ArrayRCP<gno_t> importList;
305  try{
306  numNewRows = Zoltan2::getImportList<Adapter,
308  (solution, this, importList);
309  }
311 
312  // Move the rows, creating a new vector.
313  out = XpetraTraits<User>::doMigration(in, numNewRows,
314  importList.getRawPtr());
315 }
316 
317 } //namespace Zoltan2
318 
319 #endif
InputTraits< User >::scalar_t scalar_t
Helper functions for Partitioning Problems.
fast typical checks for valid arguments
#define Z2_FORWARD_EXCEPTIONS
Forward an exception back through call stack.
InputTraits< User >::gno_t gno_t
default_part_t part_t
The data type to represent part numbers.
XpetraMultiVectorAdapter(const RCP< const User > &invector, std::vector< const scalar_t * > &weights, std::vector< int > &weightStrides)
Constructor.
Defines the VectorAdapter interface.
static RCP< User > doMigration(const User &from, size_t numLocalRows, const gno_t *myNewRows)
Migrate the object Given a user object and a new row distribution, create and return a new user objec...
static ArrayRCP< ArrayRCP< zscalar_t > > weights
Traits of Xpetra classes, including migration method.
static RCP< User > convertToXpetra(const RCP< User > &a)
Convert the object to its Xpetra wrapped version.
size_t getImportList(const PartitioningSolution< SolutionAdapter > &solution, const DataAdapter *const data, ArrayRCP< typename DataAdapter::gno_t > &imports)
From a PartitioningSolution, get a list of IDs to be imported. Assumes part numbers in PartitioningSo...
int getNumEntriesPerID() const
Return the number of vectors (typically one).
A PartitioningSolution is a solution to a partitioning problem.
void applyPartitioningSolution(const User &in, User *&out, const PartitioningSolution< Adapter > &solution) const
default_lno_t lno_t
The ordinal type (e.g., int, long, int64_t) that represents local counts and local indices...
VectorAdapter defines the interface for vector input.
The StridedData class manages lists of weights or coordinates.
void getEntriesView(const scalar_t *&elements, int &stride, int idx=0) const
Provide a pointer to the elements of the specified vector.
InputTraits< User >::part_t part_t
The user parameters, debug, timing and memory profiling output objects, and error checking methods...
int getNumWeightsPerID() const
Returns the number of weights per object. Number of weights per object should be zero or greater...
An adapter for Xpetra::MultiVector.
default_gno_t gno_t
The ordinal type (e.g., int, long, int64_t) that can represent global counts and identifiers.
default_node_t node_t
The Kokkos node type. This is only meaningful for users of Tpetra objects.
size_t getLocalNumIDs() const
Returns the number of objects on this process.
default_scalar_t scalar_t
The data type for weights and coordinates.
void getWeightsView(const scalar_t *&weights, int &stride, int idx) const
Provide pointer to a weight array with stride.
This file defines the StridedData class.