Skip to content

Commit bda0eae

Browse files
author
Damian Rouson
committed
Merge branch 'add-team-number' into opencoarrays-teams
Status: 1. team-number.f90 test builds and passes when run outside of ctest (need to diagnose why it fails when run by ctest). 2. get-communicator.f90 test fails to build because cmake can't find mpi.mod.
2 parents 6c93c47 + 3ebb293 commit bda0eae

File tree

9 files changed

+279
-6
lines changed

9 files changed

+279
-6
lines changed

CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,8 @@ if (NOT MPIEXEC)
239239
report this bug to the OpenCoarrays developers at
240240
https://github.com/sourceryinstitute/opencoarrays/issues, otherwise point CMake
241241
to the desired MPI runtime.")
242+
else()
243+
add_definitions(-DHAVE_MPI)
242244
endif()
243245

244246
get_filename_component(MPIEXEC_RELATIVE_LOC "${MPIEXEC}"
@@ -644,6 +646,10 @@ if(opencoarrays_aware_compiler)
644646
add_caf_test(async_comp_alloc_2 2 async_comp_alloc_2)
645647
add_caf_test(comp_allocated_1 2 comp_allocated_1)
646648
add_caf_test(comp_allocated_2 2 comp_allocated_2)
649+
if(NOT CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 8)
650+
add_caf_test(team_number 2 ${tests_root}/unit/teams/team_number)
651+
add_caf_test(get_communicator 3 ${tests_root}/unit/teams/get_communicator)
652+
endif()
647653
endif()
648654
add_caf_test(get_array 2 get_array)
649655
add_caf_test(get_self 2 get_self)
@@ -676,6 +682,7 @@ if(opencoarrays_aware_compiler)
676682
add_caf_test(co_heat 2 co_heat)
677683
add_caf_test(asynchronous_hello_world 3 asynchronous_hello_world)
678684

685+
679686
# Regression tests based on reported issues
680687
if((gfortran_compiler AND (NOT CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 7.0.0)) OR (CAF_RUN_DEVELOPER_TESTS OR $ENV{OPENCOARRAYS_DEVELOPER}))
681688
if( CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 7.0.0 )

src/extensions/opencoarrays.F90

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ module opencoarrays
4646
public :: num_images
4747
public :: error_stop
4848
public :: sync_all
49+
public :: team_number
50+
#ifdef HAVE_MPI
51+
public :: get_communicator
52+
#endif
4953
#ifdef COMPILER_SUPPORTS_ATOMICS
5054
public :: event_type
5155
public :: event_post
@@ -102,6 +106,31 @@ pure function logical_operator(lhs,rhs) result(lhs_op_rhs)
102106
end function
103107
end interface
104108

109+
interface
110+
#ifdef COMPILER_SUPPORTS_CAF_INTRINSICS
111+
function team_number(team_type_ptr) result(my_team_number) bind(C,name="_caf_extensions_team_number")
112+
#else
113+
function team_number(team_type_ptr) result(my_team_number) bind(C,name="_gfortran_caf_team_number")
114+
#endif
115+
use iso_c_binding, only : c_int,c_ptr
116+
implicit none
117+
type(c_ptr), optional :: team_type_ptr
118+
integer(c_int) :: my_team_number
119+
end function
120+
121+
#ifdef COMPILER_SUPPORTS_CAF_INTRINSICS
122+
function get_communicator(team_type_ptr) result(my_team) bind(C,name="_caf_extensions_get_communicator")
123+
#else
124+
function get_communicator(team_type_ptr) result(my_team) bind(C,name="_gfortran_caf_get_communicator")
125+
#endif
126+
use iso_c_binding, only : c_int,c_ptr
127+
implicit none
128+
type(c_ptr), optional :: team_type_ptr
129+
integer(c_int) :: my_team
130+
end function
131+
end interface
132+
133+
105134
! __________ End Public Interface _____________
106135

107136

src/libcaf.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
3434

3535
#include "libcaf-gfortran-descriptor.h"
3636

37+
#include <mpi.h>
38+
3739
#ifndef __GNUC__
3840
#define __attribute__(x)
3941
#define likely(x) (x)
@@ -89,7 +91,6 @@ typedef enum caf_deregister_t {
8991
caf_deregister_t;
9092

9193
typedef void* caf_token_t;
92-
#ifdef GCC_GE_7
9394
/** Add a dummy type representing teams in coarrays. */
9495

9596
typedef void * caf_team_t;
@@ -107,7 +108,6 @@ typedef struct caf_used_teams_list {
107108
}
108109
caf_used_teams_list;
109110

110-
#endif
111111

112112
/* When there is a vector subscript in this dimension, nvec == 0, otherwise,
113113
lower_bound, upper_bound, stride contains the bounds relative to the declared
@@ -288,6 +288,7 @@ void PREFIX (form_team) (int, caf_team_t *, int);
288288
void PREFIX (change_team) (caf_team_t *, int);
289289
void PREFIX (end_team) (caf_team_t *);
290290
void PREFIX (sync_team) (caf_team_t *, int);
291+
int PREFIX (team_number) (caf_team_t *);
291292

292293
int PREFIX (image_status) (int);
293294
void PREFIX (failed_images) (gfc_descriptor_t *, int, int *);
@@ -305,4 +306,10 @@ void PREFIX (unlock) (caf_token_t, size_t, int, int *, char *, int);
305306
void PREFIX (event_post) (caf_token_t, size_t, int, int *, char *, int);
306307
void PREFIX (event_wait) (caf_token_t, size_t, int, int *, char *, int);
307308
void PREFIX (event_query) (caf_token_t, size_t, int, int *, int *);
309+
310+
/* Language extension */
311+
#ifdef HAVE_MPI
312+
MPI_Fint PREFIX (get_communicator) (caf_team_t *);
313+
#endif
314+
308315
#endif /* LIBCAF_H */

src/mpi/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,6 @@ install(TARGETS caf_mpi_static EXPORT OpenCoarraysTargets
186186
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
187187
)
188188

189-
190189
##############################################
191190
# Configure `caf` and `cafrun` wrapper scripts
192191
##############################################

src/mpi/mpi_caf.c

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5223,7 +5223,7 @@ void PREFIX (change_team) (caf_team_t *team, int coselector __attribute__ ((unus
52235223

52245224
if(tmp_list == NULL)
52255225
caf_runtime_error("CHANGE TEAM called on a non-existing team");
5226-
5226+
52275227
tmp_used->team_list_elem = tmp_list;
52285228
used_teams = tmp_used;
52295229
tmp_team = tmp_used->team_list_elem->team;
@@ -5234,6 +5234,30 @@ void PREFIX (change_team) (caf_team_t *team, int coselector __attribute__ ((unus
52345234
MPI_Comm_size(*tmp_comm,&caf_num_images);
52355235
}
52365236

5237+
MPI_Fint
5238+
PREFIX (get_communicator) (caf_team_t *team)
5239+
{
5240+
if(team != NULL) caf_runtime_error("get_communicator does not yet support the optional team argument");
5241+
5242+
MPI_Comm* comm_ptr = teams_list->team;
5243+
5244+
MPI_Fint ret = MPI_Comm_c2f(*comm_ptr);
5245+
5246+
return ret;
5247+
5248+
// return *(int*)comm_ptr;
5249+
}
5250+
5251+
int
5252+
PREFIX (team_number) (caf_team_t *team)
5253+
{
5254+
if(team != NULL) caf_runtime_error("team_number does not yet support the optional team argument");
5255+
5256+
/* if(used_teams->prev == NULL) */
5257+
/* return -1; */
5258+
return used_teams->team_list_elem->team_id;
5259+
}
5260+
52375261
void PREFIX (end_team) (caf_team_t *team __attribute__ ((unused)))
52385262
{
52395263
caf_used_teams_list *tmp_used = NULL;

src/tests/unit/CMakeLists.txt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,13 @@ if (${opencoarrays_aware_compiler})
55
add_subdirectory(collectives)
66
add_subdirectory(sync)
77
add_subdirectory(events)
8-
if(NOT CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 7)
9-
add_subdirectory(fail_images)
8+
if (gfortran_compiler)
9+
if(NOT CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 7)
10+
add_subdirectory(fail_images)
11+
if(NOT CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 8)
12+
add_subdirectory(teams)
13+
endif()
14+
endif()
1015
endif()
1116
else()
1217
add_subdirectory(extensions)

src/tests/unit/teams/CMakeLists.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
add_executable(team_number team-number.f90)
2+
target_link_libraries(team_number OpenCoarrays)
3+
#TODO: Remove when gfortran supports team_number()
4+
target_include_directories(team_number PRIVATE ${CMAKE_BINARY_DIR}/include)
5+
6+
#add_executable(get_communicator get-communicator.f90)
7+
#target_link_libraries(get_communicator OpenCoarrays)
8+
#TODO: Remove when gfortran supports team_number()
9+
#target_include_directories(get_communicator PRIVATE ${CMAKE_BINARY_DIR}/include)
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
! BSD 3-Clause License
2+
!
3+
! Copyright (c) 2016, Sourcery Institute
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+
!
9+
! * Redistributions of source code must retain the above copyright notice, this
10+
! list of conditions and the following disclaimer.
11+
!
12+
! * Redistributions in binary form must reproduce the above copyright notice,
13+
! this list of conditions and the following disclaimer in the documentation
14+
! and/or other materials provided with the distribution.
15+
!
16+
! * Neither the name of the copyright holder nor the names of its
17+
! contributors may be used to endorse or promote products derived from
18+
! this software without specific prior written permission.
19+
!
20+
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21+
! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22+
! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23+
! DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24+
! FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25+
! DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26+
! SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27+
! CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28+
! OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29+
! OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30+
program main
31+
!! summary: Test get_commiunicator function, an OpenCoarrays-specific language extension
32+
use opencoarrays, only : get_communicator
33+
34+
implicit none
35+
36+
call mpi_matches_caf(get_communicator())
37+
!! verify # ranks = # images and image number = rank + 1
38+
39+
block
40+
use iso_fortran_env, only : team_type
41+
use opencoarrays, only : get_communicator, team_number !! TODO: remove team_number once gfortran supports it
42+
43+
type(team_type) :: league
44+
integer, parameter :: num_teams=2
45+
!! number of child teams to form from the parent initial team
46+
47+
associate(initial_image=>this_image(), initial_num_images=>num_images(), chosen_team=>destination_team(this_image(),num_teams))
48+
49+
form team(chosen_team,league)
50+
!! map images to num_teams teams
51+
52+
change team(league)
53+
!! join my destination team
54+
55+
call mpi_matches_caf(get_communicator())
56+
!! verify new # ranks = new # images and new image number = new rank + 1
57+
58+
associate(my_team=>team_number())
59+
call assert(my_team==chosen_team,"assigned team matches chosen team")
60+
associate(new_num_images=>initial_num_images/num_teams+merge(1,0,my_team<=mod(initial_num_images,num_teams)))
61+
call assert(num_images()==new_num_images,"block distribution of images")
62+
end associate
63+
end associate
64+
65+
end team
66+
67+
call assert( initial_image==this_image(),"correctly remapped to original image number")
68+
call assert( initial_num_images==num_images(),"correctly remapped to original number of images")
69+
70+
end associate
71+
72+
end block
73+
74+
sync all
75+
if (this_image()==1) print *,"Test passed."
76+
77+
contains
78+
79+
pure function destination_team(image,numTeams) result(team)
80+
integer, intent(in) ::image, numTeams
81+
integer ::team
82+
team = mod(image+1,numTeams)+1
83+
end function
84+
85+
subroutine mpi_matches_caf(comm)
86+
use iso_c_binding, only : c_int
87+
use mpi, only : MPI_COMM_SIZE, MPI_COMM_RANK
88+
integer(c_int), intent(in) :: comm
89+
!! MPI communicator
90+
integer(c_int) :: isize,ierror,irank
91+
92+
call MPI_COMM_SIZE(comm, isize, ierror)
93+
call assert( ierror==0 , "successful call MPI_COMM_SIZE" )
94+
call assert( isize==num_images(), "num MPI ranks = num CAF images " )
95+
96+
call MPI_COMM_RANK(comm, irank, ierror)
97+
call assert( ierror==0 , "successful call MPI_COMM_RANK" )
98+
call assert( irank==this_image()-1 , "correct rank/image-number correspondence" )
99+
100+
end subroutine
101+
102+
elemental subroutine assert(assertion,description)
103+
!! TODO: move this to a common place for all tests to use
104+
logical, intent(in) :: assertion
105+
character(len=*), intent(in) :: description
106+
integer, parameter :: max_digits=12
107+
character(len=max_digits) :: image_number
108+
if (.not.assertion) then
109+
write(image_number,*) this_image()
110+
error stop "Assertion '" // description // "' failed on image " // trim(image_number)
111+
end if
112+
end subroutine
113+
114+
end program

src/tests/unit/teams/team-number.f90

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
! BSD 3-Clause License
2+
!
3+
! Copyright (c) 2016, Sourcery Institute
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+
!
9+
! * Redistributions of source code must retain the above copyright notice, this
10+
! list of conditions and the following disclaimer.
11+
!
12+
! * Redistributions in binary form must reproduce the above copyright notice,
13+
! this list of conditions and the following disclaimer in the documentation
14+
! and/or other materials provided with the distribution.
15+
!
16+
! * Neither the name of the copyright holder nor the names of its
17+
! contributors may be used to endorse or promote products derived from
18+
! this software without specific prior written permission.
19+
!
20+
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21+
! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22+
! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23+
! DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24+
! FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25+
! DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26+
! SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27+
! CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28+
! OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29+
! OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30+
program main
31+
!! summary: Test team_number intrinsic function
32+
use iso_fortran_env, only : team_type
33+
use iso_c_binding, only : c_loc
34+
35+
use opencoarrays, only : team_number
36+
!! TODO: remove the above line below after the compiler supports team_number
37+
38+
implicit none
39+
40+
integer, parameter :: standard_initial_value=-1
41+
42+
type(team_type), target :: home
43+
44+
call assert(team_number()==standard_initial_value,"initial team number conforms with Fortran standard before 'change team'")
45+
46+
!call assert(
47+
! team_number(c_loc(home))==standard_initial_value,"initial team number conforms with Fortran standard before 'change team'"
48+
!)
49+
!! TODO: uncomment the above assertion after implementing support for team_number's optional argument:
50+
51+
after_change_team: block
52+
associate(my_team=>mod(this_image(),2)+1)
53+
!! Prepare for forming two teams: my_team = 1 for even image numbers in the initial team; 2 for odd image numbers
54+
form team(my_team,home)
55+
change team(home)
56+
call assert(team_number()==my_team,"team number conforms with Fortran standard after 'change team'")
57+
end team
58+
call assert(team_number()==standard_initial_value,"initial team number conforms with Fortran standard")
59+
end associate
60+
end block after_change_team
61+
62+
sync all
63+
if (this_image()==1) print *,"Test passed."
64+
65+
contains
66+
67+
elemental subroutine assert(assertion,description)
68+
!! TODO: move this to a common place for all tests to use
69+
logical, intent(in) :: assertion
70+
character(len=*), intent(in) :: description
71+
integer, parameter :: max_digits=12
72+
character(len=max_digits) :: image_number
73+
if (.not.assertion) then
74+
write(image_number,*) this_image()
75+
error stop "Assertion " // description // "failed on image " // trim(image_number)
76+
end if
77+
end subroutine
78+
79+
end program

0 commit comments

Comments
 (0)