dynamic parallel的问题

请问一下dynamic parallel中gpu能不能控制循环次数,我想把如下代码全部迁移到gpu上去,怎么改动呢?
while(iterSech<maxSech)
{
if(iterSech != 0)
{
step = step * 0.5;
kernle1<<<dimGrid,dimBlock>>> (…, step_d+iterSech ,…);
}
else
{
step = 100;
kernle2<<<dimGrid,dimBlock>>>(…);
}
gpu_Costfunc_f(…,step_d+iterSech, f_d…);
CudaSafeCall(cudaMemcpy(f,f_d, sizeof(double),cudaMemcpyDeviceToHost));

ftemp=old_f+0.0001 * step * ftemp;
if(*f<=ftemp)
{
CublasSafeCall( cublasDaxpy(m_cublasHandle, Zs, step_d+iterSech, dk_d, 1,x_d, 1) );
break;
}
iterSech=iterSech+1;
}

楼主您好:

关于是否能控制启动kernel的次数,这个显然是可以的。(继续用普通的for/while/if循环都行)。

但是您后者的cudaMemcpy和cublas可能有麻烦,他们可能无法在Device端使用。

感谢来访。

话说您可以考虑下cudaMemcpyAsync的,这个是支持的。
cublas刚才看了下,5.0起提供了device版本的,您可以查看手册适合改成使用Device版本的。

以及,您的 gpu_Costfunc_f()函数可能需要改写,以便让它适合device上运行。

大致如此吧。

gpu_Costfunc_f()函数内部是kernel和cufft的调用
我想把下面这部分cpu代码移到gpu上执行,可是这里break怎么跳出while循环呢?
ftemp=old_f+0.0001 * step * ftemp;
if(*f<=ftemp)
{
CublasSafeCall( cublasDaxpy(m_cublasHandle, Zs, step_d+iterSech, dk_d, 1,x_d, 1) );
break;
}
iterSech=iterSech+1;

如果您是说:
while(…)
{
您的含有break的这段代码(您可能需要去掉您的CublasSafeCall宏)
}

那么您原本的break具有跳出while的功能,现在的break也依然有跳出while的功能,这个是不变的。
您说呢?

是不是需要修改while内部已经gpu_costfun_f()函数内部的所有kernel,让每个kernel的最后调用下一个kernel,把原来的cpu调用kernel全部交个gpu调用kernel?
然后把gpu_Costfunc_f()函数内部是kernel和cufft的调用
我想把下面这部分cpu代码移到gpu上执行,可是这里break怎么跳出while循环呢?
ftemp=old_f+0.0001 * step * ftemp;
if(*f<=ftemp)
{
CublasSafeCall( cublasDaxpy(m_cublasHandle, Zs, step_d+iterSech, dk_d, 1,x_d, 1) );
break;
}
iterSech=iterSech+1;
这个代码修改成kernel,在这个内部判断(*f<=ftemp)如果满足条件就返回,不满足条件调用while开始的第一个kernel,这样对吗?

稍微补充一下5#的玫瑰斑竹:

LZ在4#表示“gpu_Costfunc_f()函数内部是kernel和cufft的调用”,以及根据1#的内容是打算从device端调用,那么cufft有可能不能在device端调用的,请LZ研究下最新的cufft手册,看看有没有明确指出这一点,或者简单测试一下。

祝LZ编码顺利~

是不是需要修改while内部以及gpu_costfun_f()函数内部的所有kernel,让每个kernel的最后调用下一个kernel,把原来的cpu调用kernel全部改成gpu调用kernel?

我想把下面这部分cpu代码移到写成一个kernel
ftemp=old_f+0.0001 * step * ftemp;
if(*f<=ftemp)
{
CublasSafeCall( cublasDaxpy(m_cublasHandle, Zs, step_d+iterSech, dk_d, 1,x_d, 1) );
break;
}
iterSech=iterSech+1;
在这个kernel内部判断(*f<=ftemp)如果满足条件就返回(作为最后一个kernel退出),如果不满足条件再次调用while开始的第一个kernel,这样对吗?

LZ您好:

1:各种分支判断和循环,如while,if,for以及break,continue等等都是和C/C++一模一样的,含义绝无修改。

2:不用修改kernel,原先计算的kernel保持原样即可。

3:您直接维护一个小的kernel,实现上述循环和分支判断的逻辑,而将那些大的计算kenrel分别被这个小的控制kernel调用即可,一个大的计算kernel执行完毕,逻辑上会回到原先调用这个kenrel的地方,然后继续向下执行,和host端调用十分类似,此时您可以容易地使用逻辑判断。

4:cufft可能不能在device端调用,请您测试一下再考虑使用。

祝您好运~

LZ您好:

您的问题已在9#给出建议做法,供您参考。

祝您编码顺利~

ice你好,你的意思是不是这样的
global kernel_f
{

kernel1<<<>>>();
kernel2<<<>>>();

//下面代码是gpu_costfun_f的简写,假设kernel可以调用cufft
kernel3<<<>>>();
cufft();
kernel4<<<>>>();

if(f_d<=ftemp_d)
break;
else
kernel_f<<<>>>(); //这里再递归调用自己
}

LZ您好:

我不是这个意思。

您原来的代码中并无递归调用,您为何要在这里加上呢?

您只需要写一个做控制用的小kernel,里面该循环循环,该判断判断,该break就break就完了。

你可以把这个小的kernel想象成device端一个具备kenrel启动能力的特殊的kenrel,或者设想成一个小型的嵌入在GPU里面干活的CPU来执行这些都行(虽然实际原理不是这样)。DP实现起来是非常顺畅和直接的,不知为何您的思路一直如此拧巴。

祝您编码顺利~

global kernel1()
{
if(f_d<=ftemp_d)
break;
}

while()
{
kernel1<<<>>>();
}
function();

我的问题是kernel1调用之后如果条件满足执行了break之后,cpu是不是就会跳出while循环执行function?
在kernel内部调用break 怎么跳出while循环,这点怎么理解呢?

LZ您好:

无法回答更多了,没有人告诉您可以用break结束函数的,您这样越写越离谱了,请回顾下基础知识。

以及,前面的回帖中已经提供了对您的问题的较完备的建议,请您参考。

一般将不再回复本帖,敬请谅解。

祝您好运~

是写一个kernel,在这个kernel中调用其他kernel以及while循环和break吗?
global kernel
{
while()
{
kerenl1<<<>>>();
kernel2<<<>>>();

if(f_d<=ftemp_d)
break;
}
}
是这样吗?

我查了一下 cufft好像还不能在设备端调用,那又该怎么办呢?是不是要自己写fft的kernel呢?

LZ您好:

如果您确实打算DP实现的话,那么您需要自己实现fft了,或者等等看下一版cufft能否提供device端的版本。

祝您好运~

有没有测试过host调用kernel的延时和device调用kernel的延时的差别呢

LZ您好:

并无测过这个比较,但是考虑到不用DP的话,经常需要传回host端数据,然后再启动kernel,这个整个事件绝对比device端就地启动kernel更慢。

祝您编码顺利~

好的 谢谢ice的耐心的解答哈。