仅求向量CUDA/推力的正元素之和

仅求向量CUDA/推力的正元素之和,cuda,gpgpu,thrust,gpu,Cuda,Gpgpu,Thrust,Gpu,我想使用推力(因为我的大多数方法都是使用推力数据类型实现的)或C CUDA,如果需要的话,只对向量的正浮点元素求和。数据最初没有排序。我最初的尝试是非常糟糕的:基本上,复制向量,对其排序,通过将其传递给一个内核来找到零交叉点,该内核比较顺序成对值,并写入与零交叉点匹配的值。基本上是在排序之后(我使用推力进行排序) inti=blockIdx.x*blockDim.x+threadIdx.x; 如果(i=0.0&&b

我想使用推力(因为我的大多数方法都是使用推力数据类型实现的)或C CUDA,如果需要的话,只对向量的正浮点元素求和。数据最初没有排序。我最初的尝试是非常糟糕的:基本上,复制向量,对其排序,通过将其传递给一个内核来找到零交叉点,该内核比较顺序成对值,并写入与零交叉点匹配的值。基本上是在排序之后(我使用推力进行排序)

inti=blockIdx.x*blockDim.x+threadIdx.x;
如果(i=0.0&&b<0.0)
答案=i+1;
}
这真是愚蠢,很多线程匹配条件方式,读取太多,分支分歧等等。因此,它完全失败了,每个调用将在相同的数据上给出不同的结果,等等


我还没有找到一个很好的方法来实现这个目标,这是我更喜欢的。排序后,我不知道如何找到零交叉点。关于起点有什么建议吗?一个实际工作的简单CUDA C实现也很好。

要只求正值的和,不需要对初始值排序,使用 推力::变换_减小:

template<typename T>
struct positive_value : public thrust::unary_function<T,T>
{
   __host__ __device__ T operator()(const T &x) const
   {
     return x < T(0) ? 0  : x;
   }
};

float result = thrust::transform_reduce(data.begin(), data.end(),
                                    positive_value<float>(),
                                    0,
                                    thrust::plus<float>());
模板
结构正函数值:公共推力::一元函数
{
__主机\uuuuuu\uuuu设备\uuuuu操作符()(常量T&x)常量
{
返回x
为什么需要排序?您确实需要订购数据吗?还有,内核代码段中奇怪的指针用法是什么?指针间接寻址的额外级别是为了实现什么?指针间接寻址并不是为了实现任何目标,我只是快速编写了它,但问题与此无关。我会更新它,这样就不会引起混乱。我认为排序是有益的,因为我可以这样简单地减少向量的前N个元素。下面回答的(用户ngimel)似乎解决了我的问题。
template<typename T>
struct positive_value : public thrust::unary_function<T,T>
{
   __host__ __device__ T operator()(const T &x) const
   {
     return x < T(0) ? 0  : x;
   }
};

float result = thrust::transform_reduce(data.begin(), data.end(),
                                    positive_value<float>(),
                                    0,
                                    thrust::plus<float>());