让南当评估PTX内核文件

5视图(30天)
弗朗西斯科
弗朗西斯科 2013年7月31日
你好,
我有一个Matlab版本和墨西哥人C版本的函数,效果很好。我试着使用nvcc实现CUDA C版本,编译成PTX(没有问题),使用GPU内核Matlab函数并行计算工具箱,但我得到NaN值作为输出输入(Matlab本机和墨西哥人C版本我得到正确的输出)。
我已经测试了一些例子CUDA代码添加向量等,他们似乎工作好。
这是我的程序:
内核= parallel.gpu.CUDAKernel (“StressDueToSeg.ptx”,“StressDueToSeg.cu”);
内核。ThreadBlockSize = 1024;
内核。GridSize =装天花板(N / 1024);
[~,~,~,~,~,~,~,~,~,~,~,~,
s22, s11 s33 s12,向s23] =函数宏指令(科恩,N, S, px, py, pz、p1x, p1y, p1z, p2x, p2y, p2z, bx,,, a,ν,亩,
sxx, syy、szz sxy、syz sxz);
输入是标量的N, S,μ,ν”,1 d向量长度为N的px, py, pz,和1 d向量长度的年代”p1x、p1y p1z, p2x, p2y, p2z, bx,,热的。
我的.cu代码如下:
#包括< math.h >
__global__无效N StressDueToSeg (int, int,双* px,双* py,双* pz、
* p1x、双* p1y、双* p1z,
* p2x、双* p2y、双* p2z,
*软、双*通过、双*热晕,
常量双一个,常量双μ,常量双ν,
* sxx、双* syy、双* szz,
* sxy、双* syz、双* sxz)
{
双oneoverLp,普遍;
双vec1x vec1y vec1z;
双tpx推算,tpy tpz;
双Rx, Rz, Rdt;
对,双ndx ndz;
双d2, s1, s2 a2 a2_d2, a2d2inv;
双Ra, Rainv, Ra3inv sRa3inv;
双s_03a, s_13a, s_05a、s_15a s_25a;
双s_03b, s_13b, s_05b、s_15b s_25b;
双s_03, s_13, s_05、s_15 s_25;
双m4p, m8p, m4pn、mn4pn a2m8p;
双txbx txby txbz;
双dxbx dxby dxbz;
双dxbdt, dmdxx, dmdyy、dmdzz dmdxy, dmdyz, dmdxz;
双tmtxx, tmtyy, tmtzz、tmtxy tmtyz, tmtxz;
双tmdxx, tmdyy, tmdzz、tmdxy tmdyz, tmdxz;
双tmtxbxx, tmtxbyy, tmtxbzz、tmtxbxy tmtxbyz, tmtxbxz;
双dmtxbxx, dmtxbyy, dmtxbzz、dmtxbxy dmtxbyz, dmtxbxz;
双tmdxbxx, tmdxbyy, tmdxbzz、tmdxbxy tmdxbyz, tmdxbxz;
双I_03xx, I_03yy, I_03zz、I_03xy I_03yz, I_03xz;
双I_13xx, I_13yy, I_13zz、I_13xy I_13yz, I_13xz;
双I_05xx, I_05yy, I_05zz、I_05xy I_05yz, I_05xz;
双I_15xx, I_15yy, I_15zz、I_15xy I_15yz, I_15xz;
双I_25xx, I_25yy, I_25zz、I_25xy I_25yz, I_25xz;
int凹陷;
int coord = threadIdx。x + blockIdx。x * blockDim。x;
如果(coord < N) {
/ /预先执行一些常量
m4p = 0.25 *亩/ M_PI;
m8p = 0.5 * m4p;
m4pn = m4p /(1 -ν);
mn4pn = m4pn *ν;
a2 =一个*;
a2m8p = a2 * m8p;
(赛格= 0;赛格<年代;赛格+ +){/ /循环段
vec1x = p2x(凹陷)——p1x(凹陷);
vec1y = p2y(凹陷)——p1y(凹陷);
vec1z = p2z(凹陷)——p1z(凹陷);
oneoverLp = 1 /√vec1x * vec1x + vec1y * vec1y + vec1z * vec1z);
tpx推算= vec1x * oneoverLp;
tpy = vec1y * oneoverLp;
tpz = vec1z * oneoverLp;
Rx = px (coord) - p1x(凹陷);
Ry = py [coord] - p1y(凹陷);
Rz = pz [coord] - p1z(凹陷);
Rdt = Rx * * tpy + Rz * tpz tpx推算+变化;
ndx = Rx - Rdt * tpx推算;
对= Ry - Rdt * tpy;
ndz = Rz - Rdt * tpz;
d2 = ndx * ndx +对* + ndz *对ndz;
s1 = rdt;
s2 = - ((px (coord) -p2x(凹陷))* tpx推算+ (py [coord] -p2y(凹陷))* tpy + (pz [coord] -p2z(凹陷))* tpz);
a2_d2 = a2 + d2;
a2d2inv = 1 / a2_d2;
Ra =√a2_d2 + s1 * s1);
Rainv = 1 / Ra;
Ra3inv = Rainv * Rainv * Rainv;
sRa3inv = s1 * Ra3inv;
s_03a = s1 * Rainv * a2d2inv;
s_13a = -Rainv;
s_05a = (2 * s_03a + sRa3inv) * a2d2inv;
s_15a = -Ra3inv;
s_25a = s_03a - sRa3inv;
Ra =√a2_d2 + s2 * s2);
Rainv = 1 / Ra;
Ra3inv = Rainv * Rainv * Rainv;
sRa3inv = s2 * Ra3inv;
s_03b = s2 * Rainv * a2d2inv;
s_13b = -Rainv;
s_05b = (2 * s_03b + sRa3inv) * a2d2inv;
s_15b = -Ra3inv;
s_25b = s_03b - sRa3inv;
s_03 = s_03b - s_03a;
s_13 = s_13b - s_13a;
s_05 = s_05b - s_05a;
s_15 = s_15b - s_15a;
s_25 = s_25b - s_25a;
txbx = tpy * bz(凹陷)- tpz *(凹陷);
txby = tpz * bx(凹陷)- tpx推算* bz(凹陷);
txbz = tpx推算*(凹陷)- tpy * bx(凹陷);
dxbx = *对bz(凹陷)- ndz *(凹陷);
dxby = ndz * bx(凹陷)- ndx * bz(凹陷);
dxbz = ndx *(凹陷)- *对bx(凹陷);
dxbdt = dxbx * tpx推算+ dxby * tpy + dxbz * tpz;
dmdxx = ndx * ndx;
dmdyy =对*对;
dmdzz = ndz * ndz;
dmdxy = ndx *对;
dmdyz = * ndz对;
dmdxz = ndx * ndz;
tmtxx = tpx推算* tpx推算;
tmtyy = tpy * tpy;
tmtzz = tpz * tpz;
tmtxy = tpx推算* tpy;
tmtyz = tpy * tpz;
tmtxz = tpx推算* tpz;
tmdxx = 2 * * ndx tpx推算;
tmdyy = 2 * tpy *对;
tmdzz = 2 * tpz * ndz;
tmdxy = tpx推算* + tpy *对ndx;
tmdyz = tpy * ndz + tpz *对;
tmdxz = tpx推算* ndz + tpz * ndx;
tmtxbxx = 2 * * txbx tpx推算;
tmtxbyy = 2 * tpy * txby;
tmtxbzz = 2 * tpz * txbz;
tmtxbxy = tpx推算* txby + tpy * txbx;
tmtxbyz = tpy * txbz + tpz * txby;
tmtxbxz = tpx推算* txbz + tpz * txbx;
dmtxbxx = 2 * ndx * txbx;
dmtxbyy = 2 * * txby对;
dmtxbzz = 2 * ndz * txbz;
dmtxbxy = ndx * txby +对* txbx;
dmtxbyz = * txbz + ndz * txby对;
dmtxbxz = ndx * txbz + ndz * txbx;
tmdxbxx = 2 * * dxbx tpx推算;
tmdxbyy = 2 * tpy * dxby;
tmdxbzz = 2 * tpz * dxbz;
tmdxbxy = tpx推算* dxby + tpy * dxbx;
tmdxbyz = tpy * dxbz + tpz * dxby;
tmdxbxz = tpx推算* dxbz + tpz * dxbx;
共同= m4pn * dxbdt;
I_03xx =常见+ m4pn * dmtxbxx - m4p * tmdxbxx;
I_03yy =常见+ m4pn * dmtxbyy - m4p * tmdxbyy;
I_03zz =常见+ m4pn * dmtxbzz - m4p * tmdxbzz;
I_03xy = m4pn * dmtxbxy - m4p * tmdxbxy;
I_03yz = m4pn * dmtxbyz - m4p * tmdxbyz;
I_03xz = m4pn * dmtxbxz - m4p * tmdxbxz;
I_13xx = -mn4pn * tmtxbxx;
I_13yy = -mn4pn * tmtxbyy;
I_13zz = -mn4pn * tmtxbzz;
I_13xy = -mn4pn * tmtxbxy;
I_13yz = -mn4pn * tmtxbyz;
I_13xz = -mn4pn * tmtxbxz;
I_05xx =常见* (a2 + dmdxx)——a2m8p * tmdxbxx;
I_05yy =常见* (a2 + dmdyy)——a2m8p * tmdxbyy;
I_05zz =常见* (a2 + dmdzz)——a2m8p * tmdxbzz;
I_05xy =常见* dmdxy - a2m8p * tmdxbxy;
I_05yz =常见* dmdyz - a2m8p * tmdxbyz;
I_05xz =常见* dmdxz - a2m8p * tmdxbxz;
I_15xx = a2m8p * tmtxbxx -常见* tmdxx;
I_15yy = a2m8p * tmtxbyy -常见* tmdyy;
I_15zz = a2m8p * tmtxbzz -常见* tmdzz;
I_15xy = a2m8p * tmtxbxy -常见* tmdxy;
I_15yz = a2m8p * tmtxbyz -常见* tmdyz;
I_15xz = a2m8p * tmtxbxz -常见* tmdxz;
I_25xx = * tmtxx常见;
I_25yy = * tmtyy常见;
I_25zz = * tmtzz常见;
I_25xy = * tmtxy常见;
I_25yz = * tmtyz常见;
I_25xz = * tmtxz常见;
sxx [coord] + = I_03xx * s_03 + I_13xx * s_13 + I_05xx * s_05 +
I_15xx * s_15 + I_25xx * s_25;
syy [coord] + = I_03yy * s_03 + I_13yy * s_13 + I_05yy * s_05 +
I_15yy * s_15 + I_25yy * s_25;
szz [coord] + = I_03zz * s_03 + I_13zz * s_13 + I_05zz * s_05 +
I_15zz * s_15 + I_25zz * s_25;
sxy [coord] + = I_03xy * s_03 + I_13xy * s_13 + I_05xy * s_05 +
I_15xy * s_15 + I_25xy * s_25;
syz [coord] + = I_03yz * s_03 + I_13yz * s_13 + I_05yz * s_05 +
I_15yz * s_15 + I_25yz * s_25;
sxz [coord] + = I_03xz * s_03 + I_13xz * s_13 + I_05xz * s_05 +
I_15xz * s_15 + I_25xz * s_25;
}
}
返回;
}
我新CUDA因此,或许这是一个实现问题;然而,墨西哥人C代码本质上是非常相似的(它有一个2号循环计数器“coord”,而不是coord = threadIdx。x + blockIdx。x * blockDim。x) and that works OK.
请开导我。
谢谢你!
F

