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 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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines