# 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? – Szabolcs Feb 18 '16 at 12:50
• MLE, tmin and tmax are missing. – Berg Feb 18 '16 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. – MicheleG Feb 18 '16 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? – Szabolcs Feb 18 '16 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? – MicheleG Feb 19 '16 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. – Szabolcs Feb 19 '16 at 10:39
• Great! Thanks a lot! – MicheleG Feb 19 '16 at 17:04