【发布时间】:2012-08-28 12:55:16
【问题描述】:
我正在使用 63 个寄存器/线程,所以(最多 32768 个)我可以使用大约 520 个线程。在这个例子中我现在使用 512 个线程。
(并行性在全局 computeEHfields 函数函数内的函数“computeEvec”中。) 问题是:
1) 下面的内存检查错误。
2) 当我使用 numPointsRp>2000 时,它显示“内存不足”,但是(如果我没有做错)我计算了全局内存,没关系。
-------------------已更新------------ ---------------
我用 cuda-memcheck 运行程序,它给了我(仅当 numPointsRs>numPointsRp 时):
========= 大小为 4 的 全局 读取无效
========= 在 computeEH 字段中的 0x00000428 处
========= 块 (0,0,0) 中的线程 (2,0,0)
========= 地址 0x4001076e0 超出范围
========= ========= 无效的 global 读取大小为 4
========= 在 computeEH 字段中的 0x00000428 处
========= 块 (0,0,0) 中的线程 (1,0,0)
========= 地址 0x4001076e0 超出范围
========= ========= 无效的 global 读取大小为 4
========= 在 computeEH 字段中的 0x00000428 处
========= 块 (0,0,0) 中的线程 (0,0,0)
========= 地址 0x4001076e0 超出范围
错误摘要:160 个错误
------------编辑----------------------------
另外,有时(如果我只使用线程而不是块(我没有测试块))如果我有 numPointsRs=1000 和 numPointsRp=100 然后更改 numPointsRp=200 然后再次更改numPointsRp=100 我没有拿到第一个结果!
import pycuda.gpuarray as gpuarray
import pycuda.autoinit
from pycuda.compiler import SourceModule
import numpy as np
import cmath
import pycuda.driver as drv
Rs=np.zeros((numPointsRs,3)).astype(np.float32)
for k in range (numPointsRs):
Rs[k]=[0,k,0]
Rp=np.zeros((numPointsRp,3)).astype(np.float32)
for k in range (numPointsRp):
Rp[k]=[1+k,0,0]
#---- Initialization and passing(allocate memory and transfer data) to GPU -------------------------
Rs_gpu=gpuarray.to_gpu(Rs)
Rp_gpu=gpuarray.to_gpu(Rp)
J_gpu=gpuarray.to_gpu(np.ones((numPointsRs,3)).astype(np.complex64))
M_gpu=gpuarray.to_gpu(np.ones((numPointsRs,3)).astype(np.complex64))
Evec_gpu=gpuarray.to_gpu(np.zeros((numPointsRp,3)).astype(np.complex64))
Hvec_gpu=gpuarray.to_gpu(np.zeros((numPointsRp,3)).astype(np.complex64))
All_gpu=gpuarray.to_gpu(np.ones(numPointsRp).astype(np.complex64))
mod =SourceModule("""
#include <pycuda-complex.hpp>
#include <cmath>
#include <vector>
#define RowRsSize %(numrs)d
#define RowRpSize %(numrp)d
typedef pycuda::complex<float> cmplx;
extern "C"{
__device__ void computeEvec(float Rs_mat[][3], int numPointsRs,
cmplx J[][3],
cmplx M[][3],
float *Rp,
cmplx kp,
cmplx eta,
cmplx *Evec,
cmplx *Hvec, cmplx *All)
{
while (c<numPointsRs){
...
c++;
}
}
__global__ void computeEHfields(float *Rs_mat_, int numPointsRs,
float *Rp_mat_, int numPointsRp,
cmplx *J_,
cmplx *M_,
cmplx kp,
cmplx eta,
cmplx E[][3],
cmplx H[][3], cmplx *All )
{
float Rs_mat[RowRsSize][3];
float Rp_mat[RowRpSize][3];
cmplx J[RowRsSize][3];
cmplx M[RowRsSize][3];
int k=threadIdx.x+blockIdx.x*blockDim.x;
while (k<numPointsRp)
{
computeEvec( Rs_mat, numPointsRs, J, M, Rp_mat[k], kp, eta, E[k], H[k], All );
k+=blockDim.x*gridDim.x;
}
}
}
"""% { "numrs":numPointsRs, "numrp":numPointsRp},no_extern_c=1)
func = mod.get_function("computeEHfields")
func(Rs_gpu,np.int32(numPointsRs),Rp_gpu,np.int32(numPointsRp),J_gpu, M_gpu, np.complex64(kp), np.complex64(eta),Evec_gpu,Hvec_gpu, All_gpu, block=(128,1,1),grid=(200,1))
print(" \n")
#----- get data back from GPU-----
Rs=Rs_gpu.get()
Rp=Rp_gpu.get()
J=J_gpu.get()
M=M_gpu.get()
Evec=Evec_gpu.get()
Hvec=Hvec_gpu.get()
All=All_gpu.get()
--------GPU型号------------- ----------------------
Device 0: "GeForce GTX 560"
CUDA Driver Version / Runtime Version 4.20 / 4.10
CUDA Capability Major/Minor version number: 2.1
Total amount of global memory: 1024 MBytes (1073283072 bytes)
( 0) Multiprocessors x (48) CUDA Cores/MP: 0 CUDA Cores //CUDA Cores 336 => 7 MP and 48 Cores/MP
【问题讨论】:
-
您是否一次将所有点复制到 GPU 内存中?一个点的大小是多少?
-
大小是 int。我在全局函数内部调用另一个(设备)函数,并在那里进行并行处理。
-
您的问题没有提供足够的详细信息,您的块/网格大小是有效的,因此您的内核或主机代码中一定有某些东西导致了错误(您甚至没有说错误来自哪里)。
-
但是你在做报复性的投票,这在很多情况下只是把不好的问题推到了列表的顶部。这可能有助于提升发帖者的自尊心,但它使支持开发者社区的任务(我的任务)变得更加困难。
-
@George:我不想看到数百行代码。我想看一个重现问题的简洁案例。如果你做不到,那是你考虑得不够多。最后一个错误意味着您的函数调用中的块尺寸无效。