diff options
author | burnus <burnus@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-03-27 09:01:34 +0000 |
---|---|---|
committer | burnus <burnus@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-03-27 09:01:34 +0000 |
commit | e60f31f13516fd8e5ade83ff86e057bfa8e1baf1 (patch) | |
tree | cf54dd924454ebbfa0ca7cf4e63c9f60cc95aacd /libgfortran/caf | |
parent | 7edb1e834d1cc8b8a25cc060e08c68f539a56584 (diff) | |
download | gcc-e60f31f13516fd8e5ade83ff86e057bfa8e1baf1.tar.gz |
2011-03-27 Tobias Burnus <burnus@net-b.de>
PR fortran/18918
* caf/libcaf.h: New - coarray communication library.
* caf/mpi.c: New.
* caf/single.c: New.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@171570 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgfortran/caf')
-rw-r--r-- | libgfortran/caf/libcaf.h | 53 | ||||
-rw-r--r-- | libgfortran/caf/mpi.c | 211 | ||||
-rw-r--r-- | libgfortran/caf/single.c | 107 |
3 files changed, 371 insertions, 0 deletions
diff --git a/libgfortran/caf/libcaf.h b/libgfortran/caf/libcaf.h new file mode 100644 index 00000000000..8a66ef3deff --- /dev/null +++ b/libgfortran/caf/libcaf.h @@ -0,0 +1,53 @@ +/* Common declarations for all of GNU Fortran libcaf implementations. + Copyright (C) 2011 + Free Software Foundation, Inc. + Contributed by Tobias Burnus <burnus@net-b.de> + +This file is part of the GNU Fortran Coarray Runtime Library (libcaf). + +Libcaf is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +Libcaf is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. */ + +#ifndef LIBCAF_H +#define LIBCAF_H + +#include <stdint.h> +#include <string.h> + +/* Definitions of the Fortran 2008 standard; need to kept in sync with + ISO_FORTRAN_ENV, cf. libgfortran.h. */ +#define STAT_UNLOCKED 0 +#define STAT_LOCKED 1 +#define STAT_LOCKED_OTHER_IMAGE 2 +#define STAT_STOPPED_IMAGE 3 + + +void _gfortran_caf_init (int *, char ***, int *, int *); +void _gfortran_caf_finalize (void); + +int _gfortran_caf_sync_all (char *, int); +int _gfortran_caf_sync_images (int count, int images[], char *, int); + +void _gfortran_caf_critical (void); +void _gfortran_caf_end_critical (void); + +void _gfortran_caf_error_stop_str (const char *, int32_t) __attribute__ ((noreturn)); +void _gfortran_caf_error_stop (int32_t) __attribute__ ((noreturn)); + +#endif /* LIBCAF_H */ diff --git a/libgfortran/caf/mpi.c b/libgfortran/caf/mpi.c new file mode 100644 index 00000000000..634e240bf19 --- /dev/null +++ b/libgfortran/caf/mpi.c @@ -0,0 +1,211 @@ +/* MPI implementation of GNU Fortran Coarray Library + Copyright (C) 2011 + Free Software Foundation, Inc. + Contributed by Tobias Burnus <burnus@net-b.de> + +This file is part of the GNU Fortran Coarray Runtime Library (libcaf). + +Libcaf is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +Libcaf is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. */ + +#include "libcaf.h" +#include <stdio.h> +#include <stdlib.h> +#include <mpi.h> + +/* Define GFC_CAF_CHECK to enable run-time checking. */ +/* #define GFC_CAF_CHECK 1 */ + + +static void error_stop (int error) __attribute__ ((noreturn)); + +/* Global variables. */ +static int caf_this_image; +static int caf_num_images; +static MPI_Win caf_world_window; + + +/* Initialize coarray program. This routine assumes that no other + MPI initialization happened before; otherwise MPI_Initialized + had to be used. As the MPI library might modify the command-line + arguments, the routine should be called before the run-time + libaray is initialized. */ + +void +_gfortran_caf_init (int *argc, char ***argv, int *this_image, int *num_images) +{ + int flag; + + /* The following is only the case if one does not have a Fortran + main program. */ + MPI_Initialized (&flag); + if (!flag) + MPI_Init (argc, argv); + + MPI_Comm_rank (MPI_COMM_WORLD, &caf_this_image); + *this_image = caf_this_image + 1; + MPI_Comm_size (MPI_COMM_WORLD, &caf_num_images); + *num_images = caf_num_images; + + /* Obtain window for CRITICAL section locking. */ + MPI_Win_create (NULL, 0, 1, MPI_INFO_NULL, MPI_COMM_WORLD, + &caf_world_window); +} + + +/* Finalize coarray program. Note: This is only called before the + program ends; thus the MPI_Initialized status of _gfortran_caf_init + does not play a role. */ + +void +_gfortran_caf_finalize (void) +{ + MPI_Win_free (&caf_world_window); + MPI_Finalize (); +} + + +/* SYNC ALL - the return value matches Fortran's STAT argument. */ + +int +_gfortran_caf_sync_all (char *errmsg, int errmsg_len) +{ + int ierr; + ierr = MPI_Barrier (MPI_COMM_WORLD); + + if (ierr && errmsg_len > 0) + { + const char msg[] = "SYNC ALL failed"; + int len = ((int) sizeof (msg) > errmsg_len) ? errmsg_len + : (int) sizeof (msg); + memcpy (errmsg, msg, len); + if (errmsg_len > len) + memset (&errmsg[len], ' ', errmsg_len-len); + } + + /* TODO: Is ierr correct? When should STAT_STOPPED_IMAGE be used? */ + return ierr; +} + + +/* SYNC IMAGES. Note: SYNC IMAGES(*) is passed as count == -1 while + SYNC IMAGES([]) has count == 0. Note further that SYNC IMAGES(*) + is not equivalent to SYNC ALL. The return value matches Fortran's + STAT argument. */ +int +_gfortran_caf_sync_images (int count, int images[], char *errmsg, + int errmsg_len) +{ + int ierr; + + if (count == 0 || (count == 1 && images[0] == caf_this_image)) + return 0; + +#ifdef GFC_CAF_CHECK + { + int i; + + for (i = 0; i < count; i++) + if (images[i] < 1 || images[i] > caf_num_images) + { + fprintf (stderr, "COARRAY ERROR: Invalid image index %d to SYNC " + "IMAGES", images[i]); + error_stop (1); + } + } +#endif + + /* FIXME: SYNC IMAGES with a nontrivial argument cannot easily be + mapped to MPI communicators. Thus, exist early with an error message. */ + if (count > 0) + { + fprintf (stderr, "COARRAY ERROR: SYNC IMAGES not yet implemented"); + error_stop (1); + } + + /* Handle SYNC IMAGES(*). */ + ierr = MPI_Barrier (MPI_COMM_WORLD); + + if (ierr && errmsg_len > 0) + { + const char msg[] = "SYNC IMAGES failed"; + int len = ((int) sizeof (msg) > errmsg_len) ? errmsg_len + : (int) sizeof (msg); + memcpy (errmsg, msg, len); + if (errmsg_len > len) + memset (&errmsg[len], ' ', errmsg_len-len); + } + + /* TODO: Is ierr correct? When should STAT_STOPPED_IMAGE be used? */ + return ierr; +} + + +/* CRITICAL BLOCK. */ + +void +_gfortran_caf_critical (void) +{ + MPI_Win_lock (MPI_LOCK_SHARED, 0, 0, caf_world_window); +} + + +void +_gfortran_caf_end_critical (void) +{ + MPI_Win_unlock (0, caf_world_window); +} + + +/* ERROR STOP the other images. */ + +static void +error_stop (int error) +{ + /* FIXME: Shutdown the Fortran RTL to flush the buffer. PR 43849. */ + /* FIXME: Do some more effort than just MPI_ABORT. */ + MPI_Abort (MPI_COMM_WORLD, error); + + /* Should be unreachable, but to make sure also call exit. */ + exit (error); +} + + +/* ERROR STOP function for string arguments. */ + +void +_gfortran_caf_error_stop_str (const char *string, int32_t len) +{ + fputs ("ERROR STOP ", stderr); + while (len--) + fputc (*(string++), stderr); + fputs ("\n", stderr); + + error_stop (1); +} + + +/* ERROR STOP function for numerical arguments. */ + +void +_gfortran_caf_error_stop (int32_t error) +{ + fprintf (stderr, "ERROR STOP %d\n", error); + error_stop (error); +} diff --git a/libgfortran/caf/single.c b/libgfortran/caf/single.c new file mode 100644 index 00000000000..7ee37b3a99d --- /dev/null +++ b/libgfortran/caf/single.c @@ -0,0 +1,107 @@ +/* Single-image implementation of GNU Fortran Coarray Library + Copyright (C) 2011 + Free Software Foundation, Inc. + Contributed by Tobias Burnus <burnus@net-b.de> + +This file is part of the GNU Fortran Coarray Runtime Library (libcaf). + +Libcaf is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +Libcaf is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. */ + +#include "libcaf.h" +#include <stdio.h> /* For fputs and fprintf. */ +#include <stdlib.h> /* For exit. */ + +/* Define GFC_CAF_CHECK to enable run-time checking. */ +/* #define GFC_CAF_CHECK 1 */ + + +/* Single-image implementation of the CAF library. + Note: For performance reasons -fcoarry=single should be used + rather than this library. */ + +void +_gfortran_caf_init (int *argc __attribute__ ((unused)), + char ***argv __attribute__ ((unused)), + int *this_image, int *num_images) +{ + *this_image = 1; + *num_images = 1; +} + +void +_gfortran_caf_finalize (void) +{ +} + +int +_gfortran_caf_sync_all (char *errmsg __attribute__ ((unused)), + int errmsg_len __attribute__ ((unused))) +{ + return 0; +} + +int +_gfortran_caf_sync_images (int count __attribute__ ((unused)), + int images[] __attribute__ ((unused)), + char *errmsg __attribute__ ((unused)), + int errmsg_len __attribute__ ((unused))) +{ +#ifdef GFC_CAF_CHECK + int i; + + for (i = 0; i < count; i++) + if (images[i] != 1) + { + fprintf (stderr, "COARRAY ERROR: Invalid image index %d to SYNC " + "IMAGES", images[i]); + exit (1); + } +#endif + + return 0; +} + +void +_gfortran_caf_critical (void) +{ +} + +void +_gfortran_caf_end_critical (void) +{ +} + +void +_gfortran_caf_error_stop_str (const char *string, int32_t len) +{ + fputs ("ERROR STOP ", stderr); + while (len--) + fputc (*(string++), stderr); + fputs ("\n", stderr); + + exit (1); +} + +void +_gfortran_caf_error_stop (int32_t error) +{ + fprintf (stderr, "ERROR STOP %d\n", error); + exit (error); +} |