[J3] [EXTERNAL] Re: Limitations of SELECT RANK?
Mark LeAir
mleair at nvidia.com
Tue Oct 20 14:58:53 EDT 2020
To give a little better context to Tom's question.
On the fortran-proposals Github, we were discussing select rank and how one would need to generate nested select ranks equal to the number of assumed rank arrays in an array expression.
For example, let's say we want to compute b1 = b1 + b2 + b3 (where b1, b2, and b3 are all assumed rank arrays). Let's also say the programmer knows that the rank of the arrays must be rank 2 or 3. Today, they would have to write something like the following:
subroutine add_arrays(b1, b2, b3)
real :: b1(..), b2(..), b3(..)
select rank (b1)
rank(2)
select rank(b2)
rank(2)
select rank(b3)
rank(2)
b1 = b1 + b2 + b3
rank default
error stop 'expected rank 2 for b3'
end select
rank default
error stop 'expected rank 2 for b2'
end select
rank(3)
select rank(b2)
rank(3)
select rank(b3)
rank(3)
b1 = b1 + b2 + b3
rank default
error stop 'expected rank 3 for b3'
end select
rank default
error stop 'expected rank 3 for b2'
end select
rank default
error stop 'unexpected rank for b1'
end select
end subroutine add_arrays
As you can see, the number of nested ranks grow with the number of expected ranks. Since a common case is for all assumed rank arrays in an expression to have the same rank, I suggested the following extension:
Select rank could be extended to evaluate a list of assumed rank arrays. If they are all the same rank, then execution branches to that rank case. Otherwise, execution branches to RANK DEFAULT (if provided) or to the end of the select rank construct. If RANK DEFAULT is provided, then the programmer could provide either one or more nested select ranks or do something else (e.g., issue an error and abort).
The following shows how the above nested rank example could be simplified with the proposed extension:
select rank (b1, b2, b3)
rank (2)
b1 = b1 + b2 + b3
rank (3)
b1 = b1 + b2 + b3
rank default
error stop 'unexpected rank'
end select
We could then take the extension a step further and allow the following:
select rank (b1, b2, b3)
rank (2:3)
b1 = b1 + b2 + b3
rank default
error stop 'unexpected rank'
end select
Because all arrays must have the same rank in the rank cases, the code that the processor must generate is simplified. It doesn't have to unfold any nested select rank cases. It just needs to generate a rank case (inline) for each alternative in the rank list. A processor could also just invoke one or more rank agnostic runtime routines to perform the arithmetic operations. This would further simplify the generated code as the processor does not have to unfold any rank cases. The runtime routines may also be acceptably slower compared to the unfolded version. Obviously, that would be for the implementer to determine which generated code approach to use.
-Mark
-----Original Message-----
From: J3 <j3-bounces at mailman.j3-fortran.org> On Behalf Of Steidel, Jon L via J3
Sent: Tuesday, October 20, 2020 9:21 AM
To: General J3 interest list <j3 at mailman.j3-fortran.org>
Cc: Steidel, Jon L <jon.l.steidel at intel.com>
Subject: Re: [J3] [EXTERNAL] Re: Limitations of SELECT RANK?
External email: Use caution opening links or attachments
Tom wrote:
We are seeing that common use cases for SELECT RANK have duplicate text. Aside from generic resolution, there are also cases involving whole array arithmetic. For these cases, the shorthand in my example is not just convenient for the coder, but is also a means to reduce errors that can happen when a subsequent change is only propagated to a subset of the RANK clauses. Granted, this is the weakest case of code duplication, as the duplicates would all line up next to each other in a single file.
End Tom
While there may be use cases that have duplicate text in multiple SELECT RANK case blocks, many involving whole array arithmetic, the code generated for each of the blocks is very different due to the difference in the array ranks between the two blocks. The compiler would have to replicate the block for each possible rank and generate a separate block for each rank. The ranks specified in the rank selector would need to be constant for this to happen, they could not be variable or values evaluated at runtime.
-jon
More information about the J3
mailing list