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