# Side effects with ParallelDo

Hi guys I've the following problem with ParallelDo: if I run the code:

r1 = {};
r2 = {};

zmin = 6;
zmax = 9;
tpass = 1;
zpass = 0.001;

Do[

MLEdata = Table[MLE[z, t], {z, zmin, zmax, zpass}];
MaxPeak = Max[MLEdata];
PosPeak = Position[MLEdata, MaxPeak];
OverHalfPeak = Select[MLEdata, # > MaxPeak/2 &];
NumPoints = Length[OverHalfPeak];

AppendTo[r1, PosPeak];
AppendTo[r2, NumPoints], {t, tmin, tmax, tpass}]

zPeak = zmin - zpass + r1*zpass // Flatten; (*pos. in um*)

DeltaMLE = r2 - 1; (*FWHM in nm*)

dat = Flatten /@ Transpose[{zPeak, DeltaMLE}];
Export["axial track.txt", dat, "Table"];


I get the values in zPeak and DeltaMLE listed in the right order, but if I use ParallelDo like this to speed up the computation:

r1 = {};
r2 = {};
SetShareVariable[r1,r2]

zmin = 6;
zmax = 9;
tpass = 1;
zpass = 0.001;

ParallelDo[

MLEdata = Table[MLE[z, t], {z, zmin, zmax, zpass}];
MaxPeak = Max[MLEdata];
PosPeak = Position[MLEdata, MaxPeak];
OverHalfPeak = Select[MLEdata, # > MaxPeak/2 &];
NumPoints = Length[OverHalfPeak];

AppendTo[r1, PosPeak];
AppendTo[r2, NumPoints], {t, tmin, tmax, tpass}]

zPeak = zmin - zpass + r1*zpass // Flatten; (*pos. in um*)

DeltaMLE = r2 - 1; (*FWHM in nm*)

dat = Flatten /@ Transpose[{zPeak, DeltaMLE}];
Export["axial track.txt", dat, "Table"];


the order is completely wrong. I understand that there are some side effects, but I don't understand how to correct for them (I'm pretty new with the parallelization). Could you help me?

• Can you explain why you are not using Tableand avoiding side-effects (i.e. AppendTo) entirely? Commented Feb 18, 2016 at 12:50
• MLE, tmin and tmax are missing.
– Berg
Commented Feb 18, 2016 at 13:14

Looking at your code, I do not see any reason not to use Table instead of Do. Why aren't you using (Parallel)Table?

Disadvantages of Do/ParallelDo:

• Each call to AppendTo[array, something] will make a complete copy of array, thus it is slow.

• You must use SetSharedVariable to access main-kernel variables from parallel kernels. This kills performance, except when variable accesses are rare and the rest of the computation takes a long time.

• There's no guarantee about the order of evaluations with ParallelDo. That's why you get results out of order. Computations happen in parallel, and whichever finishes first will append to r1 first. If you really must use Do for this, then record t with the computed values as well and sort by t at the end.

All these problems would go away if you used Table.

• Hi Szabolcs and thanks for the quick answer. Basically, MLE(z,t) is a two variable function, which has peaks at different positions for different t. So I use the Do to select different instants t and extract every time the peak position and the fwhm of the peak. I thought the Do was the best way to repeat the process for all the different t. How could I do the same job with Table and so ParallelTable? Tmin and tmax are two variables, where tmin<tpass<tmax. Commented Feb 18, 2016 at 15:20
• @MicheleGuastamacchia I don't understand the question. As far as I can see you are doing r={}; Do[AppendTo[r,f[t]], {t, 100}] (simplified). That gives the same result as Table[f[t], {t,100}]. What am I missing? Commented Feb 18, 2016 at 15:36
• I see your point. Now I have a 2D nested list, how can I extract the positions of the maxima and the number of points >= than those maxima/2 (to get the fwhm's) from each sub list? Commented Feb 19, 2016 at 10:31
• @MicheleGuastamacchia Just change Do to Table and change AppendTo[r1, PosPeak]; AppendTo[r2, NumPoints] to {PosPeak,NumPoints}. Then use Part and All to extract what you need from the result. Commented Feb 19, 2016 at 10:39
• Great! Thanks a lot! Commented Feb 19, 2016 at 17:04