Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Fwd: A doubt about lbound and ubound of an array inside a coarray

139 views
Skip to first unread message

jdelia

unread,
Mar 23, 2021, 6:22:20 PM3/23/21
to
(sorry for this forwarding)

----- Mensaje reenviado -----
​​​​De: "Gfortran List"
Para: "Gfortran List"
Enviado: Domingo, 21 de Marzo 2021 13:18:13
Asunto: A doubt about lbound and ubound of an array inside a coarray

​​​​​Hi all,

I have a doubt about lbound and bound in the test below
using gfortran with opencoarrays, gasnet, and openmpi.

With the AA coarray (each AA entry is a 2D array),
the values obtained with lbound and ubound are different
from the initial and final values arbitrarily defined for
each array entry.

Is this ok and did I miss something here?

Thanks in advance for some clarification.

Regards.
Jorge.

$ cat /proc/version
Linux version 5.10.23-200.fc33.x86_64 (bkernel01.iad2.fedoraproject.org) (gcc (GCC) 10.2.1 20201125 (Red Hat 10.2.1-9), GNU ld version 2.35-18.fc33) #1 SMP Thu Mar 11 22:18:30 UTC 2021

$ which gfortran
/usr/beta/gcc-trunk/bin/gfortran

$ gfortran --version
GNU Fortran (GCC) 11.0.1 20210315 (experimental)
Copyright (C) 2021 Free Software Foundation, Inc.

$ which ompi_info
/usr/beta/openmpi/bin/ompi_info

$ ompi_info
...
/usr/beta/gcc-trunk/bin/gfortran

$ mpifort -Wall -Wextra -g -fcoarray=lib doubt1.f90 -o doubt1-openmpi.exe -L/usr/beta/opencoarrays-openmpi/lib64 -lcaf_mpi -lopencoarrays_mod -lmpi

$ mpirun --mca pml ucx --mca osc ucx -np 4 --mca btl vader,self,tcp --machinefile ${HOME}/machi-openmpi.dat --map-by node --map-by slot --map-by core --bind-to l2cache --mca orte_base_help_aggregate 0 --report-bindings --display-allocation --display-devel-map doubt1-openmpi.exe

====================== ALLOCATED NODES ===================
flags=0x11 slots=16 max_slots=16 slots_inuse=0 state=UP
============================================================
Data for JOB [53806,1] offset 0 Total slots allocated 16

Mapper requested: NULL Last mapper: round_robin Mapping policy: BYCORE:NOOVERSUBSCRIBE Ranking policy: CORE
Binding policy: L2CACHE Cpu set: NULL PPR: NULL Cpus-per-rank: 0
Num new daemons: 0 New daemon starting vpid INVALID
Num nodes: 1

Data for node: State: 3 Flags: 11
Daemon: [[53806,0],0] Daemon launched: True
Num slots: 16 Slots in use: 4 Oversubscribed: FALSE
Num slots allocated: 16 Max slots: 16
Num procs: 4 Next node_rank: 4
Data for proc: [[53806,1],0]
Pid: 0 Local rank: 0 Node rank: 0 App rank: 0
State: INITIALIZED App_context: 0
Locale: [BB/../../..]
Binding: [BB/../../..]
Data for proc: [[53806,1],1]
Pid: 0 Local rank: 1 Node rank: 1 App rank: 1
State: INITIALIZED App_context: 0
Locale: [../BB/../..]
Binding: [../BB/../..]
Data for proc: [[53806,1],2]
Pid: 0 Local rank: 2 Node rank: 2 App rank: 2
State: INITIALIZED App_context: 0
Locale: [../../BB/..]
Binding: [../../BB/..]
Data for proc: [[53806,1],3]
Pid: 0 Local rank: 3 Node rank: 3 App rank: 3
State: INITIALIZED App_context: 0
Locale: [../../../BB]
Binding: [../../../BB]
[55028] MCW rank 0 bound to socket 0[core 0[hwt 0-1]]: [BB/../../..]
[55028] MCW rank 1 bound to socket 0[core 1[hwt 0-1]]: [../BB/../..]
[55028] MCW rank 2 bound to socket 0[core 2[hwt 0-1]]: [../../BB/..]
[55028] MCW rank 3 bound to socket 0[core 3[hwt 0-1]]: [../../../BB]

