gpt4 book ai didi

c++ - cuda thrust::for_each with thrust::counting_iterator

转载 作者:行者123 更新时间:2023-11-28 05:29:22 29 4
gpt4 key购买 nike

我是 CUDA 的新手,而且很吃力。当提供 counting_iterator 时,我似乎无法让 thrust::for_each 算法工作。这是我的简单仿函数:

struct print_Functor {
print_Functor(){}
__host__ __device__
void operator()(int i)
{
printf("index %d\n", i);
}
};

现在,如果我用一个预填充序列的宿主 vector 来调用它,它就可以正常工作:

    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 mex 文件(64 位)中调用它。

我已经能够让其他推力算法与计数迭代器一起工作(例如 thrust::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

换句话说,仿函数的重载 operator() 从 for 循环中被正确调用,但从未被 thrust::for_each 算法调用。使用计数迭代器时,让 for_each 执行仿函数的唯一方法是省略成员变量。

(我应该补充一点,经过多年使用纯 Matlab,我的 C++ 已经生锈了,所以我可能遗漏了一些明显的东西......)

最佳答案

在您的评论中,您说您希望代码在主机端执行。

错误代码“未指定的启动失败”,以及您的仿函数定义为 host device 的事实让我觉得 thrust 想要在您的设备上执行。

您能否添加一个执行策略来确定您的代码在何处执行?

替换:

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);

}

代码更新:要在您的设备上获得正确的结果,您必须使用原子操作。

关于c++ - cuda thrust::for_each with thrust::counting_iterator,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39878207/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com