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
50 
51 #include "Amesos2_Util.hpp" // for getDistributionMap
52 
53 namespace Amesos2{
54 
55  namespace Util {
56 
58  // Pointer-getting utilities //
60 
61  template <typename MV, typename V>
62  typename vector_pointer_helper<MV, V>::ptr_return_type *
63  vector_pointer_helper<MV, V>::get_pointer_to_vector ( const Teuchos::Ptr< MV > &mv ) {
64  return mv->getMVPointer_impl();
65  }
66 
67  template <typename MV, typename V>
68  typename vector_pointer_helper<MV, V>::ptr_return_type *
69  vector_pointer_helper<MV, V>::get_pointer_to_vector ( Teuchos::Ptr< MV > &mv ) {
70  return mv->getMVPointer_impl();
71  }
72 
73  template <typename MV, typename V>
74  typename vector_pointer_helper<MV, V>::ptr_return_type *
75  vector_pointer_helper<MV, V>::get_pointer_to_vector ( const Teuchos::Ptr< const MV > &mv ) {
76  return mv->getMVPointer_impl();
77  }
78 
79  template <typename MV, typename V>
80  typename vector_pointer_helper<MV, V>::ptr_return_type *
81  vector_pointer_helper<MV, V>::get_pointer_to_vector ( Teuchos::Ptr< const MV > &mv ) {
82  return mv->getMVPointer_impl();
83  }
84 
85 
87  // Copy-getting utilities //
89 
90  /*
91  * If the multivector scalar type and the desired scalar tpye are
92  * the same, then we can do a simple straight copy.
93  */
94  template <typename MV>
95  void same_type_get_copy<MV>::apply(const Teuchos::Ptr<const MV>& mv,
96  const Teuchos::ArrayView<typename MV::scalar_t>& v,
97  const size_t ldx,
98  Teuchos::Ptr<const Tpetra::Map<typename MV::local_ordinal_t, typename MV::global_ordinal_t, typename MV::node_t> > distribution_map,
99  EDistribution distribution )
100  {
101  mv->get1dCopy (v, ldx, distribution_map, distribution);
102  }
103 
104  /*
105  * In the case where the scalar type of the multi-vector and the
106  * corresponding S type are different, then we need to first get a
107  * copy of the scalar values, then convert each one into the S
108  * type before inserting into the vals array.
109  */
110  template <typename MV, typename S>
111  void diff_type_get_copy<MV,S>::
112  apply (const Teuchos::Ptr<const MV>& mv,
113  const Teuchos::ArrayView<S>& v,
114  const size_t& ldx,
115  Teuchos::Ptr<const Tpetra::Map<typename MV::local_ordinal_t, typename MV::global_ordinal_t, typename MV::node_t> > distribution_map,
116  EDistribution distribution )
117  {
118  typedef typename MV::scalar_t mv_scalar_t;
119  typedef typename Teuchos::Array<mv_scalar_t>::size_type size_type;
120 
121  TEUCHOS_TEST_FOR_EXCEPTION(
122  mv.getRawPtr () == NULL, std::invalid_argument,
123  "Amesos2::diff_type_get_copy::apply: mv is null.");
124  TEUCHOS_TEST_FOR_EXCEPTION(
125  distribution_map.getRawPtr () == NULL, std::invalid_argument,
126  "Amesos2::diff_type_get_copy::apply: distribution_map is null.");
127 
128  const size_type vals_length = v.size ();
129  Teuchos::Array<mv_scalar_t> vals_tmp (vals_length);
130 
131  mv->get1dCopy (vals_tmp (), ldx, distribution_map, distribution);
132  for (size_type i = 0; i < vals_length; ++i) {
133  v[i] = Teuchos::as<S> (vals_tmp[i]);
134  }
135  }
136 
143  template <class MV, typename S>
145  do_get (const Teuchos::Ptr<const MV>& mv,
146  const Teuchos::ArrayView<S>& vals,
147  const size_t ldx,
148  Teuchos::Ptr<const Tpetra::Map<typename MV::local_ordinal_t, typename MV::global_ordinal_t, typename MV::node_t> > distribution_map,
149  EDistribution distribution)
150  {
151  // Dispatch to the copy function appropriate for the type
152  if_then_else<is_same<typename MV::scalar_t,S>::value,
153  same_type_get_copy<MV>,
154  diff_type_get_copy<MV,S> >::type::apply (mv, vals, ldx, distribution_map, distribution);
155  }
156 
157  template <class MV, typename S>
159  do_get (const Teuchos::Ptr<const MV>& mv,
160  const Teuchos::ArrayView<S>& vals,
161  const size_t ldx,
162  EDistribution distribution,
163  typename MV::global_ordinal_t indexBase)
164  {
165  typedef typename MV::local_ordinal_t lo_t;
166  typedef typename MV::global_ordinal_t go_t;
167  typedef typename MV::global_size_t gs_t;
168  typedef typename MV::node_t node_t;
169 
170  TEUCHOS_TEST_FOR_EXCEPTION(
171  mv.getRawPtr () == NULL, std::invalid_argument,
172  "Amesos2::get_1d_copy_helper::do_get(5 args): mv is null.");
173 
174  Teuchos::RCP<const Tpetra::Map<lo_t,go_t,node_t> > map
175  = Amesos2::Util::getDistributionMap<lo_t,go_t,gs_t,node_t> (distribution,
176  mv->getGlobalLength (),
177  mv->getComm (),
178  indexBase,
179  mv->getMap());
180 
181  do_get (mv, vals, ldx, Teuchos::ptrInArg (*map), distribution);
182  }
183 
184  template <class MV, typename S>
185  void get_1d_copy_helper<MV,S>::do_get(const Teuchos::Ptr<const MV>& mv,
186  const Teuchos::ArrayView<S>& vals,
187  const size_t ldx)
188  {
189  typedef Tpetra::Map<typename MV::local_ordinal_t,
190  typename MV::global_ordinal_t,
191  typename MV::node_t> map_type;
192  TEUCHOS_TEST_FOR_EXCEPTION(
193  mv.getRawPtr () == NULL, std::invalid_argument,
194  "Amesos2::get_1d_copy_helper::do_get(3 args): mv is null.");
195 
196  Teuchos::RCP<const map_type> map = mv->getMap ();
197  TEUCHOS_TEST_FOR_EXCEPTION(
198  map.is_null (), std::invalid_argument,
199  "Amesos2::get_1d_copy_helper::do_get(3 args): mv->getMap() is null.");
200 
201 
202  do_get (mv, vals, ldx, Teuchos::ptrInArg (*map), ROOTED); // ROOTED the default here for now
203  }
204 
205 
207  // Copy-puting utilities //
209 
210  template <typename MV>
211  void same_type_data_put<MV>::apply(const Teuchos::Ptr<MV>& mv,
212  const Teuchos::ArrayView<typename MV::scalar_t>& data,
213  const size_t ldx,
214  Teuchos::Ptr<const Tpetra::Map<typename MV::local_ordinal_t, typename MV::global_ordinal_t, typename MV::node_t> > distribution_map,
215  EDistribution distribution )
216  {
217  mv->put1dData (data, ldx, distribution_map, distribution);
218  }
219 
220  /*
221  * In the case where the scalar type of the multi-vector and the
222  * corresponding S type are different, then we need to first get a
223  * copy of the scalar values, then convert each one into the S
224  * type before inserting into the vals array.
225  */
226  template <typename MV, typename S>
227  void diff_type_data_put<MV,S>::apply(const Teuchos::Ptr<MV>& mv,
228  const Teuchos::ArrayView<S>& data,
229  const size_t& ldx,
230  Teuchos::Ptr<const Tpetra::Map<typename MV::local_ordinal_t, typename MV::global_ordinal_t, typename MV::node_t> > distribution_map,
231  EDistribution distribution )
232  {
233  typedef typename MV::scalar_t mv_scalar_t;
234  typedef typename Teuchos::Array<mv_scalar_t>::size_type size_type;
235 
236  TEUCHOS_TEST_FOR_EXCEPTION(
237  mv.getRawPtr () == NULL, std::invalid_argument,
238  "Amesos2::diff_type_data_put(4 args): mv is null.");
239 
240  const size_type vals_length = data.size ();
241  Teuchos::Array<mv_scalar_t> data_tmp (vals_length);
242 
243  for (size_type i = 0; i < vals_length; ++i) {
244  data_tmp[i] = Teuchos::as<mv_scalar_t> (data[i]);
245  }
246 
247  mv->put1dData (data_tmp (), ldx, distribution_map, distribution);
248  }
249 
250 
257  template <class MV, typename S>
258  void put_1d_data_helper<MV,S>::do_put(const Teuchos::Ptr<MV>& mv,
259  const Teuchos::ArrayView<S>& data,
260  const size_t ldx,
261  Teuchos::Ptr<const Tpetra::Map<typename MV::local_ordinal_t, typename MV::global_ordinal_t, typename MV::node_t> > distribution_map,
262  EDistribution distribution )
263  {
264  // Dispatch to the copy function appropriate for the type
265  if_then_else<is_same<typename MV::scalar_t,S>::value,
266  same_type_data_put<MV>,
267  diff_type_data_put<MV,S> >::type::apply(mv, data, ldx, distribution_map, distribution);
268  }
269 
270  template <class MV, typename S>
271  void put_1d_data_helper<MV,S>::do_put(const Teuchos::Ptr<MV>& mv,
272  const Teuchos::ArrayView<S>& data,
273  const size_t ldx,
274  EDistribution distribution, typename MV::global_ordinal_t indexBase)
275  {
276  typedef typename MV::local_ordinal_t lo_t;
277  typedef typename MV::global_ordinal_t go_t;
278  typedef typename MV::global_size_t gs_t;
279  typedef typename MV::node_t node_t;
280 
281  const Teuchos::RCP<const Tpetra::Map<lo_t,go_t,node_t> > map
282  = Amesos2::Util::getDistributionMap<lo_t,go_t,gs_t,node_t>(distribution,
283  mv->getGlobalLength(),
284  mv->getComm(),
285  indexBase,
286  mv->getMap());
287 
288  do_put(mv, data, ldx, Teuchos::ptrInArg(*map), distribution);
289  }
290 
291  template <class MV, typename S>
292  void put_1d_data_helper<MV,S>::do_put (const Teuchos::Ptr<MV>& mv,
293  const Teuchos::ArrayView<S>& data,
294  const size_t ldx)
295  {
296  const Teuchos::RCP<const Tpetra::Map<typename MV::local_ordinal_t,
297  typename MV::global_ordinal_t,
298  typename MV::node_t> > map
299  = mv->getMap();
300  do_put (mv, data, ldx, Teuchos::ptrInArg (*map), ROOTED); // Default as ROOTED for now
301  }
302 
303  } // end namespace Util
304 
305 } // end namespace Amesos2
306 
307 #endif // AMESOS2_EPETRAMULTIVECADAPTER_DEF
Utility functions for Amesos2.
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:145
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:258
EDistribution
Definition: Amesos2_TypeDecl.hpp:123