ti h lbound(aa%oo,1) ubound(aa%oo,1) lbound(aa%oo,2) ubound(aa%oo,2)
1 1 1 2 1 2
3 1 1 2 1 2
4 1 1 2 1 2
2 1 1 2 1 2
2 2 1 3 1 3
1 2 1 3 1 3
4 2 1 3 1 3
3 2 1 3 1 3
3 3 1 4 1 4
2 3 1 4 1 4
1 3 1 4 1 4
4 3 1 4 1 4
4 4 1 5 1 5
3 4 1 5 1 5
2 4 1 5 1 5
1 4 1 5 1 5

ti h aa[h]%i1 aa[h]%i2 aa[h]%j1 aa[h]%j1 aa[h]%j2
1 1 2 3 4 5
2 1 2 3 4 5
2 2 8 10 12 14
1 2 8 10 12 14
2 3 14 17 20 23
2 4 20 24 28 32
3 1 2 3 4 5
4 1 2 3 4 5
1 3 14 17 20 23
3 2 8 10 12 14
4 2 8 10 12 14
1 4 20 24 28 32
3 3 14 17 20 23
4 3 14 17 20 23
3 4 20 24 28 32
4 4 20 24 28 32

$ cat doubt1.f90
program doubt1
implicit none
type tma
integer, allocatable :: oo (:,:)
integer :: i1,i2,j1,j2
end type tma
type (tma) :: aa [*]
!
integer, parameter :: np = 2, nq = 2
integer :: map (np,nq)
integer :: ni, ti
integer :: i1, i2, j1, j2
integer :: h, k, p, q
!
ni = num_images()
ti = this_image()
!
if (ni .ne. 4) error stop "num_images() must be 4"
!
k = 1
do q = 1, nq
do p = 1, np
map (p,q) = k
k = k + 1
end do
end do
!
i1 = 2
i2 = 3
j1 = 4
j2 = 5
do h = 1, ni
if (ti .eq. h) then
allocate (aa % oo (i1:i2,j1:j2))
aa % oo (i1:i2,j1:j2) = k
aa % i1 = i1
aa % i2 = i2
aa % j1 = j1
aa % j2 = j2
end if
i1 = i1 + 6
i2 = i2 + 7
j1 = j1 + 8
j2 = j2 + 9
end do
!
sync all
!
if (ti .eq. 1) then
write (*,*)
write (*,*)" ti h lbound(aa%oo,1) ubound(aa%oo,1) lbound(aa%oo,2) ubound(aa%oo,2)"
end if
do h = 1, ni
write (*,*) ti,h,lbound (aa[h]%oo,1), ubound (aa[h]%oo,1), &
lbound (aa[h]%oo,2), ubound (aa[h]%oo,2)
end do
!
sync all
!
if (ti .eq. 1) then
write (*,*)
write (*,*)" ti h aa[h]%i1 aa[h]%i2 aa[h]%j1 aa[h]%j1 aa[h]%j2"
end if
do h = 1, ni
write (*,*) ti, h, aa [h] % i1, aa [h] % i2, &
aa [h] % j1, aa [h] % j2
end do
!
end program doubt1
#end

gah4

unread,
Mar 23, 2021, 7:32:53 PM3/23/21
to
On Tuesday, March 23, 2021 at 3:22:20 PM UTC-7, jdelia wrote:

(snip)

> I have a doubt about lbound and bound in the test below
> using gfortran with opencoarrays, gasnet, and openmpi.

> With the AA coarray (each AA entry is a 2D array),
> the values obtained with lbound and ubound are different
> from the initial and final values arbitrarily defined for
> each array entry.

> Is this ok and did I miss something here?

For each image, besides printing out what you print, print out the one without
a co-index.

