Skip to content

Commit 994d436

Browse files
authored
Merge pull request #474 from sourceryinstitute/opencoarrays-teams
Merge opencoarrays-teams into master
2 parents d8d38e4 + 06dc2e2 commit 994d436

File tree

10 files changed

+441
-6
lines changed

10 files changed

+441
-6
lines changed

CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,8 @@ if (NOT MPIEXEC)
245245
report this bug to the OpenCoarrays developers at
246246
https://github.com/sourceryinstitute/opencoarrays/issues, otherwise point CMake
247247
to the desired MPI runtime.")
248+
else()
249+
add_definitions(-DHAVE_MPI)
248250
endif()
249251

250252
get_filename_component(MPIEXEC_RELATIVE_LOC "${MPIEXEC}"
@@ -656,6 +658,10 @@ if(opencoarrays_aware_compiler)
656658
add_caf_test(comp_allocated_1 2 comp_allocated_1)
657659
add_caf_test(comp_allocated_2 2 comp_allocated_2)
658660
add_caf_test(alloc_comp_get_convert_nums 2 alloc_comp_get_convert_nums)
661+
if(NOT CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 8)
662+
add_caf_test(team_number 2 ${tests_root}/unit/teams/team_number)
663+
add_caf_test(get_communicator 3 ${tests_root}/unit/teams/get_communicator)
664+
endif()
659665
endif()
660666

661667

@@ -730,6 +736,7 @@ if(opencoarrays_aware_compiler)
730736
add_caf_test(co_heat 2 co_heat)
731737
add_caf_test(asynchronous_hello_world 3 asynchronous_hello_world)
732738

739+
733740
# Regression tests based on reported issues
734741
if((gfortran_compiler AND (NOT CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 7.0.0)) OR (CAF_RUN_DEVELOPER_TESTS OR $ENV{OPENCOARRAYS_DEVELOPER}))
735742
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: 29 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,10 +91,23 @@ 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. */
95+
9496
typedef void * caf_team_t;
95-
#endif
97+
98+
typedef struct caf_teams_list {
99+
caf_team_t team;
100+
int team_id;
101+
struct caf_teams_list *prev;
102+
}
103+
caf_teams_list;
104+
105+
typedef struct caf_used_teams_list {
106+
struct caf_teams_list *team_list_elem;
107+
struct caf_used_teams_list *prev;
108+
}
109+
caf_used_teams_list;
110+
96111

97112
/* When there is a vector subscript in this dimension, nvec == 0, otherwise,
98113
lower_bound, upper_bound, stride contains the bounds relative to the declared
@@ -269,6 +284,12 @@ void PREFIX (error_stop_str) (const char *, int32_t)
269284
void PREFIX (error_stop) (int32_t) __attribute__ ((noreturn));
270285
void PREFIX (fail_image) (void) __attribute__ ((noreturn));
271286

287+
void PREFIX (form_team) (int, caf_team_t *, int);
288+
void PREFIX (change_team) (caf_team_t *, int);
289+
void PREFIX (end_team) (caf_team_t *);
290+
void PREFIX (sync_team) (caf_team_t *, int);
291+
int PREFIX (team_number) (caf_team_t *);
292+
272293
int PREFIX (image_status) (int);
273294
void PREFIX (failed_images) (gfc_descriptor_t *, int, int *);
274295
void PREFIX (stopped_images) (gfc_descriptor_t *, int, int *);
@@ -285,4 +306,10 @@ void PREFIX (unlock) (caf_token_t, size_t, int, int *, char *, int);
285306
void PREFIX (event_post) (caf_token_t, size_t, int, int *, char *, int);
286307
void PREFIX (event_wait) (caf_token_t, size_t, int, int *, char *, int);
287308
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+
288315
#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: 150 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,9 @@ char err_buffer[MPI_MAX_ERROR_STRING];
216216
MPI_COMM_WORLD for interoperability purposes. */
217217
MPI_Comm CAF_COMM_WORLD;
218218

219+
static caf_teams_list *teams_list = NULL;
220+
static caf_used_teams_list *used_teams = NULL;
221+
219222
/* Emitted when a theorectically unreachable part is reached. */
220223
const char unreachable[] = "Fatal error: unreachable alternative found.\n";
221224

@@ -801,6 +804,16 @@ PREFIX (init) (int *argc, char ***argv)
801804

802805
stat_tok = malloc (sizeof (MPI_Win));
803806

807+
teams_list = (caf_teams_list *)calloc(1,sizeof(caf_teams_list));
808+
teams_list->team_id = -1;
809+
MPI_Comm *tmp_comm = (MPI_Comm *)calloc(1,sizeof(MPI_Comm));
810+
*tmp_comm = CAF_COMM_WORLD;
811+
teams_list->team = tmp_comm;
812+
teams_list->prev = NULL;
813+
used_teams = (caf_used_teams_list *)calloc(1,sizeof(caf_used_teams_list));
814+
used_teams->team_list_elem = teams_list;
815+
used_teams->prev = NULL;
816+
804817
#ifdef WITH_FAILED_IMAGES
805818
MPI_Comm_dup (MPI_COMM_WORLD, &alive_comm);
806819
/* Handling of failed/stopped images is done by setting an error handler
@@ -7142,7 +7155,6 @@ PREFIX(atomic_ref) (caf_token_t token, size_t offset,
71427155
return;
71437156
}
71447157

7145-
71467158
void
71477159
PREFIX(atomic_cas) (caf_token_t token, size_t offset,
71487160
int image_index, void *old, void *compare,
@@ -7634,3 +7646,140 @@ unimplemented_alloc_comps_message (const char * functionname)
76347646
exit (EXIT_FAILURE);
76357647
#endif
76367648
}
7649+
7650+
void PREFIX (form_team) (int team_id, caf_team_t *team, int index __attribute__ ((unused)))
7651+
{
7652+
struct caf_teams_list *tmp;
7653+
void * tmp_team;
7654+
MPI_Comm *newcomm;
7655+
MPI_Comm *current_comm = &CAF_COMM_WORLD;
7656+
7657+
MPI_Barrier(CAF_COMM_WORLD);
7658+
newcomm = (MPI_Comm *)calloc(1,sizeof(MPI_Comm));
7659+
MPI_Comm_split(*current_comm, team_id, caf_this_image, newcomm);
7660+
7661+
tmp = calloc(1,sizeof(struct caf_teams_list));
7662+
tmp->prev = teams_list;
7663+
teams_list = tmp;
7664+
teams_list->team_id = team_id;
7665+
teams_list->team = newcomm;
7666+
*team = tmp;
7667+
}
7668+
7669+
void PREFIX (change_team) (caf_team_t *team, int coselector __attribute__ ((unused)))
7670+
{
7671+
caf_used_teams_list *tmp_used = NULL;
7672+
caf_teams_list * tmp_list = NULL;
7673+
void *tmp_team;
7674+
MPI_Comm *tmp_comm;
7675+
7676+
MPI_Barrier(CAF_COMM_WORLD);
7677+
tmp_list = (struct caf_teams_list *)*team;
7678+
tmp_team = (void *)tmp_list->team;
7679+
tmp_comm = (MPI_Comm *)tmp_team;
7680+
7681+
tmp_used = (caf_used_teams_list *)calloc(1,sizeof(caf_used_teams_list));
7682+
tmp_used->prev = used_teams;
7683+
7684+
/* /\* We need to look in the teams_list and find the appropriate element. */
7685+
/* * This is not efficient but can be easily fixed in the future. */
7686+
/* * Instead of keeping track of the communicator in the compiler */
7687+
/* * we should keep track of the caf_teams_list element associated with it. *\/ */
7688+
7689+
/* tmp_list = teams_list; */
7690+
7691+
/* while(tmp_list) */
7692+
/* { */
7693+
/* if(tmp_list->team == tmp_team) */
7694+
/* break; */
7695+
/* tmp_list = tmp_list->prev; */
7696+
/* } */
7697+
7698+
if(tmp_list == NULL)
7699+
caf_runtime_error("CHANGE TEAM called on a non-existing team");
7700+
7701+
tmp_used->team_list_elem = tmp_list;
7702+
used_teams = tmp_used;
7703+
tmp_team = tmp_used->team_list_elem->team;
7704+
tmp_comm = (MPI_Comm *)tmp_team;
7705+
CAF_COMM_WORLD = *tmp_comm;
7706+
MPI_Comm_rank(*tmp_comm,&caf_this_image);
7707+
caf_this_image++;
7708+
MPI_Comm_size(*tmp_comm,&caf_num_images);
7709+
}
7710+
7711+
MPI_Fint
7712+
PREFIX (get_communicator) (caf_team_t *team)
7713+
{
7714+
if(team != NULL) caf_runtime_error("get_communicator does not yet support the optional team argument");
7715+
7716+
MPI_Comm* comm_ptr = teams_list->team;
7717+
7718+
MPI_Fint ret = MPI_Comm_c2f(*comm_ptr);
7719+
7720+
return ret;
7721+
7722+
// return *(int*)comm_ptr;
7723+
}
7724+
7725+
int
7726+
PREFIX (team_number) (caf_team_t *team)
7727+
{
7728+
if(team != NULL) caf_runtime_error("team_number does not yet support the optional team argument");
7729+
7730+
/* if(used_teams->prev == NULL) */
7731+
/* return -1; */
7732+
return used_teams->team_list_elem->team_id;
7733+
}
7734+
7735+
void PREFIX (end_team) (caf_team_t *team __attribute__ ((unused)))
7736+
{
7737+
caf_used_teams_list *tmp_used = NULL;
7738+
void *tmp_team;
7739+
MPI_Comm *tmp_comm;
7740+
7741+
MPI_Barrier(CAF_COMM_WORLD);
7742+
if(used_teams->prev == NULL)
7743+
caf_runtime_error("END TEAM called on initial team");
7744+
7745+
tmp_used = used_teams;
7746+
used_teams = used_teams->prev;
7747+
free(tmp_used);
7748+
tmp_used = used_teams;
7749+
tmp_team = tmp_used->team_list_elem->team;
7750+
tmp_comm = (MPI_Comm *)tmp_team;
7751+
CAF_COMM_WORLD = *tmp_comm;
7752+
MPI_Barrier(CAF_COMM_WORLD);
7753+
/* CAF_COMM_WORLD = (MPI_Comm)*tmp_used->team_list_elem->team; */
7754+
MPI_Comm_rank(CAF_COMM_WORLD,&caf_this_image);
7755+
caf_this_image++;
7756+
MPI_Comm_size(CAF_COMM_WORLD,&caf_num_images);
7757+
}
7758+
7759+
void PREFIX (sync_team) (caf_team_t *team , int unused __attribute__ ((unused)))
7760+
{
7761+
caf_teams_list *tmp_list = NULL;
7762+
caf_used_teams_list *tmp_used = NULL;
7763+
void *tmp_team;
7764+
MPI_Comm *tmp_comm;
7765+
7766+
/* Check if the team is the current, and ancestor or a descendant. To be implemented. */
7767+
7768+
tmp_used = used_teams;
7769+
tmp_list = (struct caf_teams_list *)*team;
7770+
tmp_team = (void *)tmp_list->team;
7771+
tmp_comm = (MPI_Comm *)tmp_team;
7772+
7773+
while(tmp_used)
7774+
{
7775+
if(tmp_used->team_list_elem == tmp_list)
7776+
break;
7777+
tmp_used = tmp_used->prev;
7778+
}
7779+
7780+
if(tmp_used == NULL)
7781+
caf_runtime_error("SYNC TEAM called on team different from current or ancestor or descendant");
7782+
7783+
MPI_Barrier(*tmp_comm);
7784+
7785+
}

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)

0 commit comments

Comments
 (0)