Skip to content

Commit 235167d

Browse files
author
Damian Rouson
committed
Merge branch 'issue-733-impl-random-init'
2 parents ef8069d + 342421c commit 235167d

File tree

7 files changed

+233
-9
lines changed

7 files changed

+233
-9
lines changed

CMakeLists.txt

+4
Original file line numberDiff line numberDiff line change
@@ -782,6 +782,9 @@ if(opencoarrays_aware_compiler)
782782
message( AUTHOR_WARNING "Skipping the following test to GFortran < 7.4.0 lack of compatibility:
783783
send-strided-self.f90")
784784
endif()
785+
if((NOT CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 12.0.0) OR (CAF_RUN_DEVELOPER_TESTS OR $ENV{OPENCOARRAYS_DEVELOPER}))
786+
add_caf_test(random_init 4 random_init)
787+
endif()
785788
endif()
786789

787790
# Pure get tests
@@ -792,6 +795,7 @@ if(opencoarrays_aware_compiler)
792795
add_caf_test(get_with_offset_1d 2 get_with_offset_1d)
793796
add_caf_test(whole_get_array 2 whole_get_array)
794797
add_caf_test(strided_get 2 strided_get)
798+
add_caf_test(get_static_array 2 get_static_array)
795799

796800
# Pure send tests
797801
add_caf_test(send_array 2 send_array)

src/libcaf.h

+2
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,8 @@ void PREFIX (event_post) (caf_token_t, size_t, int, int *, char *, charlen_t);
331331
void PREFIX (event_wait) (caf_token_t, size_t, int, int *, char *, charlen_t);
332332
void PREFIX (event_query) (caf_token_t, size_t, int, int *, int *);
333333

334+
void PREFIX (random_init) (bool, bool);
335+
334336
/* Language extension */
335337
#ifdef HAVE_MPI
336338
MPI_Fint PREFIX (get_communicator) (caf_team_t *);

src/mpi/mpi_caf.c

+78-9
Original file line numberDiff line numberDiff line change
@@ -4673,8 +4673,8 @@ PREFIX(get_by_ref) (caf_token_t token, int image_index,
46734673
size = 1;
46744674
while (riter)
46754675
{
4676-
dprint("caf_ref = %p, offset = %zd, remote_mem = %p, global_win(data, desc)) = (%d, %d)\n",
4677-
riter, data_offset, remote_memptr, access_data_through_global_win,
4676+
dprint("caf_ref = %p, type = %d, offset = %zd, remote_mem = %p, global_win(data, desc)) = (%d, %d)\n",
4677+
riter, riter->type, data_offset, remote_memptr, access_data_through_global_win,
46784678
access_desc_through_global_win);
46794679
switch (riter->type)
46804680
{
@@ -4996,7 +4996,7 @@ case kind: \
49964996
delta = riter->u.a.dim[i].v.nvec;
49974997
#define KINDCASE(kind, type) \
49984998
case kind: \
4999-
remote_memptr += \
4999+
data_offset += \
50005000
((type *)riter->u.a.dim[i].v.vector)[0] * riter->item_size; \
50015001
break
50025002

@@ -5026,15 +5026,14 @@ case kind: \
50265026
riter->u.a.dim[i].s.stride,
50275027
riter->u.a.dim[i].s.start,
50285028
riter->u.a.dim[i].s.end);
5029-
remote_memptr += riter->u.a.dim[i].s.start
5030-
* riter->u.a.dim[i].s.stride
5031-
* riter->item_size;
5029+
data_offset += riter->u.a.dim[i].s.start
5030+
* riter->u.a.dim[i].s.stride
5031+
* riter->item_size;
50325032
break;
50335033
case CAF_ARR_REF_SINGLE:
50345034
delta = 1;
5035-
remote_memptr += riter->u.a.dim[i].s.start
5036-
* riter->u.a.dim[i].s.stride
5037-
* riter->item_size;
5035+
data_offset += riter->u.a.dim[i].s.start
5036+
* riter->item_size;
50385037
break;
50395038
case CAF_ARR_REF_OPEN_END:
50405039
/* This and OPEN_START are mapped to a RANGE and therefore can
@@ -8491,3 +8490,73 @@ void PREFIX(sync_team) (caf_team_t *team , int unused __attribute__((unused)))
84918490

84928491
int ierr = MPI_Barrier(*tmp_comm); chk_err(ierr);
84938492
}
8493+
8494+
extern void _gfortran_random_seed_i4 (int32_t *size, gfc_dim1_descriptor_t *put,
8495+
gfc_dim1_descriptor_t *get);
8496+
8497+
void PREFIX(random_init) (bool repeatable, bool image_distinct)
8498+
{
8499+
static gfc_dim1_descriptor_t rand_seed;
8500+
static bool rep_needs_init = true, arr_needs_init = true;
8501+
static int32_t seed_size;
8502+
8503+
if (arr_needs_init)
8504+
{
8505+
_gfortran_random_seed_i4(&seed_size, NULL, NULL);
8506+
memset(&rand_seed, 0, sizeof(gfc_dim1_descriptor_t));
8507+
rand_seed.base.base_addr = malloc(seed_size * sizeof(int32_t)); // because using seed_i4
8508+
rand_seed.base.offset = -1;
8509+
rand_seed.base.dtype.elem_len = sizeof(int32_t);
8510+
rand_seed.base.dtype.rank = 1;
8511+
rand_seed.base.dtype.type = BT_INTEGER;
8512+
rand_seed.base.span = 0;
8513+
rand_seed.dim[0].lower_bound = 1;
8514+
rand_seed.dim[0]._ubound = seed_size;
8515+
rand_seed.dim[0]._stride = 1;
8516+
8517+
arr_needs_init = false;
8518+
}
8519+
8520+
if (repeatable)
8521+
{
8522+
if (rep_needs_init)
8523+
{
8524+
int32_t lcg_seed = 57911963;
8525+
if (image_distinct)
8526+
{
8527+
lcg_seed *= caf_this_image;
8528+
}
8529+
int32_t *curr = rand_seed.base.base_addr;
8530+
for (int i = 0; i < seed_size; ++i)
8531+
{
8532+
const int32_t a = 16087;
8533+
const int32_t m = INT32_MAX;
8534+
const int32_t q = 127773;
8535+
const int32_t r = 2836;
8536+
lcg_seed = a * (lcg_seed % q) - r * (lcg_seed / q);
8537+
if (lcg_seed <= 0) lcg_seed += m;
8538+
*curr = lcg_seed;
8539+
++curr;
8540+
}
8541+
rep_needs_init = false;
8542+
}
8543+
_gfortran_random_seed_i4(NULL, &rand_seed, NULL);
8544+
}
8545+
else if (image_distinct)
8546+
{
8547+
_gfortran_random_seed_i4(NULL, NULL, NULL);
8548+
}
8549+
else
8550+
{
8551+
if (caf_this_image == 0)
8552+
{
8553+
_gfortran_random_seed_i4(NULL, NULL, &rand_seed);
8554+
MPI_Bcast(rand_seed.base.base_addr, seed_size, MPI_INT32_T, 0, CAF_COMM_WORLD);
8555+
}
8556+
else
8557+
{
8558+
MPI_Bcast(rand_seed.base.base_addr, seed_size, MPI_INT32_T, 0, CAF_COMM_WORLD);
8559+
_gfortran_random_seed_i4(NULL, &rand_seed, NULL);
8560+
}
8561+
}
8562+
}

src/tests/unit/send-get/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ caf_compile_executable(strided_get strided_get.f90)
1313
caf_compile_executable(get_with_vector_index get_with_vector_index.f90)
1414
## Inquiry functions (these are gets that could be optimized in the future to communicate only the descriptors)
1515
caf_compile_executable(alloc_comp_multidim_shape alloc_comp_multidim_shape.F90)
16+
caf_compile_executable(get_static_array get_static_array.f90)
1617

1718
## Pure send() tests
1819
caf_compile_executable(send_array send_array_test.f90)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
program get_static_array
2+
type :: container
3+
integer, allocatable :: stuff(:)
4+
end type
5+
6+
type(container) :: co_containers(10)[*]
7+
8+
if (this_image() == 1) then
9+
allocate(co_containers(2)%stuff(4))
10+
co_containers(2)%stuff = [1,2,3,4]
11+
end if
12+
13+
sync all
14+
15+
if (this_image() == 2) then
16+
if (any(co_containers(2)[1]%stuff /= [1,2,3,4])) then
17+
error stop "Test failed."
18+
else
19+
print *, "Test passed."
20+
end if
21+
end if
22+
end program
23+

src/tests/unit/simple/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
caf_compile_executable(increment_my_neighbor increment_neighbor.f90)
44
caf_compile_executable(atomics testAtomics.f90)
5+
caf_compile_executable(random_init random_init.f90)
56

67
# C tests
78
#include(CMakeForceCompiler)

src/tests/unit/simple/random_init.f90

+124
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
! random init test
2+
!
3+
! Copyright (c) 2021-2021, Sourcery, Inc.
4+
! All rights reserved.
5+
!
6+
! Redistribution and use in source and binary forms, with or without
7+
! modification, are permitted provided that the following conditions are met:
8+
! * Redistributions of source code must retain the above copyright
9+
! notice, this list of conditions and the following disclaimer.
10+
! * Redistributions in binary form must reproduce the above copyright
11+
! notice, this list of conditions and the following disclaimer in the
12+
! documentation and/or other materials provided with the distribution.
13+
! * Neither the name of the Sourcery, Inc., nor the
14+
! names of its contributors may be used to endorse or promote products
15+
! derived from this software without specific prior written permission.
16+
!
17+
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18+
! ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19+
! WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20+
! DISCLAIMED. IN NO EVENT SHALL SOURCERY, INC., BE LIABLE FOR ANY
21+
! DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22+
! (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23+
! LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24+
! ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25+
! (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26+
!
27+
28+
program test_random_init
29+
implicit none
30+
integer :: me,np
31+
integer(kind=4), dimension(:), allocatable :: random_num, from_master
32+
integer(kind=4) :: seed_size
33+
integer :: seed_eq
34+
35+
me = this_image()
36+
np = num_images()
37+
38+
if (np .lt. 1) then
39+
error stop "Need at least two images."
40+
end if
41+
42+
call random_seed(size=seed_size)
43+
allocate(random_num(1:seed_size))
44+
allocate(from_master(1:seed_size))
45+
46+
call random_init(.true., .true.)
47+
48+
sync all
49+
call random_seed(get=random_num)
50+
if (me .eq. 1) then
51+
from_master = random_num
52+
end if
53+
call co_broadcast(from_master, 1)
54+
if (me .eq. 1) then
55+
seed_eq = 0
56+
else
57+
seed_eq = any(random_num .eq. from_master)
58+
end if
59+
call co_max(seed_eq, 1)
60+
61+
if (me .eq. 1 .and. seed_eq .eq. 1) then
62+
error stop "Test failed. (T,T)"
63+
end if
64+
65+
call random_init(.false., .true.)
66+
67+
sync all
68+
call random_seed(get=random_num)
69+
if (me .eq. 1) then
70+
from_master = random_num
71+
end if
72+
call co_broadcast(from_master, 1)
73+
if (me .eq. 1) then
74+
seed_eq = 0
75+
else
76+
seed_eq = any(random_num .eq. from_master)
77+
end if
78+
call co_max(seed_eq, 1)
79+
80+
if (me .eq. 1 .and. seed_eq .eq. 1) then
81+
error stop "Test failed. (F,T)"
82+
end if
83+
84+
sync all
85+
86+
call random_init(.false., .false.)
87+
88+
sync all
89+
call random_seed(get=random_num)
90+
if (me .eq. 1) then
91+
from_master = random_num
92+
end if
93+
call co_broadcast(from_master, 1)
94+
seed_eq = all(random_num .eq. from_master)
95+
call co_min(seed_eq, 1)
96+
97+
print *,"me=", me, ", rand_num=", random_num, ", from_master=", from_master, ", seed_eq=", seed_eq
98+
if (me .eq. 1 .and. seed_eq .eq. 0) then
99+
error stop "Test failed. (F,F)"
100+
end if
101+
102+
sync all
103+
104+
call random_init(.true., .false.)
105+
106+
sync all
107+
call random_seed(get=random_num)
108+
if (me .eq. 1) then
109+
from_master = random_num
110+
end if
111+
call co_broadcast(from_master, 1)
112+
seed_eq = all(random_num .eq. from_master)
113+
call co_min(seed_eq, 1)
114+
115+
if (me .eq. 1 .and. seed_eq .eq. 0) then
116+
error stop "Test failed. (T,F)"
117+
end if
118+
119+
sync all
120+
121+
if (me .eq. 1) print *,"Test passed."
122+
123+
end program test_random_init
124+

0 commit comments

Comments
 (0)