【发布时间】:2017-01-24 12:33:25
【问题描述】:
我有两个索引集,一个在 [0, N] 范围内,一个在 [0, M] 范围内,其中 N != M。索引用于引用不同 thrust::device_vectors 中的值。
基本上,我想为这些索引的每个组合创建一个 GPU 线程,因此 N*M 个线程。每个线程都应根据索引组合计算一个值,并将结果存储在另一个 thrust::device_vector 中,该索引也基于输入组合。
这似乎是一个相当标准的问题,但我无法找到一种方法来解决这个问题。文档只提到了问题,其中向量的元素 i 需要用另一个向量的元素 i 计算一些东西。有thrust::permutation_iterator,但据我了解,它只给了我重新排序数据的选项,我还必须指定顺序。
一些代码:
#include <thrust/device_vector.h>
#include <thrust/host_vector.h>
#include <iostream>
int main()
{
// Initialize some data
const int N = 2;
const int M = 3;
thrust::host_vector<int> vec1_host(N);
thrust::host_vector<int> vec2_host(M);
vec1_host[0] = 1;
vec1_host[1] = 5;
vec2_host[0] = -3;
vec2_host[1] = 42;
vec2_host[2] = 9;
// Copy to device
thrust::device_vector<int> vec1_dev = vec1_host;
thrust::device_vector<int> vec2_dev = vec2_host;
// Allocate device memory to copy results to
thrust::device_vector<int> result_dev(vec1_host.size() * vec2_host.size());
// Create functor I want to call on every combination
struct myFunctor
{
thrust::device_vector<int> const& m_vec1;
thrust::device_vector<int> const& m_vec2;
thrust::device_vector<int>& m_result;
myFunctor(thrust::device_vector<int> const& vec1, thrust::device_vector<int> const& vec2, thrust::device_vector<int>& result)
: m_vec1(vec1), m_vec2(vec2), m_result(result)
{
}
__host__ __device__
void operator()(size_t i, size_t j) const
{
m_result[i + j * m_vec1.size()] = m_vec1[i] + m_vec1[j];
}
} func(vec1_dev, vec2_dev, result_dev);
// How do I create N*M threads, each of which calls func(i, j) ?
// Copy results back
thrust::host_vector<int> result_host = result_dev;
for(int i : result_host)
std::cout << i << ", ";
std::cout << std::endl;
// Expected output:
// -2, 2, 43, 47, 10, 14
return 0;
}
我很确定这很容易实现,我想我只是缺少正确的搜索词。无论如何,所有帮助表示赞赏:)
【问题讨论】:
-
这个操作的输出维度是多少
-
结果向量的维度为 N*M。因此,每个线程都会计算一个值。
-
没有推力的概念,也没有我所知道的外部产品,所以我怀疑您尝试做的任何事情都是可能的
-
也许推力::for_each 或推力::制表与推力::counting_iterator 范围为 0 到 N*M-1 可能会有所帮助。线性索引可以转换为二维索引,可以与您的仿函数一起使用。
-
这对我来说似乎很有可能,我想到了几种不同的方法。也许我在掩盖描述的某些关键部分。