$ nvfortran -V
nvfortran 21.11-0 64-bit target on x86-64 Linux -tp zen2
NVIDIA Compilers and Tools
Copyright (c) 2021, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
program main
real, allocatable:: x(:),y(:)
real:: cgdot
integer:: i,N=1024
allocate(x(N),y(N))
x=2.
y=2.
cgdot=0.
do concurrent(i=1:N ) reduce(+:cgdot)
cgdot=cgdot+x(i)*y(i)
end do
print *,"Scalar product=",cgdot
end program main
My function works a little more like this, and if you try compiling, it fails:
program main
real, allocatable:: x(:),y(:)
real:: dgdot
integer:: i,N=1024
allocate(x(N),y(N))
x=2.
y=2.
dgdot = cgdot(x,y,N)
print *,"Scalar product=",dgdot
end program main
function cgdot (x,y,N)
implicit none
integer :: N,i
real :: cgdot
real, dimension(N) :: x,y
cgdot=0.
do concurrent (i=1:N) reduce(+:cgdot)
cgdot=cgdot+x(i)*y(i)
enddo
return
end
I think it does not like the name of the function as a reduce argument, let me ask the compiler team ( that told me it is probably a bug, I am going to file one).
This version compiles and runs, you can use this workaround until the issue is fixed.
program main
real, allocatable:: x(:),y(:)
real:: dgdot
integer:: i,N=1024
allocate(x(N),y(N))
x=2.
y=2.
dgdot = fcgdot(x,y,N)
print *,"Scalar product=",dgdot
end program main
real function fcgdot (x,y,N)
implicit none
integer :: N,i
real :: cgdot
real, dimension(N) :: x,y
cgdot=0.
do concurrent (i=1:N) reduce(+:cgdot)
cgdot=cgdot+x(i)*y(i)
enddo
fcgdot=cgdot
return
end