ViennaCL - The Vienna Computing Library: viennacl/matrix_proxy.hpp Source File

ViennaCL - The Vienna Computing Library 1.7.1 Free open-source GPU-accelerated linear algebra and solver library. |

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
matrix_proxy.hpp
Go to the documentation of this file.
1 #ifndef VIENNACL_MATRIX_PROXY_HPP_
2 #define VIENNACL_MATRIX_PROXY_HPP_
3
4 /* =========================================================================
5 Copyright (c) 2010-2016, Institute for Microelectronics,
6 Institute for Analysis and Scientific Computing,
7 TU Wien.
8 Portions of this software are copyright by UChicago Argonne, LLC.
9
10 -----------------
11 ViennaCL - The Vienna Computing Library
12 -----------------
13
14 Project Head: Karl Rupp rupp@iue.tuwien.ac.at
15
16 (A list of authors and contributors can be found in the manual)
17
18 License: MIT (X11), see file LICENSE in the base directory
19 ============================================================================= */
20
25 #include "viennacl/forwards.h"
26 #include "viennacl/range.hpp"
27 #include "viennacl/slice.hpp"
28 #include "viennacl/detail/matrix_def.hpp"
29 #include "viennacl/traits/size.hpp"
30
31 namespace viennacl
32 {
33
34 namespace detail
35 {
37
38 template<typename NumericT, typename MatrixT>
39 NumericT const & matrix_access(MatrixT const & A, vcl_size_t i, vcl_size_t j)
40 {
41 return A(i, j);
42 }
43
44 template<typename NumericT>
45 NumericT const & matrix_access(std::vector< std::vector<NumericT> > const & A, vcl_size_t i, vcl_size_t j)
46 {
47 return A[i][j];
48 }
49
51
52 template<typename NumericT, typename MatrixT>
53 NumericT & matrix_access(MatrixT & A, vcl_size_t i, vcl_size_t j)
54 {
55 return A(i, j);
56 }
57
58 template<typename NumericT>
59 NumericT & matrix_access(std::vector< std::vector<NumericT> > & A, vcl_size_t i, vcl_size_t j)
60 {
61 return A[i][j];
62 }
63
64 }
65
70 template<typename MatrixType>
71 class matrix_range : public matrix_base<typename MatrixType::cpu_value_type>
72 {
73 typedef matrix_base<typename MatrixType::cpu_value_type> base_type;
74 typedef matrix_range<MatrixType> self_type;
75
76 public:
77 typedef typename MatrixType::value_type value_type;
78 typedef typename MatrixType::handle_type handle_type;
79 typedef typename viennacl::result_of::cpu_value_type<value_type>::type cpu_value_type;
80 typedef range::size_type size_type;
81 typedef range::difference_type difference_type;
82 typedef value_type reference;
83 typedef const value_type & const_reference;
84
85
86 matrix_range(MatrixType const & A,
87 range const & row_range,
88 range const & col_range) : base_type(const_cast<handle_type &>(A.handle()),
89 row_range.size(), row_range.start() * A.stride1() + A.start1(), A.stride1(), A.internal_size1(),
90 col_range.size(), col_range.start() * A.stride2() + A.start2(), A.stride2(), A.internal_size2(),
91 A.row_major()) {}
92
93 matrix_range(self_type const & A,
94 range const & row_range,
95 range const & col_range) : base_type(const_cast<handle_type &>(A.handle()),
96 row_range.size(), row_range.start() * A.stride1() + A.start1(), A.stride1(), A.internal_size1(),
97 col_range.size(), col_range.start() * A.stride2() + A.start2(), A.stride2(), A.internal_size2(),
98 A.row_major()) {}
99
100
101 matrix_range(self_type const & other) : base_type(const_cast<handle_type &>(other.handle()),
102 other.size1(), other.start1(), other.stride1(), other.internal_size1(),
103 other.size2(), other.start2(), other.stride2(), other.internal_size2(),
104 other.row_major()) {}
105
106 using base_type::operator=;
107
108 // the following are needed for Visual Studio:
109 template<typename OtherNumericT, typename F>
110 base_type & operator=(viennacl::matrix<OtherNumericT, F> const & B) { return base_type::operator=(static_cast<viennacl::matrix_base<OtherNumericT> const &>(B)); }
111
112 template<typename OtherNumericT, typename F>
113 base_type & operator=(viennacl::matrix_range<viennacl::matrix<OtherNumericT, F> > const & B) { return base_type::operator=(static_cast<viennacl::matrix_base<OtherNumericT> const &>(B)); }
114
115 template<typename OtherNumericT, typename F>
116 base_type & operator=(viennacl::matrix_slice<viennacl::matrix<OtherNumericT, F> > const & B) { return base_type::operator=(static_cast<viennacl::matrix_base<OtherNumericT> const &>(B)); }
117 };
118
119 template<typename MatrixType>
120 class matrix_range<matrix_range<MatrixType> > : public matrix_base<typename MatrixType::cpu_value_type>
121 {
122 typedef matrix_base<typename MatrixType::cpu_value_type> base_type;
123 public:
124 typedef typename MatrixType::handle_type handle_type;
125
126 matrix_range(MatrixType const & A,
127 range const & row_range,
128 range const & col_range) : base_type(const_cast<handle_type &>(A.handle()),
129 row_range.size(), row_range.start() * A.stride1() + A.start1(), A.stride1(), A.internal_size1(),
130 col_range.size(), col_range.start() * A.stride2() + A.start2(), A.stride2(), A.internal_size2(),
131 A.row_major()) {}
132
133 matrix_range(matrix_range<MatrixType> const & A,
134 range const & row_range,
135 range const & col_range) : base_type(const_cast<handle_type &>(A.handle()),
136 row_range.size(), row_range.start() * A.stride1() + A.start1(), A.stride1(), A.internal_size1(),
137 col_range.size(), col_range.start() * A.stride2() + A.start2(), A.stride2(), A.internal_size2(),
138 A.row_major()) {}
139 };
140
144
145 //row_major:
146 template<typename CPUMatrixT, typename NumericT>
147 void copy(const CPUMatrixT & cpu_matrix,
148 matrix_range<matrix<NumericT, row_major, 1> > & gpu_matrix_range )
149 {
150 assert( (viennacl::traits::size1(cpu_matrix) == gpu_matrix_range.size1())
151 && (viennacl::traits::size2(cpu_matrix) == gpu_matrix_range.size2())
152 && bool("Matrix size mismatch!"));
153
154 if ( gpu_matrix_range.start2() != 0)
155 {
156 std::vector<NumericT> entries(gpu_matrix_range.size2());
157
158 //copy each stride separately:
159 for (vcl_size_t i=0; i < gpu_matrix_range.size1(); ++i)
160 {
161 for (vcl_size_t j=0; j < gpu_matrix_range.size2(); ++j)
162 entries[j] = detail::matrix_access<NumericT>(cpu_matrix, i, j);
163
164 vcl_size_t start_offset = (gpu_matrix_range.start1() + i) * gpu_matrix_range.internal_size2() + gpu_matrix_range.start2();
165 vcl_size_t num_entries = gpu_matrix_range.size2();
166 viennacl::backend::memory_write(gpu_matrix_range.handle(), sizeof(NumericT)*start_offset, sizeof(NumericT)*num_entries, &(entries[0]));
167 //std::cout << "Strided copy worked!" << std::endl;
168 }
169 }
170 else
171 {
172 //full block can be copied:
173 std::vector<NumericT> entries(gpu_matrix_range.size1()*gpu_matrix_range.internal_size2());
174
175 //copy each stride separately:
176 for (vcl_size_t i=0; i < gpu_matrix_range.size1(); ++i)
177 for (vcl_size_t j=0; j < gpu_matrix_range.size2(); ++j)
178 entries[i*gpu_matrix_range.internal_size2() + j] = detail::matrix_access<NumericT>(cpu_matrix, i, j);
179
180 vcl_size_t start_offset = gpu_matrix_range.start1() * gpu_matrix_range.internal_size2();
181 vcl_size_t num_entries = gpu_matrix_range.size1() * gpu_matrix_range.internal_size2();
182 viennacl::backend::memory_write(gpu_matrix_range.handle(), sizeof(NumericT)*start_offset, sizeof(NumericT)*num_entries, &(entries[0]));
183 //std::cout << "Block copy worked!" << std::endl;
184 }
185 }
186
187 //column_major:
188 template<typename CPUMatrixT, typename NumericT>
189 void copy(const CPUMatrixT & cpu_matrix,
190 matrix_range<matrix<NumericT, column_major, 1> > & gpu_matrix_range )
191 {
192 assert( (viennacl::traits::size1(cpu_matrix) == gpu_matrix_range.size1())
193 && (viennacl::traits::size2(cpu_matrix) == gpu_matrix_range.size2())
194 && bool("Matrix size mismatch!"));
195
196 if ( gpu_matrix_range.start1() != 0 || gpu_matrix_range.size1() != gpu_matrix_range.size1())
197 {
198 std::vector<NumericT> entries(gpu_matrix_range.size1());
199
200 //copy each stride separately:
201 for (vcl_size_t j=0; j < gpu_matrix_range.size2(); ++j)
202 {
203 for (vcl_size_t i=0; i < gpu_matrix_range.size1(); ++i)
204 entries[i] = detail::matrix_access<NumericT>(cpu_matrix, i, j);
205
206 vcl_size_t start_offset = (gpu_matrix_range.start2() + j) * gpu_matrix_range.internal_size1() + gpu_matrix_range.start1();
207 vcl_size_t num_entries = gpu_matrix_range.size1();
208 viennacl::backend::memory_write(gpu_matrix_range.handle(), sizeof(NumericT)*start_offset, sizeof(NumericT)*num_entries, &(entries[0]));
209 //std::cout << "Strided copy worked!" << std::endl;
210 }
211 }
212 else
213 {
214 //full block can be copied:
215 std::vector<NumericT> entries(gpu_matrix_range.internal_size1()*gpu_matrix_range.size2());
216
217 //copy each stride separately:
218 for (vcl_size_t i=0; i < gpu_matrix_range.size1(); ++i)
219 for (vcl_size_t j=0; j < gpu_matrix_range.size2(); ++j)
220 entries[i + j*gpu_matrix_range.internal_size1()] = detail::matrix_access<NumericT>(cpu_matrix, i, j);
221
222 vcl_size_t start_offset = gpu_matrix_range.start2() * gpu_matrix_range.internal_size1();
223 vcl_size_t num_entries = gpu_matrix_range.internal_size1() * gpu_matrix_range.size2();
224 viennacl::backend::memory_write(gpu_matrix_range.handle(), sizeof(NumericT)*start_offset, sizeof(NumericT)*num_entries, &(entries[0]));
225 //std::cout << "Block copy worked!" << std::endl;
226 }
227
228 }
229
230
234
235
236 //row_major:
237 template<typename CPUMatrixT, typename NumericT>
238 void copy(matrix_range<matrix<NumericT, row_major, 1> > const & gpu_matrix_range,
239 CPUMatrixT & cpu_matrix)
240 {
241 assert( (viennacl::traits::size1(cpu_matrix) == gpu_matrix_range.size1())
242 && (viennacl::traits::size2(cpu_matrix) == gpu_matrix_range.size2())
243 && bool("Matrix size mismatch!"));
244
245 if ( gpu_matrix_range.start2() != 0)
246 {
247 std::vector<NumericT> entries(gpu_matrix_range.size2());
248
249 //copy each stride separately:
250 for (vcl_size_t i=0; i < gpu_matrix_range.size1(); ++i)
251 {
252 vcl_size_t start_offset = (gpu_matrix_range.start1() + i) * gpu_matrix_range.internal_size2() + gpu_matrix_range.start2();
253 vcl_size_t num_entries = gpu_matrix_range.size2();
254 viennacl::backend::memory_read(gpu_matrix_range.handle(), sizeof(NumericT)*start_offset, sizeof(NumericT)*num_entries, &(entries[0]));
255 //std::cout << "Strided copy worked!" << std::endl;
256
257 for (vcl_size_t j=0; j < gpu_matrix_range.size2(); ++j)
258 detail::matrix_access<NumericT>(cpu_matrix, i, j) = entries[j];
259 }
260 }
261 else
262 {
263 //full block can be copied:
264 std::vector<NumericT> entries(gpu_matrix_range.size1()*gpu_matrix_range.internal_size2());
265
266 vcl_size_t start_offset = gpu_matrix_range.start1() * gpu_matrix_range.internal_size2();
267 viennacl::backend::memory_read(gpu_matrix_range.handle(), sizeof(NumericT)*start_offset, sizeof(NumericT)*entries.size(), &(entries[0]));
268 //std::cout << "Block copy worked!" << std::endl;
269
270 for (vcl_size_t i=0; i < gpu_matrix_range.size1(); ++i)
271 for (vcl_size_t j=0; j < gpu_matrix_range.size2(); ++j)
272 detail::matrix_access<NumericT>(cpu_matrix, i, j) = entries[i*gpu_matrix_range.internal_size2() + j];
273 }
274
275 }
276
277
278 //column_major:
279 template<typename CPUMatrixT, typename NumericT>
280 void copy(matrix_range<matrix<NumericT, column_major, 1> > const & gpu_matrix_range,
281 CPUMatrixT & cpu_matrix)
282 {
283 assert( (viennacl::traits::size1(cpu_matrix) == gpu_matrix_range.size1())
284 && (viennacl::traits::size2(cpu_matrix) == gpu_matrix_range.size2())
285 && bool("Matrix size mismatch!"));
286
287 if ( gpu_matrix_range.start1() != 0)
288 {
289 std::vector<NumericT> entries(gpu_matrix_range.size1());
290
291 //copy each stride separately:
292 for (vcl_size_t j=0; j < gpu_matrix_range.size2(); ++j)
293 {
294 vcl_size_t start_offset = (gpu_matrix_range.start2() + j) * gpu_matrix_range.internal_size1() + gpu_matrix_range.start1();
295 vcl_size_t num_entries = gpu_matrix_range.size1();
296 viennacl::backend::memory_read(gpu_matrix_range.handle(), sizeof(NumericT)*start_offset, sizeof(NumericT)*num_entries, &(entries[0]));
297 //std::cout << "Strided copy worked!" << std::endl;
298
299 for (vcl_size_t i=0; i < gpu_matrix_range.size1(); ++i)
300 detail::matrix_access<NumericT>(cpu_matrix, i, j) = entries[i];
301 }
302 }
303 else
304 {
305 //full block can be copied:
306 std::vector<NumericT> entries(gpu_matrix_range.internal_size1()*gpu_matrix_range.size2());
307
308 //copy each stride separately:
309 vcl_size_t start_offset = gpu_matrix_range.start2() * gpu_matrix_range.internal_size1();
310 vcl_size_t num_entries = gpu_matrix_range.internal_size1() * gpu_matrix_range.size2();
311 viennacl::backend::memory_read(gpu_matrix_range.handle(), sizeof(NumericT)*start_offset, sizeof(NumericT)*num_entries, &(entries[0]));
312 //std::cout << "Block copy worked!" << std::endl;
313
314 for (vcl_size_t i=0; i < gpu_matrix_range.size1(); ++i)
315 for (vcl_size_t j=0; j < gpu_matrix_range.size2(); ++j)
316 detail::matrix_access<NumericT>(cpu_matrix, i, j) = entries[i + j*gpu_matrix_range.internal_size1()];
317 }
318
319 }
320
321
322 //
323 // Convenience function
324 //
325 template<typename MatrixType>
326 matrix_range<MatrixType> project(MatrixType const & A, viennacl::range const & r1, viennacl::range const & r2)
327 {
328 assert(r1.size() <= A.size1() && r2.size() <= A.size2() && bool("Size of range invalid!"));
329
330 return matrix_range<MatrixType>(A, r1, r2);
331 }
332
333
334 template<typename MatrixType>
335 matrix_range<MatrixType> project(matrix_range<MatrixType> const & A, viennacl::range const & r1, viennacl::range const & r2)
336 {
337 assert(r1.size() <= A.size1() && r2.size() <= A.size2() && bool("Size of range invalid!"));
338
339 return matrix_range<MatrixType>(A, r1, r2);
340 }
341
342
343
344
345 //
346 //
347 //
349 //
350 //
351 //
352
353
354
355
356
361 template<typename MatrixType>
362 class matrix_slice : public matrix_base<typename MatrixType::cpu_value_type>
363 {
364 typedef matrix_base<typename MatrixType::cpu_value_type> base_type;
365 typedef matrix_slice<MatrixType> self_type;
366
367 public:
368
369 typedef typename MatrixType::value_type value_type;
370 typedef typename MatrixType::handle_type handle_type;
371 typedef typename viennacl::result_of::cpu_value_type<value_type>::type cpu_value_type;
372 typedef range::size_type size_type;
373 typedef range::difference_type difference_type;
374 typedef value_type reference;
375 typedef const value_type & const_reference;
376
377 matrix_slice(MatrixType const & A,
378 slice const & row_slice,
379 slice const & col_slice) : base_type(const_cast<handle_type &>(A.handle()),
380 row_slice.size(), row_slice.start() * A.stride1() + A.start1(), row_slice.stride() * A.stride1(), A.internal_size1(),
381 col_slice.size(), col_slice.start() * A.stride2() + A.start2(), col_slice.stride() * A.stride2(), A.internal_size2(),
382 A.row_major()) {}
383
384 matrix_slice(self_type const & A,
385 slice const & row_slice,
386 slice const & col_slice) : base_type(const_cast<handle_type &>(A.handle()),
387 row_slice.size(), row_slice.start() * A.stride1() + A.start1(), row_slice.stride() * A.stride1(), A.internal_size1(),
388 col_slice.size(), col_slice.start() * A.stride2() + A.start2(), col_slice.stride() * A.stride2(), A.internal_size2(),
389 A.row_major()) {}
390
391
392 matrix_slice(self_type const & other) : base_type(const_cast<handle_type &>(other.handle()),
393 other.size1(), other.start1(), other.stride1(), other.internal_size1(),
394 other.size2(), other.start2(), other.stride2(), other.internal_size2(),
395 other.row_major()) {}
396
397 using base_type::operator=;
398
399 // the following are needed for Visual Studio:
400 template<typename OtherNumericT, typename F>
401 base_type & operator=(viennacl::matrix<OtherNumericT, F> const & B) { return base_type::operator=(static_cast<viennacl::matrix_base<OtherNumericT> const &>(B)); }
402
403 template<typename OtherNumericT, typename F>
404 base_type & operator=(viennacl::matrix_range<viennacl::matrix<OtherNumericT, F> > const & B) { return base_type::operator=(static_cast<viennacl::matrix_base<OtherNumericT> const &>(B)); }
405
406 template<typename OtherNumericT, typename F>
407 base_type & operator=(viennacl::matrix_slice<viennacl::matrix<OtherNumericT, F> > const & B) { return base_type::operator=(static_cast<viennacl::matrix_base<OtherNumericT> const &>(B)); }
408 };
409
410 template<typename MatrixType>
411 class matrix_slice<matrix_range<MatrixType> > : public matrix_base<typename MatrixType::cpu_value_type>
412 {
413 typedef matrix_base<typename MatrixType::cpu_value_type> base_type;
414 public:
415 typedef typename MatrixType::handle_type handle_type;
416
417 matrix_slice(MatrixType const & A,
418 slice const & row_slice,
419 slice const & col_slice) : base_type(const_cast<handle_type &>(A.handle()),
420 row_slice.size(), row_slice.start() * A.stride1() + A.start1(), row_slice.stride() * A.stride1(), A.internal_size1(),
421 col_slice.size(), col_slice.start() * A.stride2() + A.start2(), col_slice.stride() * A.stride2(), A.internal_size2(),
422 A.row_major()) {}
423
424 matrix_slice(matrix_slice<MatrixType> const & A,
425 slice const & row_slice,
426 slice const & col_slice) : base_type(const_cast<handle_type &>(A.handle()),
427 row_slice.size(), row_slice.start() * A.stride1() + A.start1(), row_slice.stride() * A.stride1(), A.internal_size1(),
428 col_slice.size(), col_slice.start() * A.stride2() + A.start2(), col_slice.stride() * A.stride2(), A.internal_size2(),
429 A.row_major()) {}
430 };
431
432
436
437 //row_major:
438 template<typename CPUMatrixT, typename NumericT>
439 void copy(const CPUMatrixT & cpu_matrix,
440 matrix_slice<matrix<NumericT, row_major, 1> > & gpu_matrix_slice )
441 {
442 assert( (viennacl::traits::size1(cpu_matrix) == gpu_matrix_slice.size1())
443 && (viennacl::traits::size2(cpu_matrix) == gpu_matrix_slice.size2())
444 && bool("Matrix size mismatch!"));
445
446 if ( (gpu_matrix_slice.size1() > 0) && (gpu_matrix_slice.size1() > 0) )
447 {
448 vcl_size_t num_entries = gpu_matrix_slice.size2() * gpu_matrix_slice.stride2(); //no. of entries per stride
449
450 std::vector<NumericT> entries(num_entries);
451
452 //copy each stride separately:
453 for (vcl_size_t i=0; i < gpu_matrix_slice.size1(); ++i)
454 {
455 vcl_size_t start_offset = (gpu_matrix_slice.start1() + i * gpu_matrix_slice.stride1()) * gpu_matrix_slice.internal_size2() + gpu_matrix_slice.start2();
456 viennacl::backend::memory_read(gpu_matrix_slice.handle(), sizeof(NumericT)*start_offset, sizeof(NumericT)*num_entries, &(entries[0]));
457
458 for (vcl_size_t j=0; j < gpu_matrix_slice.size2(); ++j)
459 entries[j * gpu_matrix_slice.stride2()] = detail::matrix_access<NumericT>(cpu_matrix, i, j);
460
461 viennacl::backend::memory_write(gpu_matrix_slice.handle(), sizeof(NumericT)*start_offset, sizeof(NumericT)*num_entries, &(entries[0]));
462 }
463 }
464 }
465
466 //column_major:
467 template<typename CPUMatrixT, typename NumericT>
468 void copy(const CPUMatrixT & cpu_matrix,
469 matrix_slice<matrix<NumericT, column_major, 1> > & gpu_matrix_slice )
470 {
471 assert( (viennacl::traits::size1(cpu_matrix) == gpu_matrix_slice.size1())
472 && (viennacl::traits::size2(cpu_matrix) == gpu_matrix_slice.size2())
473 && bool("Matrix size mismatch!"));
474
475
476 if ( (gpu_matrix_slice.size1() > 0) && (gpu_matrix_slice.size1() > 0) )
477 {
478 vcl_size_t num_entries = gpu_matrix_slice.size1() * gpu_matrix_slice.stride1(); //no. of entries per stride
479
480 std::vector<NumericT> entries(num_entries);
481
482 //copy each column stride separately:
483 for (vcl_size_t j=0; j < gpu_matrix_slice.size2(); ++j)
484 {
485 vcl_size_t start_offset = gpu_matrix_slice.start1() + (gpu_matrix_slice.start2() + j * gpu_matrix_slice.stride2()) * gpu_matrix_slice.internal_size1();
486
487 viennacl::backend::memory_read(gpu_matrix_slice.handle(), sizeof(NumericT)*start_offset, sizeof(NumericT)*num_entries, &(entries[0]));
488
489 for (vcl_size_t i=0; i < gpu_matrix_slice.size1(); ++i)
490 entries[i * gpu_matrix_slice.stride1()] = detail::matrix_access<NumericT>(cpu_matrix, i, j);
491
492 viennacl::backend::memory_write(gpu_matrix_slice.handle(), sizeof(NumericT)*start_offset, sizeof(NumericT)*num_entries, &(entries[0]));
493 }
494 }
495
496 }
497
498
502
503
504 //row_major:
505 template<typename CPUMatrixT, typename NumericT>
506 void copy(matrix_slice<matrix<NumericT, row_major, 1> > const & gpu_matrix_slice,
507 CPUMatrixT & cpu_matrix)
508 {
509 assert( (viennacl::traits::size1(cpu_matrix) == gpu_matrix_slice.size1())
510 && (viennacl::traits::size2(cpu_matrix) == gpu_matrix_slice.size2())
511 && bool("Matrix size mismatch!"));
512
513 if ( (gpu_matrix_slice.size1() > 0) && (gpu_matrix_slice.size1() > 0) )
514 {
515 vcl_size_t num_entries = gpu_matrix_slice.size2() * gpu_matrix_slice.stride2(); //no. of entries per stride
516
517 std::vector<NumericT> entries(num_entries);
518
519 //copy each stride separately:
520 for (vcl_size_t i=0; i < gpu_matrix_slice.size1(); ++i)
521 {
522 vcl_size_t start_offset = (gpu_matrix_slice.start1() + i * gpu_matrix_slice.stride1()) * gpu_matrix_slice.internal_size2() + gpu_matrix_slice.start2();
523
524 viennacl::backend::memory_read(gpu_matrix_slice.handle(), sizeof(NumericT)*start_offset, sizeof(NumericT)*num_entries, &(entries[0]));
525
526 for (vcl_size_t j=0; j < gpu_matrix_slice.size2(); ++j)
527 detail::matrix_access<NumericT>(cpu_matrix, i, j) = entries[j * gpu_matrix_slice.stride2()];
528 }
529 }
530
531 }
532
533
534 //column_major:
535 template<typename CPUMatrixT, typename NumericT>
536 void copy(matrix_slice<matrix<NumericT, column_major, 1> > const & gpu_matrix_slice,
537 CPUMatrixT & cpu_matrix)
538 {
539 assert( (viennacl::traits::size1(cpu_matrix) == gpu_matrix_slice.size1())
540 && (viennacl::traits::size2(cpu_matrix) == gpu_matrix_slice.size2())
541 && bool("Matrix size mismatch!"));
542
543 if ( (gpu_matrix_slice.size1() > 0) && (gpu_matrix_slice.size1() > 0) )
544 {
545 vcl_size_t num_entries = gpu_matrix_slice.size1() * gpu_matrix_slice.stride1(); //no. of entries per stride
546
547 std::vector<NumericT> entries(num_entries);
548
549 //copy each column stride separately:
550 for (vcl_size_t j=0; j < gpu_matrix_slice.size2(); ++j)
551 {
552 vcl_size_t start_offset = gpu_matrix_slice.start1() + (gpu_matrix_slice.start2() + j * gpu_matrix_slice.stride2()) * gpu_matrix_slice.internal_size1();
553
554 viennacl::backend::memory_read(gpu_matrix_slice.handle(), sizeof(NumericT)*start_offset, sizeof(NumericT)*num_entries, &(entries[0]));
555
556 for (vcl_size_t i=0; i < gpu_matrix_slice.size1(); ++i)
557 detail::matrix_access<NumericT>(cpu_matrix, i, j) = entries[i * gpu_matrix_slice.stride1()];
558 }
559 }
560
561 }
562
563
564 //
565 // Convenience function
566 //
567 template<typename MatrixType>
568 matrix_slice<MatrixType> project(MatrixType const & A, viennacl::slice const & r1, viennacl::slice const & r2)
569 {
570 assert(r1.size() <= A.size1() && r2.size() <= A.size2() && bool("Size of slice invalid!"));
571
572 return matrix_slice<MatrixType>(A, r1, r2);
573 }
574
575 template<typename MatrixType>
576 matrix_slice<MatrixType> project(matrix_range<MatrixType> const & A, viennacl::slice const & r1, viennacl::slice const & r2)
577 {
578 assert(r1.size() <= A.size1() && r2.size() <= A.size2() && bool("Size of slice invalid!"));
579
580 return matrix_slice<MatrixType>(A, r1, r2);
581 }
582
583 template<typename MatrixType>
584 matrix_slice<MatrixType> project(matrix_slice<MatrixType> const & A, viennacl::slice const & r1, viennacl::slice const & r2)
585 {
586 assert(r1.size() <= A.size1() && r2.size() <= A.size2() && bool("Size of slice invalid!"));
587
588 return matrix_slice<MatrixType>(A, r1, r2);
589 }
590
591 // TODO: Allow mix of range/slice
592
593 }
594
595 #endif
viennacl::backend::cpu_ram::handle_type
viennacl::tools::shared_ptr< char > handle_type
Definition: cpu_ram.hpp:40
viennacl::matrix_range::operator=
base_type & operator=(viennacl::matrix_slice< viennacl::matrix< OtherNumericT, F > > const &B)
Definition: matrix_proxy.hpp:116
viennacl::matrix_slice< matrix_range< MatrixType > >::handle_type
MatrixType::handle_type handle_type
Definition: matrix_proxy.hpp:415
viennacl::matrix_slice< matrix_range< MatrixType > >::matrix_slice
matrix_slice(MatrixType const &A, slice const &row_slice, slice const &col_slice)
Definition: matrix_proxy.hpp:417
viennacl::basic_range::difference_type
DistanceT difference_type
Definition: range.hpp:43
viennacl::backend::memory_write
void memory_write(mem_handle &dst_buffer, vcl_size_t dst_offset, vcl_size_t bytes_to_write, const void *ptr, bool async=false)
Writes data from main RAM identified by 'ptr' to the buffer identified by 'dst_buffer'.
Definition: memory.hpp:220
viennacl::matrix_range::operator=
base_type & operator=(viennacl::matrix< OtherNumericT, F > const &B)
Definition: matrix_proxy.hpp:110
viennacl::matrix_slice::reference
value_type reference
Definition: matrix_proxy.hpp:374
viennacl::matrix_range< matrix_range< MatrixType > >::matrix_range
matrix_range(matrix_range< MatrixType > const &A, range const &row_range, range const &col_range)
Definition: matrix_proxy.hpp:133
size.hpp
Generic size and resize functionality for different vector and matrix types.
viennacl::matrix_slice
Class for representing strided submatrices of a bigger matrix A.
Definition: forwards.h:443
viennacl::matrix_base::operator=
self_type & operator=(const self_type &other)
Definition: matrix.hpp:262
viennacl::basic_slice::size
size_type size() const
Definition: slice.hpp:56
viennacl::matrix_range::size_type
range::size_type size_type
Definition: matrix_proxy.hpp:80
viennacl::traits::size1
vcl_size_t size1(MatrixType const &mat)
Generic routine for obtaining the number of rows of a matrix (ViennaCL, uBLAS, etc.)
Definition: size.hpp:163
viennacl::matrix_slice::value_type
MatrixType::value_type value_type
Definition: matrix_proxy.hpp:369
viennacl::matrix_base
Definition: matrix_def.hpp:103
viennacl::matrix_range< matrix_range< MatrixType > >::handle_type
MatrixType::handle_type handle_type
Definition: matrix_proxy.hpp:124
viennacl::matrix_range::matrix_range
matrix_range(MatrixType const &A, range const &row_range, range const &col_range)
Definition: matrix_proxy.hpp:86
viennacl::matrix_range::handle_type
MatrixType::handle_type handle_type
Definition: matrix_proxy.hpp:78
viennacl::matrix_base< MatrixType::cpu_value_type >::stride2
size_type stride2() const
Returns the number of columns.
Definition: matrix_def.hpp:234
viennacl::traits::stride
result_of::size_type< viennacl::vector_base< T > >::type stride(viennacl::vector_base< T > const &s)
Definition: stride.hpp:45
forwards.h
This file provides the forward declarations for the main types used within ViennaCL.
viennacl::matrix
A dense matrix class.
Definition: forwards.h:375
viennacl::backend::memory_read
void memory_read(mem_handle const &src_buffer, vcl_size_t src_offset, vcl_size_t bytes_to_read, void *ptr, bool async=false)
Reads data from a buffer back to main RAM.
Definition: memory.hpp:261
viennacl::matrix_slice::difference_type
range::difference_type difference_type
Definition: matrix_proxy.hpp:373
matrix_def.hpp
Forward declaration of dense matrix classes.
viennacl::matrix_range::reference
value_type reference
Definition: matrix_proxy.hpp:82
viennacl::traits::size2
result_of::size_type< MatrixType >::type size2(MatrixType const &mat)
Generic routine for obtaining the number of columns of a matrix (ViennaCL, uBLAS, etc...
Definition: size.hpp:201
viennacl::matrix_range::cpu_value_type
viennacl::result_of::cpu_value_type< value_type >::type cpu_value_type
Definition: matrix_proxy.hpp:79
viennacl::matrix_slice::matrix_slice
matrix_slice(self_type const &other)
Definition: matrix_proxy.hpp:392
NumericT
float NumericT
Definition: bisect.cpp:40
viennacl::matrix_range::value_type
MatrixType::value_type value_type
Definition: matrix_proxy.hpp:77
viennacl::traits::size
vcl_size_t size(VectorType const &vec)
Generic routine for obtaining the size of a vector (ViennaCL, uBLAS, etc.)
Definition: size.hpp:239
viennacl::matrix_slice::size_type
range::size_type size_type
Definition: matrix_proxy.hpp:372
viennacl::matrix_range::matrix_range
matrix_range(self_type const &A, range const &row_range, range const &col_range)
Definition: matrix_proxy.hpp:93
viennacl::traits::start
result_of::size_type< T >::type start(T const &obj)
Definition: start.hpp:44
viennacl::matrix_slice::matrix_slice
matrix_slice(MatrixType const &A, slice const &row_slice, slice const &col_slice)
Definition: matrix_proxy.hpp:377
viennacl::matrix_range::difference_type
range::difference_type difference_type
Definition: matrix_proxy.hpp:81
viennacl::matrix_range::const_reference
const value_type & const_reference
Definition: matrix_proxy.hpp:83
viennacl::matrix_base< MatrixType::cpu_value_type >::stride1
size_type stride1() const
Returns the number of rows.
Definition: matrix_def.hpp:232
viennacl::project
matrix_range< MatrixType > project(MatrixType const &A, viennacl::range const &r1, viennacl::range const &r2)
Definition: matrix_proxy.hpp:326
viennacl::matrix_range::matrix_range
matrix_range(self_type const &other)
Definition: matrix_proxy.hpp:101
viennacl::vcl_size_t
std::size_t vcl_size_t
Definition: forwards.h:75
viennacl::matrix_base< MatrixType::cpu_value_type >::size2
size_type size2() const
Returns the number of columns.
Definition: matrix_def.hpp:226
viennacl::matrix_base< MatrixType::cpu_value_type >::handle
handle_type & handle()
Returns the OpenCL handle, non-const-version.
Definition: matrix_def.hpp:244
viennacl::matrix_slice::operator=
base_type & operator=(viennacl::matrix_slice< viennacl::matrix< OtherNumericT, F > > const &B)
Definition: matrix_proxy.hpp:407
viennacl::result_of::cpu_value_type::type
T::ERROR_CANNOT_DEDUCE_CPU_SCALAR_TYPE_FOR_T type
Definition: result_of.hpp:271
viennacl::matrix_base< MatrixType::cpu_value_type >::size1
size_type size1() const
Returns the number of rows.
Definition: matrix_def.hpp:224
viennacl::matrix_slice::handle_type
MatrixType::handle_type handle_type
Definition: matrix_proxy.hpp:370
viennacl::matrix_slice::operator=
base_type & operator=(viennacl::matrix< OtherNumericT, F > const &B)
Definition: matrix_proxy.hpp:401
viennacl::matrix_slice::matrix_slice
matrix_slice(self_type const &A, slice const &row_slice, slice const &col_slice)
Definition: matrix_proxy.hpp:384
viennacl::copy
void copy(std::vector< NumericT > &cpu_vec, circulant_matrix< NumericT, AlignmentV > &gpu_mat)
Copies a circulant matrix from the std::vector to the OpenCL device (either GPU or multi-core CPU) ...
Definition: circulant_matrix.hpp:150
slice.hpp
Implementation of a slice object for use with proxy objects.
viennacl::basic_range
A range class that refers to an interval [start, stop), where 'start' is included, and 'stop' is excluded.
Definition: forwards.h:424
viennacl::matrix_range::operator=
base_type & operator=(viennacl::matrix_range< viennacl::matrix< OtherNumericT, F > > const &B)
Definition: matrix_proxy.hpp:113
range.hpp
Implementation of a range object for use with proxy objects.
viennacl::matrix_base< MatrixType::cpu_value_type >::start2
size_type start2() const
Returns the number of columns.
Definition: matrix_def.hpp:230
viennacl::matrix_base< MatrixType::cpu_value_type >::internal_size2
size_type internal_size2() const
Returns the internal number of columns. Usually required for launching OpenCL kernels only...
Definition: matrix_def.hpp:240
viennacl::matrix_range
Class for representing non-strided submatrices of a bigger matrix A.
Definition: forwards.h:440
viennacl::detail::matrix_access
NumericT const & matrix_access(MatrixT const &A, vcl_size_t i, vcl_size_t j)
Definition: matrix_proxy.hpp:39
viennacl::matrix_base< MatrixType::cpu_value_type >::internal_size1
size_type internal_size1() const
Returns the internal number of rows. Usually required for launching OpenCL kernels only...
Definition: matrix_def.hpp:238
viennacl::basic_range::size_type
SizeT size_type
Definition: range.hpp:42
viennacl::matrix_slice::cpu_value_type
viennacl::result_of::cpu_value_type< value_type >::type cpu_value_type
Definition: matrix_proxy.hpp:371
viennacl::matrix_slice::const_reference
const value_type & const_reference
Definition: matrix_proxy.hpp:375
viennacl::basic_slice
A slice class that refers to an interval [start, stop), where 'start' is included, and 'stop' is excluded.
Definition: forwards.h:429
viennacl::row_major
A tag for row-major storage of a dense matrix.
Definition: forwards.h:304
viennacl::matrix_range< matrix_range< MatrixType > >::matrix_range
matrix_range(MatrixType const &A, range const &row_range, range const &col_range)
Definition: matrix_proxy.hpp:126
viennacl::matrix_base< MatrixType::cpu_value_type >::start1
size_type start1() const
Returns the number of rows.
Definition: matrix_def.hpp:228
viennacl::matrix_slice::operator=
base_type & operator=(viennacl::matrix_range< viennacl::matrix< OtherNumericT, F > > const &B)
Definition: matrix_proxy.hpp:404
viennacl::basic_range::size
size_type size() const
Definition: range.hpp:56
viennacl::matrix_slice< matrix_range< MatrixType > >::matrix_slice
matrix_slice(matrix_slice< MatrixType > const &A, slice const &row_slice, slice const &col_slice)
Definition: matrix_proxy.hpp:424