info about compiler error message

Hi everyone!

Where can I find information about this error

PGF90-S-0310-Automatic arrays are not allowed in a MODULE

There is no particular information about it in the link below

https://www.pgroup.com/resources/docs/18.7/x86/pgi-ref-guide/index.htm#messages

I got the message whit the following array declaration in my module.

real, constant :: d(10)

I found this info in the net

GPU data in modules must have fixed size or be allocatable:

module mm
real, device, allocatable :: a(:)
real, device :: x, y(10)
real, constant :: c1, c2(10)
integer, device :: n
contains
attributes(global) subroutine s( b )


â—�
Variable or array declaration could also have “constant� attribute,
denoting GPU constant memory
Why am I not allowed to use?

Hi oscar_ml,

The “S-0310” errors are listed as “Generic Module Errors”. In this case, the error is indicating that, as per the Fortran standard, automatic arrays are not allowed to be use as module variables. Where an automatic is an array whose size is defined using a variable.

Though, are you certain that the declaration of “d(10)” is causing the issue? This is a fixed sized array, so should be fine. I tried the example and it compiled fine for me.

% cat test.f90
module mm
real, device, allocatable :: a(:)
real, device :: x, y(10)
real, constant :: c1, c2(10)
integer, device :: n
end module mm
% pgfortran -c test.f90 -Mcuda
%

Can you please show the code you are trying to compile, the compiler command line, and the full output?

Thanks,
Mat

One more time, thanks for your answer Mat

I get it. Actually, I was using a variable instead of 10. This question is related to another post (https://forums.developer.nvidia.com/t/device-array-values-modified-without-reason-garbage/135903/1). I thought as my array has constant values I could use cudaMemcpyToSymbol. So I tried putting in my module the constant array and in an initialization subroutine inside the module to use cudaMemcpyToSymbol

module mm
  use types
  use cudafor

  implicit none

  integer, parameter          ::     sizeblock=8
  real, constant                     ::    d_coefx(:)

contains

subroutine fd_init_cuda(p)
!-------------------------------------
  implicit none 
  type (CommomParameters)   :: p
  integer                   :: istat

  istat = cudaMemcpyToSymbol(d_coefx,p%modeling%coefx(:),p%modeling%order+1)
  if (istat .ne. 0) print *,"cudaMemcpyToSymbol ",istat
end subroutine fd_init_cuda

end module mm

Here, p is derived type from the types module. Doing that I face up another problem

PGF90-S-0155-Could not resolve generic procedure cudamemcpytosymbol

And one more time I don’t have information enough about the compiler error to try to solve the issue. :/

Hi oscar_ml,

PGF90-S-0155-Could not resolve generic procedure cudamemcpytosymbol

In general, this error means that the compiler could find an actual procedure that matches the signature (i.e. the data types you’re using in the call) for a given generic procedure.

Specifically here, it looks like your missing the last two arguments: offset and kind.

See: https://docs.nvidia.com/cuda/cuda-runtime-api/group__CUDART__MEMORY.html#group__CUDART__MEMORY_1g9bcf02b53644eee2bef9983d807084c7

Though, you probably shouldn’t need to call cudaMemcpyToSymbol at all and instead just copy the variable. cudaMemcpyToSymbol is rather old and no longer used. It was mostly used for texture memory which isn’t used on modern devices.

d_coefx = p%modeling%coefx(:N)

Also, constant variables can’t be allocated. They must be fixed size. So declaring it "real, constant :: d_coefx(:) " isn’t going to work. You’ll need to replace this with “d_coefx(N)” where N is a parameter, macro or replace with a literal integer value.

Finally, constant memory isn’t very large. While the size can vary by device, a V100 is only 64KB. Using too much constant memory will cause your program to silently fail, so be mindful of how much you use.

Hope this helps,
Mat