CVS difference for ai12s/ai12-0119-1.txt

Differences between 1.15 and version 1.16
Log of other versions for file ai12s/ai12-0119-1.txt

--- ai12s/ai12-0119-1.txt	2018/03/02 06:46:45	1.15
+++ ai12s/ai12-0119-1.txt	2018/03/30 07:55:07	1.16
@@ -1,4 +1,4 @@
-!standard 5.5.2(2/3)                               18-01-10    AI12-0119-1/07
+!standard 5.5.2(2/3)                               18-03-29    AI12-0119-1/08
 !class Amendment 14-06-20
 !status work item 14-06-20
 !status received 14-06-17
@@ -19,15 +19,21 @@
 existing languages, safety concerns need to consider the paradigm shift from
 sequential to parallel behavior.
 
-Ada needs mechanisms whereby the compiler is given the necessary semantic
-information to enable the implicit and explicit parallelization of code.
-After all, the current Ada language only allows parallel execution when
-it is semantically neutral (see 1.1.4(18) and 11.6(3/3)) or explicitly
-in the code as a task.
+Ada needs mechanisms to allow the programmer to specify explicity in the code
+where parallelism should be applied. In particular, loops are often a good
+candidate for parallelisation, but there also needs to be a way to specify
+parallelism more generally to allow potentially different groups of calls to
+be executed in parallel with other groups of calls. While Ada tasks can be used
+to generate parallel execution, they are better suited for separating concerns
+of independent processing where the need for parallelisation is mostly a 
+perforamance concern, where it should be easy to convert an existing sequential
+algorithm into a parallel one, or vice versa. Declaring tasks for this purpose
+is too error prone, requires significant rework, more difficult to mainain, and
+not as easily transferable to different hardware platforms. It is better to 
+rely more on the compiler to map the parallelism to the target platform.
 
 !proposal
 
-
 This proposal depends on the facilities for aspect Global (AI12-0079-1) and for
 aspect Nonblocking (AI12-0064-2). Those proposals allow the compiler to
 statically determine where parallelism may be introduced without introducing
@@ -50,24 +56,8 @@
   minimal input from the programmer;
 - To avoid syntax that would make a POP erroneous or produce noticeably
   different results if executed sequentially vs in parallel.
