Version 1.6 of ai12s/ai12-0344-1.txt
!standard 5.5.3(16/5) 20-06-09 AI12-0344-1/03
!standard 5.5.3(20/5)
!standard 5.5.3(22/5)
!standard 9.10.1(22/5)
!standard H.4(12)
!class Amendment 19-09-30
!status work item 19-09-30
!status received 19-08-19
!priority Low
!difficulty Easy
!subject Procedural iterator aspects
!summary
Allows_Exit and Parallel_Iterator can only be applied to subprograms with
a single access parameter of an access-to-subprogram type.
Aspect Parallel_Calls is defined to check that a subprogram can be called
in parallel.
The No_Exceptions restriction also disallows use of early exits from
procedural iterators.
!problem
The legality requirement for Allows_Exit and Parallel_Iterator aspects says
that the callable entity shall have at least one parameter of an anonymous
access-to-subprogram type. If there are multiple such parameters, how do we
know which parameter is the "loop body procedure" which is mentioned in the
description of the semantics of the aspects?
If the user explicitly passes a subprogram to a subprogram with
Parallel_Iterator => True, there is no checking on that subprogram
(unlike what happens when the subprogram is used in a procedural
iterator loop).
If the No_Exceptions restriction is in place (see H.4(12)), the
implementation should not be expected to support an early exit from a
procedural iterator, as that is likely to use some mechanism based on,
or similar to, exception handling.
!proposal
(See Summary.)
!wording
Add after 5.5.3(15/5):
In a procedural iterator, the Parallel_Calls aspect (see 9.10.1) of
the loop body procedure is True if the reserved word parallel occurs
in the corresponding loop statement, and False otherwise.
Modify 5.5.3(16/5):
The following aspects may be specified for a callable entity S that
has {exactly}[at least] one formal parameter of an anonymous
access-to-subprogram type:
Add after 5.5.3(22/5):
If the actual parameter of an anonymous access-to-subprogram type,
passed in an explicit call of a subprogram for which the
Parallel_Iterator aspect is True, is of the form P'Access, the
designated subprogram P shall have a Parallel_Calls aspect True (see
9.10.1).
Add after 9.10.1(22/5):
The following aspect can be specified for a subprogram P:
Parallel_Calls
The Parallel_Calls aspect is of type Boolean. The specified value
shall be static. The Parallel_Calls aspect of an inherited primitive
subprogram is True if Parallel_Calls is True either for the
corresponding subprogram of the progenitor type or for any other
inherited subprogram that it overrides. If not specified or
inherited as True, the Parallel_Calls aspect of a subprogram is
False.
Specifying the Parallel_Calls aspect to be True for a subprogram
indicates that the subprogram can be safely called in parallel.
Conflict checks (if required by the Conflict_Check_Policy in effect)
are made on the subprogram assuming that multiple concurrent calls
exist. [Redundant: Such checks need not be repeated at each call of the
subprogram in a parallel iteration context.]
Modify RM H.4(12):
No_Exceptions
Raise_statements and exception_handlers are not allowed. No
language-defined runtime checks are generated; however, a
runtime check performed automatically by the hardware is
permitted. {The callable entity associated with a
procedural_iterator (see 5.5.3) is considered to not allow exit,
independent of the value of its Allows_Exit aspect.}
!discussion
As indicated in the !problem, to prevent ambiguity, we limit the aspects
Allows_Exit and Parallel_Iterator to subprograms with a single parameter
of an anonymous access-to-subprogram type. We allow both access-to-function
and access-to-procedure parameters, as these capabilities might be
relevant in constructs where a function rather than a
procedure is being called repeatedly. (Such as a parallel aggregate, if such
a thing exists.)
We add a new aspect, Parallel_Calls, to apply to subprograms that are
expected to be called by a subprogram with the Parallel_Iterator aspect,
or to be called in other parallel iteration contexts. Such a subprogram
is checked according to the Confict_Check_Policy in effect, to determine
whether it can be safely called concurrently. This enables some conflict
checking to be performed modularly, without relying on a specified
Global aspect.
Some concerns about implementability of an early exit from a procedural
iterator have been expressed, particularly in target environments where
exception handling is not supported. We therefore make the
No_Exceptions restriction also disallow early exits from procedural
iterators, as it is likely that such early exits will depend on some
sort of mechanism resembling exception handling.
!ASIS
None.
!ACATS test
ACATS B-Tests are needed to check that the new rules are enforced. One could
imagine a C-Test that Parallel_Calls works, but that is the normal case for
a parallel procedural iterator, so any test will check that.
!appendix
From: Tucker Taft
Sent: Monday, August 19, 2019 8:46 PM
I believe we have a bug in the legality requirement for Allows_Exit and
Parallel_Iterator aspects. It currently says that the callable entity
shall have at least one parameter of an anonymous access-to-subprogram type.
I don't think that really makes sense. I think we should say "exactly one"
because otherwise how do we know which parameter is the "loop body procedure"
which is mentioned in the description of the semantics of the aspects.
****************************************************************
From: Steve Baird
Sent: Tuesday, August 20, 2019 3:55 PM
Makes sense.
****************************************************************
From: Tucker Taft
Sent: Wednesday, August 21, 2019 6:37 PM
The latest version of AI12-0326-2 introduces the Parallel_Iterator aspect as
part of a parallel procedural iterator. If you explicitly call a procedure
with Parallel_Iterator => True rather than as part of a parallel procedural
iterator, it seems that we might want to impose a requirement on the procedure
passed as an access-to-subp parameter (which corresponds to the "loop body
procedure" created implicitly by the compiler).
My suggestion is that we require that this procedure have aspect
Parallel_Calls => True. This will indicate that the programmer recognized
this routine would be called in parallel, and would cause the compiler to
check that this procedure can safely be called in parallel with itself,
i.e. re-entrantly, if required by the Conflict_Check_Policy in effect at the
point of declaration. Even if no conflict checks are being performed, the
presence of this aspect would indicate the programmer knew (and the reader
will learn) it might be used in such a context.
When the compiler implicitly creates such a "loop body" procedure, it can
also implicitly set Parallel_Calls => True.
This came up because I am doing hand-expansions of various examples that use
parallel procedural iterators, and it seemed odd that there was no checking
implied. I suppose we could liberalize this a bit to say that either
Parallel_Calls => True, or any Global beyond "null" is synchronized.
****************************************************************
From: Brad Moore
Sent: Saturday, August 24, 2019 10:52 PM
>> ...
>> My reasoning for having the Process parameter first is that all my
>> library calls have a Process parameter.
>> It is the only common parameter, so it makes sense to have it as the
>> first parameter for consistency.
>
> The proposed syntax for the procedural iterator allows you to omit the
> "<>" if the "process" parameter is last, which is the reason I put it last.
[The above quote is from a thread filed in AI12-0357-1. - Editor.]
And from another recent email....
> I believe we have a bug in the legality requirement for Allows_Exit
> and Parallel_Iterator aspects. It currently says that the callable
> entity shall have at least one parameter of an anonymous
> access-to-subprogram type. I don't think that really makes sense. I
> think we should say "exactly one" because otherwise how do we know
> which parameter is the "loop body procedure" which is mentioned in the
> description of the semantics of the aspects.
My question is, if we are changing this to only allow "exactly one" parameter
of an anonymous access-to-subprogram type, then it seems a bit of a weird
restriction that it has to be the last parameter to allow omitting the <>.
If there can only be one such parameter, why not allow omitting the <>
regardless of which parameter it is?
****************************************************************
From: Tucker Taft
Sent: Sunday, August 25, 2019 7:47 AM
Interesting point. Worth discussing at the ARG meeting, if not before. I
was suggesting it being a requirement only when Allows_Exit or
Parallel_Iterator is specified True, but it is not a big leap to make it a
general requirement for any use of the procedural iterator.
****************************************************************
From: Tucker Taft
Sent: Sunday, April 19, 2020 9:23 PM
Given concerns about the use of an exception-like mechanism to implement the
"Allows_Exit" feature of procedural iterators, I would suggest we add to the
description of the No_Exceptions restriction the following:
RM H.4(12):
No_Exceptions
Raise_statements and exception_handlers are not allowed. No language-
defined runtime checks are generated; however, a runtime check
performed automatically by the hardware is permitted. {The callable
entity associated with a procedural_iterator (see 5.5.3) is considered
to not allow exit, independent of the value of its Allows_Exit
aspect.}
---
We had some private discussions about implementing exits from procedural
iterators using thread-local storage rather than an exception -like mechanism,
and it does seem doable, but the exception-like mechanism would probably be
the most straightforward, so therefore disallowing it when exceptions are
restricted still seems to make sense. Any implementation-defined restriction
that disallows exceptions or exception handlers could also choose to restrict
"early" exits from procedural iterators (e.g. SPARK mode).
****************************************************************
Questions? Ask the ACAA Technical Agent