I am having issues using arrayfun in MATLAB using GPU processing. I have simplified my situation below.
I have 4 large matrices (video data as (x,y,t)). Ill use random for this example.
A = gpuArray(rand(10,10,100));
B = gpuArray(rand(10,10,100));
C = gpuArray(rand(10,10,100));
D = gpuArray(rand(10,10,100));
I wish to take each pixel of each matrix;(1,1,1) then (2,1,1) etc; and perform the least squares calculation (values are examples)
X = [10 10 ; 20 20 ; 30 30 ; 40 40]\[A;B;C;D];
Performing this as a for loop takes too long for my data. Since I want to perform a function on each element individually I thought using the GPU would be the way to go.
To do this I created the function
function [x] = GPUTestFun (A,B,C,D)
X = [10 10 ; 20 20 ; 30 30 ; 40 40]\[A;B;C;D];
end
Which I then call with arrayfun (I don't think matlab has GPU support for leastsquares?)
[x] = arrayfun(@GPUTestFun,[A;B;C;D]);
My understanding is that this should take each element of the 4 matricies individually and perform the calculations.
The error I get it: Error using gpuArray/arrayfun Array concatenation is not supported. error at line: 4.
Line 4 being :
X = [10 10 ; 20 20 ; 30 30 ; 40 40]\[A;B;C;D];
Its obvious that the issue is that I am concatenating the matrix within the arrayfun. I have thought about what my options are and cant seem to see a solution. I considered concatenating the matrices before I call the function, however array fun will try to perform the function on every element, which now wont line up. I considered maybe solving the least squares manually rather than using \, however am hesitant to attempt this without checking if I've missed an easier solution first.
I also realise the output X will probably need tweaking since the single calculation produces 2 outputs, so will probably need to separate these so my outputs are the same size as my inputs. This isn't the current issue however.
Any help will be greatly appreciated.
Thanks Jordan
EDIT: Working CPU code:
A = (rand(10,10,100));
B = (rand(10,10,100));
C = (rand(10,10,100));
D = (rand(10,10,100));
[X1,X2] = arrayfun(@GPUTestFun,A,B,C,D);
Function:
function [X1,X2] = GPUTestFun (A,B,C,D)
[X] = [10 11 ; 20 8 ; 30 30 ; 40 30]\[A;B;C;D];
X1 = X(1);
X2 = X(2);
end
Xdoesn't work even for CPU data...Ethat consists ofsize(E)=size([A;B;C;D])? Additionally, the ` \ ` operator does A LOT OF THINGS. Some of them iterative and not ready for GPU computing, so most likely you are not going to get any advantage (even if it is possible to make ` \ ` in the GPU, eich i am not sure)