Kokkos Core Kernels Package  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Kokkos_CrsMatrix_MKL.hpp
Go to the documentation of this file.
1 /*
2 //@HEADER
3 // ************************************************************************
4 //
5 // Kokkos: Node API and Parallel Node Kernels
6 // Copyright (2008) Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
39 //
40 // ************************************************************************
41 //@HEADER
42 */
43 #ifndef KOKKOS_CRSMATRIX_MKL_HPP
44 #define KOKKOS_CRSMATRIX_MKL_HPP
45 
48 
49 #include <impl/Kokkos_PhysicalLayout.hpp>
50 
51 namespace Kokkos {
52 
58 template<typename T, class RangeVector,class CrsMatrix,class DomainVector>
59 bool
60 MV_Multiply_DoMKL (typename Kokkos::Impl::enable_if<
61  ! Kokkos::Impl::is_same<T,double>::value &&
62  ! Kokkos::Impl::is_same<T,float>::value,
63  typename RangeVector::value_type>::type s_b,
64  const RangeVector& y,
65  typename DomainVector::value_type s_a,
66  const CrsMatrix& A,
67  const DomainVector& x)
68 {
69  return false;
70 }
71 
72 template<typename T, class RangeVector,class CrsMatrix,class DomainVector>
73 bool MV_Multiply_DoMKL(typename Kokkos::Impl::enable_if<Kokkos::Impl::is_same<T,double>::value, double >::type s_b
74  ,const RangeVector & y, double s_a,
75  const CrsMatrix & A , const DomainVector & x) {
76 
77  char matdescra[6] = "GLNC0";
78  char transa = 'N';
79  int m = A.numRows();
80  int n = x.dimension_1();
81  int k = A.numCols();
82  double* x_ptr = (double*)x.ptr_on_device();
83  double* y_ptr = (double*)y.ptr_on_device();
84  if(x.dimension_1()>1) {
85  Impl::PhysicalLayout layout_x(x);
86  Impl::PhysicalLayout layout_y(y);
87  if((layout_x.layout_type!=layout_x.Right) || layout_y.layout_type!=layout_y.Right) return false;
88 
89  int stride_x = layout_x.stride[0];
90  int stride_y = layout_y.stride[0];
91  // FIXME (mfh 09 Aug 2013) Doesn't this interface only work with
92  // row-major multivectors? I recall that only the "Fortran"
93  // version works with column-major multivectors, and it requires
94  // that the column indices be one-based. See
95  // KokkosClassic::MklSparseOps for an example.
96  mkl_dcsrmm(&transa,
97  &m, &n, &k,
98  &s_a,
99  matdescra,
100  A.values.ptr_on_device(),
101  A.graph.entries.ptr_on_device(),
102  (int*) &A.graph.row_map(0),
103  (int*) &A.graph.row_map(1),
104  x_ptr,
105  &stride_x,
106  &s_b,
107  y_ptr,
108  &stride_y);
109  } else
110  mkl_dcsrmv(&transa,
111  &m, &k,
112  &s_a,
113  matdescra,
114  A.values.ptr_on_device(),
115  A.graph.entries.ptr_on_device(),
116  (int*) &A.graph.row_map(0),
117  (int*) &A.graph.row_map(1),
118  x_ptr,
119  &s_b,
120  y_ptr);
121  return true;
122 }
123 
124 template<typename T, class RangeVector,class CrsMatrix,class DomainVector>
125 bool MV_Multiply_DoMKL(typename Kokkos::Impl::enable_if<Kokkos::Impl::is_same<T,float>::value, float >::type s_b
126  ,const RangeVector & y, float s_a,
127  const CrsMatrix & A , const DomainVector & x) {
128 
129  char matdescra[6] = "GLNC0";
130  int stride_x = layout_x.stride[0];
131  int stride_y = layout_y.stride[0];
132  char transa = 'N';
133  int m = A.numRows();
134  int n = x.dimension_1();
135  int k = A.numCols();
136  float* x_ptr = (float*)x.ptr_on_device();
137  float* y_ptr = (float*)y.ptr_on_device();
138  if(x.dimension_1()>1) {
139 
140  Impl::PhysicalLayout layout_x(x);
141  Impl::PhysicalLayout layout_y(y);
142  if((layout_x.layout_type!=layout_x.Right) || layout_y.layout_type!=layout_y.Right) return false;
143 
144  mkl_scsrmm(&transa,
145  &m, &n, &k,
146  &s_a,
147  matdescra,
148  A.values.ptr_on_device(),
149  A.graph.entries.ptr_on_device(),
150  (int*) &A.graph.row_map(0),
151  (int*) &A.graph.row_map(1),
152  x_ptr,
153  &stride_x,
154  &s_b,
155  y_ptr,
156  &stride_y);
157  } else
158  mkl_scsrmv(&transa,
159  &m, &k,
160  &s_a,
161  matdescra,
162  A.values.ptr_on_device(),
163  A.graph.entries.ptr_on_device(),
164  (int*) &A.graph.row_map(0),
165  (int*) &A.graph.row_map(1),
166  x_ptr,
167  &s_b,
168  y_ptr);
169  return true;
170 }
171 
172 //ToDo: strip compatible type attributes (const, volatile); make type of s_b and s_a independent
173 template<class RangeVector,class CrsMatrix,class DomainVector>
174 bool MV_Multiply_Try_MKL( typename RangeVector::value_type s_b,const RangeVector & y, typename DomainVector::value_type s_a,
175  const CrsMatrix & A , const DomainVector & x)
176 {
177  if( ! Kokkos::Impl::is_same<typename RangeVector::device_type::memory_space,typename Kokkos::HostSpace>::value ) return false;
178  if(Kokkos::Impl::is_same<typename RangeVector::non_const_value_type,float>::value&&
179  Kokkos::Impl::is_same<typename DomainVector::non_const_value_type,float>::value&&
180  Kokkos::Impl::is_same<typename CrsMatrix::values_type::non_const_value_type,float>::value) {
181  return MV_Multiply_DoMKL<typename RangeVector::value_type,RangeVector,CrsMatrix,DomainVector>(s_b,y,s_a,A,x);
182  } else
183  if(Kokkos::Impl::is_same<typename RangeVector::non_const_value_type,double>::value&&
184  Kokkos::Impl::is_same<typename DomainVector::non_const_value_type,double>::value&&
185  Kokkos::Impl::is_same<typename CrsMatrix::values_type::non_const_value_type,double>::value) {
186  return MV_Multiply_DoMKL<typename RangeVector::value_type,RangeVector,CrsMatrix,DomainVector>(s_b,y,s_a,A,x);
187  } else
188  return false;
189 }
190 
191 }
192 
193 #endif // KOKKOS_CRSMATRIX_MKL_HPP
bool MV_Multiply_DoMKL(typename Kokkos::Impl::enable_if< !Kokkos::Impl::is_same< T, double >::value &&!Kokkos::Impl::is_same< T, float >::value, typename RangeVector::value_type >::type s_b, const RangeVector &y, typename DomainVector::value_type s_a, const CrsMatrix &A, const DomainVector &x)
Attempt to compute y = s_a * A * x using Intel MKL.
Compressed sparse row implementation of a sparse matrix.