write (*,*) ti,'-',lbound (aa%oo,1), ubound (aa%oo,1), &
lbound (aa%oo,2), ubound (aa%oo,2)

This subject hasn't come up so recent, but Fortran has funny rules related to
array expressions and subscripts. An array expression always has a lower
bound of 1, and the appropriate upper bound to match.

For comparison, in PL/I, array expressions keep their upper and lower
bounds. But then again, PL/I only has array sections with stride 1.
(Unless they changed it since I last looked.)

It seems that it considers a coarray reference as an array expression,
even if you don't.

Note that this sometimes can be convenient. Consider that you might
want to add two arrays. In the Fortran rules, they lose their lower bound,
such that addition works element by element. (Hopefully they have
the same extent.) In the PL/I rules, you can only add arrays that have
the same lower and upper bound.

To get this right, you have to know exactly what is an array expression,
and so when the lower bound is 1.


jdelia

unread,
Mar 24, 2021, 8:56:07 AM3/24/21
to
I agree, sometimes, that behavior can be convenient.

> To get this right, you have to know exactly what is an array expression,
> and so when the lower bound is 1.

I knew some of those details with lower bounds, e.g. in arrays with lower
bounds other than 1 that are transferred to a subroutine, some special
care must be taken if I intend to work with a same range of indices.
But I naively thought that within the main program or subroutine that
defined the array, the values of lbounds function would correspond always
to the static or dynamic definition (e.g. integer AA (n1: n2, n3: n4) or
allocate (AA (n1: n2 , n3: n4)). However, I have to refine the analysis
with arrays defined in other images.

Thanks for your clarifications. Regards.

gah4

unread,
Mar 24, 2021, 9:17:47 AM3/24/21
to
On Wednesday, March 24, 2021 at 5:56:07 AM UTC-7, jdelia wrote:

(snip, I wrote)

> > To get this right, you have to know exactly what is an array expression,
> > and so when the lower bound is 1.

> I knew some of those details with lower bounds, e.g. in arrays with lower
> bounds other than 1 that are transferred to a subroutine, some special
> care must be taken if I intend to work with a same range of indices.
> But I naively thought that within the main program or subroutine that
> defined the array, the values of lbounds function would correspond always
> to the static or dynamic definition (e.g. integer AA (n1: n2, n3: n4) or
> allocate (AA (n1: n2 , n3: n4)). However, I have to refine the analysis
> with arrays defined in other images.

I didn't actually look it up, but I suspect that if you reference
it without the coindex, so only the local one, that it keeps
bounds. You might try it to be sure.

With the coindex, there is no special case for the local image,
as far as I know. It would be strange if it did give different results.
It treats it like a different subroutine, or different image, even
when it is the same.

gah4

unread,
Mar 24, 2021, 9:24:50 AM3/24/21
to
"Except in contexts where coindexed objects are disallowed, accessing a coarray on its
own image by using a set of cosubscripts that specify that image has the same effect
as accessing it without cosubscripts. In particular, the segment ordering rules (11.6.2)
apply whether or not cosubscripts are used to access the coarray."

Hmm.

Ian Harvey

unread,
Mar 29, 2021, 6:32:22 AM3/29/21
to
On 24/03/2021 7:52 am, jdelia wrote:
> (sorry for this forwarding)
>
> ----- Mensaje reenviado -----
> ​​​​De: "Gfortran List"
> Para: "Gfortran List"
> Enviado: Domingo, 21 de Marzo 2021 13:18:13
> Asunto: A doubt about lbound and ubound of an array inside a coarray
>
> ​​​​​Hi all,
>
> I have a doubt about lbound and bound in the test below
> using gfortran with opencoarrays, gasnet, and openmpi.
>
> With the AA coarray (each AA entry is a 2D array),
> the values obtained with lbound and ubound are different
> from the initial and final values arbitrarily defined for
> each array entry.
>
> Is this ok and did I miss something here?
>
> Thanks in advance for some clarification.
>
> Regards.
> Jorge.
>

...

Looks like a Fortran processor (compiler proper, or support library -
whatever) bug to me.

The argument to LBOUND in all cases is a whole array. It is a whole
array that arises from a designator for a structure component that
includes a coarray subscript, but that doesn't matter - there is no
subscript list "appended" to the designator.

gah4

unread,
Mar 29, 2021, 4:16:17 PM3/29/21
to
On Monday, March 29, 2021 at 3:32:22 AM UTC-7, Ian Harvey wrote:

(snip)
> Looks like a Fortran processor (compiler proper, or support library -
> whatever) bug to me.

> The argument to LBOUND in all cases is a whole array. It is a whole
> array that arises from a designator for a structure component that
> includes a coarray subscript, but that doesn't matter - there is no
> subscript list "appended" to the designator.

There are some cases where arrays lose their wholeness.

Subroutine arguments being one, except for some cases.

I have no idea where (and I did look) to find in the standard where they
keep bounds and where they don't.

Until this question, I would have thought that they do in this case,
but I don't know how to prove it.

Ian Harvey

unread,
Mar 29, 2021, 5:22:21 PM3/29/21
to
On 30/03/2021 5:46 am, gah4 wrote:
> On Monday, March 29, 2021 at 3:32:22 AM UTC-7, Ian Harvey wrote:
>
> (snip)
>> Looks like a Fortran processor (compiler proper, or support library -
>> whatever) bug to me.
>
>> The argument to LBOUND in all cases is a whole array. It is a whole
>> array that arises from a designator for a structure component that
>> includes a coarray subscript, but that doesn't matter - there is no
>> subscript list "appended" to the designator.
>
> There are some cases where arrays lose their wholeness.
>
> Subroutine arguments being one, except for some cases.

The term "whole array" describes a piece of syntax.

A subroutine dummy argument isn't special, from a syntax point of view.
Inside a subroutine (or function), a reference to a dummy argument
that is an array, where that reference does not include trailing
subscripts, is still a whole array.

Each type of array available for a user written procedure (assumed
shape, assumed size, deferred shape, explicit shape...) has rules that
specify how the bounds of that dummy argument are set during argument
association. But these rules around array argument association are moot
for the example provided - there are no procedure references, bar
references to intrinsic procedures which can make their own rules up -
as LBOUND does.

> I have no idea where (and I did look) to find in the standard where they
> keep bounds and where they don't.

The result of the LBOUND intrinsic is described in F2018 16.8.109, along
with the rest of the description of LBOUND. That description references
the term "whole array", which is described in F2018 9.5.2.

gah4

unread,
Mar 29, 2021, 9:51:41 PM3/29/21
to
On Monday, March 29, 2021 at 2:22:21 PM UTC-7, Ian Harvey wrote:

(snip, I wrote)
> > There are some cases where arrays lose their wholeness.

> > Subroutine arguments being one, except for some cases.
> The term "whole array" describes a piece of syntax.

> A subroutine dummy argument isn't special, from a syntax point of view.
> Inside a subroutine (or function), a reference to a dummy argument
> that is an array, where that reference does not include trailing
> subscripts, is still a whole array.

It has been some years now, but this question of lower bounds
for dummy arrays has been discussed, and I don't always
figure out the details, or where it is in the standard.

> Each type of array available for a user written procedure (assumed
> shape, assumed size, deferred shape, explicit shape...) has rules that
> specify how the bounds of that dummy argument are set during argument
> association. But these rules around array argument association are moot
> for the example provided - there are no procedure references, bar
> references to intrinsic procedures which can make their own rules up -
> as LBOUND does.

No user visible procedure references, but how does the data get
from one image, possibly on a different machine get moved?
Usually by procedure reference.

> > I have no idea where (and I did look) to find in the standard where they
> > keep bounds and where they don't.

> The result of the LBOUND intrinsic is described in F2018 16.8.109, along
> with the rest of the description of LBOUND. That description references
> the term "whole array", which is described in F2018 9.5.2.

I did read that one, but either couldn't figure it out, or not well enough.
Especially, it doesn't well explain dummy arguments bounds loss.
0 new messages