簡體   English   中英

ViennaCL:矩陣向量乘積失敗

[英]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代替NxNy當計算元件的偏移(但不遍歷它們)。

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM