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