求问 基于 vector 的矩阵乘法 怎么做的啊,没明白

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了求问 基于 vector 的矩阵乘法 怎么做的啊,没明白相关的知识,希望对你有一定的参考价值。

基于 vector 的矩阵乘法 ,就是利用向量的内积来做乘法,例如:
AB=
(A1,A2,...,An)(B1,B2,B3,...,Bn)

其中Ai,是A的行向量
Bi是B的列向量

=
A1B1,A1B2,...,A1Bn
A2B1,A2B2,...,A2Bn
...
AnB1,AnB2,...,AnBn

其中AiBj是向量的内积
参考技术A

void CMatDeal::Matrix_Mul(vector<vector<double>> Mul1, vector<vector<double>> Mul2, vector<vector<double>> &Mul3)

int iLen1 = Mul1.size();

int ilen11 = Mul1[0].size();

int iLen2 = Mul2.size();

int ilen22 = Mul2[0].size();

double Datab = 0;

vector<double> Matrix_mul;

for (int i = 0; i < iLen1; i++)//i是第1个矩阵的行数

Matrix_mul.clear();//clear一下,防止叠加

for (int k = 0; k < iLen1; k++)//k是第2个矩阵的列数

for (int j = 0; j < ilen11; j++)//j是第1个矩阵的列数,第2个矩阵的行数

Datab += Mul1[i][j] * Mul2[j][k];

Matrix_mul.push_back(Datab);

Datab = 0;

Mul3.push_back(Matrix_mul);


使用 2D std::vector 对 SYCL 进行矩阵乘法

【中文标题】使用 2D std::vector 对 SYCL 进行矩阵乘法【英文标题】:Matrix Multiplication on SYCL using 2D std::vector 【发布时间】:2020-10-17 18:15:06 【问题描述】:

我是 SYCL 和 C++ 的新手。这是我使用 2D std::vector 进行简单矩阵乘法的内核。


void MatrixMulParallel(queue& q, 
    const std::vector<std::vector<double>>& a_host,
    const std::vector<std::vector<double>>& b_host,
    std::vector<std::vector<double>>& c_gpu) 
    /*
        To Multiply: C[M][P] = A[M][N] * B[N][P]
    */
    PROFILE_FUNCTION();
    try 
        size_t M = a_host.size();
        size_t N = a_host[0].size();
        size_t P = b_host[0].size();
        // Create device buffers for A, B, C
        buffer a(a_host.data(), range<2>M, N);
        buffer b(b_host.data(), range<2>N, P);
        buffer c(c_gpu.data(), range<2>M, P);

        PROFILE_SCOPE("Starting Multiply on GPU");
        std::cout << "GPU::Multiplying A and B into C.\n";
        auto e = q.submit([&](handler& h) 

            auto A = a.get_access<access::mode::read>(h);
            auto B = b.get_access<access::mode::read>(h);
            auto C = c.get_access<access::mode::write>(h);

            h.parallel_for(range<2>M, P, [=](id<2> index) 
                // index[0] allows accessing ROW index, index[1] is column index
                
                int row = index[0];
                int col = index[1];
                auto sum = 0.0;
                for (int i = 0; i < N; i++)
                    sum += A[row][i] * B[i][col]; // Error #1
                C[index] = sum; // Error #2
                );
            );
        e.wait();
    
    catch (sycl::exception const& e) 
        std::cout << "An exception is caught while multiplying matrices.\n";
        terminate();
    

我收到 两个错误,如下所示:

    错误 #1:invalid operands to binary expression ('const std::vector&lt;double, std::allocator&lt;double&gt;&gt;' and 'const std::vector&lt;double, std::allocator&lt;double&gt;&gt;') 错误 #2:no viable overloaded '='

我尝试查找类似于invalid operands for binary expression (...) 的错误,但它们似乎都不能帮助调试我的具体情况。也许是因为这对初学者不友好。

据我目前了解,a_host.data() 显示返回类型std::vector&lt;double&gt;(不应该是std::vector&lt; std::vector&lt;double&gt; &gt; 吗?)。

我已经尝试使用具有静态已知尺寸的std::array,它可以工作。

如何使用 2D std::vector 完成这项工作?

任何帮助将不胜感激。

【问题讨论】:

【参考方案1】:

2D std::vector&lt;std::vector&lt;T&gt;&gt; 没有元素连续存储在内存中。

更好的方法是声明 std::vector&lt;T&gt; 大小为 M*N,即线性数组,并将它们作为连续块进行操作。

由于目标向量C 应该是二维的,因此创建一个在行和列中都索引的内核。 SYCL index 实际上填满了线性可访问的内存块。

这是我使用std::vector 使其工作的方法:

template <typename T>
void MatrixMulParallelNaive(queue& q, 
    const std::vector<T>& a_host,
    const std::vector<T>& b_host,
    std::vector<T>& c_gpu) 
    /*
        To Multiply: C[M][P] = A[M][N] * B[N][P]
    */
    PROFILE_FUNCTION();
    try 
        
        buffer<double, 1> a(a_host.data(), range<1>a_host.size()); // 1D
        buffer<double, 1> b(b_host.data(), range<1>b_host.size()); // 1D
        buffer<double, 2> c(c_gpu.data(), range<2>M, P); // Create 2D buffer
        PROFILE_SCOPE("Starting Multiply on GPU");
        std::cout << "GPU::Multiplying A and B into C.\n";
        auto e = q.submit([&](handler& h) 

            auto A = a.get_access<access::mode::read>(h);
            auto B = b.get_access<access::mode::read>(h);
            auto C = c.get_access<access::mode::write>(h);
            
            h.parallel_for(range<2>M, P, [=](id<2> index) 
                // Threading index that iterates over C.
                int row = index[0];
                int col = index[1];
                auto sum = 0.0;
                // Compute result of ONE element of C
                for (int i = 0; i < N; i++)
                    sum += A[row * M + i] * B[i * N + col];
                C[index] = sum;
                );
            );
        e.wait();
    
    catch (sycl::exception const& e) 
        std::cout << "An exception is caught while multiplying matrices.\n";
        terminate();
    



【讨论】:

【参考方案2】:

更一般地说,在进行 HPC 时避免使用非紧凑的数据结构。 与连续数组元素相比,它对内存层次结构不太友好,而且初始化很复杂。改用类似于md_spanmd_array 的东西(基本上是类固醇上的Fortran 数组:-))。

【讨论】:

以上是关于求问 基于 vector 的矩阵乘法 怎么做的啊,没明白的主要内容,如果未能解决你的问题,请参考以下文章

基础训练 矩阵乘法

使用 2D std::vector 对 SYCL 进行矩阵乘法

求问C++的Eigen矩阵运算库有没有提供两个矩阵对应元素相乘的方法

矩阵乘法性能,int vs double

求问latex中奇怪的矩阵怎么打

Opengl相机和乘法矩阵