From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 10039 invoked by alias); 16 Jun 2011 09:39:43 -0000 Received: (qmail 10019 invoked by uid 22791); 16 Jun 2011 09:39:41 -0000 X-SWARE-Spam-Status: No, hits=-2.7 required=5.0 tests=AWL,BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,RFC_ABUSE_POST X-Spam-Check-By: sourceware.org Received: from mail-fx0-f47.google.com (HELO mail-fx0-f47.google.com) (209.85.161.47) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 16 Jun 2011 09:39:19 +0000 Received: by fxm19 with SMTP id 19so1176232fxm.20 for ; Thu, 16 Jun 2011 02:39:17 -0700 (PDT) Received: by 10.223.85.155 with SMTP id o27mr800443fal.109.1308217157753; Thu, 16 Jun 2011 02:39:17 -0700 (PDT) Received: from [130.235.236.18] (ip236-18.wireless.lu.se [130.235.236.18]) by mx.google.com with ESMTPS id e15sm709900faa.47.2011.06.16.02.39.15 (version=SSLv3 cipher=OTHER); Thu, 16 Jun 2011 02:39:16 -0700 (PDT) Message-ID: <4DF9CF42.8030501@gmail.com> Date: Thu, 16 Jun 2011 09:45:00 -0000 From: Daniel Carrera User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.17) Gecko/20110424 Thunderbird/3.1.10 MIME-Version: 1.0 To: gfortran , gcc-patches@gcc.gnu.org Subject: [Patch, Fortra, Coarray] Free allocated memory for static coarrays. Content-Type: multipart/mixed; boundary="------------010409010202050506020708" Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2011-06/txt/msg01225.txt.bz2 This is a multi-part message in MIME format. --------------010409010202050506020708 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-length: 1255 Hello, This is my second patch for GFortran. This patch adds a linked list to keep track of the allocated memory of all static coarrays and ensures that at the end of the program the memory is freed. Additionally, I use MPI_Allgather in mpi.c to ensure that all images know the address of the stored memory in the other images. This will be needed when the images start sending data to each other. There is no test case attached because there is no way to automatically test for allocated memory. Here is my ChangeLog to go into libgfortran/ChangeLog: 2011-06-16 Daniel Carrera * 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. Cheers, Daniel. -- I'm not overweight, I'm undertall. --------------010409010202050506020708 Content-Type: text/x-patch; name="caf-free-memory.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="caf-free-memory.patch" Content-length: 4696 Index: libgfortran/caf/single.c =================================================================== --- libgfortran/caf/single.c (revision 174944) +++ libgfortran/caf/single.c (working copy) @@ -35,7 +35,10 @@ 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)), char ***argv __attribute__ ((unused)), @@ -49,16 +52,31 @@ 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); + + 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; } Index: libgfortran/caf/libcaf.h =================================================================== --- libgfortran/caf/libcaf.h (revision 174944) +++ libgfortran/caf/libcaf.h (working copy) @@ -38,15 +38,23 @@ #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_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); Index: libgfortran/caf/mpi.c =================================================================== --- libgfortran/caf/mpi.c (revision 174944) +++ libgfortran/caf/mpi.c (working copy) @@ -42,7 +42,10 @@ 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 had to be used. As the MPI library might modify the command-line @@ -52,36 +55,68 @@ 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_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; + MPI_Comm_size (MPI_COMM_WORLD, &caf_num_images); + MPI_Comm_rank (MPI_COMM_WORLD, &caf_this_image); + caf_this_image++; + } + + if (this_image) + this_image = caf_this_image; + if (num_images) + num_images = caf_num_images; } + /* Finalize coarray program. */ 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; + + local = malloc (size); + token = malloc (sizeof (void*) * caf_num_images); + + /* Start MPI if not already started. */ + if (caf_num_images == 0) + _gfortran_caf_init (NULL, NULL, NULL, NULL); + + /* token[img-1] is the address of the token in image "img". */ + MPI_Allgather (local, sizeof (void*), MPI_BYTE, + token[0], 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; } --------------010409010202050506020708--