-
-An important part of this model is that if the compiler is not able to
-verify that the parallel computations are independent, then a warning
-will be issued at compile time (See AI12-0079-1 and AI12-0064-1 for
-ways on how this can happen).
-
-Note that in this model the compiler will identify any code where a
-potential data race occurs (following the rules for concurrent access
-to objects as specified in the 9.10(11-14), and point out where objects
-cannot be guaranteed to be independently addressable. If not determinable
-at compile-time, the compiler may insert run-time checks to detect data
-overlap.
-
-This model also disallows potentially blocking operations within parallel
-block statements and parallel loop statements, to simplify the implementation
-of tasklets, and to eliminate possibilities of deadlocking from occurring.
 
-Another issue is the underlying runtime. In this model, tasklets are
+One issue to consider is the underlying runtime. In this model, tasklets are
 associated with tasks. Regardless of implementation, tasklets are
 considered to execute in the semantic context of the task where they
 have been spawned, which means that any operation that identifies a
@@ -121,13 +111,8 @@
 of control before completing, the first occurrence of transfer of control is
 selected and the others are aborted.
 
-If an exception is raised by any of the parallel sequences, it is
-treated similarly to other forms of transfer of control, with the exception
-being propagated only after all the other sequences complete normally or due
-to abortion. If multiple parallel sequences executing in parallel
-raise an exception before completing, the first occurrence is chosen and the
-others are aborted. The parallel block completes when all of the
-parallel sequences complete, either normally or by being aborted.
+The parallel block completes when all of the parallel sequences complete, 
+either normally or by being aborted.
 
 Note that aborting a tasklet need not be preemptive, but should prevent
 the initiation of further nested parallel blocks or parallel loops.
@@ -165,21 +150,13 @@
 
 Iteration_scheme ::= while condition
    | [parallel] for loop_parameter_specification
-   | [parallel] for iterator_specification
+   |            for iterator_specification
 
 Add after 5.5(6/5)
 
 {Legality Rules}
-A loop_statement shall not have both reserve words reverse and parallel present.
-
-A loop_statement with the *parallel* reserve word shall not update variables
-global to the loop unless either the action is sequential (see 9.10), or the
-expression for the update mentions the loop parameter.
+A loop_statement shall not have both reserved words reverse and parallel present.
 
-The sequence_of_statements of a loop_statement with the *parallel* reserved word
-shall not consist of a statement that can invoke a potentially blocking
-operation (see 9.5).
-
 Add after 5.5(7)
 
 When the reserved word parallel is present and a transfer of control out of the
@@ -219,18 +196,6 @@
 determination that is made dynamically at run time, dependent on factors
 such as the available computing resources.
 
-Add after 5.5(9/4)
-
-For a parallel loop, a check is made that updates to a component of a global
-array or to an element of a container via an expression that mentions the loop
-parameter sequential. See 9.10.
-
-AARM Reason:
-The check ensures that different tasklets executing iterations of the same loop
-in parallel will not involve data races. These checks are not needed if it can
-statically be determined that each iteration of the loop accesses a unique set
-of array components or container elements via the loop parameter.
-
 Add after 5.5(21)
 
 Example of a parallel loop
@@ -241,345 +206,6 @@
    Grid(I, 1) := (for all J in Grid(2)'Range => Grid(I,J) = True);
 end loop;
 
-Add after 5.5.1(4/3)
-
-   type Chunk_Array is limited interface
-     with Nonblocking;
-
-   function Length
-     (Object  : Chunk_Array) return Natural is abstract;
-
-   function Start
-     (Object : Chunk_Array;
-      Index  : Natural) return Cursor is abstract;
-
-   function Finish
-     (Object : Chunk_Array;
-      Index  : Natural) return Cursor is abstract;
-
-   type Parallel_Iterator is limited interface and Forward_Iterator
-      with Nonblocking;
-
-   function Iterations
-     (Object : Parallel_Iterator)
-      return Ada.Containers.Count_Type is abstract;
-
-   function Split
-     (Object        : Parallel_Iterator;
-      Advised_Split : Natural)
-      return Chunk_Array'Class is abstract;
-
-   type Parallel_Reversible_Iterator is limited interface
-     and Parallel_Iterator and Reversible_Iterator
-       with Nonblocking;
-
-Modify 5.5.1(6/3)
-
-An iterator type is a type descended from the Forward_Iterator
-interface from some instance of Ada.Iterator_Interfaces. A reversible iterator
-type is a type descended from the Reversible_Iterator interface from some
-instance of Ada.Iterator_Interfaces. {A parallel iterator type is a type
-descended from the Parallel_Iterator interface from some instance of
-Ada.Iterator_Interfaces. A parallel reversible iterator type is a type
-descended from both the Parallel_Iterator interace and the Reversible_Iterator
-interface from some instance of Ada.Iterator_Interfaces.} An iterator object is
-an object of an iterator type. A reversible iterator object is an object of a
-reversible iterator type. { A parallel iterator object is an object of a
-parallel iterator type. A parallel reversible iterator object is an object of a
-parallel reversible iterator type.} The formal subtype Cursor from the
-associated instance of Ada.Iterator_Interfaces is the iteration cursor subtype
-for the iterator type.
-
-Modify 5.5.1(11/3)
-
-An iterable container type is an indexable container type with specified
-Default_Iterator and Iterator_Element aspects. A reversible iterable container
-type is an iterable container type with the default iterator type being a
-reversible iterator type. {A parallel iterable container type is an iterable
-container type with the default iterator type being a parallel iterator type. A
-parallel reversible iterable container type is an iterable container type with
-the default iterator type being a parallel reversible iterator type.} An
-iterable container object is an object of an iterable container type. A
-reversible iterable container object is an object of a reversible iterable
-container type. {A parallel iterable container object is an object of a parallel
-iterable container type. A parallel reversible iterable container object is an
-object of a parallel reversible iterable container type.}
-
-Modify 5.5.2(4/3)
-
-If the reserved word reverse appears, the iterator_specification is a reverse
-iterator[.;] {If the reserved word parallel appears, the iterator_specification
-is a parallel iterator;} otherwise it is a forward iterator. In a reverse
-generalized iterator, the iterator_name shall be of a reversible iterator type.
-{In a parallel generalized iterator, the iterator_name shall be of a parallel
-iterator type.} In a reverse container element iterator, the default
-iterator type for the type of the iterable_name shall be a reversible iterator
-type. {In a parallel container element iterator, the default iterator type for
-the type of the iterable_name shall be of a parallel iterator type.}
-
-Modify 5.5.2(7/5)
-
-An iterator_specification declares a {set of} loop parameter {objects. If the
-keyword parallel is present, multiple objects of the loop parameter are
-created where each iteration is associated with a specific loop parameter
-object; otherwise a single loop parameter object is created for the loop. Each
-loop parameter object is associated with a thread of control where each thread
-of control proceeds independently and concurrently between the points
-where they interact with other tasks and with each other}. In a generalized
-iterator, an array component iterator, or a container element iterator,
-if a loop_parameter_subtype_indication is present, it determines the nominal
-subtype of the loop parameter{s}. In a generalized iterator, if a
-loop_parameter_subtype_indication is not present, the nominal subtype of the
-loop parameter{s} is the iteration cursor subtype. In an array component
-iterator, if a loop_parameter_subtype_indication is not present, the nominal
-subtype of the loop parameter{s are}[ is] the component subtype of the type of
-the iterable_name. In a container element iterator, if a
-loop_parameter_subtype_indication is not present, the nominal subtype of the
-loop parameter{s are}[is] the default element subtype for the type of the
-iterable_name.
-
-Modify 5.5.2(8/3)
-In a generalized iterator, the loop parameter{s are} [is a] constant. In an
-array component iterator, the loop parameter{s are} [is a] constant if the
-iterable_name denotes a constant; otherwise [it]{they} denote[s] a variable.
-In a container element iterator, the loop parameter{s are}[is a] constant if the
-iterable_name denotes a constant, or if the Variable_Indexing aspect is not
-specified for the type of the iterable_name; otherwise it is a variable.
-
-Modify AARM 5.5.2(8.a/5)
-
-Ramification: The loop parameter{s} of a generalized iterator {have}[has] the
-same accessibility as the loop statement. This means that the loop parameter
-object{s} {are}[is] finalized when the loop statement is left. ([It]{They} also
-may be finalized as part of assigning a new value to the loop parameter{s}.) For
-array component iterators, the loop parameter{s each} directly denotes an
-element of the array and [has]{have} the accessibility of the associated array.
-For container element iterators, the loop parameter{s each} denotes the result
-of [the]{an} indexing function call (in the case of a constant indexing) or a
-generalized reference thereof (in the case of a variable indexing). Roughly
-speaking, the loop parameter{s have} [has] the accessibility level of a single
-iteration of the loop. More precisely, the function result (or the generalized
-reference thereof) is considered to be renamed in the declarative part of a
-notional block statement which immediately encloses the loop's
-sequence_of_statements; the accessibility of the loop parameter{s are} [is] that
-of the block statement.
-
-Modify 5.5.2(10/3)
-
-For a generalized iterator, the loop parameter{s are} [is] created, the
-iterator_name is evaluated, and the denoted iterator object{s} become[s] the
-loop iterator{s}. In a forward generalized iterator, the operation First of the
-iterator type is called on the loop iterator, to produce the initial value for
-the loop parameter. If the result of calling Has_Element on the initial value is
-False, then the execution of the loop_statement is complete. Otherwise, the
-sequence_of_statements is executed and then the Next operation of the iterator
-type is called with the loop iterator and the current value of the loop
-parameter to produce the next value to be assigned to the loop parameter. This
-repeats until the result of calling Has_Element on the loop parameter is False,
-or the loop is left as a consequence of a transfer of control. For a reverse
-generalized iterator, the operations Last and Previous are called rather than
-First and Next.
-
-Add after 5.5.2(10/3)
-
-For a parallel generalized iterator, the operation Iterations
-of the iterator type is called first to determine the number of iterations
-associated with the iterator. If the result of calling Iterations is 0, then the
-execution of the loop_statement is complete. Otherwise, the operation Split of
-the iterator type is then called on a loop iterator, with the Advised_Split
-parameter value set to a value determined by the implementation that indicates a
-recommendation for the number of loop parameter objects that should be created.
-The result of the call to Split is a Chunk_Array object that indicates the
-number of loop parameter objects to be created by the implementation, as well as
-the range of cursor values to be uniquely associated with each loop parameter
-object. The number of loop parameters to be created is determined by calling
-Length operation of the Chunk_Array. The range of cursor values to be associated
-with each loop parameter is determined by calling the Start and Finish operation
-of the Chunk_Array object using an ordinal index value of the loop parameter
-object as the Index parameter for these calls. The result of calling the Start
-operation is the initial cursor value to be assigned to a given loop parameter
-object. The result of calling the Finish operation is the final cursor value to
-be iterated for a given loop parameter object. The sequence_of_statements is
-executed for each loop parameter object and then the Next operation of the
-iterator type is called with the loop iterator and the current value of the loop
-parameter to produce the next value to be assigned to a given loop parameter.
-This repeats until the value of the loop parameter is equal to the final cursor
-value associated with the given loop parameter, or the loop is left as a
-consequence of a transfer of control.
-
-AARM Note
-
-The Advised_Split parameter value is only a recommendation by the
-implementation. A container implementation may choose to ignore that
-recommendation if a more optimal split can be determined. For instance, a tree
-based container might create the split based on the number of branches at the
-top levels of the tree.
-
-Modify AARM 5.5.2(10.a/4)
-
-Ramification: The loop parameter{s} of a generalized iterator [is a]{are}
-variable{s} of which the user only has a constant view. It follows the normal
-rules for a variable of its nominal subtype. In particular, if the nominal
-subtype is indefinite, the variable is constrained by its initial value.
-Similarly, if the nominal subtype is class-wide, the variable (like all
-variables) has the tag of the initial value. Constraint_Error may be raised by a
-subsequent iteration if Next{, }[ or] Previous{, or Split} return an object with
-a different tag or constraint.
-
-Modify 5.5.2(11/3)
-
-For an array component iterator, the iterable_name is evaluated and the denoted
-array object becomes the array for the loop. If the array for the loop is a null
-array, then the execution of the loop_statement is complete. Otherwise, the
-sequence_of_statements is executed with [the] loop parameter{s that collectively
-denote} [denoting] each component of the array for the loop{. If the iterator is
-not a parallel array component iterator, the loop is iterated} using a canonical
-order of components, which is last dimension varying fastest (unless the array
-has convention Fortran, in which case it is first dimension varying fastest).
-For a forward array component iterator, the iteration starts with the component
-whose index values are each the first in their index range, and continues in the
-canonical order. For a reverse array component iterator, the iteration starts
-with the component whose index values are each the last in their index range,
-and continues in the reverse of the canonical order. {For a parallel array
-component iterator, the order of iteration is arbitrary.} The loop iteration
-proceeds until the sequence_of_statements has been executed for each component
-of the array for the loop, or until the loop is left as a consequence of a
-transfer of control.
-
-Modify 5.5.2(12/3)
-
-For a container element iterator, the iterable_name is evaluated and the denoted
-iterable container object becomes the iterable container object for the loop.
-The default iterator function for the type of the iterable container object for
-the loop is called on the iterable container object and the result is the loop
-iterator. [An object] {Objects} of the default cursor subtype [is]{are} created
-(the loop cursor{s}).
-
-Modify 5.5.2(13/3) [into three paragraphs]
-
-For a forward container element iterator, the operation First of the iterator
-type is called on the loop iterator, to produce the initial value for the loop
-cursor. If the result of calling Has_Element on the initial value is False, then
-the execution of the loop_statement is complete. Otherwise, the
-sequence_of_statements is executed with the loop parameter denoting an indexing
-(see 4.1.6) into the iterable container object for the loop, with the only
-parameter to the indexing being the current value of the loop cursor; then the
-Next operation of the iterator type is called with the loop iterator and the
-loop cursor to produce the next value to be assigned to the loop cursor. This
-repeats until the result of calling Has_Element on the loop cursor is False, or
-until the loop is left as a consequence of a transfer of control. For a reverse
-container element iterator, the operations Last and Previous are called rather
-than First and Next.{
-
-For a parallel container element iterator, the operation Iterations is first
-called to determine the number of iterations associated with the iterator. If
-the result of calling Iterations is 0, then the execution of the loop_statement
-is complete. Otherwise, the operation Split of the iterator type is then called
-on a loop iterator, with the Advised_Split parameter value set to a value
-determined by the implementation that indicates a recommendation for the number
-of loop parameter objects that should be created. The result of the call to
-Split is a Chunk_Array object that indicates the number of loop parameter
-objects to be created by the implementation, as well as the range of cursor
-values to be uniquely associated with each loop parameter object. The number of
-loop parameters to be created is determined by calling the Length operation of
-the Chunk_Array. The range of cursor values to be associated with each loop
-parameter is determined by calling the Start and Finish operation of the
-Chunk_Array object using an ordinal index value of the loop parameter object as
-the Index parameter for these calls. The result of calling the Start operation
-is the initial cursor value to be assigned to a given loop parameter object. The
-result of calling the Finish operation is the final cursor value to be iterated
-for a given loop parameter object. The sequence_of_statements is executed for
-each loop parameter object and then the Next operation of the iterator type is
-called with the loop iterator and the current value of the loop parameter to
-produce the next value to be assigned to a given loop parameter. This repeats
-until the value of the loop parameter is equal to the final cursor value
-associated with the given loop parameter, or the loop is left as a consequence
-of a transfer of control.
-
-}If the loop parameter is a constant  (see above), then the indexing uses the
-default constant indexing function for the type of the iterable container object
-for the loop; otherwise it uses the default variable indexing function.
-
-Modify 5.5.2(15/3)
-
---  example:
-{parallel}
-for Element of Board loop  -- See 3.6.1.
-   Element := Element * 2.0; -- Double each element of Board, a two-dimensional array.
-end loop;
-
-Add a new subclause 5.5.3
-
-5.5.3 User-Defined Parallel Loop Chunking for Discrete Types
-
-The following language-defined generic library package exists:
-
-with Ada.Iterator_Interfaces;
-with Ada.Containers;
-
-generic
-   type Loop_Index is (<>);
-package Ada.Discrete_Chunking is
-
-   pragma Preelaborate;
-   pragma Remote_Types;
-
-   function Has_Element (Position : Loop_Index) return Boolean is (True);
-
-   package Chunk_Array_Iterator_Interfaces is new
-     Ada.Iterator_Interfaces (Loop_Index, Has_Element);
-
-   function Split
-     (Chunks : Natural;
-      From   : Loop_Index := Loop_Index'First;
-      To     : Loop_Index := Loop_Index'Last)
-   return Chunk_Array_Iterator_Interfaces.Chunk_Array'Class
-     with Pre => Chunks <= Loop_Index'Pos(To) - Loop_Index'Pos(From) + 1,
-          Nonblocking => False;
-
-private
-   ... -- not specified by the language
-end Ada.Discrete_Chunking;
-
-   function Split
-     (Chunks : Positive;
-      From   : Loop_Index := Loop_Index'First;
-      To     : Loop_Index := Loop_Index'Last)
-   return Chunk_Array_Iterator_Interfaces.Chunk_Array'Class
-     with Pre => Chunks <= Loop_Index'Pos(To) - Loop_Index'Pos(From) + 1;
-
-Split returns a Chunk_Array object (see 5.5.1) for user-defined parallel
-iteration over a range of values of a discrete subtype starting with the value
-From and ending with the value To. The Chunks value indicates the number of
-Executors (see 9.12) to be associated with the parallel loop, which equals the
-value returned by calling the Length operation on the Chunk_Array result.
-
-Examples
-
-  declare
-     package Manual_Chunking is new Ada.Discrete_Chunking (Integer);
-
-     Chunks : constant
-        Manual_Chunking.Chunk_Array_Iterator_Interfaces.Chunk_Array'Class :=
-          Manual_Chunking.Split (Chunks => 4);
-  begin
-     parallel
-     for Chunk in 1 .. Chunks.Length loop
-        declare
-           File : Text_IO.File_Type;
-        begin
-           Text_IO.Create(File => File,
-                          Name => Natural'Image(Chunk) & ".txt");
-
-           for I in Chunks.Start(Chunk) .. Chunks.Finish(Chunk) loop
-              Put_Line (Integer'Image(I) & "=" & Integer'Image (A(I));
-           end loop;
-
-           Text_IO.Close(File);
-        end;
-     end loop;
-  end;
-
 Add a new subclause
 
 5.6.1 Parallel Block Statements
@@ -602,7 +228,7 @@
 
 Legality Rules
 
-A parallel_block_statement shall not update variables global to the loop unless
+A parallel_block_statement shall not update variables global to the statement unless
 the action is sequential (see 9.10).
 
 A handled_sequence_of_statements of a parallel_block_statement shall not consist
@@ -692,304 +318,6 @@
 A parallel block statement or parallel loop statement may assign a set of
 executors to execute the construct, if extra computing resources are available.
 
-Add after 11.5(20)
-
-Loop_Parameter_Check
-  For a parallel loop, check that updates to a component of an array or to an
-  element of a container via the loop parameter are sequential. See 9.10.
-
-Modify A.18.2(74.1/3)
-
-function Iterate (Container : in Vector)
-      return Vector_Iterator_Interfaces.{Parallel_}Reversible_Iterator'Class;
-
-Modify A.18.2(74.2/3)
-
-function Iterate (Container : in Vector; Start : in Cursor)
-      return Vector_Iterator_Interfaces.{Parallel_}Reversible_Iterator'Class;
-
-Modify A.18.2(230.1/3)
-
-function Iterate (Container : in Vector)
-   return Vector_Iterator_Interfaces.{Parallel_}Reversible_Iterator'Class;
-
-Modify A.18.2(230.2/3)
-
-Iterate returns a {parallel} reversible iterator object (see 5.5.1) that will
-generate a value for [a] loop parameter{s} (see 5.5.2) designating each node in
-Container, starting with the first node and moving the cursor as per the Next
-function when used as a forward iterator, and starting with the last node and
-moving the cursor as per the Previous function when used as a reverse iterator
-{, and starting with all nodes simultaneously using the Split function
-to generate cursors for all the iterations of the loop when used as a parallel
-iterator}. Tampering with the cursors of Container is prohibited while the
-iterator object exists (in particular, in the sequence_of_statements of the
-loop_statement whose iterator_specification denotes this object). The iterator
-object needs finalization.
-
-Modify A.18.2(230.3/3)
-
-function Iterate (Container : in Vector; Start : in Cursor)
-   return Vector_Iterator_Interfaces.{Parallel_}Reversible_Iterator'Class;
-
-Modify A.18.2(230.4/3)
-
-If Start is not No_Element and does not designate an item in Container, then
-Program_Error is propagated. If Start is No_Element, then Constraint_Error is
-propagated. Otherwise, Iterate returns a {parallel }reversible iterator object
-(see 5.5.1) that will generate a value for [a] loop parameter{s} (see 5.5.2)
-designating each node in Container, starting with the node designated by Start
-and moving the cursor as per the Next function when used as a forward iterator,
-or moving the cursor as per the Previous function when used as a reverse
-iterator {, or all nodes simultaneously using the Split function when used as a
-parallel iterator}. Tampering with the cursors of Container is prohibited while
-the iterator object exists (in particular, in the sequence_of_statements of the
-loop_statement whose iterator_specification denotes this object). The iterator
-object needs finalization.
-
-Modify A.18.3(46.1/3)
-
-function Iterate (Container : in List)
-      return List_Iterator_Interfaces.{Parallel_}Reversible_Iterator'Class;
-
-Modify A.18.3(46.2/3)
-
-function Iterate (Container : in List; Start : in Cursor)
-      return List_Iterator_Interfaces.{Parallel_}Reversible_Iterator'Class;
-
-Modify A.18.3(144.1/3)
-
-function Iterate (Container : in List)
-   return List_Iterator_Interfaces.{Parallel_}Reversible_Iterator'Class;
-
-Modify A.18.3(144.2/3)
-
-Iterate returns a {parallel }reversible iterator object (see 5.5.1) that will
-generate a value for [a] loop parameter{s} (see 5.5.2) designating each node in
-Container, starting with the first node and moving the cursor as per the Next
-function when used as a forward iterator, and starting with the last node and
-moving the cursor as per the Previous function when used as a reverse iterator
-{, and starting with all nodes simultaneously using the Split function to
-generate cursors for all the iterations of the loop when used as a parallel
-iterator}. Tampering with the cursors of Container is prohibited while the
-iterator object exists (in particular, in the sequence_of_statements of the
-loop_statement whose iterator_specification denotes this object). The iterator
-object needs finalization.
-
-Modify A.18.3(144.3/3)
-
-function Iterate (Container : in List; Start : in Cursor)
-   return List_Iterator_Interfaces.Parallel_Reversible_Iterator'Class;
-
-Modify A.18.3(144.4/3)
-
-If Start is not No_Element and does not designate an item in Container, then
-Program_Error is propagated. If Start is No_Element, then Constraint_Error is
-propagated. Otherwise, Iterate returns a {parallel} reversible iterator object
-(see 5.5.1) that will generate [a] value{s} for [a] loop parameter{s} (see
-5.5.2) designating each node in Container, starting with the node designated by
-Start and moving the cursor as per the Next function when used as a forward
-iterator, or moving the cursor as per the Previous function when used as a
-reverse iterator {or all nodes simultaneously using the Split function when used
-as a parallel iterator}. Tampering with the cursors of Container is prohibited
-while the iterator object exists (in particular, in the sequence_of_statements
-of the loop_statement whose iterator_specification denotes this object). The
-iterator object needs finalization.
-
-Modify A.18.5(37.1/3)
-
-function Iterate (Container : in Map)
-      return Map_Iterator_Interfaces.{Parallel_}[Forward_]Iterator'Class;
-
-Modify A.18.5(61.1/3)
-
-function Iterate (Container : in Map)
-   return Map_Iterator_Interfaces.{Parallel}[Forward]_Iterator'Class;
-
-Modify A.18.5(61.2/3)
-
-Iterate returns a[n] {parallel} iterator object (see 5.5.1) that will generate
-[a] value{s} for [a] loop parameter{s} (see 5.5.2) designating each node in
-Container, starting with the first node and moving the cursor according to the
-successor relation {when used as a forward iterator, and starting with all nodes
-simultaneously using the Split function to generate cursors for all the
-iterations of the loop when used as a parallel iterator}. Tampering with the
-cursors of Container is prohibited while the iterator object exists (in
-particular, in the sequence_of_statements of the loop_statement whose
-iterator_specification denotes this object). The iterator object needs
-finalization.
-
-Modify A.18.6(51.1/3)
-
-function Iterate (Container : in Map)
-      return Map_Iterator_Interfaces.{Parallel_}Reversible_Iterator'Class;
-
-Modify A.18.6(51.2/3)
-
-function Iterate (Container : in Map; Start : in Cursor)
-      return Map_Iterator_Interfaces.{Parallel_}Reversible_Iterator'Class;
-
-Modify A.18.6(94.1/3)
-
-function Iterate (Container : in Map)
-   return Map_Iterator_Interfaces.{Parallel_}Reversible_Iterator'Class;
-
-Modify A.18.6(94.2/3)
-
-Iterate returns a {parallel} reversible iterator object (see 5.5.1) that will
-generate [a] value{s} for [a] loop parameter{s} (see 5.5.2) designating each
-node in Container, starting with the first node and moving the cursor according
-to the successor relation when used as a forward iterator, and starting with the
-last node and moving the cursor according to the predecessor relation when used
-as a reverse iterator {, and starting with all nodes simultaneously using the
-Split function to generate cursors for all the iterations of the loop when used
-as a parallel iterator}. Tampering with the cursors of Container is prohibited
-while the iterator object exists (in particular, in the sequence_of_statements
-of the loop_statement whose iterator_specification denotes this object). The
-iterator object needs finalization.
-
-Modify A.18.6(94.3/3)
-
-function Iterate (Container : in Map; Start : in Cursor)
-   return Map_Iterator_Interfaces.{Parallel_}Reversible_Iterator'Class;
-
-Modify A.18.6(94.4/3)
-
-If Start is not No_Element and does not designate an item in Container, then
-Program_Error is propagated. If Start is No_Element, then Constraint_Error is
-propagated. Otherwise, Iterate returns a {parallel} reversible iterator object
-(see 5.5.1) that will generate [a] value{s} for [a] loop parameter{s} (see
-5.5.2) designating each node in Container, starting with the node designated by
-Start and moving the cursor according to the successor relation when used as a
-forward iterator, or moving the cursor according to the predecessor relation
-when used as a reverse iterator {, or all nodes simultaneously using the Split
-function when used as a parallel iterator}. Tampering with the cursors of
-Container is prohibited while the iterator object exists (in particular, in the
-sequence_of_statements of the loop_statement whose iterator_specification
-denotes this object). The iterator object needs finalization.
-
-Modify A.18.8(49.1/3)
-
-function Iterate (Container : in Set)
-      return Set_Iterator_Interfaces.{Parallel}[Forward]_Iterator'Class;
-
-Modify A.18.8(85.1/3)
-
-function Iterate (Container : in Set)
-   return Set_Iterator_Interfaces.{Parallel}[Forward]_Iterator'Class;
-
-Modify A.18.8(85.2/3)
-
-Iterate returns a[n] {parallel} iterator object (see 5.5.1) that will generate
-[a] value{s} for [a] loop parameter{s} (see 5.5.2) designating each element in
-Container, starting with the first element and moving the cursor according to
-the successor relation {when used as a forward iterator, and starting with all
-nodes simultaneously using the Split function to generate cursors for all the
-iterations of the loop when used as a parallel iterator.} Tampering with the
-cursors of Container is prohibited while the iterator object exists (in
-particular, in the sequence_of_statements of the loop_statement whose
-iterator_specification denotes this object). The iterator object needs
-finalization.
-
-Modify A.18.9(61.1/3)
-
-function Iterate (Container : in Set)
-      return Set_Iterator_Interfaces.{Parallel_}Reversible_Iterator'Class;
-
-Modify A.18.9(61.2/3)
-
-function Iterate (Container : in Set; Start : in Cursor)
-      return Set_Iterator_Interfaces.{Parallel_}Reversible_Iterator'Class;
-
-Modify A.18.9(113.1/3)
-
-function Iterate (Container : in Set; Start : in Cursor)
-      return Set_Iterator_Interfaces.{Parallel_}Reversible_Iterator'Class;
-
-Modify A.18.9(113.2/3)
-
-Iterate returns a {parallel} reversible iterator object (see 5.5.1) that will
-generate [a] value{s} for [a] loop parameter{s} (see 5.5.2) designating each
-element in Container, starting with the first element and moving the cursor
-according to the successor relation when used as a forward iterator, and
-starting with the last element and moving the cursor according to the
-predecessor relation when used as a reverse iterator {, and starting with all
-nodes simultaneously using the Split function to generate cursors for all the
-iterations of the loop when used as a parallel iterator}. Tampering with the
-cursors of Container is prohibited while the iterator object exists (in
-particular, in the sequence_of_statements of the loop_statement whose
-iterator_specification denotes this object). The iterator object needs
-finalization.
-
-Modify A.18.9(113.3/3)
-
-function Iterate (Container : in Set; Start : in Cursor)
-   return Set_Iterator_Interfaces.{Parallel_}Reversible_Iterator'Class;
-
-Modify A.18.9(113.4/3)
-
-If Start is not No_Element and does not designate an item in Container, then
-Program_Error is propagated. If Start is No_Element, then Constraint_Error is
-propagated. Otherwise, Iterate returns a {parallel} reversible iterator object
-(see 5.5.1) that will generate [a] value{s} for [a] loop parameter{s} (see 5.5.2)
-designating each element in Container, starting with the element designated by
-Start and moving the cursor according to the successor relation when used as a
-forward iterator, or moving the cursor according to the predecessor relation
-when used as a reverse iterator {, or all nodes simultaneously using the Split
-function when used as a parallel iterator}. Tampering with the cursors of
-Container is prohibited while the iterator object exists (in particular, in the
-sequence_of_statements of the loop_statement whose iterator_specification
-denotes this object). The iterator object needs finalization.
-
-Modify A.18.10(44/3)
-
-function Iterate (Container : in Tree)
-      return Tree_Iterator_Interfaces.{Parallel}[Forward]_Iterator'Class;
-
-Modify A.18.10(45/3)
-
-function Iterate_Subtree (Position : in Cursor)
-      return Tree_Iterator_Interfaces.{Parallel}[Forward]_Iterator'Class;
-
-Modify A.18.10(156/3)
-
-function Iterate (Container : in Tree)
-   return Tree_Iterator_Interfaces.{Parallel}[Forward]_Iterator'Class;
-
-Modify A.18.10(157/4)
-
-Iterate returns a[n] {parallel} iterator object (see 5.5.1) that will generate
-[a] value{s} for [a] loop parameter{s} (see 5.5.2) designating each element node
-in Container, starting from with the root node and proceeding in a depth-first
-order {when used as a forward_iterator, and starting with all nodes
-simultaneously using the Split function to generate cursors for all the
-iterations of the loop when used as a parallel iterator}. Tampering with the
-cursors of Container is prohibited while the iterator object exists (in
-particular, in the sequence_of_statements of the loop_statement whose
-iterator_specification denotes this object). The iterator object needs
-finalization.
-
-Modify A.18.10(158/3)
-
-function Iterate_Subtree (Position : in Cursor)
-   return Tree_Iterator_Interfaces.{Parallel}[Forward]_Iterator'Class;
-
-Modify A.18.10(159/3)
-
-If Position equals No_Element, then Constraint_Error is propagated. Otherwise,
-Iterate_Subtree returns a[n] {parallel} iterator object (see 5.5.1) that will
-generate [a] value{s} for [a] loop parameter{s} (see 5.5.2) designating each
-element in the subtree rooted by the node designated by Position, starting from
-with the node designated by Position and proceeding in a depth-first order {when
-used as a forward iterator, or all nodes simultaneously using the Split function
-when used as a parallel iterator}. If Position equals No_Element, then
-Constraint_Error is propagated. Tampering with the cursors of the container that
-contains the node designated by Position is prohibited while the iterator object
-exists (in particular, in the sequence_of_statements of the loop_statement whose
-iterator_specification denotes this object). The iterator object needs
-finalization.
-
-
 Add after C.7.1(5)
 
 The Task_Id value associated with each handled_sequence_of_statements of a
@@ -1000,26 +328,6 @@
 sequence_of_statements of a parallel loop are treated as though they are all
 executing as the task that encountered the parallel construct.
 
-Add after D.16(5/3)
-
-   type Iteration_Count is range 0 .. implementation-defined;
-   for Iteration_Count'Size use implementation-defined;
-
-   type Split_Count is range 0 .. implementation-defined;
-
-   function Advised_Split_Count
-     (Iterations :  Iteration_Count) return Split_Count
-       witn Non_Blocking => False;
-
-Add after D.16(8/3)
-
-The Advised_Split_Count function accepts a parameter that indicates the number
-of iterations associated with a parallel loop, and returns a recommended value
-for the number of loop parameter objects to be associated with a parallel loop
-statement. Such a value is intended to be passed as an actual for the
-Advised_Split parameter of the Split operation associated with a parallel
-iterator object (see 5.5.1).
-
 !discussion
 
 There is a continuing trend of exponential growth of computational
@@ -1164,39 +472,6 @@
 achieve that end, but a reduction expression seems better suited since it is
 designed to produce a result value.
 
-We extended the parallel loop capability to work with containers as well as arrays,
-since there could be a need to iterate in parallel over any of the standard
-containers. Containers such as vectors are obvious candidates for parallelisation,
-since it is easy to conceptually think of a vector as a being splittable into
-a number of smaller vectors, and then applying a divide and conquer approach to
-the vector subsets. However, even a sequentially accessed container such as a
-linked list can be iterated in parallel, if cursors for each parallel executor
-can be obtained prior to execution of the loop. This typically involves iterating
-once through the container to obtain the cursors, but can still be benefit from
-parallel processing if the amount of time to process each node in the loop is
-significantly greater than the amount of time needed to iterate through the list.
-
-Sometimes there are loops that need initialization or finalization for each
-executor, that might be too expensive to apply for each iteration, but would be
-worthwhile if applied once per chunk of execution. An example might be where
-a file needs to be opened for each executor where the loop writes results to
-the file, and after the executor completes its chunk, the file needs to be closed.
-Other possible uses include memory allocation for temporary data structures.
-
-Such loops would require manual chunking, where the user code explicitly calls
-the Split function of a Parallel iterator to obtain the Chunk_Array object that
-normally the implementation would request. This allows the user to express the
-parallelism more explicitly by writing an outer loop that iterates through the
-number of chunks and an inner loop that iterates through the elements of each
-chunk.
-
-Since this capability exists for the containers, as all the containers have an
-Iterate primitive that return a parallel iterator object that can be used to
-obtain a chunk array, it was felt the same capability should exist for discrete
-types, so the package Ada.Discrete_Chunking was added to this AI, which simply
-creates a parallel iterator and calls its Split operation to obtain a chunk array
-that can be used with any given discrete type.
-
 !ASIS
 
 ** TBD.
@@ -7387,4 +6662,84 @@
  
 Thank you in advance.
  
+***************************************************************
+
+From: Brad Moore
+Sent: Wednesday, March 28, 2018  12:03 AM
+
+Here is an update to AI12-0119. [This is version /08 - ED].
+
+It is now much smaller, with manual chunking, container iterators, and
+data-race/deadlocking specific items moved into new separate AI's. Otherwise,
+the text hasn't changed much except addressed a few typos that were mentioned
+at the last teleconference call.
+
+***************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, March 28, 2018  9:10 PM
+
+Thanks, Brad.  As I mentioned in my comments on one of the other AIs, probably
+should remove the no-data-race, no blocking from this AI, since it is covered
+by a separate one.
+
+Separating out these pieces has really helped, and I think the wording is
+starting to converge.  However, I was struck by this bit of wording:
+
+  "A parallel block statement requests that two or more sequences of
+   statements should execute in parallel with each other."
+
+I find it a bit odd to describe a construct as "requesting" something.
+
+We generally just try to describe what a construct does, as opposes to what it
+"requests."
+
+I would suggest you take a look at the introduction to chapter 9.  I suspect
+we will need to introduce the notion of "tasklet" somewhere.  I am thinking 
+that perhaps all of these things should be described somewhere in chapter 9,
+even if some of the syntax appears earlier.  If we don't coordinate the
+definition of parallel block and tasklet with the introduction to tasks in
+chapter 9, the result is probably going to be very confusing, since chapter 9
+is where we talk about threads of control.  So I think that argues for having
+a separate section somewhere in chapter 9 on tasklets, and in that section
+introduce parallel blocks and loops.  And the introduction to chapter 9 will
+need to set the stage for the discussion on tasklets, even if we don't go into
+the details until a bit later in a section devoted to tasklets.
+
+***************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, March 29, 2018  6:15 PM
+
+I'm not sure I agree. He does define the tasklet semantics in chapter 9 (in 
+9.12, specifically). It probably wouldn't hurt to mention that in the
+introduction to chapter 9, too. [Oops, "Clause 9" if we're following current
+ISO-speak. :-)]
+
+OTOH, I don't think we want to hide the actual parallel blocks and loops in 
+Clause 9. Everyone "knows" that writing programs with tasks is hard, and 
+putting the parallel stuff there says that the same is true of them. Putting 
+them with the basic statements signals that these are "easy" (there's nothing
+easier in Ada than Chapter 5!). Yes, that's marketing more than any major 
+semantic consideration -- but we all know that marketing and appearances 
+matter. That does require deferring some of the rules until the tasklet 
+subclause, and/or forward references. But it would seem very odd to have 
+basic blocking and looping constructs away from the rest of those constructs.
+(And we hope/expect that parallel programming will get to be very basic during
+the lifetime of Ada 2020.)
+
+In some sense, this is very similar to your argument that eventually compilers
+will handle a lot of parallelism under the covers. A parallel block or loop
+itself is just an assertion that the block or loop can be executed in parallel
+(without regard to whether that "works" in an as-if optimization, but possibly
+with checking that it is OK). Otherwise, they are just another control
+structure.
+
+So I think the current organization is approximately right (details to be 
+determined). This obviously is a "squishy" argument and this organization is
+not a big deal -- but we need to consider how this will look in 30 years. We
+don't want to hide basic control flow in an otherwise little-used clause
+(explicit tasks would be rare in a world where a lot of parallelism is applied
+automatically or by simple declarations).
+
 ***************************************************************

Questions? Ask the ACAA Technical Agent