---
title: "ParallelTable"
language: "en"
type: "Symbol"
summary: "ParallelTable[expr, {imax}] generates in parallel a list of imax copies of expr. ParallelTable[expr, {i, imax}] generates in parallel a list of the values of expr when i runs from 1 to imax. ParallelTable[expr, {i, imin, imax}] starts with i = imin. ParallelTable[expr, {i, imin, imax, di}] uses steps di. ParallelTable[expr, {i, {i1, i2, ...}}] uses the successive values i1, i2, .... ParallelTable[expr, {i, imin, imax}, {j, jmin, jmax}, ...] gives a nested list. The list associated with i is outermost."
keywords: 
- parallel table
canonical_url: "https://reference.wolfram.com/language/ref/ParallelTable.html"
source: "Wolfram Language Documentation"
related_guides: 
  - 
    title: "Data Parallelism"
    link: "https://reference.wolfram.com/language/guide/DataParallelism.en.md"
  - 
    title: "Parallel Computing"
    link: "https://reference.wolfram.com/language/guide/ParallelComputing.en.md"
  - 
    title: "Raspberry Pi"
    link: "https://reference.wolfram.com/language/guide/RaspberryPi.en.md"
  - 
    title: "Managing Remote and Parallel Kernels"
    link: "https://reference.wolfram.com/language/guide/ManagingRemoteAndParallelKernels.en.md"
related_functions: 
  - 
    title: "Table"
    link: "https://reference.wolfram.com/language/ref/Table.en.md"
  - 
    title: "Parallelize"
    link: "https://reference.wolfram.com/language/ref/Parallelize.en.md"
  - 
    title: "ParallelArray"
    link: "https://reference.wolfram.com/language/ref/ParallelArray.en.md"
  - 
    title: "ParallelTry"
    link: "https://reference.wolfram.com/language/ref/ParallelTry.en.md"
  - 
    title: "ParallelDo"
    link: "https://reference.wolfram.com/language/ref/ParallelDo.en.md"
  - 
    title: "ParallelSum"
    link: "https://reference.wolfram.com/language/ref/ParallelSum.en.md"
---
# ParallelTable
⚠ *Unsupported in Public Cloud*

ParallelTable[expr, {imax}] generates in parallel a list of imax copies of expr.

ParallelTable[expr, {i, imax}] generates in parallel a list of the values of expr when i runs from 1 to imax. 

ParallelTable[expr, {i, imin, imax}] starts with i = imin. 

ParallelTable[expr, {i, imin, imax, di}] uses steps di. 

ParallelTable[expr, {i, {i1, i2, …}}] uses the successive values i1, i2, ….

ParallelTable[expr, {i, imin, imax}, {j, jmin, jmax}, …] gives a nested list. The list associated with i is outermost.

## Details and Options

* ``ParallelTable`` is a parallel version of ``Table`` that automatically distributes different evaluations of ``expr`` among different kernels and processors.

* ``ParallelTable`` will give the same results as ``Table``, except for side effects during the computation.

* ``Parallelize[Table[expr, iter, …]]`` is equivalent to ``ParallelTable[expr, iter, …]``.

* If an instance of ``ParallelTable`` cannot be parallelized, it is evaluated using ``Table``.

* The following options can be given:

|                      |                       |                                                              |
| -------------------- | --------------------- | ------------------------------------------------------------ |
| Method               | Automatic             | granularity of parallelization                               |
| DistributedContexts  | \$DistributedContexts | contexts used to distribute symbols to parallel computations |
| ProgressReporting    | \$ProgressReporting   | whether to report the progress of the computation            |

* The ``Method`` option specifies the parallelization method to use. Possible settings include:

|                             |                                                                           |
| --------------------------- | ------------------------------------------------------------------------- |
| "CoarsestGrained"           | break the computation into as many pieces as there are available kernels  |
| "FinestGrained"             | break the computation into the smallest possible subunits                 |
| "EvaluationsPerKernel" -> e | break the computation into at most e pieces per kernel                    |
| "ItemsPerEvaluation" -> m   | break the computation into evaluations of at most m subunits each         |
| Automatic                   | compromise between overhead and load balancing                            |

* ``Method -> "CoarsestGrained"`` is suitable for computations involving many subunits, all of which take the same amount of time. It minimizes overhead, but does not provide any load balancing.

