FrontISTR  6.0.0
Large-scale structural analysis program with finit element method
hecmw_precond_SSOR_33.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_33
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 #ifdef HECMW_ARCH_FX64
29  integer(kind=kint) :: NP
30 #endif
31  real(kind=kreal), pointer :: d(:) => null()
32  real(kind=kreal), pointer :: al(:) => null()
33  real(kind=kreal), pointer :: au(:) => null()
34  integer(kind=kint), pointer :: indexL(:) => null()
35  integer(kind=kint), pointer :: indexU(:) => null()
36  integer(kind=kint), pointer :: itemL(:) => null()
37  integer(kind=kint), pointer :: itemU(:) => null()
38  real(kind=kreal), pointer :: alu(:) => null()
39 
40  integer(kind=kint) :: NColor
41  integer(kind=kint), pointer :: COLORindex(:) => null()
42  integer(kind=kint), pointer :: perm(:) => null()
43  integer(kind=kint), pointer :: iperm(:) => null()
44 
45  ! taken from hecMAT at setup: _apply receives only ZP and cannot read it back
46  integer(kind=kint) :: precond_impl = hecmw_precond_impl_bsr
47 
48  ! a format may be selected on a build that carries no SSOR for it; saying so once
49  ! per run keeps the fallback from looking like the requested format took effect
50  logical, save :: precond_impl_missing_reported = .false.
51 
52  logical, save :: isFirst = .true.
53 
54  logical, save :: INITIALIZED = .false.
55 
56  ! relaxation parameter of
57  ! M = 1/(2-OMEGA) (D/OMEGA + L) (D/OMEGA)^-1 (D/OMEGA + U)
58  ! OMEGA = 1 is the classic (D+L) D^-1 (D+U). _apply is handed only ZP, so setup
59  ! leaves the value here for it.
60  real(kind=kreal), save :: omega = 1.d0
61 
62  ! for tuning
63  integer(kind=kint), parameter :: numOfBlockPerThread = 100
64  integer(kind=kint), save :: numOfThread = 1, numofblock
65  integer(kind=kint), save, allocatable :: icToBlockIndex(:)
66  integer(kind=kint), save, allocatable :: blockIndexToColorIndex(:)
67  integer(kind=kint), save :: sectorCacheSize0, sectorCacheSize1
68 
69  integer(kind=kint), parameter :: SSOR_DEBUG = 0
70 
71 contains
72 
73  subroutine hecmw_precond_ssor_33_setup(hecMAT)
74  implicit none
75  type(hecmwst_matrix), intent(inout) :: hecmat
76  integer(kind=kint ) :: npl, npu
77  integer(kind=kint ) :: ncolor_in
78  real (kind=kreal) :: omega_inv
79  real (kind=kreal) :: alutmp(3,3), pw(3)
80  integer(kind=kint ) :: ii, i, j, k
81  integer(kind=kint ) :: nthreads = 1
82  integer(kind=kint ), allocatable :: perm_tmp(:)
83  real (kind=kreal) :: t0
84 
85  if (ssor_debug >= 1) then
86  t0 = hecmw_wtime()
87  write(*,*) 'DEBUG: SSOR setup start', hecmw_wtime()-t0
88  endif
89 
90  if (initialized) then
91  if (hecmat%Iarray(98) == 1) then ! need symbolic and numerical setup
92  call hecmw_precond_ssor_33_clear(hecmat)
93  else if (hecmat%Iarray(97) == 1) then ! need numerical setup only
94  call hecmw_precond_ssor_33_clear(hecmat) ! TEMPORARY
95  else
96  return
97  endif
98  endif
99 
100 #ifndef _OPENACC
101  !$ nthreads = omp_get_max_threads()
102 #endif
103 
104  n = hecmat%N
105  ! N = hecMAT%NP
106  ncolor_in = hecmw_mat_get_ncolor_in(hecmat)
107  omega = hecmw_mat_get_omega(hecmat)
108  omega_inv = 1.d0 / omega
109  precond_impl = hecmw_mat_get_precond_impl(hecmat)
110 
111 #ifdef _OPENACC
112  allocate(colorindex(0:n), perm_tmp(n), perm(n), iperm(n))
113  call hecmw_matrix_ordering_rcm(n, hecmat%indexL, hecmat%itemL, &
114  hecmat%indexU, hecmat%itemU, perm_tmp, iperm)
115  if (ssor_debug >= 1) write(*,*) 'DEBUG: RCM ordering done', hecmw_wtime()-t0
116  call hecmw_matrix_ordering_mc(n, hecmat%indexL, hecmat%itemL, &
117  hecmat%indexU, hecmat%itemU, perm_tmp, &
118  ncolor_in, ncolor, colorindex, perm, iperm)
119  if (ssor_debug >= 1) write(*,*) 'DEBUG: MC ordering done', hecmw_wtime()-t0
120  deallocate(perm_tmp)
121 
122 #else
123  if (nthreads == 1) then
124  ncolor = 1
125  allocate(colorindex(0:1), perm(n), iperm(n))
126  colorindex(0) = 0
127  colorindex(1) = n
128  do i=1,n
129  perm(i) = i
130  iperm(i) = i
131  end do
132  else
133  allocate(colorindex(0:n), perm_tmp(n), perm(n), iperm(n))
134  call hecmw_matrix_ordering_rcm(n, hecmat%indexL, hecmat%itemL, &
135  hecmat%indexU, hecmat%itemU, perm_tmp, iperm)
136  if (ssor_debug >= 1) write(*,*) 'DEBUG: RCM ordering done', hecmw_wtime()-t0
137  call hecmw_matrix_ordering_mc(n, hecmat%indexL, hecmat%itemL, &
138  hecmat%indexU, hecmat%itemU, perm_tmp, &
139  ncolor_in, ncolor, colorindex, perm, iperm)
140  if (ssor_debug >= 1) write(*,*) 'DEBUG: MC ordering done', hecmw_wtime()-t0
141  deallocate(perm_tmp)
142 
143  endif
144 #endif
145 
146  npl = 0
147  do i=1,n
148  do j=hecmat%indexU(i-1)+1,hecmat%indexU(i)
149  if( hecmat%itemU(j) > n ) exit
150  npl = npl + 1
151  enddo
152  enddo
153  npl = max(hecmat%indexL(n),npl)
154  npu = hecmat%indexU(n)
155  allocate(indexl(0:n), indexu(0:n), iteml(npl), itemu(npu))
156  call hecmw_matrix_reorder_profile(n, perm, iperm, &
157  hecmat%indexL, hecmat%indexU, hecmat%itemL, hecmat%itemU, &
158  indexl, indexu, iteml, itemu)
159  if (ssor_debug >= 1) write(*,*) 'DEBUG: reordering profile done', hecmw_wtime()-t0
160 
161 
162  allocate(d(9*n), al(9*npl), au(9*npu))
163  call hecmw_matrix_reorder_values(n, 3, perm, iperm, &
164  hecmat%indexL, hecmat%indexU, hecmat%itemL, hecmat%itemU, &
165  hecmat%AL, hecmat%AU, hecmat%D, &
166  indexl, indexu, iteml, itemu, al, au, d)
167  if (ssor_debug >= 1) write(*,*) 'DEBUG: reordering values done', hecmw_wtime()-t0
168 
169  call hecmw_matrix_reorder_renum_item(n, perm, indexl, iteml)
170  call hecmw_matrix_reorder_renum_item(n, perm, indexu, itemu)
171 
172  allocate(alu(9*n))
173  alu = 0.d0
174 
175  do ii= 1, 9*n
176  alu(ii) = d(ii)
177  enddo
178 
179 #ifdef _OPENACC
180  !$acc kernels
181  !$acc loop independent private(ALUtmp,PW)
182 #else
183  !$omp parallel default(none),private(ii,ALUtmp,k,i,j,PW),shared(N,ALU,OMEGA_INV)
184  !$omp do
185 #endif
186  do ii= 1, n
187  alutmp(1,1)= alu(9*ii-8) * omega_inv
188  alutmp(1,2)= alu(9*ii-7) * omega_inv
189  alutmp(1,3)= alu(9*ii-6) * omega_inv
190  alutmp(2,1)= alu(9*ii-5) * omega_inv
191  alutmp(2,2)= alu(9*ii-4) * omega_inv
192  alutmp(2,3)= alu(9*ii-3) * omega_inv
193  alutmp(3,1)= alu(9*ii-2) * omega_inv
194  alutmp(3,2)= alu(9*ii-1) * omega_inv
195  alutmp(3,3)= alu(9*ii ) * omega_inv
196  do k= 1, 3
197  alutmp(k,k)= 1.d0/alutmp(k,k)
198  do i= k+1, 3
199  alutmp(i,k)= alutmp(i,k) * alutmp(k,k)
200  do j= k+1, 3
201  pw(j)= alutmp(i,j) - alutmp(i,k)*alutmp(k,j)
202  enddo
203  do j= k+1, 3
204  alutmp(i,j)= pw(j)
205  enddo
206  enddo
207  enddo
208  alu(9*ii-8)= alutmp(1,1)
209  alu(9*ii-7)= alutmp(1,2)
210  alu(9*ii-6)= alutmp(1,3)
211  alu(9*ii-5)= alutmp(2,1)
212  alu(9*ii-4)= alutmp(2,2)
213  alu(9*ii-3)= alutmp(2,3)
214  alu(9*ii-2)= alutmp(3,1)
215  alu(9*ii-1)= alutmp(3,2)
216  alu(9*ii )= alutmp(3,3)
217  enddo
218 #ifdef _OPENACC
219  !$acc end kernels
220 #else
221  !$omp end do
222  !$omp end parallel
223 #endif
224 
225  isfirst = .true.
226 
227  initialized = .true.
228  hecmat%Iarray(98) = 0 ! symbolic setup done
229  hecmat%Iarray(97) = 0 ! numerical setup done
230 
231  if (ssor_debug >= 1) write(*,*) 'DEBUG: SSOR setup done', hecmw_wtime()-t0
232 
233  if (precond_impl == hecmw_precond_impl_csr) call hecmw_precond_ssor_33_setup_csr(hecmat)
234 
235  end subroutine hecmw_precond_ssor_33_setup
236 
237  subroutine hecmw_precond_ssor_33_setup_csr(hecMAT)
238  implicit none
239  type(hecmwst_matrix), intent(in) :: hecmat
240 #ifdef HECMW_ARCH_FX64
241  integer(kind=kint ) :: npl, npu
242  real (kind=kreal) :: atmp(9)
243  integer(kind=kint ) :: ii
244  integer(kind=kint ), pointer :: item_tmp(:)
245 
246  np = hecmat%NP
247 
248  !$omp parallel default(none),private(ii,Atmp),shared(N,ALU)
249  !$omp do
250  do ii= 1, n
251  atmp(1)= alu(9*ii-8)
252  atmp(2)= alu(9*ii-7)
253  atmp(3)= alu(9*ii-6)
254  atmp(4)= alu(9*ii-5)
255  atmp(5)= alu(9*ii-4)
256  atmp(6)= alu(9*ii-3)
257  atmp(7)= alu(9*ii-2)
258  atmp(8)= alu(9*ii-1)
259  atmp(9)= alu(9*ii )
260 
261  alu(9*ii )= atmp(9)
262  alu(9*ii-1)= -atmp(8)*atmp(9)
263  alu(9*ii-2)= (atmp(4)*atmp(8)-atmp(7))*atmp(9)
264  alu(9*ii-3)= -atmp(5)*atmp(6)*alu(9*ii)
265  alu(9*ii-4)= atmp(5)*(1.d0-atmp(6)*alu(9*ii-1))
266  alu(9*ii-5)= -atmp(5)*(atmp(4)+atmp(6)*alu(9*ii-2))
267  alu(9*ii-6)= -atmp(1)*(atmp(3)*alu(9*ii)+atmp(2)*alu(9*ii-3))
268  alu(9*ii-7)= -atmp(1)*(atmp(3)*alu(9*ii-1)+atmp(2)*alu(9*ii-4))
269  alu(9*ii-8)= atmp(1)*(1.d0-atmp(3)*alu(9*ii-2)-atmp(2)*alu(9*ii-5))
270  enddo
271  !$omp end do
272  !$omp end parallel
273 
274  ! setup sized itemL and itemU for BSR; the expansion below takes three entries per block
275  npl = indexl(n)
276  npu = indexu(n)
277  allocate(item_tmp(3*npl))
278  item_tmp(1:npl) = iteml(1:npl)
279  deallocate(iteml)
280  iteml => item_tmp
281  allocate(item_tmp(3*npu))
282  item_tmp(1:npu) = itemu(1:npu)
283  deallocate(itemu)
284  itemu => item_tmp
285 
286  do ii=1,n
287  indexl(ii) = 3*indexl(ii)
288  indexu(ii) = 3*indexu(ii)
289  end do
290  do ii=npl,1,-1
291  iteml(3*ii ) = 3*iteml(ii)
292  iteml(3*ii-1) = 3*iteml(ii)-1
293  iteml(3*ii-2) = 3*iteml(ii)-2
294  end do
295  do ii=npu,1,-1
296  itemu(3*ii ) = 3*itemu(ii)
297  itemu(3*ii-1) = 3*itemu(ii)-1
298  itemu(3*ii-2) = 3*itemu(ii)-2
299  end do
300 
301  !$omp parallel default(none),private(ii),shared(NPL,AL)
302  !$omp do
303  do ii=1,npl
304  call hecmw_mat_block_transpose_33(al(9*ii-8:9*ii))
305  end do
306  !$omp end do
307  !$omp end parallel
308  !$omp parallel default(none),private(ii),shared(NPU,AU)
309  !$omp do
310  do ii=1,npu
311  call hecmw_mat_block_transpose_33(au(9*ii-8:9*ii))
312  end do
313  !$omp end do
314  !$omp end parallel
315 
316 #endif
317  end subroutine hecmw_precond_ssor_33_setup_csr
318 
319  subroutine setup_tuning_parameters
320  use hecmw_tuning_fx
321  implicit none
322  integer(kind=kint) :: blockindex, elementcount, numofelement, ii
323  real(kind=kreal) :: numofelementperblock
324  integer(kind=kint) :: my_rank
325  integer(kind=kint) :: ic, i
326  if (ssor_debug >= 1) write(*,*) 'DEBUG: setting up tuning parameters for SSOR'
327 #ifndef _OPENACC
328  !$ numOfThread = omp_get_max_threads()
329 #endif
330 
331  numofblock = numofthread * numofblockperthread
332  if (allocated(ictoblockindex)) deallocate(ictoblockindex)
333  if (allocated(blockindextocolorindex)) deallocate(blockindextocolorindex)
334  allocate (ictoblockindex(0:ncolor), &
335  blockindextocolorindex(0:numofblock + ncolor))
336  numofelement = n + indexl(n) + indexu(n)
337  numofelementperblock = dble(numofelement) / numofblock
338  blockindex = 0
339  ictoblockindex = -1
340  ictoblockindex(0) = 0
341  blockindextocolorindex = -1
342  blockindextocolorindex(0) = 0
343  my_rank = hecmw_comm_get_rank()
344  ! write(9000+my_rank,*) &
345  ! '# numOfElementPerBlock =', numOfElementPerBlock
346  ! write(9000+my_rank,*) &
347  ! '# ic, blockIndex, colorIndex, elementCount'
348  do ic = 1, ncolor
349  elementcount = 0
350  ii = 1
351  do i = colorindex(ic-1)+1, colorindex(ic)
352  elementcount = elementcount + 1
353  elementcount = elementcount + (indexl(i) - indexl(i-1))
354  elementcount = elementcount + (indexu(i) - indexu(i-1))
355  if (elementcount > ii * numofelementperblock &
356  .or. i == colorindex(ic)) then
357  ii = ii + 1
358  blockindex = blockindex + 1
359  blockindextocolorindex(blockindex) = i
360  ! write(9000+my_rank,*) ic, blockIndex, &
361  ! blockIndexToColorIndex(blockIndex), elementCount
362  endif
363  enddo
364  ictoblockindex(ic) = blockindex
365  enddo
366  numofblock = blockindex
367 
369  sectorcachesize0, sectorcachesize1 )
370  end subroutine setup_tuning_parameters
371 
373  use m_hecmw_comm_f
374  implicit none
375  real(kind=kreal), intent(inout) :: zp(:)
376 
377  select case (precond_impl)
380 #ifdef HECMW_ARCH_FX64
382  call hecmw_precond_ssor_33_apply_csr(zp)
383 #endif
384  case default
385  if (.not. precond_impl_missing_reported) then
386  precond_impl_missing_reported = .true.
387  if (hecmw_comm_get_rank() == 0) write(*,'(a)') &
388  '#### MATRIXFORMAT: this build has no SSOR preconditioner for the selected '// &
389  'format -- running the BSR implementation'
390  endif
392  end select
393  end subroutine hecmw_precond_ssor_33_apply
394 
396  implicit none
397  real(kind=kreal), intent(inout) :: zp(:)
398  integer(kind=kint) :: ic, i, iold, j, isL, ieL, isU, ieU, k
399  real(kind=kreal) :: sw1, sw2, sw3, x1, x2, x3
400 
401  real(kind=kreal) :: omega_fac
402 
403  ! added for tuning >>>
404  integer(kind=kint) :: blockIndex
405 
406 #ifndef _OPENACC
407  if (isfirst) then
408  call setup_tuning_parameters
409  isfirst = .false.
410  endif
411 #endif
412  ! <<< added for tuning
413 
414  omega_fac = 2.d0 - omega
415 
416 #ifndef _OPENACC
417  !call start_collection("loopInPrecond33")
418 
419  !OCL CACHE_SECTOR_SIZE(sectorCacheSize0,sectorCacheSize1)
420  !OCL CACHE_SUBSECTOR_ASSIGN(ZP)
421 
422  !$omp parallel default(none) &
423  !$omp&shared(NColor,indexL,itemL,indexU,itemU,AL,AU,D,ALU,perm,&
424  !$omp& ZP,icToBlockIndex,blockIndexToColorIndex,OMEGA_FAC) &
425  !$omp&private(SW1,SW2,SW3,X1,X2,X3,ic,i,iold,isL,ieL,isU,ieU,j,k,blockIndex)
426 #endif
427 
428  !C-- FORWARD
429  do ic=1,ncolor
430 #ifdef _OPENACC
431  !$acc kernels
432  !$acc loop independent
433  do i = colorindex(ic-1)+1, colorindex(ic)
434 #else
435  !$omp do schedule (static, 1)
436  do blockindex = ictoblockindex(ic-1)+1, ictoblockindex(ic)
437  do i = blockindextocolorindex(blockindex-1)+1, &
438  blockindextocolorindex(blockindex)
439 #endif
440  ! do i = startPos(threadNum, ic), endPos(threadNum, ic)
441  iold = perm(i)
442  sw1= omega_fac * zp(3*iold-2)
443  sw2= omega_fac * zp(3*iold-1)
444  sw3= omega_fac * zp(3*iold )
445  isl= indexl(i-1)+1
446  iel= indexl(i)
447  do j= isl, iel
448  !k= perm(itemL(j))
449  k= iteml(j)
450  x1= zp(3*k-2)
451  x2= zp(3*k-1)
452  x3= zp(3*k )
453  sw1= sw1 - al(9*j-8)*x1 - al(9*j-7)*x2 - al(9*j-6)*x3
454  sw2= sw2 - al(9*j-5)*x1 - al(9*j-4)*x2 - al(9*j-3)*x3
455  sw3= sw3 - al(9*j-2)*x1 - al(9*j-1)*x2 - al(9*j )*x3
456  enddo ! j
457 
458  x1= sw1
459  x2= sw2
460  x3= sw3
461  x2= x2 - alu(9*i-5)*x1
462  x3= x3 - alu(9*i-2)*x1 - alu(9*i-1)*x2
463  x3= alu(9*i )* x3
464  x2= alu(9*i-4)*( x2 - alu(9*i-3)*x3 )
465  x1= alu(9*i-8)*( x1 - alu(9*i-6)*x3 - alu(9*i-7)*x2)
466  zp(3*iold-2)= x1
467  zp(3*iold-1)= x2
468  zp(3*iold )= x3
469 #ifdef _OPENACC
470  enddo
471  !$acc end kernels
472 #else
473  enddo ! i
474  enddo ! blockIndex
475  !$omp end do
476 #endif
477  enddo ! ic
478 
479  !C-- BACKWARD
480  do ic=ncolor, 1, -1
481 #ifdef _OPENACC
482  !$acc kernels
483  !$acc loop independent
484  do i = colorindex(ic-1)+1, colorindex(ic)
485 #else
486  !$omp do schedule (static, 1)
487  do blockindex = ictoblockindex(ic), ictoblockindex(ic-1)+1, -1
488  do i = blockindextocolorindex(blockindex), &
489  blockindextocolorindex(blockindex-1)+1, -1
490 #endif
491  ! do blockIndex = icToBlockIndex(ic-1)+1, icToBlockIndex(ic)
492  ! do i = blockIndexToColorIndex(blockIndex-1)+1, &
493  ! blockIndexToColorIndex(blockIndex)
494  ! do i = endPos(threadNum, ic), startPos(threadNum, ic), -1
495  sw1= 0.d0
496  sw2= 0.d0
497  sw3= 0.d0
498  isu= indexu(i-1) + 1
499  ieu= indexu(i)
500  do j= ieu, isu, -1
501  !k= perm(itemU(j))
502  k= itemu(j)
503  x1= zp(3*k-2)
504  x2= zp(3*k-1)
505  x3= zp(3*k )
506  sw1= sw1 + au(9*j-8)*x1 + au(9*j-7)*x2 + au(9*j-6)*x3
507  sw2= sw2 + au(9*j-5)*x1 + au(9*j-4)*x2 + au(9*j-3)*x3
508  sw3= sw3 + au(9*j-2)*x1 + au(9*j-1)*x2 + au(9*j )*x3
509  enddo ! j
510 
511  x1= sw1
512  x2= sw2
513  x3= sw3
514  x2= x2 - alu(9*i-5)*x1
515  x3= x3 - alu(9*i-2)*x1 - alu(9*i-1)*x2
516  x3= alu(9*i )* x3
517  x2= alu(9*i-4)*( x2 - alu(9*i-3)*x3 )
518  x1= alu(9*i-8)*( x1 - alu(9*i-6)*x3 - alu(9*i-7)*x2)
519  iold = perm(i)
520  zp(3*iold-2)= zp(3*iold-2) - x1
521  zp(3*iold-1)= zp(3*iold-1) - x2
522  zp(3*iold )= zp(3*iold ) - x3
523 #ifdef _OPENACC
524  enddo
525  !$acc end kernels
526 #else
527  enddo ! i
528  enddo ! blockIndex
529  !$omp end do
530 #endif
531  enddo ! ic
532 #ifndef _OPENACC
533  !$omp end parallel
534 
535  !OCL END_CACHE_SUBSECTOR
536  !OCL END_CACHE_SECTOR_SIZE
537 
538  !call stop_collection("loopInPrecond33")
539 #endif
540 
542 
543  subroutine hecmw_precond_ssor_33_apply_csr(ZP)
544  use hecmw_tuning_fx
545  implicit none
546  real(kind=kreal), intent(inout) :: zp(:)
547 #ifdef HECMW_ARCH_FX64
548  integer(kind=kint) :: ic, i
549 
550  real(kind=kreal) :: omega_fac
551 
552  ! added for turning >>>
553  integer(kind=kint) :: blockIndex
554 
555  if (isfirst) then
556  call setup_tuning_parameters
557  isfirst = .false.
558  endif
559  ! <<< added for turning
560 
561  omega_fac = 2.d0 - omega
562 
564  n,np,zp,al,au,d,alu,iteml,itemu,indexl,indexu,perm,ictoblockindex,blockindextocolorindex, &
565  indexl(n),indexu(n),ncolor,numofblock,omega_fac)
566 
567 #endif
568  end subroutine hecmw_precond_ssor_33_apply_csr
569 
571  N,NP,ZP,AL,AU,D,ALU,itemL,itemU,indexL,indexU,perm,icToBlockIndex,blockIndexToColorIndex, &
572  NPL,NPU,NColor,numOfBlock,OMEGA_FAC)
573  integer(kind=kint), intent(in) :: N
574  integer(kind=kint), intent(in) :: NP
575  real(kind=kreal), intent(inout) :: zp(3*np)
576  real(kind=kreal), intent(in) :: al(3*npl)
577  real(kind=kreal), intent(in) :: au(3*npu)
578  real(kind=kreal), intent(in) :: d(9*n)
579  real(kind=kreal), intent(in) :: alu(9*n)
580  integer(kind=kint), intent(in) :: itemL(NPL)
581  integer(kind=kint), intent(in) :: itemU(NPU)
582  integer(kind=kint), intent(in) :: indexL(0:N)
583  integer(kind=kint), intent(in) :: indexU(0:N)
584  integer(kind=kint), intent(in) :: perm(N)
585  integer(kind=kint), intent(in) :: icToBlockIndex(0:NColor)
586  integer(kind=kint), intent(in) :: blockIndexToColorIndex(0:numOfBlock+NColor)
587  integer(kind=kint), intent(in) :: NPL
588  integer(kind=kint), intent(in) :: NPU
589  integer(kind=kint), intent(in) :: NColor
590  integer(kind=kint), intent(in) :: numOfBlock
591  real(kind=kreal), intent(in) :: omega_fac
592 #ifdef HECMW_ARCH_FX64
593 
594  integer(kind=kint) :: ic, i, iold, j, isL, ieL, isU, ieU, k
595  integer(kind=kint) :: blockIndex
596  real(kind=kreal) :: sw1, sw2, sw3, x1, x2, x3
597 
598  !call start_collection("loopInPrecond33")
599 
600  !OCL CACHE_SECTOR_SIZE(sectorCacheSize0,sectorCacheSize1)
601  !OCL CACHE_SUBSECTOR_ASSIGN(ZP)
602 
603  if( ncolor > 1 ) then
604 
605  !$omp parallel default(none) &
606  !$omp&shared(NColor,indexL,itemL,indexU,itemU,AL,AU,D,ALU,perm,&
607  !$omp& ZP,icToBlockIndex,blockIndexToColorIndex,OMEGA_FAC) &
608  !$omp&private(SW1,SW2,SW3,X1,X2,X3,ic,i,iold,isL,ieL,isU,ieU,j,k,blockIndex)
609 
610  !C-- FORWARD
611  do ic=1,ncolor
612  !$omp do schedule (static, 1)
613  do blockindex = ictoblockindex(ic-1)+1, ictoblockindex(ic)
614  do i = blockindextocolorindex(blockindex-1)+1, &
615  blockindextocolorindex(blockindex)
616  ! do i = startPos(threadNum, ic), endPos(threadNum, ic)
617  iold = perm(i)
618  sw1= omega_fac * zp(3*iold-2)
619  sw2= omega_fac * zp(3*iold-1)
620  sw3= omega_fac * zp(3*iold )
621  isl= indexl(i-1)+1
622  iel= indexl(i)
623  do j= isl, iel
624  !k= perm(itemL(j))
625  x1= zp(iteml(j))
626  sw1= sw1 - al(3*j-2)*x1
627  sw2= sw2 - al(3*j-1)*x1
628  sw3= sw3 - al(3*j )*x1
629  enddo ! j
630 
631  zp(3*iold-2)= alu(9*i-8)*sw1+alu(9*i-7)*sw2+alu(9*i-6)*sw3
632  zp(3*iold-1)= alu(9*i-5)*sw1+alu(9*i-4)*sw2+alu(9*i-3)*sw3
633  zp(3*iold )= alu(9*i-2)*sw1+alu(9*i-1)*sw2+alu(9*i )*sw3
634  enddo ! i
635  enddo ! blockIndex
636  !$omp end do
637  enddo ! ic
638 
639  !C-- BACKWARD
640  do ic=ncolor, 1, -1
641  !$omp do schedule (static, 1)
642  do blockindex = ictoblockindex(ic), ictoblockindex(ic-1)+1, -1
643  do i = blockindextocolorindex(blockindex), &
644  blockindextocolorindex(blockindex-1)+1, -1
645  ! do blockIndex = icToBlockIndex(ic-1)+1, icToBlockIndex(ic)
646  ! do i = blockIndexToColorIndex(blockIndex-1)+1, &
647  ! blockIndexToColorIndex(blockIndex)
648  ! do i = endPos(threadNum, ic), startPos(threadNum, ic), -1
649  sw1= 0.d0
650  sw2= 0.d0
651  sw3= 0.d0
652  isu= indexu(i-1) + 1
653  ieu= indexu(i)
654  do j= ieu, isu, -1
655  !k= perm(itemU(j))
656  x1= zp(itemu(j))
657  sw1= sw1 + au(3*j-2)*x1
658  sw2= sw2 + au(3*j-1)*x1
659  sw3= sw3 + au(3*j )*x1
660  enddo ! j
661 
662  iold = perm(i)
663  zp(3*iold-2)= zp(3*iold-2) - alu(9*i-8)*sw1 - alu(9*i-7)*sw2 - alu(9*i-6)*sw3
664  zp(3*iold-1)= zp(3*iold-1) - alu(9*i-5)*sw1 - alu(9*i-4)*sw2 - alu(9*i-3)*sw3
665  zp(3*iold )= zp(3*iold ) - alu(9*i-2)*sw1 - alu(9*i-1)*sw2 - alu(9*i )*sw3
666  enddo ! i
667  enddo ! blockIndex
668  !$omp end do
669  enddo ! ic
670  !$omp end parallel
671 
672  else
673 
674  !C-- FORWARD
675  do i = 1, n
676  iold = perm(i)
677  sw1= omega_fac * zp(3*iold-2)
678  sw2= omega_fac * zp(3*iold-1)
679  sw3= omega_fac * zp(3*iold )
680  isl= indexl(i-1)+1
681  iel= indexl(i)
682  do j= isl, iel
683  !k= perm(itemL(j))
684  x1= zp(iteml(j))
685  sw1= sw1 - al(3*j-2)*x1
686  sw2= sw2 - al(3*j-1)*x1
687  sw3= sw3 - al(3*j )*x1
688  enddo ! j
689 
690  zp(3*iold-2)= alu(9*i-8)*sw1+alu(9*i-7)*sw2+alu(9*i-6)*sw3
691  zp(3*iold-1)= alu(9*i-5)*sw1+alu(9*i-4)*sw2+alu(9*i-3)*sw3
692  zp(3*iold )= alu(9*i-2)*sw1+alu(9*i-1)*sw2+alu(9*i )*sw3
693  enddo ! i
694 
695  !C-- BACKWARD
696  do i = n, 1, -1
697  sw1= 0.d0
698  sw2= 0.d0
699  sw3= 0.d0
700  isu= indexu(i-1) + 1
701  ieu= indexu(i)
702  do j= ieu, isu, -1
703  x1= zp(itemu(j))
704  sw1= sw1 + au(3*j-2)*x1
705  sw2= sw2 + au(3*j-1)*x1
706  sw3= sw3 + au(3*j )*x1
707  enddo ! j
708 
709  iold = perm(i)
710  zp(3*iold-2)= zp(3*iold-2) - alu(9*i-8)*sw1 - alu(9*i-7)*sw2 - alu(9*i-6)*sw3
711  zp(3*iold-1)= zp(3*iold-1) - alu(9*i-5)*sw1 - alu(9*i-4)*sw2 - alu(9*i-3)*sw3
712  zp(3*iold )= zp(3*iold ) - alu(9*i-2)*sw1 - alu(9*i-1)*sw2 - alu(9*i )*sw3
713  enddo ! i
714 
715  end if
716 
717  !OCL END_CACHE_SUBSECTOR
718  !OCL END_CACHE_SECTOR_SIZE
719 
720  !call stop_collection("loopInPrecond33")
721 
722 #endif
723  end subroutine
724 
725  subroutine hecmw_precond_ssor_33_clear(hecMAT)
726  implicit none
727  type(hecmwst_matrix), intent(inout) :: hecmat
728  if (associated(colorindex)) deallocate(colorindex)
729  if (associated(perm)) deallocate(perm)
730  if (associated(iperm)) deallocate(iperm)
731  if (associated(alu)) deallocate(alu)
732  if (associated(d)) deallocate(d)
733  if (associated(al)) deallocate(al)
734  if (associated(au)) deallocate(au)
735  if (associated(indexl)) deallocate(indexl)
736  if (associated(indexu)) deallocate(indexu)
737  if (associated(iteml)) deallocate(iteml)
738  if (associated(itemu)) deallocate(itemu)
739  nullify(colorindex)
740  nullify(perm)
741  nullify(iperm)
742  nullify(alu)
743  nullify(d)
744  nullify(al)
745  nullify(au)
746  nullify(indexl)
747  nullify(indexu)
748  nullify(iteml)
749  nullify(itemu)
750  initialized = .false.
751  end subroutine hecmw_precond_ssor_33_clear
752 
753 end module hecmw_precond_ssor_33
real(kind=kreal) function, public hecmw_mat_get_omega(hecMAT)
integer(kind=kint), parameter, public hecmw_precond_impl_csr
subroutine, public hecmw_mat_block_transpose_33(mat)
integer(kind=kint) function, public hecmw_mat_get_precond_impl(hecMAT)
integer(kind=kint), parameter, public hecmw_precond_impl_bsr
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 hecmw_precond_ssor_33_apply_inner(N, NP, ZP, AL, AU, D, ALU, itemL, itemU, indexL, indexU, perm, icToBlockIndex, blockIndexToColorIndex, NPL, NPU, NColor, numOfBlock, OMEGA_FAC)
subroutine, public hecmw_precond_ssor_33_apply(ZP)
subroutine hecmw_precond_ssor_33_apply_generic(ZP)
subroutine, public hecmw_precond_ssor_33_setup(hecMAT)
subroutine, public hecmw_precond_ssor_33_clear(hecMAT)
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
integer(kind=kint) function hecmw_comm_get_rank()
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)