Tpetra Matrix/Vector Services  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
Tpetra_Details_MultiVectorDistObjectKernels_decl.hpp
00001 /*
00002 // @HEADER
00003 // ***********************************************************************
00004 //
00005 //          Tpetra: Templated Linear Algebra Services Package
00006 //                 Copyright (2008) Sandia Corporation
00007 //
00008 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00009 // the U.S. Government retains certain rights in this software.
00010 //
00011 // Redistribution and use in source and binary forms, with or without
00012 // modification, are permitted provided that the following conditions are
00013 // met:
00014 //
00015 // 1. Redistributions of source code must retain the above copyright
00016 // notice, this list of conditions and the following disclaimer.
00017 //
00018 // 2. Redistributions in binary form must reproduce the above copyright
00019 // notice, this list of conditions and the following disclaimer in the
00020 // documentation and/or other materials provided with the distribution.
00021 //
00022 // 3. Neither the name of the Corporation nor the names of the
00023 // contributors may be used to endorse or promote products derived from
00024 // this software without specific prior written permission.
00025 //
00026 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00027 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00029 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00030 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00031 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00032 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00033 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00034 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00035 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00036 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037 //
00038 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00039 //
00040 // ************************************************************************
00041 // @HEADER
00042 */
00043 
00044 // mfh 13/14 Sep 2013 The "should use as<size_t>" comments are both
00045 // incorrect (as() is not a device function) and usually irrelevant
00046 // (it would only matter if LocalOrdinal were bigger than size_t on a
00047 // particular platform, which is unlikely).
00048 
00049 #ifndef TPETRA_DETAILS_MULTI_VECTOR_DIST_OBJECT_KERNELS_DECL_HPP
00050 #define TPETRA_DETAILS_MULTI_VECTOR_DIST_OBJECT_KERNELS_DECL_HPP
00051 
00052 #include "Tpetra_ConfigDefs.hpp"
00053 #if TPETRA_USE_KOKKOS_DISTOBJECT
00054 
00055 #include "Kokkos_Core.hpp"
00056 
00057 // Don't include Teuchos_ScalarTraits.hpp here because we want a different
00058 // version for CPU versus GPU
00059 
00060 namespace Tpetra {
00061 namespace Details {
00062 
00063   // Functors for implementing packAndPrepare and unpackAndCombine
00064   // through parallel_for
00065 
00066   template <typename Scalar, typename LocalOrdinal, typename Device>
00067   struct PackArraySingleColumnConstantStride {
00068     typedef Device device_type;
00069     typedef typename device_type::size_type size_type;
00070 
00071     Kokkos::View<const LocalOrdinal*, device_type> exportLIDs;
00072     Kokkos::View<const Scalar*, device_type, Kokkos::MemoryUnmanaged> src;
00073     Kokkos::View<Scalar*, device_type> exports;
00074 
00075     KOKKOS_INLINE_FUNCTION
00076     void operator()( const size_type k ) const {
00077       exports[k] = src[exportLIDs[k]];
00078     }
00079 
00080     void pack();
00081   };
00082 
00083   template <typename Scalar, typename LocalOrdinal, typename Device>
00084   struct PackArraySingleColumnOffset {
00085     typedef Device device_type;
00086     typedef typename device_type::size_type size_type;
00087 
00088     Kokkos::View<const LocalOrdinal*, device_type> exportLIDs;
00089     Kokkos::View<const Scalar*, device_type, Kokkos::MemoryUnmanaged> src;
00090     Kokkos::View<Scalar*, device_type> exports;
00091     size_t offset;
00092 
00093     KOKKOS_INLINE_FUNCTION
00094     void operator()( const size_type k ) const {
00095       exports[k] = src[exportLIDs[k] + offset];
00096     }
00097 
00098     void pack();
00099   };
00100 
00101   template <typename Scalar, typename LocalOrdinal, typename Device>
00102   struct PackArrayMultiColumnConstantStride {
00103     typedef Device device_type;
00104     typedef typename device_type::size_type size_type;
00105 
00106     Kokkos::View<const LocalOrdinal*, device_type> exportLIDs;
00107     Kokkos::View<const Scalar*, device_type, Kokkos::MemoryUnmanaged> src;
00108     Kokkos::View<Scalar*, device_type> exports;
00109     size_t stride, numCols;
00110 
00111     KOKKOS_INLINE_FUNCTION
00112     void operator()( const size_type k ) const {
00113       const size_t localRow = exportLIDs[k]; // should use as<size_t>()
00114       const size_t offset = k*numCols;
00115       for (size_t j = 0; j < numCols; ++j)
00116         exports[offset + j] = src[localRow + j*stride];
00117     }
00118 
00119     void pack();
00120   };
00121 
00122   template <typename Scalar, typename LocalOrdinal, typename Device>
00123   struct PackArrayMultiColumnVariableStride {
00124     typedef Device device_type;
00125     typedef typename device_type::size_type size_type;
00126 
00127     Kokkos::View<const LocalOrdinal*, device_type> exportLIDs;
00128     Kokkos::View<const size_t*, device_type> srcWhichVectors;
00129     Kokkos::View<const Scalar*, device_type, Kokkos::MemoryUnmanaged> src;
00130     Kokkos::View<Scalar*, device_type> exports;
00131     size_t stride, numCols;
00132 
00133     KOKKOS_INLINE_FUNCTION
00134     void operator()( const size_type k ) const {
00135       const size_t localRow = exportLIDs[k]; // should use as<size_t>()
00136       const size_t offset = k*numCols;
00137       for (size_t j = 0; j < numCols; ++j)
00138         exports[offset + j] = src[localRow + srcWhichVectors[j]*stride];
00139     }
00140 
00141     void pack();
00142   };
00143 
00144   struct InsertOp {
00145     template <typename Scalar>
00146     KOKKOS_INLINE_FUNCTION
00147     void operator() (Scalar& dest, const Scalar& src) const {
00148       //dest = src;
00149       Kokkos::atomic_exchange(&dest, src);
00150     }
00151   };
00152   struct AddOp {
00153     template <typename Scalar>
00154     KOKKOS_INLINE_FUNCTION
00155     void operator() (Scalar& dest, const Scalar& src) const {
00156       //dest += src;
00157       Kokkos::atomic_fetch_add(&dest, src);
00158     }
00159   };
00160   struct AbsMaxOp {
00161     template <typename Scalar>
00162     KOKKOS_INLINE_FUNCTION
00163     Scalar max(const Scalar& a, const Scalar& b) const {
00164       return a > b ? a : b ;
00165     }
00166 
00167     template <typename Scalar>
00168     KOKKOS_INLINE_FUNCTION
00169     void operator() (Scalar& dest, const Scalar& src) const {
00170       typedef Teuchos::ScalarTraits<Scalar> SCT;
00171       //dest = max( SCT::magnitude(dest), SCT::magnitude(src) );
00172       Kokkos::atomic_exchange(
00173         &dest, max( SCT::magnitude(dest), SCT::magnitude(src) ) );
00174     }
00175   };
00176 
00177   template <typename Scalar, typename LocalOrdinal, typename Op, typename Device>
00178   struct UnpackArrayMultiColumnConstantStride {
00179     typedef Device device_type;
00180     typedef typename device_type::size_type size_type;
00181 
00182     Kokkos::View<const LocalOrdinal*, device_type> importLIDs;
00183     Kokkos::View<const Scalar*, device_type> imports;
00184     Kokkos::View<Scalar*, device_type, Kokkos::MemoryUnmanaged> dest;
00185     size_t stride, numCols;
00186     Op op;
00187 
00188     KOKKOS_INLINE_FUNCTION
00189     void operator()( const size_type k ) const {
00190       const size_t localRow = importLIDs[k]; // should use as<size_t>()
00191       const size_t offset = k*numCols;
00192       for (size_t j = 0; j < numCols; ++j)
00193         op(dest[localRow + j*stride], imports[offset + j]);
00194     }
00195 
00196     void unpack();
00197   };
00198 
00199   template <typename Scalar, typename LocalOrdinal, typename Op, typename Device>
00200   struct UnpackArrayMultiColumnVariableStride {
00201     typedef Device device_type;
00202     typedef typename device_type::size_type size_type;
00203 
00204     Kokkos::View<const LocalOrdinal*, device_type> importLIDs;
00205     Kokkos::View<const size_t*, device_type> whichVectors;
00206     Kokkos::View<const Scalar*, device_type> imports;
00207     Kokkos::View<Scalar*, device_type, Kokkos::MemoryUnmanaged> dest;
00208     size_t stride, numCols;
00209     Op op;
00210 
00211     KOKKOS_INLINE_FUNCTION
00212     void operator()( const size_type k ) const {
00213       const size_t localRow = importLIDs[k]; // should use as<size_t>()
00214       const size_t offset = k*numCols;
00215       for (size_t j = 0; j < numCols; ++j)
00216         op(dest[localRow + whichVectors[j]*stride], imports[offset + j]);
00217     }
00218 
00219     void unpack();
00220   };
00221 
00222   template <typename Scalar, typename LocalOrdinal, typename Device>
00223   struct PermuteArrayMultiColumnConstantStride {
00224     typedef Device device_type;
00225     typedef typename device_type::size_type size_type;
00226 
00227     Kokkos::View<const LocalOrdinal*, device_type> permuteToLIDs;
00228     Kokkos::View<const LocalOrdinal*, device_type> permuteFromLIDs;
00229     Kokkos::View<const Scalar*, device_type, Kokkos::MemoryUnmanaged> src;
00230     Kokkos::View<Scalar*, device_type, Kokkos::MemoryUnmanaged> dest;
00231     size_t src_stride, dest_stride, numCols;
00232 
00233     KOKKOS_INLINE_FUNCTION
00234     void operator()( const size_type k ) const {
00235       const size_t toRow = permuteToLIDs[k]; // should use as<size_t>()
00236       const size_t fromRow = permuteFromLIDs[k]; // should use as<size_t>()
00237       for (size_t j = 0; j < numCols; ++j)
00238         dest[toRow + j*dest_stride] = src[fromRow + j*src_stride];
00239     }
00240 
00241     void permute();
00242   };
00243 
00244   template <typename Scalar, typename LocalOrdinal, typename Device>
00245   struct PermuteArrayMultiColumnVariableStride {
00246     typedef Device device_type;
00247     typedef typename device_type::size_type size_type;
00248 
00249     Kokkos::View<const LocalOrdinal*, device_type> permuteToLIDs;
00250     Kokkos::View<const LocalOrdinal*, device_type> permuteFromLIDs;
00251     Kokkos::View<const size_t*, device_type> src_whichVectors;
00252     Kokkos::View<const size_t*, device_type> dest_whichVectors;
00253     Kokkos::View<const Scalar*, device_type, Kokkos::MemoryUnmanaged> src;
00254     Kokkos::View<Scalar*, device_type, Kokkos::MemoryUnmanaged> dest;
00255     size_t src_stride, dest_stride, numCols;
00256 
00257     KOKKOS_INLINE_FUNCTION
00258     void operator()( const size_type k ) const {
00259       const size_t toRow = permuteToLIDs[k]; // should use as<size_t>()
00260       const size_t fromRow = permuteFromLIDs[k]; // should use as<size_t>()
00261       for (size_t j = 0; j < numCols; ++j)
00262         dest[toRow + dest_whichVectors[j]*dest_stride] =
00263           src[fromRow + src_whichVectors[j]*src_stride];
00264     }
00265 
00266     void permute();
00267   };
00268 
00269 } // Details namespace
00270 } // Tpetra namespace
00271 
00272 #endif // TPETRA_USE_KOKKOS_DISTOBJECT
00273 
00274 #endif // TPETRA_DETAILS_MULTI_VECTOR_DIST_OBJECT_KERNELS_DECL_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines