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

compiling options "check uninit" and "check bound"

antony_muthu__Anto_J
1,261 Views
Hi,
I have a problem understanding the use of compiling options "check uninit" and "check bound".
I am debugging a code and I have created a Makefile where I can choose between a "debug" version and a "release" version. The only difference between both version is that in debug I'm using the options"check uninit" and "check bound" with traceback. I understand that these options will execute my program as normal but they will give me a runtime error when they find an uninitialed variable or and bound violation. When I execute the debug version I don't obtain any runtime error but the results of my execution are different than when I run the release version.
Could anyone help?
Thanks,
Jos.
0 Kudos
7 Replies
Ron_Green
Moderator
1,261 Views
keep in mind that -check uninit and -check bounds are limited in their capabilities. These will not catch all access violations (read the documentation on these options for what they do catch, and what they will not catch ).

For numerics, you can try

-fpmodel precise
or
-fpmodel strict

if your goal is to get the same results between a debug and optimized build.

ron
0 Kudos
tom_p
Beginner
1,261 Views
Just a wild guess: check uninit does not catch uninitialized arrays, and enabling checks at least in some cases changes the values of uninitialized arrays.
0 Kudos
jimdempseyatthecove
Honored Contributor III
1,261 Views
Quoting tom_p
Just a wild guess: check uninit does not catch uninitialized arrays, and enabling checks at least in some cases changes the values of uninitialized arrays.

You can add some conditional code that pre-initializes arrays to a "magic number". Note, in Debug Build on Windows uninitialized data gets 0xcacacaca... (full of ca ca), I do not know what your version of Linux does in debug build. Then prior to use, insert conditional code that test for uninitialized data (0xcacacaca... or whatever your "magic number" is).

Also note that different results are not necessarily wrong results. Parallel and/or vector code may produce different results from serial code depending on how (when) rounding occurs.

Jim Dempsey

0 Kudos
Olivier_C_
New Contributor I
1,261 Views
Hi Jose,

I recommend you use "-check all" as well as -ftrapuv to aid error detection related to stack variables.
Personnally, I also use "-warn all" to get more messages at compile time.
Arithmetics can be mastered using "-fp-model strict" to comply with the IEEE-754 standard on double precision real numbers.
The Intel compiler and processors can comply strictly to it, so there should be no difference between debug and optimized program, unless you have programming errors.
To aid for memory misusage you can link with "-lefence" or run with valgrind --tool=memcheck.

Be aware that check bounds is a run-time check that any locally used array index is not "out of the bounds" of the array according to it's local definition.
Take a glance at the following erroneous program that fails when linked with efence
<<
! Compile:
! ifort -g -traceback -check all -warn all -ftrapuv toto.f90 -lefence
! Execute:
! ./a.out 3
subroutine afftab(n, tab)
integer :: n
integer, dimension(n+1) :: tab ! Local range is not correct but no check is done between programming units
integer :: i
do i=1, n+1 ! index n+1 is an access violation, but "in the bounds" of the local definition
print*,'i=',i,tab(i)
enddo
end subroutine afftab
program toto
integer, dimension(:), allocatable :: tab
integer :: n
integer :: i
character(len=32) :: arg
call get_command_argument(1, arg)
read(arg, *) n
print*,'n=',n
allocate(tab(n))
do i=1, n
tab(i) = i
enddo
call afftab(n, tab)
end program toto
>>
Without efence, you get no SEGV on a standard Linux system, no "uninit" message, no "out of bounds":
./a.out 3
n= 3
i= 1 1
i= 2 2
i= 3 3
i= 4 0
With efence:
LD_PRELOAD=/usr/lib64/libefence.so.0 ./a.out 3

Electric Fence 2.2.0 Copyright (C) 1987-1999 Bruce Perens
n= 3
i= 1 1
i= 2 2
i= 3 3
forrtl: severe (174): SIGSEGV, segmentation fault occurred
Image PC Routine Line Source
a.out 0000000000402E2F afftab_ 10 toto.f90
a.out 00000000004034E4 MAIN__ 25 toto.f90
a.out 0000000000402AFC Unknown Unknown Unknown
libc.so.6 00002BA9B8358074 Unknown Unknown Unknown
a.out 0000000000402A29 Unknown Unknown Unknown

Next, be aware that if you access data at a wrong index in an allocated array, there is no automatic tool on earth that can detect that for you ! So, some memory errors are fairly undetectable.
Hope it helps.
Olivier.
0 Kudos
antony_muthu__Anto_J
1,261 Views
First of all thanks for your quick replies.
My problem is that I am debugging a code which shows "bad" behavior after 20 minutes running and it dies after 45 minutes running. So I was thinking it may be rounding errors, some uninitialized variable problem or some bound violation. I thought that enabling check will report possible errors but will not change the uninitialized values.
Jos.
0 Kudos
TimP
Honored Contributor III
1,261 Views
-check bounds adds code to perform checks at run time. This could alter the effective initial value in certain cases of undefined data. I don't believe -check uninit (compile time only check) by itself should have any such effect.
0 Kudos
Steven_L_Intel1
Employee
1,261 Views
If you don't have it already, try a free evaluation of Intel Parallel Studio XE. You can use the Static Security Analysis feature to look for problems across your program and can also use the memory checker feature of Intel Inspector to look for dynanic memory issues.
0 Kudos
Reply