【问题标题】:CUBLAS - matrix addition.. how?CUBLAS - 矩阵加法..怎么样?
【发布时间】:2026-01-21 05:25:01
【问题描述】:

我正在尝试使用 CUBLAS 对两个未知大小的大矩阵求和。我需要一个完全优化的代码(如果可能的话),所以我选择不重写矩阵加法代码(简单),而是使用 CUBLAS,特别是允许对 A 和 C 求和的 cublasSgemm 函数(如果 B 是单位矩阵):*C = alpha*op(A)*op(B)+beta*c*

问题是:C 和 C++ 以行优先格式存储矩阵,cublasSgemm 旨在(为了与 fortran 兼容)以列优先格式工作。您可以指定是否先转置A和B,但您不能指示转置C。所以我无法完成我的矩阵加法..

我不能自己转置 C 矩阵,因为该矩阵的最大尺寸类似于 20000x20000。

请问有什么解决办法吗?

【问题讨论】:

  • 如果你只是添加矩阵,这实际上并不重要,对吧?你给它 alpha、Aij、beta 和 Cij。它认为你给它alpha、Aji、beta和Cji,并给你它认为的Cji = beta Cji + alpha Aji。但就您而言,这是正确的 Cij。我担心的是,当你开始做重要的事情时——比如矩阵产品。在那里,可能无法解决它。
  • 但更重要的是,你不想想要使用 GEMM 来做矩阵addition——你在做一个完全没有意义的事情矩阵乘法(需要大约 20,000^3 次操作,并且需要多次通过内存)只需一次执行〜20,000^2 次操作!将矩阵视为 20,000^2 长的向量并使用 saxpy。
  • 非常感谢您提供的 saxpy 解决方案,非常棒!所以完全不可能用 cublas 实现(性能)版本的矩阵乘法,对吧?我应该自己编码吗?
  • 矩阵乘法是内存带宽密集型的,因此在自己编写代码和调整版本之间存在巨大(10 倍或100 倍的因素)的性能差异。理想情况下,您会更改代码中的结构以匹配库。如果你不能,你可以只使用线性代数恒等式。 C-vs-Fortran 排序意味着当您传入 A 时,CUBLAS “看到” A^T(A 转置)。所以没关系。如果您想要的是 C=A.B,请传入 B.A 。然后库看到 (B^T . A^T),并计算 C^T = (A.B)^T;然后当它传回 C^T 时,你得到(在你的订购中)C。测试它看看。
  • 你解决了我的问题,谢谢乔纳森,非常感谢!

标签: c++ matrix cuda blas cublas


【解决方案1】:

cublasgeam 已添加到 CUBLAS5.0。 它计算 2 个可选转置矩阵的加权和

【讨论】:

    【解决方案2】:

    如果您只是添加矩阵,那实际上并不重要。你给它 alpha、Aij、beta 和 Cij。它认为你正在给它 alpha、Aji、beta 和 Cji,并给你它认为的 Cji = beta Cji + alpha Aji。但就您而言,这是正确的 Cij。我担心的是当你开始做一些重要的事情时——比如矩阵产品。在那里,可能无法解决它。

    但更重要的是,您不想使用 GEMM 进行矩阵加法 - 您正在做一个完全没有意义的矩阵乘法(这需要大约 20,0003 次操作和许多穿过内存)对于一个只需要约 20,0002 次操作和一次通过的操作!将矩阵视为 20,000^2 长的向量并使用 saxpy。

    矩阵乘法是内存带宽密集型的,因此在自己编写代码和调整版本之间存在巨大的性能差异(10 倍或 100 倍)。理想情况下,您会更改代码中的结构以匹配库。如果不能,在这种情况下,您可以只使用线性代数恒等式来管理。 C-vs-Fortran 排序意味着当您传入 A 时,CUBLAS “看到” AT (转置)。这很好,我们可以解决它。如果您想要的是 C=A.B,则以相反的顺序传入矩阵 B.A 。然后库看到 (BT . AT),并计算 CT = (A.B)T;然后当它传回 CT 时,你得到(在你的排序中)C。测试它并查看。

    【讨论】: