scipy 使用cupy和归约内核创建3D均值函数,以应用于cupy的通用过滤器

f2uvfpb9  于 2023-04-06  发布在  其他
关注(0)|答案(1)|浏览(252)

我试图使用cupy来加速scipy generic_filter函数的处理。我希望cupy generic_filter函数采用一个计算3D数组平均值的内核函数。但是,如果我使用cupy.mean函数,它会返回一个错误:
TypeError: bad function type
据我所知,cupygeneric_filter函数不能接受普通函数,需要一个自定义内核(cupy.ReductionKernel或cupy.RawKernel)。
谁能帮我构建一个自定义内核来计算3D数组的平均值?我看不懂cupy内核的任何文档。

xzabzqsa

xzabzqsa1#

我不是专业人士,但我已经用CuPy加速了一个月,可能遇到了类似的问题,所以我将分享我的发现:

  1. CuPy的文档非常少,而且分散在各处,如果你必须弄清楚单个函数是如何工作的,我总是会阅读NumPy的等价物,因为它们主要是从那里复制的,你也会通过接受NumPy的答案从这里找到更多。
    1.自定义内核令人困惑,不值得使用CuPy(imo),幸运的是CuPy有一个更友好的用户名为@fuse的东西,一定要看看:https://docs.cupy.dev/en/stable/reference/generated/cupy.fuse.html它基本上允许你编写普通的函数,并将它们转换为内核,而不需要任何麻烦(据我所知;他们确实为我工作)。这将我们带到
    1.不是所有的CuPy函数都可以在用户创建的内核中使用。最有可能的是,你想要使用的函数在你试图创建的内核中不受支持。对我来说,类似的事情发生在cp.argmin()中。
  2. Cupy已经做了很好的优化,这样你就不用自己去做这些繁琐的工作了,所以当你不能把一些东西放入fuse函数时,我会坚持使用普通的代码。很有可能Numba等也不支持这些函数,因为你可能需要很多数组函数。
    1.在性能方面,CuPy有一个问题,所以如果你有多维数组,一次计算1维可以快100倍:cupy.var (variance) performance much slower than numpy.var trying to understand why
    因此,我的解决任何CuPy脚本挑战的Noob工作流程:
    1.找到NumPy的解决方案
    1.将其转换为CuPy。两者之间的完整函数列表:https://docs.cupy.dev/en/stable/reference/comparison.html
    1.查看https://readthedocs.org/projects/cupy/downloads/pdf/stable/了解更多关于@fuse的信息。它指出:* “注意:目前,cupy.fuse()只能融合简单的元素级和归约操作。不支持大多数其他例程(例如cupy.matmul(),cupy.reshape())。"* 因此,无论您想添加什么花哨的函数,都可能无法工作。
    我自己也尝试过根据一些工作示例重写argmin函数,但即使作为fuse内核,它最终也比内置的cp.argmin慢得多()函数。所以根据我的经验,我建议使用内置函数,并像使用任何其他普通函数一样使用它们。但如果你有多个维度并且性能很重要,我的目标是尽可能一次处理一维。例如:array.sum(-1).sum(-1).sum(-1)代替array.sum()。
    CuPy是一个非常好的和简单的方式来利用GPU的力量NumPy功能,即使是像我这样的新手。很值得使用它imo。检查@fuse,然后使用内置的功能,你不能把什么放进保险丝,你应该是好的几乎任何东西。
    为了计算数组的平均值,CuPy提供了内置函数cupy.mean():https://docs.cupy.dev/en/stable/reference/generated/cupy.mean.html
    值得一提的是,我发现当你的数据量变得巨大时,计算速度可能会受到影响。我的核心利用率从97%下降到39%,尽管没有超过GPU内存限制。对我来说,我认为它发生在大约6 GB的阵列上。但值得一提的是,尽管知道这一点,我无法从Numba等找到更好的替代品,因为它们不会支持数组函数到我需要它们的程度。
    干杯!

相关问题