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

ifort real*4 count bug

志强_赵_
Beginner
477 Views
Recently, I wrote a piece of codes, like that below. The value of num is larger than the range of integer 32.
The result of the tmp should be 2. But in that code, the program gave 0. No matter if use ifort 13.0.0 or 15.0.0. If I change the tmp from real*4 to real*8, the result is correct. Ang idea?


integer*8,parameter :: num = 2500000000
integer*8 :: i
real*4,dimension(:),allocatable :: a
real*4 :: tmp

allocate(a(num))
a = 0.0e0

do i = 1, num
   if(i.eq.1) then
      a(1) = 1.0e0
   else if(mod(i, 2).eq.0) then
      a(i) = 1.0e0
   else
      a(i) = -1.0e0
   end if
end do
   

tmp = 0.0e0
do i = 1, num
   tmp = tmp + a(i)
end do

print*, tmp

end

 

0 Kudos
9 Replies
jimdempseyatthecove
Honored Contributor III
477 Views

From the IVF documentation:

The iteration count is determined as follows:
      MAX(INT((expr2 - expr1 + expr3)/expr3), 0)

MAX and INT returns (type/byte size) is dependent upon the type of the interior expressions. try using

do i=1_8, num

for both your loops.

If this does not correct the matter, then structure your loops as:

i = 0_8
do
  i=i+1_8
  if(i > num) exit
  ... your code here
end do

 

Jim Dempsey

0 Kudos
Steven_L_Intel1
Employee
477 Views

I don't think the issue is with the loop control values. Is your code REALLY like that? The whole thing could be calculated based on the value of num in a single expression, and wouldn't need terabytes of storage. I can't run your program as-is, but if I rework it to avoid use of the array and just add to tmp in a loop, I get the value 2.

0 Kudos
志强_赵_
Beginner
477 Views

Dear jimdempseyatthecove:

Just like Steve replyed, if I don't use the array, I can get the correct. So I don't think it's the cause of the max loop.

And when I set the type of tmp to real*8, the result is also correct.

jimdempseyatthecove wrote:

From the IVF documentation:

The iteration count is determined as follows:
      MAX(INT((expr2 - expr1 + expr3)/expr3), 0)

MAX and INT returns (type/byte size) is dependent upon the type of the interior expressions. try using

do i=1_8, num

for both your loops.

If this does not correct the matter, then structure your loops as:

i = 0_8
do
  i=i+1_8
  if(i > num) exit
  ... your code here
end do

 

Jim Dempsey

0 Kudos
志强_赵_
Beginner
477 Views

Dear Steve:

Could you run my code as I post? Actually this code is part of another test.

If I don't use the array, the result is 2.0. 

The difference is that I use the array here.

And I don't think it's the problem of valuing the array, because if change the type of tmp from real*4 to real*8, the result is 2.0.

So, if you want to see the issue, you should use an array and use the type of tmp being real*4.

The point is that why a single expression can't be a sum variable for the array, while the double expression can be?

Steve Lionel (Intel) wrote:

I don't think the issue is with the loop control values. Is your code REALLY like that? The whole thing could be calculated based on the value of num in a single expression, and wouldn't need terabytes of storage. I can't run your program as-is, but if I rework it to avoid use of the array and just add to tmp in a loop, I get the value 2.

0 Kudos
Steven_L_Intel1
Employee
477 Views

You're just adding 1 or -1 in a loop, that should not be a problem. But I can't run the program with a count of 2500000000, which requires allocation of 10GB, on my system. Can you reproduce the problem with a smaller count?

0 Kudos
志强_赵_
Beginner
477 Views

Yes, I reduce one zero, set the count to 250000000 which has been the range of integer-32. The problem is still there.

When I reduce one zero again, the problem disappear.

I test it with ifort 13.0.0  and ifort 15.0.0 

Steve Lionel (Intel) wrote:

You're just adding 1 or -1 in a loop, that should not be a problem. But I can't run the program with a count of 2500000000, which requires allocation of 10GB, on my system. Can you reproduce the problem with a smaller count?

0 Kudos
IanH
Honored Contributor II
477 Views

志强 赵. wrote:

integer*8,parameter :: num = 2500000000

Maybe there are issues elsewhere, but the right hand side of that initializer has a value that is too big for the kind of the initializer.  Make it `2500000000_8`.

 

0 Kudos
志强_赵_
Beginner
477 Views

No, it's not the reason. But if I add the option -fp-model strict, the result is correct

IanH wrote:

Quote:

志强 赵. wrote:

 

integer*8,parameter :: num = 2500000000

 

 

Maybe there are issues elsewhere, but the right hand side of that initializer has a value that is too big for the kind of the initializer.  Make it `2500000000_8`.

 

0 Kudos
Steven_L_Intel1
Employee
477 Views

Interesting - probably related to vectorization. We'll take a closer look.

0 Kudos
Reply