|
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 S1, class S2, class LO, class GO, class Node, class Glob> 00200 typename Glob::RedOP::result_type 00201 reduce( const Vector<S1,LO,GO,Node> &vec_in1, const Vector<S2,LO,GO,Node> &vec_in2, Glob glob) 00202 { 00203 #ifdef HAVE_TPETRA_DEBUG 00204 TEUCHOS_TEST_FOR_EXCEPTION( vec_in1.getLocalLength() != vec_in2.getLocalLength(), std::runtime_error, 00205 "Tpetra::RTI::reduce(vec_in1,vec_in2): vec_in1 and vec_in2 must have the same local length."); 00206 #endif 00207 Tpetra::RTI::detail::RTIReductionAdapter<Glob,S1,S2> adapter_op(glob); 00208 return Tpetra::RTI::detail::reduce(vec_in1, vec_in2, adapter_op); 00209 } 00210 00212 00218 template <class S1, class S2, class S3, class LO, class GO, class Node, class Glob> 00219 typename Glob::RedOP::result_type 00220 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) 00221 { 00222 #ifdef HAVE_TPETRA_DEBUG 00223 TEUCHOS_TEST_FOR_EXCEPTION( vec_in1.getLocalLength() != vec_in2.getLocalLength() || vec_in2.getLocalLength() != vec_in3.getLocalLength(), 00224 std::runtime_error, "Tpetra::RTI::reduce(vec_in1,vec_in2): vec_in1 and vec_in2 must have the same local length."); 00225 #endif 00226 Tpetra::RTI::detail::RTIReductionAdapter3<Glob,S1,S2,S3> adapter_op(glob); 00227 return Tpetra::RTI::detail::reduce(vec_in1, vec_in2, vec_in3, adapter_op); 00228 } 00229 00231 00237 template <class S1, class S2, class LO, class GO, class Node,class Glob> 00238 typename Glob::RedOP::result_type 00239 binary_pre_transform_reduce(Vector<S1,LO,GO,Node> &vec_inout, const Vector<S2,LO,GO,Node> &vec_in2, Glob glob) 00240 { 00241 #ifdef HAVE_TPETRA_DEBUG 00242 TEUCHOS_TEST_FOR_EXCEPTION( vec_inout.getLocalLength() != vec_in2.getLocalLength(), std::runtime_error, 00243 "Tpetra::RTI::binary_pre_transform_reduce(vec_in1,vec_in2): vec_in1 and vec_in2 must have the same local length."); 00244 #endif 00245 Tpetra::RTI::detail::RTIPreTransformReductionAdapter<Glob,S1,S2> adapter_op(glob); 00246 return Tpetra::RTI::detail::transform_reduce(vec_inout, vec_in2, adapter_op); 00247 } 00248 00250 00257 template <class S1, class S2, class S3, class LO, class GO, class Node,class Glob> 00258 typename Glob::RedOP::result_type 00259 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) 00260 { 00261 #ifdef HAVE_TPETRA_DEBUG 00262 TEUCHOS_TEST_FOR_EXCEPTION( vec_inout.getLocalLength() != vec_in2.getLocalLength() && vec_in2.getLocalLength() != vec_in3.getLocalLength(), 00263 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."); 00264 #endif 00265 Tpetra::RTI::detail::RTIPreTransformReductionAdapter3<Glob,S1,S2,S3> adapter_op(glob); 00266 return Tpetra::RTI::detail::transform_reduce(vec_inout, vec_in2, vec_in3, adapter_op); 00267 } 00268 00269 } // end of namespace RTI 00270 00271 } // end of namespace Tpetra 00272 00273 #define TPETRA_UNARY_TRANSFORM(out,expr) \ 00274 Tpetra::RTI::unary_transform( *out, [=](decltype((out)->meanValue()) out) \ 00275 {return expr;}) 00276 00277 #define TPETRA_BINARY_TRANSFORM(out,in,expr) \ 00278 Tpetra::RTI::binary_transform( *out, *in, [=](decltype((out)->meanValue()) out, \ 00279 decltype((in)->meanValue()) in) \ 00280 {return expr;}) 00281 00282 #define TPETRA_TERTIARY_TRANSFORM(out,in2,in3,expr) \ 00283 Tpetra::RTI::tertiary_transform( *out, *in2, *in3, \ 00284 [=](decltype((out)->meanValue()) out, \ 00285 decltype((in2)->meanValue()) in2, \ 00286 decltype((in3)->meanValue()) in3) \ 00287 {return expr;}) 00288 00289 00290 #define TPETRA_REDUCE2(out,in, gexp, id, robj ) \ 00291 Tpetra::RTI::reduce( *out, *in, \ 00292 Tpetra::RTI::reductionGlob<id>( [=]( decltype((out)->meanValue()) out, \ 00293 decltype((in)->meanValue()) in ) \ 00294 { return gexp; }, \ 00295 robj ) ) 00296 00297 #define TPETRA_REDUCE3(out,in2,in3, gexp, id, robj ) \ 00298 Tpetra::RTI::reduce( *out, *in2, *in3, \ 00299 Tpetra::RTI::reductionGlob<id>( [=]( decltype((out)->meanValue()) out, \ 00300 decltype((in2)->meanValue()) in2, \ 00301 decltype((in3)->meanValue()) in3 ) \ 00302 { return gexp; }, \ 00303 robj ) ) 00304 00305 #define TPETRA_BINARY_PRETRANSFORM_REDUCE(out,in, texp, gexp, id, robj ) \ 00306 Tpetra::RTI::binary_pre_transform_reduce( *out, *in, \ 00307 Tpetra::RTI::reductionGlob<id>( [=]( decltype((out)->meanValue()) out, \ 00308 decltype((in)->meanValue()) in ) \ 00309 { return texp; }, \ 00310 [=]( decltype((out)->meanValue()) out, \ 00311 decltype((in)->meanValue()) in ) \ 00312 { return gexp; }, \ 00313 robj ) ) 00314 00315 #define TPETRA_TERTIARY_PRETRANSFORM_REDUCE(out,in2,in3, texp, gexp, id, robj ) \ 00316 Tpetra::RTI::tertiary_pre_transform_reduce( *out, *in2, *in3, \ 00317 Tpetra::RTI::reductionGlob<id>( [=]( decltype((out)->meanValue()) out, \ 00318 decltype((in2)->meanValue()) in2, \ 00319 decltype((in3)->meanValue()) in3 ) \ 00320 { return texp; }, \ 00321 [=]( decltype((out)->meanValue()) out, \ 00322 decltype((in2)->meanValue()) in2, \ 00323 decltype((in3)->meanValue()) in3 ) \ 00324 { return gexp; }, \ 00325 robj ) ) 00326 00327 00328 #endif // TPETRA_RTI_HPP
1.7.4