FrontISTR  5.9.0
Large-scale structural analysis program with finit element method
hecmw_solver_las_44.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_44
13  public :: hecmw_matresid_44
14  public :: hecmw_rel_resid_l2_44
15 
16 contains
17 
18  !C
19  !C***
20  !C*** hecmw_matvec_44
21  !C***
22  !C
23  subroutine hecmw_matvec_44 (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(in) :: 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) :: yv1, yv2, yv3, yv4, x1, x2, x3, x4
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  ! write(9000+hecMESH%my_rank,*) mod(blockNum, numOfThread), &
104  ! startPos(blockNum), endPos(blockNum)
105  blocknum = blocknum + 1
106  startpos(blocknum) = i + 1
107  if (blocknum == (numofblock - 1)) exit
108  endif
109  enddo
110  endpos(blocknum) = n
111  ! write(9000+hecMESH%my_rank,*) mod(blockNum, numOfThread), &
112  ! startPos(blockNum), endPos(blockNum)
113  ! for irregular data
114  do i= blocknum+1, numofblock-1
115  startpos(i) = n
116  endpos(i) = n-1
117  ! write(9000+hecMESH%my_rank,*) mod(i, numOfThread), &
118  ! startPos(i), endPos(i)
119  end do
120 
122  sectorcachesize0, sectorcachesize1)
123 
124  isfirst = .false.
125  endif
126 #endif
127  ! <<< added for tuning
128 
129  start_time= hecmw_wtime()
130 
131  call hecmw_update_r (hecmesh, x, np, 4)
132 
133  ! endif
134  end_time= hecmw_wtime()
135  if (present(commtime)) commtime = commtime + end_time - start_time
136 
137  start_time = hecmw_wtime()
138 
139 #ifdef _OPENACC
140  !$acc kernels
141  !$acc loop independent
142  do i = 1, n
143  x1= x(4*i-3)
144  x2= x(4*i-2)
145  x3= x(4*i-1)
146  x4= x(4*i )
147  yv1= 0
148  yv2= 0
149  yv3= 0
150  yv4= 0
151  js= indexa(i-1) + 1
152  je= indexa(i)
153  do j= js, je
154  in = itema(j)
155  x1= x(4*in-3)
156  x2= x(4*in-2)
157  x3= x(4*in-1)
158  x4= x(4*in )
159  yv1= yv1 + a(16*j-15)*x1 + a(16*j-14)*x2 + a(16*j-13)*x3 + a(16*j-12)*x4
160  yv2= yv2 + a(16*j-11)*x1 + a(16*j-10)*x2 + a(16*j- 9)*x3 + a(16*j- 8)*x4
161  yv3= yv3 + a(16*j- 7)*x1 + a(16*j- 6)*x2 + a(16*j- 5)*x3 + a(16*j- 4)*x4
162  yv4= yv4 + a(16*j- 3)*x1 + a(16*j- 2)*x2 + a(16*j- 1)*x3 + a(16*j )*x4
163  enddo
164  y(4*i-3)= yv1
165  y(4*i-2)= yv2
166  y(4*i-1)= yv3
167  y(4*i )= yv4
168  enddo
169  !$acc end kernels
170 #else
171  !call fapp_start("loopInMatvec44", 1, 0)
172  !call start_collection("loopInMatvec44")
173 
174  !OCL CACHE_SECTOR_SIZE(sectorCacheSize0,sectorCacheSize1)
175  !OCL CACHE_SUBSECTOR_ASSIGN(X)
176 
177  !$OMP PARALLEL DEFAULT(NONE) &
178  !$OMP&PRIVATE(i,X1,X2,X3,X4,YV1,YV2,YV3,YV4,jS,jE,j,in,threadNum,blockNum,blockIndex) &
179  !$OMP&SHARED(D,AL,AU,indexL,itemL,indexU,itemU,X,Y,startPos,endPos,numOfThread,N)
180  threadnum = 0
181  !$ threadNum = omp_get_thread_num()
182  do blocknum = 0 , numofblockperthread - 1
183  blockindex = blocknum * numofthread + threadnum
184  do i = startpos(blockindex), endpos(blockindex)
185  x1= x(4*i-3)
186  x2= x(4*i-2)
187  x3= x(4*i-1)
188  x4= x(4*i )
189  yv1= d(16*i-15)*x1 + d(16*i-14)*x2 + d(16*i-13)*x3 + d(16*i-12)*x4
190  yv2= d(16*i-11)*x1 + d(16*i-10)*x2 + d(16*i- 9)*x3 + d(16*i- 8)*x4
191  yv3= d(16*i- 7)*x1 + d(16*i- 6)*x2 + d(16*i- 5)*x3 + d(16*i- 4)*x4
192  yv4= d(16*i- 3)*x1 + d(16*i- 2)*x2 + d(16*i- 1)*x3 + d(16*i )*x4
193 
194  js= indexl(i-1) + 1
195  je= indexl(i )
196  do j= js, je
197  in = iteml(j)
198  x1= x(4*in-3)
199  x2= x(4*in-2)
200  x3= x(4*in-1)
201  x4= x(4*in )
202  yv1= yv1 + al(16*j-15)*x1 + al(16*j-14)*x2 + al(16*j-13)*x3 + al(16*j-12)*x4
203  yv2= yv2 + al(16*j-11)*x1 + al(16*j-10)*x2 + al(16*j- 9)*x3 + al(16*j- 8)*x4
204  yv3= yv3 + al(16*j- 7)*x1 + al(16*j- 6)*x2 + al(16*j- 5)*x3 + al(16*j- 4)*x4
205  yv4= yv4 + al(16*j- 3)*x1 + al(16*j- 2)*x2 + al(16*j- 1)*x3 + al(16*j )*x4
206  enddo
207  js= indexu(i-1) + 1
208  je= indexu(i )
209  do j= js, je
210  in = itemu(j)
211  x1= x(4*in-3)
212  x2= x(4*in-2)
213  x3= x(4*in-1)
214  x4= x(4*in )
215  yv1= yv1 + au(16*j-15)*x1 + au(16*j-14)*x2 + au(16*j-13)*x3 + au(16*j-12)*x4
216  yv2= yv2 + au(16*j-11)*x1 + au(16*j-10)*x2 + au(16*j- 9)*x3 + au(16*j- 8)*x4
217  yv3= yv3 + au(16*j- 7)*x1 + au(16*j- 6)*x2 + au(16*j- 5)*x3 + au(16*j- 4)*x4
218  yv4= yv4 + au(16*j- 3)*x1 + au(16*j- 2)*x2 + au(16*j- 1)*x3 + au(16*j )*x4
219  enddo
220  y(4*i-3)= yv1
221  y(4*i-2)= yv2
222  y(4*i-1)= yv3
223  y(4*i )= yv4
224  enddo
225  enddo
226  !$OMP END PARALLEL
227 
228  !OCL END_CACHE_SUBSECTOR
229  !OCL END_CACHE_SECTOR_SIZE
230 
231  !call stop_collection("loopInMatvec44")
232  !call fapp_stop("loopInMatvec44", 1, 0)
233 #endif
234 
235  end_time = hecmw_wtime()
236  time_ax = time_ax + end_time - start_time
237 
238  endif
239  end subroutine hecmw_matvec_44
240 
241  !C
242  !C***
243  !C*** hecmw_matresid_44
244  !C***
245  !C
246  subroutine hecmw_matresid_44 (hecMESH, hecMAT, X, B, R, time_Ax, COMMtime)
247  use hecmw_util
248  implicit none
249  type (hecmwst_local_mesh), intent(in) :: hecmesh
250  type (hecmwst_matrix), intent(in) :: hecmat
251  real(kind=kreal), intent(in) :: x(:), b(:)
252  real(kind=kreal), intent(out) :: r(:)
253  real(kind=kreal), intent(inout) :: time_ax
254  real(kind=kreal), intent(inout), optional :: commtime
255 
256  integer(kind=kint) :: i
257  real(kind=kreal) :: tcomm
258 
259  tcomm = 0.d0
260  call hecmw_matvec_44 (hecmesh, hecmat, x, r, time_ax, tcomm)
261  if (present(commtime)) commtime = commtime + tcomm
262 #ifdef _OPENACC
263  !$acc kernels
264  !$acc loop independent
265 #else
266  !$omp parallel default(none),private(i),shared(hecMAT,R,B)
267  !$omp do
268 #endif
269  do i = 1, hecmat%N * 4
270  r(i) = b(i) - r(i)
271  enddo
272 #ifdef _OPENACC
273  !$acc end kernels
274 #else
275  !$omp end do
276  !$omp end parallel
277 #endif
278  end subroutine hecmw_matresid_44
279 
280  !C
281  !C***
282  !C*** hecmw_rel_resid_L2_44
283  !C***
284  !C
285  function hecmw_rel_resid_l2_44 (hecMESH, hecMAT, time_Ax, COMMtime)
286  use hecmw_util
288  implicit none
289  real(kind=kreal) :: hecmw_rel_resid_l2_44
290  type ( hecmwst_local_mesh ), intent(in) :: hecmesh
291  type ( hecmwst_matrix ), intent(in) :: hecmat
292  real(kind=kreal), intent(inout) :: time_ax
293  real(kind=kreal), intent(inout), optional :: commtime
294 
295  real(kind=kreal), allocatable :: r(:)
296  real(kind=kreal) :: bnorm2, rnorm2
297  real(kind=kreal) :: tcomm
298 
299  allocate(r(hecmat%NDOF*hecmat%NP))
300 
301  tcomm = 0.d0
302  call hecmw_innerproduct_r(hecmesh, hecmat%NDOF, &
303  hecmat%B, hecmat%B, bnorm2, tcomm)
304  if (bnorm2 == 0.d0) then
305  bnorm2 = 1.d0
306  endif
307  call hecmw_matresid_44(hecmesh, hecmat, hecmat%X, hecmat%B, r, time_ax, tcomm)
308  call hecmw_innerproduct_r(hecmesh, hecmat%NDOF, r, r, rnorm2, tcomm)
309  hecmw_rel_resid_l2_44 = sqrt(rnorm2 / bnorm2)
310 
311  if (present(commtime)) commtime = commtime + tcomm
312 
313  deallocate(r)
314  end function hecmw_rel_resid_l2_44
315 
316 end module hecmw_solver_las_44
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_44(hecMESH, hecMAT, X, B, R, time_Ax, COMMtime)
subroutine, public hecmw_matvec_44(hecMESH, hecMAT, X, Y, time_Ax, COMMtime)
real(kind=kreal) function, public hecmw_rel_resid_l2_44(hecMESH, hecMAT, 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)