我对CUDA有点陌生。当提供一个thrust::for_each时,我似乎无法让counting_iterator算法工作。这是我的简单函子:
struct print_Functor {
print_Functor(){}
__host__ __device__
void operator()(int i)
{
printf("index %d\n", i);
}
}; 现在,如果我用一个预先填充了序列的主机向量来调用它,它可以很好地工作:
thrust::host_vector<int> h_vec(10);
thrust::sequence(h_vec.begin(),h_vec.end());
thrust::for_each(h_vec.begin(),h_vec.end(), print_Functor());但是,如果我试图用thrust::counting_iterator来完成这个任务,它就失败了:
thrust::counting_iterator<int> first(0);
thrust::counting_iterator<int> last = first+10;
for(thrust::counting_iterator<int> it=first;it!=last;it++)
printf("Value %d\n", *it);
printf("Launching for_each\n");
thrust::for_each(first,last,print_Functor());我得到的结果是for循环执行正确,但是for_each在错误消息中失败:
after cudaFuncGetAttributes: unspecified launch failure我试图通过让迭代器输入一个模板参数来做到这一点:
thrust::for_each<thrust::counting_iterator<int>>(first,last, print_Functor());但同样的错误结果。
为了完整起见,我从MATLAB文件(64位)调用它。
我已经能够让其他推力算法与计数迭代器一起工作(例如推力::reduce给出了正确的结果)。
作为一个新来的人,我可能正在做一些很愚蠢的事情,而忽略了一些显而易见的事情--有人能帮上忙吗?
到目前为止,谢谢您的评论。到目前为止,我已经采纳了这些意见。工作示例(Matlab外)正确工作并产生输出,但如果将其转换为mex文件,它仍然无法工作--第一次完全没有输出,第二次只产生与以前相同的错误消息(只有通过重新编译才能恢复到输出)。
然而,即使在DOS环境下,它也存在一个类似的问题:它不执行来自thrust::for_each的函子。下面是一个完整的例子:
#include <thrust/for_each.h>
#include <thrust/iterator/counting_iterator.h>
struct sum_Functor {
int *sum;
sum_Functor(int *s){sum = s;}
__host__ __device__
void operator()(int i)
{
*sum+=i;
printf("In functor: i %d sum %d\n",i,*sum);
}
};
int main(){
thrust::counting_iterator<int> first(0);
thrust::counting_iterator<int> last = first+10;
int sum = 0;
sum_Functor sf(&sum);
printf("After constructor: value is %d\n", *(sf.sum));
for(int i=0;i<5;i++){
sf(i);
}
printf("Initiating for_each call - current value %d\n", (*(sf.sum)));
thrust::for_each(first,last,sf);
cudaDeviceSynchronize();
printf("After for_each: value is %d\n",*(sf.sum));
}这是在DOS提示符下编译的,其中包括:
nvcc -o pf pf.cu生产的产出如下:
After constructor: value is 0
In functor: i 0 sum 0
In functor: i 1 sum 1
In functor: i 2 sum 3
In functor: i 3 sum 6
In functor: i 4 sum 10
Initiating for_each call - current value 10
After for_each: value is 10换句话说,函子的重载操作符()是从for循环中正确调用的,但是thrust::for_each算法从未调用过。在使用计数迭代器时,让for_each执行函子的唯一方法是省略成员变量。
(我要补充的是,在使用了多年的纯Matlab之后,我的C++非常生疏,所以我可能遗漏了一些明显的东西.)
发布于 2016-10-06 13:32:33
在您的评论中,您表示希望在主机端执行代码。
错误代码“未指定的启动失败”,以及函子被定义为主机的事实,使我认为execute想要在您的设备上执行。
您能添加一个执行策略以确保代码在哪里执行吗?
取代:
thrust::for_each(first,last,sf);使用
thrust::for_each(thrust::host, first,last,sf);为了能够在GPU上运行,您的结果必须在设备内存(通过cudaMalloc)上分配,然后复制回主机。
#include <thrust/host_vector.h>
#include <thrust/sequence.h>
#include <thrust/for_each.h>
#include <thrust/iterator/counting_iterator.h>
#include <thrust/execution_policy.h>
struct sum_Functor {
int *sum;
sum_Functor(int *s){sum=s;}
__host__ __device__
void operator()(int i)
{
atomicAdd(sum, 1);
}
};
int main(int argc, char**argv){
thrust::counting_iterator<int> first(0);
thrust::counting_iterator<int> last = first+atoi(argv[1]);
int *d_sum;
int h_sum = 0;
cudaMalloc(&d_sum,sizeof(int));
cudaMemcpy(d_sum,&h_sum,sizeof(int),cudaMemcpyHostToDevice);
thrust::for_each(thrust::device,first,last,sum_Functor(d_sum));
cudaDeviceSynchronize();
cudaMemcpy(&h_sum,d_sum,sizeof(int),cudaMemcpyDeviceToHost);
printf("sum = %d\n", *h_sum);
cudaFree(d_sum);
}代码更新:要在设备上获得正确的结果,必须使用原子操作。
https://stackoverflow.com/questions/39878207
复制相似问题