Routine Directive Issue

Hello,
I’ve recently started using version 14.6 (updated from 13.7) of the PGI compiler and am attempting to make use of the routine directive included in OpenACC 2.0. However, although running pgfortran -V confirms that I am indeed using version 14.6, it claims that function and procedure calls are not supported:

[esauer2@gauss ~]$ pgfortran -Minfo -ta=nvidia,cuda5.5 example.f95
foo:
      1, Generating acc routine vector
          7, !$acc loop  ! threadidx%x
      1, Generating Tesla code
PGF90-S-0155-Accelerator region ignored; see -Minfo messages  (example.f95: 24)
test:
     24, Accelerator region ignored
     25, Accelerator restriction: function/procedure calls are not supported
     26, Accelerator restriction: unsupported call to 'foo'
  0 inform,   0 warnings,   1 severes, 0 fatal for test

The example code I’m trying is the following:

subroutine foo(v, i, n)
!$ACC ROUTINE VECTOR
real, dimension(1:100, 1:100) :: v
integer :: i, n, j

!$ACC LOOP VECTOR
do j=1,n
   v(i,j) = 1.0/(i*j)
   write(*,*)v(i,j)
enddo
end subroutine

program test
integer :: i, j, n
real, dimension(1:100, 1:100) :: v

n=100
do i=1,n
   do j=1,n
      v(i,j) = 2
   enddo
enddo

!$ACC PARALLEL LOOP
do i=1,n
   call foo(v,i,n)
enddo
!$ACC END PARALLEL LOOP
end program

This is very similar to the code described here:
http://devblogs.nvidia.com/parallelforall/7-powerful-new-features-openacc-2-0/
I’m still learning, so sorry if I’ve made some obvious mistake.

Best,
Ethan

Hi Ethan,

The “routine” needs an explicit or implicit interface, otherwise the compiler can’t tell that it’s a device routine. The easiest fix is to put “foo” in a module.

Hope this helps,
Mat

module bar

contains

subroutine foo(v, i, n)
 !$ACC ROUTINE VECTOR
 real, dimension(1:100, 1:100) :: v
 integer :: i, n, j

 !$ACC LOOP VECTOR
 do j=1,n
    v(i,j) = 1.0/(i*j)
    write(*,*)v(i,j)
 enddo
 end subroutine

end module bar

 program test
 use bar
 integer :: i, j, n
 real, dimension(1:100, 1:100) :: v

 n=100
 do i=1,n
    do j=1,n
       v(i,j) = 2
    enddo
 enddo

 !$ACC PARALLEL LOOP
 do i=1,n
    call foo(v,i,n)
 enddo
 !$ACC END PARALLEL LOOP
 end program