按键排序在飞行或不同的方法
Thrust Sort by key on the fly or different approach?
我想知道是否有可能使用Thrust Library按键排序,而不需要创建一个Vector来存储键(在飞行中)。例如,我有以下两个向量:键和值:
vectorKeys: 0, 1, 2, 0, 1, 2, 0, 1, 2
VectorValues: 10, 20, 30, 40, 50, 60, 70, 80, 90
按键排序后:
thrust::sort_by_key(vKeys.begin(), vKeys.end(), vValues.begin());
结果向量为:
vectorKeys: 0, 0, 0, 1, 1, 1, 2, 2, 2
VectorValues: 10, 40, 70, 20, 50, 80, 30, 60, 90
我想知道是否有可能在不需要vKeys向量(在飞行中)的情况下sort_by_key,这样我就可以节省存储它的内存,并能够对更多的数据进行排序?
最后,我想对相同的键进行求和,并存储在一个向量中…是否有更好的方法来代替按键排序,然后按键减少,以获得相同的结果?
FinalVector = 120, 150, 180
您链接的原始推动力示例对具有行为主存储的底层数据集执行行求和。你的问题本质上是,当底层存储是列为主时,如何做同样的事情。
基本上可以使用相同的方法,但必须使用置换迭代器"动态地"将底层以列为主的存储转换为以行为主的存储。
对于这个,我们可以借用我在这里描述的函子
下面是一个完整的例子:
$ cat t466.cu
#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
#include <thrust/reduce.h>
#include <thrust/functional.h>
#include <thrust/sequence.h>
#include <thrust/iterator/transform_iterator.h>
#include <thrust/iterator/permutation_iterator.h>
#include <thrust/iterator/counting_iterator.h>
#include <iostream>
#define COLS 3
#define ROWS 3
#define DSIZE (COLS*ROWS)
#define INIT 10
#define STEP 10
// convert a linear index to a row index
template <typename T>
struct linear_index_to_row_index : public thrust::unary_function<T,T>
{
T C; // number of columns
__host__ __device__
linear_index_to_row_index(T C) : C(C) {}
__host__ __device__
T operator()(T i)
{
return i % C;
}
};
struct rm2cm_idx_functor : public thrust::unary_function<int, int>
{
int r;
int c;
rm2cm_idx_functor(int _r, int _c) : r(_r), c(_c) {};
__host__ __device__
int operator() (int idx) {
unsigned my_r = idx/c;
unsigned my_c = idx%c;
return (my_c * r) + my_r;
}
};
int main(void)
{
int C = COLS; // number of columns
int R = ROWS; // number of rows
thrust::host_vector<int> h_vals(DSIZE);
// initialize data
thrust::sequence(h_vals.begin(), h_vals.end(), INIT, STEP);
thrust::device_vector<int> vals = h_vals;
std::cout << " Initial data: " << std::endl;
thrust::copy(h_vals.begin(), h_vals.end(), std::ostream_iterator<int>(std::cout, ","));
std::cout << std::endl;
// allocate storage for row sums and indices
thrust::device_vector<int> row_sums(R);
thrust::device_vector<int> row_indices(R);
// compute row sums by summing values with equal row indices
thrust::reduce_by_key
(thrust::make_permutation_iterator(thrust::make_transform_iterator(thrust::counting_iterator<int>(0), linear_index_to_row_index<int>(R)), thrust::make_transform_iterator(thrust::counting_iterator<int>(0), rm2cm_idx_functor(R, C))),
thrust::make_permutation_iterator(thrust::make_transform_iterator(thrust::counting_iterator<int>(0), linear_index_to_row_index<int>(R)) + (R*C), thrust::make_transform_iterator(thrust::counting_iterator<int>(0), rm2cm_idx_functor(R, C)) + (R*C)),
thrust::make_permutation_iterator(vals.begin(), thrust::make_transform_iterator(thrust::counting_iterator<int>(0), rm2cm_idx_functor(R, C))),
row_indices.begin(),
row_sums.begin(),
thrust::equal_to<int>(),
thrust::plus<int>());
// print data
thrust::host_vector<int> h_row_sums = row_sums;
std::cout << " Results: " << std::endl;
thrust::copy(h_row_sums.begin(), h_row_sums.end(), std::ostream_iterator<int>(std::cout, ","));
std::cout << std::endl;
return 0;
}
$ nvcc -arch=sm_20 -o t466 t466.cu
$ ./t466
Initial data:
10,20,30,40,50,60,70,80,90,
Results:
120,150,180,
$
注意,我还更改了linear_index_to_row_index
函子,以获得适合底层列主要存储的行索引(假设底层存储为行主要时,前一个函子返回索引)。这只涉及将除法操作更改为模操作,并传递R
而不是C
来初始化函子,因此请注意细微的差异。
相关文章:
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- 通过方法访问结构
- 最小硬币更换问题(自上而下方法)
- C++为构建时间获取QDateTime的可靠方法
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 处理多个异常集合的C++方法
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 有什么方法可以遍历结构吗
- 当类在C++中定义时,有什么方法可以"register"类吗?
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- 使用std::函数映射对象方法
- 有符号的int和int-有没有一种方法可以在C++中区分它们
- C++从另一个类访问公共静态向量的正确方法是什么
- C++优先级队列,按对象的唯一指针的特定方法升序排列
- 没有为自己的结构调用列表推回方法
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- 在类定义之后定义一个私有方法
- 枚举环境变量的惯用C++14/C++17方法
- 按键排序在飞行或不同的方法