Skip to content

Commit b96d832

Browse files
committed
Update Reference “opencilk-language-specification”
1 parent d7a791e commit b96d832

File tree

1 file changed

+4
-113
lines changed

1 file changed

+4
-113
lines changed

src/doc/reference/opencilk-language-specification.md

Lines changed: 4 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -142,9 +142,9 @@ attribution: true
142142

143143
A new form of Statement is introduced:
144144

145-
_Cilk_scope { Statement* }
145+
cilk_scope { Statement* }
146146

147-
Statements within _Cilk_scope are executed as usual. There is an implicit _Cilk_sync at the end of the statements included within the _Cilk_scope construct.
147+
Statements within cilk_scope are executed as usual. There is an implicit cilk_sync at the end of the statements included within the cilk_scope construct.
148148

149149
## Semantics
150150

@@ -682,9 +682,9 @@ else ((<var>first</var>) <code>-</code> (<var>limit</var>)) <code>/</code> <code
682682
a++;</pre>
683683
<p>The call to function <code>f</code> is the spawn point and the statement <code>a++;</code>
684684
is the continuation. The expression <code>a + b</code> and the initialization of
685-
the temporary variable holding that value, and the evaluation of <code>x\\\\\\[g()]</code>
685+
the temporary variable holding that value, and the evaluation of <code>x\\\\\\\[g()]</code>
686686
take place before the spawn point. The execution of <code>f</code>, the assignment
687-
to <code>x\\\\\\[g()]</code>, and the destruction of the temporary variable holding <code>
687+
to <code>x\\\\\\\[g()]</code>, and the destruction of the temporary variable holding <code>
688688
a + b</code> take place in the child.</p>
689689
<p>If a statement is followed by an implicit sync, that sync is the spawn continuation.</p>
690690
<p class="note">Programmer note: The sequencing may be more clear if</p>
@@ -732,115 +732,6 @@ a++;</pre>
732732
the serial execution order of the program) are destructed in an unspecified order
733733
before the earliest exception is caught.</p>
734734

