|
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_HPP 00043 #define TPETRA_RTI_HPP 00044 00045 #include <Teuchos_Tuple.hpp> 00046 #include <Teuchos_Assert.hpp> 00047 00048 #include "Tpetra_ConfigDefs.hpp" 00049 00050 #include "Tpetra_Operator.hpp" 00051 #include "Tpetra_Import.hpp" 00052 #include "Tpetra_Export.hpp" 00053 #include "Tpetra_Vector.hpp" 00054 #include "Tpetra_RTI_detail.hpp" 00055 00056 namespace Tpetra { 00057 00058 namespace RTI { 00059 00066 template <class T> 00067 class ZeroOp { 00068 public: 00069 static inline T identity() {return Teuchos::ScalarTraits<T>::zero();} 00070 }; 00071 00078 template <class T> 00079 class OneOp { 00080 public: 00081 static inline T identity() {return Teuchos::ScalarTraits<T>::one();} 00082 }; 00083 00110 template <class GOP, class ROP, class IOP> 00111 class ReductionGlob { 00112 public: 00113 typedef GOP GenOP; 00114 typedef ROP RedOP; 00115 typedef IOP IdOP; 00116 GenOP genop; 00117 RedOP redop; 00118 ReductionGlob(GenOP gop, RedOP rop) : genop(gop), redop(rop) {} 00119 }; 00120 00122 template <class TxOP, class GOP, class ROP, class IOP> 00123 class TransformReductionGlob { 00124 public: 00125 typedef TxOP TOP; 00126 typedef GOP GenOP; 00127 typedef ROP RedOP; 00128 typedef IOP IdOP; 00129 TOP top; 00130 GenOP genop; 00131 RedOP redop; 00132 TransformReductionGlob(TOP txop, GenOP gop, RedOP rop) : top(txop), genop(gop), redop(rop) {} 00133 }; 00134 00136 template <class IOP, class GOP, class ROP> 00137 inline ReductionGlob<GOP,ROP,IOP> reductionGlob(GOP gop, ROP rop) 00138 { 00139 return ReductionGlob<GOP,ROP,IOP>(gop,rop); 00140 } 00141 00143 template <class IOP, class TOP, class GOP, class ROP> 00144 inline TransformReductionGlob<TOP,GOP,ROP,IOP> reductionGlob(TOP top, GOP gop, ROP rop) 00145 { 00146 return TransformReductionGlob<TOP,GOP,ROP,IOP>(top,gop,rop); 00147 } 00148 00150 00154 template <class S, class LO, class GO, class Node, class OP> 00155 void unary_transform(Vector<S,LO,GO,Node> &vec_inout, OP op) 00156 { 00157 Tpetra::RTI::detail::UnaryFunctorAdapter<OP,S> Adapter_op(op); 00158 Tpetra::RTI::detail::unary_transform(vec_inout, Adapter_op); 00159 } 00160 00162 00166 template <class S1, class S2, class LO, class GO, class Node, class OP> 00167 void binary_transform(Vector<S1,LO,GO,Node> &vec_inout, const Vector<S2,LO,GO,Node> &vec_in2, OP op) 00168 { 00169 #ifdef HAVE_TPETRA_DEBUG 00170 TEUCHOS_TEST_FOR_EXCEPTION( vec_inout.getLocalLength() != vec_in2.getLocalLength(), std::runtime_error, 00171 "Tpetra::RTI::binary_transform(vec_inout,vec_in2): vec_in2 and vec_inout must have the same local length."); 00172 #endif 00173 Tpetra::RTI::detail::BinaryFunctorAdapter<OP,S1,S2> adapter_op(op); 00174 Tpetra::RTI::detail::binary_transform(vec_inout, vec_in2, adapter_op); 00175 } 00176 00178 00182 template <class S1, class S2, class S3, class LO, class GO, class Node, class OP> 00183 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) 00184 { 00185 #ifdef HAVE_TPETRA_DEBUG 00186 TEUCHOS_TEST_FOR_EXCEPTION( vec_inout.getLocalLength() != vec_in2.getLocalLength() || vec_in2.getLocalLength() != vec_in3.getLocalLength(), std::runtime_error, 00187 "Tpetra::RTI::tertiary_transform(vec_inout,vec_in2,vec_in3): vec_inout, vec_in2 and vec_in3 must have the same local length."); 00188 #endif 00189 Tpetra::RTI::detail::TertiaryFunctorAdapter<OP,S1,S2,S3> adapter_op(op); 00190 Tpetra::RTI::detail::tertiary_transform(vec_inout, vec_in2, vec_in3, adapter_op); 00191 } 00192 00194 00199 template <class S, class LO, class GO, class Node, class Glob> 00200 typename Glob::RedOP::result_type 00201 reduce( const Vector<S,LO,GO,Node> &vec_in, Glob glob) 00202 { 00203 Tpetra::RTI::detail::RTIReductionAdapter1<Glob,S> adapter_op(glob); 00204 return Tpetra::RTI::detail::reduce(vec_in, adapter_op); 00205 } 00206 00208 00213 template <class S1, class S2, class LO, class GO, class Node, class Glob> 00214 typename Glob::RedOP::result_type 00215 reduce( const Vector<S1,LO,GO,Node> &vec_in1, const Vector<S2,LO,GO,Node> &vec_in2, Glob glob) 00216 { 00217 #ifdef HAVE_TPETRA_DEBUG 00218 TEUCHOS_TEST_FOR_EXCEPTION( vec_in1.getLocalLength() != vec_in2.getLocalLength(), std::runtime_error, 00219 "Tpetra::RTI::reduce(vec_in1,vec_in2): vec_in1 and vec_in2 must have the same local length."); 00220 #endif 00221 Tpetra::RTI::detail::RTIReductionAdapter2<Glob,S1,S2> adapter_op(glob); 00222 return Tpetra::RTI::detail::reduce(vec_in1, vec_in2, adapter_op); 00223 } 00224 00226 00232 template <class S1, class S2, class S3, class LO, class GO, class Node, class Glob> 00233 typename Glob::RedOP::result_type 00234 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, Glob glob) 00235 { 00236 #ifdef HAVE_TPETRA_DEBUG 00237 TEUCHOS_TEST_FOR_EXCEPTION( vec_in1.getLocalLength() != vec_in2.getLocalLength() || vec_in2.getLocalLength() != vec_in3.getLocalLength(), 00238 std::runtime_error, "Tpetra::RTI::reduce(vec_in1,vec_in2): vec_in1 and vec_in2 must have the same local length."); 00239 #endif 00240 Tpetra::RTI::detail::RTIReductionAdapter3<Glob,S1,S2,S3> adapter_op(glob); 00241 return Tpetra::RTI::detail::reduce(vec_in1, vec_in2, vec_in3, adapter_op); 00242 } 00243 00245 00251 template <class S1, class S2, class LO, class GO, class Node,class Glob> 00252 typename Glob::RedOP::result_type 00253 binary_pre_transform_reduce(Vector<S1,LO,GO,Node> &vec_inout, const Vector<S2,LO,GO,Node> &vec_in2, Glob glob) 00254 { 00255 #ifdef HAVE_TPETRA_DEBUG 00256 TEUCHOS_TEST_FOR_EXCEPTION( vec_inout.getLocalLength() != vec_in2.getLocalLength(), std::runtime_error, 00257 "Tpetra::RTI::binary_pre_transform_reduce(vec_in1,vec_in2): vec_in1 and vec_in2 must have the same local length."); 00258 #endif 00259 Tpetra::RTI::detail::RTIPreTransformReductionAdapter<Glob,S1,S2> adapter_op(glob); 00260 return Tpetra::RTI::detail::transform_reduce(vec_inout, vec_in2, adapter_op); 00261 } 00262 00264 00271 template <class S1, class S2, class S3, class LO, class GO, class Node,class Glob> 00272 typename Glob::RedOP::result_type 00273 tertiary_pre_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, Glob glob) 00274 { 00275 #ifdef HAVE_TPETRA_DEBUG 00276 TEUCHOS_TEST_FOR_EXCEPTION( vec_inout.getLocalLength() != vec_in2.getLocalLength() && vec_in2.getLocalLength() != vec_in3.getLocalLength(), 00277 std::runtime_error, "Tpetra::RTI::tertiary_pre_transform_reduce(vec_in1,vec_in2,vec_in3): vec_in1, vec_in2 and vec_in3 must have the same local length."); 00278 #endif 00279 Tpetra::RTI::detail::RTIPreTransformReductionAdapter3<Glob,S1,S2,S3> adapter_op(glob); 00280 return Tpetra::RTI::detail::transform_reduce(vec_inout, vec_in2, vec_in3, adapter_op); 00281 } 00282 00283 } // end of namespace RTI 00284 00285 } // end of namespace Tpetra 00286 00287 #define TPETRA_UNARY_TRANSFORM(out,expr) \ 00288 Tpetra::RTI::unary_transform( *out, [=](decltype((out)->meanValue()) out) \ 00289 {return expr;}) 00290 00291 #define TPETRA_BINARY_TRANSFORM(outVec, inVec, expr) \ 00292 Tpetra::RTI::binary_transform( *outVec, *inVec, [=] (decltype ((outVec)->meanValue ()) outVec, \ 00293 decltype ((inVec)->meanValue ()) inVec) \ 00294 { return expr; }) 00295 00296 #define TPETRA_TERTIARY_TRANSFORM(out,in2,in3,expr) \ 00297 Tpetra::RTI::tertiary_transform( *out, *in2, *in3, \ 00298 [=](decltype((out)->meanValue()) out, \ 00299 decltype((in2)->meanValue()) in2, \ 00300 decltype((in3)->meanValue()) in3) \ 00301 {return expr;}) 00302 00303 00304 #define TPETRA_REDUCE1(in, gexp, id, robj ) \ 00305 Tpetra::RTI::reduce( *in, \ 00306 Tpetra::RTI::reductionGlob<id>( [=]( decltype((in)->meanValue()) in ) \ 00307 { return gexp; }, \ 00308 robj ) ) 00309 00310 #define TPETRA_REDUCE2(in1vec, in2vec, gexp, id, robj ) \ 00311 Tpetra::RTI::reduce (*in1vec, *in2vec, \ 00312 Tpetra::RTI::reductionGlob<id> ([=] (decltype((in1vec)->meanValue ()) in1vec, \ 00313 decltype((in2vec)->meanValue ()) in2vec ) \ 00314 { return gexp; }, \ 00315 robj)) 00316 00317 #define TPETRA_REDUCE3(in1,in2,in3, gexp, id, robj ) \ 00318 Tpetra::RTI::reduce( *in1, *in2, *in3, \ 00319 Tpetra::RTI::reductionGlob<id>( [=]( decltype((in1)->meanValue()) in1, \ 00320 decltype((in2)->meanValue()) in2, \ 00321 decltype((in3)->meanValue()) in3 ) \ 00322 { return gexp; }, \ 00323 robj ) ) 00324 00325 #define TPETRA_BINARY_PRETRANSFORM_REDUCE(out,in, texp, gexp, id, robj ) \ 00326 Tpetra::RTI::binary_pre_transform_reduce( *out, *in, \ 00327 Tpetra::RTI::reductionGlob<id>( [=]( decltype((out)->meanValue()) out, \ 00328 decltype((in)->meanValue()) in ) \ 00329 { return texp; }, \ 00330 [=]( decltype((out)->meanValue()) out, \ 00331 decltype((in)->meanValue()) in ) \ 00332 { return gexp; }, \ 00333 robj ) ) 00334 00335 #define TPETRA_TERTIARY_PRETRANSFORM_REDUCE(out,in2,in3, texp, gexp, id, robj ) \ 00336 Tpetra::RTI::tertiary_pre_transform_reduce( *out, *in2, *in3, \ 00337 Tpetra::RTI::reductionGlob<id>( [=]( decltype((out)->meanValue()) out, \ 00338 decltype((in2)->meanValue()) in2, \ 00339 decltype((in3)->meanValue()) in3 ) \ 00340 { return texp; }, \ 00341 [=]( decltype((out)->meanValue()) out, \ 00342 decltype((in2)->meanValue()) in2, \ 00343 decltype((in3)->meanValue()) in3 ) \ 00344 { return gexp; }, \ 00345 robj ) ) 00346 00347 #endif // TPETRA_RTI_HPP
1.7.6.1