matrix_assign.hpp
Go to the documentation of this file.
1 /*!
2  * \brief Kernels for matrix-expression assignments
3  *
4  * \author O. Krause
5  * \date 2013
6  *
7  *
8  * \par Copyright 1995-2015 Shark Development Team
9  *
10  * <BR><HR>
11  * This file is part of Shark.
12  * <http://image.diku.dk/shark/>
13  *
14  * Shark is free software: you can redistribute it and/or modify
15  * it under the terms of the GNU Lesser General Public License as published
16  * by the Free Software Foundation, either version 3 of the License, or
17  * (at your option) any later version.
18  *
19  * Shark is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  * GNU Lesser General Public License for more details.
23  *
24  * You should have received a copy of the GNU Lesser General Public License
25  * along with Shark. If not, see <http://www.gnu.org/licenses/>.
26  *
27  */
28 #ifndef REMORA_KERNELS_MATRIX_ASSIGN_HPP
29 #define REMORA_KERNELS_MATRIX_ASSIGN_HPP
30 
32 #ifdef REMORA_USE_GPU
33 #include "gpu/matrix_assign.hpp"
34 #endif
35 #include <type_traits>
36 
37 namespace remora {namespace kernels{
38 //////////////////////////////////////////////////////
39 ////Scalar Assignment to Matrix
40 /////////////////////////////////////////////////////
41 
42 // Dispatcher
43 template<class F, class M, class Device>
44 void assign(
45  matrix_expression<M, Device> &m,
46  typename M::value_type t
47 ){
48  if(m().size1() == 0|| m().size2() == 0) return;
49  typedef typename M::orientation orientation;
50  bindings::matrix_assign<F> (m, t, orientation());
51 }
52 
53 /////////////////////////////////////////////////////////////////
54 //////Matrix Assignment implementing op=
55 ////////////////////////////////////////////////////////////////
56 
57 namespace detail{
58 
59 //general dispatcher: if the second argument has an unknown orientation
60 // it is chosen the same as the first one
61 template<class M, class E, class EOrientation, class TagE, class TagM, class Device>
62 void matrix_assign(
63  matrix_expression<M, Device> &m,
64  matrix_expression<E, Device> const& e,
65  row_major, EOrientation ,TagE tagE, TagM tagM
66 ) {
67  typedef typename std::conditional<
68  std::is_same<EOrientation, unknown_orientation>::value,
69  typename M::orientation,//always row_major
70  typename E::orientation
71  >::type Orientation;
72  bindings::matrix_assign(m,e,typename M::orientation(),Orientation(),tagE,tagM);
73 }
74 
75 //general dispatcher: if the first argument is column major, we transpose the whole expression
76 //so that it is row-major, this saves us to implment everything twice.
77 template<class M, class E,class EOrientation, class TagE, class TagM, class Device>
78 void matrix_assign(
79  matrix_expression<M, Device> &m,
80  matrix_expression<E, Device> const& e,
81  column_major, EOrientation,TagE tagE, TagM tagM
82 ) {
83  typedef typename M::orientation::transposed_orientation::orientation TMOrientation;
84  typedef typename E::orientation::transposed_orientation::orientation TEOrientation;
85  auto transM = trans(m);
86  auto transE = trans(e);
87  //dispatch to first version
88  matrix_assign(transM,transE,TMOrientation(),TEOrientation(),tagE,tagM);
89 }
90 }
91 
92 // Dispatcher
93 template<class M, class E, class Device>
94 void assign(matrix_expression<M, Device>& m, matrix_expression<E, Device> const& e) {
95  REMORA_SIZE_CHECK(m().size1() == e().size1());
96  REMORA_SIZE_CHECK(m().size2() == e().size2());
97  if(m().size1() == 0|| m().size2() == 0) return;
98  typedef typename M::orientation::orientation MOrientation;
99  typedef typename E::orientation::orientation EOrientation;
100  typedef typename M::evaluation_category::tag MCategory;
101  typedef typename E::evaluation_category::tag ECategory;
102  detail::matrix_assign(m, e, MOrientation(),EOrientation(),MCategory(), ECategory());
103 }
104 
105 
106 ///////////////////////////////////////////////////////////////////////////////////////////
107 //////Matrix Assignment With Functor implementing +=,-=...
108 ///////////////////////////////////////////////////////////////////////////////////////////
109 
110 namespace detail{
111 //general dispatcher: if the second argument has an unknown orientation
112 // it is chosen the same as the first one
113 template<class F, class M, class E, class EOrientation, class TagE, class TagM, class Device>
114 void matrix_assign_functor(
115  matrix_expression<M, Device> &m,
116  matrix_expression<E, Device> const& e,
117  F f,
118  row_major, EOrientation ,TagE tagE, TagM tagM
119 ) {
120  typedef typename std::conditional<
121  std::is_same<EOrientation, unknown_orientation>::value,
122  typename M::orientation,//always row_major
123  typename E::orientation
124  >::type Orientation;
125  bindings::matrix_assign_functor(m,e,f,typename M::orientation(),Orientation(),tagE,tagM);
126 }
127 
128 //general dispatcher: if the first argument is column major, we transpose the whole expression
129 //so that it is row-major, this saves us to implment everything twice.
130 template<class F, class M, class E,class EOrientation, class TagE, class TagM, class Device>
131 void matrix_assign_functor(
132  matrix_expression<M, Device> &m,
133  matrix_expression<E, Device> const& e,
134  F f,
135  column_major, EOrientation,TagE tagE, TagM tagM
136 ) {
137  typedef typename M::orientation::transposed_orientation::orientation TMOrientation;
138  typedef typename E::orientation::transposed_orientation::orientation TEOrientation;
139 
140  auto transM = trans(m);
141  auto transE = trans(e);
142  matrix_assign_functor(transM,transE,f,TMOrientation(),TEOrientation(),tagE,tagM);
143 }
144 
145 }
146 
147 
148 //First Level Dispatcher, dispatches by orientation
149 template<class F, class M, class E, class Device>
150 void assign(matrix_expression<M, Device> &m, const matrix_expression<E, Device> &e, F f = F()) {
151  REMORA_SIZE_CHECK(m().size1() == e().size1());
152  REMORA_SIZE_CHECK(m().size2() == e().size2());
153  if(m().size1() == 0|| m().size2() == 0) return;
154  typedef typename M::orientation::orientation MOrientation;
155  typedef typename E::orientation::orientation EOrientation;
156  typedef typename M::evaluation_category::tag MCategory;
157  typedef typename E::evaluation_category::tag ECategory;
158  detail::matrix_assign_functor(m, e, f, MOrientation(),EOrientation(), MCategory(), ECategory());
159 }
160 
161 }}
162 
163 #endif