Tpetra Matrix/Vector Services Version of the Day
Tpetra_RTI.hpp
00001 //@HEADER
00002 // ************************************************************************
00003 // 
00004 //               Tpetra: Templated Linear Algebra Services Package 
00005 //                 Copyright (2008) Sandia Corporation
00006 // 
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 // 
00010 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //  
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more detail.
00019 //  
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 
00025 // 
00026 // ************************************************************************
00027 //@HEADER
00028 
00029 #ifndef TPETRA_RTI_HPP
00030 #define TPETRA_RTI_HPP
00031 
00032 #include <Teuchos_Tuple.hpp>
00033 #include <Teuchos_TestForException.hpp>
00034 
00035 #include "Tpetra_ConfigDefs.hpp"
00036 
00037 #include "Tpetra_Operator.hpp"
00038 #include "Tpetra_Import.hpp"
00039 #include "Tpetra_Export.hpp"
00040 #include "Tpetra_Vector.hpp"
00041 #include "Tpetra_RTI_detail.hpp"
00042 
00043 namespace Tpetra {
00044 
00045   namespace RTI {
00046     
00048     template <class T>
00049     class ZeroOp {
00050       public:
00051       static inline T identity() {return Teuchos::ScalarTraits<T>::zero();}
00052     };
00053 
00055     template <class T>
00056     class OneOp {
00057       public:
00058       static inline T identity() {return Teuchos::ScalarTraits<T>::one();}
00059     };
00060 
00062     template <class GOP, class ROP, class IOP> 
00063     class ReductionGlob {
00064       public:
00065         typedef GOP GenOP;
00066         typedef ROP RedOP;
00067         typedef IOP  IdOP;
00068         GenOP genop;
00069         RedOP redop;
00070         ReductionGlob(GenOP gop, RedOP rop) : genop(gop), redop(rop) {}
00071     };
00072 
00074     template <class TxOP, class GOP, class ROP, class IOP> 
00075     class TransformReductionGlob {
00076       public:
00077         typedef TxOP   TOP;
00078         typedef GOP  GenOP;
00079         typedef ROP  RedOP;
00080         typedef IOP   IdOP;
00081         TOP     top;
00082         GenOP genop;
00083         RedOP redop;
00084         TransformReductionGlob(TOP txop, GenOP gop, RedOP rop) : top(txop), genop(gop), redop(rop) {}
00085     };
00086 
00088     template <class IOP, class GOP, class ROP> 
00089     inline ReductionGlob<GOP,ROP,IOP> reductionGlob(GOP gop, ROP rop) 
00090     {
00091       return ReductionGlob<GOP,ROP,IOP>(gop,rop);
00092     }
00093 
00095     template <class IOP, class TOP, class GOP, class ROP> 
00096     inline TransformReductionGlob<TOP,GOP,ROP,IOP> reductionGlob(TOP top, GOP gop, ROP rop) 
00097     {
00098       return TransformReductionGlob<TOP,GOP,ROP,IOP>(top,gop,rop);
00099     }
00100 
00102 
00106     template <class S, class LO, class GO, class Node, class OP>
00107     void unary_transform(Vector<S,LO,GO,Node> &vec_inout, OP op) 
00108     {
00109       Tpetra::RTI::detail::UnaryFunctorAdapter<OP,S> Adapter_op(op);
00110       Tpetra::RTI::detail::unary_transform(vec_inout, Adapter_op);
00111     }
00112 
00114 
00118     template <class S1, class S2, class LO, class GO, class Node, class OP>
00119     void binary_transform(Vector<S1,LO,GO,Node> &vec_inout, const Vector<S2,LO,GO,Node> &vec_in2, OP op) 
00120     {
00121 #ifdef HAVE_TPETRA_DEBUG
00122       TEST_FOR_EXCEPTION( vec_inout.getLocalLength() != vec_in2.getLocalLength(), std::runtime_error,
00123           "Tpetra::RTI::binary_transform(vec_inout,vec_in2): vec_in2 and vec_inout must have the same local length.");
00124 #endif
00125       Tpetra::RTI::detail::BinaryFunctorAdapter<OP,S1,S2> adapter_op(op);
00126       Tpetra::RTI::detail::binary_transform(vec_inout, vec_in2, adapter_op);
00127     }
00128 
00130 
00134     template <class S1, class S2, class S3, class LO, class GO, class Node, class OP>
00135     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) 
00136     {
00137 #ifdef HAVE_TPETRA_DEBUG
00138       TEST_FOR_EXCEPTION( vec_inout.getLocalLength() != vec_in2.getLocalLength() || vec_in2.getLocalLength() != vec_in3.getLocalLength(), std::runtime_error,
00139           "Tpetra::RTI::tertiary_transform(vec_inout,vec_in2,vec_in3): vec_inout, vec_in2 and vec_in3 must have the same local length.");
00140 #endif
00141       Tpetra::RTI::detail::TertiaryFunctorAdapter<OP,S1,S2,S3> adapter_op(op);
00142       Tpetra::RTI::detail::tertiary_transform(vec_inout, vec_in2, vec_in3, adapter_op);
00143     }
00144 
00146 
00151     template <class S1, class S2, class LO, class GO, class Node, class Glob>
00152     typename Glob::RedOP::result_type 
00153     reduce( const Vector<S1,LO,GO,Node> &vec_in1, const Vector<S2,LO,GO,Node> &vec_in2, Glob glob)
00154     {
00155 #ifdef HAVE_TPETRA_DEBUG
00156       TEST_FOR_EXCEPTION( vec_in1.getLocalLength() != vec_in2.getLocalLength(), std::runtime_error,
00157           "Tpetra::RTI::reduce(vec_in1,vec_in2): vec_in1 and vec_in2 must have the same local length.");
00158 #endif
00159       Tpetra::RTI::detail::RTIReductionAdapter<Glob,S1,S2> adapter_op(glob);
00160       return Tpetra::RTI::detail::reduce(vec_in1, vec_in2, adapter_op);
00161     }
00162 
00164 
00170     template <class S1, class S2, class S3, class LO, class GO, class Node, class Glob>
00171     typename Glob::RedOP::result_type 
00172     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)
00173     {
00174 #ifdef HAVE_TPETRA_DEBUG
00175       TEST_FOR_EXCEPTION( vec_in1.getLocalLength() != vec_in2.getLocalLength() || vec_in2.getLocalLength() != vec_in3.getLocalLength(), 
00176           std::runtime_error, "Tpetra::RTI::reduce(vec_in1,vec_in2): vec_in1 and vec_in2 must have the same local length.");
00177 #endif
00178       Tpetra::RTI::detail::RTIReductionAdapter3<Glob,S1,S2,S3> adapter_op(glob);
00179       return Tpetra::RTI::detail::reduce(vec_in1, vec_in2, vec_in3, adapter_op);
00180     }
00181 
00183 
00189     template <class S1, class S2, class LO, class GO, class Node,class Glob>
00190     typename Glob::RedOP::result_type 
00191     binary_pre_transform_reduce(Vector<S1,LO,GO,Node> &vec_inout, const Vector<S2,LO,GO,Node> &vec_in2, Glob glob)
00192     {
00193 #ifdef HAVE_TPETRA_DEBUG
00194       TEST_FOR_EXCEPTION( vec_inout.getLocalLength() != vec_in2.getLocalLength(), std::runtime_error,
00195           "Tpetra::RTI::binary_pre_transform_reduce(vec_in1,vec_in2): vec_in1 and vec_in2 must have the same local length.");
00196 #endif
00197       Tpetra::RTI::detail::RTIPreTransformReductionAdapter<Glob,S1,S2> adapter_op(glob);
00198       return Tpetra::RTI::detail::transform_reduce(vec_inout, vec_in2, adapter_op);
00199     }
00200 
00202 
00209     template <class S1, class S2, class S3, class LO, class GO, class Node,class Glob>
00210     typename Glob::RedOP::result_type 
00211     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)
00212     {
00213 #ifdef HAVE_TPETRA_DEBUG
00214       TEST_FOR_EXCEPTION( vec_inout.getLocalLength() != vec_in2.getLocalLength() && vec_in2.getLocalLength() != vec_in3.getLocalLength(), 
00215           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.");
00216 #endif
00217       Tpetra::RTI::detail::RTIPreTransformReductionAdapter3<Glob,S1,S2,S3> adapter_op(glob);
00218       return Tpetra::RTI::detail::transform_reduce(vec_inout, vec_in2, vec_in3, adapter_op);
00219     }
00220 
00221   } // end of namespace RTI
00222 
00223 } // end of namespace Tpetra
00224 
00225 #define TPETRA_UNARY_TRANSFORM(out,expr) \
00226   Tpetra::RTI::unary_transform( *out, [=](decltype((out)->meanValue()) out) \
00227                                          {return expr;})
00228 
00229 #define TPETRA_BINARY_TRANSFORM(out,in,expr) \
00230   Tpetra::RTI::binary_transform( *out, *in, [=](decltype((out)->meanValue()) out, \
00231                                                     decltype((in)->meanValue()) in) \
00232                                                     {return expr;})
00233 
00234 #define TPETRA_TERTIARY_TRANSFORM(out,in2,in3,expr) \
00235   Tpetra::RTI::tertiary_transform( *out, *in2, *in3, \
00236                                    [=](decltype((out)->meanValue()) out, \
00237                                        decltype((in2)->meanValue()) in2, \
00238                                        decltype((in3)->meanValue()) in3) \
00239                                        {return expr;})
00240 
00241 
00242 #define TPETRA_REDUCE2(out,in, gexp, id, robj ) \
00243   Tpetra::RTI::reduce( *out, *in,                                                \
00244     Tpetra::RTI::reductionGlob<id>( [=]( decltype((out)->meanValue()) out,       \
00245                                          decltype((in)->meanValue()) in )        \
00246                                        { return gexp; },                         \
00247                                        robj ) )
00248 
00249 #define TPETRA_REDUCE3(out,in2,in3, gexp, id, robj ) \
00250   Tpetra::RTI::reduce( *out, *in2, *in3,                  \
00251     Tpetra::RTI::reductionGlob<id>( [=]( decltype((out)->meanValue()) out,       \
00252                                          decltype((in2)->meanValue()) in2,       \
00253                                          decltype((in3)->meanValue()) in3 )      \
00254                                        { return gexp; },                         \
00255                                        robj ) )
00256 
00257 #define TPETRA_BINARY_PRETRANSFORM_REDUCE(out,in,  texp, gexp, id, robj ) \
00258   Tpetra::RTI::binary_pre_transform_reduce( *out, *in,                     \
00259     Tpetra::RTI::reductionGlob<id>( [=]( decltype((out)->meanValue()) out,  \
00260                                          decltype((in)->meanValue()) in )   \
00261                                        { return texp; },                    \
00262                                     [=]( decltype((out)->meanValue()) out,  \
00263                                          decltype((in)->meanValue()) in )   \
00264                                        { return gexp; },                    \
00265                                        robj ) )
00266 
00267 #define TPETRA_TERTIARY_PRETRANSFORM_REDUCE(out,in2,in3, texp, gexp, id, robj ) \
00268   Tpetra::RTI::tertiary_pre_transform_reduce( *out, *in2, *in3,                  \
00269     Tpetra::RTI::reductionGlob<id>( [=]( decltype((out)->meanValue()) out,       \
00270                                          decltype((in2)->meanValue()) in2,       \
00271                                          decltype((in3)->meanValue()) in3 )      \
00272                                        { return texp; },                         \
00273                                     [=]( decltype((out)->meanValue()) out,       \
00274                                          decltype((in2)->meanValue()) in2,       \
00275                                          decltype((in3)->meanValue()) in3 )      \
00276                                        { return gexp; },                         \
00277                                        robj ) )
00278 
00279 
00280 #endif // TPETRA_RTI_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines