how do I use filtfilt on a GPU?

9 views (last 30 days)
Susan Leemburg
Susan Leemburg on 20 Dec 2023
Commented: Guy Ye on 7 May 2024
Hello,
I am trying to get filtfilt to run on a GPU and I'm unable to get the formatting right (I think).
Eventually, I'd like to calculate phase-amplitude coupling over a wide range of frequencies with a zero-phase filter.This ends up taking a very long time and the slowest step so far seems to be the bandpass filtering of my signals, so I'd like to run those on my GPU instead of the CPU. I'm basing my filter design on eegfilt.m from the EEGLab toolbox.
I'm trying to get my code to run with a small EEG snippet first. I've replaced the real signal with random numbers for this question, but I can share some real signal later if that helps.
I have tried two different ways of calling filtfilt with arrayfun and am receiving two different error messages:
Attempt1: I tried to use arrayfun in the way I'd normally use it (on a non-gpuArray). This gives 'Use of functional workspace is not supported.'
In attempt 2: when I try to use arrayfun in a way that more closely resembles the GPU-related documentation, I get 'Indexing is not supported'.
Is it possible to use filtfilt with a GPU array at all? Can someone please tell me what stupid thing I'm doing wrong?
srate = 1000;
locutoff = 10;
hicutoff = 12;
testbit = rand(12*srate,1) %testbit = EEG(1:12*srate);
%filter settings
minfac = 3; % this many (lo)cutoff-freq cycles in filter
min_filtorder = 15; % minimum filter length
filtorder = minfac*fix(srate/hicutoff);
if filtorder < min_filtorder
filtorder = min_filtorder;
end
filtwts = fir1(filtorder, [locutoff, hicutoff]./(srate/2));
% without GPU
filtsig1 = filtfilt(filtwts,1,testbit');
%attempt 1 with GPU (does not work)
testbit = gpuArray(testbit');
filtsig2 = arrayfun(@(x) filtfilt(filtwts,1,x),testbit);
%attempt 2 with GPU (also does not work)
testbit = gpuArray(testbit');
filtsig2 = arrayfun(@filtfilt, filtwts,1,testbit);

Answers (1)

Infinite_king
Infinite_king on 8 Jan 2024
Edited: Infinite_king on 12 Apr 2024
Hi Susan Leemburg,
I understand that you are attempting to utilize the 'filtfilt' function and wish to perform the computation on the GPU.
The 'filtfilt' function fully supports GPU Arrays. Once the input is passed as a 'gpuArray,' the computations are automatically performed on the GPU, eliminating the need for the 'arrayfun' function
You can use the 'filtfilt' as follows to shift the computational load to GPU.
srate = 1000;
locutoff = 10;
hicutoff = 12;
testbit = rand(12*srate,1) %testbit = EEG(1:12*srate);
%filter settings
minfac = 3; % this many (lo)cutoff-freq cycles in filter
min_filtorder = 15; % minimum filter length
filtorder = minfac*fix(srate/hicutoff);
if filtorder < min_filtorder
filtorder = min_filtorder;
end
filtwts = fir1(filtorder, [locutoff, hicutoff]./(srate/2));
% without GPU
filtsig1 = filtfilt(filtwts,1,testbit');
% Transfer the data to GPU
gpu_testbit = gpuArray(testbit');
% Call the 'filtfilt', with the gpuArray as input
filtsig1 = filtfilt(filtwts,1,gpu_testbit);
% Now the computations are shifted to GPU.
For more information, refer the following MATLAB documentations,
Hope this is helpful.
  3 Comments
Infinite_king
Infinite_king on 12 Apr 2024
Can you share your modified code, so that i can reproduce the error ?
Guy Ye
Guy Ye on 7 May 2024
Strangely, I used the above code to compare the time taken by the filtfilt function in CPU mode and GPU mode, and the result showed that the time taken by the filtfilt function was the same, that is, there was no acceleration in GPU mode. Why is this phenomenon?

Sign in to comment.

Products


Release

R2019b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!