[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 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)