* ``Method -> "FinestGrained"`` is suitable for computations involving few subunits whose evaluations take different amounts of time. It leads to higher overhead, but maximizes load balancing.

* By default, a nested table with a large outermost level is parallelized at the outermost level, otherwise, at the innermost level. With ``Method -> "CoarsestGrained"``, it is parallelized at the outermost level. With ``Method -> "FinestGrained"``, it is parallelized at the innermost level.

* The ``DistributedContexts`` option specifies which symbols appearing in ``expr`` have their definitions automatically distributed to all available kernels before the computation.

* The default value is ``DistributedContexts :> \$DistributedContexts`` with ``\$DistributedContexts := \$Context``, which distributes definitions of all symbols in the current context but does not distribute definitions of symbols from packages.

* The ``ProgressReporting`` option specifies whether to report the progress of the parallel computation.

* The default value is ``ProgressReporting :> \$ProgressReporting``.

---

## Examples (46)

### Basic Examples (6)

``ParallelTable`` works like ``Table``, but in parallel:

```wl
In[1]:= Table[Pause[1];f[i], {i, 4}]//AbsoluteTiming

Out[1]= {4.000286, {f[1], f[2], f[3], f[4]}}

In[2]:= ParallelTable[Pause[1];f[i], {i, 4}]//AbsoluteTiming

Out[2]= {1.009126, {f[1], f[2], f[3], f[4]}}
```

---

A table of the first 10 squares:

```wl
In[1]:= ParallelTable[i ^ 2, {i, 10}]

Out[1]= {1, 4, 9, 16, 25, 36, 49, 64, 81, 100}
```

---

A table with ``i`` running from 0 to 20 in steps of 2:

```wl
In[1]:= ParallelTable[f[i], {i, 0, 20, 2}]

Out[1]= {f[0], f[2], f[4], f[6], f[8], f[10], f[12], f[14], f[16], f[18], f[20]}
```

---

Make a 4×3 matrix:

```wl
In[1]:= ParallelTable[10i + j, {i, 4}, {j, 3}]

Out[1]= {{11, 12, 13}, {21, 22, 23}, {31, 32, 33}, {41, 42, 43}}

In[2]:= MatrixForm[%]

Out[2]//MatrixForm=
(⁠|    |    |    |
| -- | -- | -- |
| 11 | 12 | 13 |
| 21 | 22 | 23 |
| 31 | 32 | 33 |
| 41 | 42 | 43 |⁠)
```

---

Plot a table:

```wl
In[1]:= ListPlot[ParallelTable[Total[FactorInteger[2 ^ i - 1][[All, 2]]], {i, 150, 190}]]

Out[1]= [image]
```

---

Longer computations display information about their progress and estimated time to completion:

```wl
In[1]:= res = ParallelTable[PrimeQ[2 ^ i - 1], {i, 9601, 12000}];

During evaluation of In[2]:=
Animator[0., {0., Infinity, 1.}, AnimationRate -> 1, AnimationRunTime -> 0.2437129020690918, 
 AnimationTimeIndex -> 0.2437129020690918, AppearanceElements -> None, ImageSize -> {1, 1}]
```

### Scope (5)

The index in the table can run backward:

```wl
In[1]:= ParallelTable[f[i], {i, 10, -5, -2}]

Out[1]= {f[10], f[8], f[6], f[4], f[2], f[0], f[-2], f[-4]}
```

---

Make a triangular array:

```wl
In[1]:= ParallelTable[10i + j, {i, 5}, {j, i}]

Out[1]= {{11}, {21, 22}, {31, 32, 33}, {41, 42, 43, 44}, {51, 52, 53, 54, 55}}

In[2]:= TableForm[%]

Out[2]//TableForm= TableForm[{{11}, {21, 22}, {31, 32, 33}, {41, 42, 43, 44}, {51, 52, 53, 54, 55}}]
```

---

Make a 3x2x4 array, or tensor:

```wl
In[1]:= ParallelTable[100i + 10j + k, {i, 3}, {j, 2}, {k, 4}]

Out[1]= {{{111, 112, 113, 114}, {121, 122, 123, 124}}, {{211, 212, 213, 214}, {221, 222, 223, 224}}, {{311, 312, 313, 314}, {321, 322, 323, 324}}}
```

