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

sum on array longer than max value

Patrice_l_
Beginner
1,252 Views

Hi all,

I just discover than the sum intrinsic function use the type of the array ( I guess) to do the sum and therefor if the array is longer than the max value of type. I don't know if that is defined in the standard, is there a solution to this other than custom sum function ?

program sum1
integer(1),dimension(200) :: int1
integer(2),dimension(200000) :: int2

int1=1
int2=1
print *,sum(int1)
print *,sum(int2)
end program

 

Gives the results  -56   3392.

Thanks for your thoughts on this.

P.

 

0 Kudos
6 Replies
Steven_L_Intel1
Employee
1,252 Views

The standard doesn't allow for the result being a different "kind" from that of the argument, if that's what you're asking for. Your program creates a value that exceeds the range of the integer kind, therefore the program's behavior is not specified by the standard.

0 Kudos
Patrice_l_
Beginner
1,252 Views

Thanks Steve that was the question.

0 Kudos
TimP
Honored Contributor III
1,252 Views

sum(int(int2,int32)) is valid syntax under 'use iso_fortran_env' in case that is what you want.  If you omit ,int32 it should promote to default int kind.
 

0 Kudos
Patrice_l_
Beginner
1,252 Views

I think that this way generates a copy of the array first ?

I don't see that being a solution since this is done a lot of time on shiftting array.

0 Kudos
TimP
Honored Contributor III
1,252 Views

I suppose you could submit a feature request if you find this expression isn't optimized, as well as trying a DO loop.

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,252 Views

What you might consider doing is creating one or two generic functions. One returning an integer(4) and the other returning integer(8) (assuming you want the integer(8)). then make 4 dispatch routines based on the size of an element in the array.

function sum_4_2(x) result(ret)
  integer(2) :: x(:) ! get dimension from array descriptor on call
  integer(4) :: ret
  integer :: i
  ret = 0 ! not necessary, reduction implies zeroing, here for clarity of operation
  !DIR$ SIMD REDUCTION(+:ret)
  do i=lbound(x), ubound(x)
    ret = ret + int(x(i),kind(ret)) ! should optimize to _mm_cvtepi16_epi32
  end do
end function sum_4_2

You can add the interface and other routines.

Jim Dempsey

0 Kudos
Reply