【问题标题】:How to write the cuda kernel for convolutions?如何为卷积编写 cuda 内核?
【发布时间】:2018-05-03 04:01:45
【问题描述】:

我是 cuda 的新手,我想编写一个 cuda 内核,在给定输入矩阵、卷积(或滤波器)和输出矩阵的情况下计算卷积。

注意:我希望 cuda 内核的每个线程在输出矩阵中计算一个值。

我该怎么做?

【问题讨论】:

  • 据我所知,CUDA 网站上有几十个示例。特别是考虑到卷积是一项非常常见的任务这一事实。这种情况是否发生了变化,或者您在那里没有发现任何东西?
  • @CWBudde 谢谢你的评论。是的,我在整个网站上找到了几个带有许多困难案例的长示例,但不幸的是,我还没有找到简单的示例。如果你有的话,我会很高兴的。

标签: cuda nvidia gpgpu convolution


【解决方案1】:

如果过滤器覆盖矩阵的填充范围,则可以直接转换为cublasSgemm

例如,假设矩阵的维度是 5 * 4,需要 130 个过滤器,那么要训练的过滤器矩阵的维度是 130 * 20,那么 5 * 4 的矩阵可以取为 20 * 1 .

这样计算速度是最优的;它被转换为 m1 (130, 20) 和 m2 (20, 1) 之间的矩阵乘法。

【讨论】:

  • 感谢您的评论和示例。它让我对这个问题有了一些了解。您是否也有一些 cuda 代码示例来执行此操作。如果可能的话,我想通过真实的例子知道它是如何工作的。谢谢
  • 我总是用“JCuda”来调用 Cuda 库,所以代码不在 C 中。您可以查看 Web 上的 cublasSgemm 示例以及 Cuda 手册中的示例。使用操作 'N' 和 'N' 执行 sgemm 并将 lda 和 ldb 和 ldc 设置为 130、20 和 130。熟悉使用 cublasSgemm 方法需要一点时间。
  • 谢谢。当然我会检查和编码,我会更新你。
【解决方案2】:

我想编写一个 cuda 内核来计算给定输入矩阵、卷积(或滤波器)和输出矩阵的卷积。

您可能对该主题的this treatment 感兴趣(虽然它有点老了)。或者看CUDA卷积核示例程序:non-separableseparable

我希望 cuda 内核的每个线程在输出矩阵中计算一个值。

如果您点击该链接,您会意识到您并不完全希望这样做。换句话说:不要对内核应该如何在线程之间分配工作做出严格的假设,您以后可能会改变主意。

【讨论】:

    【解决方案3】:

    如果您正在寻找图像卷积核,此链接可能会有所帮助 (Two Dimensional (2D) Image Convolution in CUDA by Shared & Constant Memory: An Optimized way )。

    就我而言,使用每个线程计算输出中的像素或位置可能不是一个好主意。请考虑如何加载此卷积的子区域,或者同一 warp 中的线程是否在每次读取时读取连续内存。否则,即使有数百个线程可用,内核也可能会受到数据加载的影响。

    因此,基本上您可以只编写您描述的代码,并使用分析器 (nvvp) 获得进一步的优化建议。

    【讨论】:

    • 感谢您的评论和参考网站。我只是在寻找创建一个二维卷积核,以便在使用 CUDA 的 GPU 上使用。最后,我希望我的代码能够打印输入、过滤和输出矩阵。
    • 链接中的代码是否执行 winograd(或任何其他次立方)转换?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-11
    • 2012-04-26
    • 2011-10-23
    • 1970-01-01
    • 2016-12-31
    • 2016-11-01
    • 2020-10-10
    相关资源
    最近更新 更多