[exec.par.scheduler]

# 33 Execution control library [[exec]](./#exec)

## 33.15 Parallel scheduler [exec.par.scheduler]

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8281)

parallel_scheduler models [scheduler](exec.sched#concept:scheduler "33.6 Schedulers [exec.sched]")[.](#1.sentence-1)

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8284)

Let sch be an object of type parallel_scheduler, and
let *BACKEND-OF*(sch) be *ptr,
where sch is associated with ptr[.](#2.sentence-1)

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8289)

The expression get_forward_progress_guarantee(sch) has the valueforward_progress_guarantee​::​​parallel[.](#3.sentence-1)

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8293)

Let sch2 be an object of type parallel_scheduler[.](#4.sentence-1)

Two objects sch and sch2 compare equal if and only if*BACKEND-OF*(sch) and*BACKEND-OF*(sch2) refer to the same object[.](#4.sentence-2)

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8299)

Let rcvr be a receiver[.](#5.sentence-1)

A [*proxy for rcvr with base B*](#def:proxy "33.15 Parallel scheduler [exec.par.scheduler]") is
an lvalue r of type B such that:

- [(5.1)](#5.1)

  r.set_value() has effects equivalent toset_value(std​::​move(rcvr))[.](#5.1.sentence-1)

- [(5.2)](#5.2)

  r.set_error(e), where e is an exception_ptr object,
has effects equivalent to set_error(std​::​move(​rcvr), std​::​move(e))[.](#5.2.sentence-1)

- [(5.3)](#5.3)

  r.set_stopped() has effects equivalent toset_stopped(std​::​move(rcvr))[.](#5.3.sentence-1)

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8315)

A [*preallocated backend storage for a proxy*](#def:preallocated_backend_storage_for_a_proxy "33.15 Parallel scheduler [exec.par.scheduler]") r is
an object s of type span<byte> such that the range s remains valid and may be overwritten
until one of set_value, set_error, or set_stopped is called on r[.](#6.sentence-1)

[*Note [1](#note-1)*:

The storage referenced by s can be used as temporary storage
for operations launched via calls to parallel_scheduler_backend[.](#6.sentence-2)

â *end note*]

[7](#7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8326)

A [*bulk chunked proxy for rcvr with callable f and arguments args*](#def:proxy,bulk_chunked "33.15 Parallel scheduler [exec.par.scheduler]") is a proxy r for rcvr with base system_context_replaceability​::​bulk_item_receiver_proxy such thatr.execute(i, j) for indices i and j has effects equivalent to f(i, j, args...)[.](#7.sentence-1)

[8](#8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8335)

A [*bulk unchunked proxy for rcvr with callable f and arguments args*](#def:proxy,bulk_unchunked "33.15 Parallel scheduler [exec.par.scheduler]") is a proxy r for rcvr with base system_context_replaceability​::​bulk_item_receiver_proxy such thatr.execute(i, i + 1) for index i has effects equivalent to f(i, args...)[.](#8.sentence-1)

[9](#9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8344)

Let b be *BACKEND-OF*(sch),
let sndr be the object returned by schedule(sch), and
let rcvr be a receiver[.](#9.sentence-1)

If rcvr is connected to sndr and
the resulting operation state is started, then:

- [(9.1)](#9.1)

  If sndr completes successfully,
then b.schedule(r, s) is called, where
  * [(9.1.1)](#9.1.1)

r is a proxy for rcvr with base system_context_replaceability​::​receiver_proxy and

  * [(9.1.2)](#9.1.2)

s is a preallocated backend storage for r[.](#9.1.sentence-1)

- [(9.2)](#9.2)

  All other completion operations are forwarded unchanged[.](#9.2.sentence-1)

[10](#10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8365)

parallel_scheduler provides a customized implementation of
the bulk_chunked algorithm ([[exec.bulk]](exec.bulk "33.9.12.11 execution​::​bulk, execution​::​bulk_­chunked, and execution​::​bulk_­unchunked"))[.](#10.sentence-1)

If a receiver rcvr is connected to the sender
returned by bulk_chunked(sndr, pol, shape, f) and
the resulting operation state is started, then:

- [(10.1)](#10.1)

  If sndr completes with values vals,
let args be a pack of lvalue subexpressions designating vals,
then b.schedule_bulk_chunked(shape, r, s) is called, where
  * [(10.1.1)](#10.1.1)

r is a bulk chunked proxy for rcvr with callable f and arguments args and

  * [(10.1.2)](#10.1.2)

s is a preallocated backend storage for r[.](#10.1.sentence-1)

- [(10.2)](#10.2)

  All other completion operations are forwarded unchanged[.](#10.2.sentence-1)

[*Note [2](#note-2)*:

Customizing the behavior of bulk_chunked affects the default implementation of bulk[.](#10.sentence-3)

â *end note*]

[11](#11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8391)

parallel_scheduler provides a customized implementation of
the bulk_unchunked algorithm ([[exec.bulk]](exec.bulk "33.9.12.11 execution​::​bulk, execution​::​bulk_­chunked, and execution​::​bulk_­unchunked"))[.](#11.sentence-1)

If a receiver rcvr is connected to the sender
returned by bulk_unchunked(sndr, pol, shape, f) and
the resulting operation state is started, then:

- [(11.1)](#11.1)

  If sndr completes with values vals,
let args be a pack of lvalue subexpressions designating vals,
then b.schedule_bulk_unchunked(shape, r, s) is called, where
  * [(11.1.1)](#11.1.1)

r is a bulk unchunked proxy for rcvr with callable f and arguments args and

  * [(11.1.2)](#11.1.2)

s is a preallocated backend storage for r[.](#11.1.sentence-1)

- [(11.2)](#11.2)

  All other completion operations are forwarded unchanged[.](#11.2.sentence-1)

[ð](#lib:get_parallel_scheduler)

`parallel_scheduler get_parallel_scheduler();
`

[12](#12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L8419)

*Effects*: Let eb be the result of system_context_replaceability​::​query_parallel_scheduler_backend()[.](#12.sentence-1)

If eb == nullptr is true,
calls terminate ([[except.terminate]](except.terminate "14.6.2 The std​::​terminate function"))[.](#12.sentence-2)

Otherwise, returns a parallel_scheduler object
associated with eb[.](#12.sentence-3)
