28 #ifndef REMORA_GPU_MATRIX_HPP 29 #define REMORA_GPU_MATRIX_HPP 31 #include "../detail/traits.hpp" 32 #include "../assignment.hpp" 33 #include "../detail/matrix_proxy_classes.hpp" 34 #include <boost/compute/container/vector.hpp> 35 #include <boost/compute/iterator/strided_iterator.hpp> 40 template<
class Arg1,
class Arg2,
class T>
41 struct induced_matrix_element{
42 typedef T result_type;
45 std::size_t leading_dimension;
46 boost::compute::buffer
const& buffer;
49 template<
class Arg1,
class Arg2,
class T>
50 boost::compute::detail::meta_kernel& operator<< (
51 boost::compute::detail::meta_kernel& k,
52 induced_matrix_element<Arg1, Arg2, T>
const& e
54 return k<< k.get_buffer_identifier<T>(e.buffer, boost::compute::memory_object::global_memory)
55 <<
'['<<e.arg1 <<
'*'<<e.leading_dimension<<
'+'<< e.arg2<<
']';
70 template<
class T,
class L>
71 class matrix<T,L, gpu_tag> :
public matrix_container<matrix<T,L, gpu_tag>, gpu_tag > {
73 template<
class IndexExpr1,
class IndexExpr2>
74 detail::induced_matrix_element<IndexExpr1, IndexExpr2, T> get_element(
75 IndexExpr1
const& expr1,IndexExpr2
const& expr2,
78 return {expr1, expr2,orientation::index_m(m_size1,m_size2), m_storage.get_buffer()};
80 template<
class IndexExpr1,
class IndexExpr2>
81 detail::induced_matrix_element<IndexExpr2, IndexExpr1,T> get_element(
82 IndexExpr1
const& expr1,IndexExpr2
const& expr2,
85 return {expr2, expr1,orientation::index_m(m_size1,m_size2), m_storage.get_buffer()};
89 typedef value_type const_reference;
90 typedef value_type reference;
91 typedef std::size_t size_type;
93 typedef matrix_reference<matrix const> const_closure_type;
94 typedef matrix_reference<matrix> closure_type;
95 typedef gpu::dense_matrix_storage<T, continuous_dense_tag> storage_type;
96 typedef gpu::dense_matrix_storage<T const, continuous_dense_tag> const_storage_type;
97 typedef elementwise<dense_tag> evaluation_category;
98 typedef L orientation;
106 matrix(boost::compute::command_queue& queue = boost::compute::system::default_queue())
107 : m_storage(queue.get_context())
108 , m_queue(&queue),m_size1(0), m_size2(0){}
115 explicit matrix(size_type size1, size_type size2, boost::compute::command_queue& queue = boost::compute::system::default_queue())
116 : m_storage(size1 * size2, queue.get_context())
126 matrix(size_type size1, size_type size2, value_type
const& init, boost::compute::command_queue& queue = boost::compute::system::default_queue())
127 : m_storage(size1 * size2, init, queue)
135 : m_storage(
std::move(m.m_storage))
136 , m_queue(&m.queue())
138 , m_size2(m.size2()){}
142 matrix(matrix
const& m)
143 : m_storage(m.m_storage)
144 , m_queue(&m.queue())
146 , m_size2(m.size2()){}
151 matrix(matrix_expression<E, gpu_tag>
const& e)
152 : m_storage(e().size1() * e().size2(), e().queue().get_context())
153 , m_queue(&e().queue())
154 , m_size1(e().size1())
155 , m_size2(e().size2()){
167 matrix& operator = (matrix
const& m){
168 resize(m.size1(),m.size2());
169 return assign(*
this, m);
175 matrix& operator = (matrix && m){
176 m_storage = std::move(m.m_storage);
188 matrix& operator = (matrix_container<C, gpu_tag>
const& m) {
189 resize(m().size1(), m().size2());
190 return assign(*
this, m);
198 matrix& operator = (matrix_expression<E, gpu_tag>
const& e) {
200 swap(*
this,temporary);
209 size_type size1()
const {
213 size_type size2()
const {
217 boost::compute::command_queue& queue()
const{
221 const_storage_type raw_storage()
const{
222 return {m_storage.get_buffer(),0,orientation::index_m(m_size1,m_size2)};
226 storage_type raw_storage(){
227 return {m_storage.get_buffer(),0,orientation::index_m(m_size1,m_size2)};
231 template <
class IndexExpr1,
class IndexExpr2>
232 detail::induced_matrix_element<IndexExpr1,IndexExpr2,T> operator()(IndexExpr1
const& i, IndexExpr2
const& j)
const{
233 return this->get_element(i,j,orientation());
243 void resize(size_type size1, size_type size2) {
244 if(size1 * size2 < m_storage.size())
245 m_storage.resize(size1 * size2);
247 m_storage = boost::compute::vector<T>(size1 * size2, queue().get_context());
260 void resize(size_type size1, size_type size2, value_type init) {
262 boost::compute::fill(m_storage.begin(),m_storage.end(), init, queue());
266 boost::compute::fill(m_storage.begin(),m_storage.end(), value_type(), queue());
270 typedef boost::compute::strided_iterator<typename boost::compute::vector<T>::iterator > row_iterator;
271 typedef boost::compute::strided_iterator<typename boost::compute::vector<T>::iterator > column_iterator;
272 typedef boost::compute::strided_iterator<typename boost::compute::vector<T>::const_iterator > const_row_iterator;
273 typedef boost::compute::strided_iterator<typename boost::compute::vector<T>::const_iterator > const_column_iterator;
275 const_row_iterator row_begin(size_type i)
const {
276 return {m_storage.begin() + i * stride1(), stride2()};
278 const_row_iterator row_end(size_type i)
const {
279 return {m_storage.begin() + i * stride1()+size2()*stride2(), stride2()};
282 const_row_iterator column_begin(size_type j)
const {
283 return {m_storage.begin() + j * stride2(), stride1()};
285 const_column_iterator column_end(size_type j)
const {
286 return {m_storage.begin() + j * stride2()+size1()*stride1(), stride1()};
289 row_iterator row_begin(size_type i){
290 return {m_storage.begin() + i * stride1(), stride2()};
292 row_iterator row_end(size_type i){
293 return {m_storage.begin() + i * stride1()+size2()*stride2(), stride2()};
296 row_iterator column_begin(size_type j){
297 return {m_storage.begin() + j * stride2(), stride1()};
299 column_iterator column_end(size_type j){
300 return {m_storage.begin() + j * stride2()+size1()*stride1(), stride1()};
307 friend void swap(matrix& m1, matrix& m2) {
309 swap(m1.m_storage,m2.m_storage);
317 std::ptrdiff_t stride1()
const {
318 return (std::ptrdiff_t) orientation::stride1(m_size1, m_size2);
320 std::ptrdiff_t stride2()
const {
321 return (std::ptrdiff_t) orientation::stride2(m_size1, m_size2);
324 boost::compute::vector<T> m_storage;
325 boost::compute::command_queue* m_queue;