|
Kokkos Core Kernels Package
Version of the Day
|
00001 /* 00002 //@HEADER 00003 // ************************************************************************ 00004 // 00005 // Kokkos: Node API and Parallel Node Kernels 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 #ifndef KOKKOS_CRSMATRIX_MKL_HPP 00044 #define KOKKOS_CRSMATRIX_MKL_HPP 00045 00048 00049 #include <impl/Kokkos_PhysicalLayout.hpp> 00050 00051 namespace Kokkos { 00052 00058 template<typename T, class RangeVector,class CrsMatrix,class DomainVector> 00059 bool 00060 MV_Multiply_DoMKL (typename Kokkos::Impl::enable_if< 00061 ! Kokkos::Impl::is_same<T,double>::value && 00062 ! Kokkos::Impl::is_same<T,float>::value, 00063 typename RangeVector::value_type>::type s_b, 00064 const RangeVector& y, 00065 typename DomainVector::value_type s_a, 00066 const CrsMatrix& A, 00067 const DomainVector& x) 00068 { 00069 return false; 00070 } 00071 00072 template<typename T, class RangeVector,class CrsMatrix,class DomainVector> 00073 bool MV_Multiply_DoMKL(typename Kokkos::Impl::enable_if<Kokkos::Impl::is_same<T,double>::value, double >::type s_b 00074 ,const RangeVector & y, double s_a, 00075 const CrsMatrix & A , const DomainVector & x) { 00076 00077 char matdescra[6] = "GLNC0"; 00078 char transa = 'N'; 00079 int m = A.numRows(); 00080 int n = x.dimension_1(); 00081 int k = A.numCols(); 00082 double* x_ptr = (double*)x.ptr_on_device(); 00083 double* y_ptr = (double*)y.ptr_on_device(); 00084 if(x.dimension_1()>1) { 00085 Impl::PhysicalLayout layout_x(x); 00086 Impl::PhysicalLayout layout_y(y); 00087 if((layout_x.layout_type!=layout_x.Right) || layout_y.layout_type!=layout_y.Right) return false; 00088 00089 int stride_x = layout_x.stride[0]; 00090 int stride_y = layout_y.stride[0]; 00091 // FIXME (mfh 09 Aug 2013) Doesn't this interface only work with 00092 // row-major multivectors? I recall that only the "Fortran" 00093 // version works with column-major multivectors, and it requires 00094 // that the column indices be one-based. See 00095 // KokkosClassic::MklSparseOps for an example. 00096 mkl_dcsrmm(&transa, 00097 &m, &n, &k, 00098 &s_a, 00099 matdescra, 00100 A.values.ptr_on_device(), 00101 A.graph.entries.ptr_on_device(), 00102 (int*) &A.graph.row_map(0), 00103 (int*) &A.graph.row_map(1), 00104 x_ptr, 00105 &stride_x, 00106 &s_b, 00107 y_ptr, 00108 &stride_y); 00109 } else 00110 mkl_dcsrmv(&transa, 00111 &m, &k, 00112 &s_a, 00113 matdescra, 00114 A.values.ptr_on_device(), 00115 A.graph.entries.ptr_on_device(), 00116 (int*) &A.graph.row_map(0), 00117 (int*) &A.graph.row_map(1), 00118 x_ptr, 00119 &s_b, 00120 y_ptr); 00121 return true; 00122 } 00123 00124 template<typename T, class RangeVector,class CrsMatrix,class DomainVector> 00125 bool MV_Multiply_DoMKL(typename Kokkos::Impl::enable_if<Kokkos::Impl::is_same<T,float>::value, float >::type s_b 00126 ,const RangeVector & y, float s_a, 00127 const CrsMatrix & A , const DomainVector & x) { 00128 00129 char matdescra[6] = "GLNC0"; 00130 int stride_x = layout_x.stride[0]; 00131 int stride_y = layout_y.stride[0]; 00132 char transa = 'N'; 00133 int m = A.numRows(); 00134 int n = x.dimension_1(); 00135 int k = A.numCols(); 00136 float* x_ptr = (float*)x.ptr_on_device(); 00137 float* y_ptr = (float*)y.ptr_on_device(); 00138 if(x.dimension_1()>1) { 00139 00140 Impl::PhysicalLayout layout_x(x); 00141 Impl::PhysicalLayout layout_y(y); 00142 if((layout_x.layout_type!=layout_x.Right) || layout_y.layout_type!=layout_y.Right) return false; 00143 00144 mkl_scsrmm(&transa, 00145 &m, &n, &k, 00146 &s_a, 00147 matdescra, 00148 A.values.ptr_on_device(), 00149 A.graph.entries.ptr_on_device(), 00150 (int*) &A.graph.row_map(0), 00151 (int*) &A.graph.row_map(1), 00152 x_ptr, 00153 &stride_x, 00154 &s_b, 00155 y_ptr, 00156 &stride_y); 00157 } else 00158 mkl_scsrmv(&transa, 00159 &m, &k, 00160 &s_a, 00161 matdescra, 00162 A.values.ptr_on_device(), 00163 A.graph.entries.ptr_on_device(), 00164 (int*) &A.graph.row_map(0), 00165 (int*) &A.graph.row_map(1), 00166 x_ptr, 00167 &s_b, 00168 y_ptr); 00169 return true; 00170 } 00171 00172 //ToDo: strip compatible type attributes (const, volatile); make type of s_b and s_a independent 00173 template<class RangeVector,class CrsMatrix,class DomainVector> 00174 bool MV_Multiply_Try_MKL( typename RangeVector::value_type s_b,const RangeVector & y, typename DomainVector::value_type s_a, 00175 const CrsMatrix & A , const DomainVector & x) 00176 { 00177 if( ! Kokkos::Impl::is_same<typename RangeVector::device_type::memory_space,typename Kokkos::HostSpace>::value ) return false; 00178 if(Kokkos::Impl::is_same<typename RangeVector::non_const_value_type,float>::value&& 00179 Kokkos::Impl::is_same<typename DomainVector::non_const_value_type,float>::value&& 00180 Kokkos::Impl::is_same<typename CrsMatrix::values_type::non_const_value_type,float>::value) { 00181 return MV_Multiply_DoMKL<typename RangeVector::value_type,RangeVector,CrsMatrix,DomainVector>(s_b,y,s_a,A,x); 00182 } else 00183 if(Kokkos::Impl::is_same<typename RangeVector::non_const_value_type,double>::value&& 00184 Kokkos::Impl::is_same<typename DomainVector::non_const_value_type,double>::value&& 00185 Kokkos::Impl::is_same<typename CrsMatrix::values_type::non_const_value_type,double>::value) { 00186 return MV_Multiply_DoMKL<typename RangeVector::value_type,RangeVector,CrsMatrix,DomainVector>(s_b,y,s_a,A,x); 00187 } else 00188 return false; 00189 } 00190 00191 } 00192 00193 #endif // KOKKOS_CRSMATRIX_MKL_HPP
1.7.6.1