- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks Steve that was the question.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I suppose you could submit a feature request if you find this expression isn't optimized, as well as trying a DO loop.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page