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

!$omp declare reduction then reduction with declared type issue

jimdempseyatthecove
Honored Contributor III
1,933 Views

Using ifort from oneAPI 2023.2

module mod_foo
    type type_foo
        real :: A, B, C
    end type type_foo
    interface operator (+)
        module procedure :: foo_plus
    end interface
    contains
    
    function foo_plus(afoo, val) result(ret)
        implicit none
        type(type_foo), intent(in) :: afoo
        type(type_foo) :: ret
        real, intent(in) :: val
        ret%A = afoo%A + val
        ret%B = afoo%B + val
        ret%C = afoo%C + val
    end function foo_plus
end module mod_foo
module mod_foo2
    use mod_foo
    !$omp declare reduction(+: type_foo : omp_out = omp_out + omp_in) initializer(omp_priv = type_foo(0.0,0.0,0.0))
end module mod_foo2  
program Console27
    use mod_foo2
    implicit none
    integer :: i
    type(type_foo) :: foo
    !$omp parallel reduction(+:foo)
    do i = 1,10
        foo = foo + 1234. * i
    end do
    !$omp end parallel do
end program Console27
------------
Build started...
1>------ Build started: Project: Console27 (IFORT), Configuration: Debug Win32 ------
Compiling with Intel® Fortran Compiler Classic 2021.10.0 [IA-32]...
Console27.f90
C:\Users\Jim\Source\Repos\Console27\Console27\Console27.f90(30): error #6549: An arithmetic or LOGICAL type is required in this context.   [OMP_OUT]
C:\Users\Jim\Source\Repos\Console27\Console27\Console27.f90(30): error #6549: An arithmetic or LOGICAL type is required in this context.   [OMP_IN]
C:\Users\Jim\Source\Repos\Console27\Console27\Console27.f90(30): error #6355: This binary operation is invalid for this data type.   [OMP_OUT]
C:\Users\Jim\Source\Repos\Console27\Console27\Console27.f90(30): error #6355: This binary operation is invalid for this data type.   [OMP_IN]
C:\Users\Jim\Source\Repos\Console27\Console27\Console27.f90(34): error #7628: This OpenMP* END directive does not match the OpenMP* block directive at the top of the stack.
compilation aborted for C:\Users\Jim\Source\Repos\Console27\Console27\Console27.f90 (code 1)

Note, ifx is not integrated into MS VS, however, if I compile the same program using ifx from the command line I get the same error:

C:\Users\Jim\Source\Repos\Console27\Console27>ifx console27.f90 -Qopenmp
Intel(R) Fortran Compiler for applications running on Intel(R) 64, Version 2023.2.0 Build 20230627
Copyright (C) 1985-2023 Intel Corporation. All rights reserved.

console27.f90(30): error #6549: An arithmetic or LOGICAL type is required in this context.   [OMP_OUT]
    !$omp parallel reduction(+:foo)
^
console27.f90(30): error #6549: An arithmetic or LOGICAL type is required in this context.   [OMP_IN]
    !$omp parallel reduction(+:foo)
^
console27.f90(30): error #6355: This binary operation is invalid for this data type.   [OMP_OUT]
    !$omp parallel reduction(+:foo)
^
console27.f90(30): error #6355: This binary operation is invalid for this data type.   [OMP_IN]
    !$omp parallel reduction(+:foo)
^
console27.f90(34): error #7628: This OpenMP* END directive does not match the OpenMP* block directive at the top of the stack.
    !$omp end parallel do
--------------^
compilation aborted for console27.f90 (code 1)

 

The declare reduction does not report an error, but the parallel reduction (and parallel do reduction) shows this error.

 

Jim Dempsey

0 Kudos
9 Replies
Steve_Lionel
Honored Contributor III
1,907 Views

To use ifx in VS, right click on the project (64-bit configuration only), select Intel Compiler > IFX.

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,880 Views

I know that is how it is supposed to work. But the choice did not appear.

I've updated my VS 2019 to the most recent update of VS 2019 last night.

Will re-install/repair HPC kit to see if it integrates with the IDE.

 

Jim

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,872 Views

After MS VS update and HPC kit Repair, ifx found. However my initial problem was the platform was not x64

 

The OpenMP declare reduction use error is still present:

Build started...
1>------ Build started: Project: Console27 (IFX), Configuration: Debug x64 ------
Compiling with Intel® Fortran Compiler 2023.2.0 [Intel(R) 64]...
Console27.f90
C:\Users\Jim\Source\Repos\Console27\Console27\Console27.f90(30):

  error #6549: An arithmetic or LOGICAL type is required in this context. [OMP_OUT]
C:\Users\Jim\Source\Repos\Console27\Console27\Console27.f90(30):

  error #6549: An arithmetic or LOGICAL type is required in this context. [OMP_IN]
C:\Users\Jim\Source\Repos\Console27\Console27\Console27.f90(30):

  error #6355: This binary operation is invalid for this data type. [OMP_OUT]
C:\Users\Jim\Source\Repos\Console27\Console27\Console27.f90(30):

  error #6355: This binary operation is invalid for this data type. [OMP_IN]
compilation aborted for C:\Users\Jim\Source\Repos\Console27\Console27\Console27.f90 (code 1)

 

Jim Dempsey

0 Kudos
TobiasK
Moderator
1,845 Views

@jimdempseyatthecove

 

That took me a while:)

You forgot to specify an interface operator for type_foo + type_foo. The error message is totally misleading here...

module mod_foo
  type type_foo
     real :: A, B, C
  end type type_foo
  interface operator (+)
     procedure :: foo_plus_real,foo_plus_foo
  end interface operator (+)
  !$omp declare reduction(+: type_foo : omp_out = omp_out + omp_in) initializer(omp_priv = type_foo(0.0,0.0,0.0))                                                                                                                                                                                                                                                                             

