【问题标题】:Passing CuPy array through scipy low pass filter通过 scipy 低通滤波器传递 CuPy 数组
【发布时间】:2020-12-22 01:28:39
【问题描述】:

我想通过 scipy 内置的低通滤波器发送一些数据。我正在用下面的一些 numpy 数据数组对其进行测试。它工作正常并在使用 numpy 时输出过滤后的值。然后我想看看我是否可以使用 GPU 并加快速度,并听说了与 numpy 类似的 CuPy。但是,当我将 numpy 数组替换为 cupy 数组时,出现以下错误ValueError: could not convert b, a, and x to a common type

from scipy.signal import butter, lfilter, freqz
import cupy as cp
import time
import numpy as np

def butter_lowpass(cutoff, fs, order=5):
    nyq = 0.5 * fs
    normal_cutoff = cutoff / nyq
    b, a = butter(order, normal_cutoff, btype='low', analog=False)
    return b, a

def butter_lowpass_filter(data, cutoff, fs, order=5):
    b, a = butter_lowpass(cutoff, fs, order=order)
    y = lfilter(b, a, data)
    return y

order = 1
fs = 30.0       
cutoff = 0.3 

new_frame_np = np.ones(100)*3
new_frame_cp = cp.ones(100)*3

y = butter_lowpass_filter(new_frame_np, cutoff, fs, order) #WORKS
y = butter_lowpass_filter(new_frame_cp, cutoff, fs, order) #DOES NOT WORK

如何让cupy数组在上面的例子中工作?

Scipy 似乎适用于 CPU 任务,因此它可能不适用于 GPU 的 Cupy 数组。我找不到任何为cupy阵列提供低通或带通滤波器的库。

【问题讨论】:

  • 您不能将 GPU 阵列与 scipy.signal 一起使用。对于基于 GPU 的信号处理,您应该查看 cuSignal 或 torch.audio (pytorch)
  • 我查看了 cuSignal 并确认, firwin() 是什么可以进行过滤的?没有任何明确称为低通滤波器的东西

标签: python arrays numpy scipy cupy


【解决方案1】:

我是 cuSignal 的创造者。过去我们花了一些时间尝试对 SciPy 的lfilter 进行 GPU 加速,但对于 ARMA 过滤器,lfilter 使用具有数据依赖性的 DF-II 形式,这使得并行化变得困难。有一些方法可以解决这个问题(例如,通过一次过滤的信号数量进行并行化),但我们最终称之为“阻塞”。

也就是说,我们确实通过 FFT 方法支持 FIR 滤波器。这与 fftconvolve 基本相同,但在我们的夜间 conda 版本中它被包装为 cusignal.firfilter(或者如果您使用 branch-0.16 从源代码构建)。

你可以这样做:

>>> from scipy import signal
>>> import cupy as cp
>>> import cusignal
>>> [b, a] = signal.butter(3, 0.5)
>>> b = cp.asarray(b)
>>> x = cp.random.randn(2**8)
>>> y = cusignal.firfilter(b, x)

请注意,我们目前不支持巴特沃斯滤波器设计,而是依赖 scipy 在将系数移动到 GPU 内存之前生成系数(使用 cupy.asarray)。

【讨论】:

  • 感谢您的回复,有什么更新吗?
猜你喜欢
  • 2018-03-28
  • 1970-01-01
  • 2011-05-08
  • 2014-07-29
  • 2014-02-09
  • 2011-05-29
  • 2019-04-29
  • 2015-05-09
  • 1970-01-01
相关资源
最近更新 更多