Intel® oneAPI Math Kernel Library
Ask questions and share information with other developers who use Intel® Math Kernel Library.

segment fault error for fortran code

Maggie_m_
Beginner
966 Views

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
0 Kudos
1 Solution
mecej4
Honored Contributor III
966 Views

The TMP array is rather large and there may not be enough stack space for it.

Please zip (or use tar -zcf ... to create a compressed tar archive) and attach the source code archive to a reply, using the "Attach Media" button. Someone may then look into the problem.

View solution in original post

0 Kudos
11 Replies
mecej4
Honored Contributor III
966 Views

Not much can be done with the code fragments that you have given. The code is not complete, so it cannot be run to duplicate the seg-fault, and the parts that you gave are too long to check by visual inspection. Which MKL example code did you use as a basis for developing the code that you posted?

0 Kudos
Maggie_m_
Beginner
966 Views

I used fgmres_full_funct_f.f and changed it as a subroutine. The main problem is the variables IA,JA,A,RHS have not been passed successfully. When I tried to print info of IA, JA, A in the subroutine, it turned out these variables got segment fault.  I checked the stack size

$limit

stacksize 10240 kbytes

The size of IA is 33140.  JA ,A  are 234808.  Not sure about whether this is because of the stack size. 

 

0 Kudos
mecej4
Honored Contributor III
967 Views

The TMP array is rather large and there may not be enough stack space for it.

Please zip (or use tar -zcf ... to create a compressed tar archive) and attach the source code archive to a reply, using the "Attach Media" button. Someone may then look into the problem.

0 Kudos
Maggie_m_
Beginner
966 Views

Thank for reply.  Yes, the reason is tmp is too large.  Don't know whether there is a better idea to figure this out since this is too large memory requirement, even more than storing the whole matrix. 

0 Kudos
TimP
Honored Contributor III
966 Views

Among remedies for stack overflow are setting larger stack or -heap-array compile option.

0 Kudos
TimP
Honored Contributor III
966 Views

Most operating systems have a means for raising stack limit, while most fortrans have an option like ifort -heap-arrays to cause allocations to use heap rather than stack.  You may need to use 64-bit (Intel64) mode and make the big array allocatable.

0 Kudos
mecej4
Honored Contributor III
966 Views

Maggie m. wrote:

Thank for reply.  Yes, the reason is tmp is too large.  Don't know whether there is a better idea to figure this out since this is too large memory requirement, even more than storing the whole matrix. 

One solution is to allocate TMP on the heap by declaring TMP as ALLOCATABLE and allocating it in the subroutine, before passing it as an argument to other subroutines.

0 Kudos
Maggie_m_
Beginner
966 Views

I am back.  After allocating the parameter arrays,  I got such error in DCSRILU0: 

Intel MKL DCSRILU0 ERROR: 
Cannot proceed with calculations as input
matrix column indexes are not in increasing order.
ilu end
forrtl: severe (174): SIGSEGV, segmentation fault occurred
 
 
When I delete the ILU,  I got the errors: 
 
dfgmres check begin
dfgmres check end
Some info about the current run of RCI FGMRES method:
 
As ipar[7]=1, the automatic test for the maximal number of iterations will be
performed
+++
As ipar[8]=1, the automatic residual test will be performed
+++
As ipar[9]=0, the user-defined stopping test will not be requested, thus,
RCI_request will not take the value 2
+++
As ipar[10]=0, the Preconditioned FGMRES iterations will not be performed,
thus, RCI_request will not take the value 3
+++
As ipar[11]=1, the automatic test for the norm of the next generated vector is
not equal to zero up to rounding and computational errors will be performed,
thus, RCI_request will not take the value 4
+++
 
The solver has returned the ERROR code -1 .
 
Any suggestions?  Thanks!
0 Kudos
mecej4
Honored Contributor III
966 Views

Please post the complete source code using either (i) the {code} button at the right of the toolbar when you reply in this forum, or (ii) as a file attachment using the "Attach media/Browse" button at the bottom left of the comment window.

0 Kudos
Maggie_m_
Beginner
966 Views

I  tried to print out the matrix in csr format. But got another issue here. 

https://software.intel.com/en-us/forums/topic/560493

 

0 Kudos
Ying_H_Intel
Employee
966 Views

Hi Maggie, 

There are some code errors in your code.  For example, i mentioned, the function required 1 -based index whatever in C or fortran. 

and the array ipar and dpar should be 128 . not N. 

and the  bilu0 = (double *)calloc(*NNZ, sizeof(double)) , not NN etc.

remove some correct conditions which is in original sample code, you don't need when solve the Ax=b.. 

I attach the modify code for your reference. 

Best Regards,

Ying 

 

[yhu5@prc-mic01 mklex]$ make
ifort -check bounds -g -traceback -i8 -openmp -w -fast -DMKL_ILP64 -m64 -I/opt/intel/mkl/include/intel64/ilp64 -I/opt/intel/mkl/include  -c hypretest.f
icc -g -traceback -i8 -openmp -w -fast -DMKL_ILP64 -m64 -I/opt/intel/mkl/include/intel64/ilp64 -I/opt/intel/mkl/include  -c LinearSolver.c
ifort -check bounds -g -traceback hypretest.o LinearSolver.o -L/opt/intel/mkl/lib/intel64 -lmkl_intel_ilp64 -lmkl_intel_thread -lmkl_blas95_ilp64 -lmkl_lapack95_ilp64 -liomp5 -lmkl_core  -lm -lpthread -o ds
[yhu5@prc-mic01 mklex]$ ./ds
 number of rows =                     10
 number of nonzeros =                     28
sizetmpi= 306, sizeof(ia)= 8
N=10, NNZ= 28
LinearSolver: Line 48
dfgmres_init
dfgmres_end
ilu begin
ilu end
dfgmres check begin
dfgmres check end
Some info about the current run of RCI FGMRES method:

As ipar[7]=0, the automatic test for the maximal number of iterations will be
skipped
+++
As ipar[8]=0, the automatic residual test will be skipped
+++
As ipar[9]=1 the user-defined stopping test will be requested via
RCI_request=2
+++
As ipar[10]=1, the Preconditioned FGMRES iterations will be performed, thus,
the preconditioner action will be requested via RCI_request=3
+++
As ipar[11]=0, the automatic test for the norm of the next generated vector is
not equal to zero up to rounding and computational errors will be skipped,
thus, the user-defined test will be requested via RCI_request=4
+++

dfgmres begin to solve
dfgmres end of solve
dfgmres end of solve
dfgmres end of solve
dfgmres end of solve
dfgmres end of solve
dfgmres end of solve
The system has been solved

Number of iterations: 1

 b(                     1 )=   1.00000000000000
 b(                     2 )=   1.00000000000000
 b(                     3 )=   1.00000000000000
 b(                     4 )=   1.00000000000000
 b(                     5 )=   1.00000000000000
 b(                     6 )=   1.00000000000000
 b(                     7 )=   1.00000000000000
 b(                     8 )=   1.00000000000000
 b(                     9 )=   1.00000000000000
 b(                    10 )=   1.00000000000000
[yhu5@prc-mic01 mklex]$

0 Kudos
Reply