如何使用 CUDA Thrust 删除嵌套循环以进行全对距离检查?
How to remove a nested loop with CUDA Thrust for an all-pair distance check?
我有两个数组 array1 和 array2 以及 n 和 m个元素分别。我想找到元素之间的所有对距离。 CPU 上的暴力算法是:
for(int i =0; i<n; i++)
{
for(int j =0; j<m; j++)
{
array_pair_distances[i][j] = array1[i]-array2[j];
}
}
使用 CUDA Thrust 我只是通过使用 thrust::transform 和一个 for 循环将这个 n*m 问题变成了 n 或 m 问题。我的问题是如何使用 Thrust 删除最后一个 for 循环?
编辑:添加了使用 Thrust 和一个 for 循环的实施示例。代码检查 pair-distance 是否大于 0.1 和 returns 一个 int.
#include <stdio.h>
#include <iostream>
#include <cuda.h>
#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
#include <thrust/random.h>
#include <thrust/fill.h>
#include <thrust/transform.h>
#include <thrust/reduce.h>
struct PairDistanceCheck : public thrust::binary_function<float,float,int>
{
__host__ __device__
int operator()(const float& a, const float& b) const
{
if(thrust::get<0>(a) - thrust::get<0>(b) > 0.1)
{
return 1;
}
else return 0;
}
};
void function()
{
int n = 1000;
int m = 2000;
// Initialization of host vectors
thrust::host_vector<float> h_1 (n);
thrust::host_vector<float> h_2 (m);
// Fill host_vectors with data
*
*
*
//
// Copy host_vectors to device_vectors
thrust::device_vector<float> d_1 = h_1;
thrust::device_vector<float> d_2 = h_2;
thrust::device_vector<float> d_temp (m);
thrust::device_vector<int> d_sum (m);
thrust::fill(d_sum.begin(), d_sum.end(), 0);
thrust::device_vector<int> d_result (m);
for (int i=0; i<n; i++)
{
// Filling device_vector d_temp with element i from d_2
thrust::fill(d_temp.begin(), d_temp.end(), d_2[i]);
thrust::transform((d_1.begin(), d_1.end(), d_temp.begin(), d_result.begin(), PairDistanceCheck());
// Summing the vectors
thrust::transform(d_sum.begin(), d_sum.end(), d_result.begin(), d_sum.begin(), thrust::plus<int>());
}
// Final sum
int sum = thrust::reduce(d_sum.begin(), d_sum.end(), (int) 0, thrust::plus<int>());
return 0;
}
非常简短的回答是你不能。
Thrust 没有外积算法,这是执行您感兴趣的那种计算所需要的。您可以通过用 rows/columns 两个输入向量,然后直接减去它们。但与适当的外部产品实施相比,这将是非常低效的(内存和性能)。
我有两个数组 array1 和 array2 以及 n 和 m个元素分别。我想找到元素之间的所有对距离。 CPU 上的暴力算法是:
for(int i =0; i<n; i++)
{
for(int j =0; j<m; j++)
{
array_pair_distances[i][j] = array1[i]-array2[j];
}
}
使用 CUDA Thrust 我只是通过使用 thrust::transform 和一个 for 循环将这个 n*m 问题变成了 n 或 m 问题。我的问题是如何使用 Thrust 删除最后一个 for 循环?
编辑:添加了使用 Thrust 和一个 for 循环的实施示例。代码检查 pair-distance 是否大于 0.1 和 returns 一个 int.
#include <stdio.h>
#include <iostream>
#include <cuda.h>
#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
#include <thrust/random.h>
#include <thrust/fill.h>
#include <thrust/transform.h>
#include <thrust/reduce.h>
struct PairDistanceCheck : public thrust::binary_function<float,float,int>
{
__host__ __device__
int operator()(const float& a, const float& b) const
{
if(thrust::get<0>(a) - thrust::get<0>(b) > 0.1)
{
return 1;
}
else return 0;
}
};
void function()
{
int n = 1000;
int m = 2000;
// Initialization of host vectors
thrust::host_vector<float> h_1 (n);
thrust::host_vector<float> h_2 (m);
// Fill host_vectors with data
*
*
*
//
// Copy host_vectors to device_vectors
thrust::device_vector<float> d_1 = h_1;
thrust::device_vector<float> d_2 = h_2;
thrust::device_vector<float> d_temp (m);
thrust::device_vector<int> d_sum (m);
thrust::fill(d_sum.begin(), d_sum.end(), 0);
thrust::device_vector<int> d_result (m);
for (int i=0; i<n; i++)
{
// Filling device_vector d_temp with element i from d_2
thrust::fill(d_temp.begin(), d_temp.end(), d_2[i]);
thrust::transform((d_1.begin(), d_1.end(), d_temp.begin(), d_result.begin(), PairDistanceCheck());
// Summing the vectors
thrust::transform(d_sum.begin(), d_sum.end(), d_result.begin(), d_sum.begin(), thrust::plus<int>());
}
// Final sum
int sum = thrust::reduce(d_sum.begin(), d_sum.end(), (int) 0, thrust::plus<int>());
return 0;
}
非常简短的回答是你不能。
Thrust 没有外积算法,这是执行您感兴趣的那种计算所需要的。您可以通过用 rows/columns 两个输入向量,然后直接减去它们。但与适当的外部产品实施相比,这将是非常低效的(内存和性能)。