On 7/27/25 1:25 PM, Harald Anlauf wrote:
Gesendet: Sonntag, 27. Juli 2025 um 21:18
Von: "Mikael Morin" <morin-mik...@orange.fr>
An: "Andre Vehreschild" <ve...@gmx.de>
CC: "Harald Anlauf" <anl...@gmx.de>, fortran@gcc.gnu.org
Betreff: Re: Add: [Bug fortran/121043] [16 Regression] Tests of OpenCoarray
fail to pass, works on 15.1.1 20250712
Le 27/07/2025 à 17:35, Andre Vehreschild a écrit :
On Sun, 27 Jul 2025 16:57:14 +0200
Mikael Morin <morin-mik...@orange.fr> wrote:
Le 27/07/2025 à 12:57, Andre Vehreschild a écrit :
Hi Mikael,
In this example, image 1, i.e., for
Opencoarrays a thread on image one takes the data from the executing
image and writes it into the memory of image 1.
When you say it takes data, do you mean it takes the assignment right
hand side (named "data"), or do you mean that it takes all required data
(right hand side "data" and index value initialized with the result of
"get_val()") from the executing image?
Both! Always keep in mind that an expression like
res(this_image())[1] = 42
executed on image 2, manipulates memory of process/image 1. When those
images are not running on the same machine (like in MPI possible), then the
(evaluated) index, here this_image(), and the evaluated rhs need to be
send to image 1 like in this example. On image 1 a routine is called,
that looks like this (pseudo C, abbreviated):
void caf_accessor_res_1(struct array_integer_t &res, void *rhs, struct
add_data_t *add_data) {
int *int_rhs = (int *)rhs;
res.data[add_data->this_image_val) = *int_rhs;
}
The above routine is generated by the Fortran compiler from a gfc_code
structure that models it in Fortran. I went that way to have exactly the
assignment behavior of Fortran. This way assigning res(1:N)[...] = rhs(1:N)
does no trigger N communication for assigning scalars, but the vector is
send as a block and the loop to modify the data in res is done in the
accessor (significantly faster).
This routine is executed on the remote image, here image 1. Note, that it
lacks the coindex now, because that is the implementation of coindexing.
For brevity I left out all the boilerplate that is implemented in
OpenCoarrays.
If I rephrase the above on my example:
https://gcc.gnu.org/pipermail/fortran/2025-July/062591.html
with the assignment:
res(get_val())[1] = data
every image <n> does:
rhs_n = data;
idx_n = get_val();
and the image <1> does:
for each n:
res(idx_n) = rhs_n;
Do you confirm?
Absolutely confirmed!
And now if I come back to your patch:
https://gcc.gnu.org/pipermail/fortran/2025-July/062530.html
the behaviour before the patch was different;
every image <n> was doing:
rhs_n = data;
and the image <1> was doing:
for each n:
res(get_val()) = rhs_n;
because get_val() is pure and takes zero argument.
Still confirming?
And again confirmed. You got it!
Great, I'm starting to emerge from the mist.
Then I think the patch goes in the right direction.
Is it possible to add a testcase for the testsuite?
Should the case EXPR_COMPCALL be handled in a similar way to
EXPR_FUNCTION (it can probably wait for a later patch)?
Harald, are you still unconvinced? Do we need to discuss the behavior of
the testcase test_teams_1? or something else?
I will not make any specific suggestions about the actual implementation
of coarrays in gfortran.
Let me phrase the following requirements:
(a) Assuming that the following code is standard-conforming:
program p
implicit none
integer :: img, data
integer :: cnt[*] = 0
integer, allocatable :: res(:)[:]
img = this_image()
data = img * img + 10 ! Something different on each image
allocate(res(num_images())[*], source=-1)
select case (img)
case (1)
res(img )[1] = data
case (2)
res(this_image ())[1] = data
case (3)
res(get_val_pure ())[1] = data
case default
res(get_val_impure())[1] = data
end select
sync all
if (this_image() == 1) print *, res
contains
pure integer function get_val_pure() result (get_val)
get_val = img
end function
impure integer function get_val_impure() result (get_val)
get_val = img
cnt = cnt + 1 ! Count invocations of get_val
end function
end program
I am trying to catch up here somewhat. Using Andre's modified patch of:
diff --git a/gcc/fortran/coarray.cc b/gcc/fortran/coarray.cc
index ef8fd4e42d0..07e4f91d2d5 100644
--- a/gcc/fortran/coarray.cc
+++ b/gcc/fortran/coarray.cc
@@ -696,21 +696,11 @@ check_add_new_component (gfc_symbol *type, gfc_expr *e,
gfc_symbol *add_data)
and
diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc
index 43bd7be54cb..ba4a842a025 100644
--- a/gcc/fortran/trans-decl.cc
+++ b/gcc/fortran/trans-decl.cc
@@ -4223,10 +4223,9 @@ gfc_build_builtin_function_decls (void)
I get the following running Harald's example above:
The OpenCoarrays is using mpich on Fedora 42, issue-779 branch.
$ /home/jerry/dev/opencoarrays-clean/bin/caf harald.f90
$ /home/jerry/dev/opencoarrays-clean/bin/cafrun -np 30 ./a.out
11 14 19 26 35 46
59 74 91 110 131 154 179
206 235 266 299 334 371
410 451 494 539 586 635 686
739
794 851 910
$ $FC -fcoarray=lib harald.f90 -o xharald -lcaf_shmem
$ export GFORTRAN_NUM_IMAGES=30
$ ./xharald
11 14 19 26 35 46
59 74 91 110 131 154 179
206 235 266 299 334 371
410 451 494 539 586 635 686
739 794 851 910
Is this the expected result?
Jerry