Zoltan2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Zoltan2_BasicVectorAdapter.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_BASICVECTORADAPTER_HPP_
51 #define _ZOLTAN2_BASICVECTORADAPTER_HPP_
52 
53 #include "Zoltan2_Adapter.hpp"
54 #include <Zoltan2_StridedData.hpp>
56 
57 namespace Zoltan2 {
58 
86 template <typename User> class BasicVectorAdapter : public VectorAdapter<User> {
87 
88 public:
89 #ifndef DOXYGEN_SHOULD_SKIP_THIS
90 
91  using scalar_t = typename InputTraits<User>::scalar_t;
92  using lno_t = typename InputTraits<User>::lno_t;
93  using gno_t = typename InputTraits<User>::gno_t;
94  using offset_t = typename InputTraits<User>::offset_t;
95  using part_t = typename InputTraits<User>::part_t;
96  using node_t = typename InputTraits<User>::node_t;
97  using user_t = User;
98  using Base = BaseAdapter<User>;
99 
100 #endif
101 
117  BasicVectorAdapter(lno_t numIds, const gno_t *ids, const scalar_t *entries,
118  int entryStride = 1, bool usewgts = false,
119  const scalar_t *wgts = NULL, int wgtStride = 1)
120  : numIds_(numIds), idList_(ids), numEntriesPerID_(1),
121  numWeights_(usewgts == true) {
122  std::vector<const scalar_t *> values;
123  std::vector<int> strides;
124  std::vector<const scalar_t *> weightValues;
125  std::vector<int> weightStrides;
126 
127  values.push_back(entries);
128  strides.push_back(entryStride);
129  if (usewgts) {
130  weightValues.push_back(wgts);
131  weightStrides.push_back(wgtStride);
132  }
133 
134  createBasicVector(values, strides, weightValues, weightStrides);
135  }
136 
162  BasicVectorAdapter(lno_t numIds, const gno_t *ids,
163  std::vector<const scalar_t *> &entries,
164  std::vector<int> &entryStride,
165  std::vector<const scalar_t *> &weights,
166  std::vector<int> &weightStrides)
167  : numIds_(numIds), idList_(ids), numEntriesPerID_(entries.size()),
168  numWeights_(weights.size()) {
169  createBasicVector(entries, entryStride, weights, weightStrides);
170  }
171 
198  BasicVectorAdapter(lno_t numIds, const gno_t *ids, const scalar_t *x,
199  const scalar_t *y, const scalar_t *z, int xStride = 1,
200  int yStride = 1, int zStride = 1, bool usewgts = false,
201  const scalar_t *wgts = NULL, int wgtStride = 1)
202  : numIds_(numIds), idList_(ids), numEntriesPerID_(0),
203  numWeights_(usewgts == true) {
204  std::vector<const scalar_t *> values, weightValues;
205  std::vector<int> strides, weightStrides;
206 
207  if (x) {
208  values.push_back(x);
209  strides.push_back(xStride);
210  numEntriesPerID_++;
211  if (y) {
212  values.push_back(y);
213  strides.push_back(yStride);
214  numEntriesPerID_++;
215  if (z) {
216  values.push_back(z);
217  strides.push_back(zStride);
218  numEntriesPerID_++;
219  }
220  }
221  }
222  if (usewgts) {
223  weightValues.push_back(wgts);
224  weightStrides.push_back(wgtStride);
225  }
226  createBasicVector(values, strides, weightValues, weightStrides);
227  }
228 
230  // The Adapter interface.
232 
233  size_t getLocalNumIDs() const { return numIds_; }
234 
235  void getIDsView(const gno_t *&ids) const { ids = idList_; }
236 
237  void getIDsKokkosView(typename Base::ConstIdsDeviceView &ids) const {
238  ids = this->kIds_;
239  }
240 
241  void getIDsHostView(typename Base::ConstIdsHostView &ids) const override {
242  auto hostIds = Kokkos::create_mirror_view(this->kIds_);
243  Kokkos::deep_copy(hostIds, this->kIds_);
244  ids = hostIds;
245  }
246 
247  void getIDsDeviceView(typename Base::ConstIdsDeviceView &ids) const override {
248  ids = this->kIds_;
249  }
250 
251  int getNumWeightsPerID() const { return numWeights_; }
252 
253  virtual void
254  getWeightsKokkos2dView(typename Base::WeightsDeviceView &wgt) const {
255  wgt = kWeights_;
256  }
257 
258  void getWeightsView(const scalar_t *&weights, int &stride, int idx) const {
259  AssertCondition((idx >= 0) and (idx < numWeights_),
260  "Invalid weight index.");
261 
262  size_t length;
263  weights_[idx].getStridedList(length, weights, stride);
264  }
265 
266  void getWeightsHostView(typename Base::WeightsHostView1D &hostWgts,
267  int idx = 0) const override {
268  AssertCondition((idx >= 0) and (idx < numWeights_),
269  "Invalid weight index.");
270 
271  auto weightsDevice =
272  typename Base::WeightsDeviceView1D("weights", kWeights_.extent(0));
273  getWeightsDeviceView(weightsDevice, idx);
274 
275  hostWgts = Kokkos::create_mirror_view(weightsDevice);
276  Kokkos::deep_copy(hostWgts, weightsDevice);
277  }
278 
279  void getWeightsHostView(typename Base::WeightsHostView &wgts) const override {
280  auto hostWeights = Kokkos::create_mirror_view(kWeights_);
281  Kokkos::deep_copy(hostWeights, kWeights_);
282  wgts = hostWeights;
283  }
284 
285  void getWeightsDeviceView(typename Base::WeightsDeviceView1D &deviceWgts,
286  int idx = 0) const override {
287  AssertCondition((idx >= 0) and (idx < numWeights_),
288  "Invalid weight index.");
289 
290  const auto size = kWeights_.extent(0);
291  deviceWgts = typename Base::WeightsDeviceView1D("weights", size);
292 
293  Kokkos::parallel_for(
294  size, KOKKOS_CLASS_LAMBDA(const int id) {
295  deviceWgts(id) = kWeights_(id, idx);
296  });
297 
298  Kokkos::fence();
299  }
300 
301  void
302  getWeightsDeviceView(typename Base::WeightsDeviceView &wgts) const override {
303  wgts = kWeights_;
304  }
305 
307  // The VectorAdapter interface.
309 
310  int getNumEntriesPerID() const { return numEntriesPerID_; }
311 
312  void getEntriesView(const scalar_t *&entries, int &stride,
313  int idx = 0) const {
314  if (idx < 0 || idx >= numEntriesPerID_) {
315  std::ostringstream emsg;
316  emsg << __FILE__ << ":" << __LINE__ << " Invalid vector index " << idx
317  << std::endl;
318  throw std::runtime_error(emsg.str());
319  }
320  size_t length;
321  entries_[idx].getStridedList(length, entries, stride);
322  }
323 
325  typename AdapterWithCoords<User>::CoordsDeviceView &entries) const {
326  entries = kEntries_;
327  }
328 
330  &entries) const override {
331  auto hostEntries = Kokkos::create_mirror_view(kEntries_);
332  Kokkos::deep_copy(hostEntries, kEntries_);
333  entries = hostEntries;
334  }
335 
337  &entries) const override {
338  entries = kEntries_;
339  }
340 
341 private:
342  lno_t numIds_;
343  const gno_t *idList_;
344 
345  int numEntriesPerID_;
346  int numWeights_;
347 
348  // Old API variable members
349  ArrayRCP<StridedData<lno_t, scalar_t>> entries_;
350  ArrayRCP<StridedData<lno_t, scalar_t>> weights_;
351 
352  // New API variable members
353  typename Base::IdsDeviceView kIds_;
355  typename Base::WeightsDeviceView kWeights_;
356 
357  void createBasicVector(std::vector<const scalar_t *> &entries,
358  std::vector<int> &entryStride,
359  std::vector<const scalar_t *> &weights,
360  std::vector<int> &weightStrides) {
361  typedef StridedData<lno_t, scalar_t> input_t;
362 
363  if (numIds_) {
364  // make kokkos ids
365  kIds_ = typename Base::IdsDeviceView(
366  Kokkos::ViewAllocateWithoutInitializing("ids"), numIds_);
367  auto host_kIds_ = Kokkos::create_mirror_view(kIds_);
368  for (int n = 0; n < numIds_; ++n) {
369  host_kIds_(n) = idList_[n];
370  }
371  Kokkos::deep_copy(kIds_, host_kIds_);
372 
373  // make coordinates
374  int stride = 1;
375  entries_ = arcp(new input_t[numEntriesPerID_], 0, numEntriesPerID_, true);
376  for (int v = 0; v < numEntriesPerID_; v++) {
377  if (entryStride.size())
378  stride = entryStride[v];
379  ArrayRCP<const scalar_t> eltV(entries[v], 0, stride * numIds_, false);
380  entries_[v] = input_t(eltV, stride);
381  }
382 
383  // setup kokkos entries
384  kEntries_ = typename AdapterWithCoords<User>::CoordsDeviceView(
385  Kokkos::ViewAllocateWithoutInitializing("entries"), numIds_,
386  numEntriesPerID_);
387 
388  size_t length;
389  const scalar_t *entriesPtr;
390 
391  auto host_kokkos_entries = Kokkos::create_mirror_view(this->kEntries_);
392 
393  for (int idx = 0; idx < numEntriesPerID_; idx++) {
394  entries_[idx].getStridedList(length, entriesPtr, stride);
395  size_t fill_index = 0;
396  for (int n = 0; n < numIds_; ++n) {
397  host_kokkos_entries(fill_index++, idx) = entriesPtr[n * stride];
398  }
399  }
400  Kokkos::deep_copy(this->kEntries_, host_kokkos_entries);
401  }
402 
403  if (numWeights_) {
404  int stride = 1;
405  weights_ = arcp(new input_t[numWeights_], 0, numWeights_, true);
406  for (int w = 0; w < numWeights_; w++) {
407  if (weightStrides.size())
408  stride = weightStrides[w];
409  ArrayRCP<const scalar_t> wgtV(weights[w], 0, stride * numIds_, false);
410  weights_[w] = input_t(wgtV, stride);
411  }
412 
413  // set up final view with weights
414  kWeights_ = typename Base::WeightsDeviceView(
415  Kokkos::ViewAllocateWithoutInitializing("kokkos weights"), numIds_,
416  numWeights_);
417 
418  // setup weights
419  auto host_weight_temp_values =
420  Kokkos::create_mirror_view(this->kWeights_);
421  for (int idx = 0; idx < numWeights_; ++idx) {
422  const scalar_t *weightsPtr;
423  size_t length;
424  weights_[idx].getStridedList(length, weightsPtr, stride);
425  size_t fill_index = 0;
426  for (size_t n = 0; n < length; n += stride) {
427  host_weight_temp_values(fill_index++, idx) = weightsPtr[n];
428  }
429  }
430  Kokkos::deep_copy(this->kWeights_, host_weight_temp_values);
431  }
432  }
433 };
434 
435 } // namespace Zoltan2
436 
437 #endif
void getEntriesDeviceView(typename AdapterWithCoords< User >::CoordsDeviceView &entries) const override
Provide a Kokkos view (Device side) to the elements of the specified vector.
size_t getLocalNumIDs() const
Returns the number of objects on this process.
void getIDsHostView(typename Base::ConstIdsHostView &ids) const override
static void AssertCondition(bool condition, const std::string &message, const char *file=__FILE__, int line=__LINE__)
BasicVectorAdapter(lno_t numIds, const gno_t *ids, const scalar_t *entries, int entryStride=1, bool usewgts=false, const scalar_t *wgts=NULL, int wgtStride=1)
Constructor for one vector with (optionally) one weight.
static ArrayRCP< ArrayRCP< zscalar_t > > weights
Kokkos::View< scalar_t **, Kokkos::LayoutLeft, device_t > CoordsDeviceView
default_part_t part_t
The data type to represent part numbers.
default_offset_t offset_t
The data type to represent offsets.
map_t::global_ordinal_type gno_t
Definition: mapRemotes.cpp:18
Defines the VectorAdapter interface.
void getWeightsHostView(typename Base::WeightsHostView1D &hostWgts, int idx=0) const override
typename InputTraits< User >::part_t part_t
void getIDsDeviceView(typename Base::ConstIdsDeviceView &ids) const override
int getNumEntriesPerID() const
Return the number of vectors.
typename InputTraits< User >::node_t node_t
typename CoordsDeviceView::HostMirror CoordsHostView
void getWeightsHostView(typename Base::WeightsHostView &wgts) const override
void getWeightsView(const scalar_t *&weights, int &stride, int idx) const
Provide pointer to a weight array with stride.
virtual void getWeightsKokkos2dView(typename Base::WeightsDeviceView &wgt) const
typename InputTraits< User >::gno_t gno_t
default_lno_t lno_t
The ordinal type (e.g., int, long, int64_t) that represents local counts and local indices...
void getEntriesKokkosView(typename AdapterWithCoords< User >::CoordsDeviceView &entries) const
VectorAdapter defines the interface for vector input.
void getWeightsDeviceView(typename Base::WeightsDeviceView1D &deviceWgts, int idx=0) const override
The StridedData class manages lists of weights or coordinates.
BasicVectorAdapter represents a vector (plus optional weights) supplied by the user as pointers to st...
map_t::local_ordinal_type lno_t
Definition: mapRemotes.cpp:17
void getEntriesHostView(typename AdapterWithCoords< User >::CoordsHostView &entries) const override
Provide a Kokkos view (Host side) to the elements of the specified vector.
BasicVectorAdapter(lno_t numIds, const gno_t *ids, std::vector< const scalar_t * > &entries, std::vector< int > &entryStride, std::vector< const scalar_t * > &weights, std::vector< int > &weightStrides)
Constructor for multivector (a set of vectors sharing the same global numbering and data distribution...
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.
typename InputTraits< User >::offset_t offset_t
void getIDsView(const gno_t *&ids) const
Provide a pointer to this process&#39; identifiers.
int getNumWeightsPerID() const
Returns the number of weights per object. Number of weights per object should be zero or greater...
typename BaseAdapter< User >::scalar_t scalar_t
void getWeightsDeviceView(typename Base::WeightsDeviceView &wgts) const override
void getEntriesView(const scalar_t *&entries, int &stride, int idx=0) const
Provide a pointer to the elements of the specified vector.
void getIDsKokkosView(typename Base::ConstIdsDeviceView &ids) const
BasicVectorAdapter(lno_t numIds, const gno_t *ids, const scalar_t *x, const scalar_t *y, const scalar_t *z, int xStride=1, int yStride=1, int zStride=1, bool usewgts=false, const scalar_t *wgts=NULL, int wgtStride=1)
A simple constructor for coordinate-based problems with dimension 1, 2 or 3 and (optionally) one weig...
default_scalar_t scalar_t
The data type for weights and coordinates.
This file defines the StridedData class.