+2011-06-17 Daniel Carrera <dcarrera@gmail.com>
+
+ * caf/single.c (_gfortran_caf_register): Store the address
+ of all static coarrays in a linked list.
+ (_gfortran_caf_finalize): Free memory of staic coarrays.
+ * caf/mpi.c (_gfortran_caf_register): Store the address
+ of all static coarrays in a linked list. Initialize MPI
+ if necessary.
+ (_gfortran_caf_finalize): Free memory of staic coarrays.
+ (_gfortran_caf_init): Check if MPI is already initialized
+ before initializing again.
+ * caf/libcaf.h: Add a type to caf_register_t to distinguish
+ static coarrays and add the type caf_static_t to make the
+ linked list of static coarrays.
+
2011-06-11 Janne Blomqvist <jb@gcc.gnu.org>
* io/unix.c (buf_seek): Return error if file is not seekable.
#define STAT_LOCKED_OTHER_IMAGE 2
#define STAT_STOPPED_IMAGE 3
-
+/* Describes what type of array we are registerring. */
typedef enum caf_register_t {
- CAF_REGTYPE_COARRAY,
+ CAF_REGTYPE_COARRAY_STATIC,
+ CAF_REGTYPE_COARRAY_ALLOC,
CAF_REGTYPE_LOCK,
- CAF_REGTYPE_LOCK_COMP
+ CAF_REGTYPE_LOCK_COMP
}
caf_register_t;
+/* Linked list of static coarrays registered. */
+typedef struct caf_static_t {
+ void **token;
+ struct caf_static_t *prev;
+}
+caf_static_t;
+
void _gfortran_caf_init (int *, char ***, int *, int *);
void _gfortran_caf_finalize (void);
static int caf_this_image;
static int caf_num_images;
+caf_static_t *caf_static_list = NULL;
+
/* Initialize coarray program. This routine assumes that no other
MPI initialization happened before; otherwise MPI_Initialized
void
_gfortran_caf_init (int *argc, char ***argv, int *this_image, int *num_images)
{
- /* caf_mpi_initialized is only true if the main program is not written in
- Fortran. */
- MPI_Initialized (&caf_mpi_initialized);
- if (!caf_mpi_initialized)
- MPI_Init (argc, argv);
+ if (caf_num_images == 0)
+ {
+ /* caf_mpi_initialized is only true if the main program is
+ not written in Fortran. */
+ MPI_Initialized (&caf_mpi_initialized);
+ if (!caf_mpi_initialized)
+ MPI_Init (argc, argv);
+
+ MPI_Comm_size (MPI_COMM_WORLD, &caf_num_images);
+ MPI_Comm_rank (MPI_COMM_WORLD, &caf_this_image);
+ caf_this_image++;
+ }
- MPI_Comm_rank (MPI_COMM_WORLD, &caf_this_image);
- *this_image = ++caf_this_image;
- MPI_Comm_size (MPI_COMM_WORLD, &caf_num_images);
- *num_images = caf_num_images;
+ if (this_image)
+ *this_image = caf_this_image;
+ if (num_images)
+ *num_images = caf_num_images;
}
void
_gfortran_caf_finalize (void)
{
+ while (caf_static_list != NULL)
+ {
+ free(caf_static_list->token[caf_this_image-1]);
+ caf_static_list = caf_static_list->prev;
+ }
+
if (!caf_mpi_initialized)
MPI_Finalize ();
}
void *
-_gfortran_caf_register (ptrdiff_t size,
- caf_register_t type __attribute__ ((unused)),
+_gfortran_caf_register (ptrdiff_t size, caf_register_t type,
void **token)
{
- *token = NULL;
- return malloc (size);
+ void *local;
+
+ /* Start MPI if not already started. */
+ if (caf_num_images == 0)
+ _gfortran_caf_init (NULL, NULL, NULL, NULL);
+
+ /* Token contains only a list of pointers. */
+ local = malloc (size);
+ token = malloc (sizeof (void*) * caf_num_images);
+
+ /* token[img-1] is the address of the token in image "img". */
+ MPI_Allgather (&local, sizeof (void*), MPI_BYTE,
+ token, sizeof (void*), MPI_BYTE, MPI_COMM_WORLD);
+
+ if (type == CAF_REGTYPE_COARRAY_STATIC)
+ {
+ caf_static_t *tmp = malloc (sizeof (caf_static_t));
+ tmp->prev = caf_static_list;
+ tmp->token = token;
+ caf_static_list = tmp;
+ }
+ return local;
}
Note: For performance reasons -fcoarry=single should be used
rather than this library. */
+/* Global variables. */
+caf_static_t *caf_static_list = NULL;
+
void
_gfortran_caf_init (int *argc __attribute__ ((unused)),
void
_gfortran_caf_finalize (void)
{
+ while (caf_static_list != NULL)
+ {
+ free(caf_static_list->token[0]);
+ caf_static_list = caf_static_list->prev;
+ }
}
void *
-_gfortran_caf_register (ptrdiff_t size,
- caf_register_t type __attribute__ ((unused)),
+_gfortran_caf_register (ptrdiff_t size, caf_register_t type,
void **token)
{
- *token = NULL;
- return malloc (size);
+ void *local;
+
+ local = malloc (size);
+ token = malloc (sizeof (void*) * 1);
+ token[0] = local;
+
+ if (type == CAF_REGTYPE_COARRAY_STATIC)
+ {
+ caf_static_t *tmp = malloc (sizeof (caf_static_t));
+ tmp->prev = caf_static_list;
+ tmp->token = token;
+ caf_static_list = tmp;
+ }
+ return local;
}
*stat = 0;
}
+
void
_gfortran_caf_sync_images (int count __attribute__ ((unused)),
int images[] __attribute__ ((unused)),