({{, (RefLink[ParallelCombine, paclet:ref/ParallelCombine])[f,h[(Subscript[e, 1]),(Subscript[e, 2]),…],comb] 
evaluates f[h[(Subscript[e, 1]),(Subscript[e, 2]),…]] in parallel by distributing parts of the computation to all parallel kernels and combining the partial results with comb.}, {, (RefLink[ParallelCombine, paclet:ref/ParallelCombine])[f,h[(Subscript[e, 1]),(Subscript[e, 2]), …]]
is equivalent to (RefLink[ParallelCombine, paclet:ref/ParallelCombine])[f,h[(Subscript[e, 1]),(Subscript[e, 2]),…],h] if h has attribute (RefLink[Flat, paclet:ref/Flat]), and (RefLink[ParallelCombine, paclet:ref/ParallelCombine])[f,h[(Subscript[e, 1]),(Subscript[e, 2]),…],(RefLink[Join, paclet:ref/Join])] otherwise.}})

OpenersNotesSection(Spacer1)Details and Options

(RefLink[ParallelCombine, paclet:ref/ParallelCombine])[f,h[(Subscript[e, 1]),…,(Subscript[e, n])],comb] forms expressions f[h[(Subscript[e, 1]),…,(Subscript[e, k])]], f[h[(Subscript[e, k+1]),…]], …, f[h[…,(Subscript[e, n])]], evaluates these on all available kernels, and combines the results (Subscript[r, i]) with comb[(Subscript[r, 1]),(Subscript[r, 2]),…].

The default combiner (RefLink[Join, paclet:ref/Join]) is appropriate for functions f such that the result of f[h[(Subscript[e, 1]),…,(Subscript[e, k])]] has head h. This includes all functions with attribute (RefLink[Listable, paclet:ref/Listable]).

For heads h with attribute (RefLink[Flat, paclet:ref/Flat]) the default combiner h effectively implements the associative law h[(Subscript[e, 1]),…,(Subscript[e, n])] = h[h[(Subscript[e, 1]),…,(Subscript[e, k])],h[(Subscript[e, k+1]),…],…,h[…,(Subscript[e, n])]].

With a compatible choice of comb, (RefLink[ParallelCombine, paclet:ref/ParallelCombine])[f,h[(Subscript[e, 1]),(Subscript[e, 2]),…],comb] is equivalent to f[h[(Subscript[e, 1]),(Subscript[e, 2]),…]].

If no kernels are available, (RefLink[ParallelCombine, paclet:ref/ParallelCombine]) evaluates f[h[(Subscript[e, 1]),(Subscript[e, 2]),…]] normally.

(RefLink[ParallelCombine, paclet:ref/ParallelCombine]) takes the same (RefLink[Method, paclet:ref/Method]) option as (RefLink[Parallelize, paclet:ref/Parallelize]).

(RefLink[ParallelCombine, paclet:ref/ParallelCombine]) takes the same (RefLink[DistributedContexts, paclet:ref/DistributedContexts]) option as (RefLink[Parallelize, paclet:ref/Parallelize]); the default value is (RefLink[DistributedContexts, paclet:ref/DistributedContexts]):>(RefLink[$DistributedContexts, paclet:ref/$DistributedContexts]).

OpenersPrimaryExamplesSection(Spacer1)Examples  (33)

OpenersExampleSection0(Spacer1)Basic Examples  (2)

Apply f in parallel to chunks of a list (with 4 parallel kernels available):

