14#ifndef _ZOLTAN2_XPETRAMULTIVECTORADAPTER_HPP_
15#define _ZOLTAN2_XPETRAMULTIVECTORADAPTER_HPP_
22#if defined(HAVE_ZOLTAN2_EPETRA) && defined(HAVE_XPETRA_EPETRA)
23#include <Xpetra_EpetraMultiVector.hpp>
25#include <Xpetra_TpetraMultiVector.hpp>
46template <
typename User>
50#ifndef DOXYGEN_SHOULD_SKIP_THIS
57 typedef User userCoord_t;
59 typedef Xpetra::MultiVector<scalar_t, lno_t, gno_t, node_t> x_mvector_t;
60 typedef Xpetra::TpetraMultiVector<
80 std::vector<const scalar_t *> &
weights, std::vector<int> &weightStrides);
98 ids = map_->getLocalElementList().getRawPtr();
102 Kokkos::View<const gno_t *, typename node_t::device_type> &ids)
const {
103 if (map_->lib() == Xpetra::UseTpetra) {
104 using device_type =
typename node_t::device_type;
105 const xt_mvector_t *tvector =
106 dynamic_cast<const xt_mvector_t *
>(vector_.get());
114 ids = Kokkos::create_mirror_view_and_copy(device_type(),
115 tvector->getTpetra_MultiVector()->getMap()->getMyGlobalIndices());
117 else if (map_->lib() == Xpetra::UseEpetra) {
118#if defined(HAVE_ZOLTAN2_EPETRA) && defined(HAVE_XPETRA_EPETRA)
122 throw std::logic_error(
"Epetra requested, but Trilinos is not "
123 "built with Epetra");
127 throw std::logic_error(
"getIDsKokkosView called but not on Tpetra or Epetra!");
135 if(idx<0 || idx >= numWeights_)
137 std::ostringstream emsg;
138 emsg << __FILE__ <<
":" << __LINE__
139 <<
" Invalid weight index " << idx << std::endl;
140 throw std::runtime_error(emsg.str());
144 weights_[idx].getStridedList(length,
weights, stride);
148 typename node_t::device_type> &wgt)
const {
149 typedef Kokkos::View<scalar_t**, typename node_t::device_type> view_t;
150 wgt = view_t(
"wgts", vector_->getLocalLength(), numWeights_);
151 typename view_t::host_mirror_type host_wgt = Kokkos::create_mirror_view(wgt);
152 for(
int idx = 0; idx < numWeights_; ++idx) {
156 weights_[idx].getStridedList(length,
weights, stride);
157 size_t fill_index = 0;
158 for(
size_t n = 0; n < length; n += stride) {
159 host_wgt(fill_index++,idx) =
weights[n];
162 Kokkos::deep_copy(wgt, host_wgt);
175 Kokkos::View<
scalar_t **, Kokkos::LayoutLeft,
176 typename node_t::device_type> & elements)
const;
178 template <
typename Adapter>
182 template <
typename Adapter>
188 RCP<const User> invector_;
189 RCP<const x_mvector_t> vector_;
190 RCP<const Xpetra::Map<lno_t, gno_t, node_t> > map_;
193 ArrayRCP<StridedData<lno_t, scalar_t> > weights_;
200template <
typename User>
202 const RCP<const User> &invector,
203 std::vector<const scalar_t *> &
weights, std::vector<int> &weightStrides):
204 invector_(invector), vector_(), map_(),
210 RCP<x_mvector_t> tmp =
212 vector_ = rcp_const_cast<const x_mvector_t>(tmp);
216 map_ = vector_->getMap();
218 size_t length = vector_->getLocalLength();
220 if (length > 0 && numWeights_ > 0){
222 for (
int w=0; w < numWeights_; w++){
223 if (weightStrides.size())
224 stride = weightStrides[w];
225 ArrayRCP<const scalar_t> wgtV(
weights[w], 0, stride*length,
false);
226 weights_[w] = input_t(wgtV, stride);
233template <
typename User>
235 const RCP<const User> &invector):
236 invector_(invector), vector_(), map_(),
237 numWeights_(0), weights_()
240 RCP<x_mvector_t> tmp =
242 vector_ = rcp_const_cast<const x_mvector_t>(tmp);
246 map_ = vector_->getMap();
250template <
typename User>
252 const scalar_t *&elements,
int &stride,
int idx)
const
257 if (map_->lib() == Xpetra::UseTpetra){
258 const xt_mvector_t *tvector =
259 dynamic_cast<const xt_mvector_t *
>(vector_.get());
261 vecsize = tvector->getLocalLength();
263 ArrayRCP<const scalar_t> data = tvector->getData(idx);
264 elements = data.get();
267 else if (map_->lib() == Xpetra::UseEpetra){
268#if defined(HAVE_ZOLTAN2_EPETRA) && defined(HAVE_XPETRA_EPETRA)
269 typedef Xpetra::EpetraMultiVectorT<gno_t,node_t> xe_mvector_t;
270 const xe_mvector_t *evector =
271 dynamic_cast<const xe_mvector_t *
>(vector_.get());
273 vecsize = evector->getLocalLength();
275 ArrayRCP<const double> data = evector->getData(idx);
279 elements =
reinterpret_cast<const scalar_t *
>(data.get());
282 throw std::logic_error(
"Epetra requested, but Trilinos is not "
283 "built with Epetra");
287 throw std::logic_error(
"invalid underlying lib");
292template <
typename User>
295 Kokkos::View<scalar_t **, Kokkos::LayoutLeft, typename node_t::device_type> & elements)
const
297 if (map_->lib() == Xpetra::UseTpetra){
298 const xt_mvector_t *tvector =
299 dynamic_cast<const xt_mvector_t *
>(vector_.get());
301 Kokkos::View<scalar_t **, Kokkos::LayoutLeft, typename node_t::device_type> view2d =
302 tvector->getTpetra_MultiVector()->template getLocalView<typename node_t::device_type>(Tpetra::Access::ReadWrite);
308 else if (map_->lib() == Xpetra::UseEpetra){
309#if defined(HAVE_ZOLTAN2_EPETRA) && defined(HAVE_XPETRA_EPETRA)
310 typedef Xpetra::EpetraMultiVectorT<gno_t,node_t> xe_mvector_t;
311 const xe_mvector_t *evector =
312 dynamic_cast<const xe_mvector_t *
>(vector_.get());
314 Kokkos::View<scalar_t **, Kokkos::LayoutLeft, typename node_t::device_type>
315 (
"elements", evector->getLocalLength(), evector->getNumVectors());
316 if(evector->getLocalLength() > 0) {
317 for(
size_t idx = 0; idx < evector->getNumVectors(); ++idx) {
320 getEntriesView(ptr, stride, idx);
321 for(
size_t n = 0; n < evector->getLocalLength(); ++n) {
322 elements(n, idx) = ptr[n];
327 throw std::logic_error(
"Epetra requested, but Trilinos is not "
328 "built with Epetra");
332 throw std::logic_error(
"getEntriesKokkosView called but not using Tpetra or Epetra!");
337template <
typename User>
338 template <
typename Adapter>
340 const User &in, User *&out,
345 ArrayRCP<gno_t> importList;
349 (solution,
this, importList);
355 importList.getRawPtr());
361template <
typename User>
362 template <
typename Adapter>
364 const User &in, RCP<User> &out,
369 ArrayRCP<gno_t> importList;
373 (solution,
this, importList);
379 importList.getRawPtr());
Zoltan2::BasicUserTypes< zscalar_t, zlno_t, zgno_t > user_t
#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
virtual void getIDsKokkosView(ConstIdsDeviceView &ids) const
Provide a Kokkos view to this process' identifiers.
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.
VectorAdapter defines the interface for vector input.
An adapter for Xpetra::MultiVector.
void getEntriesView(const scalar_t *&elements, int &stride, int idx=0) const
Provide a pointer to the elements of the specified vector.
void applyPartitioningSolution(const User &in, User *&out, const PartitioningSolution< Adapter > &solution) const
void getIDsView(const gno_t *&ids) const
void getWeightsKokkos2dView(Kokkos::View< scalar_t **, typename node_t::device_type > &wgt) const
void getEntriesKokkosView(Kokkos::View< scalar_t **, Kokkos::LayoutLeft, typename node_t::device_type > &elements) const
Provide a Kokkos view to the elements of the specified vector.
XpetraMultiVectorAdapter(const RCP< const User > &invector, std::vector< const scalar_t * > &weights, std::vector< int > &weightStrides)
Constructor.
void getIDsKokkosView(Kokkos::View< const gno_t *, typename node_t::device_type > &ids) const
int getNumEntriesPerID() const
Return the number of vectors.
int getNumWeightsPerID() const
Returns the number of weights per object. Number of weights per object should be zero or greater....
void getWeightsView(const scalar_t *&weights, int &stride, int idx) const
size_t getLocalNumIDs() const
Returns the number of objects on this process.
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 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 RCP< User > convertToXpetra(const RCP< User > &a)
Convert the object to its Xpetra wrapped version.