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
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 (device array values modified without reason (garbage?)). 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: CUDA Runtime API :: CUDA Toolkit Documentation
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