CUDA推力:查找满足谓词(例如,零或负)的向量中第一个元素的索引[Matlab';s syntax min(find(x<;=0))]

CUDA推力:查找满足谓词(例如,零或负)的向量中第一个元素的索引[Matlab';s syntax min(find(x<;=0))],cuda,gpgpu,thrust,Cuda,Gpgpu,Thrust,我正在尝试使用CUDA推力查找数组的第一个零或负值的索引。我试图使用CUDA推力编写的串行CPU代码如下: for (int i = StartIndex; i <= ArrayLimitIndex; i++) { if (Array[i] <= 0) { DesiredIndex = i; break; } } 现在,我想使用iter的值作为下一个内核的参数: newKernel<<<size, 1>>>(*dev_array,

我正在尝试使用CUDA推力查找数组的第一个零或负值的索引。我试图使用CUDA推力编写的串行CPU代码如下:

for (int i = StartIndex; i <= ArrayLimitIndex; i++) 
{ 
    if (Array[i] <= 0) { DesiredIndex = i; break; } 
}
现在,我想使用
iter
的值作为下一个内核的参数:

newKernel<<<size, 1>>>(*dev_array, iter)
我知道我这里的代码是不正确的,我有一些关于
iter
使用的问题。首先,
iter
是一个
设备向量。有没有办法让iter只产生一个值而不是一个向量?另外,当我执行
find_if
时,我如何在下一个内核调用中使用
iter
的值

在此方面的任何帮助都将不胜感激


谢谢

因为在内核中使用的不是
设备_向量
,而是原始数组,所以必须向其传递索引,而不是迭代器。您可以使用
推力::距离
来计算
dev_ptr_Col46
iter
之间的距离,从而获得索引


您还需要阅读文档,其中记录了
distance

由于内核中不使用
device\u vector
,而是使用原始数组,因此必须向其传递索引,而不是迭代器。您可以使用
推力::距离
来计算
dev_ptr_Col46
iter
之间的距离,从而获得索引

您还需要阅读文档,其中记录了距离。

尝试以下方法:

 thrust::device_ptr<double> val_ptr = thrust::find_if(dev_ptr_Col46, dev_ptr_Col46 + size,less_than_or_eq_zero());
 double * val = thrust::raw_pointer_cast(val_ptr);
 newKernel<<<size, 1>>>(dev_array, val)
试试这个:

 thrust::device_ptr<double> val_ptr = thrust::find_if(dev_ptr_Col46, dev_ptr_Col46 + size,less_than_or_eq_zero());
 double * val = thrust::raw_pointer_cast(val_ptr);
 newKernel<<<size, 1>>>(dev_array, val)


我在一个完全可编译和可执行的示例中总结了Talonmes和Jared Hoberock的评论以及Sebastian Dressler的答案。代码通过CUDA推力计算满足谓词的向量的第一个元素的索引(
x我总结了上面Talonmes和Jared Hoberock的评论,以及Sebastian Dressler在一个完全可编译和可执行的示例中的答案。代码通过CUDA推力计算满足谓词的向量的第一个元素的索引(
x
iter
不是
device\u vector
——它是指向
device\u vector
的迭代器。您可以直接在
newKernel
中使用它。好的。谢谢。有什么方法可以不用
device\u vector
,而创建这个迭代器吗?我在想,不用
开发工具,我可能会获得更好的性能ice_vector
@Jared Hoberock:另外,我如何在我的内核定义中声明
iter
?作为类型
double
?声明它与您在代码中所做的相同:
推力::设备_vector::迭代器iter
@JaredHoberock:我假定OP的意思是在内核中,而不是在主机代码中。我认为他或她不理解va迭代器的lue不是数组索引,而是数组值。
iter
不是
device\u vector
-它是指向
device\u vector
的迭代器。你可以直接在
newKernel
中使用它。好的。谢谢。有没有办法不用
device\u vector
创建这个迭代器?我想我如果不使用
设备向量
@Jared-Hoberock,可能会获得更好的性能。另外,我如何在我的内核定义中声明
iter
?作为类型
double
?声明与在代码中相同:
推力::设备向量::迭代器iter
@Jared-Hoberock:我假设OP的意思是在内核中,而不是在hos中t代码。我认为他或她不理解迭代器的值不是数组索引,而是数组值。谢谢你的回答。我能够用一个正常的
device\u vector
得到这个结果,但是当我传递
device\u ptr
时无法得到。当我使用以下表达式
int index=推力::距离时(dev_ptr_Col46,iter)
编译器告诉我,
distance
函数模板的实例与参数列表不匹配。是否可以将此
设备\u ptr
用作
推力::距离
函数的参数?您必须测量迭代器距离,即使用
begin()
你的
设备_向量的成员
。要在自定义内核上使用
设备_向量
,你可以从中获得一个原始指针。感谢你的回复。我可以用一个普通的
设备_向量
工作,但是当我传递
设备_ptr
时,我无法使用以下表达式
int index>时=推力:距离(dev_ptr_Col46,iter)
编译器告诉我,
distance
函数模板的任何实例都与参数列表不匹配。是否可以使用此
device\u ptr
作为
推力:距离
函数的参数?您必须测量迭代器距离,即使用
begin()
你的
设备_向量的成员
。要在自定义内核上使用
设备_向量
,你可以从中获得一个原始指针。看看原始问题中的内核代码。将数组中的值传递给内核如何解决问题?问题的关键是如何从迭代器中获取索引,而不是从值。@talonmies好的,我误读了内核。如果他需要获取索引,他可以执行int iter=val\u ptr-dev\u ptr\u Col46。看看原始问题中的内核代码。将数组中的值传递给内核如何解决问题?问题的关键是如何从迭代器中获取索引,而不是值。@talonmies好的,我误读了如果他需要获取索引,他可以执行int iter=val\u ptr-dev\u ptr\u Col46。
 thrust::device_ptr<double> val_ptr = thrust::find_if(dev_ptr_Col46, dev_ptr_Col46 + size,less_than_or_eq_zero());
 double * val = thrust::raw_pointer_cast(val_ptr);
 newKernel<<<size, 1>>>(dev_array, val)
 __global__ void newKernel(double * dev_array, double * val)
#include <thrust/device_vector.h>
#include <stdio.h>

struct less_than_or_eq_zero
{
    __host__ __device__ bool operator() (double x) { return x <= 0.; }
};

int main(void)
{
    int N = 6;

    thrust::device_vector<float> D(N);

    D[0] = 3.;
    D[1] = 2.3;
    D[2] = -1.3;
    D[3] = 0.;
    D[4] = 3.;
    D[5] = -44.;

    thrust::device_vector<float>::iterator iter1    = D.begin();
    thrust::device_vector<float>::iterator iter2    = thrust::find_if(D.begin(), D.begin() + N, less_than_or_eq_zero());
    int d = thrust::distance(iter1, iter2);

    printf("Index = %i\n",d);

    getchar();

    return 0;
}