How can I adapt arrayfun() to operate on vectors rather than scalars?

4 views (last 30 days)
I have a 45-variable function for which I'm trying to speed up computation of the finite-differencing based gradient, as function evaluation is expensive. I'm currently doing this with parfor on my 4-core CPU, but I'd still like things to be faster by using arrayfun() on my GPU (1050 Ti).
So I was thinking of creating a 45x45 matrix P where the ith column has the ith variable incremented by a small step size for finite differencing, and then calling
z = arrayfun(@objectiveFunction, P), and having arrayfun apply objectiveFunction to each column of P at a time.
However, arrayfun doesn't seem configured to do this, and I couldn't find another answer on the forums addressing whether its possible to reconfigure somehow.
Any thoughts?
Thanks.
  2 Comments
Rik
Rik on 2 Aug 2018
Usually it is easier to reshape the data to fit the needs of the function. You could also convert to a cell (with mat2cell) and use cellfun, or convert to a struct and use structfun (probably slower).
Anish Potnis
Anish Potnis on 2 Aug 2018
You're right -- I realized I can just pass the current variable values as a constant, and have the variable for parallelization to just be the index of the variable that we want to compute the partial derivative for. This works normally with arrayfun().
Thanks.

Sign in to comment.

Accepted Answer

Joss Knight
Joss Knight on 2 Aug 2018
Look at pagefun for mixing in calls to vector operations with your ordinary element-wise functions. Usually with the functions supported by pagefun, standard MATLAB functions on gpuArray data, and arrayfun, you can get the result you're after.
  2 Comments
Anish Potnis
Anish Potnis on 2 Aug 2018
Hey Joss.
I'm trying to parallelize the computation of column norms of a matrix.
1) pagefun doesn't support norm or vecnorm, so that seems out.
2) arrayfun(@(idx) norm(A(:,idx)), 1:n) will work, but there's a ton of data overhead in pushing the entire matrix to every parallel worker that makes this very slow.
3) I don't seem to be able to call vecnorm on the matrix directly, since its a gpuArray, and I want to have everything run on the GPU for speed.
I'm probably missing something obvious, but any advice would be appreciated.
Joss Knight
Joss Knight on 2 Aug 2018
Yeah, vecnorm isn't supported for gpuArray yet, but it's really simple piece of code:
norm_X = sqrt(sum(X.*X));

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!