1+ #:include "common.fypp"
2+ #:set RANKS = range(1, 2+1)
3+ #:set R_KINDS_TYPES = list(zip(REAL_KINDS, REAL_TYPES, REAL_SUFFIX))
4+ #:set C_KINDS_TYPES = list(zip(CMPLX_KINDS, CMPLX_TYPES, CMPLX_SUFFIX))
5+ #:set KINDS_TYPES = R_KINDS_TYPES+C_KINDS_TYPES
6+ #! define ranks without parentheses
7+ #:def rksfx2(rank)
8+ #{if rank > 0}#${":," + ":," * (rank - 1)}$#{endif}#
9+ #:enddef
10+ submodule (stdlib_sparse_spmv) stdlib_sparse_spmv_csr
11+ contains
12+
13+ !! spmv_csr
14+ #:for k1, t1, s1 in (KINDS_TYPES)
15+ #:for rank in RANKS
16+ module subroutine spmv_csr_${rank}$d_${s1}$(matrix,vec_x,vec_y,alpha,beta,op)
17+ type(CSR_${s1}$_type), intent(in) :: matrix
18+ ${t1}$, intent(in) :: vec_x${ranksuffix(rank)}$
19+ ${t1}$, intent(inout) :: vec_y${ranksuffix(rank)}$
20+ ${t1}$, intent(in), optional :: alpha
21+ ${t1}$, intent(in), optional :: beta
22+ character(1), intent(in), optional :: op
23+ ${t1}$ :: alpha_
24+ character(1) :: op_
25+ integer(ilp) :: i, j
26+ #:if rank == 1
27+ ${t1}$ :: aux, aux2
28+ #:else
29+ ${t1}$ :: aux(size(vec_x,dim=1)), aux2(size(vec_x,dim=1))
30+ #:endif
31+
32+ op_ = sparse_op_none; if(present(op)) op_ = op
33+ alpha_ = one_${k1}$
34+ if(present(alpha)) alpha_ = alpha
35+ if(present(beta)) then
36+ vec_y = beta * vec_y
37+ else
38+ vec_y = zero_${s1}$
39+ endif
40+
41+ associate( data => matrix%data, col => matrix%col, rowptr => matrix%rowptr, &
42+ & nnz => matrix%nnz, nrows => matrix%nrows, ncols => matrix%ncols, storage => matrix%storage )
43+
44+ if( storage == sparse_full .and. op_==sparse_op_none ) then
45+ do i = 1, nrows
46+ aux = zero_${k1}$
47+ do j = rowptr(i), rowptr(i+1)-1
48+ aux = aux + data(j) * vec_x(${rksfx2(rank-1)}$col(j))
49+ end do
50+ vec_y(${rksfx2(rank-1)}$i) = vec_y(${rksfx2(rank-1)}$i) + alpha_ * aux
51+ end do
52+
53+ else if( storage == sparse_full .and. op_==sparse_op_transpose ) then
54+ do i = 1, nrows
55+ aux = alpha_ * vec_x(${rksfx2(rank-1)}$i)
56+ do j = rowptr(i), rowptr(i+1)-1
57+ vec_y(${rksfx2(rank-1)}$col(j)) = vec_y(${rksfx2(rank-1)}$col(j)) + data(j) * aux
58+ end do
59+ end do
60+
61+ else if( storage == sparse_lower .and. op_/=sparse_op_hermitian )then
62+ do i = 1 , nrows
63+ aux = zero_${s1}$
64+ aux2 = alpha_ * vec_x(${rksfx2(rank-1)}$i)
65+ do j = rowptr(i), rowptr(i+1)-2
66+ aux = aux + data(j) * vec_x(${rksfx2(rank-1)}$col(j))
67+ vec_y(${rksfx2(rank-1)}$col(j)) = vec_y(${rksfx2(rank-1)}$col(j)) + data(j) * aux2
68+ end do
69+ aux = alpha_ * aux + data(j) * aux2
70+ vec_y(${rksfx2(rank-1)}$i) = vec_y(${rksfx2(rank-1)}$i) + aux
71+ end do
72+
73+ else if( storage == sparse_upper .and. op_/=sparse_op_hermitian )then
74+ do i = 1 , nrows
75+ aux = vec_x(${rksfx2(rank-1)}$i) * data(rowptr(i))
76+ aux2 = alpha_ * vec_x(${rksfx2(rank-1)}$i)
77+ do j = rowptr(i)+1, rowptr(i+1)-1
78+ aux = aux + data(j) * vec_x(${rksfx2(rank-1)}$col(j))
79+ vec_y(${rksfx2(rank-1)}$col(j)) = vec_y(${rksfx2(rank-1)}$col(j)) + data(j) * aux2
80+ end do
81+ vec_y(${rksfx2(rank-1)}$i) = vec_y(${rksfx2(rank-1)}$i) + alpha_ * aux
82+ end do
83+
84+ #:if t1.startswith('complex')
85+ else if( storage == sparse_full .and. op_==sparse_op_hermitian) then
86+ do i = 1, nrows
87+ aux = alpha_ * vec_x(${rksfx2(rank-1)}$i)
88+ do j = rowptr(i), rowptr(i+1)-1
89+ vec_y(${rksfx2(rank-1)}$col(j)) = vec_y(${rksfx2(rank-1)}$col(j)) + conjg(data(j)) * aux
90+ end do
91+ end do
92+
93+ else if( storage == sparse_lower .and. op_==sparse_op_hermitian )then
94+ do i = 1 , nrows
95+ aux = zero_${s1}$
96+ aux2 = alpha_ * vec_x(${rksfx2(rank-1)}$i)
97+ do j = rowptr(i), rowptr(i+1)-2
98+ aux = aux + conjg(data(j)) * vec_x(${rksfx2(rank-1)}$col(j))
99+ vec_y(${rksfx2(rank-1)}$col(j)) = vec_y(${rksfx2(rank-1)}$col(j)) + conjg(data(j)) * aux2
100+ end do
101+ aux = alpha_ * aux + conjg(data(j)) * aux2
102+ vec_y(${rksfx2(rank-1)}$i) = vec_y(${rksfx2(rank-1)}$i) + aux
103+ end do
104+
105+ else if( storage == sparse_upper .and. op_==sparse_op_hermitian )then
106+ do i = 1 , nrows
107+ aux = vec_x(${rksfx2(rank-1)}$i) * conjg(data(rowptr(i)))
108+ aux2 = alpha_ * vec_x(${rksfx2(rank-1)}$i)
109+ do j = rowptr(i)+1, rowptr(i+1)-1
110+ aux = aux + conjg(data(j)) * vec_x(${rksfx2(rank-1)}$col(j))
111+ vec_y(${rksfx2(rank-1)}$col(j)) = vec_y(${rksfx2(rank-1)}$col(j)) + conjg(data(j)) * aux2
112+ end do
113+ vec_y(${rksfx2(rank-1)}$i) = vec_y(${rksfx2(rank-1)}$i) + alpha_ * aux
114+ end do
115+ #:endif
116+ end if
117+ end associate
118+ end subroutine
119+
120+ #:endfor
121+ #:endfor
122+
123+ end submodule stdlib_sparse_spmv_csr
0 commit comments