FrontISTR  6.0.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  use hecmw_util
8  implicit none
9 
10  private
11 
12  public :: hecmw_matvec_22
13  public :: hecmw_matresid_22
14  public :: hecmw_rel_resid_l2_22
15 
16 contains
17 
18  !C
19  !C***
20  !C*** hecmw_matvec_22
21  !C***
22  !C
23  subroutine hecmw_matvec_22 (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) :: yv1, yv2, x1, x2
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, 2)
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  x1= x(2*i-1)
135  x2= x(2*i )
136  yv1= 0
137  yv2= 0
138  js= indexa(i-1) + 1
139  je= indexa(i)
140  do j= js, je
141  in = itema(j)
142  x1 = x(2*in-1)
143  x2 = x(2*in )
144  yv1= yv1 + a(4*j-3)*x1 + a(4*j-2)*x2
145  yv2= yv2 + a(4*j-1)*x1 + a(4*j )*x2
146  enddo
147  y(2*i-1)= yv1
148  y(2*i )= yv2
149  enddo
150  !$acc end kernels
151 #else
152  !call fapp_start("loopInMatvec22", 1, 0)
153  !call start_collection("loopInMatvec22")
154 
155  !OCL CACHE_SECTOR_SIZE(sectorCacheSize0,sectorCacheSize1)
156  !OCL CACHE_SUBSECTOR_ASSIGN(X)
157 
158  !$OMP PARALLEL DEFAULT(NONE) &
159  !$OMP&PRIVATE(i,X1,X2,YV1,YV2,jS,jE,j,in,threadNum,blockNum,blockIndex) &
160  !$OMP&SHARED(D,AL,AU,indexL,itemL,indexU,itemU,X,Y,startPos,endPos,numOfThread,N)
161  threadnum = 0
162  !$ threadNum = omp_get_thread_num()
163  do blocknum = 0 , numofblockperthread - 1
164  blockindex = blocknum * numofthread + threadnum
165  do i = startpos(blockindex), endpos(blockindex)
166  x1= x(2*i-1)
167  x2= x(2*i )
168  yv1= d(4*i-3)*x1 + d(4*i-2)*x2
169  yv2= d(4*i-1)*x1 + d(4*i )*x2
170 
171  js= indexl(i-1) + 1
172  je= indexl(i )
173  do j= js, je
174  in = iteml(j)
175  x1 = x(2*in-1)
176  x2 = x(2*in )
177  yv1= yv1 + al(4*j-3)*x1 + al(4*j-2)*x2
178  yv2= yv2 + al(4*j-1)*x1 + al(4*j )*x2
179  enddo
180  js= indexu(i-1) + 1
181  je= indexu(i )
182  do j= js, je
183  in = itemu(j)
184  x1 = x(2*in-1)
185  x2 = x(2*in )
186  yv1= yv1 + au(4*j-3)*x1 + au(4*j-2)*x2
187  yv2= yv2 + au(4*j-1)*x1 + au(4*j )*x2
188  enddo
189  y(2*i-1)= yv1
190  y(2*i )= yv2
191  enddo
192  enddo
193 
194  !$OMP END PARALLEL
195 
196  !OCL END_CACHE_SUBSECTOR
197  !OCL END_CACHE_SECTOR_SIZE
198 
199  !call stop_collection("loopInMatvec22")
200  !call fapp_stop("loopInMatvec22", 1, 0)
201 #endif
202 
203 
204  end_time = hecmw_wtime()
205  time_ax = time_ax + end_time - start_time
206  endif
207 
208  end subroutine hecmw_matvec_22
209 
210 
211 
212 
213 
214 
215  !C
216  !C***
217  !C*** hecmw_matresid_22
218  !C***
219  !C
220  subroutine hecmw_matresid_22 (hecMESH, hecMAT, X, B, R, time_Ax, COMMtime)
221  use hecmw_util
222  implicit none
223  type (hecmwst_local_mesh), intent(in) :: hecmesh
224  type (hecmwst_matrix), intent(in) :: hecmat
225  real(kind=kreal), intent(in) :: b(:)
226  real(kind=kreal), intent(inout) :: x(:)
227  real(kind=kreal), intent(out) :: r(:)
228  real(kind=kreal), intent(inout) :: time_ax
229  real(kind=kreal), intent(inout), optional :: commtime
230 
231  integer(kind=kint) :: i
232  real(kind=kreal) :: tcomm
233 
234  tcomm = 0.d0
235  call hecmw_matvec_22 (hecmesh, hecmat, x, r, time_ax, tcomm)
236  if (present(commtime)) commtime = commtime + tcomm
237 #ifdef _OPENACC
238  !$acc kernels
239  !$acc loop independent
240 #else
241  !$omp parallel default(none),private(i),shared(hecMAT,R,B)
242  !$omp do
243 #endif
244  do i = 1, hecmat%N * 2
245  r(i) = b(i) - r(i)
246  enddo
247 #ifdef _OPENACC
248  !$acc end kernels
249 #else
250  !$omp end do
251  !$omp end parallel
252 #endif
253  end subroutine hecmw_matresid_22
254 
255  !C
256  !C***
257  !C*** hecmw_rel_resid_L2_22
258  !C***
259  !C
260  function hecmw_rel_resid_l2_22 (hecMESH, hecMAT, time_Ax, COMMtime)
261  use hecmw_util
263  implicit none
264  real(kind=kreal) :: hecmw_rel_resid_l2_22
265  type ( hecmwst_local_mesh ), intent(in) :: hecmesh
266  type ( hecmwst_matrix ), intent(in) :: hecmat
267  real(kind=kreal), intent(inout) :: time_ax
268  real(kind=kreal), intent(inout), optional :: commtime
269 
270  real(kind=kreal), allocatable :: r(:)
271  real(kind=kreal) :: bnorm2, rnorm2
272  real(kind=kreal) :: tcomm
273 
274  allocate(r(hecmat%NDOF*hecmat%NP))
275 
276  tcomm = 0.d0
277  call hecmw_innerproduct_r(hecmesh, hecmat%NDOF, &
278  hecmat%B, hecmat%B, bnorm2, tcomm)
279  if (bnorm2 == 0.d0) then
280  bnorm2 = 1.d0
281  endif
282  call hecmw_matresid_22(hecmesh, hecmat, hecmat%X, hecmat%B, r, time_ax, tcomm)
283  call hecmw_innerproduct_r(hecmesh, hecmat%NDOF, r, r, rnorm2, tcomm)
284  hecmw_rel_resid_l2_22 = sqrt(rnorm2 / bnorm2)
285 
286  if (present(commtime)) commtime = commtime + tcomm
287 
288  deallocate(r)
289  end function hecmw_rel_resid_l2_22
290 
291 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)