FrontISTR  5.9.0
Large-scale structural analysis program with finit element method
hecmw_solver_las_66.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_66
13  public :: hecmw_matresid_66
14  public :: hecmw_rel_resid_l2_66
15 
16 contains
17 
18  !C
19  !C***
20  !C*** hecmw_matvec_66
21  !C***
22  !C
23  subroutine hecmw_matvec_66 (hecMESH, hecMAT, X, Y, time_Ax, COMMtime)
24  use hecmw_util
25  use m_hecmw_comm_f
27  use hecmw_jad_type
28  use hecmw_tuning_fx
29  !$ use omp_lib
30 
31  implicit none
32  type (hecmwst_local_mesh), intent(in) :: hecmesh
33  type (hecmwst_matrix), intent(in), target :: hecmat
34  real(kind=kreal), intent(in) :: x(:)
35  real(kind=kreal), intent(out) :: y(:)
36  real(kind=kreal), intent(inout) :: time_ax
37  real(kind=kreal), intent(inout), optional :: commtime
38 
39  real(kind=kreal) :: start_time, end_time, tcomm
40  integer(kind=kint) :: i, j, js, je, in
41  real(kind=kreal) :: yv1, yv2, yv3, x1, x2, x3
42  real(kind=kreal) :: yv4, yv5, yv6, x4, x5, x6
43 
44  integer(kind=kint) :: n, np
45  integer(kind=kint), pointer :: indexl(:), iteml(:), indexu(:), itemu(:), indexa(:), itema(:)
46  real(kind=kreal), pointer :: al(:), au(:), d(:), a(:)
47 
48  ! added for tuning >>>
49  integer, parameter :: numofblockperthread = 100
50  logical, save :: isfirst = .true.
51  integer, save :: numofthread = 1
52  integer, save, allocatable :: startpos(:), endpos(:)
53  integer(kind=kint), save :: sectorcachesize0, sectorcachesize1
54  integer(kind=kint) :: threadnum, blocknum, numofblock
55  integer(kind=kint) :: numofelement, elementcount, blockindex
56  real(kind=kreal) :: numofelementperblock
57  ! <<< added for tuning
58 
59  if (hecmw_jad_is_initialized().ne.0) then
60  tcomm = 0.d0
61  start_time = hecmw_wtime()
62  call hecmw_jad_matvec(hecmesh, hecmat, x, y, tcomm)
63  end_time = hecmw_wtime()
64  time_ax = time_ax + end_time - start_time - tcomm
65  if (present(commtime)) commtime = commtime + tcomm
66  else
67 
68  n = hecmat%N
69  np = hecmat%NP
70  indexl => hecmat%indexL
71  indexu => hecmat%indexU
72  indexa => hecmat%indexA
73  iteml => hecmat%itemL
74  itemu => hecmat%itemU
75  itema => hecmat%itemA
76  al => hecmat%AL
77  au => hecmat%AU
78  d => hecmat%D
79  a => hecmat%A
80 
81  ! added for tuning >>>
82 #ifndef _OPENACC
83  if (isfirst .eqv. .true.) then
84  !$ numOfThread = omp_get_max_threads()
85  numofblock = numofthread * numofblockperthread
86  allocate (startpos(0 : numofblock - 1), endpos(0 : numofblock - 1))
87  numofelement = n + indexl(n) + indexu(n)
88  numofelementperblock = dble(numofelement) / numofblock
89  blocknum = 0
90  elementcount = 0
91  startpos(blocknum) = 1
92  do i= 1, n
93  elementcount = elementcount + 1
94  elementcount = elementcount + (indexl(i) - indexl(i-1))
95  elementcount = elementcount + (indexu(i) - indexu(i-1))
96  if (elementcount > (blocknum + 1) * numofelementperblock) then
97  endpos(blocknum) = i
98  ! write(9000+hecMESH%my_rank,*) mod(blockNum, numOfThread), &
99  ! startPos(blockNum), endPos(blockNum)
100  blocknum = blocknum + 1
101  startpos(blocknum) = i + 1
102  if (blocknum == (numofblock - 1)) exit
103  endif
104  enddo
105  endpos(blocknum) = n
106  ! write(9000+hecMESH%my_rank,*) mod(blockNum, numOfThread), &
107  ! startPos(blockNum), endPos(blockNum)
108  ! for irregular data
109  do i= blocknum+1, numofblock-1
110  startpos(i) = n
111  endpos(i) = n-1
112  ! write(9000+hecMESH%my_rank,*) mod(i, numOfThread), &
113  ! startPos(i), endPos(i)
114  end do
115 
117  sectorcachesize0, sectorcachesize1)
118 
119  isfirst = .false.
120  endif
121 #endif
122  ! <<< added for tuning
123 
124  start_time= hecmw_wtime()
125  call hecmw_update_r (hecmesh, x, np, 6)
126  end_time= hecmw_wtime()
127  if (present(commtime)) commtime = commtime + end_time - start_time
128 
129  start_time = hecmw_wtime()
130 
131 #ifdef _OPENACC
132  !$acc kernels
133  !$acc loop independent
134  do i = 1, n
135  x1= x(6*i-5)
136  x2= x(6*i-4)
137  x3= x(6*i-3)
138  x4= x(6*i-2)
139  x5= x(6*i-1)
140  x6= x(6*i )
141  yv1= 0
142  yv2= 0
143  yv3= 0
144  yv4= 0
145  yv5= 0
146  yv6= 0
147  js= indexa(i-1) + 1
148  je= indexa(i)
149  do j= js, je
150  in = itema(j)
151  x1= x(6*in-5)
152  x2= x(6*in-4)
153  x3= x(6*in-3)
154  x4= x(6*in-2)
155  x5= x(6*in-1)
156  x6= x(6*in )
157  yv1= yv1 + a(36*j-35)*x1 + a(36*j-34)*x2 + a(36*j-33)*x3 + a(36*j-32)*x4 + a(36*j-31)*x5 + a(36*j-30)*x6
158  yv2= yv2 + a(36*j-29)*x1 + a(36*j-28)*x2 + a(36*j-27)*x3 + a(36*j-26)*x4 + a(36*j-25)*x5 + a(36*j-24)*x6
159  yv3= yv3 + a(36*j-23)*x1 + a(36*j-22)*x2 + a(36*j-21)*x3 + a(36*j-20)*x4 + a(36*j-19)*x5 + a(36*j-18)*x6
160  yv4= yv4 + a(36*j-17)*x1 + a(36*j-16)*x2 + a(36*j-15)*x3 + a(36*j-14)*x4 + a(36*j-13)*x5 + a(36*j-12)*x6
161  yv5= yv5 + a(36*j-11)*x1 + a(36*j-10)*x2 + a(36*j-9 )*x3 + a(36*j-8 )*x4 + a(36*j-7 )*x5 + a(36*j-6 )*x6
162  yv6= yv6 + a(36*j-5 )*x1 + a(36*j-4 )*x2 + a(36*j-3 )*x3 + a(36*j-2 )*x4 + a(36*j-1 )*x5 + a(36*j )*x6
163  enddo
164  y(6*i-5)= yv1
165  y(6*i-4)= yv2
166  y(6*i-3)= yv3
167  y(6*i-2)= yv4
168  y(6*i-1)= yv5
169  y(6*i )= yv6
170  enddo
171  !$acc end kernels
172 #else
173  !call fapp_start("loopInMatvec66", 1, 0)
174  !call start_collection("loopInMatvec66")
175 
176  !OCL CACHE_SECTOR_SIZE(sectorCacheSize0,sectorCacheSize1)
177  !OCL CACHE_SUBSECTOR_ASSIGN(X)
178 
179  !$OMP PARALLEL DEFAULT(NONE) &
180  !$OMP&PRIVATE(i,X1,X2,X3,X4,X5,X6,YV1,YV2,YV3,YV4,YV5,YV6,jS,jE,j,in,threadNum,blockNum,blockIndex) &
181  !$OMP&SHARED(D,AL,AU,indexL,itemL,indexU,itemU,X,Y,startPos,endPos,numOfThread)
182  threadnum = 0
183  !$ threadNum = omp_get_thread_num()
184  do blocknum = 0 , numofblockperthread - 1
185  blockindex = blocknum * numofthread + threadnum
186  do i = startpos(blockindex), endpos(blockindex)
187  x1= x(6*i-5)
188  x2= x(6*i-4)
189  x3= x(6*i-3)
190  x4= x(6*i-2)
191  x5= x(6*i-1)
192  x6= x(6*i )
193  yv1= d(36*i-35)*x1 + d(36*i-34)*x2 + d(36*i-33)*x3 + d(36*i-32)*x4 + d(36*i-31)*x5 + d(36*i-30)*x6
194  yv2= d(36*i-29)*x1 + d(36*i-28)*x2 + d(36*i-27)*x3 + d(36*i-26)*x4 + d(36*i-25)*x5 + d(36*i-24)*x6
195  yv3= d(36*i-23)*x1 + d(36*i-22)*x2 + d(36*i-21)*x3 + d(36*i-20)*x4 + d(36*i-19)*x5 + d(36*i-18)*x6
196  yv4= d(36*i-17)*x1 + d(36*i-16)*x2 + d(36*i-15)*x3 + d(36*i-14)*x4 + d(36*i-13)*x5 + d(36*i-12)*x6
197  yv5= d(36*i-11)*x1 + d(36*i-10)*x2 + d(36*i-9 )*x3 + d(36*i-8 )*x4 + d(36*i-7 )*x5 + d(36*i-6 )*x6
198  yv6= d(36*i-5 )*x1 + d(36*i-4 )*x2 + d(36*i-3 )*x3 + d(36*i-2 )*x4 + d(36*i-1 )*x5 + d(36*i )*x6
199 
200  js= indexl(i-1) + 1
201  je= indexl(i )
202  do j= js, je
203  in = iteml(j)
204  x1= x(6*in-5)
205  x2= x(6*in-4)
206  x3= x(6*in-3)
207  x4= x(6*in-2)
208  x5= x(6*in-1)
209  x6= x(6*in )
210  yv1= yv1 + al(36*j-35)*x1 + al(36*j-34)*x2 + al(36*j-33)*x3 + al(36*j-32)*x4 + al(36*j-31)*x5 + al(36*j-30)*x6
211  yv2= yv2 + al(36*j-29)*x1 + al(36*j-28)*x2 + al(36*j-27)*x3 + al(36*j-26)*x4 + al(36*j-25)*x5 + al(36*j-24)*x6
212  yv3= yv3 + al(36*j-23)*x1 + al(36*j-22)*x2 + al(36*j-21)*x3 + al(36*j-20)*x4 + al(36*j-19)*x5 + al(36*j-18)*x6
213  yv4= yv4 + al(36*j-17)*x1 + al(36*j-16)*x2 + al(36*j-15)*x3 + al(36*j-14)*x4 + al(36*j-13)*x5 + al(36*j-12)*x6
214  yv5= yv5 + al(36*j-11)*x1 + al(36*j-10)*x2 + al(36*j-9 )*x3 + al(36*j-8 )*x4 + al(36*j-7 )*x5 + al(36*j-6 )*x6
215  yv6= yv6 + al(36*j-5 )*x1 + al(36*j-4 )*x2 + al(36*j-3 )*x3 + al(36*j-2 )*x4 + al(36*j-1 )*x5 + al(36*j )*x6
216  enddo
217  js= indexu(i-1) + 1
218  je= indexu(i )
219  do j= js, je
220  in = itemu(j)
221  x1= x(6*in-5)
222  x2= x(6*in-4)
223  x3= x(6*in-3)
224  x4= x(6*in-2)
225  x5= x(6*in-1)
226  x6= x(6*in )
227  yv1= yv1 + au(36*j-35)*x1 + au(36*j-34)*x2 + au(36*j-33)*x3 + au(36*j-32)*x4 + au(36*j-31)*x5 + au(36*j-30)*x6
228  yv2= yv2 + au(36*j-29)*x1 + au(36*j-28)*x2 + au(36*j-27)*x3 + au(36*j-26)*x4 + au(36*j-25)*x5 + au(36*j-24)*x6
229  yv3= yv3 + au(36*j-23)*x1 + au(36*j-22)*x2 + au(36*j-21)*x3 + au(36*j-20)*x4 + au(36*j-19)*x5 + au(36*j-18)*x6
230  yv4= yv4 + au(36*j-17)*x1 + au(36*j-16)*x2 + au(36*j-15)*x3 + au(36*j-14)*x4 + au(36*j-13)*x5 + au(36*j-12)*x6
231  yv5= yv5 + au(36*j-11)*x1 + au(36*j-10)*x2 + au(36*j-9 )*x3 + au(36*j-8 )*x4 + au(36*j-7 )*x5 + au(36*j-6 )*x6
232  yv6= yv6 + au(36*j-5 )*x1 + au(36*j-4 )*x2 + au(36*j-3 )*x3 + au(36*j-2 )*x4 + au(36*j-1 )*x5 + au(36*j )*x6
233  enddo
234  y(6*i-5)= yv1
235  y(6*i-4)= yv2
236  y(6*i-3)= yv3
237  y(6*i-2)= yv4
238  y(6*i-1)= yv5
239  y(6*i )= yv6
240  enddo
241  enddo
242  !$OMP END PARALLEL
243 
244  !OCL END_CACHE_SUBSECTOR
245  !OCL END_CACHE_SECTOR_SIZE
246 
247  !call stop_collection("loopInMatvec66")
248  !call fapp_stop("loopInMatvec66", 1, 0)
249 #endif
250 
251  end_time = hecmw_wtime()
252  time_ax = time_ax + end_time - start_time
253 
254  endif
255  end subroutine hecmw_matvec_66
256 
257  !C
258  !C***
259  !C*** hecmw_matresid_66
260  !C***
261  !C
262  subroutine hecmw_matresid_66 (hecMESH, hecMAT, X, B, R, time_Ax, COMMtime)
263  use hecmw_util
264  implicit none
265  type (hecmwst_local_mesh), intent(in) :: hecmesh
266  type (hecmwst_matrix), intent(in) :: hecmat
267  real(kind=kreal), intent(in) :: x(:), b(:)
268  real(kind=kreal), intent(out) :: r(:)
269  real(kind=kreal), intent(inout) :: time_ax
270  real(kind=kreal), intent(inout), optional :: commtime
271 
272  integer(kind=kint) :: i
273  real(kind=kreal) :: tcomm
274 
275  tcomm = 0.d0
276  call hecmw_matvec_66 (hecmesh, hecmat, x, r, time_ax, tcomm)
277  if (present(commtime)) commtime = commtime + tcomm
278 #ifdef _OPENACC
279  !$acc kernels
280  !$acc loop independent
281 #endif
282  do i = 1, hecmat%N * 6
283  r(i) = b(i) - r(i)
284  enddo
285 #ifdef _OPENACC
286  !$acc end kernels
287 #endif
288 
289  end subroutine hecmw_matresid_66
290 
291  !C
292  !C***
293  !C*** hecmw_rel_resid_L2_66
294  !C***
295  !C
296  function hecmw_rel_resid_l2_66 (hecMESH, hecMAT, time_Ax, COMMtime)
297  use hecmw_util
299  implicit none
300  real(kind=kreal) :: hecmw_rel_resid_l2_66
301  type ( hecmwst_local_mesh ), intent(in) :: hecmesh
302  type ( hecmwst_matrix ), intent(in) :: hecmat
303  real(kind=kreal), intent(inout) :: time_ax
304  real(kind=kreal), intent(inout), optional :: commtime
305 
306  real(kind=kreal), allocatable :: r(:)
307  real(kind=kreal) :: bnorm2, rnorm2
308  real(kind=kreal) :: tcomm
309 
310  allocate(r(hecmat%NDOF*hecmat%NP))
311 
312  tcomm = 0.d0
313  call hecmw_innerproduct_r(hecmesh, hecmat%NDOF, &
314  hecmat%B, hecmat%B, bnorm2, tcomm)
315  if (bnorm2 == 0.d0) then
316  bnorm2 = 1.d0
317  endif
318  call hecmw_matresid_66(hecmesh, hecmat, hecmat%X, hecmat%B, r, time_ax, tcomm)
319  call hecmw_innerproduct_r(hecmesh, hecmat%NDOF, r, r, rnorm2, tcomm)
320  hecmw_rel_resid_l2_66 = sqrt(rnorm2 / bnorm2)
321 
322  if (present(commtime)) commtime = commtime + tcomm
323 
324  deallocate(r)
325  end function hecmw_rel_resid_l2_66
326 
327 end module hecmw_solver_las_66
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
subroutine, public hecmw_matresid_66(hecMESH, hecMAT, X, B, R, time_Ax, COMMtime)
real(kind=kreal) function, public hecmw_rel_resid_l2_66(hecMESH, hecMAT, time_Ax, COMMtime)
subroutine, public hecmw_matvec_66(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)