Amesos2 - Direct Sparse Solver Interfaces  Version of the Day
Amesos2_MultiVecAdapter_def.hpp
1 // @HEADER
2 //
3 // ***********************************************************************
4 //
5 // Amesos2: Templated Direct Sparse Solver Package
6 // Copyright 2011 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 Michael A. Heroux (maherou@sandia.gov)
39 //
40 // ***********************************************************************
41 //
42 // @HEADER
43 
44 
45 #ifndef AMESOS2_MULTIVECADAPTER_DEF_HPP
46 #define AMESOS2_MULTIVECADAPTER_DEF_HPP
47 
49 // EpetraMultiVecAdapter_def.hpp not included because the specialization is not a template
51 
52 #include "Amesos2_Util.hpp" // for getDistributionMap
53 
54 namespace Amesos2{
55 
56  namespace Util {
57 
59  // Pointer-getting utilities //
61 
62  template <typename MV, typename V>
63  typename vector_pointer_helper<MV, V>::ptr_return_type *
64  vector_pointer_helper<MV, V>::get_pointer_to_vector ( const Teuchos::Ptr< MV > &mv ) {
65  return mv->getMVPointer_impl();
66  }
67 
68  template <typename MV, typename V>
69  typename vector_pointer_helper<MV, V>::ptr_return_type *
70  vector_pointer_helper<MV, V>::get_pointer_to_vector ( Teuchos::Ptr< MV > &mv ) {
71  return mv->getMVPointer_impl();
72  }
73 
74  template <typename MV, typename V>
75  typename vector_pointer_helper<MV, V>::ptr_return_type *
76  vector_pointer_helper<MV, V>::get_pointer_to_vector ( const Teuchos::Ptr< const MV > &mv ) {
77  return mv->getMVPointer_impl();
78  }
79 
80  template <typename MV, typename V>
81  typename vector_pointer_helper<MV, V>::ptr_return_type *
82  vector_pointer_helper<MV, V>::get_pointer_to_vector ( Teuchos::Ptr< const MV > &mv ) {
83  return mv->getMVPointer_impl();
84  }
85 
86 
88  // Copy-getting utilities //
90 
91  /*
92  * If the multivector scalar type and the desired scalar tpye are
93  * the same, then we can do a simple straight copy.
94  */
95  template <typename MV>
96  void same_type_get_copy<MV>::apply(const Teuchos::Ptr<const MV> mv,
97  const Teuchos::ArrayView<typename MV::scalar_t>& v,
98  const size_t ldx,
99  Teuchos::Ptr<const Tpetra::Map<typename MV::local_ordinal_t, typename MV::global_ordinal_t, typename MV::node_t> > distribution_map,
100  EDistribution distribution )
101  {
102  mv->get1dCopy (v, ldx, distribution_map, distribution);
103  }
104 
105  /*
106  * In the case where the scalar type of the multi-vector and the
107  * corresponding S type are different, then we need to first get a
108  * copy of the scalar values, then convert each one into the S
109  * type before inserting into the vals array.
110  */
111  template <typename MV, typename S>
112  void diff_type_get_copy<MV,S>::
113  apply (const Teuchos::Ptr<const MV> mv,
114  const Teuchos::ArrayView<S>& v,
115  const size_t ldx,
116  Teuchos::Ptr<const Tpetra::Map<typename MV::local_ordinal_t, typename MV::global_ordinal_t, typename MV::node_t> > distribution_map,
117  EDistribution distribution )
118  {
119  typedef typename MV::scalar_t mv_scalar_t;
120  typedef typename Teuchos::Array<mv_scalar_t>::size_type size_type;
121 
122  TEUCHOS_TEST_FOR_EXCEPTION(
123  mv.getRawPtr () == NULL, std::invalid_argument,
124  "Amesos2::diff_type_get_copy::apply: mv is null.");
125  TEUCHOS_TEST_FOR_EXCEPTION(
126  distribution_map.getRawPtr () == NULL, std::invalid_argument,
127  "Amesos2::diff_type_get_copy::apply: distribution_map is null.");
128 
129  const size_type vals_length = v.size ();
130  Teuchos::Array<mv_scalar_t> vals_tmp (vals_length);
131 
132  mv->get1dCopy (vals_tmp (), ldx, distribution_map, distribution);
133  for (size_type i = 0; i < vals_length; ++i) {
134  v[i] = Teuchos::as<S> (vals_tmp[i]);
135  }
136  }
137 
144  template <class MV, typename S>
146  do_get (const Teuchos::Ptr<const MV>& mv,
147  const Teuchos::ArrayView<S>& vals,
148  const size_t ldx,
149  Teuchos::Ptr<const Tpetra::Map<typename MV::local_ordinal_t, typename MV::global_ordinal_t, typename MV::node_t> > distribution_map,
150  EDistribution distribution)
151  {
152  // Dispatch to the copy function appropriate for the type
153  std::conditional_t<std::is_same_v<typename MV::scalar_t,S>,
154  same_type_get_copy<MV>,
155  diff_type_get_copy<MV,S> >::apply (mv, vals, ldx, distribution_map, distribution);
156  }
157 
158  template <class MV, typename S>
160  do_get (const Teuchos::Ptr<const MV>& mv,
161  const Teuchos::ArrayView<S>& vals,
162  const size_t ldx,
163  EDistribution distribution,
164  typename MV::global_ordinal_t indexBase)
165  {
166  typedef typename MV::local_ordinal_t lo_t;
167  typedef typename MV::global_ordinal_t go_t;
168  typedef typename MV::global_size_t gs_t;
169  typedef typename MV::node_t node_t;
170 
171  TEUCHOS_TEST_FOR_EXCEPTION(
172  mv.getRawPtr () == NULL, std::invalid_argument,
173  "Amesos2::get_1d_copy_helper::do_get(5 args): mv is null.");
174 
175  Teuchos::RCP<const Tpetra::Map<lo_t,go_t,node_t> > map
176  = Amesos2::Util::getDistributionMap<lo_t,go_t,gs_t,node_t> (distribution,
177  mv->getGlobalLength (),
178  mv->getComm (),
179  indexBase,
180  mv->getMap());
181 
182  do_get (mv, vals, ldx, Teuchos::ptrInArg (*map), distribution);
183  }
184 
185  template <class MV, typename S>
186  void get_1d_copy_helper<MV,S>::do_get(const Teuchos::Ptr<const MV>& mv,
187  const Teuchos::ArrayView<S>& vals,
188  const size_t ldx)
189  {
190  typedef Tpetra::Map<typename MV::local_ordinal_t,
191  typename MV::global_ordinal_t,
192  typename MV::node_t> map_type;
193  TEUCHOS_TEST_FOR_EXCEPTION(
194  mv.getRawPtr () == NULL, std::invalid_argument,
195  "Amesos2::get_1d_copy_helper::do_get(3 args): mv is null.");
196 
197  Teuchos::RCP<const map_type> map = mv->getMap ();
198  TEUCHOS_TEST_FOR_EXCEPTION(
199  map.is_null (), std::invalid_argument,
200  "Amesos2::get_1d_copy_helper::do_get(3 args): mv->getMap() is null.");
201 
202 
203  do_get (mv, vals, ldx, Teuchos::ptrInArg (*map), ROOTED); // ROOTED the default here for now
204  }
205 
206  template <class MV, typename KV>
207  bool get_1d_copy_helper_kokkos_view<MV,KV>::
208  do_get (bool bInitialize,
209  const Teuchos::Ptr<const MV>& mv,
210  KV& kokkos_vals,
211  const size_t ldx,
212  Teuchos::Ptr<const Tpetra::Map<typename MV::local_ordinal_t, typename MV::global_ordinal_t, typename MV::node_t> > distribution_map,
213  EDistribution distribution)
214  {
215  return mv->get1dCopy_kokkos_view(bInitialize, kokkos_vals, ldx, distribution_map, distribution);
216  }
217 
218  template <class MV, typename KV>
219  bool get_1d_copy_helper_kokkos_view<MV,KV>::
220  do_get (bool bInitialize,
221  const Teuchos::Ptr<const MV>& mv,
222  KV& kokkos_vals,
223  const size_t ldx,
224  EDistribution distribution,
225  typename MV::global_ordinal_t indexBase)
226  {
227  typedef typename MV::local_ordinal_t lo_t;
228  typedef typename MV::global_ordinal_t go_t;
229  typedef typename MV::global_size_t gs_t;
230  typedef typename MV::node_t node_t;
231 
232  TEUCHOS_TEST_FOR_EXCEPTION(
233  mv.getRawPtr () == NULL, std::invalid_argument,
234  "Amesos2::get_1d_copy_helper_kokkos_view::do_get(5 args): mv is null.");
235 
236  Teuchos::RCP<const Tpetra::Map<lo_t,go_t,node_t> > map
237  = Amesos2::Util::getDistributionMap<lo_t,go_t,gs_t,node_t> (distribution,
238  mv->getGlobalLength (),
239  mv->getComm (),
240  indexBase,
241  mv->getMap());
242 
243  return do_get (bInitialize, mv, kokkos_vals, ldx, Teuchos::ptrInArg (*map), distribution);
244  }
245 
246  template <class MV, typename KV>
247  bool get_1d_copy_helper_kokkos_view<MV,KV>::
248  do_get (bool bInitialize,
249  const Teuchos::Ptr<const MV>& mv,
250  KV& kokkos_vals,
251  const size_t ldx)
252  {
253  typedef Tpetra::Map<typename MV::local_ordinal_t,
254  typename MV::global_ordinal_t,
255  typename MV::node_t> map_type;
256  TEUCHOS_TEST_FOR_EXCEPTION(
257  mv.getRawPtr () == NULL, std::invalid_argument,
258  "Amesos2::get_1d_copy_helper::do_get(3 args): mv is null.");
259 
260  Teuchos::RCP<const map_type> map = mv->getMap ();
261  TEUCHOS_TEST_FOR_EXCEPTION(
262  map.is_null (), std::invalid_argument,
263  "Amesos2::get_1d_copy_helper_kokkos_view::do_get(3 args): mv->getMap() is null.");
264 
265  return do_get (bInitialize, mv, kokkos_vals, ldx, Teuchos::ptrInArg (*map), ROOTED); // ROOTED the default here for now
266  }
267 
268 
270  // Copy-puting utilities //
272 
273  template <typename MV>
274  void same_type_data_put<MV>::apply(const Teuchos::Ptr<MV>& mv,
275  const Teuchos::ArrayView<typename MV::scalar_t>& data,
276  const size_t ldx,
277  Teuchos::Ptr<const Tpetra::Map<typename MV::local_ordinal_t, typename MV::global_ordinal_t, typename MV::node_t> > distribution_map,
278  EDistribution distribution )
279  {
280  mv->put1dData (data, ldx, distribution_map, distribution);
281  }
282 
283  /*
284  * In the case where the scalar type of the multi-vector and the
285  * corresponding S type are different, then we need to first get a
286  * copy of the scalar values, then convert each one into the S
287  * type before inserting into the vals array.
288  */
289  template <typename MV, typename S>
290  void diff_type_data_put<MV,S>::apply(const Teuchos::Ptr<MV>& mv,
291  const Teuchos::ArrayView<S>& data,
292  const size_t ldx,
293  Teuchos::Ptr<const Tpetra::Map<typename MV::local_ordinal_t, typename MV::global_ordinal_t, typename MV::node_t> > distribution_map,
294  EDistribution distribution )
295  {
296  typedef typename MV::scalar_t mv_scalar_t;
297  typedef typename Teuchos::Array<mv_scalar_t>::size_type size_type;
298 
299  TEUCHOS_TEST_FOR_EXCEPTION(
300  mv.getRawPtr () == NULL, std::invalid_argument,
301  "Amesos2::diff_type_data_put(4 args): mv is null.");
302 
303  const size_type vals_length = data.size ();
304  Teuchos::Array<mv_scalar_t> data_tmp (vals_length);
305 
306  for (size_type i = 0; i < vals_length; ++i) {
307  data_tmp[i] = Teuchos::as<mv_scalar_t> (data[i]);
308  }
309 
310  mv->put1dData (data_tmp (), ldx, distribution_map, distribution);
311  }
312 
313 
320  template <class MV, typename S>
321  void put_1d_data_helper<MV,S>::do_put(const Teuchos::Ptr<MV>& mv,
322  const Teuchos::ArrayView<S>& data,
323  const size_t ldx,
324  Teuchos::Ptr<const Tpetra::Map<typename MV::local_ordinal_t, typename MV::global_ordinal_t, typename MV::node_t> > distribution_map,
325  EDistribution distribution )
326  {
327  // Dispatch to the copy function appropriate for the type
328  std::conditional_t<std::is_same_v<typename MV::scalar_t,S>,
329  same_type_data_put<MV>,
330  diff_type_data_put<MV,S> >::apply(mv, data, ldx, distribution_map, distribution);
331  }
332 
333  template <class MV, typename S>
334  void put_1d_data_helper<MV,S>::do_put(const Teuchos::Ptr<MV>& mv,
335  const Teuchos::ArrayView<S>& data,
336  const size_t ldx,
337  EDistribution distribution, typename MV::global_ordinal_t indexBase)
338  {
339  typedef typename MV::local_ordinal_t lo_t;
340  typedef typename MV::global_ordinal_t go_t;
341  typedef typename MV::global_size_t gs_t;
342  typedef typename MV::node_t node_t;
343 
344  const Teuchos::RCP<const Tpetra::Map<lo_t,go_t,node_t> > map
345  = Amesos2::Util::getDistributionMap<lo_t,go_t,gs_t,node_t>(distribution,
346  mv->getGlobalLength(),
347  mv->getComm(),
348  indexBase,
349  mv->getMap());
350 
351  do_put(mv, data, ldx, Teuchos::ptrInArg(*map), distribution);
352  }
353 
354  template <class MV, typename S>
355  void put_1d_data_helper<MV,S>::do_put (const Teuchos::Ptr<MV>& mv,
356  const Teuchos::ArrayView<S>& data,
357  const size_t ldx)
358  {
359  const Teuchos::RCP<const Tpetra::Map<typename MV::local_ordinal_t,
360  typename MV::global_ordinal_t,
361  typename MV::node_t> > map
362  = mv->getMap();
363  do_put (mv, data, ldx, Teuchos::ptrInArg (*map), ROOTED); // Default as ROOTED for now
364  }
365 
366  template <class MV, typename KV>
367  void put_1d_data_helper_kokkos_view<MV,KV>::do_put(const Teuchos::Ptr<MV>& mv,
368  KV& kokkos_data,
369  const size_t ldx,
370  Teuchos::Ptr<const Tpetra::Map<typename MV::local_ordinal_t, typename MV::global_ordinal_t, typename MV::node_t> > distribution_map,
371  EDistribution distribution )
372  {
373  mv->put1dData_kokkos_view(kokkos_data, ldx, distribution_map, distribution);
374  }
375 
376  template <class MV, typename KV>
377  void put_1d_data_helper_kokkos_view<MV,KV>::do_put(const Teuchos::Ptr<MV>& mv,
378  KV& kokkos_data,
379  const size_t ldx,
380  EDistribution distribution, typename MV::global_ordinal_t indexBase)
381  {
382  typedef typename MV::local_ordinal_t lo_t;
383  typedef typename MV::global_ordinal_t go_t;
384  typedef typename MV::global_size_t gs_t;
385  typedef typename MV::node_t node_t;
386 
387  const Teuchos::RCP<const Tpetra::Map<lo_t,go_t,node_t> > map
388  = Amesos2::Util::getDistributionMap<lo_t,go_t,gs_t,node_t>(distribution,
389  mv->getGlobalLength(),
390  mv->getComm(),
391  indexBase,
392  mv->getMap());
393 
394  do_put(mv, kokkos_data, ldx, Teuchos::ptrInArg(*map), distribution);
395  }
396 
397  template <class MV, typename KV>
398  void put_1d_data_helper_kokkos_view<MV,KV>::do_put (const Teuchos::Ptr<MV>& mv,
399  KV& kokkos_data,
400  const size_t ldx)
401  {
402  const Teuchos::RCP<const Tpetra::Map<typename MV::local_ordinal_t,
403  typename MV::global_ordinal_t,
404  typename MV::node_t> > map
405  = mv->getMap();
406  do_put (mv, kokkos_data, ldx, Teuchos::ptrInArg (*map), ROOTED); // Default as ROOTED for now
407  }
408 
409  } // end namespace Util
410 
411 } // end namespace Amesos2
412 
413 #endif // AMESOS2_EPETRAMULTIVECADAPTER_DEF
Utility functions for Amesos2.
Amesos2::MultiVecAdapter specialization for the Kokkos::View class.
static void do_get(const Teuchos::Ptr< const MV > &mv, const Teuchos::ArrayView< S > &vals, const size_t ldx, Teuchos::Ptr< const Tpetra::Map< typename MV::local_ordinal_t, typename MV::global_ordinal_t, typename MV::node_t > > distribution_map, EDistribution distribution=ROOTED)
Helper class for getting 1-D copies of multivectors.
Definition: Amesos2_MultiVecAdapter_def.hpp:146
Amesos2::MultiVecAdapter specialization for the Tpetra::MultiVector class.
static void do_put(const Teuchos::Ptr< MV > &mv, const Teuchos::ArrayView< S > &data, const size_t ldx, Teuchos::Ptr< const Tpetra::Map< typename MV::local_ordinal_t, typename MV::global_ordinal_t, typename MV::node_t > > distribution_map, EDistribution distribution=ROOTED)
Helper class for putting 1-D data arrays into multivectors.
Definition: Amesos2_MultiVecAdapter_def.hpp:321
EDistribution
Definition: Amesos2_TypeDecl.hpp:123