To: J3 J3/14-104 From: Reinhold Bader Subject: Alternate suggestion for changes to counted events Date: 2014 January 20 References: N1996, N1999 Discussion: ~~~~~~~~~~~ Nick MacLaren in his vote has pointed out that counted events still suffer from incomplete specification in the TS draft, leading to variant interpretations and possibly to a circular definition. While there exists the fallback of permitting binary semaphores only, the latter cause sufficiently much clutter in code that can profit from counted events that I feel it is worth the trouble to retain them. Therefore, this paper suggests adding suitable gatekeeper semantics to EVENT WAIT, as well as removing the STAT_POSTED_IMAGE and the MAX_COUNT feature. The way to retain counted events is based on Bill Long's suggestion of allowing an UNTIL_COUNT on EVENT WAIT, but the rule is added that the number of otherwise unordered posts to that wait must be exactly the UNTIL_COUNT. Without an UNTIL_COUNT events effectively are binary semaphores (i.e. the UNTIL_COUNT has a default value 1). This change renders example A.2.2 invalid. Also the following code given by Nick Maclaren in his vote is invalid if the IF statement on image 2 is executed: INTEGER :: x[*] On image 1 On image 2 POST EVENT (q[2]) CALL EVENT_QUERY (q, n) x[3] = 123 IF (n >= 2) THEN POST EVENT (q[2]) WAIT EVENT (q) x[3] = 456 END IF Edits to N1996: ~~~~~~~~~~~~~~~ Section 6.2: Replace [15:8-9], "An event variable ... event variable." by "An event variable has a count that is updated by execution of EVENT POST or EVENT WAIT statements. The effect of each change is as if it occurred instantaneously, without any overlap with another change." [[Details of the update procedure are described in 6.3 and 6.4.]] Replace [15:10], "The processor shall support ... HUGE(0)." by "An event variable has a threshold that describes the maximum value of the event count. The initial value for this threshold is at least HUGE(0). The threshold is updated by execution of an EVENT WAIT statement. A sequence of updates of event counts and thresholds shall not at any time during execution of the program cause the event count to exceed the event threshold." Section 6.3 [15:24] Replace "post-spec-list" by "sync-stat-list" [15:26-27] Delete R603 [15:29] After "variable's count" add "by 1". [15:30-33] Delete "If the MAX_COUNT ... (6.5)." Section 6.4 [16:3] Replace "sync-stat-list" by "wait-spec-list" and insert a new line "R604+ wait-spec is UNTIL_COUNT = scalar_int_expr or sync-stat Replace [16:5-7] by "Execution of an EVENT WAIT statement causes the following sequence of actions: (1) the threshold of its event argument is set to UNTIL_COUNT if this specifier is provided with a positive value, and to 1 otherwise, (2) the executing image waits until the count of the event variable reaches its threshold value or an error condition occurs, (3) if no error condition occurs, the event count is decreased by its threshold value, [[from this point onward it is unlikely that the implementation can detect incorrect excess posts without additional effort, but this is not a requirement anyway. Note that for reasoning about the correctness of the program all possible interleavings of changes to the count must be inspected.]] (4) the threshold of its event argument is set to its default value, (5) a new segment starts execution." [[I put (5) there for clarity. Perhaps analogous text should be added to EVENT POST?]] Delete [16:8-10] "During execution ... another change" [[was moved to section 6.2]]. Replace text of NOTE 6.2 by "The segment that follows the execution of an EVENT WAIT statement is ordered with respect to exactly n segments that precede EVENT POST statements that caused prior changes in the sequence of values of the event count variable, where n is the event threshold value determined by that EVENT WAIT statement. If a further post to the same event is executed by the program, it is the programmer's responsibility to ensure that the segment preceding such a post is ordered after the segment preceding that EVENT WAIT statement." [16:14-19] Delete section 6.5. Section 7 [23:40] After "successful waits", add " without an UNTIL_COUNT specification". Section 8 [[I think none are needed but have not checked very thoroughly.]] Annex A [38:45-39:17] Replace example A.2.2 by John Reid's tree code: "A tree is a graph in which every node except one has a single "parent" node to which it is connected by an edge. The node without a parent is the "root". The nodes that has a given node as parent are the "children" of that node. The root is at level 1, its children are at level 2, etc. A multifrontal code to solve a sparse set of linear equations involves a tree. Work at a node starts after work at all its children is complete and their data has been passed to it. Here we assume that all the nodes have been assigned to images. Each image has a list of its nodes and these are ordered in decreasing tree level (all those at level L preceding those at level L-1). For each node, array elements hold the number of children, details about the parent and an event variable. This allows the processing to proceed asynchrononously subject to the rule that a parent must wait for all its children as follows: PROGRAM TREE USE, INTRINSIC :: ISO_FORTRAN_ENV INTEGER,ALLOCATABLE :: NODE(:) ! Tree nodes that this image handles INTEGER,ALLOCATABLE :: NC(:) ! NODE(I) has NC(I) children INTEGER,ALLOCATABLE :: PARENT(:), SUB(:) ! The parent of NODE(I) is NODE(SUB(I))[PARENT(I)] TYPE(EVENT_TYPE),ALLOCATABLE :: DONE(:)[*] INTEGER :: I, J, STATUS ! Set up the tree, including allocation of all arrays. DO I = 1, SIZE(NODE) ! Wait for children to complete EVENT_WAIT(DONE(I),UNTIL_COUNT=NC(I),STAT=STATUS) IF (STATUS/=0) EXIT ! Process node, using data from children IF (PARENT(I)>0) THEN ! Node is not the root. ! Place result on image PARENT(I) for node NODE(SUB)[PARENT(I)] ! Tell PARENT(I) that this has been done. EVENT_POST(DONE(SUB(I))[PARENT(I)],STAT=STATUS) IF (STATUS/=0) EXIT END IF END DO END PROGRAM TREE" Further remarks: ~~~~~~~~~~~~~~~~ Nick Maclaren has commented the following on the draft of this paper sent to the coarray-ts mailing list: ---- Subject to the following changes, I think that it is unambiguous and non-circular. I am still not keen on events, but that is a lesser matter. >Replace [15:10], "The processor shall support ... HUGE(0)." by >"An event variable has a threshold that describes the maximum > value of the event count. The initial value for > this threshold is at least HUGE(0). The threshold is > updated by execution of an EVENT WAIT statement. > > A sequence of updates of event counts and thresholds shall not > at any time during execution of the program cause the event count > to exceed the event threshold." Grrk. That makes sense only if the threshold is an attribute of the event. From what you post below, you seem to be assuming that the EVENT WAIT precedes the EVENT POSTs, which is another form of circularity! I suggest dropping the last paragraph, in your model. >Replace [16:5-7] by > >"Execution of an EVENT WAIT statement causes the following > sequence of actions: > (1) the threshold of its event argument is set to UNTIL_COUNT > if this specifier is provided with a positive value, > and to 1 otherwise, Removing "of its event argument" from the above action (1), and adding: (*) if the event count exceeds the threshold, an error condition occurs, > (2) the executing image waits until the count of the event > variable reaches its threshold value or an error condition > occurs, > (3) if no error condition occurs, the event count is decreased > by its threshold value, > [[from this point onward it is unlikely that the implementation > can detect incorrect excess posts without additional effort, > but this is not a requirement anyway. Note that for reasoning > about the correctness of the program all possible interleavings > of changes to the count must be inspected.]] > (4) the threshold of its event argument is set to its > default value, And removing action (4). > (5) a new segment starts execution." >[[I put (5) there for clarity. Perhaps analogous text > should be added to EVENT POST?]] --- These seem to indicate that the threshold should not be part of the event state, but only maintained while EVENT WAIT is executing. However I don't see the point Nick makes about my model implicitly assuming the EVENT WAIT starting before the posts do.