735-
# Hyperobjects
736-
737-
## Description
738-
739-
<p>Cilk <ins>Plus</ins> defines a category of objects called &#x201c;hyperobjects&#x201d;.
740-
Hyperobjects allow thread-safe access to shared objects by giving each <del>parallel</del>
741-
strand <ins>running in parallel</ins> a separate instance of the object.</p>
742-
<p>Parallel code uses a hyperobject by performing a <dfn>hyperobject lookup</dfn> operation.
743-
The hyperobject lookup returns a reference to an object, called a <dfn>view,</dfn>
744-
that is guaranteed not to be shared with any other active strands in the program.
745-
The sequencing of a hyperobject lookup within an expression is not specified. The
746-
runtime system creates a view when needed, using callback functions provided by
747-
the hyperobject type. When strands synchronize, the hyperobject views are merged
748-
into a single view, using another callback function provided by the hyperobject
749-
type.</p>
750-
<p>The view of a hyperobject visible to a program may change at any spawn or sync (including
751-
the implicit spawns and syncs within a <code>cilk_for</code> loop). The identity
752-
(address) of the view does not change within a single strand. The view of a given
753-
hyperobject visible within a given strand is said to be <dfn>associated</dfn> with
754-
that view. A hyperobject has the same view before the first spawn within a task
755-
block as after a sync within the same task block, even though the thread ID may
756-
not be the same (i.e., hyperobject views are not tied to threads). A hyperobject
757-
has the same view upon entering and leaving a <code>cilk_for</code> loop and within
758-
the first iteration (at least) of the <code>cilk_for</code> loop. A special view
759-
is associated with a hyperobject when the hyperobject is initially created. This
760-
special view is called the <dfn>leftmost view</dfn> or <dfn>earliest view</dfn>
761-
because it is always visible to the leftmost (earliest) descendent in the depth-first,
762-
left-to-right traversal of the program's spawn tree. The leftmost view is given
763-
an initial value when the hyperobject is created.</p>
764-
<p class="note">Programmer note: If two expressions compute the same address for a view,
765-
then they have not been scheduled in parallel. This property yields one of the simplest
766-
ways by which a program can observe the runtime behavior of the scheduler.</p>
767-
<p class="note">Implementation note: An implementation can optimize hyperobject lookups
768-
by performing them only when a view has (or might have) changed. This optimization
769-
can be facilitated by attaching implementation-specific attributes to the hyperobject
770-
creation, lookup, and/or destruction operations.</p>
771-
772-
## Reducers
773-
774-
<p>The vast majority of hyperobjects belong to a category known as &#x201c;reducers.&#x201d;
775-
Each reducer type provides a <code>reduce</code> callback operation that merges
776-
two views in a manner specific to the reducer. For a pair of views <var>V<sub>1</sub></var>
777-
and <var>V<sub>2</sub></var>, the result of calling <code>reduce(</code><var>V<sub>1</sub></var><code>,</code>
778-
<var>V<sub>2</sub></var><code>)</code> is notated as <var>V<sub>1</sub>&#x2297;V<sub>2</sub></var>.
779-
Each reducer also provides an <code>identity</code> callback operation that initializes
780-
a new view.</p>
781-
<p>The <code>reduce</code> callback for a &#x201c;classical&#x201d; reducer implements
782-
an operation &#x2297; such that (<var>a&#x2297;b</var>)&#x2297;<var>c==a</var>&#x2297;(<var>b&#x2297;c</var>)
783-
(i.e., &#x2297; is associative). The view-initialization callback for such a reducer
784-
sets the view to an identity value <var>I</var> such that <var>I&#x2297;v==v</var>
785-
and <var>v&#x2297;I==v</var> for any value <var>v</var> of <var>value_type</var>.
786-
Given an associative &#x2297; and an identity <var>I</var>, the triplet (<var>value_type</var>,
787-
&#x2297;, <var>I</var>) describes a mathematical <dfn>monoid</dfn>. For example,
788-
(<code>int</code>, <code>+</code>, <code>0</code>) is a monoid, as is (<code>list</code>,
789-
<code>concatenate</code>, <var>empty</var>). If each individual view, <var>R</var>,
790-
of a classical reducer is modified using only expressions that are equivalent to
791-
<var>R</var>&#x2190;<var>R</var>&#x2297;<var>v</var> (where <var>v</var> is of <var>
792-
value_type</var>), then the reducer computes the same value in the parallel
793-
program as would be computed in the serialization of the program. (In actuality,
794-
the &#x201c;&#x2297;&#x201d; in the expression &#x201c;<var>R</var>&#x2190;<var>R</var>&#x2297;<var>v</var>&#x201d;
795-
can represent a set of mutually-associative operations. For example, <code>+=</code>
796-
and <code>-=</code> are mutually associative.) For example, a spawned function or
797-
<code>cilk_for</code> body can append items onto the view of a list reducer with
798-
monoid (<code>list</code>, <code>concatenate</code>, <var>empty</var>). At the end
799-
of the parallel section of code, the reducer's view contains the same list items
800-
in the same order as would be generated in a serial execution of the same code.</p>
801-
<p>Given a set of strands entering a sync, <var>S<sub>1</sub>,S<sub>2</sub>,S<sub>3</sub>,&#x2026;S<sub>n</sub></var>,
802-
associated with views <var>V<sub>1</sub>,V<sub>2</sub>,V<sub>3</sub>,&#x2026;V<sub>n</sub></var>,
803-
respectively such that <var>S<sub>i</sub></var> is earlier in the serial ordering
804-
than <var>S<sub>i+1</sub></var>, a single view, <var>W</var>, emerges from the sync
805-
with value <var>W&#x2190;V<sub>1</sub>&#x2297;V<sub>2</sub>&#x2297;V<sub>3</sub>&#x2297;&#x2026;&#x2297;V<sub>n</sub></var>,
806-
such that the left-to-right order is maintained but the grouping (associativity)
807-
of the operations is unspecified. The timing of this &#x201c;reduction&#x201d; is
808-
unspecified &#x2013; in particular, subsequences typically will be computed asynchronously
809-
as child tasks complete. Every view except the one emerging from the sync is destroyed
810-
after the merge. If any of the strands does not have an associated view, then the
811-
invocation of the <code>reduce</code> callback function can be elided (i.e., the
812-
missing view is treated as an identity).</p>
813-
<p>A strand is never associated with more than one view for a given reducer, but multiple
814-
strands can be associated with the same view if those strands are not scheduled
815-
in parallel (at run time). Specifically, for a given reducer, the association of
816-
a strand to a view of the reducer obeys the following rules:</p>
817-
<ol>
818-
<li>The strand that initializes the reducer is associated with the leftmost view.</li>
819-
<li>If two strands execute in series (i.e., both strands are part of a larger strand),
820-
then both are associated with the same view.</li>
821-
<li>The child strand of a spawn is associated with the same view as the strand that
822-
entered the spawn.</li>
823-
<li>If the continuation strand of a spawn is scheduled in parallel with the child, then
824-
the continuation strand is associated with a new view, initialized using <code>identity</code>.
825-
The implementation may create the new view at any time up until the first hyperobject
826-
lookup following the spawn. If the continuation strand does not perform a hyperobject
827-
lookup, then the implementation is not required to create a view for that strand.</li>
828-
<li>If the continuation strand of a spawn is not scheduled in parallel with the child
829-
strand (i.e., the child and the continuation execute in series), then the continuation
830-
strand is associated with the same view as the child strand.</li>
831-
<li>The strand that emerges from a sync is associated with the same view as the leftmost
832-
strand entering the sync.</li>
833-
</ol>
834-
<p>Even before the final reduction, the leftmost view of a reducer will contain the
835-
same value as in the serial execution. Other views, however, will contain partial
836-
values that are different from the serial execution.</p>
837-
<p>If &#x2297; is not associative or if <code>identity</code> does not yield a true
838-
identity value then the result of a set of reductions will be non-deterministic
839-
(i.e., it will vary based on runtime scheduling). Such &#x201c;non-classical&#x201d;
840-
reducers are nevertheless occasionally useful. Note that, for a classical reducer,
841-
the &#x2297; operator needs to be associative, but does not need to be commutative.</p>
842-
843-
844735
# Disclaimer and other legal information
845736

846737
<p>Copyright (c) 2020 Massachusetts Institute of Technology</p>

0 commit comments

Comments
 (0)