cublas 函数的重叠输入和输出
Posted
技术标签:
【中文标题】cublas 函数的重叠输入和输出【英文标题】:Overlapped input and output for cublas functions 【发布时间】:2021-03-20 05:00:31 【问题描述】:我正在使用 cublas 库处理一些大数据以进行矩阵乘法。为了节省内存空间,我想要A=A*B
之类的东西,其中A
和B
都是n×n 方阵,即对输出和输入矩阵之一使用相同的内存空间。
虽然一些旧帖子说这在 cublas 库中是不允许的,但我实际上使用 cublasZgemmStridedBatched()
函数实现了它。令人惊讶的是,计算是完全正确的,并且反复运行是稳定的。所以我想知道当前的cublas库是否支持重叠的输入和输出。如果是,它实际节省了多少内存?我的意思是直观地说该函数至少需要一些额外的内存来存储中间计算,因为A
ij
= A
ik
B
kj
依赖于整行 A
。这对于批处理 gemms 是否特别节省内存?
【问题讨论】:
我认为在一般情况下不提供 CUBLAS 中的输入/输出重叠,除了geam
等少数例外情况。我怀疑在各种矩阵乘法运算(包括gemmStridedBatched
)的情况下,您可能能够编写一个演示案例,在其中您可以观察到失败,可能涉及到单独足够大的矩阵。
@Robert Crovella 感谢 cmets。我使用 'cublasDgemm()' 进行了更多测试。在我的 GPU 上,就地操作在恰好 512×512 矩阵之前是正确的,而对于 513×513 矩阵则错误。
这似乎工作和似乎不工作的情况可能取决于 GPU 类型、CUDA 版本和特定的 CUBLAS 函数,也许还有其他变量。您的测试用例足以证明它不是一般提供的,因此即使有特定限制,我也会非常犹豫是否依赖它。
【参考方案1】:
虽然一些旧帖子说 cublas 库中不允许这样做,但
而且它们是完全正确的(注意“旧帖子”指的是标准 GEMM 调用,而不是您询问的批处理实现)。
我实际上是使用
cublasZgemmStridedBatched()
函数实现的。出乎意料的是,计算完全正确,反复运行也很稳定
这并没有被记录为安全的,我怀疑您可能只是靠运气才能获得稳定的结果,因为小矩阵可能已预加载到共享内存或寄存器中,因此就地操作有效。如果你使用更大的矩阵,我想你会看到失败,因为最终会出现这样一种情况,即在一个写入周期之后,如果没有多次访问源矩阵,就无法执行单个 GEMM,这会破坏源矩阵。
即使您发现它适用于一种情况,我也不推荐就地操作。不同的问题大小、库版本和硬件可能会产生您根本没有测试过的故障。选择和相关风险取决于您。
【讨论】:
感谢您的回答,您完全正确。我使用cublasDgemm()
进行了更多测试。在我的 GPU 上,就地操作在恰好 512×512 矩阵之前是正确的,而对于 513×513 矩阵来说它是错误的。以上是关于cublas 函数的重叠输入和输出的主要内容,如果未能解决你的问题,请参考以下文章