28 logical,
save :: matvec_impl_missing_reported = .false.
29 #ifdef HECMW_ARCH_FX64
31 integer(kind=kint),
save :: N, NP, NZIN
32 integer(kind=kint),
allocatable,
save :: index_i(:), item_i(:)
33 real(kind=
kreal),
allocatable,
save :: a_i(:)
37 integer,
parameter :: numOfBlockPerThread = 100
38 logical,
save :: isFirst = .true.
39 integer,
save :: numOfThread = 1
40 integer,
save,
allocatable :: startPos(:), endPos(:)
41 integer(kind=kint),
save :: sectorCacheSize0, sectorCacheSize1
69 type (hecmwST_local_mesh),
intent(in) :: hecMESH
70 type (hecmwST_matrix),
intent(in),
target :: hecMAT
71 #ifdef HECMW_ARCH_FX64
73 integer(kind=kint) :: i, j, k
79 if(
allocated(index_i) )
deallocate(index_i)
80 if(
allocated(item_i) )
deallocate(item_i)
81 if(
allocated(a_i) )
deallocate(a_i)
87 nzin = hecmat%indexL(n) + n + hecmat%indexU(n)
98 allocate(index_i(0:n),item_i(3*nzin),a_i(9*nzin))
108 do k=hecmat%indexL(i-1)+1,hecmat%indexL(i)
110 item_i(nzin+1) = 3*j-2
111 item_i(nzin+2) = 3*j-1
114 a_i(3*nzin-8:3*nzin) = hecmat%AL(9*k-8:9*k)
118 item_i(nzin+1) = 3*i-2
119 item_i(nzin+2) = 3*i-1
122 a_i(3*nzin-8:3*nzin) = hecmat%D(9*i-8:9*i)
125 do k=hecmat%indexU(i-1)+1,hecmat%indexU(i)
135 item_i(nzin+1) = 3*j-2
136 item_i(nzin+2) = 3*j-1
139 a_i(3*nzin-8:3*nzin) = hecmat%AU(9*k-8:9*k)
159 #ifdef HECMW_ARCH_FX64
160 if(
allocated(index_i) )
deallocate(index_i)
161 if(
allocated(item_i) )
deallocate(item_i)
162 if(
allocated(a_i) )
deallocate(a_i)
180 real(kind=
kreal),
intent(inout) :: x(:)
181 real(kind=
kreal),
intent(out) :: y(:)
182 real(kind=
kreal),
intent(inout) :: time_ax
183 real(kind=
kreal),
intent(inout),
optional :: commtime
185 real(kind=
kreal) :: start_time, end_time, tcomm
192 time_ax = time_ax + end_time - start_time - tcomm
193 if (
present(commtime)) commtime = commtime + tcomm
195 select case (matvec_impl)
198 #ifdef HECMW_ARCH_FX64
203 if (.not. matvec_impl_missing_reported)
then
204 matvec_impl_missing_reported = .true.
206 '#### MATRIXFORMAT: this build has no matvec for the selected format '// &
207 '-- running the BSR implementation'
225 type (hecmwST_local_mesh),
intent(in) :: hecMESH
226 type (hecmwST_matrix),
intent(in),
target :: hecMAT
227 real(kind=
kreal),
intent(inout) :: x(:)
228 real(kind=
kreal),
intent(out) :: y(:)
229 real(kind=
kreal),
intent(inout) :: time_ax
230 real(kind=
kreal),
intent(inout),
optional :: commtime
232 real(kind=
kreal) :: start_time, end_time
233 integer(kind=kint) :: i, j, jS, jE, in
234 real(kind=
kreal) :: yv1, yv2, yv3, x1, x2, x3
236 integer(kind=kint) :: N, NP
237 integer(kind=kint),
pointer :: indexL(:), itemL(:), indexU(:), itemU(:), indexA(:), itemA(:)
238 real(kind=
kreal),
pointer :: al(:), au(:), d(:), a(:)
241 integer(kind=kint) :: threadNum, blockNum, numOfBlock
242 integer(kind=kint) :: blockIndex
247 indexl => hecmat%indexL
248 indexu => hecmat%indexU
249 indexa => hecmat%indexA
250 iteml => hecmat%itemL
251 itemu => hecmat%itemU
252 itema => hecmat%itemA
260 if (.not. isfirst)
then
261 numofblock = numofthread * numofblockperthread
262 if (endpos(numofblock-1) .ne. n-1)
then
263 deallocate(startpos, endpos)
268 call setup_tuning_parameters(n, np, indexl, indexu)
277 if (
present(commtime)) commtime = commtime + end_time - start_time
298 yv1= yv1 + a(9*j-8)*x1 + a(9*j-7)*x2 + a(9*j-6)*x3
299 yv2= yv2 + a(9*j-5)*x1 + a(9*j-4)*x2 + a(9*j-3)*x3
300 yv3= yv3 + a(9*j-2)*x1 + a(9*j-1)*x2 + a(9*j )*x3
319 do blocknum = 0 , numofblockperthread - 1
320 blockindex = blocknum * numofthread + threadnum
321 do i = startpos(blockindex), endpos(blockindex)
325 yv1= d(9*i-8)*x1 + d(9*i-7)*x2 + d(9*i-6)*x3
326 yv2= d(9*i-5)*x1 + d(9*i-4)*x2 + d(9*i-3)*x3
327 yv3= d(9*i-2)*x1 + d(9*i-1)*x2 + d(9*i )*x3
336 yv1= yv1 + al(9*j-8)*x1 + al(9*j-7)*x2 + al(9*j-6)*x3
337 yv2= yv2 + al(9*j-5)*x1 + al(9*j-4)*x2 + al(9*j-3)*x3
338 yv3= yv3 + al(9*j-2)*x1 + al(9*j-1)*x2 + al(9*j )*x3
347 yv1= yv1 + au(9*j-8)*x1 + au(9*j-7)*x2 + au(9*j-6)*x3
348 yv2= yv2 + au(9*j-5)*x1 + au(9*j-4)*x2 + au(9*j-3)*x3
349 yv3= yv3 + au(9*j-2)*x1 + au(9*j-1)*x2 + au(9*j )*x3
366 time_ax = time_ax + end_time - start_time
380 type (hecmwST_local_mesh),
intent(in) :: hecMESH
381 type (hecmwST_matrix),
intent(in),
target :: hecMAT
382 real(kind=
kreal),
intent(inout) :: x(:)
383 real(kind=
kreal),
intent(out) :: y(:)
384 real(kind=
kreal),
intent(inout) :: time_ax
385 real(kind=
kreal),
intent(inout),
optional :: commtime
386 #ifdef HECMW_ARCH_FX64
388 real(kind=
kreal) :: start_time, end_time
389 integer(kind=kint) :: N, NP
390 integer(kind=kint) :: numOfBlock
396 if (.not. isfirst)
then
397 numofblock = numofthread * numofblockperthread
398 if (endpos(numofblock-1) .ne. n-1)
then
399 deallocate(startpos, endpos)
404 call setup_tuning_parameters(n, np, hecmat%indexL, hecmat%indexU)
407 numofblock = numofthread * numofblockperthread
413 if (
present(commtime)) commtime = commtime + end_time - start_time
419 numofblock,numofthread,startpos,endpos)
424 time_ax = time_ax + end_time - start_time
429 subroutine hecmw_matvec_33_core(N,NP,NNZ,X,Y,aval,item,idx,numOfBlock,numOfThread,startPos,endPos)
431 integer(kind=kint),
intent(in) :: N
432 integer(kind=kint),
intent(in) :: NP
433 integer(kind=kint),
intent(in) :: NNZ
434 real(kind=
kreal),
intent(in) :: x(3*np)
435 real(kind=
kreal),
intent(inout) :: y(3*n)
436 real(kind=
kreal),
intent(in) :: aval(3*nnz)
437 integer(kind=kint),
intent(in) :: item(NNZ)
438 integer(kind=kint),
intent(in) :: idx(0:N)
439 integer(kind=kint),
intent(in) :: numOfBlock
440 integer(kind=kint),
intent(in) :: numOfThread
441 integer(kind=kint),
intent(in) :: startPos(0:numOfBlock)
442 integer(kind=kint),
intent(in) :: endPos(0:numOfBlock)
443 #ifdef HECMW_ARCH_FX64
445 integer(kind=kint) :: i, j, jS, jE, in
446 real(kind=
kreal) :: yv1, yv2, yv3, x1
447 integer(kind=kint) :: threadNum, blockNum, blockIndex
454 if( numofthread > 1 )
then
461 do blocknum = 0 , numofblockperthread - 1
462 blockindex = blocknum * numofthread + threadnum
463 do i = startpos(blockindex), endpos(blockindex)
468 do j= idx(i-1)+1, idx(i)
470 yv1= yv1 + aval(3*j-2)*x1
471 yv2= yv2 + aval(3*j-1)*x1
472 yv3= yv3 + aval(3*j )*x1
489 do j= idx(i-1)+1, idx(i)
491 yv1= yv1 + aval(3*j-2)*x1
492 yv2= yv2 + aval(3*j-1)*x1
493 yv3= yv3 + aval(3*j )*x1
512 subroutine setup_tuning_parameters(N, NP, indexL, indexU)
516 integer(kind=kint),
intent(in) :: N, NP
517 integer(kind=kint),
pointer,
intent(in) :: indexL(:), indexU(:)
518 integer(kind=kint) :: i, blockNum, numOfBlock
519 integer(kind=kint) :: numOfElement, elementCount
520 real(kind=
kreal) :: numofelementperblock
523 numofblock = numofthread * numofblockperthread
524 allocate (startpos(0 : numofblock - 1), endpos(0 : numofblock - 1))
525 numofelement = n + indexl(n) + indexu(n)
526 numofelementperblock = dble(numofelement) / numofblock
529 startpos(blocknum) = 1
531 elementcount = elementcount + 1
532 elementcount = elementcount + (indexl(i) - indexl(i-1))
533 elementcount = elementcount + (indexu(i) - indexu(i-1))
534 if (elementcount > (blocknum + 1) * numofelementperblock)
then
538 blocknum = blocknum + 1
539 startpos(blocknum) = i + 1
540 if (blocknum == (numofblock - 1))
exit
547 do i= blocknum+1, numofblock-1
555 sectorcachesize0, sectorcachesize1)
556 end subroutine setup_tuning_parameters
568 real(kind=
kreal),
intent(in) :: b(:)
569 real(kind=
kreal),
intent(inout) :: x(:)
570 real(kind=
kreal),
intent(out) :: r(:)
571 real(kind=
kreal),
intent(inout) :: time_ax
572 real(kind=
kreal),
intent(inout),
optional :: commtime
574 integer(kind=kint) :: i
575 real(kind=
kreal) :: tcomm
579 if (
present(commtime)) commtime = commtime + tcomm
587 do i = 1, hecmat%N * 3
610 real(kind=
kreal),
intent(inout) :: time_ax
611 real(kind=
kreal),
intent(inout),
optional :: commtime
613 real(kind=
kreal),
allocatable :: r(:)
614 real(kind=
kreal) :: bnorm2, rnorm2
615 real(kind=
kreal) :: tcomm
617 allocate(r(hecmat%NDOF*hecmat%NP))
621 hecmat%B, hecmat%B, bnorm2, tcomm)
622 if (bnorm2 == 0.d0)
then
629 if (
present(commtime)) commtime = commtime + tcomm
644 real(kind=
kreal),
intent(inout) :: x(:)
645 real(kind=
kreal),
intent(out) :: y(:)
646 real(kind=
kreal),
intent(inout) :: commtime
648 real(kind=
kreal) :: start_time, end_time
649 integer(kind=kint) :: i, j, jj, k, kk
654 commtime = commtime + end_time - start_time
663 do i= 1, hecmesh%nn_internal * hecmesh%n_dof
675 outer:
do i= 1, hecmesh%mpc%n_mpc
676 do j= hecmesh%mpc%mpc_index(i-1) + 1, hecmesh%mpc%mpc_index(i)
677 if (hecmesh%mpc%mpc_dof(j) > 3) cycle outer
679 k = hecmesh%mpc%mpc_index(i-1) + 1
680 kk = 3 * (hecmesh%mpc%mpc_item(k) - 1) + hecmesh%mpc%mpc_dof(k)
682 do j= hecmesh%mpc%mpc_index(i-1) + 2, hecmesh%mpc%mpc_index(i)
683 jj = 3 * (hecmesh%mpc%mpc_item(j) - 1) + hecmesh%mpc%mpc_dof(j)
684 y(kk) = y(kk) - hecmesh%mpc%mpc_val(j) * x(jj)
706 real(kind=
kreal),
intent(inout) :: x(:)
707 real(kind=
kreal),
intent(inout) :: y(:)
708 real(kind=
kreal),
intent(inout) :: commtime
710 real(kind=
kreal) :: start_time, end_time
711 integer(kind=kint) :: i, j, jj, k, kk
716 commtime = commtime + end_time - start_time
725 do i= 1, hecmesh%nn_internal * hecmesh%n_dof
737 outer:
do i= 1, hecmesh%mpc%n_mpc
738 do j= hecmesh%mpc%mpc_index(i-1) + 1, hecmesh%mpc%mpc_index(i)
739 if (hecmesh%mpc%mpc_dof(j) > 3) cycle outer
741 k = hecmesh%mpc%mpc_index(i-1) + 1
742 kk = 3 * (hecmesh%mpc%mpc_item(k) - 1) + hecmesh%mpc%mpc_dof(k)
744 do j= hecmesh%mpc%mpc_index(i-1) + 2, hecmesh%mpc%mpc_index(i)
745 jj = 3 * (hecmesh%mpc%mpc_item(j) - 1) + hecmesh%mpc%mpc_dof(j)
751 y(jj) = y(jj) - hecmesh%mpc%mpc_val(j) * x(kk)
Jagged Diagonal Matrix storage for vector processors. Original code was provided by JAMSTEC.
subroutine, public hecmw_jad_matvec(hecMESH, hecMAT, X, Y, COMMtime)
integer(kind=kint) function, public hecmw_jad_is_initialized()
subroutine, public hecmw_mat_block_transpose_33(mat)
integer(kind=kint) function, public hecmw_mat_get_matvec_impl(hecMAT)
integer(kind=kint), parameter, public hecmw_matvec_impl_bsr
integer(kind=kint), parameter, public hecmw_matvec_impl_csr
subroutine, public hecmw_matresid_33(hecMESH, hecMAT, X, B, R, time_Ax, COMMtime)
subroutine, public hecmw_matvec_33(hecMESH, hecMAT, X, Y, time_Ax, COMMtime)
subroutine, public hecmw_matvec_33_setup(hecMESH, hecMAT)
subroutine hecmw_matvec_33_generic(hecMESH, hecMAT, X, Y, time_Ax, COMMtime)
subroutine hecmw_matvec_setup_33(hecMESH, hecMAT)
subroutine, public hecmw_matvec_33_teardown
subroutine hecmw_matvec_33_csr(hecMESH, hecMAT, X, Y, time_Ax, COMMtime)
subroutine, public hecmw_ttvec_33(hecMESH, X, Y, COMMtime)
subroutine hecmw_matvec_33_core(N, NP, NNZ, X, Y, aval, item, idx, numOfBlock, numOfThread, startPos, endPos)
real(kind=kreal) function, public hecmw_rel_resid_l2_33(hecMESH, hecMAT, time_Ax, COMMtime)
subroutine, public hecmw_tvec_33(hecMESH, X, Y, COMMtime)
subroutine hecmw_innerproduct_r(hecMESH, ndof, X, Y, sum, COMMtime)
subroutine, public hecmw_tuning_fx_calc_sector_cache(N, NDOF, sectorCacheSize0, sectorCacheSize1)
integer(kind=4), parameter kreal
integer(kind=kint) function hecmw_comm_get_rank()
real(kind=kreal) function hecmw_wtime()
subroutine hecmw_update_r(hecMESH, val, n, m)