Amesos2 - Direct Sparse Solver Interfaces  Version of the Day
Amesos2_Util.hpp
Go to the documentation of this file.
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 
52 #ifndef AMESOS2_UTIL_HPP
53 #define AMESOS2_UTIL_HPP
54 
55 #include "Amesos2_config.h"
56 
57 #include <Teuchos_RCP.hpp>
58 #include <Teuchos_BLAS_types.hpp>
59 #include <Teuchos_ArrayView.hpp>
60 #include <Teuchos_FancyOStream.hpp>
61 
62 #ifdef HAVE_AMESOS2_EPETRA
63 # include <Epetra_Map.h>
64 #endif
65 
66 #include <Tpetra_Map.hpp>
67 
68 #include "Amesos2_TypeDecl.hpp"
69 #include "Amesos2_Meta.hpp"
70 
71 
72 namespace Amesos2 {
73 
74  namespace Util {
75 
82  using Teuchos::RCP;
83  using Teuchos::ArrayView;
84 
85  using Meta::is_same;
86  using Meta::if_then_else;
87 
103  template <typename LO, typename GO, typename GS, typename Node>
104  const Teuchos::RCP<const Tpetra::Map<LO,GO,Node> >
105  getDistributionMap(EDistribution distribution,
106  GS num_global_elements,
107  const Teuchos::RCP<const Teuchos::Comm<int> >& comm,
108  GO indexBase = 0);
109 
110 
111 #ifdef HAVE_AMESOS2_EPETRA
112 
117  template <typename LO, typename GO, typename GS, typename Node>
118  RCP<Tpetra::Map<LO,GO,Node> >
119  epetra_map_to_tpetra_map(const Epetra_BlockMap& map);
120 
126  template <typename LO, typename GO, typename GS, typename Node>
127  RCP<Epetra_Map>
128  tpetra_map_to_epetra_map(const Tpetra::Map<LO,GO,Node>& map);
129 
135  const RCP<const Teuchos::Comm<int> > to_teuchos_comm(RCP<const Epetra_Comm> c);
136 
142  const RCP<const Epetra_Comm> to_epetra_comm(RCP<const Teuchos::Comm<int> > c);
143 #endif // HAVE_AMESOS2_EPETRA
144 
150  template <typename Scalar,
151  typename GlobalOrdinal,
152  typename GlobalSizeT>
153  void transpose(ArrayView<Scalar> vals,
154  ArrayView<GlobalOrdinal> indices,
155  ArrayView<GlobalSizeT> ptr,
156  ArrayView<Scalar> trans_vals,
157  ArrayView<GlobalOrdinal> trans_indices,
158  ArrayView<GlobalSizeT> trans_ptr);
159 
173  template <typename Scalar1, typename Scalar2>
174  void scale(ArrayView<Scalar1> vals, size_t l,
175  size_t ld, ArrayView<Scalar2> s);
176 
195  template <typename Scalar1, typename Scalar2, class BinaryOp>
196  void scale(ArrayView<Scalar1> vals, size_t l,
197  size_t ld, ArrayView<Scalar2> s, BinaryOp binary_op);
198 
199 
201  void printLine( Teuchos::FancyOStream &out );
202 
203 
205  // Matrix/MultiVector Utilities //
207 
208 #ifndef DOXYGEN_SHOULD_SKIP_THIS
209  /*
210  * The following represents a general way of getting a CRS or CCS
211  * representation of a matrix with implicit type conversions. The
212  * \c get_crs_helper and \c get_ccs_helper classes are templated
213  * on 4 types:
214  *
215  * - A Matrix type (conforming to the Amesos2 MatrixAdapter interface)
216  * - A scalar type
217  * - A global ordinal type
218  * - A global size type
219  *
220  * The last three template types correspond to the input argument
221  * types. For example, if the scalar type is \c double , then we
222  * require that the \c nzvals argument is a \c
223  * Teuchos::ArrayView<double> type.
224  *
225  * These helpers perform any type conversions that must be
226  * performed to go between the Matrix's types and the input types.
227  * If no conversions are necessary the static functions can be
228  * effectively inlined.
229  */
230 
231  template <class M, typename S, typename GO, typename GS, class Op>
232  struct same_gs_helper
233  {
234  static void do_get(const Teuchos::Ptr<const M> mat,
235  const ArrayView<typename M::scalar_t> nzvals,
236  const ArrayView<typename M::global_ordinal_t> indices,
237  const ArrayView<GS> pointers,
238  GS& nnz,
239  const Teuchos::Ptr<
240  const Tpetra::Map<typename M::local_ordinal_t,
241  typename M::global_ordinal_t,
242  typename M::node_t> > map,
243  EStorage_Ordering ordering)
244  {
245  Op::apply(mat, nzvals, indices, pointers, nnz, map, ordering);
246  }
247  };
248 
249  template <class M, typename S, typename GO, typename GS, class Op>
250  struct diff_gs_helper
251  {
252  static void do_get(const Teuchos::Ptr<const M> mat,
253  const ArrayView<typename M::scalar_t> nzvals,
254  const ArrayView<typename M::global_ordinal_t> indices,
255  const ArrayView<GS> pointers,
256  GS& nnz,
257  const Teuchos::Ptr<
258  const Tpetra::Map<typename M::local_ordinal_t,
259  typename M::global_ordinal_t,
260  typename M::node_t> > map,
261  EStorage_Ordering ordering)
262  {
263  typedef typename M::global_size_t mat_gs_t;
264  typename ArrayView<GS>::size_type i, size = pointers.size();
265  Teuchos::Array<mat_gs_t> pointers_tmp(size);
266  mat_gs_t nnz_tmp = 0;
267 
268  Op::apply(mat, nzvals, indices, pointers_tmp, nnz_tmp, map, ordering);
269 
270  for (i = 0; i < size; ++i){
271  pointers[i] = Teuchos::as<GS>(pointers_tmp[i]);
272  }
273  nnz = Teuchos::as<GS>(nnz_tmp);
274  }
275  };
276 
277  template <class M, typename S, typename GO, typename GS, class Op>
278  struct same_go_helper
279  {
280  static void do_get(const Teuchos::Ptr<const M> mat,
281  const ArrayView<typename M::scalar_t> nzvals,
282  const ArrayView<GO> indices,
283  const ArrayView<GS> pointers,
284  GS& nnz,
285  const Teuchos::Ptr<
286  const Tpetra::Map<typename M::local_ordinal_t,
287  typename M::global_ordinal_t,
288  typename M::node_t> > map,
289  EStorage_Ordering ordering)
290  {
291  typedef typename M::global_size_t mat_gs_t;
292  if_then_else<is_same<GS,mat_gs_t>::value,
293  same_gs_helper<M,S,GO,GS,Op>,
294  diff_gs_helper<M,S,GO,GS,Op> >::type::do_get(mat, nzvals, indices,
295  pointers, nnz, map,
296  ordering);
297  }
298  };
299 
300  template <class M, typename S, typename GO, typename GS, class Op>
301  struct diff_go_helper
302  {
303  static void do_get(const Teuchos::Ptr<const M> mat,
304  const ArrayView<typename M::scalar_t> nzvals,
305  const ArrayView<GO> indices,
306  const ArrayView<GS> pointers,
307  GS& nnz,
308  const Teuchos::Ptr<
309  const Tpetra::Map<typename M::local_ordinal_t,
310  typename M::global_ordinal_t,
311  typename M::node_t> > map,
312  EStorage_Ordering ordering)
313  {
314  typedef typename M::global_ordinal_t mat_go_t;
315  typedef typename M::global_size_t mat_gs_t;
316  typename ArrayView<GO>::size_type i, size = indices.size();
317  Teuchos::Array<mat_go_t> indices_tmp(size);
318 
319  if_then_else<is_same<GS,mat_gs_t>::value,
320  same_gs_helper<M,S,GO,GS,Op>,
321  diff_gs_helper<M,S,GO,GS,Op> >::type::do_get(mat, nzvals, indices_tmp,
322  pointers, nnz, map,
323  ordering);
324 
325  for (i = 0; i < size; ++i){
326  indices[i] = Teuchos::as<GO>(indices_tmp[i]);
327  }
328  }
329  };
330 
331  template <class M, typename S, typename GO, typename GS, class Op>
332  struct same_scalar_helper
333  {
334  static void do_get(const Teuchos::Ptr<const M> mat,
335  const ArrayView<S> nzvals,
336  const ArrayView<GO> indices,
337  const ArrayView<GS> pointers,
338  GS& nnz,
339  const Teuchos::Ptr<
340  const Tpetra::Map<typename M::local_ordinal_t,
341  typename M::global_ordinal_t,
342  typename M::node_t> > map,
343  EStorage_Ordering ordering)
344  {
345  typedef typename M::global_ordinal_t mat_go_t;
346  if_then_else<is_same<GO,mat_go_t>::value,
347  same_go_helper<M,S,GO,GS,Op>,
348  diff_go_helper<M,S,GO,GS,Op> >::type::do_get(mat, nzvals, indices,
349  pointers, nnz, map,
350  ordering);
351  }
352  };
353 
354  template <class M, typename S, typename GO, typename GS, class Op>
355  struct diff_scalar_helper
356  {
357  static void do_get(const Teuchos::Ptr<const M> mat,
358  const ArrayView<S> nzvals,
359  const ArrayView<GO> indices,
360  const ArrayView<GS> pointers,
361  GS& nnz,
362  const Teuchos::Ptr<
363  const Tpetra::Map<typename M::local_ordinal_t,
364  typename M::global_ordinal_t,
365  typename M::node_t> > map,
366  EStorage_Ordering ordering)
367  {
368  typedef typename M::scalar_t mat_scalar_t;
369  typedef typename M::global_ordinal_t mat_go_t;
370  typename ArrayView<S>::size_type i, size = nzvals.size();
371  Teuchos::Array<mat_scalar_t> nzvals_tmp(size);
372 
373  if_then_else<is_same<GO,mat_go_t>::value,
374  same_go_helper<M,S,GO,GS,Op>,
375  diff_go_helper<M,S,GO,GS,Op> >::type::do_get(mat, nzvals_tmp, indices,
376  pointers, nnz, map,
377  ordering);
378 
379  for (i = 0; i < size; ++i){
380  nzvals[i] = Teuchos::as<S>(nzvals_tmp[i]);
381  }
382  }
383  };
384 #endif // DOXYGEN_SHOULD_SKIP_THIS
385 
398  template<class Matrix, typename S, typename GO, typename GS, class Op>
400  {
401  static void do_get(const Teuchos::Ptr<const Matrix> mat,
402  const ArrayView<S> nzvals,
403  const ArrayView<GO> indices,
404  const ArrayView<GS> pointers,
405  GS& nnz, EDistribution distribution,
406  EStorage_Ordering ordering=ARBITRARY,
407  GO indexBase = 0)
408  {
409  typedef typename Matrix::local_ordinal_t lo_t;
410  typedef typename Matrix::global_ordinal_t go_t;
411  typedef typename Matrix::global_size_t gs_t;
412  typedef typename Matrix::node_t node_t;
413 
414  const Teuchos::RCP<const Tpetra::Map<lo_t,go_t,node_t> > map
415  = getDistributionMap<lo_t,go_t,gs_t,node_t>(distribution,
416  Op::get_dimension(mat),
417  mat->getComm(), indexBase);
418  do_get(mat, nzvals, indices, pointers, nnz, Teuchos::ptrInArg(*map), ordering);
419  }
420 
425  static void do_get(const Teuchos::Ptr<const Matrix> mat,
426  const ArrayView<S> nzvals,
427  const ArrayView<GO> indices,
428  const ArrayView<GS> pointers,
429  GS& nnz, EStorage_Ordering ordering=ARBITRARY)
430  {
431  const Teuchos::RCP<const Tpetra::Map<typename Matrix::local_ordinal_t,
432  typename Matrix::global_ordinal_t,
433  typename Matrix::node_t> > map
434  = Op::getMap(mat);
435  do_get(mat, nzvals, indices, pointers, nnz, Teuchos::ptrInArg(*map), ordering);
436  }
437 
442  static void do_get(const Teuchos::Ptr<const Matrix> mat,
443  const ArrayView<S> nzvals,
444  const ArrayView<GO> indices,
445  const ArrayView<GS> pointers,
446  GS& nnz,
447  const Teuchos::Ptr<
448  const Tpetra::Map<typename Matrix::local_ordinal_t,
449  typename Matrix::global_ordinal_t,
450  typename Matrix::node_t> > map,
451  EStorage_Ordering ordering=ARBITRARY)
452  {
453  typedef typename Matrix::scalar_t mat_scalar;
454  if_then_else<is_same<mat_scalar,S>::value,
455  same_scalar_helper<Matrix,S,GO,GS,Op>,
456  diff_scalar_helper<Matrix,S,GO,GS,Op> >::type::do_get(mat,
457  nzvals, indices,
458  pointers, nnz,
459  map, ordering);
460  }
461  };
462 
463 #ifndef DOXYGEN_SHOULD_SKIP_THIS
464  /*
465  * These two function-like classes are meant to be used as the \c
466  * Op template parameter for the \c get_cxs_helper template class.
467  */
468  template<class Matrix>
469  struct get_ccs_func
470  {
471  static void apply(const Teuchos::Ptr<const Matrix> mat,
472  const ArrayView<typename Matrix::scalar_t> nzvals,
473  const ArrayView<typename Matrix::global_ordinal_t> rowind,
474  const ArrayView<typename Matrix::global_size_t> colptr,
475  typename Matrix::global_size_t& nnz,
476  const Teuchos::Ptr<
477  const Tpetra::Map<typename Matrix::local_ordinal_t,
478  typename Matrix::global_ordinal_t,
479  typename Matrix::node_t> > map,
480  EStorage_Ordering ordering)
481  {
482  mat->getCcs(nzvals, rowind, colptr, nnz, map, ordering);
483  }
484 
485  static
486  const Teuchos::RCP<const Tpetra::Map<typename Matrix::local_ordinal_t,
487  typename Matrix::global_ordinal_t,
488  typename Matrix::node_t> >
489  getMap(const Teuchos::Ptr<const Matrix> mat)
490  {
491  return mat->getColMap();
492  }
493 
494  static
495  typename Matrix::global_size_t
496  get_dimension(const Teuchos::Ptr<const Matrix> mat)
497  {
498  return mat->getGlobalNumCols();
499  }
500  };
501 
502  template<class Matrix>
503  struct get_crs_func
504  {
505  static void apply(const Teuchos::Ptr<const Matrix> mat,
506  const ArrayView<typename Matrix::scalar_t> nzvals,
507  const ArrayView<typename Matrix::global_ordinal_t> colind,
508  const ArrayView<typename Matrix::global_size_t> rowptr,
509  typename Matrix::global_size_t& nnz,
510  const Teuchos::Ptr<
511  const Tpetra::Map<typename Matrix::local_ordinal_t,
512  typename Matrix::global_ordinal_t,
513  typename Matrix::node_t> > map,
514  EStorage_Ordering ordering)
515  {
516  mat->getCrs(nzvals, colind, rowptr, nnz, map, ordering);
517  }
518 
519  static
520  const Teuchos::RCP<const Tpetra::Map<typename Matrix::local_ordinal_t,
521  typename Matrix::global_ordinal_t,
522  typename Matrix::node_t> >
523  getMap(const Teuchos::Ptr<const Matrix> mat)
524  {
525  return mat->getRowMap();
526  }
527 
528  static
529  typename Matrix::global_size_t
530  get_dimension(const Teuchos::Ptr<const Matrix> mat)
531  {
532  return mat->getGlobalNumRows();
533  }
534  };
535 #endif // DOXYGEN_SHOULD_SKIP_THIS
536 
574  template<class Matrix, typename S, typename GO, typename GS>
575  struct get_ccs_helper : get_cxs_helper<Matrix,S,GO,GS,get_ccs_func<Matrix> >
576  {};
577 
585  template<class Matrix, typename S, typename GO, typename GS>
586  struct get_crs_helper : get_cxs_helper<Matrix,S,GO,GS,get_crs_func<Matrix> >
587  {};
588 
589  /* End Matrix/MultiVector Utilities */
590 
591 
593  // Definitions //
595 
596  template <typename LO, typename GO, typename GS, typename Node>
597  const Teuchos::RCP<const Tpetra::Map<LO,GO,Node> >
599  GS num_global_elements,
600  const Teuchos::RCP<const Teuchos::Comm<int> >& comm,
601  GO indexBase)
602  {
603  // TODO: Need to add indexBase to cases other than ROOTED
604  // We do not support these maps in any solver now.
605  switch( distribution ){
606  case DISTRIBUTED:
608  return Tpetra::createUniformContigMapWithNode<LO,GO, Node>(num_global_elements, comm);
609  break;
610  case GLOBALLY_REPLICATED:
611  return Tpetra::createLocalMapWithNode<LO,GO, Node>(num_global_elements, comm);
612  break;
613  case ROOTED:
614  {
615  int rank = Teuchos::rank(*comm);
616  size_t my_num_elems = Teuchos::OrdinalTraits<size_t>::zero();
617  if( rank == 0 ) my_num_elems = num_global_elements;
618  return rcp(new Tpetra::Map<LO,GO, Node>(num_global_elements,
619  my_num_elems, indexBase, comm));
620  break;
621  }
622  default:
623  TEUCHOS_TEST_FOR_EXCEPTION( true,
624  std::logic_error,
625  "Control should never reach this point. "
626  "Please contact the Amesos2 developers." );
627  break;
628  }
629  }
630 
631 #ifdef HAVE_AMESOS2_EPETRA
632  template <typename LO, typename GO, typename GS, typename Node>
633  Teuchos::RCP<Tpetra::Map<LO,GO,Node> >
634  epetra_map_to_tpetra_map(const Epetra_BlockMap& map)
635  {
636  using Teuchos::as;
637  using Teuchos::rcp;
638 
639  int num_my_elements = map.NumMyElements();
640  Teuchos::Array<int> my_global_elements(num_my_elements);
641  map.MyGlobalElements(my_global_elements.getRawPtr());
642 
643  typedef Tpetra::Map<LO,GO,Node> map_t;
644  RCP<map_t> tmap = rcp(new map_t(Teuchos::OrdinalTraits<GS>::invalid(),
645  my_global_elements(),
646  as<GO>(map.IndexBase()),
647  to_teuchos_comm(Teuchos::rcpFromRef(map.Comm()))));
648  return tmap;
649  }
650 
651  template <typename LO, typename GO, typename GS, typename Node>
652  Teuchos::RCP<Epetra_Map>
653  tpetra_map_to_epetra_map(const Tpetra::Map<LO,GO,Node>& map)
654  {
655  using Teuchos::as;
656 
657  Teuchos::Array<GO> elements_tmp;
658  elements_tmp = map.getNodeElementList();
659  int num_my_elements = elements_tmp.size();
660  Teuchos::Array<int> my_global_elements(num_my_elements);
661  for (int i = 0; i < num_my_elements; ++i){
662  my_global_elements[i] = as<int>(elements_tmp[i]);
663  }
664 
665  using Teuchos::rcp;
666  RCP<Epetra_Map> emap = rcp(new Epetra_Map(-1,
667  num_my_elements,
668  my_global_elements.getRawPtr(),
669  as<GO>(map.getIndexBase()),
670  *to_epetra_comm(map.getComm())));
671  return emap;
672  }
673 #endif // HAVE_AMESOS2_EPETRA
674 
675  template <typename Scalar,
676  typename GlobalOrdinal,
677  typename GlobalSizeT>
678  void transpose(Teuchos::ArrayView<Scalar> vals,
679  Teuchos::ArrayView<GlobalOrdinal> indices,
680  Teuchos::ArrayView<GlobalSizeT> ptr,
681  Teuchos::ArrayView<Scalar> trans_vals,
682  Teuchos::ArrayView<GlobalOrdinal> trans_indices,
683  Teuchos::ArrayView<GlobalSizeT> trans_ptr)
684  {
685  /* We have a compressed-row storage format of this matrix. We
686  * transform this into a compressed-column format using a
687  * distribution-counting sort algorithm, which is described by
688  * D.E. Knuth in TAOCP Vol 3, 2nd ed pg 78.
689  */
690 
691 #ifdef HAVE_AMESOS2_DEBUG
692  typename Teuchos::ArrayView<GlobalOrdinal>::iterator ind_it, ind_begin, ind_end;
693  ind_begin = indices.begin();
694  ind_end = indices.end();
695  size_t min_trans_ptr_size = *std::max_element(ind_begin, ind_end) + 1;
696  TEUCHOS_TEST_FOR_EXCEPTION( Teuchos::as<size_t>(trans_ptr.size()) < min_trans_ptr_size,
697  std::invalid_argument,
698  "Transpose pointer size not large enough." );
699  TEUCHOS_TEST_FOR_EXCEPTION( trans_vals.size() < vals.size(),
700  std::invalid_argument,
701  "Transpose values array not large enough." );
702  TEUCHOS_TEST_FOR_EXCEPTION( trans_indices.size() < indices.size(),
703  std::invalid_argument,
704  "Transpose indices array not large enough." );
705 #else
706  typename Teuchos::ArrayView<GlobalOrdinal>::iterator ind_it, ind_end;
707 #endif
708 
709  // Count the number of entries in each column
710  Teuchos::Array<GlobalSizeT> count(trans_ptr.size(), 0);
711  ind_end = indices.end();
712  for( ind_it = indices.begin(); ind_it != ind_end; ++ind_it ){
713  ++(count[(*ind_it) + 1]);
714  }
715 
716  // Accumulate
717  typename Teuchos::Array<GlobalSizeT>::iterator cnt_it, cnt_end;
718  cnt_end = count.end();
719  for( cnt_it = count.begin() + 1; cnt_it != cnt_end; ++cnt_it ){
720  *cnt_it = *cnt_it + *(cnt_it - 1);
721  }
722  // This becomes the array of column pointers
723  trans_ptr.assign(count);
724 
725  /* Move the nonzero values into their final place in nzval, based on the
726  * counts found previously.
727  *
728  * This sequence deviates from Knuth's algorithm a bit, following more
729  * closely the description presented in Gustavson, Fred G. "Two Fast
730  * Algorithms for Sparse Matrices: Multiplication and Permuted
731  * Transposition" ACM Trans. Math. Softw. volume 4, number 3, 1978, pages
732  * 250--269, http://doi.acm.org/10.1145/355791.355796.
733  *
734  * The output indices end up in sorted order
735  */
736 
737  GlobalSizeT size = ptr.size();
738  for( GlobalSizeT i = 0; i < size - 1; ++i ){
739  GlobalOrdinal u = ptr[i];
740  GlobalOrdinal v = ptr[i + 1];
741  for( GlobalOrdinal j = u; j < v; ++j ){
742  GlobalOrdinal k = count[indices[j]];
743  trans_vals[k] = vals[j];
744  trans_indices[k] = i;
745  ++(count[indices[j]]);
746  }
747  }
748  }
749 
750 
751  template <typename Scalar1, typename Scalar2>
752  void
753  scale(Teuchos::ArrayView<Scalar1> vals, size_t l,
754  size_t ld, Teuchos::ArrayView<Scalar2> s)
755  {
756  size_t vals_size = vals.size();
757 #ifdef HAVE_AMESOS2_DEBUG
758  size_t s_size = s.size();
759  TEUCHOS_TEST_FOR_EXCEPTION( s_size < l,
760  std::invalid_argument,
761  "Scale vector must have length at least that of the vector" );
762 #endif
763  size_t i, s_i;
764  for( i = 0, s_i = 0; i < vals_size; ++i, ++s_i ){
765  if( s_i == l ){
766  // bring i to the next multiple of ld
767  i += ld - s_i;
768  s_i = 0;
769  }
770  vals[i] *= s[s_i];
771  }
772  }
773 
774  template <typename Scalar1, typename Scalar2, class BinaryOp>
775  void
776  scale(Teuchos::ArrayView<Scalar1> vals, size_t l,
777  size_t ld, Teuchos::ArrayView<Scalar2> s,
778  BinaryOp binary_op)
779  {
780  size_t vals_size = vals.size();
781 #ifdef HAVE_AMESOS2_DEBUG
782  size_t s_size = s.size();
783  TEUCHOS_TEST_FOR_EXCEPTION( s_size < l,
784  std::invalid_argument,
785  "Scale vector must have length at least that of the vector" );
786 #endif
787  size_t i, s_i;
788  for( i = 0, s_i = 0; i < vals_size; ++i, ++s_i ){
789  if( s_i == l ){
790  // bring i to the next multiple of ld
791  i += ld - s_i;
792  s_i = 0;
793  }
794  vals[i] = binary_op(vals[i], s[s_i]);
795  }
796  }
797 
800  } // end namespace Util
801 
802 } // end namespace Amesos2
803 
804 #endif // #ifndef AMESOS2_UTIL_HPP
void scale(ArrayView< Scalar1 > vals, size_t l, size_t ld, ArrayView< Scalar2 > s)
Scales a 1-D representation of a multivector.
static void do_get(const Teuchos::Ptr< const Matrix > mat, const ArrayView< S > nzvals, const ArrayView< GO > indices, const ArrayView< GS > pointers, GS &nnz, const Teuchos::Ptr< const Tpetra::Map< typename Matrix::local_ordinal_t, typename Matrix::global_ordinal_t, typename Matrix::node_t > > map, EStorage_Ordering ordering=ARBITRARY)
Definition: Amesos2_Util.hpp:442
const Teuchos::RCP< const Tpetra::Map< LO, GO, Node > > getDistributionMap(EDistribution distribution, GS num_global_elements, const Teuchos::RCP< const Teuchos::Comm< int > > &comm, GO indexBase=0)
Gets a Tpetra::Map described by the EDistribution.
Definition: Amesos2_Util.hpp:598
Similar to get_ccs_helper , but used to get a CRS representation of the given matrix.
Definition: Amesos2_Util.hpp:586
Provides some simple meta-programming utilities for Amesos2.
A generic base class for the CRS and CCS helpers.
Definition: Amesos2_Util.hpp:399
Definition: Amesos2_TypeDecl.hpp:142
EStorage_Ordering
Definition: Amesos2_TypeDecl.hpp:140
Definition: Amesos2_TypeDecl.hpp:125
void transpose(ArrayView< Scalar > vals, ArrayView< GlobalOrdinal > indices, ArrayView< GlobalSizeT > ptr, ArrayView< Scalar > trans_vals, ArrayView< GlobalOrdinal > trans_indices, ArrayView< GlobalSizeT > trans_ptr)
const RCP< const Teuchos::Comm< int > > to_teuchos_comm(RCP< const Epetra_Comm > c)
Transform an Epetra_Comm object into a Teuchos::Comm object.
Definition: Amesos2_AbstractConcreteMatrixAdapter.hpp:48
void printLine(Teuchos::FancyOStream &out)
Prints a line of 70 "-"s on std::cout.
Definition: Amesos2_Util.cpp:119
A generic helper class for getting a CCS representation of a Matrix.
Definition: Amesos2_Util.hpp:575
Definition: Amesos2_TypeDecl.hpp:126
static void do_get(const Teuchos::Ptr< const Matrix > mat, const ArrayView< S > nzvals, const ArrayView< GO > indices, const ArrayView< GS > pointers, GS &nnz, EStorage_Ordering ordering=ARBITRARY)
Definition: Amesos2_Util.hpp:425
const RCP< const Epetra_Comm > to_epetra_comm(RCP< const Teuchos::Comm< int > > c)
Transfrom a Teuchos::Comm object into an Epetra_Comm object.
Teuchos::RCP< Epetra_Map > tpetra_map_to_epetra_map(const Tpetra::Map< LO, GO, Node > &map)
Transform a Tpetra::Map object into an Epetra_Map.
Definition: Amesos2_Util.hpp:653
Definition: Amesos2_TypeDecl.hpp:124
Enum and other types declarations for Amesos2.
Teuchos::RCP< Tpetra::Map< LO, GO, Node > > epetra_map_to_tpetra_map(const Epetra_BlockMap &map)
Transform an Epetra_Map object into a Tpetra::Map.
Definition: Amesos2_Util.hpp:634
Definition: Amesos2_TypeDecl.hpp:127
EDistribution
Definition: Amesos2_TypeDecl.hpp:123