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

Illegal instruction when calling subroutine

Andrea_J_
Beginner
2,400 Views

I am getting a runtime error that simply says "Illegal instruction". I am compiling fortran90 code with the Intel Fortran Compiler XE. I have tried to attempt to narrow down what is causing the error message, and it seems to be something in the declaration of variables. 

The error is occurring when the subroutine "DataInput" is called. The error message prints, and the program exits before the message "Opening temperature file" is displayed.

What is the problem here?

Here is a sample of my code

Main program:

program findCIN
  use kinds
  use fileio
  implicit none

  integer, parameter :: nx = 2048       ! number of boxes in the x-dir
  integer, parameter :: ny = 2048       ! number of boxes in the y-dir
  integer, parameter :: nz = 255         ! number of boxes in the z-dir

  real(wp) :: t(nz,nx,ny)        ! temperature
  real(wp) :: q(nz,nx,ny)       ! moisture
  real(wp) :: z(nz)                 ! heights
  real(wp) :: p(nz)                 ! pressures

!---------------------------- PRE PROCESSING -----------------------------------
! Read in data

  print *, "Reading data..."

  call DataInput(nx,ny,nz,t,q,z,p)
....
....
....
end program findCIN

------------------------------------------------------------------------------------

Calling module/subroutine

module fileio
  use kinds
  use netcdf
  implicit none

contains
!-------------------------------------------------------------------------------
subroutine DataInput(nx,ny,nz,t,q,z,p)
  integer, intent(in) :: nx,ny,nz           ! variable dims
  real(wp), intent(out) :: t(nz,nx,ny)   ! temperature
  real(wp), intent(out) :: q(nz,nx,ny)  ! specific humidity
  real(wp), intent(out) :: z(nz)            ! heights
  real(wp), intent(out) :: p(nz)            ! pressures
 
  real(wp) :: t4d(nz,nx,ny,1)           ! temp from file has singlet time dimension
  real(wp) :: q4d(nz,nx,ny,1)           ! moisture from file has singlet time dimension

  character(len = *), parameter :: t_file = 'myfileT.nc'
  character(len = *), parameter :: q_file = 'myfileQ.nc'

  integer :: ncid,varid,p_id,z_id

! Read temperature file and dimensions

  print *, "Opening temperature file"

  call check(nf90_open(t_file,nf90_nowrite,ncid))       ! open file

  print *, "Temperature file opened"

  call check(nf90_inq_varid(ncid,"TABS",varid))         ! get temp. variable ID
  call check(nf90_inq_varid(ncid,"pres",p_id))          ! get pres. variable ID
  call check(nf90_inq_varid(ncid,"z",z_id))             ! get height variable ID

  print *, "Temperature variables identified"

  call check(nf90_get_var(ncid,varid,t4d))              ! read temperature
  call check(nf90_get_var(ncid,p_id,p))                 ! read pressure
  call check(nf90_get_var(ncid,z_id,z))                 ! read height

  print *, "Temperature variables read"

  call check(nf90_close(ncid))                          ! close temperature file

  print *, "Done reading file: ", t_file


! Read moisture file
  call check(nf90_open(q_file,NF90_NOWRITE,ncid))

  print *, "Moisture file opened"

  call check(nf90_inq_varid(ncid,"QV",varid))

  print *, "Moisture variable identified"

  call check(nf90_get_var(ncid,varid,q4d))

  print *, "Moisture variable read"

  call check(nf90_close(ncid))

  print *, "Done reading file", q_file

! Remove singleton dimensions from temp and moisture variables

  t = t4d(:,:,:,1)
  q = q4d(:,:,:,1)

return
end subroutine DataInput
end module fileio
!-------------------------------------------------------------------------------

 

0 Kudos
1 Solution
Kevin_D_Intel
Employee
2,400 Views

Just a guess that the values of nx,ny,nz might be leading to sufficiently large array temporaries or the automatic arrays (t4d, q4d) that exhaust the shell stack limit (ulimit -s).

I have seen "illegal instruction" in the past related to this as well as the infamous segmentation fault. See if some of the guidance in the article about Determining Root Cause of Segmentation Faults SIGSEGV or SIGBUS errors helps avoid this.

Maybe you could consider making t4d and 14d allocatable within the subroutine. A good reference is the Dr. Fortran Article "Don't Blow Your Stack!"

View solution in original post

0 Kudos
4 Replies
Kevin_D_Intel
Employee
2,401 Views

Just a guess that the values of nx,ny,nz might be leading to sufficiently large array temporaries or the automatic arrays (t4d, q4d) that exhaust the shell stack limit (ulimit -s).

I have seen "illegal instruction" in the past related to this as well as the infamous segmentation fault. See if some of the guidance in the article about Determining Root Cause of Segmentation Faults SIGSEGV or SIGBUS errors helps avoid this.

Maybe you could consider making t4d and 14d allocatable within the subroutine. A good reference is the Dr. Fortran Article "Don't Blow Your Stack!"

0 Kudos
Andrea_J_
Beginner
2,400 Views

Kevin, making my t4d and q4d arrays allocatable (and then immediately allocating them a couple lines down) solved the problem. Thank you for your help!

0 Kudos
Kevin_D_Intel
Employee
2,400 Views

Excellent, glad to hear that!

0 Kudos
jimdempseyatthecove
Honored Contributor III
2,400 Views

Andrea,

I caution you as to if you should consider your problem solved until further investigation. True, the illegal instruction crash stopped, but the underlying problem may still be present. Explanation:

When a program allocates too much on stack, the symptom is (possibly always) manifests itself as a SIGSEGV/SEGBUS error. This is to say NOT as an illegal instruction. Illegal instruction usually has two sources:

a) Compiler optimization switch specifying the target machine has a (single) specific architecture and to code to that architecture (but then run the program on a different incompatible architecture. The crash occurred in one case due to luck/unluck of code generation.

b) The stack temporary array being addressed outside of bounds and where the written data overwrites prior stack frame data (e.g. the return address).

c) Compiler bug.

In the case of b), the use of allocatable arrays will fix the overwriting of a return address (stack variable) but will not avoid overwriting memory outside the range of the allocation. Note, my advice is not to say you have this situation, rather that you may have this situation. Please enable array index out of bounds checking, at least once for a test, then remove when you are confident that the problem is resolved. Test using the same size of data that caused the error condition.

Jim Dempsey

0 Kudos
Reply