({{, (RefLink[ParallelSubmit, paclet:ref/ParallelSubmit])[expr] 
submits expr for evaluation on the next available parallel kernel and returns an (RefLink[EvaluationObject, paclet:ref/EvaluationObject]) expression representing the submitted evaluation.}, {, (RefLink[ParallelSubmit, paclet:ref/ParallelSubmit])[{(Subscript[var, 1]),(Subscript[var, 2]), …},expr]
builds a closure for the variables given before submitting expr.}})

OpenersNotesSection(Spacer1)Details and Options

(RefLink[ParallelSubmit, paclet:ref/ParallelSubmit])[{(Subscript[var, 1]),(Subscript[var, 2]), …},expr] substitutes the current values of the (Subscript[var, i]) into expr before submitting it for evaluation.

(RefLink[ParallelSubmit, paclet:ref/ParallelSubmit]) has attribute (RefLink[HoldAllComplete, paclet:ref/HoldAllComplete]).

OpenersPrimaryExamplesSection(Spacer1)Examples  (17)

OpenersExampleSection0(Spacer1)Basic Examples  (3)

ParallelSubmit[1+2]

WaitAll[%]

Schedule a range of evaluations concurrently:

Table[ParallelSubmit[{i},Total[FactorList[x^i+1][[2;;,2]]]],{i,15,20}]

Start the calculations and wait for all results:

WaitAll[%]

Functions used need to be distributed first:

fl[n_]:=Total[FactorList[x^n+1][[2;;,2]]]

DistributeDefinitions[fl]

WaitAll[Table[ParallelSubmit[{i},fl[i]],{i,21,30}]]

OpenersExampleSection1(Spacer1)Scope  (3)

Use (RefLink[Table, paclet:ref/Table]) to submit evaluations:

evs=Table[ParallelSubmit[{i},{i,PrimeQ[2^i-1]}],{i,2200,2222}];

WaitAll[evs]

Use a function to generate evaluations:

