- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

For the code

module pure_binary_funcs_mod

implicit none

contains

pure function add(i,j) result(sum_ij)

integer, intent(in) :: i, j

integer :: sum_ij

sum_ij = i + j

end function add

!

pure function mult(i,j) result(prod_ij)

integer, intent(in) :: i, j

integer :: prod_ij

prod_ij = i*j

end function mult

end module pure_binary_funcs_mod

program test_reduce

use pure_binary_funcs_mod

implicit none

integer, parameter :: vec(*) = [10, 20, 30, 40]

logical, parameter :: keep(size(vec)) = vec > 10 .and. vec < 40

print*,reduce(vec,add), reduce(vec,mult)

print*,reduce(vec,add,mask=keep), reduce(vec,mult,mask=keep)

print*,reduce(vec,add,mask=mod(vec,4)==0), reduce(vec,mult)

end program test_reduce

ifort reduce_ice.f90

gives

Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.5.0 Build 20211109_000000

Copyright (C) 1985-2021 Intel Corporation. All rights reserved.

reduce_ice.f90(24): catastrophic error: **Internal compiler error: internal abort** Please report this error along with the circumstances in which it occurred in a Software Problem Report. Note: File and line given may not be explicit cause of this error.

compilation aborted for reduce_ice.f90 (code 1)

Link Copied

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

I did some testing. Just one of the REDUCE() cases causes the ICE. It's this one.

```
print*,reduce(vec,add,mask=mod(vec,4)==0)
```

I'll keep investigating.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

I filed a bug report on your behalf, CMPLRIL0-34551. I'll let you know when it is fixed.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

Another ICE:

c:\fortran\test>type reduce_join.f90

module join_mod

implicit none

contains

pure function join_csv(a,b) result(c)

character (len=*), intent(in) :: a,b

character (len=len_trim(a)+len_trim(b)+1) :: c

c = trim(a) // "," // trim(b)

end function join_csv

end module join_mod

program test_join

use join_mod

implicit none

print "(a)", "'" // reduce(["cat","dog","boy"],join_csv) // "'"

end program test_join

c:\fortran\test>ifort reduce_join.f90

Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.5.0 Build 20211109_000000

Copyright (C) 1985-2021 Intel Corporation. All rights reserved.

010101_13941

catastrophic error: **Internal compiler error: internal abort** Please report this error along with the circumstances in which it occurred in a Software Problem Report. Note: File and line given may not be explicit cause of this error.

compilation aborted for reduce_join.f90 (code 1)

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

I filed a bug report, CMPLRIL0-34565, for this second issue.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

The Intel manual appears to indicate that only math operations are allowed with reduce, is this incorrect?

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

I don't think the function needs to be mathematical. Here is what Metcalf/Reid/Cohen (2018) say:

23.6.2 Generalized array reduction

A new transformational intrinsic function reduce for performing user-defined array reductions

has been added. It is analogous to the collective subroutine co_reduce (Section 20.19).

reduce (array, operation [ , mask, identity, ordered ] ) or

reduce (array, operation, dim [ , mask, identity, ordered ] )

**array** is an array of any type.

**operation** is a pure function that provides the binary operation for reducing the

array. It is recommended that the operation be mathematically associative.1 The

function must have two scalar arguments and a scalar result, all non-polymorphic

with the same type and type parameters as array. The arguments must not have

the allocatable, optional, or pointer attributes; if one argument has the

asynchronous, target, or volatile attribute, the other must have the same

attribute.

...

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

```
module join_mod
implicit none
contains
pure function join_csv(a,b) result(c)
character (len=*), intent(in) :: a,b
character (len=len_trim(a)+len_trim(b)+1) :: c
c = trim(a) // "," // trim(b)
end function join_csv
end module join_mod
program test_join
use join_mod
implicit none
print "(a)", "'" // reduce(["cat","dog","boy"],join_csv) // "'"
end program test_join
```

Can you please use the language insert box, so the code is easy to read and understand.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

```
module join_mod
implicit none
contains
pure function my_add(a,b) result(c)
real, intent(in) :: a,b
real c
c = a + b
end function my_add
end module join_mod
program test_join
use join_mod
implicit none
real result(3)
real, dimension(3,2) :: array = [1.0, 2.0, 3.0, 4.0, 5.0 , 6.0]
result = REDUCE (array, my_add, DIM = 2)
write(*,*)result
end program test_join
```

The reduce example on your page https://www.intel.com/content/www/us/en/develop/documentation/fortran-compiler-oneapi-dev-guide-and-reference/top/language-reference/a-to-z-reference/q-to-r/reduce.html is incorrect. The above code shows the correct code.

Also the rank of a matrix is the number of linearly independent columns. In this case 3. Your example provides an answer of [9, 12] as this has a rank of 2.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

From the Intel notes:

The function should implement a mathematically associated operation; it need not be commutative.

```
module join_mod
implicit none
contains
pure function join_csv(a,b) result(c)
character (len=3), intent(in) :: a
character (len=3), intent(in) :: b
character (len=len_trim(a)+len_trim(b)) :: c
c = trim(a)
end function join_csv
end module join_mod
program test_join
use join_mod
implicit none
character*3 result(2)
character*3, dimension(2,2) :: array = ["cat","dog","boy", "lad"]
result = reduce(array,join_csv, DIM = 2)
end program test_join
```

Debugging shows b is never set to a value., no matter how I arrange result and array.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

When you post the Fortran code, can you also look at the language button and select Fortran - it makes it much easier to read your code.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

You are correct.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

It took me a while to get a sample working, I ended up with our manual and my old Linear Algebra textbook open to work out what was wrong.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

The Fortran Developer Guide has been updated per the discussion in this thread. And the bug reported as CMPLRIL0-34551 is also fixed.

Check out the Fortran compiler that was released last week as part of oneAPI 2022.3.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

I checked the new one out, it is super swell and thank you for the fixes.

I am sorry but the 2022.2 version on ifort gave me a chuckle.

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