hello, everyone,
Newbie of the fortran code. I was trying to use ilu0+gmres to solve Ax =b with A the csr format. But got the segment fault error when calling the subroutine. It seems that the arrays didn't pass successfully. Really confused about the error. Would anyone please help me about that? Thanks!
The variables are defined as :
integer nn, nnz
INTEGER, PARAMETER :: DP = SELECTED_REAL_KIND(14)
INTEGER, ALLOCATABLE, DIMENSION(:) :: irowJac
INTEGER, ALLOCATABLE, DIMENSION(:) :: icolJac
REAL(KIND=DP), ALLOCATABLE, DIMENSION(:) :: valJac
REAL(KIND=DP), ALLOCATABLE, DIMENSION(:) :: DeltaY,DeltaX
call LinearSolverCSR(nn, nnz,irowJac, icolJac,valJac, DeltaY)
The subroutine of the linear solver is as below:
SUBROUTINE LinearSolverCSR(N,NNZ,IA,JA,A,RHS)
INTEGER N
INTEGER NNZ
INTEGER SIZE
PARAMETER (SIZE=128)
INTEGER, PARAMETER :: DP = SELECTED_REAL_KIND(14)
INTEGER IA(N+1), JA(NNZ)
! DOUBLE PRECISION A(NNZ), RHS(N),COMPUTED_SOLUTION(N)
REAL(KIND=DP) A(NNZ), RHS(N),COMPUTED_SOLUTION(N), B(N)
DOUBLE PRECISION BILU0(NNZ), TRVEC(N)
!---------------------------------------------------------------------------
! Allocate storage for the ?par parameters and the solution/rhs/residual vectors
!---------------------------------------------------------------------------
INTEGER IPAR(SIZE),IERR
DOUBLE PRECISION DPAR(SIZE), TMP(N*(2*N+1)+(N*(N+9))/2+1)
DOUBLE PRECISION RESIDUAL(N)
INTEGER MATSIZE, INCX
DOUBLE PRECISION REF_NORM2, NRM2
PARAMETER ( INCX=1)
!---------------------------------------------------------------------------
! Some additional variables to use with the RCI (P)FGMRES solver
!---------------------------------------------------------------------------
INTEGER ITERCOUNT
INTEGER RCI_REQUEST, I
DOUBLE PRECISION DVAR
!---------------------------------------------------------------------------
! An external BLAS function is taken from MKL BLAS to use
! with the RCI (P)FGMRES solver
!---------------------------------------------------------------------------
DOUBLE PRECISION DNRM2
EXTERNAL DNRM2
!---------------------------------------------------------------------------
! Save the right-hand side in vector B for future use
!---------------------------------------------------------------------------
MATSIZE = NNZ
CALL DCOPY(N, RHS, 1, B, 1)
!---------------------------------------------------------------------------
! Initialize the solver
!---------------------------------------------------------------------------
CALL DFGMRES_INIT(N, COMPUTED_SOLUTION, RHS, RCI_REQUEST, IPAR,
1 DPAR, TMP)
IF (RCI_REQUEST.NE.0) GOTO 999
!---------------------------------------------------------------------------
! Calculate ILU0 preconditioner.
! !ATTENTION!
! DCSRILU0 routine uses some IPAR, DPAR set by DFGMRES_INIT routine.
! Important for DCSRILU0 default entries set by DFGMRES_INIT are
! ipar(2) = 6 - output of error messages to the screen,
! ipar(6) = 1 - allow output of error messages,
! ipar(31)= 0 - abort DCSRILU0 calculations if routine meets zero diagonal element.
!
! If ILU0 is going to be used out of MKL FGMRES context, than the values
! of ipar(2), ipar(6), ipar(31), dpar(31), and dpar(32) should be user
! provided before the DCSRILU0 routine call.
!
! In this example, specific for DCSRILU0 entries are set in turn:
! ipar(31)= 1 - change small diagonal value to that given by dpar(32),
! dpar(31)= 1.D-20 instead of the default value set by DFGMRES_INIT.
! It is a small value to compare a diagonal entry with it.
! dpar(32)= 1.D-16 instead of the default value set by DFGMRES_INIT.
! It is the target value of the diagonal value if it is
! small as compared to dpar(31) and the routine should change
! it rather than abort DCSRILU0 calculations.
!---------------------------------------------------------------------------
IPAR(31)=1
DPAR(31)=1.D-20
DPAR(32)=1.D-16
CALL DCSRILU0(N, A, IA, JA, BILU0, IPAR, DPAR, IERR)
NRM2=DNRM2(MATSIZE, BILU0, INCX)
IF(IERR.ne.0) THEN
WRITE(*,'(A,A,I1)') ' Error after calculation of the',
1 ' preconditioner DCSRILU0',IERR
GOTO 998
ENDIF
!---------------------------------------------------------------------------
! Set the desired parameters:
! do the restart after 2 iterations
! LOGICAL parameters:
! do not do the stopping test for the maximal number of iterations
! do the Preconditioned iterations of FGMRES method
! Set parameter IPAR(11) for preconditioner call. For this example,
! it reduces the number of iterations.
! DOUBLE PRECISION parameters
! set the relative tolerance to 1.0D-3 instead of default value 1.0D-6
! NOTE. Preconditioner may increase the number of iterations for an
! arbitrary case of the system and initial guess and even ruin the
! convergence. It is user's responsibility to use a suitable preconditioner
! and to apply it skillfully.
!---------------------------------------------------------------------------
IPAR(15)=2
IPAR(8)=0
IPAR(11)=1
DPAR(1)=1.0D-3
!---------------------------------------------------------------------------
! Check the correctness and consistency of the newly set parameters
!---------------------------------------------------------------------------
CALL DFGMRES_CHECK(N, COMPUTED_SOLUTION, RHS, RCI_REQUEST,
1 IPAR, DPAR, TMP)
IF (RCI_REQUEST.NE.0) GOTO 999
!---------------------------------------------------------------------------
! Print the info about the RCI FGMRES method, could be skipped 166-224
!---------------------------------------------------------------------------
WRITE( *,'(A)') ''
WRITE( *,'(A,A)') 'Some info about the current run of RCI FGMRES',
1 ' method:'
WRITE( *,'(A)') ''
IF (IPAR(8).NE.0) THEN
WRITE(*,'(A,I1,A,A)') 'As IPAR(8)=',IPAR(8),', the automatic',
1 ' test for the maximal number of iterations will be performed'
ELSE
WRITE(*,'(A,I1,A,A)') 'As IPAR(8)=',IPAR(8),', the automatic',
1 ' test for the maximal number of iterations will be skipped'
ENDIF
WRITE( *,'(A)') '+++'
IF (IPAR(9).NE.0) THEN
WRITE(*,'(A,I1,A,A)') 'As IPAR(9)=',IPAR(9),', the automatic',
1 ' residual test will be performed'
ELSE
WRITE(*,'(A,I1,A,A)') 'As IPAR(9)=',IPAR(9),', the automatic',
1 ' residual test will be skipped'
ENDIF
WRITE( *,'(A)') '+++'
IF (IPAR(10).NE.0) THEN
WRITE(*,'(A,I1,A,A)') 'As IPAR(10)=',IPAR(10),', the',
1 ' user-defined stopping test will be requested via RCI_REQUEST=2'
ELSE
WRITE(*,'(A,I1,A,A,A)') 'As IPAR(10)=',IPAR(10),', the',
1 ' user-defined stopping test will not be requested, thus,',
1 ' RCI_REQUEST will not take the value 2'
ENDIF
WRITE( *,'(A)') '+++'
IF (IPAR(11).NE.0) THEN
WRITE(*,'(A,I1,A,A)') 'As IPAR(11)=',IPAR(11),', the',
1 ' Preconditioned FGMRES iterations will be performed, thus,'
WRITE(*,'(A,A)') 'the preconditioner action will be requested',
1 ' via RCI_REQUEST=3'
ELSE
WRITE(*,'(A,I1,A,A)') 'As IPAR(11)=',IPAR(11),', the',
1 ' Preconditioned FGMRES iterations will not be performed,'
WRITE( *,'(A)') 'thus, RCI_REQUEST will not take the value 3'
ENDIF
WRITE( *,'(A)') '+++'
IF (IPAR(12).NE.0) THEN
WRITE(*,'(A,I1,A,A)')'As IPAR(12)=',IPAR(12),', the automatic',
1 ' test for the norm of the next generated vector is not'
WRITE( *,'(A,A)') ' equal to zero up to rounding and',
1 ' computational errors will be performed,'
WRITE( *,'(A)') 'thus, RCI_REQUEST will not take the value 4'
ELSE
WRITE(*,'(A,I1,A,A)')'As IPAR(12)=',IPAR(12),', the automatic',
1 ' test for the norm of the next generated vector is'
WRITE(*,'(A,A)') 'not equal to zero up to rounding and',
1 ' computational errors will be skipped,'
WRITE(*,'(A,A)') 'thus, the user-defined test will be requested',
1 ' via RCI_REQUEST=4'
ENDIF
WRITE( *,'(A)') '+++'
!---------------------------------------------------------------------------
! Compute the solution by RCI (P)FGMRES solver with preconditioning
! Reverse Communication starts here
!---------------------------------------------------------------------------
1 CALL DFGMRES(N, COMPUTED_SOLUTION, RHS, RCI_REQUEST, IPAR,
1 DPAR, TMP)
!---------------------------------------------------------------------------
! If RCI_REQUEST=0, then the solution was found with the required precision
!---------------------------------------------------------------------------
IF (RCI_REQUEST.EQ.0) GOTO 3
!---------------------------------------------------------------------------
! If RCI_REQUEST=1, then compute the vector A*TMP(IPAR(22))
! and put the result in vector TMP(IPAR(23))
!---------------------------------------------------------------------------
IF (RCI_REQUEST.EQ.1) THEN
CALL MKL_DCSRGEMV('N',N, A, IA, JA, TMP(IPAR(22)), TMP(IPAR(23)))
GOTO 1
ENDIF
!---------------------------------------------------------------------------
! If RCI_request=2, then do the user-defined stopping test
! The residual stopping test for the computed solution is performed here
!---------------------------------------------------------------------------
IF (RCI_REQUEST.EQ.2) THEN
! Request to the DFGMRES_GET routine to put the solution into B(N) via IPAR(13)
IPAR(13)=1
! Get the current FGMRES solution in the vector B(N)
CALL DFGMRES_GET(N, COMPUTED_SOLUTION, B, RCI_REQUEST, IPAR,
1 DPAR, TMP, ITERCOUNT)
! Compute the current true residual via MKL (Sparse) BLAS routines
CALL MKL_DCSRGEMV('N', N, A, IA, JA, B, RESIDUAL)
CALL DAXPY(N, -1.0D0, RHS, 1, RESIDUAL, 1)
DVAR=DNRM2(N, RESIDUAL, 1)
IF (DVAR.LT.1.0E-3) THEN
GOTO 3
ELSE
GOTO 1
ENDIF
ENDIF
!---------------------------------------------------------------------------
! If RCI_REQUEST=3, then apply the preconditioner on the vector
! TMP(IPAR(22)) and put the result in vector TMP(IPAR(23))
! Here is the recommended usage of the result produced by ILU0 routine
! via standard MKL Sparse Blas solver routine mkl_dcsrtrsv.
!---------------------------------------------------------------------------
IF (RCI_REQUEST.EQ.3) THEN
CALL MKL_DCSRTRSV('L','N','U',N,BILU0,IA,JA,TMP(IPAR(22)),TRVEC)
CALL MKL_DCSRTRSV('U','N','N',N,BILU0,IA,JA,TRVEC,TMP(IPAR(23)))
GOTO 1
ENDIF
!---------------------------------------------------------------------------
! If RCI_REQUEST=4, then check if the norm of the next generated vector is
! not zero up to rounding and computational errors. The norm is contained
! in DPAR(7) parameter
!---------------------------------------------------------------------------
IF (RCI_REQUEST.EQ.4) THEN
IF (DPAR(7).LT.1.0D-12) THEN
GOTO 3
ELSE
GOTO 1
ENDIF
!---------------------------------------------------------------------------
! If RCI_REQUEST=anything else, then DFGMRES subroutine failed
! to compute the solution vector: COMPUTED_SOLUTION(N)
!---------------------------------------------------------------------------
ELSE
GOTO 999
ENDIF
!---------------------------------------------------------------------------
! Reverse Communication ends here
! Get the current iteration number and the FGMRES solution. (DO NOT FORGET to
! call DFGMRES_GET routine as computed_solution is still containing
! the initial guess!). Request to DFGMRES_GET to put the solution into
! vector COMPUTED_SOLUTION(N) via IPAR(13)
!---------------------------------------------------------------------------
3 IPAR(13)=0
CALL DFGMRES_GET(N, COMPUTED_SOLUTION, RHS, RCI_REQUEST, IPAR,
1 DPAR, TMP, ITERCOUNT)
!---------------------------------------------------------------------------
! Print solution vector: COMPUTED_SOLUTION(N) and
! the number of iterations: ITERCOUNT
!---------------------------------------------------------------------------
WRITE( *,'(A)') ''
WRITE( *,'(A)') 'The system has been solved'
WRITE( *,'(A)') ''
WRITE( *,'(A)') 'The following solution has been obtained:'
DO I=1,N
WRITE(*,'(A18,I1,A2,E10.3)') 'COMPUTED_SOLUTION(',I,')=',
1 COMPUTED_SOLUTION(I)
ENDDO
WRITE( *,'(A)') ''
WRITE( *,'(A,I2)') 'Number of iterations: ',ITERCOUNT
WRITE( *,'(A)') ''
!---------------------------------------------------------------------------
! Release internal MKL memory that might be used for computations
!---------------------------------------------------------------------------
CALL MKL_FREE_BUFFERS
999 WRITE( *,'(A,I2)') 'The solver has returned the ERROR code ',
1 RCI_REQUEST
!---------------------------------------------------------------------------
! Release internal MKL memory that might be used for computations
! NOTE: It is important to call the routine below to avoid memory leaks
! unless you disable MKL Memory Manager
!---------------------------------------------------------------------------
998 WRITE( *,'(A)') ''
WRITE( *,'(A,A)') '---------------------------------------------',
1 '----------------------'
WRITE( *,'(A,A)') 'Unfortunately, FGMRES+ILU0 Fortran example',
1 ' has FAILED'
WRITE( *,'(A,A)') '---------------------------------------------',
1 '----------------------'
WRITE( *,'(A)') ''
CALL MKL_FREE_BUFFERS
STOP 1
DO I =1,N,1
RHS(I) = COMPUTED_SOLUTION(I)
ENDDO
END