Tpetra Matrix/Vector Services Version of the Day
Tpetra_RTI_detail.hpp
00001 // @HEADER
00002 // ***********************************************************************
00003 //
00004 //          Tpetra: Templated Linear Algebra Services Package
00005 //                 Copyright (2008) Sandia Corporation
00006 //
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00008 // the U.S. Government retains certain rights in this software.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00038 //
00039 // ************************************************************************
00040 // @HEADER
00041 
00042 #ifndef TPETRA_RTI_detail_HPP
00043 #define TPETRA_RTI_detail_HPP
00044 
00045 #include <Teuchos_Assert.hpp>
00046 #include <Teuchos_CommHelpers.hpp>
00047 #include <Kokkos_NodeHelpers.hpp>
00048 
00049 #include "Tpetra_Vector.hpp"
00050 
00051 namespace Tpetra {
00052 
00053   namespace RTI {
00054 
00056     namespace detail {
00057 
00059       template <class S>
00060       class StdOpKernel
00061       {
00062         protected:
00063           S _alpha, _beta;
00064           S       * _vec_inout;
00065           const S * _vec_in2;
00066         public:
00067           inline StdOpKernel() : _alpha(ScalarTraits<S>::one()), _beta(ScalarTraits<S>::zero()) {}
00068           inline void setData(S * vec_inout, const S * vec_in2)   { _vec_inout = vec_inout; _vec_in2 = vec_in2; }
00069           inline void setAlphaBeta(const S &alpha, const S &beta) { _alpha = alpha; _beta = beta; }
00070       };
00071 
00073       template <class OP, class S>
00074       class UnaryFunctorAdapter {
00075       protected:
00076         OP   _op;
00077         S  * _vec;
00078       public:
00079         UnaryFunctorAdapter(OP op) : _op(op) {}
00080         inline void setData (S *vec) {
00081           _vec = vec;
00082         }
00083         inline void execute (const int i) const {
00084           _vec[i] = _op (_vec[i]);
00085         }
00086       };
00087 
00089       template <class OP, class S1, class S2>
00090       class BinaryFunctorAdapter {
00091       protected:
00092         OP         _op;
00093         S1       * _vec_inout;
00094         const S2 * _vec_in2;
00095       public:
00096         BinaryFunctorAdapter (OP op) : _op(op) {}
00097         inline void setData (S1 *vec_inout, const S2 *vec_in2) {
00098           _vec_inout = vec_inout;
00099           _vec_in2 = vec_in2;
00100         }
00101         inline void execute (const int i) const {
00102           _vec_inout[i] = _op (_vec_inout[i], _vec_in2[i]);
00103         }
00104       };
00105 
00107       template <class OP, class S>
00108       class BinaryFunctorAdapterWithAlphaBeta : public StdOpKernel<S> {
00109       protected:
00110         OP        _op;
00111         S       * _vec_inout;
00112         const S * _vec_in2;
00113       public:
00114         BinaryFunctorAdapterWithAlphaBeta (OP op) : _op(op) {}
00115         inline void setData (S *vec_inout, const S *vec_in2) {
00116           _vec_inout = vec_inout;
00117           _vec_in2 = vec_in2;
00118         }
00119         inline void execute (const int i) const {
00120           S res = _op (_vec_inout[i], _vec_in2[i]);
00121           _vec_inout[i] = this->_alpha * res + this->_beta * _vec_inout[i];
00122         }
00123       };
00124 
00126       template <class OP, class S1, class S2, class S3>
00127       class TertiaryFunctorAdapter {
00128       protected:
00129         OP         _op;
00130         S1       * _vec_inout;
00131         const S2 * _vec_in2;
00132         const S3 * _vec_in3;
00133       public:
00134         TertiaryFunctorAdapter (OP op) : _op(op) {}
00135         inline void setData (S1 *vec_inout, const S2 *vec_in2, const S3 *vec_in3) {
00136           _vec_inout = vec_inout;
00137           _vec_in2 = vec_in2;
00138           _vec_in3 = vec_in3;
00139         }
00140         inline void execute (const int i) const {
00141           _vec_inout[i] = _op (_vec_inout[i], _vec_in2[i], _vec_in3[i]);
00142         }
00143       };
00144 
00146       template <class Glob, class S>
00147       class RTIReductionAdapter1 {
00148       public:
00149         typedef typename Glob::GenOP                GenOP;
00150         typedef typename Glob::RedOP                RedOP;
00151         typedef typename Glob::IdOP                  IdOP;
00152         typedef typename RedOP::result_type ReductionType;
00153       protected:
00154         GenOP      _genop;
00155         RedOP      _redop;
00156         const S * _vec_in;
00157       public:
00158         RTIReductionAdapter1 (Glob glob) :
00159           _genop (glob.genop), _redop (glob.redop)
00160         {}
00161         inline void setData (const S *vec_in) {
00162           _vec_in = vec_in;
00163         }
00164         inline ReductionType identity () const {
00165           return IdOP::identity ();
00166         }
00167         inline ReductionType generate (const int i) const {
00168           return _genop (_vec_in[i]);
00169         }
00170         inline ReductionType reduce (ReductionType a, ReductionType b) const {
00171           return _redop(a, b);
00172         }
00173       };
00174 
00176       template <class Glob, class S1, class S2>
00177       class RTIReductionAdapter2 {
00178       public:
00179         typedef typename Glob::GenOP                GenOP;
00180         typedef typename Glob::RedOP                RedOP;
00181         typedef typename Glob::IdOP                  IdOP;
00182         typedef typename RedOP::result_type ReductionType;
00183       protected:
00184         GenOP      _genop;
00185         RedOP      _redop;
00186         const S1 * _vec_in1;
00187         const S2 * _vec_in2;
00188       public:
00189         RTIReductionAdapter2 (Glob glob) :
00190           _genop (glob.genop), _redop (glob.redop)
00191         {}
00192         inline void setData (const S1 *vec_in1, const S2 *vec_in2) {
00193           _vec_in1 = vec_in1; _vec_in2 = vec_in2;
00194         }
00195         inline ReductionType identity () const {
00196           return IdOP::identity ();
00197         }
00198         inline ReductionType generate (const int i) const {
00199           return _genop (_vec_in1[i], _vec_in2[i]);
00200         }
00201         inline ReductionType reduce (ReductionType a, ReductionType b) const {
00202           return _redop (a, b);
00203         }
00204       };
00205 
00207       template <class Glob, class S1, class S2, class S3>
00208       class RTIReductionAdapter3 {
00209       public:
00210         typedef typename Glob::GenOP                GenOP;
00211         typedef typename Glob::RedOP                RedOP;
00212         typedef typename Glob::IdOP                  IdOP;
00213         typedef typename RedOP::result_type ReductionType;
00214       protected:
00215         GenOP      _genop;
00216         RedOP      _redop;
00217         const S1 * _vec_in1;
00218         const S2 * _vec_in2;
00219         const S3 * _vec_in3;
00220       public:
00221         RTIReductionAdapter3 (Glob glob) :
00222           _genop (glob.genop), _redop (glob.redop)
00223         {}
00224         inline void setData (const S1 *vec_in1, const S2 *vec_in2, const S3 *vec_in3) {
00225           _vec_in1 = vec_in1; _vec_in2 = vec_in2; _vec_in3 = vec_in3;
00226         }
00227         inline ReductionType identity () const {
00228           return IdOP::identity ();
00229         }
00230         inline ReductionType generate (const int i) const {
00231           return _genop (_vec_in1[i], _vec_in2[i], _vec_in3[i]);
00232         }
00233         inline ReductionType reduce (ReductionType a, ReductionType b) const {
00234           return _redop (a, b);
00235         }
00236       };
00237 
00239       template <class Glob, class S1, class S2>
00240       class RTIPreTransformReductionAdapter {
00241       public:
00242         typedef typename Glob::TOP                    TOP;
00243         typedef typename Glob::GenOP                GenOP;
00244         typedef typename Glob::RedOP                RedOP;
00245         typedef typename Glob::IdOP                  IdOP;
00246         typedef typename RedOP::result_type ReductionType;
00247       protected:
00248         TOP        _top;
00249         GenOP      _genop;
00250         RedOP      _redop;
00251         S1       * _vec_inout;
00252         const S2 * _vec_in2;
00253       public:
00254         RTIPreTransformReductionAdapter (Glob glob) :
00255           _top (glob.top), _genop (glob.genop), _redop (glob.redop)
00256         {}
00257         inline void setData (S1 *vec_inout, const S2 *vec_in2) {
00258           _vec_inout = vec_inout;
00259           _vec_in2 = vec_in2;
00260         }
00261         inline ReductionType identity () const {
00262           return IdOP::identity ();
00263         }
00264         inline ReductionType reduce (ReductionType a, ReductionType b) const {
00265           return _redop (a, b);
00266         }
00267         inline ReductionType generate (const int i) const {
00268           _vec_inout[i] = _top (_vec_inout[i], _vec_in2[i]);
00269           return _genop (_vec_inout[i], _vec_in2[i]);
00270         }
00271       };
00272 
00274       template <class Glob, class S1, class S2, class S3>
00275       class RTIPreTransformReductionAdapter3 {
00276       public:
00277         typedef typename Glob::TOP                    TOP;
00278         typedef typename Glob::GenOP                GenOP;
00279         typedef typename Glob::RedOP                RedOP;
00280         typedef typename Glob::IdOP                  IdOP;
00281         typedef typename RedOP::result_type ReductionType;
00282       protected:
00283         TOP        _top;
00284         GenOP      _genop;
00285         RedOP      _redop;
00286         S1       * _vec_inout;
00287         const S2 * _vec_in2;
00288         const S3 * _vec_in3;
00289       public:
00290         RTIPreTransformReductionAdapter3 (Glob glob) :
00291           _top (glob.top), _genop (glob.genop), _redop (glob.redop)
00292         {}
00293         inline void setData (S1 *vec_inout, const S2 *vec_in2, const S3 *vec_in3) {
00294           _vec_inout = vec_inout;
00295           _vec_in2 = vec_in2;
00296           _vec_in3 = vec_in3;
00297         }
00298         inline ReductionType identity () const {
00299           return IdOP::identity ();
00300         }
00301         inline ReductionType reduce (ReductionType a, ReductionType b) const {
00302           return _redop (a, b);
00303         }
00304         inline ReductionType generate (const int i) const {
00305           _vec_inout[i] = _top (_vec_inout[i], _vec_in2[i], _vec_in3[i]);
00306           return _genop (_vec_inout[i], _vec_in2[i], _vec_in3[i]);
00307         }
00308       };
00309 
00311       template <class OP>
00312       class TeuchosValueTypeReductionOpAdapter :
00313         public Teuchos::ValueTypeReductionOp<int,typename OP::ReductionType> {
00314       protected:
00315         mutable OP _op;
00316       public:
00317         typedef typename OP::ReductionType Packet;
00318         TeuchosValueTypeReductionOpAdapter (OP op) : _op(op) {}
00319         void reduce (const int count, const Packet inBuffer[], Packet inoutBuffer []) const
00320         {
00321           for (int i = 0; i != count; ++i) {
00322             inoutBuffer[i] = _op.reduce (inoutBuffer[i], inBuffer[i]);
00323           }
00324         }
00325       };
00326 
00328       template <class S, class LO, class GO, class Node, class OP>
00329       void unary_transform (Vector<S,LO,GO,Node> &vec, OP op)
00330       {
00331         KokkosClassic::MultiVector<S,Node> mv = vec.getLocalMV ();
00332         const RCP<Node> node = mv.getNode();
00333         // ready data
00334         KokkosClassic::ReadyBufferHelper<Node> rbh(node);
00335         rbh.begin();
00336         S * out_ptr = rbh.addNonConstBuffer(mv.getValuesNonConst());
00337         rbh.end();
00338         op.setData(out_ptr);
00339         const size_t N = mv.getNumRows();
00340         node->template parallel_for (0, N, op);
00341       }
00342 
00344       template <class S1, class S2, class LO, class GO, class Node, class OP>
00345       void binary_transform (Vector<S1,LO,GO,Node> &vec_inout, const Vector<S2,LO,GO,Node> &vec_in2, OP op)
00346       {
00347         KokkosClassic::MultiVector<S1,Node> mv_inout = vec_inout.getLocalMV ();
00348         KokkosClassic::MultiVector<S2,Node> mv_in2 = vec_in2.getLocalMV ();
00349         const RCP<Node> node = mv_inout.getNode();
00350         // ready data
00351         KokkosClassic::ReadyBufferHelper<Node> rbh(node);
00352         rbh.begin();
00353         S1       * out_ptr = rbh.addNonConstBuffer(mv_inout.getValuesNonConst());
00354         const S2 * in_ptr  = rbh.addConstBuffer(mv_in2.getValues());
00355         rbh.end();
00356         op.setData(out_ptr, in_ptr);
00357         const size_t N = mv_inout.getNumRows();
00358 #ifdef HAVE_TPETRA_DEBUG
00359         TEUCHOS_TEST_FOR_EXCEPTION( mv_in2.getNode() != mv_inout.getNode(), std::runtime_error,
00360             "Tpetra::RTI::detail::binary_transform(): multivectors must share the same node.");
00361 #endif
00362         node->template parallel_for(0, N, op);
00363       }
00364 
00366       template <class S1, class S2, class S3, class LO, class GO, class Node, class OP>
00367       void tertiary_transform(Vector<S1,LO,GO,Node> &vec_inout, const Vector<S2,LO,GO,Node> &vec_in2, const Vector<S3,LO,GO,Node> &vec_in3, OP op)
00368       {
00369         KokkosClassic::MultiVector<S1,Node> mv_inout = vec_inout.getLocalMV ();
00370         KokkosClassic::MultiVector<S2,Node> mv_in2   = vec_in2.getLocalMV ();
00371         KokkosClassic::MultiVector<S3,Node> mv_in3   = vec_in3.getLocalMV ();
00372         const RCP<Node> node = mv_inout.getNode();
00373         // ready data
00374         KokkosClassic::ReadyBufferHelper<Node> rbh(node);
00375         rbh.begin();
00376         S1       * out_ptr = rbh.addNonConstBuffer(mv_inout.getValuesNonConst());
00377         const S2 * in_ptr2 = rbh.addConstBuffer(mv_in2.getValues());
00378         const S3 * in_ptr3 = rbh.addConstBuffer(mv_in3.getValues());
00379         rbh.end();
00380         op.setData(out_ptr, in_ptr2, in_ptr3);
00381         const size_t N = mv_inout.getNumRows();
00382 #ifdef HAVE_TPETRA_DEBUG
00383         TEUCHOS_TEST_FOR_EXCEPTION( mv_in2.getNode() != mv_inout.getNode() || mv_in3.getNode() != mv_in2.getNode(), std::runtime_error,
00384             "Tpetra::RTI::detail::tertiary_transform(): multivectors must share the same node.");
00385 #endif
00386         node->template parallel_for(0, N, op);
00387       }
00388 
00390       template <class S, class LO, class GO, class Node, class OP>
00391       typename OP::ReductionType
00392       reduce(const Vector<S,LO,GO,Node> &vec_in, OP op)
00393       {
00394         const KokkosClassic::MultiVector<S,Node> &mv_in = vec_in.getLocalMV();
00395         const RCP<Node> node = mv_in.getNode();
00396         const RCP<const Teuchos::Comm<int> > comm = vec_in.getMap()->getComm();
00397         // ready data
00398         KokkosClassic::ReadyBufferHelper<Node> rbh(node);
00399         rbh.begin();
00400         const S * in_ptr = rbh.addConstBuffer(mv_in.getValues());
00401         rbh.end();
00402         op.setData( in_ptr );
00403         const size_t N = mv_in.getNumRows();
00404         // compute local reduction
00405         typename OP::ReductionType gbl_res, lcl_res;
00406         lcl_res = node->template parallel_reduce(0, N, op);
00407         // compute global reduction
00408         TeuchosValueTypeReductionOpAdapter<OP> vtrop(op);
00409         Teuchos::reduceAll(*comm, vtrop, 1, &lcl_res, &gbl_res);
00410         return gbl_res;
00411       }
00412 
00414       template <class S1, class S2, class LO, class GO, class Node, class OP>
00415       typename OP::ReductionType
00416       reduce(const Vector<S1,LO,GO,Node> &vec_in1, const Vector<S2,LO,GO,Node> &vec_in2, OP op)
00417       {
00418         const KokkosClassic::MultiVector<S1,Node> &mv_in1 = vec_in1.getLocalMV(),
00419                                            &mv_in2 = vec_in2.getLocalMV();
00420         const RCP<Node> node = mv_in1.getNode();
00421         const RCP<const Teuchos::Comm<int> > comm = vec_in1.getMap()->getComm();
00422         // ready data
00423         KokkosClassic::ReadyBufferHelper<Node> rbh(node);
00424         rbh.begin();
00425         const S1 * in_ptr1 = rbh.addConstBuffer(mv_in1.getValues());
00426         const S2 * in_ptr2 = rbh.addConstBuffer(mv_in2.getValues());
00427         rbh.end();
00428         op.setData( in_ptr1, in_ptr2 );
00429         const size_t N = mv_in1.getNumRows();
00430 #ifdef HAVE_TPETRA_DEBUG
00431         TEUCHOS_TEST_FOR_EXCEPTION( mv_in1.getNode() != mv_in2.getNode(), std::runtime_error,
00432             "Tpetra::RTI::detail::reduce(): multivectors must share the same node.");
00433 #endif
00434         // compute local reduction
00435         typename OP::ReductionType gbl_res, lcl_res;
00436         lcl_res = node->template parallel_reduce(0, N, op);
00437         // compute global reduction
00438         TeuchosValueTypeReductionOpAdapter<OP> vtrop(op);
00439         Teuchos::reduceAll(*comm, vtrop, 1, &lcl_res, &gbl_res);
00440         return gbl_res;
00441       }
00442 
00444       template <class S1, class S2, class S3, class LO, class GO, class Node, class OP>
00445       typename OP::ReductionType
00446       reduce(const Vector<S1,LO,GO,Node> &vec_in1, const Vector<S2,LO,GO,Node> &vec_in2, const Vector<S3,LO,GO,Node> &vec_in3, OP op)
00447       {
00448         const KokkosClassic::MultiVector<S1,Node> &mv_in1 = vec_in1.getLocalMV();
00449         const KokkosClassic::MultiVector<S2,Node> &mv_in2 = vec_in2.getLocalMV();
00450         const KokkosClassic::MultiVector<S3,Node> &mv_in3 = vec_in3.getLocalMV();
00451         const RCP<Node> node = mv_in1.getNode();
00452         const RCP<const Teuchos::Comm<int> > comm = vec_in1.getMap()->getComm();
00453         // ready data
00454         KokkosClassic::ReadyBufferHelper<Node> rbh(node);
00455         rbh.begin();
00456         const S1 * in_ptr1 = rbh.addConstBuffer(mv_in1.getValues());
00457         const S2 * in_ptr2 = rbh.addConstBuffer(mv_in2.getValues());
00458         const S3 * in_ptr3 = rbh.addConstBuffer(mv_in3.getValues());
00459         rbh.end();
00460         op.setData( in_ptr1, in_ptr2, in_ptr3 );
00461         const size_t N = mv_in1.getNumRows();
00462 #ifdef HAVE_TPETRA_DEBUG
00463         TEUCHOS_TEST_FOR_EXCEPTION( mv_in1.getNode() != mv_in2.getNode() || mv_in2.getNode() != mv_in3.getNode(), std::runtime_error,
00464             "Tpetra::RTI::detail::reduce(): multivectors must share the same node.");
00465 #endif
00466         // compute local reduction
00467         typename OP::ReductionType gbl_res, lcl_res;
00468         lcl_res = node->template parallel_reduce(0, N, op);
00469         // compute global reduction
00470         TeuchosValueTypeReductionOpAdapter<OP> vtrop(op);
00471         Teuchos::reduceAll(*comm, vtrop, 1, &lcl_res, &gbl_res);
00472         return gbl_res;
00473       }
00474 
00476       template <class S1, class S2, class LO, class GO, class Node, class OP>
00477       typename OP::ReductionType
00478       transform_reduce(Vector<S1,LO,GO,Node> &vec_inout, const Vector<S2,LO,GO,Node> &vec_in2, OP op)
00479       {
00480         KokkosClassic::MultiVector<S1,Node> mv_inout = vec_inout.getLocalMV ();
00481         KokkosClassic::MultiVector<S2,Node> mv_in2 = vec_in2.getLocalMV ();
00482         const RCP<Node> node = mv_inout.getNode();
00483         const RCP<const Teuchos::Comm<int> > comm = vec_inout.getMap()->getComm();
00484         // ready data
00485         KokkosClassic::ReadyBufferHelper<Node> rbh(node);
00486         rbh.begin();
00487         S1 * in_ptr1 = rbh.addNonConstBuffer(mv_inout.getValuesNonConst());
00488         const S2 * in_ptr2 = rbh.addConstBuffer(mv_in2.getValues());
00489         rbh.end();
00490         op.setData( in_ptr1, in_ptr2 );
00491         const size_t N = mv_inout.getNumRows();
00492 #ifdef HAVE_TPETRA_DEBUG
00493         TEUCHOS_TEST_FOR_EXCEPTION( mv_inout.getNode() != mv_in2.getNode(), std::runtime_error,
00494             "Tpetra::RTI::detail::transform_reduce(): multivectors must share the same node.");
00495 #endif
00496         // compute local reduction
00497         typename OP::ReductionType gbl_res, lcl_res;
00498         lcl_res = node->template parallel_reduce(0, N, op);
00499         // compute global reduction
00500         TeuchosValueTypeReductionOpAdapter<OP> vtrop(op);
00501         Teuchos::reduceAll(*comm, vtrop, 1, &lcl_res, &gbl_res);
00502         return gbl_res;
00503       }
00504 
00506       template <class S1, class S2, class S3, class LO, class GO, class Node, class OP>
00507       typename OP::ReductionType
00508       transform_reduce(Vector<S1,LO,GO,Node> &vec_inout, const Vector<S2,LO,GO,Node> &vec_in2, const Vector<S3,LO,GO,Node> &vec_in3, OP op)
00509       {
00510         KokkosClassic::MultiVector<S1,Node> mv_inout = vec_inout.getLocalMV ();
00511         KokkosClassic::MultiVector<S2,Node> mv_in2   = vec_in2.getLocalMV ();
00512         KokkosClassic::MultiVector<S3,Node> mv_in3   = vec_in3.getLocalMV ();
00513         const RCP<Node> node = mv_inout.getNode();
00514         const RCP<const Teuchos::Comm<int> > comm = vec_inout.getMap()->getComm();
00515         // ready data
00516         KokkosClassic::ReadyBufferHelper<Node> rbh(node);
00517         rbh.begin();
00518         S1 * in_ptr1 = rbh.addNonConstBuffer(mv_inout.getValuesNonConst());
00519         const S2 * in_ptr2 = rbh.addConstBuffer(mv_in2.getValues());
00520         const S3 * in_ptr3 = rbh.addConstBuffer(mv_in3.getValues());
00521         rbh.end();
00522         op.setData( in_ptr1, in_ptr2, in_ptr3 );
00523         const size_t N = mv_inout.getNumRows();
00524 #ifdef HAVE_TPETRA_DEBUG
00525         TEUCHOS_TEST_FOR_EXCEPTION( mv_inout.getNode() != mv_in2.getNode() && mv_inout.getNode() != mv_in3.getNode(), std::runtime_error,
00526             "Tpetra::RTI::detail::transform_transform(): multivectors must share the same node.");
00527 #endif
00528         // compute local reduction
00529         typename OP::ReductionType gbl_res, lcl_res;
00530         lcl_res = node->template parallel_reduce(0, N, op);
00531         // compute global reduction
00532         TeuchosValueTypeReductionOpAdapter<OP> vtrop(op);
00533         Teuchos::reduceAll(*comm, vtrop, 1, &lcl_res, &gbl_res);
00534         return gbl_res;
00535       }
00536 
00537     } // end of namespace Tpetra::RTI::detail
00538 
00539   } // end of namespace Tpetra::RTI
00540 
00541 } // end of namespace Tpetra
00542 
00543 #endif // TPETRA_RTI_detail_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines