Home > Archive > Fortran > December 2006 > index value after FORALL
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
index value after FORALL
|
|
| Beliavsky 2006-12-11, 7:12 pm |
| program xforall
implicit none
integer, parameter :: n = 10, dz = 3
integer :: i,z(0:n)
forall (i=0:n) z(i) = i*dz
print*,"z=",z
print*,"i=",i
end program xforall
For the code above, I think "i" can take on any value after the FORALL.
Experimenting with g95 and gfortran confirms this. Is that correct?
This question is motivated by a recent thread "forall issues an
uninitialized variable warning" in the g95 newsgroup
http://groups.google.com/group/gg95 .
| |
| Steven G. Kargl 2006-12-11, 7:12 pm |
| In article <1165878522.635263.139900@f1g2000cwa.googlegroups.com>,
"Beliavsky" <beliavsky@aol.com> writes:
> program xforall
> implicit none
> integer, parameter :: n = 10, dz = 3
> integer :: i,z(0:n)
> forall (i=0:n) z(i) = i*dz
> print*,"z=",z
> print*,"i=",i
> end program xforall
>
> For the code above, I think "i" can take on any value after the FORALL.
> Experimenting with g95 and gfortran confirms this. Is that correct?
"i" has not been defined by the time you get to 'print*,"i=",i',
so technically I believe it's an invalid program. See line 25 on
page 115 of the Final Committee Draft of the Fortran 95 standard.
See also 14.1.3.
--
Steve
http://troutmask.apl.washington.edu/~kargl/
| |
| glen herrmannsfeldt 2006-12-11, 7:12 pm |
| Beliavsky <beliavsky@aol.com> wrote:
(snip)
> forall (i=0:n) z(i) = i*dz
> For the code above, I think "i" can take on any value after the FORALL.
> Experimenting with g95 and gfortran confirms this. Is that correct?
My understanding is that FORALL makes no guarantee on the order the
assignments are made. Assuming i had the value of the last assignment,
that would give it any value between 0 and n, but I don't know why
it would even do that.
As with Fortran 66 DO loops, the loop variable may be in a
register and never stored. On a vector processor it may be done
with vector registers, without the use of an index variable.
Otherwise, from Fortran 2003 draft:
"An index-name in a forall-construct has a scope of the construct
(16.3). It is a scalar variable that has the type and type parameters
that it would have if it were the name of a variable in the scoping unit
that includes the FORALL, and this type shall be integer type;
it has no other attributes."
-- glen
| |
| Brooks Moses 2006-12-13, 4:18 pm |
| glen herrmannsfeldt wrote:
> Beliavsky <beliavsky@aol.com> wrote:
As Steve Kargl implied, that may be technically correct (in your case
where i was not previously defined), but it's most definitely misleading
-- it implies that the value is compiler-dependent, when the truth is
that it is undefined. See below.
[...][color=darkred]
> As with Fortran 66 DO loops, the loop variable may be in a
> register and never stored. On a vector processor it may be done
> with vector registers, without the use of an index variable.
>
> Otherwise, from Fortran 2003 draft:
>
> "An index-name in a forall-construct has a scope of the construct
> (16.3). It is a scalar variable that has the type and type parameters
> that it would have if it were the name of a variable in the scoping unit
> that includes the FORALL, and this type shall be integer type;
> it has no other attributes."
Note that this means that the following code is legal, even though i (in
the main program) is an array, and an unallocated one at that!
integer, dimension(:), allocatable :: i
forall (i=0:n) z(i) = i*dz
Further, consider this little bit of code:
integer :: i
i = -42
forall (i=0:n) z(i) = i*dz
print *, i
Here, i is defined when printed, and will have the value of -42.
As a result of this, any compiler implementation that leads i being
given a value by the forall in Beliavsky's sample code (where it was an
undefined scalar before the forall statement) is liable to be either
excessively complicated or else buggy.
- Brooks
--
The "bmoses-nospam" address is valid; no unmunging needed.
| |
| John Harper 2006-12-13, 4:18 pm |
| In article <elkpkd$2u0$1@naig.caltech.edu>,
glen herrmannsfeldt <gah@seniti.ugcs.caltech.edu> wrote:
>Beliavsky <beliavsky@aol.com> wrote:
>(snip)
>
>...
>Otherwise, from Fortran 2003 draft:
>
> "An index-name in a forall-construct has a scope of the construct
> (16.3). It is a scalar variable that has the type and type parameters
> that it would have if it were the name of a variable in the scoping unit
> that includes the FORALL, and this type shall be integer type;
> it has no other attributes."
What that doesn't say but, I think, does imply, is that merely making
i an index-name does not declare it, so if IMPLICIT NONE is in force
in the scoping unit, then the integer i must be declared there or be
host-associated or use-associated. If any other IMPLICIT is in force,
then it must make i of integer type.
-- John Harper, School of Mathematics, Statistics and Computer Science,
Victoria University, PO Box 600, Wellington 6140, New Zealand
e-mail john.harper@vuw.ac.nz phone (+64)(4)463 5341 fax (+64)(4)463 5045
| |
| John Harper 2006-12-13, 4:18 pm |
| In article <457E144E.5090701@cits1.stanford.edu>,
Brooks Moses <bmoses-nospam@cits1.stanford.edu> wrote:
>glen herrmannsfeldt wrote:
>
>As Steve Kargl implied, that may be technically correct (in your case
>where i was not previously defined), but it's most definitely misleading
>-- it implies that the value is compiler-dependent, when the truth is
>that it is undefined. See below.
>
>
>Note that this means that the following code is legal, even though i (in
>the main program) is an array, and an unallocated one at that!
>
> integer, dimension(:), allocatable :: i
> forall (i=0:n) z(i) = i*dz
But that F2003 quote says the index-name is scalar. It's also in a
Constraint:
(R755) The index-name shall be a named scalar variable of type integer.
So I think g95 is quite right to refuse to compile a program in which
i is an array.
-- John Harper, School of Mathematics, Statistics and Computer Science,
Victoria University, PO Box 600, Wellington 6140, New Zealand
e-mail john.harper@vuw.ac.nz phone (+64)(4)463 5341 fax (+64)(4)463 5045
| |
| glen herrmannsfeldt 2006-12-13, 4:18 pm |
| Brooks Moses wrote:
(snip)
> Note that this means that the following code is legal, even though i (in
> the main program) is an array, and an unallocated one at that!
> integer, dimension(:), allocatable :: i
> forall (i=0:n) z(i) = i*dz
Also, consider:
DATA X/(I,I=1,10)/
Now, data statements are not executable, the 'loop' is done at
compile time. There really isn't a variable I, but I must have
the right type anyway. One should have no expectation that I
is 11 after that statement.
FORALL is not described as a loop, but as a construct. As far
as I can tell, the word 'loop' is not used anywhere in its description.
> Further, consider this little bit of code:
> integer :: i
> i = -42
> forall (i=0:n) z(i) = i*dz
> print *, i
> Here, i is defined when printed, and will have the value of -42.
It looks like that to me.
> As a result of this, any compiler implementation that leads i being
> given a value by the forall in Beliavsky's sample code (where it was an
> undefined scalar before the forall statement) is liable to be either
> excessively complicated or else buggy.
Well, undefined variables are allowed to have any possible value,
including the one you think they shouldn't have. It I isn't
otherwise defined, it would seem legal to give it the value just
past the FORALL limit. On the other hand, any code using that value
is non-standard.
-- glen
| |
| glen herrmannsfeldt 2006-12-13, 4:18 pm |
| John Harper wrote:
(snip)
[color=darkred]
[color=darkred]
[color=darkred]
[color=darkred]
> But that F2003 quote says the index-name is scalar. It's also in a
> Constraint:
> (R755) The index-name shall be a named scalar variable of type integer.
> So I think g95 is quite right to refuse to compile a program in which
> i is an array.
Reading the quote again, it says it has the type and type parameters
as it would have in the scoping unit ... the type shall be integer,
it has no other attributes. Is DIMENSION an attribute or parameter?
I believe KIND is a parameter, and DIMENSION is an attribute.
-- glen
| |
| Brooks Moses 2006-12-13, 4:18 pm |
| John Harper wrote:
> In article <457E144E.5090701@cits1.stanford.edu>,
> Brooks Moses <bmoses-nospam@cits1.stanford.edu> wrote:
>
> But that F2003 quote says the index-name is scalar. It's also in a
> Constraint:
> (R755) The index-name shall be a named scalar variable of type integer.
The quote doesn't say what you think it says. Note that there are _two_
variables here named "i": There is the variable in the host program
(which has the scope of the program), and there is a second variable in
the forall construct (which has the scope of the construct). They share
a name, and they share a type and type parameters; they do not share
other attributes.
What the quote says is that the second of these variables -- the one
that has the scope of the forall construct -- is a scalar variable. It
does not say anything about the first, and it specifically does _not_
say that the scalarness or dimensions of the two variables must be the same.
Given the existence of two variables, R755 is also clearly referring to
the second variable, not to the variable which has program scope. (This
is supported by the observation that there is not necessarily any such
variable with program scope, in cases of implicit typing, and thus R755
cannot be referring to it!) In particular, I think what the "scalar"
language in R755 is intended to disallow is using things like I(1) as an
index-name.
> So I think g95 is quite right to refuse to compile a program in which
> i is an array.
Incidentally, for a clearer case, does it compile a function in which i
is an INTENT(IN) dummy? Even if you're right about arrays, that one's
quite clearly an allowed case.
- Brooks
--
The "bmoses-nospam" address is valid; no unmunging needed.
| |
| Brooks Moses 2006-12-13, 4:18 pm |
| glen herrmannsfeldt wrote:
> Brooks Moses wrote:
>
>
>
> It looks like that to me.
>
>
> Well, undefined variables are allowed to have any possible value,
> including the one you think they shouldn't have. It I isn't
> otherwise defined, it would seem legal to give it the value just
> past the FORALL limit. On the other hand, any code using that value
> is non-standard.
Oh, I completely agree. That's the "excessively complicated" branch of
my "or" expression -- I would contend that the compiler effort required
to accomplish that reliably (and to not mess up when i is already
defined) is liable to be excessively complicated. :)
But, of course, it's perfectly legal if it works right.
- Brooks
--
The "bmoses-nospam" address is valid; no unmunging needed.
| |
| glen herrmannsfeldt 2006-12-13, 4:18 pm |
| Brooks Moses wrote:
(snip)
> The quote doesn't say what you think it says. Note that there are _two_
> variables here named "i": There is the variable in the host program
> (which has the scope of the program), and there is a second variable in
> the forall construct (which has the scope of the construct). They share
> a name, and they share a type and type parameters; they do not share
> other attributes.
How about :
INTEGER, KIND(SELECTED_INT_KIND(1)) :: I
REAL X(100000)
FORALL (I=1:100000) X(I)=0
Since KIND is a parameter, and not an attribute, it would seem
that this should, or could, fail.
-- glen
| |
| Brooks Moses 2006-12-13, 4:18 pm |
| glen herrmannsfeldt wrote:
> Brooks Moses wrote:
>
> How about :
>
> INTEGER, KIND(SELECTED_INT_KIND(1)) :: I
> REAL X(100000)
>
> FORALL (I=1:100000) X(I)=0
>
> Since KIND is a parameter, and not an attribute, it would seem
> that this should, or could, fail.
Yes, I agree. Assuming that this gives I a kind which is too small to
contain 100000, this should fail. (Of course, that's always true; it's
just that this is somewhat more likely to do so than INTEGER::I is!)
- Brooks
--
The "bmoses-nospam" address is valid; no unmunging needed.
| |
| Richard E Maine 2006-12-13, 4:18 pm |
| Brooks Moses <bmoses-nospam@cits1.stanford.edu> wrote:
> glen herrmannsfeldt wrote:
>
> Oh, I completely agree. That's the "excessively complicated" branch of
> my "or" expression
I don't agree. Well, I agree with the Fortran part, but not with the
English wording, which I think is relevant here. The whole point is that
there are 2 *DIFFERENT* variables named I here. I think it is misleading
at best, but mostly just wrong, to use the word "it" to refer to them. I
think that this misleading use is leading people astray here.
Yes, it would be valid for the compiler to give the undefined I variable
the value of the other one after the FORALL. But when you express it
that way, instead os misleadingly using the word "it" to refer to 2
different things, it is much more apparent how strange and pointlessly
complicated a thing that would be.
--
Richard Maine | Good judgment comes from experience;
email: my first.last at org.domain| experience comes from bad judgment.
org: nasa, domain: gov | -- Mark Twain
| |
| glen herrmannsfeldt 2006-12-13, 4:18 pm |
| Richard E Maine <nospam@see.signature> wrote:
> Brooks Moses <bmoses-nospam@cits1.stanford.edu> wrote:
[color=darkred]
(snip)
[color=darkred]
> I don't agree. Well, I agree with the Fortran part, but not with the
> English wording, which I think is relevant here. The whole point is that
> there are 2 *DIFFERENT* variables named I here. I think it is misleading
> at best, but mostly just wrong, to use the word "it" to refer to them. I
> think that this misleading use is leading people astray here.
> Yes, it would be valid for the compiler to give the undefined I variable
> the value of the other one after the FORALL. But when you express it
> that way, instead os misleadingly using the word "it" to refer to 2
> different things, it is much more apparent how strange and pointlessly
> complicated a thing that would be.
Not to disagree too much, but if the non-FORALL variable is
not initialized anywhere it is not legal to reference its value.
I agree that there should be two variables and that "it" is misleading.
Since there is no guarantee for the value it would seem legal for
the compiler to actually generate only one variable. Why someone
would write an optimizer to do that, I have no idea. (It would
most likely take more time to write than ever saved in using it.)
OK, for all legal Fortran programs there must be two separate
variables. Though it many cases the FORALL variable will
be in a register or maybe not even that. If one does
FORALL (I=LBOUND(X):UBOUND(X)) X(I)=0
many systems could use a memory clearing instruction
where no variable I exists anywhere.
To continue with the "referencing unintialized data" idea,
but leave the FORALL discussion, there was a story about
someone trying to test the speed of moving data with something like:
REAL, ALLOCATABLE:: X(:),Y(:)
ALLOCATE X(10000000)
DO I=1,10000
Y=X
ENDDO
Notice no initialization for X. It seems that many systems
now have a single page filled with zeros, which is put into
the page table for newly allocated storage. All the bytes of
X reference the same memory page. The result is that it is
not a good test of the time it takes to copy one large array
to another. (When X is modified, a new page is allocated and
put into the appropriate page table.)
-- glen
| |
| John Harper 2006-12-13, 4:18 pm |
| In article <457E3E08.4010305@cits1.stanford.edu>,
Brooks Moses <bmoses-nospam@cits1.stanford.edu> wrote:
>John Harper wrote:
....[color=darkred]
....[color=darkred]
>
>Incidentally, for a clearer case, does it compile a function in which i
>is an INTENT(IN) dummy? Even if you're right about arrays, that one's
>quite clearly an allowed case.
NAG and Sun f95, and g95, do indeed allow that. This program:
PROGRAM testforallint3
CALL foo(666)
CONTAINS
SUBROUTINE foo( i)
INTEGER,INTENT(IN)::i
INTEGER n(4)
FORALL (i=1:4) n(i) = i
PRINT *,i,n
END SUBROUTINE foo
END PROGRAM testforallint3
prints
666 1 2 3 4
with all three compilers.
-- John Harper, School of Mathematics, Statistics and Computer Science,
Victoria University, PO Box 600, Wellington 6140, New Zealand
e-mail john.harper@vuw.ac.nz phone (+64)(4)463 5341 fax (+64)(4)463 5045
|
|
|
|
|