FrontISTR  6.0.0
Large-scale structural analysis program with finit element method
hecmw_precond_SSOR_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 
6 !C
7 !C***
8 !C*** module hecmw_precond_SSOR_11
9 !C***
10 !C
12  use hecmw_util
17 #ifndef _OPENACC
18  !$ use omp_lib
19 #endif
20 
21  private
22 
26 
27  integer(kind=kint) :: N
28  real(kind=kreal), pointer :: d(:) => null()
29  real(kind=kreal), pointer :: al(:) => null()
30  real(kind=kreal), pointer :: au(:) => null()
31  integer(kind=kint), pointer :: indexL(:) => null()
32  integer(kind=kint), pointer :: indexU(:) => null()
33  integer(kind=kint), pointer :: itemL(:) => null()
34  integer(kind=kint), pointer :: itemU(:) => null()
35  real(kind=kreal), pointer :: alu(:) => null()
36 
37  integer(kind=kint) :: NColor
38  integer(kind=kint), pointer :: COLORindex(:) => null()
39  integer(kind=kint), pointer :: perm(:) => null()
40  integer(kind=kint), pointer :: iperm(:) => null()
41 
42  logical, save :: isFirst = .true.
43 
44  logical, save :: INITIALIZED = .false.
45 
46  ! relaxation parameter of
47  ! M = 1/(2-OMEGA) (D/OMEGA + L) (D/OMEGA)^-1 (D/OMEGA + U)
48  ! OMEGA = 1 is the classic (D+L) D^-1 (D+U). _apply is handed only ZP, so setup
49  ! leaves the value here for it.
50  real(kind=kreal), save :: omega = 1.d0
51 
52  ! for tuning
53  integer(kind=kint), parameter :: numOfBlockPerThread = 100
54  integer(kind=kint), save :: numOfThread = 1, numofblock
55  integer(kind=kint), save, allocatable :: icToBlockIndex(:)
56  integer(kind=kint), save, allocatable :: blockIndexToColorIndex(:)
57  integer(kind=kint), save :: sectorCacheSize0, sectorCacheSize1
58 
59  integer(kind=kint), parameter :: SSOR_DEBUG = 0
60 
61 contains
62 
63  subroutine hecmw_precond_ssor_11_setup(hecMAT)
64  implicit none
65  type(hecmwst_matrix), intent(inout) :: hecmat
66  integer(kind=kint ) :: npl, npu
67  integer(kind=kint ) :: ncolor_in
68  real (kind=kreal) :: omega_inv
69  real (kind=kreal) :: alutmp(1,1), pw(1)
70  integer(kind=kint ) :: ii, i, j, k
71  integer(kind=kint ) :: nthreads = 1
72  integer(kind=kint ), allocatable :: perm_tmp(:)
73  real (kind=kreal) :: t0
74 
75  if (ssor_debug >= 1) then
76  t0 = hecmw_wtime()
77  write(*,*) 'DEBUG: SSOR setup start', hecmw_wtime()-t0
78  endif
79 
80  if (initialized) then
81  if (hecmat%Iarray(98) == 1) then ! need symbolic and numerical setup
82  call hecmw_precond_ssor_11_clear(hecmat)
83  else if (hecmat%Iarray(97) == 1) then ! need numerical setup only
84  call hecmw_precond_ssor_11_clear(hecmat) ! TEMPORARY
85  else
86  return
87  endif
88  endif
89 
90 #ifndef _OPENACC
91  !$ nthreads = omp_get_max_threads()
92 #endif
93 
94  n = hecmat%N
95  ! N = hecMAT%NP
96  ncolor_in = hecmw_mat_get_ncolor_in(hecmat)
97  omega = hecmw_mat_get_omega(hecmat)
98  omega_inv = 1.d0 / omega
99 
100 #ifdef _OPENACC
101  allocate(colorindex(0:n), perm_tmp(n), perm(n), iperm(n))
102  call hecmw_matrix_ordering_rcm(n, hecmat%indexL, hecmat%itemL, &
103  hecmat%indexU, hecmat%itemU, perm_tmp, iperm)
104  if (ssor_debug >= 1) write(*,*) 'DEBUG: RCM ordering done', hecmw_wtime()-t0
105  call hecmw_matrix_ordering_mc(n, hecmat%indexL, hecmat%itemL, &
106  hecmat%indexU, hecmat%itemU, perm_tmp, &
107  ncolor_in, ncolor, colorindex, perm, iperm)
108  if (ssor_debug >= 1) write(*,*) 'DEBUG: MC ordering done', hecmw_wtime()-t0
109  deallocate(perm_tmp)
110 
111 #else
112  if (nthreads == 1) then
113  ncolor = 1
114  allocate(colorindex(0:1), perm(n), iperm(n))
115  colorindex(0) = 0
116  colorindex(1) = n
117  do i=1,n
118  perm(i) = i
119  iperm(i) = i
120  end do
121  else
122  allocate(colorindex(0:n), perm_tmp(n), perm(n), iperm(n))
123  call hecmw_matrix_ordering_rcm(n, hecmat%indexL, hecmat%itemL, &
124  hecmat%indexU, hecmat%itemU, perm_tmp, iperm)
125  if (ssor_debug >= 1) write(*,*) 'DEBUG: RCM ordering done', hecmw_wtime()-t0
126  call hecmw_matrix_ordering_mc(n, hecmat%indexL, hecmat%itemL, &
127  hecmat%indexU, hecmat%itemU, perm_tmp, &
128  ncolor_in, ncolor, colorindex, perm, iperm)
129  if (ssor_debug >= 1) write(*,*) 'DEBUG: MC ordering done', hecmw_wtime()-t0
130  deallocate(perm_tmp)
131 
132  endif
133 #endif
134 
135  npl = 0
136  do i=1,n
137  do j=hecmat%indexU(i-1)+1,hecmat%indexU(i)
138  if( hecmat%itemU(j) > n ) exit
139  npl = npl + 1
140  enddo
141  enddo
142  npl = max(hecmat%indexL(n),npl)
143  npu = hecmat%indexU(n)
144  allocate(indexl(0:n), indexu(0:n), iteml(npl), itemu(npu))
145  call hecmw_matrix_reorder_profile(n, perm, iperm, &
146  hecmat%indexL, hecmat%indexU, hecmat%itemL, hecmat%itemU, &
147  indexl, indexu, iteml, itemu)
148  if (ssor_debug >= 1) write(*,*) 'DEBUG: reordering profile done', hecmw_wtime()-t0
149 
150 
151  allocate(d(n), al(npl), au(npu))
152  call hecmw_matrix_reorder_values(n, 1, perm, iperm, &
153  hecmat%indexL, hecmat%indexU, hecmat%itemL, hecmat%itemU, &
154  hecmat%AL, hecmat%AU, hecmat%D, &
155  indexl, indexu, iteml, itemu, al, au, d)
156  if (ssor_debug >= 1) write(*,*) 'DEBUG: reordering values done', hecmw_wtime()-t0
157 
158  call hecmw_matrix_reorder_renum_item(n, perm, indexl, iteml)
159  call hecmw_matrix_reorder_renum_item(n, perm, indexu, itemu)
160 
161  allocate(alu(n))
162  alu = 0.d0
163 
164  do ii= 1, n
165  alu(ii) = d(ii)
166  enddo
167 
168 #ifdef _OPENACC
169  !$acc kernels
170  !$acc loop independent private(ALUtmp)
171 #else
172  !$omp parallel default(none),private(ii,ALUtmp,k,i,j,PW),shared(N,ALU,OMEGA_INV)
173  !$omp do
174 #endif
175  do ii= 1, n
176  alutmp(1,1)= alu(ii) * omega_inv
177  alutmp(1,1)= 1.d0/alutmp(1,1)
178  alu(ii)= alutmp(1,1)
179  enddo
180 #ifdef _OPENACC
181  !$acc end kernels
182 #else
183  !$omp end do
184  !$omp end parallel
185 #endif
186 
187  isfirst = .true.
188 
189  initialized = .true.
190  hecmat%Iarray(98) = 0 ! symbolic setup done
191  hecmat%Iarray(97) = 0 ! numerical setup done
192 
193  if (ssor_debug >= 1) write(*,*) 'DEBUG: SSOR setup done', hecmw_wtime()-t0
194 
195  end subroutine hecmw_precond_ssor_11_setup
196 
197  subroutine setup_tuning_parameters
198  use hecmw_tuning_fx
199  implicit none
200  integer(kind=kint) :: blockindex, elementcount, numofelement, ii
201  real(kind=kreal) :: numofelementperblock
202  integer(kind=kint) :: ic, i
203  if (ssor_debug >= 1) write(*,*) 'DEBUG: setting up tuning parameters for SSOR'
204 #ifndef _OPENACC
205  !$ numOfThread = omp_get_max_threads()
206 #endif
207 
208  numofblock = numofthread * numofblockperthread
209  if (allocated(ictoblockindex)) deallocate(ictoblockindex)
210  if (allocated(blockindextocolorindex)) deallocate(blockindextocolorindex)
211  allocate (ictoblockindex(0:ncolor), &
212  blockindextocolorindex(0:numofblock + ncolor))
213  numofelement = n + indexl(n) + indexu(n)
214  numofelementperblock = dble(numofelement) / numofblock
215  blockindex = 0
216  ictoblockindex = -1
217  ictoblockindex(0) = 0
218  blockindextocolorindex = -1
219  blockindextocolorindex(0) = 0
220  do ic = 1, ncolor
221  elementcount = 0
222  ii = 1
223  do i = colorindex(ic-1)+1, colorindex(ic)
224  elementcount = elementcount + 1
225  elementcount = elementcount + (indexl(i) - indexl(i-1))
226  elementcount = elementcount + (indexu(i) - indexu(i-1))
227  if (elementcount > ii * numofelementperblock &
228  .or. i == colorindex(ic)) then
229  ii = ii + 1
230  blockindex = blockindex + 1
231  blockindextocolorindex(blockindex) = i
232  endif
233  enddo
234  ictoblockindex(ic) = blockindex
235  enddo
236  numofblock = blockindex
237 
239  sectorcachesize0, sectorcachesize1 )
240  end subroutine setup_tuning_parameters
241 
243  implicit none
244  real(kind=kreal), intent(inout) :: zp(:)
245  integer(kind=kint) :: ic, i, iold, j, isl, iel, isu, ieu, k
246  real(kind=kreal) :: sw1, x1
247 
248  real(kind=kreal) :: omega_fac
249 
250  ! added for tuning >>>
251  integer(kind=kint) :: blockindex
252 
253 #ifndef _OPENACC
254  if (isfirst) then
255  call setup_tuning_parameters
256  isfirst = .false.
257  endif
258 #endif
259  ! <<< added for tuning
260 
261  omega_fac = 2.d0 - omega
262 
263 #ifndef _OPENACC
264  !call start_collection("loopInPrecond11")
265 
266  !OCL CACHE_SECTOR_SIZE(sectorCacheSize0,sectorCacheSize1)
267  !OCL CACHE_SUBSECTOR_ASSIGN(ZP)
268 
269  !$omp parallel default(none) &
270  !$omp&shared(NColor,indexL,itemL,indexU,itemU,AL,AU,D,ALU,perm,&
271  !$omp& ZP,icToBlockIndex,blockIndexToColorIndex,OMEGA_FAC) &
272  !$omp&private(SW1,X1,ic,i,iold,isL,ieL,isU,ieU,j,k,blockIndex)
273 #endif
274 
275  !C-- FORWARD
276  do ic=1,ncolor
277 #ifdef _OPENACC
278  !$acc kernels
279  !$acc loop independent
280  do i = colorindex(ic-1)+1, colorindex(ic)
281 #else
282  !$omp do schedule (static, 1)
283  do blockindex = ictoblockindex(ic-1)+1, ictoblockindex(ic)
284  do i = blockindextocolorindex(blockindex-1)+1, &
285  blockindextocolorindex(blockindex)
286 #endif
287  iold = perm(i)
288  sw1= omega_fac * zp(iold)
289  isl= indexl(i-1)+1
290  iel= indexl(i)
291  do j= isl, iel
292  k= iteml(j)
293  x1= zp(k)
294  sw1= sw1 - al(j)*x1
295  enddo ! j
296 
297  x1= alu(i )* sw1
298  zp(iold)= x1
299 #ifdef _OPENACC
300  enddo
301  !$acc end kernels
302 #else
303  enddo ! i
304  enddo ! blockIndex
305  !$omp end do
306 #endif
307  enddo ! ic
308 
309  !C-- BACKWARD
310  do ic=ncolor, 1, -1
311 #ifdef _OPENACC
312  !$acc kernels
313  !$acc loop independent
314  do i = colorindex(ic-1)+1, colorindex(ic)
315 #else
316  !$omp do schedule (static, 1)
317  do blockindex = ictoblockindex(ic), ictoblockindex(ic-1)+1, -1
318  do i = blockindextocolorindex(blockindex), &
319  blockindextocolorindex(blockindex-1)+1, -1
320 #endif
321  ! do blockIndex = icToBlockIndex(ic-1)+1, icToBlockIndex(ic)
322  ! do i = blockIndexToColorIndex(blockIndex-1)+1, &
323  ! blockIndexToColorIndex(blockIndex)
324  ! do i = endPos(threadNum, ic), startPos(threadNum, ic), -1
325  sw1= 0.d0
326  isu= indexu(i-1) + 1
327  ieu= indexu(i)
328  do j= ieu, isu, -1
329  k= itemu(j)
330  x1= zp(k)
331  sw1= sw1 + au(j)*x1
332  enddo ! j
333 
334  x1= alu(i)* sw1
335 
336  iold = perm(i)
337  zp(iold)= zp(iold) - x1
338 #ifdef _OPENACC
339  enddo
340  !$acc end kernels
341 #else
342  enddo ! i
343  enddo ! blockIndex
344  !$omp end do
345 #endif
346  enddo ! ic
347 #ifndef _OPENACC
348  !$omp end parallel
349 
350  !OCL END_CACHE_SUBSECTOR
351  !OCL END_CACHE_SECTOR_SIZE
352 
353  !call stop_collection("loopInPrecond11")
354 #endif
355 
356  end subroutine hecmw_precond_ssor_11_apply
357 
358  subroutine hecmw_precond_ssor_11_clear(hecMAT)
359  implicit none
360  type(hecmwst_matrix), intent(inout) :: hecmat
361  if (associated(colorindex)) deallocate(colorindex)
362  if (associated(perm)) deallocate(perm)
363  if (associated(iperm)) deallocate(iperm)
364  if (associated(alu)) deallocate(alu)
365  if (associated(d)) deallocate(d)
366  if (associated(al)) deallocate(al)
367  if (associated(au)) deallocate(au)
368  if (associated(indexl)) deallocate(indexl)
369  if (associated(indexu)) deallocate(indexu)
370  if (associated(iteml)) deallocate(iteml)
371  if (associated(itemu)) deallocate(itemu)
372  nullify(colorindex)
373  nullify(perm)
374  nullify(iperm)
375  nullify(alu)
376  nullify(d)
377  nullify(al)
378  nullify(au)
379  nullify(indexl)
380  nullify(indexu)
381  nullify(iteml)
382  nullify(itemu)
383  initialized = .false.
384  end subroutine hecmw_precond_ssor_11_clear
385 
386 end module hecmw_precond_ssor_11
real(kind=kreal) function, public hecmw_mat_get_omega(hecMAT)
integer(kind=kint) function, public hecmw_mat_get_ncolor_in(hecMAT)
subroutine, public hecmw_matrix_reorder_values(N, NDOF, perm, iperm, indexL, indexU, itemL, itemU, AL, AU, D, indexLp, indexUp, itemLp, itemUp, ALp, AUp, Dp)
subroutine, public hecmw_matrix_reorder_renum_item(N, perm, indexXp, itemXp)
subroutine, public hecmw_matrix_reorder_profile(N, perm, iperm, indexL, indexU, itemL, itemU, indexLp, indexUp, itemLp, itemUp)
subroutine, public hecmw_precond_ssor_11_setup(hecMAT)
subroutine, public hecmw_precond_ssor_11_clear(hecMAT)
subroutine, public hecmw_precond_ssor_11_apply(ZP)
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, public hecmw_matrix_ordering_rcm(N, indexL, itemL, indexU, itemU, perm, iperm)
subroutine, public hecmw_matrix_ordering_mc(N, indexL, itemL, indexU, itemU, perm_cur, ncolor_in, ncolor_out, COLORindex, perm, iperm)