---

Iterate over an existing list:

```wl
In[1]:= ParallelTable[Sqrt[x], {x, {1, 4, 9, 16}}]

Out[1]= {1, 2, 3, 4}
```

---

Make an array from existing lists:

```wl
In[1]:= ParallelTable[j ^ (1 / i), {i, {1, 2, 4}}, {j, {1, 4, 9}}]

Out[1]= {{1, 4, 9}, {1, 2, 3}, {1, Sqrt[2], Sqrt[3]}}
```

### Generalizations & Extensions (1)

The table index can have symbolic values:

```wl
In[1]:= ParallelTable[2 ^ x + x, {x, a, a + 5n, n}]

Out[1]= {2^a + a, 2^a + n + a + n, 2^a + 2 n + a + 2 n, 2^a + 3 n + a + 3 n, 2^a + 4 n + a + 4 n, 2^a + 5 n + a + 5 n}
```

### Options (14)

#### Method (7)

Break the computation into the smallest possible subunits:

```wl
In[1]:= ParallelTable[Labeled[Framed[i], $KernelID], {i, 10}, Method -> "FinestGrained"]

Out[1]= {Labeled[1, 1, {}], Labeled[2, 2, {}], Labeled[3, 3, {}], Labeled[4, 4, {}], Labeled[5, 1, {}], Labeled[6, 2, {}], Labeled[7, 3, {}], Labeled[8, 4, {}], Labeled[9, 1, {}], Labeled[10, 2, {}]}
```

---

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

```wl
In[1]:= ParallelTable[Labeled[Framed[i], $KernelID], {i, 10}, Method -> "CoarsestGrained"]

Out[1]= {Labeled[1, 1, {}], Labeled[2, 1, {}], Labeled[3, 1, {}], Labeled[4, 2, {}], Labeled[5, 2, {}], Labeled[6, 2, {}], Labeled[7, 3, {}], Labeled[8, 3, {}], Labeled[9, 4, {}], Labeled[10, 4, {}]}
```

---

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

```wl
In[1]:= ParallelTable[Labeled[Framed[i], $KernelID], {i, 12}, Method -> "EvaluationsPerKernel" -> 2]

Out[1]= {Labeled[1, 1, {}], Labeled[2, 1, {}], Labeled[3, 2, {}], Labeled[4, 2, {}], Labeled[5, 3, {}], Labeled[6, 3, {}], Labeled[7, 4, {}], Labeled[8, 4, {}], Labeled[9, 1, {}], Labeled[10, 2, {}], Labeled[11, 3, {}], Labeled[12, 4, {}]}
```

---

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

```wl
In[1]:= ParallelTable[Labeled[Framed[i], $KernelID], {i, 18}, Method -> "ItemsPerEvaluation" -> 5]

Out[1]= {Labeled[1, 1, {}], Labeled[2, 1, {}], Labeled[3, 1, {}], Labeled[4, 1, {}], Labeled[5, 1, {}], Labeled[6, 2, {}], Labeled[7, 2, {}], Labeled[8, 2, {}], Labeled[9, 2, {}], Labeled[10, 2, {}], Labeled[11, 3, {}], Labeled[12, 3, {}], Labeled[13, 3, {}], Labeled[14, 3, {}], Labeled[15, 4, {}], Labeled[16, 4, {}], Labeled[17, 4, {}], Labeled[18, 4, {}]}
```

---

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

```wl
In[1]:= ParallelTable[Labeled[Framed[i], $KernelID], {i, 18}, Method -> Automatic]

Out[1]= {Labeled[1, 1, {}], Labeled[2, 1, {}], Labeled[3, 1, {}], Labeled[4, 2, {}], Labeled[5, 2, {}], Labeled[6, 2, {}], Labeled[7, 3, {}], Labeled[8, 3, {}], Labeled[9, 4, {}], Labeled[10, 4, {}], Labeled[11, 1, {}], Labeled[12, 1, {}], Labeled[13, 2, {}], Labeled[14, 2, {}], Labeled[15, 3, {}], Labeled[16, 3, {}], Labeled[17, 4, {}], Labeled[18, 4, {}]}
```

---

Calculations with vastly differing runtimes should be parallelized as finely as possible:

