10#include "scaleFElib.h"
19 use scale_const,
only: &
20 undef8 => const_undef8, &
37 real(rp),
allocatable :: val(:)
38 integer,
allocatable :: colidx(:)
41 integer,
allocatable :: rowptr(:)
47 integer,
private :: storage_format_id
49 procedure,
public :: init => sparsemat_init
50 procedure,
public :: final => sparsemat_final
51 procedure,
public :: print => sparsemat_print
52 procedure,
public :: replaceval => sparsemat_replceval
53 procedure,
public :: getval => sparsemat_getval
54 procedure,
public :: getstorageformatid => sparsemat_get_storage_format_id
58 module procedure sparsemat_matmul1
59 module procedure sparsemat_matmul1_2
60 module procedure sparsemat_matmul2
75 private :: sparsemat_matmul_csr_1
76 private :: sparsemat_matmul_csr_2
77 private :: sparsemat_matmul_ell_1
78 private :: sparsemat_matmul_ell_2
90 subroutine sparsemat_init( this, mat, &
95 real(rp),
intent(in) :: mat(:,:)
96 real(rp),
optional,
intent(in) :: eps
97 character(len=*),
optional,
intent(in) :: storage_format
103 integer :: val_counter
104 integer :: rowptr_counter
106 real(dp) :: tmp_val(size(mat)+1)
107 integer :: tmp_colind(size(mat)+1)
108 integer :: tmp_rowptr(0:size(mat,1)+1)
111 character(len=H_MID) :: storage_format_ =
'CSR'
113 integer :: row_nonzero_counter(size(mat,1))
114 integer :: col_size_l
127 if (
present(eps))
then
130 eps_ = const_eps * 500.0_rp
133 if (
present(storage_format))
then
134 storage_format_ = storage_format
137 select case (storage_format_)
143 if ( abs(mat(i,j)) > eps_ )
then
144 tmp_val(val_counter) = mat(i,j)
145 tmp_colind(val_counter) = j
146 val_counter = val_counter + 1
149 rowptr_counter = rowptr_counter + 1
150 tmp_rowptr(rowptr_counter) = val_counter
156 row_nonzero_counter(i) = 0
158 if ( abs(mat(i,j)) >= eps_ ) &
159 row_nonzero_counter(i) = row_nonzero_counter(i) + 1
162 this%col_size = maxval(row_nonzero_counter(:))
163 val_counter = this%M * this%col_size
170 if ( abs(mat(i,j)) >= eps_ )
then
171 col_size_l = col_size_l + 1
172 l = i+(col_size_l-1)*this%M
173 tmp_val(l) = mat(i,j)
179 log_error(
"SparseMat_Init",*)
'Not appropriate names of storage format. Check!', trim(storage_format_)
183 this%nnz = val_counter
184 allocate( this%val(val_counter) )
185 allocate( this%colIdx(val_counter) )
186 this%val(:) = tmp_val(1:val_counter)
187 this%colIdx(:) = tmp_colind(1:val_counter)
189 select case (storage_format_)
191 allocate( this%rowPtr(rowptr_counter) )
192 this%rowPtr(:) = tmp_rowptr(1:rowptr_counter)
195 this%rowPtrSize = rowptr_counter
198 if (this%colIdx(l) == -1)
then
199 this%colIdx(l) = this%colIdx(l-1)
222 end subroutine sparsemat_init
226 subroutine sparsemat_final(this)
233 deallocate( this%val )
234 deallocate( this%colIdx )
236 select case( this%storage_format_id )
240 deallocate( this%rowPtr )
247 end subroutine sparsemat_final
249 function sparsemat_getval(A, i, j)
result(v)
251 integer,
intent(in) :: i, j
259 select case( a%storage_format_id )
261 do n=a%rowPtr(i),a%rowPtr(i+1)-1
262 if (a%colIdx(n) == j)
then
269 if (a%colIdx(n) == j)
then
276 end function sparsemat_getval
278 subroutine sparsemat_replceval(A, i, j, v)
281 integer,
intent(in) :: i, j
282 real(rp),
intent(in) ::v
288 select case ( a%storage_format_id )
290 do n=a%rowPtr(i),a%rowPtr(i+1)-1
291 if (a%colIdx(n) == j)
then
298 if (a%colIdx(n) == j)
then
305 end subroutine sparsemat_replceval
307 subroutine sparsemat_print(A)
311 real(rp) :: row_val(a%n)
316 write(*,*)
"-- print matrix:"
317 write(*,
'(a,i5,a,i5)')
"orginal matrix shape:", a%M,
'x', a%N
318 write(*,
'(a,i5)')
"size of compressed matrix:", a%nnz
319 select case ( a%storage_format_id )
321 write(*,*)
"rowPtr:", a%rowPtr(:)
323 write(*,*)
"colInd:", a%colIdx(:)
326 select case ( a%storage_format_id )
329 do p=1, a%rowPtrSize-1
332 row_val(a%colIdx(j1:j2-1)) = a%val(j1:j2-1)
333 write(*,*) row_val(:)
341 row_val(a%colIdx(j2)) = a%val(j2)
343 write(*,*) row_val(:)
348 end subroutine sparsemat_print
350 function sparsemat_get_storage_format_id( A )
result(id)
356 id = a%storage_format_id
358 end function sparsemat_get_storage_format_id
362 subroutine sparsemat_matmul1(A, b, c)
366 real(RP),
intent(in ) :: b(:)
367 real(RP),
intent(out) :: c(A%M)
373 select case( a%storage_format_id )
375 call sparsemat_matmul_csr_1( a%val, a%colIdx, a%rowPtr, b, c, &
376 a%M, a%N, a%nnz, a%rowPtrSize )
378 call sparsemat_matmul_ell_1( a%val, a%colIdx, b, c, &
379 a%M, a%N, a%nnz, a%col_size )
383 end subroutine sparsemat_matmul1
388 subroutine sparsemat_matmul1_2(A, b1, b2, c)
392 real(RP),
intent(in ) :: b1(:)
393 real(RP),
intent(in ) :: b2(:)
394 real(RP),
intent(out) :: c(A%M)
400 select case( a%storage_format_id )
402 call sparsemat_matmul_csr_1_2( a%val, a%colIdx, a%rowPtr, b1, b2, c, &
403 a%M, a%N, a%nnz, a%rowPtrSize )
405 call sparsemat_matmul_ell_1_2( a%val, a%colIdx, b1, b2, c, &
406 a%M, a%N, a%nnz, a%col_size )
410 end subroutine sparsemat_matmul1_2
414 subroutine sparsemat_matmul2(A, b, c)
418 real(RP),
intent(in ) :: b(:,:)
419 real(RP),
intent(out) :: c(size(b,1),A%M)
423 select case( a%storage_format_id )
425 call sparsemat_matmul_csr_2( a%val, a%colIdx, a%rowPtr, b, c, &
426 a%M, a%N, a%nnz, a%rowPtrSize,
size(b,1) )
428 call sparsemat_matmul_ell_2( a%val, a%colIdx, b, c, &
429 a%M, a%N, a%nnz, a%col_size,
size(b,1) )
433 end subroutine sparsemat_matmul2
439 subroutine sparsemat_matmul_csr_1(A, col_Ind, rowPtr, b, c, M, N, buf_size, rowPtr_size)
442 integer,
intent(in) :: M
443 integer,
intent(in) :: N
444 integer,
intent(in) :: buf_size
445 integer,
intent(in) :: rowPtr_size
446 real(RP),
intent(in) :: A(buf_size)
447 integer,
intent(in) :: col_Ind(buf_size)
448 integer,
intent(in) :: rowPtr(rowPtr_size)
449 real(RP),
intent(in ) :: b(N)
450 real(RP),
intent(out) :: c(M)
463 do p=1, rowptr_size-1
468 s = s + a(j) * b(col_ind(j))
474 end subroutine sparsemat_matmul_csr_1
479 subroutine sparsemat_matmul_csr_1_2(A, col_Ind, rowPtr, b1, b2, c, M, N, buf_size, rowPtr_size)
482 integer,
intent(in) :: M
483 integer,
intent(in) :: N
484 integer,
intent(in) :: buf_size
485 integer,
intent(in) :: rowPtr_size
486 real(RP),
intent(in) :: A(buf_size)
487 integer,
intent(in) :: col_Ind(buf_size)
488 integer,
intent(in) :: rowPtr(rowPtr_size)
489 real(RP),
intent(in ) :: b1(N)
490 real(RP),
intent(in ) :: b2(N)
491 real(RP),
intent(out) :: c(M)
504 do p=1, rowptr_size-1
509 s = s + a(j) * b1(col_ind(j)) * b2(col_ind(j))
515 end subroutine sparsemat_matmul_csr_1_2
519 subroutine sparsemat_matmul_csr_2(A, col_Ind, rowPtr, b, c, M, N, buf_size, rowPtr_size, NQ)
522 integer,
intent(in) :: M
523 integer,
intent(in) :: N
524 integer,
intent(in) :: NQ
525 integer,
intent(in) :: buf_size
526 integer,
intent(in) :: rowPtr_size
527 real(RP),
intent(in) :: A(buf_size)
528 integer,
intent(in) :: col_Ind(buf_size)
529 integer,
intent(in) :: rowPtr(rowPtr_size)
530 real(RP),
intent(in ) :: b(NQ,N)
531 real(RP),
intent(out) :: c(NQ,M)
541 do p=1, rowptr_size-1
544 c(:,p) = c(:,p) + a(j) * b(:,col_ind(j))
550 end subroutine sparsemat_matmul_csr_2
554 subroutine sparsemat_matmul_ell_1(A, col_Ind, b, c, M, N, buf_size, col_size)
557 integer,
intent(in) :: M
558 integer,
intent(in) :: N
559 integer,
intent(in) :: buf_size
560 integer,
intent(in) :: col_size
561 real(RP),
intent(in) :: A(buf_size)
562 integer,
intent(in) :: col_Ind(buf_size)
563 real(RP),
intent(in ) :: b(N)
564 real(RP),
intent(out) :: c(M)
586 c(i) = c(i) + a(j_ptr) * b(col_ind(j_ptr))
591 end subroutine sparsemat_matmul_ell_1
596 subroutine sparsemat_matmul_ell_1_2(A, col_Ind, b1, b2, c, M, N, buf_size, col_size)
599 integer,
intent(in) :: M
600 integer,
intent(in) :: N
601 integer,
intent(in) :: buf_size
602 integer,
intent(in) :: col_size
603 real(RP),
intent(in) :: A(buf_size)
604 integer,
intent(in) :: col_Ind(buf_size)
605 real(RP),
intent(in ) :: b1(N)
606 real(RP),
intent(in ) :: b2(N)
607 real(RP),
intent(out) :: c(M)
629 c(i) = c(i) + a(j_ptr) * b1(col_ind(j_ptr)) * b2(col_ind(j_ptr))
634 end subroutine sparsemat_matmul_ell_1_2
638 subroutine sparsemat_matmul_ell_2(A, col_Ind, b, c, M, N, buf_size, col_size, NQ)
641 integer,
intent(in) :: M
642 integer,
intent(in) :: N
643 integer,
intent(in) :: buf_size
644 integer,
intent(in) :: col_size
645 integer,
intent(in) :: NQ
646 real(RP),
intent(in) :: A(buf_size)
647 integer,
intent(in) :: col_Ind(buf_size)
648 real(RP),
intent(in ) :: b(NQ,N)
649 real(RP),
intent(out) :: c(NQ,M)
660 c(:,i) = c(:,i) + a(j_ptr) * b(:,col_ind(j_ptr))
665 end subroutine sparsemat_matmul_ell_2
Module common / sparsemat.
integer, parameter, public sparsemat_storage_typeid_csr
Storage format ID for CSR format.
integer, parameter, public sparsemat_storage_typeid_ell
Storage format ID for ELL format.
Derived type to manage a sparse matrix.