FrontISTR  6.0.0
Large-scale structural analysis program with finit element method
hecmw_solver_las_11.F90
Go to the documentation of this file.
1 !-------------------------------------------------------------------------------
2 ! Copyright (c) 2019 FrontISTR Commons
3 ! This software is released under the MIT License, see LICENSE.txt
4 !-------------------------------------------------------------------------------
5 
7  use hecmw_util
8  implicit none
9 
10  private
11 
12  public :: hecmw_matvec_11
13  public :: hecmw_matresid_11
14  public :: hecmw_rel_resid_l2_11
15 
16 contains
17 
18  !C
19  !C***
20  !C*** hecmw_matvec_11
21  !C***
22  !C
23  subroutine hecmw_matvec_11 (hecMESH, hecMAT, X, Y, time_Ax, COMMtime)
24  use hecmw_util
25  use m_hecmw_comm_f
26  use hecmw_jad_type
27  use hecmw_tuning_fx
28  !$ use omp_lib
29 
30  implicit none
31  type (hecmwst_local_mesh), intent(in) :: hecmesh
32  type (hecmwst_matrix), intent(in), target :: hecmat
33  real(kind=kreal), intent(inout) :: x(:)
34  real(kind=kreal), intent(out) :: y(:)
35  real(kind=kreal), intent(inout) :: time_ax
36  real(kind=kreal), intent(inout), optional :: commtime
37 
38  real(kind=kreal) :: start_time, end_time, tcomm
39  integer(kind=kint) :: i, j, js, je, in
40  real(kind=kreal) :: yv
41 
42  integer(kind=kint) :: n, np
43  integer(kind=kint), pointer :: indexl(:), iteml(:), indexu(:), itemu(:), indexa(:), itema(:)
44  real(kind=kreal), pointer :: al(:), au(:), d(:), a(:)
45 
46  ! added for tuning >>>
47  integer, parameter :: numofblockperthread = 100
48  logical, save :: isfirst = .true.
49  integer, save :: numofthread = 1
50  integer, save, allocatable :: startpos(:), endpos(:)
51  integer(kind=kint), save :: sectorcachesize0, sectorcachesize1
52  integer(kind=kint) :: threadnum, blocknum, numofblock
53  integer(kind=kint) :: numofelement, elementcount, blockindex
54  real(kind=kreal) :: numofelementperblock
55  ! <<< added for tuning
56 
57  if (hecmw_jad_is_initialized().ne.0) then
58  tcomm = 0.d0
59  start_time = hecmw_wtime()
60  call hecmw_jad_matvec(hecmesh, hecmat, x, y, tcomm)
61  end_time = hecmw_wtime()
62  time_ax = time_ax + end_time - start_time - tcomm
63  if (present(commtime)) commtime = commtime + tcomm
64  else
65 
66  n = hecmat%N
67  np = hecmat%NP
68  indexl => hecmat%indexL
69  indexu => hecmat%indexU
70  indexa => hecmat%indexA
71  iteml => hecmat%itemL
72  itemu => hecmat%itemU
73  itema => hecmat%itemA
74  al => hecmat%AL
75  au => hecmat%AU
76  d => hecmat%D
77  a => hecmat%A
78 
79  ! added for tuning >>>
80 #ifndef _OPENACC
81  if (.not. isfirst) then
82  numofblock = numofthread * numofblockperthread
83  if (endpos(numofblock-1) .ne. n-1) then
84  deallocate(startpos, endpos)
85  isfirst = .true.
86  endif
87  endif
88  if (isfirst) then
89  !$ numOfThread = omp_get_max_threads()
90  numofblock = numofthread * numofblockperthread
91  allocate (startpos(0 : numofblock - 1), endpos(0 : numofblock - 1))
92  numofelement = n + indexl(n) + indexu(n)
93  numofelementperblock = dble(numofelement) / numofblock
94  blocknum = 0
95  elementcount = 0
96  startpos(blocknum) = 1
97  do i= 1, n
98  elementcount = elementcount + 1
99  elementcount = elementcount + (indexl(i) - indexl(i-1))
100  elementcount = elementcount + (indexu(i) - indexu(i-1))
101  if (elementcount > (blocknum + 1) * numofelementperblock) then
102  endpos(blocknum) = i
103  blocknum = blocknum + 1
104  startpos(blocknum) = i + 1
105  if (blocknum == (numofblock - 1)) exit
106  endif
107  enddo
108  endpos(blocknum) = n
109  ! for irregular data
110  do i= blocknum+1, numofblock-1
111  startpos(i) = n
112  endpos(i) = n-1
113  end do
114 
116  sectorcachesize0, sectorcachesize1)
117 
118  isfirst = .false.
119  endif
120 #endif
121  ! <<< added for tuning
122 
123  start_time= hecmw_wtime()
124  call hecmw_update_r (hecmesh, x, np, 1)
125  end_time= hecmw_wtime()
126  if (present(commtime)) commtime = commtime + end_time - start_time
127 
128  start_time = hecmw_wtime()
129 
130 #ifdef _OPENACC
131  !$acc kernels
132  !$acc loop independent
133  do i = 1, n
134  yv= 0
135  js= indexa(i-1) + 1
136  je= indexa(i)
137  do j= js, je
138  in= itema(j)
139  yv= yv + a(j) * x(in)
140  enddo
141  y(i)= yv
142  enddo
143  !$acc end kernels
144 #else
145  !OCL CACHE_SECTOR_SIZE(sectorCacheSize0,sectorCacheSize1)
146  !OCL CACHE_SUBSECTOR_ASSIGN(X)
147 
148  !$OMP PARALLEL DEFAULT(NONE) &
149  !$OMP&PRIVATE(i,YV,jS,jE,j,in,threadNum,blockNum,blockIndex) &
150  !$OMP&SHARED(D,AL,AU,indexL,itemL,indexU,itemU,X,Y,startPos,endPos,numOfThread,N)
151  threadnum = 0
152  !$ threadNum = omp_get_thread_num()
153  do blocknum = 0 , numofblockperthread - 1
154  blockindex = blocknum * numofthread + threadnum
155  do i = startpos(blockindex), endpos(blockindex)
156  yv= d(i) * x(i)
157 
158  js= indexl(i-1) + 1
159  je= indexl(i )
160  do j= js, je
161  in= iteml(j)
162  yv= yv + al(j) * x(in)
163  enddo
164  js= indexu(i-1) + 1
165  je= indexu(i )
166  do j= js, je
167  in= itemu(j)
168  yv= yv + au(j) * x(in)
169  enddo
170  y(i)= yv
171  enddo
172  enddo
173  !$OMP END PARALLEL
174 
175  !OCL END_CACHE_SUBSECTOR
176  !OCL END_CACHE_SECTOR_SIZE
177 #endif
178 
179  end_time = hecmw_wtime()
180  time_ax = time_ax + end_time - start_time
181 
182  endif
183  end subroutine hecmw_matvec_11
184 
185  !C
186  !C***
187  !C*** hecmw_matresid_11
188  !C***
189  !C
190  subroutine hecmw_matresid_11 (hecMESH, hecMAT, X, B, R, time_Ax, COMMtime)
191  use hecmw_util
192  implicit none
193  type (hecmwst_local_mesh), intent(in) :: hecmesh
194  type (hecmwst_matrix), intent(in) :: hecmat
195  real(kind=kreal), intent(in) :: b(:)
196  real(kind=kreal), intent(inout) :: x(:)
197  real(kind=kreal), intent(out) :: r(:)
198  real(kind=kreal), intent(inout) :: time_ax
199  real(kind=kreal), intent(inout), optional :: commtime
200 
201  integer(kind=kint) :: i
202  real(kind=kreal) :: tcomm
203 
204  tcomm = 0.d0
205  call hecmw_matvec_11 (hecmesh, hecmat, x, r, time_ax, tcomm)
206  if (present(commtime)) commtime = commtime + tcomm
207 #ifdef _OPENACC
208  !$acc kernels
209  !$acc loop independent
210 #else
211  !$omp parallel default(none),private(i),shared(hecMAT,R,B)
212  !$omp do
213 #endif
214  do i = 1, hecmat%N
215  r(i) = b(i) - r(i)
216  enddo
217 #ifdef _OPENACC
218  !$acc end kernels
219 #else
220  !$omp end do
221  !$omp end parallel
222 #endif
223  end subroutine hecmw_matresid_11
224 
225  !C
226  !C***
227  !C*** hecmw_rel_resid_L2_11
228  !C***
229  !C
230  function hecmw_rel_resid_l2_11 (hecMESH, hecMAT, time_Ax, COMMtime)
231  use hecmw_util
233  implicit none
234  real(kind=kreal) :: hecmw_rel_resid_l2_11
235  type ( hecmwst_local_mesh ), intent(in) :: hecmesh
236  type ( hecmwst_matrix ), intent(in) :: hecmat
237  real(kind=kreal), intent(inout) :: time_ax
238  real(kind=kreal), intent(inout), optional :: commtime
239 
240  real(kind=kreal), allocatable :: r(:)
241  real(kind=kreal) :: bnorm2, rnorm2
242  real(kind=kreal) :: tcomm
243 
244  allocate(r(hecmat%NDOF*hecmat%NP))
245 
246  tcomm = 0.d0
247  call hecmw_innerproduct_r(hecmesh, hecmat%NDOF, &
248  hecmat%B, hecmat%B, bnorm2, tcomm)
249  if (bnorm2 == 0.d0) then
250  bnorm2 = 1.d0
251  endif
252  call hecmw_matresid_11(hecmesh, hecmat, hecmat%X, hecmat%B, r, time_ax, tcomm)
253  call hecmw_innerproduct_r(hecmesh, hecmat%NDOF, r, r, rnorm2, tcomm)
254  hecmw_rel_resid_l2_11 = sqrt(rnorm2 / bnorm2)
255 
256  if (present(commtime)) commtime = commtime + tcomm
257 
258  deallocate(r)
259  end function hecmw_rel_resid_l2_11
260 
261 end module hecmw_solver_las_11
Jagged Diagonal Matrix storage for vector processors. Original code was provided by JAMSTEC.
Definition: hecmw_jadm.f90:8
subroutine, public hecmw_jad_matvec(hecMESH, hecMAT, X, Y, COMMtime)
Definition: hecmw_jadm.f90:61
integer(kind=kint) function, public hecmw_jad_is_initialized()
Definition: hecmw_jadm.f90:56
real(kind=kreal) function, public hecmw_rel_resid_l2_11(hecMESH, hecMAT, time_Ax, COMMtime)
subroutine, public hecmw_matresid_11(hecMESH, hecMAT, X, B, R, time_Ax, COMMtime)
subroutine, public hecmw_matvec_11(hecMESH, hecMAT, X, Y, time_Ax, COMMtime)
subroutine hecmw_innerproduct_r(hecMESH, ndof, X, Y, sum, COMMtime)
subroutine, public hecmw_tuning_fx_calc_sector_cache(N, NDOF, sectorCacheSize0, sectorCacheSize1)
I/O and Utility.
Definition: hecmw_util_f.F90:7
integer(kind=4), parameter kreal
real(kind=kreal) function hecmw_wtime()
subroutine hecmw_update_r(hecMESH, val, n, m)