Zoltan2
Loading...
Searching...
No Matches
Zoltan2_TpetraMultiVectorAdapter.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_TPETRAMULTIVECTORADAPTER_HPP
15#define ZOLTAN2_TPETRAMULTIVECTORADAPTER_HPP
16
21
22#include <Tpetra_MultiVector.hpp>
23
24namespace Zoltan2 {
25
41template <typename User>
43public:
44
45#ifndef DOXYGEN_SHOULD_SKIP_THIS
47 typedef typename InputTraits<User>::impl_scalar_t impl_scalar_t;
48 typedef typename InputTraits<User>::lno_t lno_t;
49 typedef typename InputTraits<User>::gno_t gno_t;
50 typedef typename InputTraits<User>::part_t part_t;
51 typedef typename InputTraits<User>::node_t node_t;
52 typedef User user_t;
53 typedef User userCoord_t;
54
55 typedef Tpetra::MultiVector<scalar_t, lno_t, gno_t, node_t> t_mvector_t;
56#endif
57
73 TpetraMultiVectorAdapter(const RCP<const User> &invector,
74 std::vector<const scalar_t *> &weights, std::vector<int> &weightStrides);
75
81 TpetraMultiVectorAdapter(const RCP<const User> &invector);
82
83
85 // The Adapter interface.
87
88 size_t getLocalNumIDs() const { return vector_->getLocalLength();}
89
90 void getIDsView(const gno_t *&ids) const
91 {
92 ids = map_->getLocalElementList().getRawPtr();
93 }
94
96 Kokkos::View<const gno_t *, typename node_t::device_type> &ids) const {
97 using device_type = typename node_t::device_type;
98 // MJ can be running Host, CudaSpace, or CudaUVMSpace while Map now
99 // internally never stores CudaUVMSpace so we may need a conversion.
100 // However Map stores both Host and CudaSpace so this could be improved
101 // if device_type was CudaSpace. Then we could add a new accessor to
102 // Map such as getMyGlobalIndicesDevice() which could be direct assigned
103 // here. Since Tpetra is still UVM dependent that is not going to happen
104 // yet so just leaving this as Host to device_type conversion for now.
105 ids = Kokkos::create_mirror_view_and_copy(device_type(),
106 vector_->getMap()->getMyGlobalIndices());
107 }
108
109 int getNumWeightsPerID() const { return numWeights_;}
110
111 void getWeightsView(const scalar_t *&weights, int &stride, int idx) const
112 {
113 if(idx<0 || idx >= numWeights_)
114 {
115 std::ostringstream emsg;
116 emsg << __FILE__ << ":" << __LINE__
117 << " Invalid weight index " << idx << std::endl;
118 throw std::runtime_error(emsg.str());
119 }
120
121 size_t length;
122 weights_[idx].getStridedList(length, weights, stride);
123 }
124
125 void getWeightsKokkos2dView(Kokkos::View<scalar_t **,
126 typename node_t::device_type> &wgt) const {
127 typedef Kokkos::View<scalar_t**, typename node_t::device_type> view_t;
128 wgt = view_t("wgts", vector_->getLocalLength(), numWeights_);
129 typename view_t::host_mirror_type host_wgt = Kokkos::create_mirror_view(wgt);
130 for(int idx = 0; idx < numWeights_; ++idx) {
131 const scalar_t * weights;
132 size_t length;
133 int stride;
134 weights_[idx].getStridedList(length, weights, stride);
135 size_t fill_index = 0;
136 for(size_t n = 0; n < length; n += stride) {
137 host_wgt(fill_index++,idx) = weights[n];
138 }
139 }
140 Kokkos::deep_copy(wgt, host_wgt);
141 }
142
144 // The VectorAdapter interface.
146
147 int getNumEntriesPerID() const {return vector_->getNumVectors();}
148
149 void getEntriesView(const scalar_t *&elements, int &stride, int idx=0) const;
150
152 // coordinates in MJ are LayoutLeft since Tpetra Multivector gives LayoutLeft
153 Kokkos::View<impl_scalar_t **, Kokkos::LayoutLeft,
154 typename node_t::device_type> & elements) const;
155
156 template <typename Adapter>
157 void applyPartitioningSolution(const User &in, User *&out,
158 const PartitioningSolution<Adapter> &solution) const;
159
160 template <typename Adapter>
161 void applyPartitioningSolution(const User &in, RCP<User> &out,
162 const PartitioningSolution<Adapter> &solution) const;
163
164private:
165
166 RCP<const User> invector_;
167 RCP<const t_mvector_t> vector_;
168 RCP<const Tpetra::Map<lno_t, gno_t, node_t> > map_;
169
170 int numWeights_;
171 ArrayRCP<StridedData<lno_t, scalar_t> > weights_;
172};
173
175// Definitions
177
178template <typename User>
180 const RCP<const User> &invector,
181 std::vector<const scalar_t *> &weights, std::vector<int> &weightStrides):
182 invector_(invector), vector_(), map_(),
183 numWeights_(weights.size()), weights_(weights.size())
184{
185 typedef StridedData<lno_t, scalar_t> input_t;
186
187 vector_ = invector;
188 map_ = vector_->getMap();
189
190 size_t length = vector_->getLocalLength();
191
192 if (length > 0 && numWeights_ > 0){
193 int stride = 1;
194 for (int w=0; w < numWeights_; w++){
195 if (weightStrides.size())
196 stride = weightStrides[w];
197 ArrayRCP<const scalar_t> wgtV(weights[w], 0, stride*length, false);
198 weights_[w] = input_t(wgtV, stride);
199 }
200 }
201}
202
203
205template <typename User>
207 const RCP<const User> &invector):
208 invector_(invector), vector_(), map_(),
209 numWeights_(0), weights_()
210{
211 vector_ = invector;
212 map_ = vector_->getMap();
213}
214
216template <typename User>
218 const scalar_t *&elements, int &stride, int idx) const
219{
220 size_t vecsize;
221 stride = 1;
222 elements = NULL;
223 vecsize = vector_->getLocalLength();
224 if (vecsize > 0){
225 ArrayRCP<const scalar_t> data = vector_->getData(idx);
226 elements = data.get();
227 }
228}
229
231template <typename User>
233 // coordinates in MJ are LayoutLeft since Tpetra Multivector gives LayoutLeft
234 Kokkos::View<impl_scalar_t **, Kokkos::LayoutLeft, typename node_t::device_type> & elements) const
235{
236 // coordinates in MJ are LayoutLeft since Tpetra Multivector gives LayoutLeft
237 auto view2d =
238 rcp_const_cast<t_mvector_t>(vector_)->getLocalViewDevice(Tpetra::Access::ReadWrite);
239 elements = view2d;
240 // CMS/KDD: Look at this stuff right here. Compare against a non-cuda build OR, look at core/driver/driverinputs/kuberry/kuberry.coords
241 // Ca try changing the kuberry.xml to use "input adapter" "BasicVector" rather than "XpetraMultiVector"
242}
243
245template <typename User>
246 template <typename Adapter>
248 const User &in, User *&out,
249 const PartitioningSolution<Adapter> &solution) const
250{
251 // Get an import list (rows to be received)
252 size_t numNewRows;
253 ArrayRCP<gno_t> importList;
254 try{
255 numNewRows = Zoltan2::getImportList<Adapter,
257 (solution, this, importList);
258 }
260
261 // Move the rows, creating a new vector.
262 RCP<User> outPtr = XpetraTraits<User>::doMigration(in, numNewRows,
263 importList.getRawPtr());
264 out = outPtr.get();
265 outPtr.release();
266}
267
269template <typename User>
270 template <typename Adapter>
272 const User &in, RCP<User> &out,
273 const PartitioningSolution<Adapter> &solution) const
274{
275 // Get an import list (rows to be received)
276 size_t numNewRows;
277 ArrayRCP<gno_t> importList;
278 try{
279 numNewRows = Zoltan2::getImportList<Adapter,
281 (solution, this, importList);
282 }
284
285 // Move the rows, creating a new vector.
286 out = XpetraTraits<User>::doMigration(in, numNewRows,
287 importList.getRawPtr());
288}
289
290} //namespace Zoltan2
291
292#endif
Zoltan2::BasicUserTypes< zscalar_t, zlno_t, zgno_t > user_t
Definition Metric.cpp:39
#define Z2_FORWARD_EXCEPTIONS
Forward an exception back through call stack.
Helper functions for Partitioning Problems.
This file defines the StridedData class.
Defines the VectorAdapter interface.
Traits of Xpetra classes, including migration method.
typename BaseAdapter< User >::scalar_t scalar_t
typename InputTraits< User >::node_t node_t
typename InputTraits< User >::lno_t lno_t
typename InputTraits< User >::gno_t gno_t
typename InputTraits< User >::part_t part_t
A PartitioningSolution is a solution to a partitioning problem.
The StridedData class manages lists of weights or coordinates.
int getNumWeightsPerID() const
Returns the number of weights per object. Number of weights per object should be zero or greater....
void getEntriesKokkosView(Kokkos::View< impl_scalar_t **, Kokkos::LayoutLeft, typename node_t::device_type > &elements) const
TpetraMultiVectorAdapter(const RCP< const User > &invector, std::vector< const scalar_t * > &weights, std::vector< int > &weightStrides)
Constructor.
void getWeightsKokkos2dView(Kokkos::View< scalar_t **, typename node_t::device_type > &wgt) const
int getNumEntriesPerID() const
Return the number of vectors.
void applyPartitioningSolution(const User &in, User *&out, const PartitioningSolution< Adapter > &solution) const
void getWeightsView(const scalar_t *&weights, int &stride, int idx) const
void getIDsKokkosView(Kokkos::View< const gno_t *, typename node_t::device_type > &ids) const
void getEntriesView(const scalar_t *&elements, int &stride, int idx=0) const
Provide a pointer to the elements of the specified vector.
size_t getLocalNumIDs() const
Returns the number of objects on this process.
VectorAdapter defines the interface for vector input.
map_t::global_ordinal_type gno_t
Created by mbenlioglu on Aug 31, 2020.
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...
static ArrayRCP< ArrayRCP< zscalar_t > > weights
The traits required of User input classes or structures.
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.
default_lno_t lno_t
The ordinal type (e.g., int, long, int64_t) that represents local counts and local indices.
default_part_t part_t
The data type to represent part numbers.
default_scalar_t scalar_t
The data type for weights and coordinates.
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...