[英]ViennaCL: matrix-vector product fails
我正在嘗試使用ViennaCL庫用OpenCL做一個簡單的矩陣向量乘積。
這是我的主要內容:
#include "viennacl/scalar.hpp"
#include "viennacl/vector.hpp"
#include "viennacl/matrix.hpp"
#include "viennacl/linalg/prod.hpp"
#include "viennacl/matrix_proxy.hpp"
#include "viennacl/linalg/lu.hpp"
int main()
{
viennacl::ocl::set_context_device_type(0, viennacl::ocl::gpu_tag());
std::vector<viennacl::ocl::device> devices = viennacl::ocl::current_context().devices();
viennacl::ocl::current_context().switch_device(devices[0]);
int Nx=10;
int Ny=10;
//GPU vectors
viennacl::matrix<float> vcl_A(Nx,Ny);
viennacl::vector<float> vcl_b(Ny);
viennacl::vector<float> vcl_c(Nx);
//CPU vectors
std::vector<float> stl_A(Nx*Ny);
std::vector<float> stl_b(Ny);
std::vector<float> stl_c(Nx);
//filling CPU vectors
for (unsigned int i = 0; i < Nx; ++i)
for (unsigned int j = 0; j < Ny; ++j)
stl_A[i*Ny + j] = (float) (rand()%100);
for (unsigned int i = 0; i < stl_b.size(); ++i)
stl_b[i] = (float) (rand()%100);
//copying input data to GPU
viennacl::fast_copy(&(stl_A[0]),
&(stl_A[0]) + stl_A.size(),
vcl_A);
viennacl::fast_copy(stl_b, vcl_b);
//launching product c = A*b
vcl_c = viennacl::linalg::prod(vcl_A, vcl_b);
//copying output data back to CPU
viennacl::copy(vcl_c, stl_c);
viennacl::backend::finish();
}
然后,我的stl_c向量的第一個系數正確計算,但其他9個系數為0
。 當我將尺寸更改為較高值時,在向量的開頭我得到了多個不正確的系數,但是對於其他系數,我仍然得到了一堆零。
我猜我的某些副本做錯了方法,但也許是由於我的生產操作引起的(本地/全局大小問題,但我認為ViennaCL會處理所有問題)
任何知道我在做什么錯? 任何幫助或建議,將不勝感激。
(我在VS 2012上運行代碼,我的GPU是NVIDIA Geforce gtx 670)
1.問題:
manual-types-matrix
頁面中的viennacl::matrix
文檔指出:
默認情況下,
matrix<>
的內部存儲緩沖區用零填充,以使內部矩陣的大小是例如2的冪的倍數。 在矩陣上使用fast_copy()
時,需要正確考慮填充的零。 查詢internal_size1()
和internal_size2()
來執行此操作。
這意味着viennacl::matrix
的元素不連續,這與用於模擬矩陣的std::vector
中的元素相反。 因此,此行不符合您的期望:
viennacl::fast_copy(&(stl_A[0]), &(stl_A[0]) + stl_A.size(), vcl_A);
2.解決方案:
那么,如何正確地將主機矩陣復制到ViennaCL矩陣?
一種可能是使用std::vector<std::vector<float>>
表示宿主矩陣,然后使用viennacl::copy
而不是vienna::fast_copy
,元素的填充將為您處理。
std::vector<std::vector<float>> stl_A(Ny);
for (unsigned int i = 0; i < Ny; ++i) {
stl_A[i].resize(Nx);
for (unsigned int j = 0; j < Nx; ++j)
stl_A[i][j] = (float)(rand() % 100);
}
viennacl::copy(stl_A, vcl_A);
另一種可能性,如文檔中建議的,是匹配的內部布局viennacl::matrix
在主基質,通過使用internal_size
代替Nx
和Ny
當計算元件的偏移(但不遍歷它們)。
std::vector<float> stl_A(vcl_A.internal_size());
for (unsigned int i = 0; i < Ny; ++i)
for (unsigned int j = 0; j < Nx; ++j)
stl_A[i*vcl_A.internal_size2() + j] = (float)(rand() % 100);
viennacl::fast_copy(&(stl_A[0]), &(stl_A[0]) + stl_A.size(), vcl_A);
3.注意事項:
上面提供的兩個代碼示例均適用於行優先矩陣。 對於主要列矩陣,請交換循環並使用internal_size1()
代替。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.