type mismatch error

I’m trying to use “attributes(host,device)” to create a generic function, but I always get a compiler error:

PGF90-S-0188-Argument number 1 to x2: type mismatch (fcuda.cuf: 23)

I thought this sort of code (see below) was legal in CUDA fortran. Am I mistaken?


module gpufunc
	use cudafor
	implicit none


	attributes(host,device) subroutine x2(data)
	implicit none
	integer :: data

	data = data*2

	end subroutine x2
end module gpufunc

program fcuda
	use cudafor
	use gpufunc
	implicit none

	integer :: data = 1

	call x2(data)
	print *, data
end program fcuda

Hi Todd,

Looks like a compiler error since I see no reason this shouldn’t work. I have sent a report to our compiler engineers for further investigation (TPR#16510). Hopefully, we can have this fixed shortly.


I think I have the same problem any time I have a variable with intent (out).
Any news?

Hi goblinsqueen,

TPR#16510 was to do with using the “host” and “device” attributes where the user wants to call the host version. Unfortunately, the engineer who’s work on the issue says it’s complex problem that won’t be resolved for a while. The work around is to create two routines, one for the host and one for the device.

Is this the same problem you’re encountering?

  • Mat

Hi Mat,
I am writing my first programs with CUDA fortran, so maybe I have a stupid error…
But I can’t see why I cannot write a code like the one below.
The error is

PGF90-S-0188-Argument number 5 to in: type mismatch (test2.cuf: 42)
0 inform, 0 warnings, 1 severes, 0 fatal for sub1_device

module test_cuda

  use cudafor
  implicit none

  logical attributes(device) FUNCTION  In (X0min, X0Max, xMin, xMax, I)

    implicit none

    REAL(kind=8), value :: X0min,X0max,xMin, xMax
    REAL(kind=8) :: I

    IF ( X0Min >= xMax .OR. X0Max <= xMin ) THEN
       In = .FALSE.
       I = 0.D0
       In = .TRUE.
       I = 0.5D0  / (X0max - X0min) 
    END IF

  attributes(device) subroutine sub1_device(x0,dx0)

    implicit none

    real(kind=8), value :: x0,dx0
    real(kind=8) :: lmin, lmax, I
    real(kind=8) :: WL, WU

    lmin = x0 - 0.5D0 * dx0
    lmax = x0 - 0.5D0 * dx0
    I = 0.D0
    WL = 1.D0
    WU = 3.D0

    if (In(lmin,lmax,WL,WU,I)) then
   ! some code here
    end if
  end subroutine sub1_device
  attributes(global) subroutine kernel_1(N1,nblocks,nthreads)
    use cudafor

    implicit none
    integer, value :: N1, nthreads, nblocks
    real(kind=8) :: x0_dev, dx0_dev
    integer :: i, idx

    idx = (blockidx%x-1)*blockdim%x + threadidx%x
    do i=idx,N1,nthreads*nblocks
	x0_dev = 1.5D0
	dx0_dev = 1.D0
	call sub1_device(x0_dev,dx0_dev)
    end do
  end subroutine
end module
program test

  use cudafor
  use test_cuda

  integer :: nblocks, nthreads
  integer :: N1

  !--- kernel call  
  nblocks = 32
  nthreads = 256
  N1 = 1000

  call kernel_1<<<nblocks,nthreads>>>(N1,nblocks,nthreads)

end program

Hi goblinsqueen,

Things are in a bit of a flux in terms of argument passing on the device. In early 2010 compilers (10.0,10.1) the CUDA Fortran spec required scalars to be passed by value. In 10.2, our engineers changed this to pass by reference. This in turn was decided to be too strict so in the upcoming 10.3 release, both methods are allowed. Sorry for the confusion as we get the kinks in the language ironed out.

Since you’re using 10.1, the solution is to add the value attribute to the “I” variable in “In”. In 10.2, remove the ‘value’ attribute from the device routines’ variables. In 10.3 (due out early March 2010), the code will compile as is.

  • Mat