# How to run this custom-built function on GPU?

2 views (last 30 days)
O.Hubert on 26 Feb 2018
Edited: O.Hubert on 26 Feb 2018
I have a fairly simple code to run multiple times and I was wondering how to use GPU in Matlab for this.
Typically, what the code does is the following:
1. Draw a random matrix
2. Have some basic action with this random matrix and other inputs of the function. In this case, a simple matrix multiplication
3. Check the sign of some cells
4. Keep the draw if the draw respects signs set a priori; Draw again if not
5. Repeat this for 500 or 1000 times
Since each repetition is independent of the previous one, I can consider parallelizing.
My question is: *with custom-built functions, how can I use the GPU for 500 or 1000 parallel simulations? In particular, what is the syntax I have to respect for this aim?*
Notes: I have an NVIDIA GeForce GTX 1060 6GB (supported) and MATLAB R2016a with parallel computing toolbox.
I have put here a Minimum Working Example of what I want to do.
% Minimum Working Example MATLAB - GPU
A=[0.0027 -0.0001 0.0004 ; -0.0001 0.009 0.0004 ; - 0.00023 -0.0003 0.005]; % variance-covariance matrix
cholA=chol(A,'lower');
Nrep=zeros(3);
Nrep(1,1)=500; % number of repetition for the function ; Nrep is the same size as A because arrayfun only supports same-size matrices.
gpuArray(cholA); % could have created A as gpuArray directly, but this is an example
gpuArray(Nrep);
[output_fct_results,output_fct_draws]=arrayfun(@sign_test,cholA,Nrep,'UniformOutput',false) % launch the function onto the GPU.
Option 1:
function [output_fct_results,output_fct_draws]=sign_test(cholA,Nrep) % option 1
% This function tests whether the following signs are respected:
% test_mat(1,1)=+;test_mat(1,2)=+;
% test_mat(2,1)=+;test_mat(2,2)=-;
Nreptemp=Nrep(1,1); % Trick to pass inputs with different sizes
clear Nrep;
Nrep=Nreptemp;
% Initialize output matrices
output_fct_results=zeros(3,3,Nrep);
output_fct_draws=zeros(1,Nrep);
parfor repet=1:Nrep % range of the loop
fprintf('Repetition %d: \n',repet);
respect=0;
draws=0;
while respect<1 % run as long as the conditions are not respected
% Draw a normal random matrix
A=normrnd(0,1,3,3);
[Q R]=qr(A); % Compute qr decomposition of random matrix A
for ii=1:3;
if R(ii,ii)<0
Q(:,ii)=-Q(:,ii); % normalize the sign ; makes the QR decomposition unique (Arias et al 2014)
end
end
% Initialize the test matrix
test_mat=zeros(3);
% Compute the test matrix
for j=1:3
test_mat(:,j)=cholA*Q(:,j);
end
% Initialize the test for the signs of the test_matrix
test_sign=zeros(1,4);
% Test each relevant cell
if test_mat(1,1)>=0;
test_sign(1)=1;
end
if test_mat(1,2)>=0;
test_sign(2)=1;
end
if test_mat(2,1)>=0;
test_sign(3)=1;
end
if test_mat(2,2)<=0;
test_sign(4)=1;
end
if sum(test_sign==1)==size(test_mat,2) % If all signs are respected, then exit the loop
respect=1;
end
draws=draws+1;
end
output_fct_results(:,:,repet)=Q;
output_fct_draws(1,repet)=draws;
end
end
Option 2:
function [output_fct_results,output_fct_draws]=sign_test(cholA,Nrep) % option 2
% This function tests whether the following signs are respected:
% test_mat(1,1)=+;test_mat(1,2)=+;
% test_mat(2,1)=+;test_mat(2,2)=-;
Nreptemp=Nrep(1,1); % Trick to pass inputs with different sizes
clear Nrep;
Nrep=Nreptemp;
% Initialize output matrices
output_fct_results=zeros(3,3,Nrep);
output_fct_draws=zeros(1,Nrep);
draws=0;
accepted=0;
while accepted<=Nrep % range of the loop
% Draw a normal random matrix
A=normrnd(0,1,3,3);
[Q R]=qr(A); % Compute qr decomposition of random matrix A
for ii=1:3;
if R(ii,ii)<0
Q(:,ii)=-Q(:,ii); % normalize the sign ; makes the QR decomposition unique (Arias et al 2014)
end
end
% Initialize the test matrix
test_mat=zeros(3);
% Compute the test matrix
for j=1:3
test_mat(:,j)=cholA*Q(:,j);
end
% Initialize the test for the signs of the test_matrix
test_sign=zeros(1,4);
% Test each relevant cell
if test_mat(1,1)>=0;
test_sign(1)=1;
end
if test_mat(1,2)>=0;
test_sign(2)=1;
end
if test_mat(2,1)>=0;
test_sign(3)=1;
end
if test_mat(2,2)<=0;
test_sign(4)=1;
end
if sum(test_sign==1)==size(test_mat,2) % If all signs are respected, then move on to the next iteration
accepted=accepted+1;
output_fct_results(:,:,accepted)=Q;
end
draws=draws+1;
end
output_fct_draws(1,1)=draws;
end