I have the exact same code written in Fortran and Matlab. The code runs serially in both languages fine, but is substantially faster in Fortran.
One of the loops of the code can be parallelized. In Matlab I achieve this very easily by just replacing a for with parfor.
Is there any such easy to it in Fortran? I am using Intel Fortran to compile the code.
Here is a very simple example of what I am doing:
Matlab code:
clear;
tic
gamma=5;
beta=0.95;
T=5;
r=0.015;
maxw = 50;
minw = 1;
nw = 50;
nc = 50;
gw = linspace(minw,maxw,nw)';
gc = linspace(0.0,maxw,nc)';
c = zeros(nw,T);
v = zeros(nw,T);
c(:,T)=gw(:,1);
v(:,T) = (c(:,T).^(1-gamma))/(1-gamma);
for i=T-1:-1:1,
i
aux = v(:,i+1);
parfor z=1:nw,
auxV=zeros(nc,1);
for j=1:nc,
sav = gw(z,1)-gc(j,1);
w_t1 = (1+r)*sav;
w_t1 = max(min(w_t1,maxw),minw);
auxV(j,1)=(gc(j,1)^(1-gamma))/(1-gamma)+beta*interpn(gw,aux,w_t1);
end
[v(z,i) imax]= max(auxV);
c(z,i)=gc(imax,1);
end
end
toc
With that parfor on the syntax computational time reduces significantly.
And equivalent fortran code is:
PROGRAM toy
IMPLICIT NONE
REAL :: gamma=5;
REAL :: beta=0.95;
INTEGER :: T=5;
REAL :: r=0.015;
REAL :: maxw = 50;
REAL :: minw = 1;
INTEGER :: nw = 50;
REAL, DIMENSION(1,50) :: gw, gc, aux3
REAL, DIMENSION(50,1) :: secd
INTEGER :: ind1, ind2, ind3
INTEGER :: nc = 50;
REAL, DIMENSION(50,5) :: c, v
REAL, DIMENSION(50,1) :: aux, auxV
REAL :: sav, w_t1
INTEGER, DIMENSION(1,1) :: pt
REAL :: aux1
c = 0;
v = 0;
DO ind1=1,nw
gw(1,ind1)=1.0+(ind1-1.0)*1.0
END DO
DO ind1=1,nc
gc(1,ind1)=0.0+(ind1-1.0)*1.0
END DO
aux3(1,:) = gw(1,:)
c(:,T)=gw(1,:);
v(:,T) = (c(:,T)**(1-gamma))/(1-gamma);
do ind1=T-1,1,-1
secd(:,1) = 0.0
call spline(aux3,v(:,ind1+1),nw,gamma,secd(:,1))
aux(:,1) = v(:,ind1+1)
do ind3=1,nw
auxV=0;
do ind2=1,nc
sav = gw(1,ind3)-gc(1,ind2);
w_t1 = (1+r)*sav;
w_t1 = max(min(w_t1,maxw),minw)
call splint(aux3,v(:,ind1+1),secd(:,1),nw,w_t1,1,1,aux1)
auxV(ind2,1)=(gc(1,ind2)**(1-gamma))/(1-gamma)+beta*aux1
end do
v(ind3,ind1) = maxval(auxV)
pt(1,1) = sum(maxloc(auxV))
c(ind3,ind1)=gc(1,pt(1,1))
end do
end do
end program
Is there any simple way to parallelize that second nested loop just like the matlab?