1
votes

I am learning matlab GPU functions. My function myfun takes 2 input parameters delta, p. Eventually, I will apply myfun to many combinations of delta,p. For each combination of delta,p, 'myfun' will how many V's satisfies the condition delta*V-p>0, where V = [0:0.001:1]. Ideally, I want V to be a global variable. But it seems that matlab GPU has some restrictions on global variable. So I use another way to do this thing. The code is as the following:

 function result = gpueg2()
          dd = 0.1;
          DELTA = [dd:dd:1];
          dp = 0.001;
          P = [0:dp:1];
          [p,delta]=meshgrid(P,DELTA);
          p = gpuArray(p(:));
          delta = gpuArray(delta(:));


           V = [0:0.001:1];

           function [O] = myfun(delta,p)
                     O = sum((delta*V-p)>0);
           end
           result = arrayfun(@myfun,delta,p);
 end

However, it through an error message

Function passed as first input argument contains unsupported or unknown function 'sum'.

But I believe sum is applicable in GPU.

Any advice and suggestions are highly appreciated.

1
sum(A) and sum(A>10) have different under the hood implementations. The second, inserts a control flow if, which for a GPU matters a lot. GPUs are very hard to code and only certain functionalities can benefit from their architecture, so when Matlab says it supports sum for GPU arrays, I guess it supports sum(A), sum(A(10:30)) and stuff like that, where the input is an actual array.tryman

1 Answers

0
votes

The problem with sum is not with the GPU, it's with using arrayfun on a GPU. The list of functions that arrayfun on a GPU accepts is given here: https://www.mathworks.com/help/distcomp/run-element-wise-matlab-code-on-a-gpu.html. sum is not on the list on that page of documentation.

Your vectors are not so big (though I accept this may be a toy example of your real problem). I suggest the following alternative implementation:

function result = gpueg2()
dd = 0.1;
DELTA = dd:dd:1;
dp = 0.001;
P = 0:dp:1;
V = 0:0.001:1;
[p,delta,v] = meshgrid(P,DELTA,V);
p = gpuArray(p);
delta = gpuArray(delta);
v = gpuArray(v);
result = sum(delta.*v-p>0, 3);
end

Note the following differences:

  1. I make 3D arrays of p,delta,v, rather than 2D. These three are only 24MB in total.
  2. I do the calculation delta.*v-p>0 on the whole 3D array: this will be well split on the GPU.
  3. I do the sum on the 3rd index, i.e. over V.

I have checked that your routine on the CPU and mine on the GPU give the same results.