# Using counters within parallelize [closed]

I am running a lengthy do loop and I wish to use Parallelize so that multiple kernels are used. What I do in the loop is update a set of counters that report the final results. The counters do not work when using Parallelize. How can I fix this if possible. Here is some sample code

Ncases=0; NS5=0; NA5=0; NF20=0; ND5=0; NC5=0; Nreducible=0; Nirreducible=0;
Parallelize[Do[Ncases++; test=x^5+rx^3+sx^2+t(x+1);
If[IrreduciblePolynomialQ[test],Nirreducible++;group=QuinticGaloisGroup[test];
If[group==SymmetricGroup[5],NS5++]; If[group==AlternatingGroup[5],NA5++];
If[group==MetacyclicGroup[20],NF20++]; If[group==DihedralGroup[10],ND5++];
If[group==CyclicGroup[5],NC5++],Nreducible++],{r,-10,+10},{s,-10,+10},{t,-10,+10‌​}]];


Where IrreduciblePolynomialQ returns true if the polynomial is reducible. The function QuinticGaloisGroup determines the Galois group. So using a generic polynomial as the test polynomial I am counting the cases. The counters are not being incremented. I have many examples like this where the calculation times becomes hours and days.

## closed as off-topic by Feyre, corey979, happy fish, Öskå, SaschaDec 15 '16 at 8:56

This question appears to be off-topic. The users who voted to close gave this specific reason:

• "This question cannot be answered without additional information. Questions on problems in code must describe the specific problem and include valid code to reproduce it. Any data used for programming examples should be embedded in the question or code to generate the (fake) data must be included." – Feyre, corey979, happy fish, Öskå, Sascha
If this question can be reworded to fit the rules in the help center, please edit the question.

• Please give skeleton example code so we can help. – David G. Stork Nov 13 '15 at 23:43
• Ncases=0; NS5=0; NA5=0; NF20=0; ND5=0; NC5=0; Nreducible=0; Nirreducible=0; Parallelize[Do[Ncases++; test=x^5+rx^3+sx^2+t(x+1); If[IrreduciblePolynomialQ[test],Nirreducible++;group=QuinticGaloisGroup[test]; If[group==SymmetricGroup[5],NS5++]; If[group==AlternatingGroup[5],NA5++]; If[group==MetacyclicGroup[20],NF20++]; If[group==DihedralGroup[10],ND5++]; If[group==CyclicGroup[5],NC5++],Nreducible++],{r,-10,+10},{s,-10,+10},{t,-10,+10}]]; – Lorenz H Menke Nov 13 '15 at 23:46
• In the sample code IrreduciblePolynomialQ returns true if the polynomial is reducible and QuinticGaloisGroup return the quintic Galois group of the polynomial. Then I count the cases of the five possible groups. This is an example of generic polynomials. – Lorenz H Menke Nov 13 '15 at 23:48
• This example takes about 20 seconds to run. Set the do loop parameters to 100 or more then calculation times is hours and days. – Lorenz H Menke Nov 13 '15 at 23:49
• @LorenzHMenke Please update your question with your code, don't put it as a comment. – C. E. Nov 14 '15 at 0:00

Update: It might be more convenient to use Association instead of lists of rules, if you have V10.

Instead of trying to tally the result from within the kernels, return a data structure indicating what should be incremented. Then total the results after the parallel computations have been completed.

Since you did not supply complete code, I made up a simple QuinticGaloisGroup function for proof of concept.

Clear[NS5, NA5, NF20, ND5, NC5, Nreducible, Nirreducible];
groups = {NS5, NA5, NF20, ND5, NC5, Nreducible, Nirreducible};
QuinticGaloisGroup[t_] := {SymmetricGroup[5],
AlternatingGroup[5],
MetacyclicGroup[20],
DihedralGroup[10],
CyclicGroup[5]}[[Mod[Hash[{r, s, t}], 5, 1]]];
res = ParallelTable[
With[{test = x^5 + r x^3 + s x^2 + t (x + 1)},
If[IrreduciblePolynomialQ[test],
Association@                      (* remove this line, if version is below V10 *)
Join[{Nirreducible -> 1},
Switch[QuinticGaloisGroup[test],
SymmetricGroup[5], {NS5 -> 1},
AlternatingGroup[5], {NA5 -> 1},
MetacyclicGroup[20], {NF20 -> 1},
DihedralGroup[10], {ND5 -> 1},
CyclicGroup[5], {NC5 -> 1},
_, {}]
],
{Nreducible -> 1}]
],
{r, -10, 10}, {s, -10, 10}, {t, -10, 10}];


Then tally the results:

Merge[Flatten[res], Total]
(*
<|Nirreducible -> 7971, NC5 -> 1633, NS5 -> 1633, NF20 -> 1524,
ND5 -> 1593, NA5 -> 1588, Nreducible -> 1290|>
*)


If not using Association:

Thread[groups -> Total[groups /. Flatten[res, 2] /. Thread[groups -> 0]]]
(*
{NS5 -> 1633, NA5 -> 1588, NF20 -> 1524, ND5 -> 1593, NC5 -> 1633,
Nreducible -> 1290, Nirreducible -> 7971}
*)


Use SetSharedVariable[Ncases], but be aware that this is essentially a mutex that the master kernel must synchronize access to. This probably isn't a problem if the rest of the code in your loop is slow.

Edit A potential better solution is to do something like this after your ParallelDo has finished:

Total /@ Transpose@ParallelEvaluate[{Ncases, NS5, NA5, NF20, ND5, NC5, Nreducible, Nirreducible}]


... which will sum each kernel's local values for the iterators.

• The QuinticGaloisGroup function is slow. – Lorenz H Menke Nov 14 '15 at 1:41
• As long as Ncases isn't being read/written frequently, it's a safe approach. Try it! – ZachB Nov 14 '15 at 1:42
• I tried setting the SetSharedVariable[severl counters] and the results were slower by a factor of 10. Now the primary function QuinticGaloisGroup evaluates at hundreds to thousands of times per second depending on the test function being evaluated. Is this a potential cause of this longer total time taken? – Lorenz H Menke Nov 16 '15 at 21:52
• I'm not following -- QuinticGaloisGroup evaluates more times now than before, thus slowing down total time? See also a new idea in my edited answer. – ZachB Nov 16 '15 at 22:22