void _gfortran_caf_deregister (caf_token_t *token, int *stat, char *errmsg, int errmsg_len) { if (unlikely (caf_is_finalized)) { const char msg[] = "Failed to deallocate coarray - " "there are stopped images"; if (stat) { *stat = STAT_STOPPED_IMAGE; if (errmsg_len > 0) { int len = ((int) sizeof (msg) - 1 > errmsg_len) ? errmsg_len : (int) sizeof (msg) - 1; memcpy (errmsg, msg, len); if (errmsg_len > len) memset (&errmsg[len], ' ', errmsg_len-len); } return; } caf_runtime_error (msg); } _gfortran_caf_sync_all (NULL, NULL, 0); if (stat) *stat = 0; free (TOKEN (*token)[caf_this_image-1]); free (*token); }
void _gfortran_caf_sync_all (int *stat, char *errmsg, int errmsg_len) { int ierr; if (unlikely (caf_is_finalized)) ierr = STAT_STOPPED_IMAGE; else ierr = MPI_Barrier (MPI_COMM_WORLD); if (stat) *stat = ierr; if (ierr) { char *msg; if (caf_is_finalized) msg = "SYNC ALL failed - there are stopped images"; else msg = "SYNC ALL failed"; if (errmsg_len > 0) { int len = ((int) strlen (msg) > errmsg_len) ? errmsg_len : (int) strlen (msg); memcpy (errmsg, msg, len); if (errmsg_len > len) memset (&errmsg[len], ' ', errmsg_len-len); } else caf_runtime_error (msg); } }
void * _gfortran_caf_register (size_t size, caf_register_t type, caf_token_t *token, int *stat, char *errmsg, int errmsg_len) { void *local; if (type == CAF_REGTYPE_LOCK_STATIC || type == CAF_REGTYPE_LOCK_ALLOC || type == CAF_REGTYPE_CRITICAL || type == CAF_REGTYPE_EVENT_STATIC || type == CAF_REGTYPE_EVENT_ALLOC) local = calloc (size, sizeof (bool)); else local = malloc (size); *token = malloc (sizeof (single_token_t)); if (unlikely (local == NULL || token == NULL)) { const char msg[] = "Failed to allocate coarray"; if (stat) { *stat = 1; if (errmsg_len > 0) { 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); } return NULL; } else caf_runtime_error (msg); } *token = local; if (stat) *stat = 0; if (type == CAF_REGTYPE_COARRAY_STATIC || type == CAF_REGTYPE_LOCK_STATIC || type == CAF_REGTYPE_CRITICAL || type == CAF_REGTYPE_EVENT_STATIC || type == CAF_REGTYPE_EVENT_ALLOC) { caf_static_t *tmp = malloc (sizeof (caf_static_t)); tmp->prev = caf_static_list; tmp->token = *token; caf_static_list = tmp; } return local; }
/* 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. */ void _gfortran_caf_sync_images (int count, int images[], int *stat, char *errmsg, int errmsg_len) { int ierr; if (count == 0 || (count == 1 && images[0] == caf_this_image)) { if (stat) *stat = 0; return; } #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(*). */ if (unlikely (caf_is_finalized)) ierr = STAT_STOPPED_IMAGE; else ierr = MPI_Barrier (MPI_COMM_WORLD); if (stat) *stat = ierr; if (ierr) { char *msg; if (caf_is_finalized) msg = "SYNC IMAGES failed - there are stopped images"; else msg = "SYNC IMAGES failed"; if (errmsg_len > 0) { int len = ((int) strlen (msg) > errmsg_len) ? errmsg_len : (int) strlen (msg); memcpy (errmsg, msg, len); if (errmsg_len > len) memset (&errmsg[len], ' ', errmsg_len-len); } else caf_runtime_error (msg); } }
void * _gfortran_caf_register (size_t size, caf_register_t type, caf_token_t *token, int *stat, char *errmsg, int errmsg_len) { void *local; int err; if (unlikely (caf_is_finalized)) goto error; /* Start MPI if not already started. */ if (caf_num_images == 0) _gfortran_caf_init (NULL, NULL); /* Token contains only a list of pointers. */ local = malloc (size); *token = malloc (sizeof (mpi_token_t) * caf_num_images); if (unlikely (local == NULL || *token == NULL)) goto error; /* token[img-1] is the address of the token in image "img". */ err = MPI_Allgather (&local, sizeof (void*), MPI_BYTE, TOKEN (*token), sizeof (void*), MPI_BYTE, MPI_COMM_WORLD); if (unlikely (err)) { free (local); free (*token); goto error; } 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; } if (stat) *stat = 0; return local; error: { char *msg; if (caf_is_finalized) msg = "Failed to allocate coarray - there are stopped images"; else msg = "Failed to allocate coarray"; if (stat) { *stat = caf_is_finalized ? STAT_STOPPED_IMAGE : 1; if (errmsg_len > 0) { int len = ((int) strlen (msg) > errmsg_len) ? errmsg_len : (int) strlen (msg); memcpy (errmsg, msg, len); if (errmsg_len > len) memset (&errmsg[len], ' ', errmsg_len-len); } } else caf_runtime_error (msg); } return NULL; }