我在尝试在内核中声明共享内存数组时遇到了麻烦。这是包含我内核的代码:
module my_kernels
use cudafor
implicit none
contains
attributes(global) subroutine mykernel(N)
! Declare variables
integer :: index
integer, intent(in), value :: N
real,shared,dimension(N) :: shared_array
! Map threadID to index
index = blockDim%x * (blockIdx%x-1) + threadIdx%x
! Set array element equal to index
shared_array(index) = index
end subroutine mykernel
end module my_kernels
以下是我调用内核的方式:
program cuda
use my_kernels
implicit none
! Set number of threads
integer :: N = 9
! Invoke kernel with 3 blocks of 3 threads
call mykernel<<<N/3,3>>>(N)
end program cuda
我所有这一切都在一个文件test.cuf中。当我尝试使用pgf90编译test.cuf时,我收到此错误:
PGF90-S-0000-Internal compiler error. unexpected runtime function call 0 (test.cuf: 34)
PGF90-S-0000-Internal compiler error. unsupported procedure 349 (test.cuf: 34)
0 inform, 0 warnings, 2 severes, 0 fatal for mykernel
/tmp/pgcudaforw5MgcaFALD9p.gpu(19): error: a value of type "int" cannot be assigned to an entity of type "float *"
/tmp/pgcudaforw5MgcaFALD9p.gpu(22): error: expected an expression
2 errors detected in the compilation of "/tmp/pgnvdl7MgHLY1VOV5.nv0".
PGF90-F-0000-Internal compiler error. pgnvd job exited with nonzero status code 0 (test.cuf: 34)
PGF90/x86-64 Linux 10.8-0: compilation aborted
在这种情况下,第34行引用end subroutine mykernel
。编译器错误不是很有用,我花了一段时间才发现问题与共享数组有关(我使用这段代码作为一个简单的例子)。
当我在共享数组的声明中将'N'替换为'9'以使real,shared,dimension(N) :: shared_array
替换为real,shared,dimension(9) :: shared_array
时,错误消失了。
我的问题是,为什么会出现此错误,如何使用变量设置共享数组的维度(如果可能的话)?
答案 0 :(得分:1)
将“dimension(N)”更改为“dimension(*)”,然后传入共享数组的大小(以字节为单位)作为内核启动的第三个参数。
希望这有帮助,
垫
% cat test.cuf
module my_kernels
use cudafor
implicit none
real, dimension(:), allocatable,device :: Ad
real, dimension(:),allocatable :: Ah
contains
attributes(global) subroutine mykernel(N)
! Declare variables
integer :: index
integer, intent(IN), value :: N
real,shared,dimension(*) :: shared_array
! Map threadID to index
index = blockDim%x * (blockIdx%x-1) + threadIdx%x
! Set array element equal to index
shared_array(index) = index
Ad(index) = index
end subroutine mykernel
end module my_kernels
program cuda
use my_kernels
implicit none
! Set number of threads
integer :: N = 9
allocate(Ad(N), Ah(N))
! Invoke kernel with 3 blocks of 3 threads
call mykernel<<<N/3,3,N*4>>>(N)
Ah=Ad
print *, Ah
end program cuda
% pgf90 test.cuf -V10.9 ; a.out
1.000000 2.000000 3.000000 4.000000
5.000000 6.000000 7.000000 8.000000
9.000000
答案 1 :(得分:1)
您可以拥有多个共享内存数组,但必须在编译时知道它们的大小。 通常,共享内存数组应该是固定大小的,在运行时可以传递大小以字节为单位的情况有点特殊。 我想这都是由于SM(流多处理器)中共享内存的限制。 根据我的经验,在CUDA C和CUDA中开发fortran最好让所有这些参数“固定”,然后让内核重复工作所需的次数以覆盖所有输入数据,这样我就更容易控制所有的paarmeters影响占用率(您使用GPU中所有物理资源的程度)。