matlabparallel-processingparforspmd

Using spmd or parfor in Matlab


I am currently trying to run experiments in parallel using MATLAB 2011b that are very time-consuming. I am wondering if someone could help me 'translate' the following block of generic (non-working) parfor code into something that will work in the spmd code.

amountOfOptions = 8;
startStockPrice = 60 + 40 * rand(1,amountOfOptions);        
strike = 70 + 20 * rand(1,amountOfOptions);                 
v = 0.35 + 0.3 * rand(1,amountOfOptions);                   
IV = 0.25 + 0.1 * rand(1,amountOfOptions);                  
sigma = 0.15 + 0.65 * rand(1,amountOfOptions);              
riskFreeRate = 0.05 + 0.1 * rand(1,amountOfOptions);        
tn = fix(1 + 3 * rand(1,amountOfOptions)); 
tic;
for g=1:amountOfOptions
        for i=1:10                          
        N = i*5;              
        Cti = zeros(1,N);                       
        Sti = zeros(1,N);                       
        B = zeros(1,N);                         
        d1_ti = zeros(1,N);    
        delta_t = zeros(1,N);
        ctn = 0;
        cmtn = 0;
        result = 0;
        t = (1:N)/N;        
        dt = 1/N;                         
        c_mt0 = 0;                                      
      for j=1:10
            B = sigma(g)*randn(1,N);      
                 part1 = startStockPrice(g)*normcdf((log(startStockPrice(g)/strike(g))+(riskFreeRate(g)+(0.5*(IV(g))^2))*(tn))/(v(g)*sqrt(tn)),0,sigma(g));
                 part2 = exp(-riskFreeRate(g)*tn)*strike(g)*normcdf((log(startStockPrice(g)/strike(g))+(riskFreeRate(g)-(0.5*(IV(g))^2))*(tn))/(IV(g)*sqrt(tn)));
            c_mt0 = part1 - part2;          
            Sti(1) = startStockPrice(g);       
                for j = 2:N-1
                   Sti(j)=Sti(j-1)*exp( (riskFreeRate(g)-dt*0.5*sigma(g)^2) * t(j)*dt + sigma(g)*B(j));
                end                                                               
            Sti(N) = Sti(N-1)*exp( (riskFreeRate(g)-dt*0.5*sigma(g)^2) * t(N)*dt + sigma(g)*B(N));

                    parfor i = 1:N-1
                         d1ti(i) = (log(Sti(i)/strike(g)) +  (riskFreeRate(g) + v(g).^2/2) * (tn - t(i))) / (v(g) * sqrt(tn - t(i)));
                    end 
                    parfor i = 1:N-1 
                        Cti(i) = Sti(i).*normcdf((d1ti(i)),0,sigma(g)) - exp(-riskFreeRate(g).*(tn(g) - t(i))).*strike(g).*normcdf(((d1ti(i) - v(g)*sqrt(tn(g) - t(i)))) , 0 ,sigma(g));  
                    end
                        if((Sti(N) - strike(g)) > 0) 
                            ctn = Sti(N) - strike(g);
                        else
                            ctn = 0;
                        end
                    parfor i = 1:N-1
                         delta_t(i) = normcdf((d1ti(i)),0,sigma(g)); 
                    end
           cmtn = ctn - c_mt0*exp(riskFreeRate(g)*tn(g));                                                  
           result= cmtn + result;
        end
        result= result/10;                                                               
      end
end
time = toc; 

Solution

  • I've always used parfor over spmd because it's more logical for me. Since parfor requires that each iteration within the loop be independent of all other iterations. It's as easy as encapsulating it using the following method.

    % Initial Variables
    amountOfOptions = 8;
    startStockPrice = 60 + 40 * rand(1,amountOfOptions);        
    strike = 70 + 20 * rand(1,amountOfOptions);                 
    v = 0.35 + 0.3 * rand(1,amountOfOptions);                   
    IV = 0.25 + 0.1 * rand(1,amountOfOptions);                  
    sigma = 0.15 + 0.65 * rand(1,amountOfOptions);              
    riskFreeRate = 0.05 + 0.1 * rand(1,amountOfOptions);        
    tn = fix(1 + 3 * rand(1,amountOfOptions)); 
    
    % Open Parpool
    try
        parpool;
    catch
    end
    
    % Use parfor
    parfor i = 1:amountOfOptions
        [startStockPrice(i),strike(i),v(i),IV(i),sigma(i),riskFreeRate(i),tn(i)] = fun( startStockPrice(i),strike(i),v(i),IV(i),sigma(i),riskFreeRate(i),tn(i) );
    end
    

    Then you can create the encapsulating function fun that will accept all the parameters and process/reoutput them. It will have the following definition/header:

    function [startStockPrice,strike,v,IV,sigma,riskFreeRate,tn] = fun( startStockPrice,strike,v,IV,sigma,riskFreeRate,tn );