|
Tpetra Matrix/Vector Services
Version of the Day
|
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
1.7.6.1