contains

  function foo_plus_real(afoo, val) result(ret)
    implicit none
    type(type_foo), intent(in) :: afoo
    type(type_foo) :: ret
    real, intent(in) :: val
    ret%A = afoo%A + val
    ret%B = afoo%B + val
    ret%C = afoo%C + val
  end function foo_plus_real
  function foo_plus_foo(afoo, bfoo) result(ret)
    implicit none
    type(type_foo), intent(in) :: afoo,bfoo
    type(type_foo) :: ret
    ret%A = afoo%A + bfoo%a
    ret%B = afoo%B + bfoo%b
    ret%C = afoo%C + bfoo%c
  end function foo_plus_foo
end module mod_foo
program Console27
  use mod_foo
  implicit none
  integer :: i
  type(type_foo) :: foo
  foo%a=0
  foo%b=0
  foo%c=0
  !$omp parallel reduction(+:foo)                                                                                                                                                                                                                                                                                                                                                             
  do i = 1,10
     foo = foo + 1.
  end do
  !$omp end parallel                                                                                                                                                                                                                                                                                                                                                                          
  write(*,*) foo%a, foo%b, foo%c
end program Console27

Can you please try this?

 

jimdempseyatthecove
Honored Contributor III
1,840 Views

The posted code had foo_plus adding the real. Will test your code...

That builds??

The run is strange. Using ifx:

jimdempseyatthecove_0-1696940812399.png

The write does not print?

The omp_in/out are visible after scope of !$omp parallel

foo is not visible  after scope of !$omp parallel

 

You were correct (thanks) it that my code was in error as it did not have  a type_foo+type_foo necessary for the reduction.

 

Using ifort:

jimdempseyatthecove_1-1696941133855.png

 

Still no output, no foo, and an extra symbol "--PLUS"?

 

Hmmm...

back to ifx...

Changing "parallal" to "parallel do", the code works as expected.

jimdempseyatthecove_2-1696941515108.png

 

So while the "parallel" is an issue, it will not affect the code I intend to use as it will contain "parallel do".

 

Thanks for your help.

 

Jim Dempsey

 

 

0 Kudos
TobiasK
Moderator
1,827 Views

@jimdempseyatthecove


do you still have problems with just !$omp parallel, so it works only for !$omp parallel do?


I tried 2023.2 and it works fine, e.g. the wirte statement is working. I also see the OMP_OUT --PLUS in the debugger which is strange, agreed, but the code works fine


0 Kudos
jimdempseyatthecove
Honored Contributor III
1,820 Views

I too have 2023.2 installed

Interesting find.

If I run in Debug mode with break point on end program, the output does not show, and the omp_in and omp_out show in Locals (foo and i do not)

 

If I do Debug | Start without debugging

The console window pops up with the result as expected.

 

It behaves as if the break point was placed inside the !$omp parallel.

If I insert an additional print * folllowing the write, still no output with break at end program (in Debug mode)

 

If I move the body of program to subroutine, the code works as expected

 

module mod_foo
  type type_foo
     real :: A, B, C
  end type type_foo
  interface operator (+)
     procedure :: foo_plus_real,foo_plus_foo
  end interface operator (+)
  !$omp declare reduction(+: type_foo : omp_out = omp_out + omp_in) initializer(omp_priv = type_foo(0.0,0.0,0.0))                                                                                                                                                                                                                                                                             

contains

  function foo_plus_real(afoo, val) result(ret)
    implicit none
    type(type_foo), intent(in) :: afoo
    type(type_foo) :: ret
    real, intent(in) :: val
    ret%A = afoo%A + val
    ret%B = afoo%B + val
    ret%C = afoo%C + val
  end function foo_plus_real
  
  function foo_plus_foo(afoo, bfoo) result(ret)
    implicit none
    type(type_foo), intent(in) :: afoo,bfoo
    type(type_foo) :: ret
    ret%A = afoo%A + bfoo%a
    ret%B = afoo%B + bfoo%b
    ret%C = afoo%C + bfoo%c
  end function foo_plus_foo
end module mod_foo
program Console27
  use mod_foo
  implicit none
  integer :: i
  type(type_foo) :: foo
  call fee(foo)
  write(*,*) foo%a, foo%b, foo%c
  print *,"here"
end program Console27
subroutine fee(foo)
  use mod_foo
  implicit none
  integer :: i
  type(type_foo) :: foo
  foo%a=0
  foo%b=0
  foo%c=0
  !$omp parallel reduction(+:foo)                                                                                                                                                                                                                                                                                                                                                             
  do i = 1,10
     foo = foo + 1.
  end do
  !$omp end parallel                                                                                                                                                                                                                                                                                                                                                                    
end subroutine fee

 

So there is some issue when the "!$omp parallel reduction(+:foo_)" resides in PROGRAM as opposed to in subroutine.

 

Jim Dempsey

0 Kudos
TobiasK
Moderator
1,779 Views

@jimdempseyatthecove I am still not able to reproduce the missing console output in debug mode.

Could you please share the VS project? I also asked @Devorah_H_Intel to have a look at it.


0 Kudos
jimdempseyatthecove
Honored Contributor III
1,752 Views

This is strange....

Yesterday, last night, and way early this morning, I cloned my hard drive (was SSD) to another disk (HD), then took the other disk and inserted it into a different system. IOW like a motherboard replacement (and backup). On the replacement system, the peculiarity (missing output) does not happen.

 

The problem system had a Core i7 2600K CPU. The replacement system has a E5-2620v2. Possibly a code (path) generation issue.

 

So, on the replacement system, I cannot reproduce the problem. 

 

Jim Dempsey

 

 

0 Kudos
Reply