|
Tpetra Matrix/Vector Services
Version of the Day
|
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
1.7.6.1