# ParallelTable vs. Table: Parallel gives NMinimize:nnum error

I have run into an issue where I am getting nnum errors when I use ParallelTable, which I do not get when I use Table (and even though I have distributed the definitions to the kernels).

EDIT: As requested, here is a "more minimal" example:

Module1[n_] := Module[{y, x, s},
s = NDSolve[{y'[x] == y[x] Cos[n*x + y[x]], y == 1}, y, {x, 0, 30}];
With[{X = (y /. s[])[x] /. x -> #}, X &]
]

Module2[n_, x_] := Module[{Mys},
Mys[X_] = Module1[n][X];
First@NMaximize[{Mys[X], 0 < X < x}, X]
]


The following code runs fine:

test1 = Table[Module2[i, 20], {i, 1, 5}]


But this does not:

DistributeDefinitions["Global"];
test2 = ParallelTable[Module2[i, 20], {i, 1, 5}]


The necessary ingredients to reproduce the problem seem to be:

1) A module which uses NDSolve and returns a pure function

2) A second module which uses NMinimize or NMaximize on that function.

In this toy example, there's no reason to introduce two modules (as compared to doing everything in one module); however, in my actual project this is not desirable.

ORIGINAL EXAMPLE: The problem makes use of the following modules:

mpl = 1/Sqrt[6.70837*10^-39]
gsT = 106.75

aANDρr[ΛI_, ΓI_, tf_] := Module[{s},
s = NDSolve[{as'[t] == as[t]*Sqrt[(8 π)/(3 mpl^2)(ρrs[t] + ΛI^4/as[t]^3 Exp[-ΓI t])],
ρrs'[t] + 4*Sqrt[(8 π)/(3 mpl^2) (ρrs[t] + ΛI^4/as[t]^3 Exp[-ΓI t])] ρrs[t] == ΓI ΛI^4/as[t]^3 Exp[-ΓI t],
as == 1, ρrs == 0}, {as, ρrs}, {t, 0, tf}];
Return[{With[{x = (as /. s[])[t] /. t -> #1}, x &],
With[{x = (ρrs /. s[])[t] /. t -> #1}, x &]}];
];

UniverseEvolve[ΛI_, ΓI_, tfmini_: 0] := Module[{tfmin, HI, ti, tR, tf, s,(*ρI,*)H, Trad, T, TR, Tmax, aANDρrRESULTS, a, ρr},
tfmin = tfmini;
HI = Sqrt[(8 π*ΛI^4)/(3 mpl^2)];
ti = 2/3 Sqrt[3/(8 π)] mpl/ΛI^2;
tR = 1/ΓI;
tf = Max[100 tR, 100 ti, tfmin];

aANDρrRESULTS = aANDρr[ΛI, ΓI, tf];
a[t_] = aANDρrRESULTS[][t];
ρr[t_] = aANDρrRESULTS[][t];
H[t_] = a'[t]/a[t];
Trad[ρ_] = (30/(π^2 gsT) ρ)^(1/4);
T[t_] = Trad[ρr[t]];
TR = Trad[ρr[tR]] ;
Tmax = NMaximize[{T[t], 0.1 ti < t < 10 ti}, t][];

Return[{HI,
With[{x = H[t] /. t -> #1}, x &],
With[{x = T[t] /. t -> #1}, x &],
Tmax,
TR,
ti,
tf}];
]


The following runs without any errors:

Table[UniverseEvolve[10^15, 10^i], {i, 6, 10}];


However, the following does not:

DistributeDefinitions["Global"];
ParallelTable[UniverseEvolve[10^15, 10^i], {i, 6, 10}];


In particular, each kernel generates a large number of NMaximize::nnum errors, and I cannot figure out why. (Note that the notebook's context is indeed global.) Any insight would be appreciated.

• Happens in Kubuntu 16.04 with Mma 11 too. – bobbym Sep 3 '16 at 4:22
• Can you produce a minimal example please? See sscce.org for guidance. – Szabolcs Sep 5 '16 at 8:54
• @Szabolcs, while the original code is well beneath the 100 lines suggested on that page, I've written an even more minimal example for you. – Lauren Pearce Sep 6 '16 at 13:36
• @LaurenPearce It's not about me personally. The new example considerably increases the chance that someone will take the time to look at the problem and maybe find a solution. I reduced it a bit more. +1. – Szabolcs Sep 6 '16 at 13:39

## 2 Answers

The issue is due to that you assigned the slot # outside the Function ()&. You can avoid these issues by putting the slot # inside the Function[] as

Module1[n_] := Module[{y, x, s},
s = NDSolve[{y'[x] == y[x] Cos[n*x + y[x]], y == 1}, y, {x, 0, 30}];
Function[Evaluate[(y /. s[])[#]]]
]


If you just want to return the interpolating function, you can also simply write

Module1[n_] := Module[{y, x, s},
s = NDSolve[{y'[x] == y[x] Cos[n*x + y[x]], y == 1}, y, {x, 0, 30}][];
y /. s
]


to avoid any confusion about #.

Both methods will run fine in the ParallelTable[].

DistributeDefinitions["Global"];
test2 = ParallelTable[Module2[i, 20], {i, 1, 5}]
(* returns {1.12259, 1.0692, 1.04819, 1.03696, 1.02997} *)


For the longer example, you can do it by

aANDρr[ΛI_,ΓI_,tf_]:= Module[{s},
s = NDSolve[{
as'[t] == as[t]*Sqrt[(8 π)/(3 mpl^2)(ρrs[t] + ΛI^4/as[t]^3 Exp[-ΓI t])],
ρrs'[t] + 4*Sqrt[(8 π)/(3 mpl^2) (ρrs[t] + ΛI^4/as[t]^3 Exp[-ΓI t])]
ρrs[t] == ΓI ΛI^4/as[t]^3 Exp[-ΓI t],
as == 1, ρrs == 0}, {as, ρrs}, {t, 0, tf}][];
{as/.s, ρrs/.s}
]


and

UniverseEvolve[ΛI_, ΓI_, tfmini_: 0] :=
Module[{tfmin, HI, ti, tR, tf, s,(*ρI,*)H, Trad, T, TR, Tmax, aANDρrRESULTS, a, ρr},
tfmin = tfmini;
HI = Sqrt[(8 π*ΛI^4)/(3 mpl^2)];
ti = 2/3 Sqrt[3/(8 π)] mpl/ΛI^2;
tR = 1/ΓI;
tf = Max[100 tR, 100 ti, tfmin];

aANDρrRESULTS = aANDρr[ΛI, ΓI, tf];
a[t_] = aANDρrRESULTS[][t];
ρr[t_] = aANDρrRESULTS[][t];
H[t_] = a'[t]/a[t];
Trad[ρ_] = (30/(π^2 gsT) ρ)^(1/4);
T[t_] = Trad[ρr[t]];
TR = Trad[ρr[tR]];
Tmax = NMaximize[{T[t], 0.1 ti < t < 10 ti}, t][];
{HI, Function[Evaluate[H[#]]], Function[Evaluate[T[#]]], Tmax, TR, ti, tf}
]

• This works- thank you – Lauren Pearce Sep 7 '16 at 15:44

This is not an answer, just an extended comment. A smaller example demonstrating a closely related (though not entirely identical) problem is the following:

In:= fun[] := f[x] & /. x -> #

In:= fun[][z]
Out= f[z]

In:= ParallelEvaluate[fun[][z], 1]
Out= f["KernelObject"[1, "local"]]


Out should be identical to Out, but it isn't.

Hope fully this will help in debugging the issue.

A TracePrint reveals than when this expression is evaluated on a subkernel, the slot (#) is somehow replaced by this: Compare TracePrint[fun[][x]] with ParallelEvaluate[TracePrint[fun[][x]], 1].

A more trivial example is

slot[] := #
ParallelEvaluate[slot[], 1]

(* "KernelObject"[1, "local"] *)


or the TracePrint equivalent.

The root cause of all of this is very likely that the free #` (i.e. slot not bound to a pure function) gets at some point injected into the expression of some pure function, which then replaces it with an argument. I seem to remember some StackExchange posts dealing with similar problems, and will try to search for them.