Search 推力矢量化搜索:有效地结合下界搜索和二进制搜索,以找到位置和存在
我试图使用推力来检测数组的每个元素是否可以在另一个数组中找到,以及在哪里(两个数组都被排序)。我遇到了矢量化搜索例程(下限搜索和二进制搜索) lower_bound将为每个值返回一个索引,在该索引中,可以根据其顺序将其插入列表中 我还需要知道是否找到了值(这可以通过二进制搜索完成),而不仅仅是它的位置 不进行两次搜索(先调用二进制搜索,然后调用下界搜索),是否可以有效地实现这两种搜索 我知道在标量情况下,如果找不到值,lower_bound将返回指向数组末尾的指针,但在矢量化版本中不会发生这种情况Search 推力矢量化搜索:有效地结合下界搜索和二进制搜索,以找到位置和存在,search,cuda,binary-search,thrust,lower-bound,Search,Cuda,Binary Search,Thrust,Lower Bound,我试图使用推力来检测数组的每个元素是否可以在另一个数组中找到,以及在哪里(两个数组都被排序)。我遇到了矢量化搜索例程(下限搜索和二进制搜索) lower_bound将为每个值返回一个索引,在该索引中,可以根据其顺序将其插入列表中 我还需要知道是否找到了值(这可以通过二进制搜索完成),而不仅仅是它的位置 不进行两次搜索(先调用二进制搜索,然后调用下界搜索),是否可以有效地实现这两种搜索 我知道在标量情况下,如果找不到值,lower_bound将返回指向数组末尾的指针,但在矢量化版本中不会发生这种情
谢谢 您可以检查
下限
返回的元素是否与您搜索的元素相同。例如,给定a={1,3,5}
并搜索b={1,4}
,结果将是c={0,2}
。我们有a[c[0]==b[0]
,所以b[0]
在a
,但是a[c[1]!=b[1]
因此b[1]
不在a
中
(请注意,您需要确保不进行任何越界内存访问,因为
下限
可以返回超出数组末尾的索引。)@tat0:您还可以使用:
使用lower_bound()进行矢量化搜索不会立即给出答案
在arrayfire中使用setintersect()时,可以直接获得两个数组的“交集”:
float A_host[] = {3,22,4,5,2,9,234,11,6,17,7,873,23,45,454};
int szA = sizeof(A_host) / sizeof(float);
float B_host[] = {345,5,55,6,7,8,19,2,63};
int szB = sizeof(B_host) / sizeof(float);
// initialize arrays from host data
array A(szA, 1, A_host);
array B(szB, 1, B_host);
array U = setintersect(A, B); // compute intersection of 2 arrays
int n_common = U.elements();
std::cout << "common: ";
print(U);
然后:loc=
4
3
8
10.0000
此外,推力::下限()似乎比setintersect()慢,
我通过以下计划对其进行了基准测试:
int *g_data = 0;
int g_N = 0;
void thrust_test() {
thrust::device_ptr<int> A = thrust::device_pointer_cast((int *)g_data),
B = thrust::device_pointer_cast((int *)g_data + g_N);
thrust::device_vector<int> output(g_N);
thrust::lower_bound(A, A + g_N, B, B + g_N,
output.begin(),
thrust::less<int>());
std::cout << "thrust: " << output.size() << "\n";
}
void af_test()
{
array A(g_N, 1, g_data, afDevicePointer);
array B(g_N, 1, g_data + g_N, afDevicePointer);
array U = setintersect(A, B);
std::cout << "intersection sz: " << U.elements() << "\n";
}
int main()
{
g_N = 3e6; // 3M entries
thrust::host_vector< int > input(g_N*2);
for(int i = 0; i < g_N*2; i++) { // generate some input
if(i & 1)
input[i] = (i*i) % 1131;
else
input[i] = (i*i*i-1) % 1223 ;
}
thrust::device_vector< int > dev_input = input;
// sort the vector A
thrust::sort(dev_input.begin(), dev_input.begin() + g_N);
// sort the vector B
thrust::sort(dev_input.begin() + g_N, dev_input.begin() + g_N*2);
g_data = thrust::raw_pointer_cast(dev_input.data());
try {
info();
printf("thrust: %.5f seconds\n", timeit(thrust_test));
printf("af: %.5f seconds\n", timeit(af_test));
} catch (af::exception& e) {
fprintf(stderr, "%s\n", e.what());
}
return 0;
}
int*g_data=0;
int g_N=0;
无效推力试验(){
推力::设备\u ptr A=推力::设备\u指针\u转换((int*)g\u数据),
B=推力::设备指针投射((int*)g_数据+g_N);
推力:设备矢量输出(g_N);
推力:下界(A,A+g\N,B,B+g\N,
output.begin(),
推力:小于();
标准::cout
int *g_data = 0;
int g_N = 0;
void thrust_test() {
thrust::device_ptr<int> A = thrust::device_pointer_cast((int *)g_data),
B = thrust::device_pointer_cast((int *)g_data + g_N);
thrust::device_vector<int> output(g_N);
thrust::lower_bound(A, A + g_N, B, B + g_N,
output.begin(),
thrust::less<int>());
std::cout << "thrust: " << output.size() << "\n";
}
void af_test()
{
array A(g_N, 1, g_data, afDevicePointer);
array B(g_N, 1, g_data + g_N, afDevicePointer);
array U = setintersect(A, B);
std::cout << "intersection sz: " << U.elements() << "\n";
}
int main()
{
g_N = 3e6; // 3M entries
thrust::host_vector< int > input(g_N*2);
for(int i = 0; i < g_N*2; i++) { // generate some input
if(i & 1)
input[i] = (i*i) % 1131;
else
input[i] = (i*i*i-1) % 1223 ;
}
thrust::device_vector< int > dev_input = input;
// sort the vector A
thrust::sort(dev_input.begin(), dev_input.begin() + g_N);
// sort the vector B
thrust::sort(dev_input.begin() + g_N, dev_input.begin() + g_N*2);
g_data = thrust::raw_pointer_cast(dev_input.data());
try {
info();
printf("thrust: %.5f seconds\n", timeit(thrust_test));
printf("af: %.5f seconds\n", timeit(af_test));
} catch (af::exception& e) {
fprintf(stderr, "%s\n", e.what());
}
return 0;
}