FORTRAN: Explicit array argument & No device symbol for address reference

Hi,

Is it possible to call subroutines with explicit array arguments?

program test
    implicit none
    real(8), dimension(100) :: a, b
    integer                 :: i
    
    do i=1,100,1
        a(i) = real(i,8)
        b(i) = a(i)**2
    end do
    
    !$acc data copy(a(:),b(:))
    !$acc parallel loop
    do i=1,100,1
        call sub(a(i),b(i))
    end do
    !$acc end data
    
    write(*,*) sum(b)
    
    contains
    
    pure subroutine sub(a,b)
        use mdl
        !$acc routine seq
        implicit none
        real(8), intent(in)    :: a
        real(8), intent(inout) :: b
        
        real(8), dimension(1)  :: f1
        real(8), dimension(2)  :: f2
        
        ! works fine
        !f1 = [1._8]
        !f2 = [1._8,1._8]
        !call mdl_sub_1(f1,a,b)
        !call mdl_sub_2(f2,a,b)
        
        ! problem with explicit array argument
        call mdl_sub_1([1._8],a,b)
        call mdl_sub_2([1._8,1._8],a,b)

    end subroutine sub
    
end program test



module mdl
    implicit none
    
    contains
    
    pure subroutine mdl_sub_1(factor,a,b)
        !$acc routine seq
        real(8), intent(in), dimension(1) :: factor
        real(8), intent(in)               :: a
        real(8), intent(inout)            :: b
        b = factor(1)*a + b
    end subroutine mdl_sub_1
    
    pure subroutine mdl_sub_2(factor,a,b)
        !$acc routine seq
        real(8), intent(in), dimension(2) :: factor
        real(8), intent(in)               :: a
        real(8), intent(inout)            :: b
        b = factor(1)*a + factor(2)*b
    end subroutine mdl_sub_2
    
    
end module mdl



mdl.f90:
pro.f90:
PGF90-S-0155-Compiler failed to translate accelerator region (see -Minfo messages): No device symbol for address reference (pro.f90: 1)
PGF90-F-0704-Compilation aborted due to previous errors. (pro.f90)
PGF90/x86-64 Linux 19.4-0: compilation aborted

Thanks imorozov,

This does look like a compiler issue so I have added a problem report (TPR#27580) and sent to our engineers for further investigation.

Another work around is to use a variable instead of a constant in the explicit arrays.

    pure subroutine sub(a,b)
        use mdl
        !$acc routine seq
        implicit none
        real(8), intent(in)    :: a
        real(8), intent(inout) :: b
        real(8) :: one
        one=1._8
        call mdl_sub_1([one],a,b)
        call mdl_sub_2([one,one],a,b)
    end subroutine sub

Also, while it works in this example, I would recommend to not using device internal procedures. Internal procedures require a hidden argument, a pointer to the parent’s stack. Given the device can’t access the host’s stack, this can cause problems. Instead, I would recommend putting “sub” into a module.

-Mat