How do I convert my nested for loop into a nested parfor loop?
Show older comments
I have a 36x34x8812 hourly current data called tpres3d. I used the matlab toolbox t_tide from Rich Pawlowicz toolbox to separate tidal currents. Since my data is a 3D array. I used a nested for loop that works but is taking too long to finish. I use the parallel computing toolbox and incorporate a parfor loop to speed up the process. My problem is I don't know how to properly write a parfor loop from a normal for loop. When I use this code:
tpres3d = tpres_U + tpres_V*sqrt(-1) %36x34x8812
[a,b,c] = size(tpres3d)
Ttides_hfdr = NaN*ones(a,b,c)
parfor i = 1:a
for j = 1:b
t0=squeeze(tpres3d(i,j,:));
I=find(~isnan(t0));
if ~isempty(I)
try
[~,~,~,tide_hfdr]=t_tide(t0, ...
'interval',1, ...
'start time',ttime(1), ...
'latitude',y, ...
'rayleigh',constituents, ...
'synthesis',0);
catch
end
end
end
Ttides_hfdr(i,j,:)=tide_hfdr
end
It gives a warning:
Warning: The temporary variable 'tide_hfdr' will be cleared at the beginning of each iteration of the
parfor-loop. If 'tide_hfdr' is used before it is set, a runtime error will occur. For more information,
see Parallel for Loops in MATLAB, "Uninitialized Temporaries".
and an error:
Error: When indexing the sliced variable 'Ttides_hfdr' with the nested for-loop variable 'j', the sliced
variable must be inside a for-loop that defines the range of the for-loop variable. For more information,
see Parallel for Loops in MATLAB, "Nested for-Loops with Sliced Variables".
Trust me, I read the guides and tried it out but I can't seem to grasp how to fix my code. Please help. Thank you.
Answers (1)
One way:
tpres3d = tpres_U + tpres_V*sqrt(-1); %36x34x8812
[a,b,c] = size(tpres3d);
T0=reshape(tpres3D,[],c).';
Ttides_hfdr = nan(size(T0));
ttime1=ttime(1);
parfor k=1:width(T0)
t0=T0(:,k);
if any(~isnan(t0))
try
[~,~,~,tide_hfdr]=t_tide(t0, ...
'interval',1, ...
'start time',ttime1, ...
'latitude',y, ...
'rayleigh',constituents, ...
'synthesis',0);
catch
end
end
Ttides_hfdr(:,k)=tide_hfdr;
end
Ttides_hfdr=reshape(Ttides_hfdr.',[a,b,c]);
11 Comments
Edcel
on 17 Dec 2024
Walter Roberson
on 17 Dec 2024
You do not set tide_hdfr in your catch block. If this were a serial loop then in this iteration if catch occurred then tide_hdfr would have been set by a previous iteration. But in parfor the previous iteration might or might not exist or might be for a completely unrelated iteration.
You need to set tide_hdfr in your catch block.
Edcel
on 17 Dec 2024
Matt J
on 17 Dec 2024
See if the t_tide() is ever getting executed, e.g., using,
tpres3d = tpres_U + tpres_V*sqrt(-1); %36x34x8812
[a,b,c] = size(tpres3d);
T0=reshape(tpres3d,[],c).';
Ttides_hfdr = nan(size(T0));
ttime1=ttime(1);
fails=0;
parfor k=1:width(T0)
t0=T0(:,k);
if any(~isnan(t0))
try
[~,~,~,tide_hfdr]=t_tide(t0, ...
'interval',1, ...
'start time',ttime1, ...
'latitude',y, ...
'rayleigh',constituents, ...
'synthesis',0);
Ttides_hfdr(:,k)=tide_hfdr;
catch
fails=fails+1;
end
else
fails=fails+1;
end
end
Ttides_hfdr=reshape(Ttides_hfdr.',[a,b,c]);
disp("Failures occurred "+fails/a/b*100+" percent")
Edcel
on 17 Dec 2024
Matt J
on 17 Dec 2024
If so, you shouldn't be getting Ttides_hfdr=nan all the time. That would seem to imply that t_tide() is always returning NaNs.
Edcel
on 18 Dec 2024
Just run your original loop until a combination of i,j giving a non-trivial tide_hfdr is found. Then it will be easier -- we just need to compare and troubleshoot the two versions for that particular (i,j),
for i = 1:a
for j = 1:b
t0=squeeze(tpres3d(i,j,:));
if ~all(isnan(t0))
try
[~,~,~,tide_hfdr]=t_tide(t0, ...
'interval',1, ...
'start time',ttime(1), ...
'latitude',y, ...
'rayleigh',constituents, ...
'synthesis',0);
if any(isfinite(tide_hfdr));
disp 'Located'
i,j
break;
end
catch
end
end
end
end
Edcel
on 18 Dec 2024
Categories
Find more on Loops and Conditional Statements in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!