28 #ifndef REMORA_GPU_MATRIX_PROXY_CLASSES_HPP 29 #define REMORA_GPU_MATRIX_PROXY_CLASSES_HPP 31 #include "../expression_types.hpp" 32 #include "../detail/traits.hpp" 33 #include <boost/compute/iterator/strided_iterator.hpp> 34 #include <boost/compute/iterator/buffer_iterator.hpp> 39 template<
class Arg1,
class Arg2,
class T>
40 struct induced_matrix_adaptor_element{
41 typedef T result_type;
44 gpu::dense_matrix_storage<T, dense_tag> storage;
47 template<
class Arg1,
class Arg2,
class T>
48 boost::compute::detail::meta_kernel& operator<< (
49 boost::compute::detail::meta_kernel& k,
50 induced_matrix_adaptor_element<Arg1, Arg2, T>
const& e
52 return k<< k.get_buffer_identifier<T>(e.storage.buffer, boost::compute::memory_object::global_memory)
53 <<
" [ "<<e.storage.offset <<
"+("<<e.arg1 <<
")*"<<e.storage.leading_dimension<<
"+"<<
"("<<e.arg2<<
")"<<
']';
57 template<
class T,
class Orientation>
58 class dense_matrix_adaptor<T, Orientation, gpu_tag>:
public matrix_expression<dense_matrix_adaptor<T,Orientation, gpu_tag>, gpu_tag > {
60 template<
class IndexExpr1,
class IndexExpr2>
61 detail::induced_matrix_adaptor_element<IndexExpr1, IndexExpr2, T> get_element(
62 IndexExpr1
const& expr1,IndexExpr2
const& expr2,
65 return {expr1, expr2,m_storage};
67 template<
class IndexExpr1,
class IndexExpr2>
68 detail::induced_matrix_adaptor_element<IndexExpr2, IndexExpr1,T> get_element(
69 IndexExpr1
const& expr1,IndexExpr2
const& expr2,
72 return {expr2, expr1,m_storage};
75 typedef std::size_t size_type;
76 typedef typename std::remove_const<T>::type value_type;
77 typedef value_type
const& const_reference;
80 typedef matrix_reference<dense_matrix_adaptor> closure_type;
81 typedef matrix_reference<dense_matrix_adaptor const> const_closure_type;
82 typedef gpu::dense_matrix_storage<T, dense_tag> storage_type;
83 typedef gpu::dense_matrix_storage<value_type const, dense_tag> const_storage_type;
84 typedef Orientation orientation;
85 typedef elementwise<dense_tag> evaluation_category;
89 dense_matrix_adaptor(dense_matrix_adaptor<value_type, Orientation>
const& expression)
90 : m_storage(expression.m_storage)
91 , m_queue(expression.m_queue)
92 , m_size1(expression.size1())
93 , m_size2(expression.size2())
102 dense_matrix_adaptor(
103 storage_type storage,
104 boost::compute::command_queue& queue,
105 size_type size1, size_type size2
113 dense_matrix_adaptor(vector_expression<E, gpu_tag>
const& expression, std::size_t size1, std::size_t size2)
114 : m_queue(&expression().queue())
117 auto storage = expression().raw_storage();
118 m_storage.buffer = storage.buffer;
119 m_storage.offset = storage.offset;
120 m_storage.leading_dimension = orientation::index_m(size1, size2);
121 REMORA_RANGE_CHECK(storage.stride == 1);
125 dense_matrix_adaptor(vector_expression<E, gpu_tag>& expression, std::size_t size1, std::size_t size2)
126 : m_queue(&expression().queue())
129 auto storage = expression().raw_storage();
130 m_storage.buffer = storage.buffer;
131 m_storage.offset = storage.offset;
132 m_storage.leading_dimension = orientation::index_m(size1, size2);
133 REMORA_RANGE_CHECK(storage.stride == 1);
141 dense_matrix_adaptor& operator = (dense_matrix_adaptor
const& e) {
142 REMORA_SIZE_CHECK(size1() == e().size1());
143 REMORA_SIZE_CHECK(size2() == e().size2());
144 return assign(*
this,
typename matrix_temporary<dense_matrix_adaptor>::type(e));
147 dense_matrix_adaptor& operator = (matrix_expression<E, gpu_tag>
const& e) {
148 REMORA_SIZE_CHECK(size1() == e().size1());
149 REMORA_SIZE_CHECK(size2() == e().size2());
150 return assign(*
this,
typename matrix_temporary<dense_matrix_adaptor>::type(e));
158 size_type size1()
const {
162 size_type size2()
const {
166 boost::compute::command_queue& queue()
const{
170 storage_type raw_storage(){
171 return {m_storage.buffer, m_storage.offset, m_storage.leading_dimension};
175 const_storage_type raw_storage()
const{
176 return {m_storage.buffer, m_storage.offset, m_storage.leading_dimension};
180 template <
class IndexExpr1,
class IndexExpr2>
181 auto operator()(IndexExpr1
const& i, IndexExpr2
const& j)
const -> decltype(std::declval<dense_matrix_adaptor const&>().get_element(i,j,orientation())){
182 return this->get_element(i,j,orientation());
186 typedef boost::compute::strided_iterator<boost::compute::buffer_iterator<T> > row_iterator;
187 typedef boost::compute::strided_iterator<boost::compute::buffer_iterator<T> > column_iterator;
188 typedef boost::compute::strided_iterator<boost::compute::buffer_iterator<T const> > const_row_iterator;
189 typedef boost::compute::strided_iterator<boost::compute::buffer_iterator<T const> > const_column_iterator;
191 const_row_iterator row_begin(size_type i)
const {
192 return {buffer_begin() + i * stride1(), stride2()};
194 const_row_iterator row_end(size_type i)
const {
195 return {buffer_begin() + i * stride1()+size2()*stride2(), stride2()};
198 const_row_iterator column_begin(size_type j)
const {
199 return {buffer_begin() + j * stride2(), stride1()};
201 const_column_iterator column_end(size_type j)
const {
202 return {buffer_begin() + j * stride2()+size1()*stride1(), stride1()};
205 row_iterator row_begin(size_type i){
206 return {buffer_begin() + i * stride1(), stride2()};
208 row_iterator row_end(size_type i){
209 return {buffer_begin() + i * stride1()+size2()*stride2(), stride2()};
212 row_iterator column_begin(size_type j){
213 return {buffer_begin() + j * stride2(), stride1()};
215 column_iterator column_end(size_type j){
216 return {buffer_begin() + j * stride2()+size1()*stride1(), stride1()};
220 boost::compute::buffer_iterator<T const> buffer_begin()
const{
221 return boost::compute::buffer_iterator<T>(m_storage.buffer, m_storage.offset);
224 boost::compute::buffer_iterator<T> buffer_begin(){
225 return boost::compute::buffer_iterator<T>(m_storage.buffer, m_storage.offset);
228 std::ptrdiff_t stride1()
const {
229 return (std::ptrdiff_t) orientation::stride1(std::size_t(1), m_storage.leading_dimension);
231 std::ptrdiff_t stride2()
const {
232 return (std::ptrdiff_t) orientation::stride2(std::size_t(1), m_storage.leading_dimension);
235 storage_type m_storage;
236 boost::compute::command_queue* m_queue;