nvlink error: Prototype doesn't match (Fortran+C + OpenACC)

Hello,

porting a code to OpenACC I found a problem that I don’t know how to solve. Basically, when I compile without OpenACC support the code gives no trouble, but when I compile with OpenACC support I get a “Prototype doesn’t match” error.

The code (just ~60 code lines) can be downloaded from https://goo.gl/Ue8KZf

As it is, the code will compile with no OpenACC support, and I have no trouble compiling and executing it:

[angelv@deimos test]$ make
pgcc  -c test.c
pgf90  -c fad.f90
pgf90  -c math.f90
pgf90  -c main.f90
pgf90 test.o math.o fad.o main.o  -o main.x
[angelv@deimos test]$ ./main.x
    1.000000000000000         2.000000000000000
[angelv@deimos test]$

By removing the comment in the OPTS variable in the makefile, I recompile with OpenACC support, but then I get:

[angelv@deimos test]$ make
pgcc -ta=tesla -acc -c test.c
pgf90 -ta=tesla -acc -c fad.f90
pgf90 -ta=tesla -acc -c math.f90
pgf90 -ta=tesla -acc -c main.f90
pgf90 test.o math.o fad.o main.o -ta=tesla -acc -o main.x
nvlink error   : Prototype doesn't match for 'Faddeeva_w' in 'math.o', first defined in 'test.o'
pgacclnk: child process exit status 2: /usr/pkg/pgi/linux86-64/18.1/bin/pgnvd
make: *** [makefile:9: all] Error 2
[angelv@deimos test]$

The Faddeeva_w function is defined in the file test.c, as:

#pragma acc routine seq
cmplx Faddeeva_w(cmplx z, double relerr) {
  return z + (relerr + _Complex_I * relerr) ;
}

with the following interface in fad.f90

 interface
     function Faddeeva_w(z,relerr) bind(c,name='Faddeeva_w')
       !$acc routine seq                                                                                                                                                                          
       use iso_c_binding
       implicit none
       complex(c_double) :: Faddeeva_w
       complex(c_double), value, intent(in) :: z
       real(c_double), value, intent(in) :: relerr
     end function Faddeeva_w
  end interface

and is being used in the file math.f90 as part of the faddeevas function as:

    SUBROUTINE faddeevas(A,V,VO,GA)
    !$acc routine seq                                                                                                                                                                             

    use iso_c_binding

    DOUBLE PRECISION :: a,v,vo,ga
  
    real(c_double) :: relerr = 0.0
    complex(c_double) :: ca, cb

    ca = CMPLX(a,v)
    cb = Faddeeva_w(ca,relerr)

    VO = REAL(cb)
    GA = IMAG(cb)

  END SUBROUTINE faddeevas

Any idea what could be going on?

Many thanks,
AdV[/code]

I’ll have to dig into this a little bit more. It is not your problem, I think, but a problem in how we pass and return complex arguments in device code.

OK, thanks. Let me know if you find a workaround and/or if this will be fixed (assuming it is a bug) in future versions.

(FWIW, I had no issues compiling with GCC with the -fopenacc flag).

Thanks,
AdV

I’ve entered a bug into our system, FS#25493. I’ll let you know what engineering determines.