These function are only available if PARI was configured using
`Configure --mt = ...`

. Two multithread interfaces are supported:

***** POSIX threads

***** Message passing interface (MPI)

As a rule, POSIX threads are well-suited for single systems, while MPI is used by most clusters. However the parallel GP interface does not depend on the chosen multithread interface: a properly written GP program will work identically with both.

Parallel evaluation of `f`

on the elements of `x`

.
The function `f`

must not access global variables or variables
declared with local(), and must be free of side effects.

parapply(factor,[2^256 + 1, 2^193 - 1])

factors 2^{256} + 1 and 2^{193} - 1 in parallel.

{ my(E = ellinit([1,3]), V = vector(12,i,randomprime(2^200))); parapply(p->ellcard(E,p), V) }

computes the order of E(𝔽_p) for 12 random primes of 200 bits.

The library syntax is `GEN `

.**parapply**(GEN f, GEN x)

Parallel evaluation of the elements of `x`

, where `x`

is a
vector of closures. The closures must be of arity 0, must not access
global variables or variables declared with `local`

and must be
free of side effects.

The library syntax is `GEN `

.**pareval**(GEN x)

Evaluates in parallel the expression `expr1`

in the formal
argument i running from a to b.
If b is set to `+oo`

, the loop runs indefinitely.
If r and `expr2`

are present, the expression `expr2`

in the
formal variables r and i is evaluated with r running through all
the different results obtained for `expr1`

and i takes the
corresponding argument.

The computations of `expr1`

are *started* in increasing order
of i; otherwise said, the computation for i = c is started after those
for i = 1,..., c-1 have been started, but before the computation for
i = c+1 is started. Notice that the order of *completion*, that is,
the order in which the different r become available, may be different;
`expr2`

is evaluated sequentially on each r as it appears.

The following example computes the sum of the squares of the integers
from 1 to 10 by computing the squares in parallel and is equivalent
to `parsum (i = 1, 10, i^2)`

:

? s=0; ? parfor (i=1, 10, i^2, r, s=s+r) ? s %3 = 385

More precisely, apart from a potentially different order of evaluation
due to the parallelism, the line containing `parfor`

is equivalent to

? my (r); for (i=1, 10, r=i^2; s=s+r)

The sequentiality of the evaluation of `expr2`

ensures that the
variable `s`

is not modified concurrently by two different additions,
although the order in which the terms are added is non-deterministic.

It is allowed for `expr2`

to exit the loop using
`break`

/`next`

/`return`

. If that happens for i = c,
then the evaluation of `expr1`

and `expr2`

is continued
for all values i < c, and the return value is the one obtained for
the smallest i causing an interruption in `expr2`

(it may be
undefined if this is a `break`

/`next`

).
In that case, using side-effects
in `expr2`

may lead to undefined behavior, as the exact
number of values of i for which it is executed is non-deterministic.
The following example computes `nextprime(1000)`

in parallel:

? parfor (i=1000, , isprime (i), r, if (r, return (i))) %1 = 1009

Behaves exactly as `parfor`

, but loops only over prime values p.
Precisely, the functions evaluates in parallel the expression `expr1`

in the formal
argument p running through the primes from a to b.
If b is set to `+oo`

, the loop runs indefinitely.
If r and `expr2`

are present, the expression `expr2`

in the
formal variables r and p is evaluated with r running through all
the different results obtained for `expr1`

and p takes the
corresponding argument.

It is allowed fo `expr2`

to exit the loop using
`break`

/`next`

/`return`

; see the remarks in the documentation
of `parfor`

for details.

Evaluates the sequence `expr2`

(dependent on X and j) for X
as generated by `forvec`

, in random order, computed in parallel. Substitute
for j the value of `expr1`

(dependent on X).

It is allowed fo `expr2`

to exit the loop using
`break`

/`next`

/`return`

, however in that case, `expr2`

will
still be evaluated for all remaining value of p less than the current one,
unless a subsequent `break`

/`next`

/`return`

happens.

Selects elements of A according to the selection function f, done in
parallel. If *flag* is 1, return the indices of those elements (indirect
selection) The function `f`

must not access global variables or
variables declared with local(), and must be free of side effects.

The library syntax is `GEN `

.**parselect**(GEN f, GEN A, long flag)

Sum of expression *expr*, initialized at x, the formal parameter
going from a to b, evaluated in parallel in random order.
The expression `expr`

must not access global variables or
variables declared with `local()`

, and must be free of side effects.

parsum(i=1,1000,ispseudoprime(2^prime(i)-1))

returns the numbers of prime numbers among the first 1000 Mersenne numbers.

As `vector(N,i,expr)`

but the evaluations of `expr`

are done in
parallel. The expression `expr`

must not access global variables or
variables declared with `local()`

, and must be free of side effects.

parvector(10,i,quadclassunit(2^(100+i)+1).no)

computes the class numbers in parallel.