【发布时间】:2015-07-25 05:30:43
【问题描述】:
我有一个@m.s. 给出的代码:
#include <thrust/device_vector.h>
#include <thrust/scan.h>
#include <thrust/iterator/transform_iterator.h>
#include <thrust/iterator/counting_iterator.h>
#include <iostream>
struct omit_negative : public thrust::unary_function<int, int>
{
__host__ __device__
int operator()(int value)
{
if (value<0)
{
value = 0;
}
return value;
}
};
int main()
{
int array[] = {2,1,-1,3,-1,2};
const int array_size = sizeof(array)/sizeof(array[0]);
thrust::device_vector<int> d_array(array, array + array_size);
thrust::device_vector<int> d_result(array_size);
std::cout << "input data" << std::endl;
thrust::copy(d_array.begin(), d_array.end(), std::ostream_iterator<int>(std::cout, " "));
thrust::inclusive_scan(thrust::make_transform_iterator(d_array.begin(), omit_negative()),
thrust::make_transform_iterator(d_array.end(), omit_negative()),
d_result.begin());
std::cout << std::endl << "after inclusive_scan" << std::endl;
thrust::copy(d_result.begin(), d_result.end(), std::ostream_iterator<int>(std::cout, " "));
using namespace thrust::placeholders;
thrust::scatter_if(d_array.begin(),
d_array.end(),
thrust::make_counting_iterator(0),
d_array.begin(),
d_result.begin(),
_1<0
);
std::cout << std::endl << "after scatter_if" << std::endl;
thrust::copy(d_result.begin(), d_result.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
}
我不知道推力,但现在我想我要放弃编写自己的代码的想法了。我宁愿用推力。我修改了我的算法:而不是 -1 有 0(所以 make_transform 不是必需的)。您的示例也在主机上创建数组。但实际上我已经准备好存储在设备上的数组,我喜欢使用它(而不是向量)来避免创建冗余内存并避免复制内存(它需要时间 - 最小的时间成本是我的目标)。我不确定如何使用数组而不是向量。这是我写的:
int* dev_l_set = 0;
cudaMalloc((void**)&dev_l_set, actualVerticesRowCount * sizeof(int));
...prepare array in kernel...
thrust::device_vector<int> d_result(actualVerticesRowCount);
thrust::inclusive_scan(dev_l_set, dev_l_set + actualVerticesRowCount, dev_l_set);
using namespace thrust::placeholders;
thrust::scatter_if(dev_l_set, dev_l_set + actualVerticesRowCount, thrust::make_counting_iterator(0), dev_l_set, d_result.begin(), _1 <= 0);
cudaFree(dev_l_set);
dev_l_set = thrust::raw_pointer_cast(d_result.data());
我无法从 device_vector 转换为 int*,但我想将扫描结果存储在初始 dev_l_set 数组中。也可以原地做就好了,有必要在scatter_if中使用d_result吗?
实际输入(存储在 int* - 设备端): (示例)
dev_l_set[0] = 0
dev_l_set[1] = 2
dev_l_set[2] = 0
dev_l_set[3] = 3
dev_l_set[4] = 0
dev_l_set[5] = 1
上述输入的期望输出:
dev_l_set[0] = 0
dev_l_set[1] = 2
dev_l_set[2] = 0
dev_l_set[3] = 5
dev_l_set[4] = 0
dev_l_set[5] = 6
dev_l_set 应该存储输入,然后在原地进行扫描,最后它应该存储输出。
可能是这样的。
int* dev_l_set = 0;
cudaMalloc((void**)&dev_l_set, actualVerticesRowCount * sizeof(int));
...prepare array in kernel... (see input data)
thrust::inclusive_scan(dev_l_set, dev_l_set + actualVerticesRowCount, dev_l_set);
using namespace thrust::placeholders;
thrust::scatter_if(dev_l_set, dev_l_set + actualVerticesRowCount, thrust::make_counting_iterator(0), dev_l_set, dev_l_set, _1 <= 0);
我的 Cuda 版本(应用程序应该工作的最低版本)是 5.5(特斯拉 M2070),不幸的是我不能使用 c++11。
【问题讨论】:
-
就地可能是可能的。您的输入数据现在看起来如何?请在您的问题中举例说明您想要的输出数据。
标签: c++ arrays vector cuda thrust