接受的答案

本Tordoff
本Tordoff 2013年8月1日
跟踪下来首先要做的是明确指定您的输入和输出。输入应该是常量。根据你的描述,你的函数应该看起来像:
__global__无效N StressDueToSeg (int, int年代,
const * px、双const * py、双const * pz,
const * p1x、双const * p1y、双const * p1z,
const * p2x、双const * p2y、双const * p2z,
const * bx、双const *,、双const * bz,
常量双一个,常量双μ,常量双ν,
* sxx、双* syy、双* szz,
* sxy、双* syz、双* sxz)
做,你只需要捕获输出(最后6数组)。这是更容易阅读和可能会更快:
[s11, s22 s33 s12,向,s23] =函数宏指令(
克恩,N, S,
px, py、pz
p1x、p1y p1z,
p2x、p2y p2z,
bx,,,
ν,亩,
sxx, syy、szz sxy、syz sxz);
(注:一种看起来像你有最后两个输出切换)。我已经尝试了一些假的μ值,ν,等等,不要让nan。有两个重要的注意事项:
  • 你需要以正确的顺序输入参数(你似乎把ν首先在调用站点,但μ首先在内核中)
  • 你需要intialize输出数组为零之前调用内核自内核使用+ =没有初始化数组。(更好的是内核为零的值。)
  • 通过ν= 1.0将保证正/南无处不在,因为你有行m4p / (1-NU)。
您可以调试这种事情通过将中间值为输出参数(可能是额外的添加为目的)——这就是我意识到μ和ν是交换。
我希望有帮助。
2的评论
本Tordoff
本Tordoff 2013年8月1日
如果你初始化内核内部使用0,您仍然可以创建它们南或者别的什么东西,它只是增加了一些额外的安全。由你决定你是否在GPU创建它们——non-GPU数组应该自动转移。

登录置评。

更多的答案(0)

类别

找到更多的在并行for循环(parfor)帮助中心文件交换

社区寻宝

找到宝藏在MATLAB中央,发现社区如何帮助你!

开始狩猎!