#python #arrays #numpy #scipy #cupy
#python #массивы #numpy #scipy #cupy
Вопрос:
Я хочу отправить некоторые данные через встроенный фильтр нижних частот scipy. Я тестировал его с некоторыми массивами данных numpy, приведенными ниже. Он отлично работает и выводит отфильтрованные значения при использовании numpy. Затем я хотел посмотреть, смогу ли я использовать графический процессор и ускорить работу, и услышал о CuPy, который работает аналогично numpy. Однако, когда я заменяю массив 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, похоже, работает с задачами процессора, поэтому, возможно, он не может работать с массивами cupy графического процессора. Я не смог найти ни одной библиотеки, предоставляющей фильтр нижних частот или полосовой фильтр для массивов cupy.
Комментарии:
1. Вы не можете использовать массивы GPU с scipy.signal. Для обработки сигналов на основе GPU вам следует посмотреть на cuSignal или torch.audio (pytorch)
2. Я просмотрел cuSignal и просто для подтверждения, firwin() — это то, что может правильно выполнить фильтрацию? Не было ничего, что явно называлось фильтром нижних частот
Ответ №1:
Я создатель cuSignal. В прошлом мы потратили некоторое время на то, чтобы ускорить работу SciPy с помощью GPU lfilter
, но для фильтров ARMA lfilter использует форму DF-II, которая зависит от данных, что затрудняет распараллеливание. Есть способы обойти это (например, распараллеливание с помощью нескольких сигналов, отфильтрованных одновременно), но в итоге мы назвали это «заблокированным».
Тем не менее, у нас есть поддержка фильтра FIR с помощью метода FFT. По сути, это то же самое, что и fftconvolve
, но оно завернуто, как cusignal.firfilter
в нашем выпуске nightly conda (или если вы создаете из исходного кода с переходом 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
).
Комментарии:
1. Спасибо за ответ, есть какие-либо обновления по этому поводу?