ParallelCombine[f[#]&,{1,2,3,4,5,6,7,8,9,10},comb]

Show where each computation takes place:

ParallelCombine[Composition[Labeled[#,$KernelID]&,Framed,f],{1,2,3,4,5,6,7,8,9,10},comb]

By default (RefLink[Join, paclet:ref/Join]) is used as a combiner function:

ParallelCombine[#^2&,{1,2,3,4,5,6,7,8,9,10,11}]

Do a parallel filtering operation:

ParallelCombine[Select[#,PrimeQ]&,{1,2,3,4,5,6,7,8,9,10,11}]

OpenersExampleSection1(Spacer1)Scope  (9)

OpenersExampleSubsection0(Spacer1)Listable Functions  (1)

All (RefLink[Listable, paclet:ref/Listable]) functions can be parallelized with (RefLink[ParallelCombine, paclet:ref/ParallelCombine]):

ParallelCombine[Sqrt,Range[10]]

ParallelCombine[Prime,Range[10]]

If the function is not (RefLink[Listable, paclet:ref/Listable]) use an explicit (RefLink[Map, paclet:ref/Map]):

ParallelCombine[Map[f,#]&,{a,b,c,d,e,f}]

OpenersExampleSubsection1(Spacer1)Structure-Preserving Functions  (3)

Many functional programming constructs can be parallelized with (RefLink[ParallelCombine, paclet:ref/ParallelCombine]):

ParallelCombine[Map[f,#]&,{a,b,c,d,e,f}]

ParallelCombine[Apply[f,#,1]&,{{a,b,c},{u,v,w}}]

The result need not have the same length as the input:

ParallelCombine[Cases[#,_?PrimeQ]&,Range[100]]

ParallelCombine[Select[#,PrimeQ]&,Range[100]]

Evaluate the elements of a list in parallel:

ParallelCombine[Identity,Unevaluated[{1+1,2+2,3+3}]]

OpenersExampleSubsection2(Spacer1)Reductions  (3)

The overall count of matching elements is equal to the sum of the partial counts:

ParallelCombine[Count[#,_?PrimeQ]&,Range[10000],Plus]

An element appears in a list if it appears in at least one of the pieces:

ParallelCombine[MemberQ[#,5]&,Range[20],Or]

An element does not appear on a list if it appears in none of the pieces:

ParallelCombine[FreeQ[#,5]&,Range[20], And]

OpenersExampleSubsection3(Spacer1)Associative Functions  (2)

Each subkernel performs a smaller number of additions and the combiner combines the results:

ParallelCombine[Identity,Unevaluated[a+b+c+d+e+f],comb]

ParallelCombine[Identity,Unevaluated[a+b+c+d+e+f],Plus]

Automatically pick the combiner for (RefLink[Flat, paclet:ref/Flat]) functions:

ParallelCombine[Identity,Unevaluated[a+b+c+d+e+f]]

Typical (RefLink[Flat, paclet:ref/Flat]) functions:

ParallelCombine[Identity,Unevaluated[1+2+3+4+5+6]]

ParallelCombine[Identity,Unevaluated[1*2*3*4*5*6]]

ParallelCombine[Identity,Unevaluated[Max[1,2,3,4,5,6]]]

ParallelCombine[Identity,Unevaluated[Min[1,2,3,4,5,6]]]

ParallelCombine[Identity,Unevaluated[GCD[1,2,3,4,5,6]]]

ParallelCombine[Identity,Unevaluated[LCM[1,2,3,4,5,6]]]

OpenersExampleSection2(Spacer1)Generalizations & Extensions  (1)

Listable functions of several arguments:

ParallelCombine[f@@@#&,Transpose[{{a,b,c},{u,v,w},{x,y,z}}]]

OpenersExampleSection3(Spacer1)Options  (11)

OpenersExampleSubsection4(Spacer1)Method  (6)

Break the computation into the smallest possible subunits:

ParallelCombine[Labeled[Framed[#],$KernelID]&,Range[10],List,Method->"FinestGrained"]

Break the computation into as many pieces as there are available kernels:

ParallelCombine[Labeled[Framed[#],$KernelID]&,Range[10],List,Method->"CoarsestGrained"]

Break the computation into at most 2 evaluations per kernel for the entire job:

GatherBy[ParallelCombine[{$KernelID,#}&,Range[18],List,Method->"EvaluationsPerKernel"->2],First]

Break the computation into evaluations of at most 5 elements each:

ParallelCombine[{$KernelID,Length[#]}&,Range[18],List,Method->"ItemsPerEvaluation"->5]

The default option setting balances evaluation size and number of evaluations:

ParallelCombine[{$KernelID,Length[#]}&,Range[40],List,Method->Automatic]

Visualize the number of evaluations per kernel and items per evaluation:

Manipulate[batches=ParallelCombine[{$KernelID,Length[#]}&,Range[items],List,Method->method];
BarChart[Map[Labeled[#,#,Center]&,Last/@Sort[{#[[1,1]],Last/@#}&/@GatherBy[batches,First]],{2}],ChartLayout->"Stacked"],
{method,{"FinestGrained","CoarsestGrained",Automatic}},
{items,1,100,1},SaveDefinitions->True]

OpenersExampleSubsection5(Spacer1)DistributedContexts  (5)

By default, definitions in the current context are distributed automatically:

remote[x_]:={$KernelID,Length[x]}

ParallelCombine[remote,Range[39],List]

Do not distribute any definitions of functions:

local[x_]:={$KernelID,Length[x]}

ParallelCombine[local,Range[38],List,DistributedContexts->None]

Distribute definitions for all symbols in all contexts appearing in a parallel computation:

a`f[x_]:={$KernelID,Length[x]}

ParallelCombine[a`f,Range[37],List,DistributedContexts->Automatic]

Distribute only definitions in the given contexts:

b`f[x_]:={$KernelID,Length[x]}

ParallelCombine[b`f,Range[36],List,DistributedContexts->{"a`"}]

Restore the value of the (RefLink[DistributedContexts, paclet:ref/DistributedContexts]) option to its default:

SetOptions[ParallelCombine,DistributedContexts:>$DistributedContexts]

OpenersExampleSection4(Spacer1)Applications  (3)

Reduce an associative expression in parallel:

ParallelCombine[Identity,Unevaluated[1+2+3+4+5+6+7+8]]

Find out how a computation is distributed among all kernels:

ParallelCombine[{$KernelID,Length[#]}&,Range[20],List]

A parallel version of (RefLink[MapThread, paclet:ref/MapThread]):

parallelMapThread[f_,args_List]:=ParallelCombine[f@@@#&,Transpose[args]]

parallelMapThread[f,{{a,b,c},{u,v,w},{x,y,z}}]

OpenersExampleSection5(Spacer1)Properties & Relations  (5)

An implementation of (RefLink[ParallelMap, paclet:ref/ParallelMap]):

ParallelCombine[Map[f,#]&,{a,b,c,d,e}]

For listable functions (RefLink[ParallelCombine, paclet:ref/ParallelCombine]) and (RefLink[ParallelMap, paclet:ref/ParallelMap]) are equivalent:

ParallelCombine[Sin,Range[0.0,1,0.1]]

ParallelMap[Sin,Range[0.0,1,0.1]]

(RefLink[Parallelize, paclet:ref/Parallelize]) is often implemented in terms of (RefLink[ParallelCombine, paclet:ref/ParallelCombine]):

Parallelize[Count[Range[20],_?PrimeQ]]

ParallelCombine[Count[#,_?PrimeQ]&,Range[20],Plus]

Parallelize[Select[Range[100],PrimeQ]]

ParallelCombine[Select[#,PrimeQ]&,Range[100]]

Parallel versions of many data-parallel commands can easily be written with (RefLink[ParallelCombine, paclet:ref/ParallelCombine]):

parallelCount[range_,patt_]:=ParallelCombine[Count[#,patt]&,range,Plus]

parallelCount[Range[10000],_?PrimeQ]

Functions defined interactively are automatically distributed to all kernels when needed:

ftest[n_]:=Labeled[Framed[PrimeQ[2^n-1]],$KernelID]

ParallelCombine[ftest/@#&,Range[1275,1285]]

Distribute definitions manually and disable automatic distribution:

gtest[n_]:=Labeled[Framed[PrimeQ[2^n-1]],$KernelID]

DistributeDefinitions[gtest];

The function is now evaluated on the parallel kernels:

ParallelCombine[gtest/@#&,Range[1275,1285],DistributedContexts->None]

OpenersExampleSection6(Spacer1)Possible Issues  (2)

The combiner must be compatible with the type of the partial results:

ParallelCombine[Count[#,_?PrimeQ]&,Range[100],Plus]

The default combiner is (RefLink[Join, paclet:ref/Join]), which is appropriate for list-like results:

ParallelCombine[Cases[#,_?PrimeQ]&,Range[100]]

Functions may simplify short argument lists, but not longer ones:

{Xnor[a],Xnor[b,c],Xnor[d,e,f]}

Such simplification of partial expressions may make parallel evaluation impossible:

ParallelCombine[Map[fun,#]&,Xnor[a,b,c,d,e,f],Join]

Prevent simplification of partial expressions and apply the desired function only at the end:

Xnor@@ParallelCombine[Map[fun,#]&,{a,b,c,d,e,f},Join]

({{DocumentationFooterIconsRelatedFunction.png, ({{See Also}, {(RefLink[ParallelMap, paclet:ref/ParallelMap])  ▪  (RefLink[Parallelize, paclet:ref/Parallelize])  ▪  (RefLink[ParallelSum, paclet:ref/ParallelSum])  ▪  (RefLink[ParallelProduct, paclet:ref/ParallelProduct])  ▪  (RefLink[Fold, paclet:ref/Fold])  ▪  (RefLink[GroupBy, paclet:ref/GroupBy])}})}})

({{DocumentationFooterIconsRelatedGuide.png, ({{Related Guides}, {▪(RefLinkPlain[Data Parallelism, paclet:guide/DataParallelism])}, {▪(RefLinkPlain[Parallel Computing, paclet:guide/ParallelComputing])}, {▪(RefLinkPlain[Managing Remote and Parallel Kernels, paclet:guide/ManagingRemoteAndParallelKernels])}})}})