簡體   English   中英

VexCL中的密集矩陣向量乘法

[英]Dense Matrix-vector multiplication in VexCL

VexCL似乎是一個非常有吸引力的gpu編程庫。

不幸的是,它是一個非常年輕的圖書館,那里的信息很少。 我一直在尋找如何執行矩陣向量乘法,但我發現的唯一矩陣表示是vex :: SpMat,它包含一個稀疏矩陣。

如果矩陣是密集的,那么稀疏表示通常對計算的效率較低。

我的所有矩陣都很密集,我想知道如何在VexCL中有效地執行它。

我是VexCL庫的開發人員。

我必須承認密集線性代數操作不在我的優先級列表中。 我認為很難以VexCL支持的各種設備(即OpenCL / CUDA)的性能可移植方式實現這些。 這個任務最好留給供應商BLAS實現(但歡迎補丁!)。

您可能還想查看opensource ViennaCL庫,它提供密集矩陣操作並支持OpenCL,CUDA和OpenMP后端。 他們的自動調整框架允許他們獲得與供應商調優的庫接近的便攜性能。

話雖如此,您還有一些選項(除了提供自定義內核)用於VexCL中的密集矩陣 - 矢量產品。 首先,您可以使用基於矩陣向量乘積定義的直接實現:

using namespace vex;
Context ctx(Filter::Env && Filter::Count(1));

// The n x m matrix stored row-wise.
vector<double> A(ctx, n * m);
// The LHS and RHS vectors.
vector<double> x(ctx, m);
vector<double> y(ctx, n);

// Make an n x m matrix from vector x by replicating it along the first
// dimension (reshape), multiply it elementwise by A, and reduce the result
// along the second dimension.
// In other words, y_i = sum_j (A_ij * x_j)
y = reduce<SUM>(
        extents[n][m],  // Shape of the expression to reduce,
        A * reshape(
                x,
                extents[n][m], // (We need an n x m matrix...
                extents[1]     // ... but we only have vector of size m).
            ),          // the expression,
        1               // and the dimension to reduce along.
        );

使用C ++ 14,可以很容易地將其隱藏到函數調用中:

template <class M, class V>
auto prod(size_t n, size_t m, M &&A, V &&x) {
    using namespace vex;
    auto NxM = extents[n][m];
    return reduce<SUM>(NxM, A * reshape(x, NxM, extents[1]), 1);
}

其次,您可以只使用供應商特定的庫。 例如,如果您將CUDA后端與VexCL一起使用,則可以獲得指向Ve​​xCL分配的內存區域的原始指針並調用cuBLAS gemv

double one  = 1;
double zero = 0;
cublasDgemv(
        cublas_handle, CUBPLAS_OP_N, n, m,
        &zero,
        A(0).raw_ptr(), m,
        x(0).raw_ptr(), 1
        &one,
        y(0).raw_ptr(), 1
        );

第一種方法應該不如調用cuBLAS有效。 它的優點是reduce()調用的結果是一個向量表達式,原則上你可以將其中的幾個組合成一個融合的計算內核。 例如,您可以在單個內核調用中計算Ax + Bysin(Ax) + cos(By) ,或(A + B)(x - y)或任何其他向量表達式:

z = prod(n, m, A, x) + prod(n, m, B, y);
z = sin(prod(n, m, A, x)) + cos(prod(n, m, B, y));
z = prod(n, m, A + B, x - y);

這可能比幾個鏈式cuBLAS調用更有效。 我有一些例子 ,其中VexCL因此而優於cuBLAS 1.5倍。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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