evs=Map[ParallelSubmit[PrimeQ[2^#-1]]&,Range[2200,2222]];

WaitAll[evs]

Schedule the same expression on each available kernel:

WaitAll[Table[ParallelSubmit[First[Timing[Inverse[RandomReal[{-1,1},{1000,1000}]]]]],{$KernelCount}]]

OpenersExampleSection3(Spacer1)Applications  (4)

Run a search for a random prime on each parallel kernel:

With[{base=10^1000,r=10^10},WaitAll[Table[ParallelSubmit[
While[!PrimeQ[p=RandomInteger[{base,base+r}]],Null];p],{$KernelCount}]]-base]

Watch the scheduling of the evaluations while they are running:

With[{base=10^1000,r=10^10},evs=Table[ParallelSubmit[
While[!PrimeQ[p=RandomInteger[{base,base+r}]],Null];p-base],{$KernelCount}];
PrintTemporary[evs];
WaitAll[evs]]

Stop all evaluations as soon as one result has been found using a shared variable:

With[{base=10^1000,r=10^10},
SetSharedVariable[stop];stop=False;
WaitAll[Table[ParallelSubmit[
While[!PrimeQ[p=RandomInteger[{base,base+r}]],If[stop,Return[$Failed]]];stop=True;Return[p-base]],{$KernelCount}]]]

Write a command that evaluates the arguments of a list in parallel:

SetAttributes[concurrentEvaluate,HoldAll]
concurrentEvaluate[l_List]:=WaitAll[ParallelSubmit/@Unevaluated[l]]

concurrentEvaluate[{$KernelID,PrimeQ[2^2203-1],$KernelID}]

Use (RefLink[ParallelCombine, paclet:ref/ParallelCombine]) for the same purpose:

ParallelCombine[Identity,Unevaluated[{$KernelID,PrimeQ[2^2203-1],$KernelID}],Method->"FinestGrained"]

Submit evaluations for searching adjacent ranges:

evs=Table[ParallelSubmit[{i},Count[2^Range[1000i,1000(i+1)-1]-1,_?PrimeQ]],{i,2,5}];
Total[WaitAll[evs]]

Use (RefLink[Parallelize, paclet:ref/Parallelize]) for the same purpose:

Parallelize[Count[2^Range[2000,5999]-1,_?PrimeQ]]

OpenersExampleSection4(Spacer1)Properties & Relations  (2)

The "FinestGrained" (RefLink[Method, paclet:ref/Method]) setting schedules each item as a single evaluation:

ParallelTable[Labeled[Framed[f[i]],$KernelID],{i,12},Method->"FinestGrained"]

Internally it works similarly to (RefLink[WaitAll, paclet:ref/WaitAll])[ParallelSubmit[…]]:

WaitAll[Table[ParallelSubmit[{i},Labeled[Framed[f[i]],$KernelID]],{i,12}]]

Scheduling larger evaluations first usually leads to better load balancing:

AbsoluteTiming[WaitAll[Table[ParallelSubmit[{t},Pause[t];t],{t,1,7}]]]

AbsoluteTiming[WaitAll[Table[ParallelSubmit[{t},Pause[t];t],{t,7,1,-1}]]]

OpenersExampleSection5(Spacer1)Possible Issues  (3)

(RefLink[ParallelSubmit, paclet:ref/ParallelSubmit]) does not evaluate its arguments on the master kernel:

WaitAll[Table[ParallelSubmit[2^i],{i,10}]]

Use a closure to insert the values of local variables into the expressions to be evaluated:

WaitAll[Table[ParallelSubmit[{i},2^i],{i,10}]]

Use (RefLink[With, paclet:ref/With]) to insert the values of local variables:

WaitAll[Table[With[{i=i},ParallelSubmit[2^i]],{i,10}]]

Side effects are local to each evaluation:

results={};
WaitAll[Table[ParallelSubmit[{p},If[PrimeQ[2^p-1],AppendTo[results,p]];],{p,2000,3000}]];
results

Use a shared variable to support global side effects:

SetSharedVariable[global]

global={};
WaitAll[Table[ParallelSubmit[{p},If[PrimeQ[2^p-1],Quiet[AppendTo[global,p]]];],{p,2000,3000}]];
global

There is a considerable overhead for scheduling trivial calculations:

AbsoluteTiming[WaitAll[Table[ParallelSubmit[{i},N[Sin[i]]],{i,1000}]];]

The overhead is smaller for generating fewer, but larger, evaluation units:

AbsoluteTiming[ParallelTable[N[Sin[i]],{i,1000},Method->"CoarsestGrained"];]

A sequential evaluation avoids all communication overhead:

AbsoluteTiming[Table[N[Sin[i]],{i,1000}];]

OpenersExampleSection6(Spacer1)Neat Examples  (2)

Parallelize a functional operation by functional composition with (RefLink[ParallelSubmit, paclet:ref/ParallelSubmit]):

Map[f,{a,b,c,d}]

WaitAll[Map[Composition[ParallelSubmit,f],{a,b,c,d}]]

Watch the scheduling of evaluations taking vastly varying amounts of time:

factors=Table[ParallelSubmit[{i},Plus@@FactorInteger[2^i-1][[All,2]]],{i,195,170,-1}];
PrintTemporary[factors];
WaitAll[factors]

({{DocumentationFooterIconsRelatedFunction.png, ({{See Also}, {(RefLink[WaitAll, paclet:ref/WaitAll])  ▪  (RefLink[WaitNext, paclet:ref/WaitNext])  ▪  (RefLink[DistributeDefinitions, paclet:ref/DistributeDefinitions])  ▪  (RefLink[EvaluationObject, paclet:ref/EvaluationObject])  ▪  (RefLink[AbortKernels, paclet:ref/AbortKernels])}})}})

({{DocumentationFooterIconsRelatedGuide.png, ({{Related Guides}, {▪(RefLinkPlain[Parallel Computing, paclet:guide/ParallelComputing])}, {▪(RefLinkPlain[Concurrency, paclet:guide/Concurrency])}})}})