# GPU looping through matrices

7 views (last 30 days)
Weixin Wang on 28 Aug 2020
Commented: Walter Roberson on 29 Aug 2020
Hello, I have a very basic question about GPU computing. Suppose I have a 3-by-3-by-1000 array, I want to loop through the third dimension and calculate every trace of the 3-by-3 matrices.
A = rand(3,3,1000);
trA = zeros(1000,1);
for n = 1:1000
trA(n) = trace(A(:,:,n));
end
Is there any way I can use GPU to do this? I know the "pagefun" can be used to loop through the third dimension, but the function it accepts is very limited, which does not include the trace function. Is it possible to even loop through the third dimension with a custom function from a matrix to a real number?

Walter Roberson on 28 Aug 2020
traceG = @(A) sum(pagefun(@triu, pagefun(@tril, A)),[1 2]);
Walter Roberson on 29 Aug 2020
The general solution is to loop using indexing.
However, indexing of GPU arrays is slow!! The instruction set does not have direct indexing in the sense of selecting only a single element and working on it: instead the set of instructions has to create a mask that each computation unit has that checks to see whether the address of its data is one of the ones that needs to be worked on, and if so then it does the operation, and if not then it sits idle until the next instruction. If you had (say) a 2^24 element array and wanted to select a single element from it, then the computation units for 2^24 minus 1 elements would say "Nope, that isn't me" and would idle and the one selected element would do the instruction.
Therefor it is significantly faster to vectorize, especially with longer vectors, doing work on as large a portion of the array as feasible. You can index: it just isn't efficient to do so. Smart methods like Edric's might at first look like they are doing a lot of extra work compared to what could be done on a classic system, but the work is being done in parallel over large portions of the array and that can be much faster than being selective on the data to work on.