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

Problem with optimisation in Intel Fortran 11.0

Deleted_U_Intel
Employee
1,231 Views
We encountered a problem with Intel Fortran 11.0 and optimisation flag -O2. Belowis a sample
program that exhibits this.

When we compile it using -O0 or -O1 and run it, the output is:

openings check for cms8 = OK.

With the default flags (-O2 IIRC):

forrtl: severe (71): integer divide by zero
Image PC Routine Line Source
main168a.exe 0809D3F1 Unknown Unknown Unknown
main168a.exe 0804A578 Unknown Unknown Unknown
main168a.exe 08049C71 Unknown Unknown Unknown
libc.so.6 0020EE23 Unknown Unknown Unknown
main168a.exe 08049B91 Unknown Unknown Unknown

Ifthe statement marked with (*) is changed to:
100 lexpr = (...)
if ( lexpr ) then

it behaves correctly.

Can you confirm this misbehaviour?

(I hope the pasted code retains its formatting ...)

Regards,

Arjen Markus

--- main program ---
program main168c
!
! main program to run wap168c
!

integer, parameter :: nto = 23
integer :: ibnd, iopen(nto,4)

iopen( 1,:) = (/ 59, 1, 51, 1/)
iopen( 2,:) = (/ 51, 1, 39, 1/)
iopen( 3,:) = (/ 39, 1, 27, 1/)
iopen( 4,:) = (/ 27, 1, 15, 1/)
iopen( 5,:) = (/ 15, 1, 2, 1/)
iopen( 6,:) = (/ 1, 2, 1, 19/)
iopen( 7,:) = (/ 1, 19, 1, 35/)
iopen( 8,:) = (/ 1, 35, 1, 55/)
iopen( 9,:) = (/ 1, 55, 1, 63/)
iopen(10,:) = (/ 1, 63, 1, 71/)
iopen(11,:) = (/ 1, 71, 1, 87/)
iopen(12,:) = (/ 1, 87, 1, 103/)
iopen(13,:) = (/ 1, 103, 1, 117/)
iopen(14,:) = (/ 2, 118, 15, 131/)
iopen(15,:) = (/ 15, 131, 27, 143/)
iopen(16,:) = (/ 27, 143, 43, 159/)
iopen(17,:) = (/ 43, 159, 47, 163/)
iopen(18,:) = (/ 47, 163, 51, 167/)
iopen(19,:) = (/ 51, 167, 56, 172/)
iopen(20,:) = (/ 57, 173, 75, 173/)
iopen(21,:) = (/ 75, 173, 91, 173/)
iopen(22,:) = (/ 91, 173, 115, 173/)
iopen(23,:) = (/115, 173, 135, 173/)

ibnd = nto + 1
call wap168 (iopen, ibnd - 1)

write (*,*) 'openings check for cms8 = OK.'

end program

--- routine wap168 ---

subroutine wap168 (iopen, nbnd)
c
c
c INPUT / OUTPUT PARAMETERS
c
implicit none

integer nbnd, iopen(nbnd,4)

c
c iopen i array containing open boundaries
c nbnd i number of valid openings
c
c LOCAL PARAMETERS
c
integer ibnd, ibnd2
integer mstart, mstcur, mend, mencur
integer nstart, nstcur, nend, nencur
integer incrmc, incrnc, incrn, incrm
integer m, mc, n, nc, mcmax, m2max, ncmax, n2max
integer ncstep, n2step, icstep, i2step
c
c --- loop over reference opening
c
do 400 ibnd=1, nbnd
c
c --- determine start and end values of m and n for current segment
c
mstcur = iopen(ibnd,1)
mencur = iopen(ibnd,3)
nstcur = iopen(ibnd,2)
nencur = iopen(ibnd,4)
c
c --- determine increment of m and n:
c (assume that a line segment is either horizontal,
c vertical or diagonal!)
c
if (mencur .ne. mstcur) then
incrmc = 1
else
incrmc = 0
endif

if (nencur .ne. nstcur) then
incrnc = 1
else
incrnc = 0
endif
c
c --- loop over second opening
c
do 300 ibnd2 = ibnd + 1, nbnd
c
c --- determine start and end values of segment to compare
c with current segment
c
mstart = iopen(ibnd2,1)
mend = iopen(ibnd2,3)
nstart = iopen(ibnd2,2)
nend = iopen(ibnd2,4)
c
c --- determine increment of m and n:
c (assume that a line segment is either horizontal,
c vertical or diagonal!)
c
if (mend .ne. mstart) then
incrm = 1
else
incrm = 0
endif

if (nend .ne. nstart) then
incrn = 1
else
incrn = 0
endif
c
c --- preparations for the loop over the current segment;
c do not include the first and last point of this
c segment, since these are allowed to coincide with
c other openings
c
mc = min (mstcur, mencur)
nc = min (nstcur, nencur)

mcmax = max (mstcur, mencur) - 2 * incrmc
ncmax = max (nstcur, nencur) - 2 * incrnc

ncstep = max (mcmax - mc, ncmax - nc)
if (mstcur .eq. mencur .and. nstcur .eq. nencur) then
ncstep = -1
endif
icstep = 0
c
c --- loop over the points of the 'current line segment';
c this is a while loop:
c (*)
100 if (mc .le. mcmax .and.
+ nc .le. ncmax .and. icstep .le. ncstep) then

mc = mc + incrmc
nc = nc + incrnc
icstep = icstep + 1
c
c --- preparations for the loop over the 2nd segment;
c this time: DO include the first and last point of this
c segment
c
m = min (mstart, mend) - incrm
n = min (nstart, nend) - incrn

m2max = max (mstart, mend) - incrm
n2max = max (nstart, nend) - incrn

n2step = max (m2max - m, n2max - n)
i2step = 0
c
c --- now loop over the points of the 2nd line segment;
c this is a while loop:
c
200 if (m .le. m2max .and.
+ n .le. n2max .and. i2step .le. n2step) then

m = m + incrm
n = n + incrn
i2step = i2step + 1
c
c --- test if the points of the two segments concur;
c if so, issue an error message and STOP!
c
if (m .eq. mc .and. n .eq. nc) then

write (*,*) 'Error'
stop

endif

goto 200
c
c --- end of loop over '2nd segment'
c
endif

goto 100
c
c --- end of loop over 'current segment'
c
endif

300 continue
400 continue

end
0 Kudos
3 Replies
TimP
Honored Contributor III
1,231 Views
After a tedious bit of reformatting, I see that -vec- option is required to avoid the failure. Not surprisingly, introducing DO WHILE doesn't help. It's worth a problem report on premier.intel.com. It looks like a compiler phase by phase test will be needed to isolate this.
0 Kudos
TimP
Honored Contributor III
1,231 Views
Same problem with current compilers, after tedious reformatting. -vec- avoids the failure. No difference with DO WHILE. This will need phase by phase testing to find the failure, so a problem submission on premier.intel.com would be appropriate.
0 Kudos
TimP
Honored Contributor III
1,231 Views
Quoting - arjen.markus
How do I submit a problem report on premier.intel.com?


If you haven't registered an Intel software product such as ifort, you would use your serial number to create an account at https://registrationcenter.intel.com log into the account and file a problem report.
0 Kudos
Reply