使用推力减少计数
Count reduction using Thrust
给定一些输入键和值,我试图计算存在多少个具有相同键的连续值。我将举一个例子来说明这一点。
输入键:{ 1, 4, 4, 4, 2, 2, 1 }
输入值:{ 9, 8, 7, 6, 5, 4, 3 }
预期输出键:{ 1, 4, 2, 1 }
预期输出值:{ 1, 3, 2, 1 }
我正在尝试使用 CUDA 在 GPU 上解决这个问题。 Thrust 库的缩减功能似乎是一个很好的解决方案,我得到了以下结果:
#include <thrust/reduce.h>
#include <thrust/functional.h>
struct count_functor : public thrust::binary_function<int, int, int>
{
__host__ __device__
int operator()(int input, int counter)
{
return counter + 1;
}
};
const int N = 7;
int A[N] = { 1, 4, 4, 4, 2, 2, 1 }; // input keys
int B[N] = { 9, 8, 7, 6, 5, 4, 3 }; // input values
int C[N]; // output keys
int D[N]; // output values
thrust::pair<int*, int*> new_end;
thrust::equal_to<int> binary_pred;
count_functor binary_op;
new_end = thrust::reduce_by_key(A, A + N, B, C, D, binary_pred, binary_op);
for (int i = 0; i < new_end.first - C; i++) {
std::cout << C[i] << " - " << D[i] << "\n";
}
此代码与 Thrust documentation 中的示例非常相似。但是,我尝试计算而不是 plus
操作。此代码的输出如下:
1 - 9
4 - 7
2 - 5
1 - 3
但是,我希望第二列包含值 1, 3, 2, 1
。我认为计数是关闭的,因为减少从它找到的第一个值开始并且在它具有第二个值之前不应用运算符,但我不确定情况是否如此。
我是不是忽略了可以解决这个问题的 reduce_by_key
函数,还是我应该使用完全不同的函数来实现我想要的?
对于您的用例,您不需要 B
的值,D
的值仅取决于 A
.
的值
为了计算 A
中有多少个连续值,您可以提供 thrust::constant_iterator
作为输入值并应用 thrust::reduce_by_key
:
#include <thrust/reduce.h>
#include <thrust/functional.h>
#include <iostream>
#include <thrust/iterator/constant_iterator.h>
int main()
{
const int N = 7;
int A[N] = { 1, 4, 4, 4, 2, 2, 1 };
int C[N];
int D[N];
thrust::pair<int*, int*> new_end;
thrust::equal_to<int> binary_pred;
thrust::plus<int> binary_op;
new_end = thrust::reduce_by_key(A, A + N, thrust::make_constant_iterator(1), C, D, binary_pred, binary_op);
for (int i = 0; i < new_end.first - C; i++) {
std::cout << C[i] << " - " << D[i] << "\n";
}
return 0;
}
输出
1 - 1
4 - 3
2 - 2
1 - 1
给定一些输入键和值,我试图计算存在多少个具有相同键的连续值。我将举一个例子来说明这一点。
输入键:{ 1, 4, 4, 4, 2, 2, 1 }
输入值:{ 9, 8, 7, 6, 5, 4, 3 }
预期输出键:{ 1, 4, 2, 1 }
预期输出值:{ 1, 3, 2, 1 }
我正在尝试使用 CUDA 在 GPU 上解决这个问题。 Thrust 库的缩减功能似乎是一个很好的解决方案,我得到了以下结果:
#include <thrust/reduce.h>
#include <thrust/functional.h>
struct count_functor : public thrust::binary_function<int, int, int>
{
__host__ __device__
int operator()(int input, int counter)
{
return counter + 1;
}
};
const int N = 7;
int A[N] = { 1, 4, 4, 4, 2, 2, 1 }; // input keys
int B[N] = { 9, 8, 7, 6, 5, 4, 3 }; // input values
int C[N]; // output keys
int D[N]; // output values
thrust::pair<int*, int*> new_end;
thrust::equal_to<int> binary_pred;
count_functor binary_op;
new_end = thrust::reduce_by_key(A, A + N, B, C, D, binary_pred, binary_op);
for (int i = 0; i < new_end.first - C; i++) {
std::cout << C[i] << " - " << D[i] << "\n";
}
此代码与 Thrust documentation 中的示例非常相似。但是,我尝试计算而不是 plus
操作。此代码的输出如下:
1 - 9
4 - 7
2 - 5
1 - 3
但是,我希望第二列包含值 1, 3, 2, 1
。我认为计数是关闭的,因为减少从它找到的第一个值开始并且在它具有第二个值之前不应用运算符,但我不确定情况是否如此。
我是不是忽略了可以解决这个问题的 reduce_by_key
函数,还是我应该使用完全不同的函数来实现我想要的?
对于您的用例,您不需要 B
的值,D
的值仅取决于 A
.
为了计算 A
中有多少个连续值,您可以提供 thrust::constant_iterator
作为输入值并应用 thrust::reduce_by_key
:
#include <thrust/reduce.h>
#include <thrust/functional.h>
#include <iostream>
#include <thrust/iterator/constant_iterator.h>
int main()
{
const int N = 7;
int A[N] = { 1, 4, 4, 4, 2, 2, 1 };
int C[N];
int D[N];
thrust::pair<int*, int*> new_end;
thrust::equal_to<int> binary_pred;
thrust::plus<int> binary_op;
new_end = thrust::reduce_by_key(A, A + N, thrust::make_constant_iterator(1), C, D, binary_pred, binary_op);
for (int i = 0; i < new_end.first - C; i++) {
std::cout << C[i] << " - " << D[i] << "\n";
}
return 0;
}
输出
1 - 1
4 - 3
2 - 2
1 - 1