CUDA推力:查找满足谓词(例如,零或负)的向量中第一个元素的索引[Matlab';s syntax min(find(x<;=0))]
我正在尝试使用CUDA推力查找数组的第一个零或负值的索引。我试图使用CUDA推力编写的串行CPU代码如下: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,
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推力计算满足谓词的向量的第一个元素的索引(xiter
不是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;
}