gpt4 book ai didi

c++ - 推力 即时按键排序还是不同的方法?

转载 作者:搜寻专家 更新时间:2023-10-31 01:43:44 25 4
gpt4 key购买 nike

我想知道是否可以使用 Thrust 库按键排序,而无需创建 Vector 来存储键(动态)。例如,我有以下两个 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());

结果 vector 是:

vectorKeys:    0,  0,  0,  1,  1,  1,  2,  2,  2 

VectorValues: 10, 40, 70, 20, 50, 80, 30, 60, 90

我想知道是否可以在不需要 vKeys vector (即时)的情况下按键排序,这样我就可以节省存储它的内存并能够对更多数据进行排序?

最后,我想通过相同的键求和并存储在一个 vector 中...是否有更好的方法来代替键排序然后键归约以获得相同的结果?

FinalVector = 120, 150, 180  

最佳答案

原始推力示例 you linked对具有行优先存储的基础数据集执行行求和。您的问题本质上是当底层存储是列优先时如何做同样的事情。

我们可以使用本质上相同的方法,但我们必须使用置换迭代器“即时”将底层的列优先存储转换为行优先存储。

为此,我们可以借用我描述的仿函数 here .

这是一个完整的例子:

$ 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 来初始化仿函数,因此请注意细微差别。

关于c++ - 推力 即时按键排序还是不同的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24632649/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com