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
37namespace remora {namespace kernels{
38
39template<class F, class M, class Device>
40void apply(
41 matrix_expression<M, Device>& m,
42 F const&f
43){
44 if(m().size1() == 0|| m().size2() == 0) return;
45 typedef typename M::orientation orientation;
46 bindings::matrix_apply(m, f, orientation());
47}
48
49//////////////////////////////////////////////////////
50////Scalar Assignment to Matrix
51/////////////////////////////////////////////////////
52
53// Dispatcher
54template<class F, class M, class Device>
55void assign(
56 matrix_expression<M, Device>& m,
57 typename M::value_type t
58){
59 if(m().size1() == 0|| m().size2() == 0) return;
60 typedef typename M::orientation orientation;
61 bindings::matrix_assign<F> (m, t, orientation());
62}
63
64/////////////////////////////////////////////////////////////////
65//////Matrix Assignment implementing op=
66////////////////////////////////////////////////////////////////
67
68namespace detail{
69
70//general dispatcher: if the second argument has an unknown orientation
71// it is chosen the same as the first one
72template<class M, class E, class EOrientation, class TagE, class TagM, class Device>
73void matrix_assign(
74 matrix_expression<M, Device>& m,
75 matrix_expression<E, Device> const& e,
76 row_major, EOrientation ,TagE tagE, TagM tagM
77) {
78 typedef typename std::conditional<
79 std::is_same<EOrientation, unknown_orientation>::value,
80 row_major,
81 typename E::orientation
82 >::type Orientation;
83 bindings::matrix_assign(m, e, typename M::orientation(), Orientation(), tagE, tagM);
84}
85
86//general dispatcher: if the first argument is column major, we transpose the whole expression
87//so that it is row-major, this saves us to implment everything twice.
88template<class M, class E,class EOrientation, class TagE, class TagM, class Device>
89void matrix_assign(
90 matrix_expression<M, Device>& m,
91 matrix_expression<E, Device> const& e,
92 column_major, EOrientation,TagE tagE, TagM tagM
93) {
94 typedef typename M::orientation::transposed_orientation::orientation TMOrientation;
95 typedef typename E::orientation::transposed_orientation::orientation TEOrientation;
96 auto transM = trans(m);
97 auto transE = trans(e);
98 //dispatch to first version
99 matrix_assign(transM, transE, TMOrientation(), TEOrientation(), tagE, tagM);
100}
101}
102
103// Dispatcher
104template<class M, class E, class Device>
105void assign(
106 matrix_expression<M, Device>& m,
107 matrix_expression<E, Device> const& e
108){
109 REMORA_SIZE_CHECK(m().size1() == e().size1());
110 REMORA_SIZE_CHECK(m().size2() == e().size2());
111 if(m().size1() == 0|| m().size2() == 0) return;
112 typedef typename M::orientation::orientation MOrientation;
113 typedef typename E::orientation::orientation EOrientation;
114 typedef typename M::evaluation_category::tag MCategory;
115 typedef typename E::evaluation_category::tag ECategory;
116 detail::matrix_assign(m, e, MOrientation(), EOrientation(), MCategory(), ECategory());
117}
118
119
120///////////////////////////////////////////////////////////////////////////////////////////
121//////Matrix Assignment With Functor implementing +=,-=...
122///////////////////////////////////////////////////////////////////////////////////////////
123
124namespace detail{
125// general dispatcher: if the second argument has an unknown orientation
126// it is chosen the same as the first one
127template<class F, class M, class E, class EOrientation, class TagE, class TagM, class Device>
128void matrix_assign_functor(
129 matrix_expression<M, Device>& m,
130 matrix_expression<E, Device> const& e,
131 F f,
132 row_major, EOrientation ,TagE tagE, TagM tagM
133) {
134 typedef typename std::conditional<
135 std::is_same<EOrientation, unknown_orientation>::value,
136 row_major,
137 typename E::orientation
138 >::type Orientation;
139 bindings::matrix_assign_functor(m, e, f, typename M::orientation(), Orientation(), tagE, tagM);
140}
141
142//general dispatcher: if the first argument is column major, we transpose the whole expression
143//so that it is row-major, this saves us to implment everything twice.
144template<class F, class M, class E,class EOrientation, class TagE, class TagM, class Device>
145void matrix_assign_functor(
146 matrix_expression<M, Device>& m,
147 matrix_expression<E, Device> const& e,
148 F f,
149 column_major, EOrientation,TagE tagE, TagM tagM
150) {
151 typedef typename M::orientation::transposed_orientation::orientation TMOrientation;
152 typedef typename E::orientation::transposed_orientation::orientation TEOrientation;
153
154 auto transM = trans(m);
155 auto transE = trans(e);
156 matrix_assign_functor(transM, transE, f, TMOrientation(), TEOrientation(), tagE, tagM);
157}
158
159}
160
161
162//First Level Dispatcher, dispatches by orientation
163template<class F, class M, class E, class Device>
164void assign(
165 matrix_expression<M, Device>& m,
166 matrix_expression<E, Device> const&e,
167 F const& f
168){
169 REMORA_SIZE_CHECK(m().size1() == e().size1());
170 REMORA_SIZE_CHECK(m().size2() == e().size2());
171 if(m().size1() == 0|| m().size2() == 0) return;
172 typedef typename M::orientation::orientation MOrientation;
173 typedef typename E::orientation::orientation EOrientation;
174 typedef typename M::evaluation_category::tag MCategory;
175 typedef typename E::evaluation_category::tag ECategory;
176 detail::matrix_assign_functor(m, e, f, MOrientation(), EOrientation(), MCategory(), ECategory());
177}
178
179}}
180
181#endif