对 STL 副本的推力无法按预期工作
Thrust to STL copy doesn't work as intended
我不确定 thrust::copy
到 STL 矢量的实际工作原理。
当我执行以下操作时,它会给我预期的结果:
struct TestOperation
{
TestOperation(){}
__host__ __device__
CustomPoint operator()(const CustomPoint& point)
{
CustomPoint pt;
pt.x = point.x * 2;
pt.y = point.y * 2;
pt.z = point.z;
return pt;
}
};
void CudaLoader::TestLoader(std::vector<CustomPoint>& customPoints) //Host vector reference
{
thrust::device_vector<CustomPoint> devicePoints(customPoints.begin(), customPoints.end());
thrust::device_vector<CustomPoint> output;
output.reserve(devicePoints.size());
thrust::transform(devicePoints.begin(), devicePoints.end(), output.begin(), TestOperation());
for (int i = 0; i < customPoints.size(); i++)
{
customPoints[i] = output[i];
}
}
但是遍历所有元素,尤其是当有很多元素时,对我来说似乎不是最佳选择,所以我想使用 copy
。但是当我尝试这样做时:
thrust::copy(output.begin(), output.end(), customPoints.begin());
而不是循环,然后我没有得到预期的结果 - 作为参数给出的引用的主机 stl 向量保持不变。此外,output.size()
returns 0,但我看到存储大小是正确的。这是为什么?
问题的根源是这样的:
thrust::device_vector<CustomPoint> output;
output.reserve(devicePoints.size());
reserve
仅更改向量的保证最小存储分配。它不会更改其 大小 。在上面的代码中,output.size()
仍然是 0。另请注意,thrust::transform
不会改变输出向量的大小。只要有足够的有效内存来保存转换的输出,执行转换操作的推力闭包内核就不会产生非法内存访问错误。
改为这样做:
thrust::device_vector<CustomPoint> output;
output.resize(devicePoints.size());
thrust::transform(devicePoints.begin(), devicePoints.end(), output.begin(), TestOperation());
然后
thrust::copy(output.begin(), output.end(), customPoints.begin());
将按预期工作,因为 output
具有非零大小。
我不确定 thrust::copy
到 STL 矢量的实际工作原理。
当我执行以下操作时,它会给我预期的结果:
struct TestOperation
{
TestOperation(){}
__host__ __device__
CustomPoint operator()(const CustomPoint& point)
{
CustomPoint pt;
pt.x = point.x * 2;
pt.y = point.y * 2;
pt.z = point.z;
return pt;
}
};
void CudaLoader::TestLoader(std::vector<CustomPoint>& customPoints) //Host vector reference
{
thrust::device_vector<CustomPoint> devicePoints(customPoints.begin(), customPoints.end());
thrust::device_vector<CustomPoint> output;
output.reserve(devicePoints.size());
thrust::transform(devicePoints.begin(), devicePoints.end(), output.begin(), TestOperation());
for (int i = 0; i < customPoints.size(); i++)
{
customPoints[i] = output[i];
}
}
但是遍历所有元素,尤其是当有很多元素时,对我来说似乎不是最佳选择,所以我想使用 copy
。但是当我尝试这样做时:
thrust::copy(output.begin(), output.end(), customPoints.begin());
而不是循环,然后我没有得到预期的结果 - 作为参数给出的引用的主机 stl 向量保持不变。此外,output.size()
returns 0,但我看到存储大小是正确的。这是为什么?
问题的根源是这样的:
thrust::device_vector<CustomPoint> output;
output.reserve(devicePoints.size());
reserve
仅更改向量的保证最小存储分配。它不会更改其 大小 。在上面的代码中,output.size()
仍然是 0。另请注意,thrust::transform
不会改变输出向量的大小。只要有足够的有效内存来保存转换的输出,执行转换操作的推力闭包内核就不会产生非法内存访问错误。
改为这样做:
thrust::device_vector<CustomPoint> output;
output.resize(devicePoints.size());
thrust::transform(devicePoints.begin(), devicePoints.end(), output.begin(), TestOperation());
然后
thrust::copy(output.begin(), output.end(), customPoints.begin());
将按预期工作,因为 output
具有非零大小。