10 #ifndef STOKHOS_CRSMATRIX_HPP
11 #define STOKHOS_CRSMATRIX_HPP
16 #include "Kokkos_Core.hpp"
17 #include "Kokkos_StaticCrsGraph.hpp"
27 Dim3(
const size_t x_,
const size_t y_ = 1,
const size_t z_ = 1) :
28 x(x_),
y(y_),
z(z_) {}
36 const size_t threads_per_block_x_,
37 const size_t threads_per_block_y_ = 1,
38 const size_t threads_per_block_z_ = 1) :
39 block_dim(threads_per_block_x_,threads_per_block_y_,threads_per_block_z_),
46 template <
typename ValueType,
typename Device,
47 typename Layout = Kokkos::LayoutRight>
52 typedef Kokkos::View< value_type[], Layout, execution_space >
values_type;
53 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE // Don't remove this until Kokkos has removed the deprecated code path probably around September 2018
54 typedef Kokkos::StaticCrsGraph< int , Layout, execution_space , int >
graph_type;
56 typedef Kokkos::StaticCrsGraph< int , Layout, execution_space , void, int >
graph_type;
70 template <
typename MatrixValue,
73 typename InputVectorType,
74 typename OutputVectorType>
87 typedef typename execution_space::size_type
size_type;
104 KOKKOS_INLINE_FUNCTION
107 const size_type iEntryBegin = m_A.graph.row_map[iRow];
108 const size_type iEntryEnd = m_A.graph.row_map[iRow+1];
112 for (
size_type iEntry = iEntryBegin; iEntry < iEntryEnd; ++iEntry ) {
113 sum += m_A.values(iEntry) * m_x( m_A.graph.entries(iEntry) );
123 const size_t row_count = A.
graph.row_map.extent(0) - 1;
124 Kokkos::parallel_for( row_count,
Multiply(A,x,y) );
129 template <
typename MatrixValue,
132 typename InputMultiVectorType,
133 typename OutputMultiVectorType,
134 typename OrdinalType >
136 InputMultiVectorType,
137 OutputMultiVectorType,
138 std::vector<OrdinalType>,
164 , m_col_indices( col_indices )
165 , m_num_vecs( col_indices.size() )
170 KOKKOS_INLINE_FUNCTION
173 const size_type iEntryBegin = m_A.graph.row_map[iRow];
174 const size_type iEntryEnd = m_A.graph.row_map[iRow+1];
181 for (
size_type iEntry = iEntryBegin ; iEntry < iEntryEnd ; ++iEntry ) {
182 sum += m_A.values(iEntry) * m_x( m_A.graph.entries(iEntry), iCol );
185 m_y( iRow, iCol ) =
sum;
196 const size_t n = A.
graph.row_map.extent(0) - 1 ;
199 const size_t block_size = 20;
200 const size_t num_vecs = col.size();
201 std::vector<OrdinalType> block_col;
202 block_col.reserve(block_size);
203 for (
size_t block=0; block<num_vecs; block+=block_size) {
205 block+block_size <= num_vecs ? block_size : num_vecs-block;
206 block_col.resize(bs);
207 for (
size_t i=0; i<bs; ++i)
208 block_col[i] = col[block+i];
209 Kokkos::parallel_for( n ,
Multiply(A,x,y,block_col) );
220 template <
typename MatrixValue,
223 typename InputMultiVectorType,
224 typename OutputMultiVectorType >
226 InputMultiVectorType,
227 OutputMultiVectorType,
255 , m_num_row( A.graph.row_map.extent(0)-1 )
256 , m_num_col( m_y.extent(1) )
262 KOKKOS_INLINE_FUNCTION
267 iBlockRow+m_block_row_size <= m_num_row ?
268 m_block_row_size : m_num_row-iBlockRow;
271 for (
size_type iBlockCol=0; iBlockCol<m_num_col; iBlockCol+=m_block_col_size) {
274 iBlockCol+m_block_col_size <= m_num_col ?
275 m_block_col_size : m_num_col-iBlockCol;
278 const size_type iRowEnd = iBlockRow + num_row;
279 for (
size_type iRow=iBlockRow; iRow<iRowEnd; ++iRow) {
282 const size_type iEntryBegin = m_A.graph.row_map[iRow];
283 const size_type iEntryEnd = m_A.graph.row_map[iRow+1];
286 const size_type iColEnd = iBlockCol + num_col;
287 for (
size_type iCol=iBlockCol; iCol<iColEnd; iCol++) {
291 for (
size_type iEntry = iEntryBegin; iEntry<iEntryEnd; ++iEntry) {
292 sum += m_A.values(iEntry) * m_x( m_A.graph.entries(iEntry), iCol );
294 m_y( iRow, iCol ) =
sum;
310 const size_type n = (num_row+m_block_row_size-1) / m_block_row_size;
311 Kokkos::parallel_for( n ,
Multiply(A,x,y) );
316 template <
typename MatrixValue,
319 typename InputMultiVectorType,
320 typename OutputMultiVectorType >
321 class Multiply< CrsMatrix<MatrixValue,Device,Layout>,
322 InputMultiVectorType,
323 OutputMultiVectorType,
328 typedef CrsMatrix<MatrixValue,Device,Layout> matrix_type;
329 typedef InputMultiVectorType input_multi_vector_type;
330 typedef OutputMultiVectorType output_multi_vector_type;
333 typedef typename execution_space::size_type size_type;
336 const matrix_type m_A;
337 const input_multi_vector_type m_x;
338 output_multi_vector_type m_y;
339 const size_type m_num_vecs;
341 Multiply(
const matrix_type&
A,
342 const input_multi_vector_type& x,
343 output_multi_vector_type& y)
347 , m_num_vecs( m_y.extent(1) )
352 KOKKOS_INLINE_FUNCTION
353 void operator()(
const size_type iRow )
const
355 const size_type iEntryBegin = m_A.graph.row_map[iRow];
356 const size_type iEntryEnd = m_A.graph.row_map[iRow+1];
358 for (size_type iCol=0; iCol<m_num_vecs; iCol++) {
362 for ( size_type iEntry = iEntryBegin ; iEntry < iEntryEnd ; ++iEntry ) {
363 sum += m_A.values(iEntry) * m_x( m_A.graph.entries(iEntry), iCol );
366 m_y( iRow, iCol ) =
sum;
372 static void apply(
const matrix_type&
A,
373 const input_multi_vector_type& x,
374 output_multi_vector_type& y )
376 const size_t n = A.graph.row_map.extent(0) - 1 ;
377 Kokkos::parallel_for( n , Multiply(A,x,y) );
400 template <
typename MatrixValue,
403 typename InputViewType,
404 typename OutputViewType>
406 std::vector<InputViewType>,
407 std::vector<OutputViewType>,
435 , m_num_row( A.graph.row_map.extent(0)-1 )
436 , m_num_col( x.size() )
442 KOKKOS_INLINE_FUNCTION
447 iBlockRow+m_block_row_size <= m_num_row ?
448 m_block_row_size : m_num_row-iBlockRow;
451 for (
size_type iBlockCol=0; iBlockCol<m_num_col; iBlockCol+=m_block_col_size) {
454 iBlockCol+m_block_col_size <= m_num_col ?
455 m_block_col_size : m_num_col-iBlockCol;
458 const size_type iRowEnd = iBlockRow + num_row;
459 for (
size_type iRow=iBlockRow; iRow<iRowEnd; ++iRow) {
462 const size_type iEntryBegin = m_A.graph.row_map[iRow];
463 const size_type iEntryEnd = m_A.graph.row_map[iRow+1];
466 const size_type iColEnd = iBlockCol + num_col;
467 for (
size_type iCol=iBlockCol; iCol<iColEnd; iCol++) {
471 for (
size_type iEntry = iEntryBegin; iEntry<iEntryEnd; ++iEntry) {
472 sum += m_A.values(iEntry) * m_x[iCol](m_A.graph.entries(iEntry));
474 m_y[iCol](iRow) = sum;
490 const size_type n = (num_row+m_block_row_size-1) / m_block_row_size;
491 Kokkos::parallel_for( n ,
Multiply(A,x,y) );
496 template <
typename MatrixValue,
499 typename InputViewType,
500 typename OutputViewType>
501 class Multiply< CrsMatrix<MatrixValue,Device,Layout>,
502 std::vector<InputViewType>,
503 std::vector<OutputViewType>,
508 typedef CrsMatrix<MatrixValue,Device,Layout> matrix_type;
509 typedef std::vector<InputViewType> input_multi_vector_type;
510 typedef std::vector<OutputViewType> output_multi_vector_type;
513 typedef typename execution_space::size_type size_type;
516 const matrix_type m_A;
517 const input_multi_vector_type m_x;
518 output_multi_vector_type m_y;
519 const size_type m_num_vecs;
521 Multiply(
const matrix_type& A,
522 const input_multi_vector_type& x,
523 output_multi_vector_type& y )
527 , m_num_vecs( x.size() )
533 KOKKOS_INLINE_FUNCTION
534 void operator()(
const size_type iRow )
const
536 const size_type iEntryBegin = m_A.graph.row_map[iRow];
537 const size_type iEntryEnd = m_A.graph.row_map[iRow+1];
539 for (size_type iCol=0; iCol<m_num_vecs; iCol++) {
543 for ( size_type iEntry = iEntryBegin ; iEntry < iEntryEnd ; ++iEntry ) {
544 sum += m_A.values(iEntry) * m_x[iCol]( m_A.graph.entries(iEntry) );
547 m_y[iCol]( iRow) = sum;
553 static void apply(
const matrix_type & A,
554 const input_multi_vector_type& x,
555 output_multi_vector_type& y )
557 const size_t n = A.graph.row_map.extent(0) - 1 ;
558 Kokkos::parallel_for( n , Multiply(A,x,y) );
583 template <
typename MatrixValue,
586 typename InputMultiVectorType,
587 typename OutputMultiVectorType,
588 typename OrdinalType>
590 const InputMultiVectorType& x,
591 OutputMultiVectorType& y,
592 const std::vector<OrdinalType>& col_indices,
597 typedef Kokkos::View<typename InputMultiVectorType::value_type*, typename InputMultiVectorType::array_layout, Device, Kokkos::MemoryUnmanaged> InputVectorType;
598 typedef Kokkos::View<typename OutputMultiVectorType::value_type*, typename OutputMultiVectorType::array_layout, Device, Kokkos::MemoryUnmanaged> OutputVectorType;
600 for (
size_t i=0; i<col_indices.size(); ++i) {
601 InputVectorType x_view =
602 Kokkos::subview( x , Kokkos::ALL() , col_indices[i] );
603 OutputVectorType y_view =
604 Kokkos::subview( y , Kokkos::ALL() , col_indices[i] );
605 multiply_type::apply( A , x_view , y_view );
609 template <
typename MatrixValue,
612 typename InputVectorType,
613 typename OutputVectorType>
615 const std::vector<InputVectorType>& x,
616 std::vector<OutputVectorType>& y,
621 for (
size_t i=0; i<x.size(); ++i) {
622 multiply_type::apply( A , x[i] , y[i] );
633 template <
typename ValueType,
typename Layout,
typename Device>
643 template <
typename ValueType,
typename Layout,
typename Device>
653 template <
typename ValueType,
typename Layout,
typename DstDevice,
669 template <
typename MatrixValue,
typename Layout,
typename Device >
678 std::ofstream file(filename.c_str());
680 file.setf(std::ios::scientific);
688 file <<
"%%MatrixMarket matrix coordinate real general" << std::endl;
689 file << nRow <<
" " << nRow <<
" " << hA.
values.extent(0) << std::endl;
694 for (
size_type entry=entryBegin; entry<entryEnd; ++entry) {
695 file << row+1 <<
" " << hA.
graph.entries(entry)+1 <<
" "
696 << std::setw(22) << hA.
values(entry) << std::endl;
KOKKOS_INLINE_FUNCTION void operator()(const size_type iBlockRow) const
const size_type m_num_row
output_multi_vector_type m_y
const input_multi_vector_type m_x
const size_type m_num_col
Kokkos::DefaultExecutionSpace execution_space
execution_space::size_type size_type
Multiply(const matrix_type &A, const input_multi_vector_type &x, output_multi_vector_type &y)
Dim3(const size_t x_, const size_t y_=1, const size_t z_=1)
CrsMatrix(Stokhos::DeviceConfig dev_config_)
CrsMatrix< ValueType, typename values_type::host_mirror_space, Layout > HostMirror
void multiply(const CrsMatrix< MatrixValue, Device, Layout > &A, const InputMultiVectorType &x, OutputMultiVectorType &y, const std::vector< OrdinalType > &col_indices, SingleColumnMultivectorMultiply)
std::vector< InputViewType > input_multi_vector_type
std::vector< OutputViewType > output_multi_vector_type
static void write(const matrix_type &A, const std::string &filename)
DeviceConfig(const size_t num_blocks_, const size_t threads_per_block_x_, const size_t threads_per_block_y_=1, const size_t threads_per_block_z_=1)
CrsMatrix< MatrixValue, Device, Layout > matrix_type
Kokkos::View< value_type[], Layout, execution_space > values_type
size_t num_threads_per_block
void deep_copy(const Stokhos::CrsMatrix< ValueType, DstDevice, Layout > &dst, const Stokhos::CrsMatrix< ValueType, SrcDevice, Layout > &src)
execution_space::size_type size_type
Kokkos::StaticCrsGraph< int, Layout, execution_space, void, int > graph_type
Stokhos::DeviceConfig dev_config
OutputViewType::value_type scalar_type
static void apply(const matrix_type &A, const input_multi_vector_type &x, output_multi_vector_type &y)
CrsMatrix< MatrixValue, Device, Layout > matrix_type
Stokhos::CrsMatrix< ValueType, Device, Layout >::HostMirror create_mirror(const Stokhos::CrsMatrix< ValueType, Device, Layout > &A)
std::enable_if< Kokkos::is_view_uq_pce< Kokkos::View< RD, RP...> >::value &&Kokkos::is_view_uq_pce< Kokkos::View< XD, XP...> >::value >::type sum(const Kokkos::View< RD, RP...> &r, const Kokkos::View< XD, XP...> &x)
Stokhos::CrsMatrix< ValueType, Device, Layout >::HostMirror create_mirror_view(const Stokhos::CrsMatrix< ValueType, Device, Layout > &A)