Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29244 Discussions

sigsev with profiling and optimization, correct code otherwise

Izaak_Beekman
New Contributor II
987 Views
Hi,
I suspect that i have found a compiler bug. When I compile my code for profiling with the -p flag and with optimizations greater than O1 I encounter a sigsev. If I use less optimization or do not instrument the code for profiling I don't get a sigsev, and the code passes all tests. Sadly, we haven't deployed the latest version of the Intel compilers so it's possible this bug is not present in the new version.

[bash]12:19 PM (0) MPI-proj $ ifort -V
Intel Fortran Intel 64 Compiler Professional for applications running on Intel 64, Version 11.1    Build 20090630 Package ID: l_cprof_p_11.1.046
Copyright (C) 1985-2009 Intel Corporation.  All rights reserved.

12:22 PM (0) MPI-proj $ ifort -trace -p -O2 seqlife.f90 
12:22 PM (0) MPI-proj $ ./a.out life.data.1 100 250 250 > out
forrtl: severe (174): SIGSEGV, segmentation fault occurred
Image              PC                Routine            Line        Source             
a.out              00000000004049F6  gol_mp_wrt_living          68  seqlife.f90
a.out              00000000004030A5  MAIN__                    131  seqlife.f90
a.out              0000000000402CAC  Unknown               Unknown  Unknown
libc.so.6          0000003806E1D974  Unknown               Unknown  Unknown
a.out              0000000000402B79  Unknown               Unknown  Unknown
12:22 PM (0) MPI-proj $ ifort -trace -O2 seqlife.f90 
12:23 PM (0) MPI-proj $ ./a.out life.data.1 100 250 250 | sort -n | diff -s - life.data.1.100.250.250.out.sorted 
Files - and life.data.1.100.250.250.out.sorted are identical
12:24 PM (0) MPI-proj $ ifort -trace -p -O1 seqlife.f90 
12:24 PM (0) MPI-proj $ ./a.out life.data.1 100 250 250 | sort -n | diff -s - life.data.1.100.250.250.out.sorted 
Files - and life.data.1.100.250.250.out.sorted are identical
12:24 PM (0) MPI-proj $  uname -a
Linux XXXXXXXXXXX.XXXXXX.XXX.edu 2.6.18-128.el5 #1 SMP Wed Dec 17 11:41:38 EST 2008 x86_64 x86_64 x86_64 GNU/Linux[/bash]
Despite the name of the folder this code resides in, this is a serial code. The code is a simple/niave implementation of John Conway's game of life cellular automata. The code can be seen below:

[fortran]! $Id$
MODULE gol
  IMPLICIT NONE
  INTEGER, PARAMETER :: fl_rd_err = 50, no_handles = 49, bad_cmd_arg = 48
  INTEGER, PARAMETER :: mx_arg_l = 1024 ! Arbitrary but no pre-F2003 mechanism 
                                        ! to dynamically ALLOCATE mem for str

