【发布时间】:2019-05-11 10:26:39
【问题描述】:
我有三组点 X、Y、Z。我打算使用 Eigen::Matrix4f 应用变换。我使用一个 zip 迭代器和一个转换运算符来做到这一点。程序编译但结果只是部分正确。这篇文章的灵感来自How to modify the contents of a zip iterator
的转变 A= [0 1 2;3 4 5;6 7 8; 1 1 1] 与 M=[1 2 3 4;5 6 7 8;9 10 11 12;13 14 15 16] 使用 M*A 应导致: R=[28 34 40; 68 86 104; 108 138 168] 但是它给出: R=[28 34 40; 208 251 294; 2410 2905 3400]。
X 值正在正确修改。但是 Y 和 Z 值是错误的。
我的代码和cmakelists如下:
#include <thrust/iterator/zip_iterator.h>
#include <thrust/execution_policy.h>
#include <thrust/copy.h>
#include <thrust/device_vector.h>
#include <Eigen/Dense>
#include <iostream>
typedef thrust::device_vector<float>::iterator FloatIterator;
typedef thrust::tuple<FloatIterator, FloatIterator, FloatIterator> FloatIteratorTuple;
typedef thrust::zip_iterator<FloatIteratorTuple> Float3Iterator;
typedef thrust::tuple<float,float,float> Float3;
struct modify_tuple
{
Eigen::Matrix4f _Mat4f;
modify_tuple(Eigen::Matrix4f Mat4f) : _Mat4f(Mat4f) { }
__host__ __device__ Float3 operator()(Float3 a) const
{
Eigen::Vector4f V(thrust::get<0>(a), thrust::get<1>(a), thrust::get<2>(a), 1.0);
V=_Mat4f*V;
Float3 res=thrust::make_tuple( V(0,0), V(1,0), V(2,0) );
return res;
}
};
int main(void)
{
thrust::device_vector<float> X(3);
thrust::device_vector<float> Y(3);
thrust::device_vector<float> Z(3);
X[0]=0, X[1]=1, X[2]=2;
Y[0]=4, Y[1]=5, Y[2]=6;
Z[0]=7, Z[1]=8, Z[2]=9;
std::cout << "X,Y,Z before transformation="<< std::endl;
thrust::copy_n(X.begin(), 3, std::ostream_iterator<float>(std::cout, ","));
std::cout << std::endl;
thrust::copy_n(Y.begin(), 3, std::ostream_iterator<float>(std::cout, ","));
std::cout << std::endl;
thrust::copy_n(Z.begin(), 3, std::ostream_iterator<float>(std::cout, ","));
std::cout << std::endl;
Float3Iterator P_first = thrust::make_zip_iterator(make_tuple(X.begin(), Y.begin(), Z.begin()));
Float3Iterator P_last = thrust::make_zip_iterator(make_tuple(X.end(), Y.end(), Z.end()));
Eigen::Matrix4f M;
M(0,0)= 1; M(0,1)= 2; M(0,2)= 3; M(0,3)= 4;
M(1,0)= 5; M(1,1)= 6; M(1,2)= 7; M(1,3)= 8;
M(2,0)= 9; M(2,1)= 10; M(2,2)= 11; M(2,3)= 12;
M(3,0)= 13; M(3,1)= 14; M(3,2)= 15; M(3,3)= 16;
thrust::transform(thrust::device, P_first,P_last, P_first, modify_tuple(M));
std::cout << "X, Y, Z after transformation="<< std::endl;
thrust::copy_n(X.begin(), 3, std::ostream_iterator<float>(std::cout, ","));
std::cout << std::endl;
thrust::copy_n(Y.begin(), 3, std::ostream_iterator<float>(std::cout, ","));
std::cout << std::endl;
thrust::copy_n(Z.begin(), 3, std::ostream_iterator<float>(std::cout, ","));
std::cout << std::endl;
return 0;
}
CMakeLists.txt
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
FIND_PACKAGE(CUDA REQUIRED)
INCLUDE_DIRECTORIES(${CUDA_INCLUDE_DIRS})
INCLUDE_DIRECTORIES (/usr/include/eigen3)
set(
CUDA_NVCC_FLAGS
${CUDA_NVCC_FLAGS};
-O3 -gencode arch=compute_52,code=sm_52;
)
CUDA_ADD_EXECUTABLE(modify_zip_iterator_stackoverflow_ver2 modify_zip_iterator_stackoverflow_ver2.cu)
TARGET_LINK_LIBRARIES(modify_zip_iterator_stackoverflow_ver2 ${CUDA_LIBRARIES})
【问题讨论】:
-
你对问题描述的向量和代码不匹配
-
矩阵(4X4)*向量(4X1)=向量(4X1)。不清楚为什么它不起作用。
标签: cuda iterator zip tuples thrust