首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >cuda thrust::for_each与thrust::counting_iterator

cuda thrust::for_each与thrust::counting_iterator
EN

Stack Overflow用户
提问于 2016-10-05 15:33:18
回答 1查看 2.3K关注 0票数 0

我对CUDA有点陌生。当提供一个thrust::for_each时,我似乎无法让counting_iterator算法工作。这是我的简单函子:

代码语言:javascript
复制
struct print_Functor {
    print_Functor(){}
    __host__ __device__
    void operator()(int i)
    {
        printf("index %d\n", i);
    }
}; 

现在,如果我用一个预先填充了序列的主机向量来调用它,它可以很好地工作:

代码语言:javascript
复制
    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来完成这个任务,它就失败了:

代码语言:javascript
复制
    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在错误消息中失败:

代码语言:javascript
复制
   after cudaFuncGetAttributes: unspecified launch failure

我试图通过让迭代器输入一个模板参数来做到这一点:

代码语言:javascript
复制
thrust::for_each<thrust::counting_iterator<int>>(first,last, print_Functor());

但同样的错误结果。

为了完整起见,我从MATLAB文件(64位)调用它。

我已经能够让其他推力算法与计数迭代器一起工作(例如推力::reduce给出了正确的结果)。

作为一个新来的人,我可能正在做一些很愚蠢的事情,而忽略了一些显而易见的事情--有人能帮上忙吗?

到目前为止,谢谢您的评论。到目前为止,我已经采纳了这些意见。工作示例(Matlab外)正确工作并产生输出,但如果将其转换为mex文件,它仍然无法工作--第一次完全没有输出,第二次只产生与以前相同的错误消息(只有通过重新编译才能恢复到输出)。

然而,即使在DOS环境下,它也存在一个类似的问题:它不执行来自thrust::for_each的函子。下面是一个完整的例子:

代码语言:javascript
复制
#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提示符下编译的,其中包括:

代码语言:javascript
复制
nvcc -o pf pf.cu

生产的产出如下:

代码语言:javascript
复制
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++非常生疏,所以我可能遗漏了一些明显的东西.)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-10-06 13:32:33

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

错误代码“未指定的启动失败”,以及函子被定义为主机的事实,使我认为execute想要在您的设备上执行。

您能添加一个执行策略以确保代码在哪里执行吗?

取代:

代码语言:javascript
复制
thrust::for_each(first,last,sf);

使用

代码语言:javascript
复制
thrust::for_each(thrust::host, first,last,sf);

为了能够在GPU上运行,您的结果必须在设备内存(通过cudaMalloc)上分配,然后复制回主机。

代码语言:javascript
复制
#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);

}

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39878207

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档