CONTAINS
  ! Read two integers from a text file, line by line
  ! is_eof is true once we reach the end, false otherwise
  SUBROUTINE rdln(handle,i,j,is_eof)
    INTEGER, INTENT(in)  :: handle
    INTEGER, INTENT(out) :: i, j
    LOGICAL, INTENT(out) :: is_eof
    INTEGER :: ios

    is_eof = .FALSE.
    READ(handle,*,iostat=ios) i, j ! Would like to explicitly set edit descriptor....
    IF (ios /= 0) is_eof = .TRUE.  ! assume no other errors encountered
  END SUBROUTINE rdln

  SUBROUTINE getfreehandle(handle)
    INTEGER, INTENT(out) :: handle
    INTEGER, PARAMETER :: start = 1, last = 1024 ! max open file handles on x86_64 RHEL5
    INTEGER :: i
    LOGICAL :: h_exists, h_is_used
    
    handle = -500 ! init to a bad value
    DO i = start, last
       INQUIRE(unit=i, exist=h_exists, opened=h_is_used)
       IF ( h_exists .AND. .NOT. h_is_used) THEN
          handle = i
          EXIT
       END IF
    END DO
    IF (handle == -500) STOP no_handles
  END SUBROUTINE getfreehandle

  SUBROUTINE parse_cmd_args(fl_name,ngen,xlim,ylim)
    CHARACTER(len=mx_arg_l), INTENT(inout) :: fl_name
    INTEGER,                 INTENT(out)   :: ngen, xlim, ylim
    CHARACTER(len=mx_arg_l) :: argn
    INTEGER :: argc

    argc = IARGC()
    CALL GETARG(0,argn)
    IF (argc /= 4) THEN
       WRITE(0,'(a)') 'Usage: '//TRIM(ADJUSTL(argn))//'  &
            &<# of generations>  ' ! 0 *should* be stderr
       STOP bad_cmd_arg
    END IF
    CALL GETARG(1,fl_name)
    CALL GETARG(2,argn)
    READ(argn,*) ngen
    CALL GETARG(3,argn)
    READ(argn,*) xlim
    CALL GETARG(4,argn)
    READ(argn,*) ylim
  END SUBROUTINE parse_cmd_args

  SUBROUTINE wrt_living(pop)
    LOGICAL, DIMENSION(0:,0:) :: pop
    INTEGER :: i, j, imx, jmx

    imx = UBOUND(pop,dim=1)
    jmx = UBOUND(pop,dim=2)
    DO j = 1,jmx-1
       DO i = 1,imx-1
          IF (pop(i,j)) WRITE(*,'(2(i0,1x))') i-1, j-1 ! Fortran starts at 1
       END DO
    END DO
  END SUBROUTINE wrt_living

  SUBROUTINE gol_kernel(ngen,pop)
    INTEGER,              INTENT(in) :: ngen
    LOGICAL, POINTER, DIMENSION(:,:) :: pop
    LOGICAL, POINTER, DIMENSION(:,:) :: old => NULL(), tmp => NULL()
    INTEGER(SELECTED_INT_KIND(1)) :: cnt ! small integer (always >= 0 & < 9)
    INTEGER :: imx, jmx, i, j, n
    
    imx = UBOUND(pop,dim=1)
    jmx = UBOUND(pop,dim=2)
    
    ALLOCATE(old(0:imx,0:jmx))
    old = pop
    
    imx = imx - 1
    jmx = jmx - 1
    DO n=1,ngen
       DO j=1,jmx
          DO i=1,imx
             cnt = COUNT(old(i-1:i+1,j-1)) + &
                   COUNT(old(i-1:i+1:2,j)) + &
                   COUNT(old(i-1:i+1,j+1))
             pop(i,j) = (old(i,j) .AND. (cnt == 2)) .OR. (cnt == 3)
          END DO
       END DO
       tmp => pop
       pop => old
       old => tmp ! can now rewrite pop
    END DO

    pop = old
    DEALLOCATE(old)
  END SUBROUTINE gol_kernel
    
END MODULE gol

PROGRAM tst
  USE gol
  IMPLICIT NONE
  CHARACTER(len=mx_arg_l) :: fl_name
  INTEGER :: ngen, imx, jmx, i, j, h
  LOGICAL, POINTER :: pop(:,:) => NULL()
  LOGICAL :: is_eof
  
  CALL parse_cmd_args(fl_name,ngen,imx,jmx)
  ALLOCATE(pop(0:imx+1,0:jmx+1))
  pop = .FALSE.
  CALL getfreehandle(h)
  OPEN(unit=h,file=fl_name,status='old',action='read')
  DO ! Read in IC
     CALL rdln(h,i,j,is_eof)
     IF (is_eof) EXIT
     pop(i+1,j+1) = .TRUE. ! Fortran indices start at 1
  END DO
  CLOSE(h)

  CALL gol_kernel(ngen,pop)

  CALL wrt_living(pop)
  DEALLOCATE(pop)
END PROGRAM tst
[/fortran]
I have also attached the code as an attachment. Not that the line returned by -trace is the head of a DO loop block.

Thanks for having a look,
Z

0 Kudos
5 Replies
Kevin_D_Intel
Employee
987 Views

I confirmed the error you detailed with 11.1.046 and verified it does not occur with Version 11.1 Build 20101201(Linux:l_cprof_p_11.1.080) soafix appears to be available in this update .

FYI -the life.data.1 input file thatI created only contained1 10 which was sufficient to recreate the error.

0 Kudos
mecej4
Honored Contributor III
987 Views
Please attach the needed data file so that the error can be reproduced.
0 Kudos
Izaak_Beekman
New Contributor II
987 Views
Sorry about that. I suspect the bug is independant of the data file, but here you go. Please see attachment.
0 Kudos
jimdempseyatthecove
Honored Contributor III
987 Views
Try changing:

SUBROUTINE wrt_living(pop)
LOGICAL, DIMENSION(0:,0:) :: pop ! assumed size

to:


SUBROUTINE wrt_living(pop)
LOGICAL, DIMENSION(:,:) :: pop ! assumed shape

Jim Dempsey
0 Kudos
Izaak_Beekman
New Contributor II
987 Views
Jim,
The solution to me is to compile the code without optimization for profiling or use intel profilers. Even If I were to change the code my version is correct Fortran 95, there's no reason that the compiler shouldn't support it, and it appears that the bug has been fixed in later versions already.
0 Kudos
Reply