```wl
In[1]:= ParallelTable[{i, PrimeQ[2 ^ i - 1]}, {i, 4410, 4430}, Method -> "FinestGrained"]

Out[1]= {{4410, False}, {4411, False}, {4412, False}, {4413, False}, {4414, False}, {4415, False}, {4416, False}, {4417, False}, {4418, False}, {4419, False}, {4420, False}, {4421, False}, {4422, False}, {4423, True}, {4424, False}, {4425, False}, {4426, False}, {4427, False}, {4428, False}, {4429, False}, {4430, False}}
```

A large number of simple calculations should be distributed into as few batches as possible:

```wl
In[2]:= BinCounts[ParallelTable[Mod[Floor[i * Pi], 10], {i, 10000}, Method -> "CoarsestGrained"], {0, 10}]

Out[2]= {973, 1018, 973, 1019, 1016, 975, 1017, 974, 1017, 1018}
```

---

By default, a small nested table is parallelized fully at the innermost level:

```wl
In[1]:= ParallelTable[{i, j, Style[$KernelID, Red]}, {i, 4}, {j, i}]

Out[1]= {{{1, 1, 1}}, {{2, 1, 2}, {2, 2, 3}}, {{3, 1, 4}, {3, 2, 1}, {3, 3, 2}}, {{4, 1, 3}, {4, 2, 4}, {4, 3, 1}, {4, 4, 2}}}
```

To parallelize only at the first level, use ``Method -> "CoarsestGrained"`` :

```wl
In[2]:= ParallelTable[{i, j, Style[$KernelID, Red]}, {i, 4}, {j, i}, Method -> "CoarsestGrained"]

Out[2]= {{{1, 1, 1}}, {{2, 1, 2}, {2, 2, 2}}, {{3, 1, 3}, {3, 2, 3}, {3, 3, 3}}, {{4, 1, 4}, {4, 2, 4}, {4, 3, 4}, {4, 4, 4}}}
```

#### DistributedContexts (5)

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

```wl
In[1]:= remote[x_] := {$KernelID, x ^ 3}

In[2]:= ParallelTable[remote[i], {i, 4}]

Out[2]= {{4, 1}, {3, 8}, {2, 27}, {1, 64}}
```

---

Do not distribute any definitions of functions:

```wl
In[1]:= local[x_] := {$KernelID, x ^ 2}

In[2]:= ParallelTable[local[i], {i, 4}, DistributedContexts -> None]

Out[2]= {{0, 1}, {0, 4}, {0, 9}, {0, 16}}
```

---

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

```wl
In[1]:= a`f[x_] := {$KernelID, x}

In[2]:= ParallelTable[a`f[i], {i, 4}, DistributedContexts -> Automatic]

Out[2]= {{4, 1}, {3, 2}, {2, 3}, {1, 4}}
```

---

Distribute only definitions in the given contexts:

```wl
In[1]:= b`g[x_] := {$KernelID, -x}

In[2]:= ParallelTable[b`g[i], {i, 4}, DistributedContexts -> {"a`"}]

Out[2]= {{0, -1}, {0, -2}, {0, -3}, {0, -4}}
```

---

Restore the value of the ``DistributedContexts`` option to its default:

```wl
In[1]:= SetOptions[ParallelTable, DistributedContexts :> $DistributedContexts]

Out[1]= {Method -> Automatic, DistributedContexts :> $DistributedContexts}
```

#### ProgressReporting (2)

Do not show a temporary progress report:

```wl
In[1]:= res = ParallelTable[PrimeQ[2 ^ i - 1], {i, 9601, 12000}, ProgressReporting -> False];
```

---

Use ``Method -> "FinestGrained"`` for the most accurate progress report:

```wl
In[1]:= res = ParallelTable[{i, Total[FactorInteger[10 ^ 60 + i][[All, 2]]]}, {i, 1000}, Method -> "FinestGrained"];

During evaluation of In[2]:=
Animator[0., {0., Infinity, 1.}, AnimationRate -> 1, AnimationRunTime -> 0.27040624618530273, 
 AnimationTimeIndex -> 0.27040624618530273, AppearanceElements -> None, ImageSize -> {1, 1}]
```

### Applications (5)

Solve and plot a differential equation for many initial conditions and animate the results:

```wl
In[1]:= eqn = D[z[t, s], t, t] == -(z[t, s]/(z[t, s]^2 + ((1/2) (1 + 0.1 Sin[2 Pi t]))^2)^3 / 2);

In[2]:=
sols = ParallelTable[localsol = NDSolve[{eqn, z[0, s] == param s, Derivative[1, 0][z][0, s] == param}, z, {t, 0, 10}, {s, 1, 2}]; 
	Plot3D[Evaluate[z[tp, z0] /. localsol], {tp, 0, 10}, {z0, 1, 2}, PlotRange -> {-5, 5}, PlotLabel -> param], 
	{param, -1, 1, 0.1}];

In[3]:= ListAnimate[sols]

Out[3]= DynamicModule[«8»]
```

---

Explore different parameter values for the sine-Gordon equation in two spatial dimensions:

```wl
In[1]:=
With[{L = 4, dz = 0.25}, 
	sols = ParallelTable[
	localsol = Quiet@NDSolve[{D[u[t, x, y], t, t] == D[u[t, x, y], x, x] + D[u[t, x, y], y, y] + Sin[u[t, x, y]], u[t, -L, y] == u[t, L, y], u[t, x, -L] == u[t, x, L], u[0, x, y] == a Exp[-(b x ^ 2 + y ^ 2)], Derivative[1, 0, 0][u][0, x, y] == 0}, u, {t, 0, L / 2}, {x, -L, L}, {y, -L, L}]; 
	Plot3D[Evaluate[u[L / 2, x, y] /. First[localsol]], {x, -L, L}, {y, -L, L}, PlotRange -> {{-L, L}, {-L, L}, {-dz, dz}}, Axes -> None, PlotLabel -> {a, b}], {a, -0.5, 0.5, 0.2}, {b, 0.8, 1.2, .1}, Method -> "FinestGrained"]
	];

In[2]:= GraphicsGrid[sols]

Out[2]= [image]
```

---

Apply different algorithms to the same set of data:

```wl
In[1]:= img = [image];
```

Apply a list of different filters to the same image and display the result:

```wl
In[2]:=
filters = {Identity, Sharpen, Blur, GaussianFilter[#, 3]&, LaplacianFilter[#, 1]&, LaplacianGaussianFilter[#, 2]&, 
	GradientFilter[#, 2]&, MedianFilter[#, 5]&, 
	ImageConvolve[#, BoxMatrix[1] / 9]&};

In[3]:= ParallelTable[Tooltip[filter[img], filter], {filter, filters}]

Out[3]= [image]
```

Or apply a list of effects:

```wl
In[4]:= ParallelTable[ImageEffect[img, effect], {effect, {"Charcoal", "Embossing", "Solarization"}}]

Out[4]= [image]
```

---

Generate 10 frames from an animation and save them to individual files:

```wl
In[1]:=
frames[i_, f_, R_] := Module[{frame}, 
	Do[frame = RevolutionPlot3D[Sin[t / (10f) * 2 * Pi]BesselJ[0, r], {r, 0, R}, PlotRange -> {{-R, R}, {-R, R}, {-1, 1}}, Axes -> None, PlotPoints -> 5];
	Export["drum-" <> ToString[PaddedForm[t, 3, NumberPadding -> "0"]] <> ".gif", frame]
	, {t, 10i + 1, 10(i + 1)}
	];
	frame
	];
```

Run several batches in parallel:

```wl
In[2]:= samples = With[{batches = 8}, ParallelTable[frames[i, batches, 11], {i, 0, batches - 1}]];
```

Each run returns one frame which can be used for checking the correctness:

```wl
In[3]:= samples

Out[3]= {[image], [image], [image], [image], [image], [image], [image], [image]}
```

Remove the generated files:

```wl
In[4]:= DeleteFile[FileNames["drum-*.gif"]]
```

---

Quickly show the evaluation of several nontrivial cellular automata:

```wl
In[1]:= data = Select[ParallelTable[Graphics3D[{Cuboid /@ Position[CellularAutomaton[{n, {2, 1}, {1, 1, 1}}, {{{{1}}}, 0}, {{{8}}}], 1]}, Boxed -> False], {n, 2, 80, 5}], Length[#[[1, -1]]] > 50&];

In[2]:= GraphicsGrid[Partition[data, 3], Frame -> All, ImageSize -> 500]

Out[2]= [image]
```

### Properties & Relations (10)

Parallelization happens along the outermost (first) index:

```wl
In[1]:= ParallelTable[Labeled[Framed[f[i, j]], $KernelID], {i, 4}, {j, i}]

Out[1]= {{Labeled[f[1, 1], 4]}, {Labeled[f[2, 1], 3], Labeled[f[2, 2], 3]}, {Labeled[f[3, 1], 2], Labeled[f[3, 2], 2], Labeled[f[3, 3], 2]}, {Labeled[f[4, 1], 1], Labeled[f[4, 2], 1], Labeled[f[4, 3], 1], Labeled[f[4, 4], 1]}}
```

---

Using multiple iteration specifications is equivalent to nesting ``Table`` functions:

```wl
In[1]:= ParallelTable[i + j, {i, 3}, {j, i}]

Out[1]= {{2}, {3, 4}, {4, 5, 6}}

In[2]:= ParallelTable[Table[i + j, {j, i}], {i, 3}]

Out[2]= {{2}, {3, 4}, {4, 5, 6}}
```

---

``ParallelDo`` evaluates the same sequence of expressions as ``ParallelTable`` :

```wl
In[1]:= ParallelDo[Print[i ^ i], {i, 3}]

(kernel 4) 1

(kernel 3) 4

(kernel 2) 27

In[2]:= ParallelTable[i ^ i, {i, 3}]

Out[2]= {1, 4, 27}
```

---

``ParallelSum`` effectively applies ``Plus`` to results from ``ParallelTable`` :

```wl
In[1]:= ParallelSum[x ^ i, {i, 3}]

Out[1]= x + x^2 + x^3

In[2]:= ParallelTable[x ^ i, {i, 3}]

Out[2]= {x, x^2, x^3}
```

---

``ParallelArray`` iterates over successive integers:

```wl
In[1]:= ParallelArray[#1 ^ #2&, {3, 4}]

Out[1]= {{1, 1, 1, 1}, {2, 4, 8, 16}, {3, 9, 27, 81}}

In[2]:= ParallelArray[Function[{x, y}, x ^ y], {3, 4}]

Out[2]= {{1, 1, 1, 1}, {2, 4, 8, 16}, {3, 9, 27, 81}}

In[3]:= ParallelTable[x ^ y, {x, 3}, {y, 4}]

Out[3]= {{1, 1, 1, 1}, {2, 4, 8, 16}, {3, 9, 27, 81}}
```

---

``Map`` applies a function to successive elements in a list:

```wl
In[1]:= list = RandomInteger[9, 10]

Out[1]= {0, 5, 1, 9, 0, 1, 0, 0, 1, 6}

In[2]:= ParallelMap[Last[IntegerDigits[#, 2]]&, list]

Out[2]= {0, 1, 1, 1, 0, 1, 0, 0, 1, 0}
```

``Table`` can substitute successive elements in a list into an expression:

```wl
In[3]:= ParallelTable[Last[IntegerDigits[x, 2]], {x, list}]

Out[3]= {0, 1, 1, 1, 0, 1, 0, 0, 1, 0}
```

---

``ParallelTable`` iterating over a given list is equivalent to ``ParallelCombine`` :

```wl
In[1]:= list = RandomInteger[9, 10]

Out[1]= {4, 4, 4, 0, 7, 1, 2, 2, 2, 8}

In[2]:= ParallelTable[x ^ 2, {x, list}]

Out[2]= {16, 16, 16, 0, 49, 1, 4, 4, 4, 64}

In[3]:= ParallelCombine[Function[x, x ^ 2], list]

Out[3]= {16, 16, 16, 0, 49, 1, 4, 4, 4, 64}
```

---

``ParallelTable`` can be implemented with ``WaitAll`` and ``ParallelSubmit`` :

```wl
In[1]:= WaitAll[Table[ParallelSubmit[{i}, Labeled[Framed[f[i]], $KernelID]], {i, 4}]]

Out[1]= {Labeled[f[1], 4], Labeled[f[2], 3], Labeled[f[3], 2], Labeled[f[4], 1]}
```

Parallelization at the innermost level of a multidimensional table:

```wl
In[2]:= WaitAll[Table[ParallelSubmit[{i, j}, Labeled[Framed[f[i, j]], $KernelID]], {i, 4}, {j, i}]]

Out[2]= {{Labeled[f[1, 1], 4]}, {Labeled[f[2, 1], 3], Labeled[f[2, 2], 2]}, {Labeled[f[3, 1], 1], Labeled[f[3, 2], 4], Labeled[f[3, 3], 3]}, {Labeled[f[4, 1], 2], Labeled[f[4, 2], 1], Labeled[f[4, 3], 4], Labeled[f[4, 4], 3]}}
```

---

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

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

In[2]:= ParallelTable[ftest[i], {i, 1275, 1285}]

Out[2]= {Labeled[False, 4], Labeled[False, 4], Labeled[False, 3], Labeled[False, 3], Labeled[True, 2], Labeled[False, 2], Labeled[False, 1], Labeled[False, 4], Labeled[False, 4], Labeled[False, 3], Labeled[False, 1]}
```

Distribute definitions manually and disable automatic distribution:

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

In[4]:= DistributeDefinitions[gtest];

In[5]:= ParallelTable[gtest[i], {i, 1275, 1285}, DistributedContexts -> None]

Out[5]= {Labeled[False, 4], Labeled[False, 4], Labeled[False, 3], Labeled[False, 3], Labeled[True, 2], Labeled[False, 2], Labeled[False, 1], Labeled[False, 4], Labeled[False, 1], Labeled[False, 4], Labeled[False, 3]}
```

---

For functions from a package, use ``ParallelNeeds`` rather than ``DistributeDefinitions`` :

```wl
In[1]:= Needs["FiniteFields`"]

In[2]:= Table[FieldSize[GF[2, i]], {i, 10}]

Out[2]= {2, 4, 8, 16, 32, 64, 128, 256, 512, 1024}

In[3]:= ParallelNeeds["FiniteFields`"]

In[4]:= ParallelTable[FieldSize[GF[2, i]], {i, 10}]

Out[4]= {2, 4, 8, 16, 32, 64, 128, 256, 512, 1024}
```

### Possible Issues (3)

A function used that is not known on the parallel kernels may lead to sequential evaluation:

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

In[2]:= ParallelTable[ftest[i], {i, 1275, 1285}, DistributedContexts -> None]

Out[2]= {Labeled[False, 0], Labeled[False, 0], Labeled[False, 0], Labeled[False, 0], Labeled[True, 0], Labeled[False, 0], Labeled[False, 0], Labeled[False, 0], Labeled[False, 0], Labeled[False, 0], Labeled[False, 0]}
```

Define the function on all parallel kernels:

```wl
In[3]:= DistributeDefinitions[ftest]

Out[3]= {ftest}
```

The function is now evaluated on the parallel kernels:

```wl
In[4]:= ParallelTable[ftest[i], {i, 1275, 1285}, DistributedContexts -> None]

Out[4]= {Labeled[False, 4], Labeled[False, 4], Labeled[False, 3], Labeled[False, 3], Labeled[True, 2], Labeled[False, 2], Labeled[False, 1], Labeled[False, 4], Labeled[False, 3], Labeled[False, 1], Labeled[False, 4]}
```

---

Definitions of functions in the current context are distributed automatically:

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

In[2]:= ParallelTable[gtest[i], {i, 1275, 1285}]

Out[2]= {Labeled[False, 4], Labeled[False, 4], Labeled[False, 3], Labeled[False, 3], Labeled[True, 2], Labeled[False, 2], Labeled[False, 1], Labeled[False, 4], Labeled[False, 1], Labeled[False, 4], Labeled[False, 4]}
```

Definitions from contexts other than the default context are not distributed automatically:

```wl
In[3]:= ctx`mtest[n_] := Labeled[Framed[PrimeQ[2 ^ n - 1]], $KernelID]

In[4]:= ParallelTable[ctx`mtest[i], {i, 1275, 1285}]

Out[4]= {Labeled[False, 0], Labeled[False, 0], Labeled[False, 0], Labeled[False, 0], Labeled[True, 0], Labeled[False, 0], Labeled[False, 0], Labeled[False, 0], Labeled[False, 0], Labeled[False, 0], Labeled[False, 0]}
```

Use ``DistributeDefinitions`` to distribute such definitions:

```wl
In[5]:= DistributeDefinitions[ctx`mtest];

In[6]:= ParallelTable[ctx`mtest[i], {i, 1275, 1285}]

Out[6]= {Labeled[False, 4], Labeled[False, 4], Labeled[False, 3], Labeled[False, 3], Labeled[True, 2], Labeled[False, 2], Labeled[False, 1], Labeled[False, 4], Labeled[False, 1], Labeled[False, 4], Labeled[False, 4]}
```

Alternatively, set the ``DistributedContexts`` option to include all contexts:

```wl
In[7]:= cty`mtest[n_] := Labeled[Framed[PrimeQ[2 ^ n - 1]], $KernelID]

In[8]:= ParallelTable[cty`mtest[i], {i, 1275, 1285}, DistributedContexts -> Automatic]

Out[8]= {Labeled[False, 4], Labeled[False, 4], Labeled[False, 3], Labeled[False, 3], Labeled[True, 2], Labeled[False, 2], Labeled[False, 1], Labeled[False, 4], Labeled[False, 1], Labeled[False, 4], Labeled[False, 4]}
```

---

Trivial operations may take longer when parallelized:

```wl
In[1]:= AbsoluteTiming[ParallelTable[N[Sin[x]], {x, 0, 1000}];]

Out[1]= {0.017345, Null}

In[2]:= AbsoluteTiming[Table[N[Sin[x]], {x, 0, 1000}];]

Out[2]= {0.000429, Null}
```

### Neat Examples (2)

Visualize the Mandelbrot set:

```wl
In[1]:= mlength[z_] := Length[FixedPointList[# ^ 2 + z&, z, 20, SameTest -> (Abs[#] > 2&)]]

In[2]:= points = ParallelTable[mlength[x + I y], {y, -1, 1, 0.005}, {x, -2, 1, 0.005}];

In[3]:= ArrayPlot[points, ColorFunction -> Hue]

Out[3]= [image]
```

---

Calculate and display the Feigenbaum (or bifurcation) diagram of the logistics map:

```wl
In[1]:=
line[r_, dy_, np_, n0_, n_] := Module[{pts}, 
	With[{logistics = Function[x, r x(1 - x)]}, 
	pts = Join@@NestList[logistics, Nest[logistics, RandomReal[{0, 1}, np], n0], n - 1]];
	Log[1.0 + BinCounts[pts, {0, 1, dy}]]]

In[2]:=
With[{w = 400, h = 250, r0 = 2.95, r1 = 4.0}, 
	ArrayPlot[ParallelTable[line[r, 1 / (w - 1), w, 500, 50], {r, r0, r1, (r1 - r0) / (h - 1)}], ImageSize -> {w, h}]]

Out[2]= [image]
```

## See Also

* [`Table`](https://reference.wolfram.com/language/ref/Table.en.md)
* [`Parallelize`](https://reference.wolfram.com/language/ref/Parallelize.en.md)
* [`ParallelArray`](https://reference.wolfram.com/language/ref/ParallelArray.en.md)
* [`ParallelTry`](https://reference.wolfram.com/language/ref/ParallelTry.en.md)
* [`ParallelDo`](https://reference.wolfram.com/language/ref/ParallelDo.en.md)
* [`ParallelSum`](https://reference.wolfram.com/language/ref/ParallelSum.en.md)

## Related Guides

* [Data Parallelism](https://reference.wolfram.com/language/guide/DataParallelism.en.md)
* [Parallel Computing](https://reference.wolfram.com/language/guide/ParallelComputing.en.md)
* [Raspberry Pi](https://reference.wolfram.com/language/guide/RaspberryPi.en.md)
* [Managing Remote and Parallel Kernels](https://reference.wolfram.com/language/guide/ManagingRemoteAndParallelKernels.en.md)

## History

* [Introduced in 2008 (7.0)](https://reference.wolfram.com/language/guide/SummaryOfNewFeaturesIn70.en.md) \| [Updated in 2010 (8.0)](https://reference.wolfram.com/language/guide/SummaryOfNewFeaturesIn80.en.md) ▪ [2021 (13.0)](https://reference.wolfram.com/language/guide/SummaryOfNewFeaturesIn130.en.md)