aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Koenig <tkoenig@gcc.gnu.org>2021-10-04 22:34:53 +0200
committerThomas Koenig <tkoenig@gcc.gnu.org>2021-10-04 22:34:53 +0200
commit8df87c9e2c0a31c669625c4942d09b03d36c73e9 (patch)
tree1ac8786b5a56815c0c534f4b8deba011bfc46823
parentc92ee4037c3a6df882907c06ae6313d2dcb0cc0d (diff)
downloadgcc-8df87c9e2c0a31c669625c4942d09b03d36c73e9.zip
gcc-8df87c9e2c0a31c669625c4942d09b03d36c73e9.tar.gz
gcc-8df87c9e2c0a31c669625c4942d09b03d36c73e9.tar.bz2
Take memory from envirnoment variables; document those.
-rw-r--r--gcc/fortran/gfortran.texi31
-rw-r--r--gcc/fortran/invoke.texi9
-rw-r--r--libgfortran/caf_shared/coarraynative.c54
-rw-r--r--libgfortran/caf_shared/shared_memory.c12
-rw-r--r--libgfortran/caf_shared/shared_memory.h2
5 files changed, 94 insertions, 14 deletions
diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi
index a54153b..6c5ed84 100644
--- a/gcc/fortran/gfortran.texi
+++ b/gcc/fortran/gfortran.texi
@@ -608,6 +608,8 @@ Malformed environment variables are silently ignored.
* GFORTRAN_ERROR_BACKTRACE:: Show backtrace on run-time errors
* GFORTRAN_FORMATTED_BUFFER_SIZE:: Buffer size for formatted files
* GFORTRAN_UNFORMATTED_BUFFER_SIZE:: Buffer size for unformatted files
+* GFORTRAN_NUM_IMAGES:: Number of images to for -fcoarray=shared
+* GFORTRAN_SHARED_MEMORY_SIZE:: Memory for shared-memory coarrays
@end menu
@node TMPDIR
@@ -793,6 +795,35 @@ The @env{GFORTRAN_UNFORMATTED_BUFFER_SIZE} environment variable
specifies buffer size in bytes to be used for unformatted output.
The default value is 131072.
+@node GFORTRAN_NUM_IMAGES
+@section @env{GFORTRAN_NUM_IMAGES}---Set number of images for shared-memory coarrays
+
+The @env{GFORTRAN_NUM_IMAGES} environment variable specifies the number
+of images to be run for shared-memory coarrays, as an integer. The default
+value is the number of CPUs on the system.
+
+@node GFORTRAN_SHARED_MEMORY_SIZE
+@section @env{GFORTRAN_SHARED_MEMORY_SIZE}---Set size for shared-memory coarrays
+
+The @env{GFORTRAN_SHARED_MEMORY_SIZE} environment variable specifies
+the size of the shared memory block to be allocated for shared
+coarrays. It is safe on Linux and Darwin to make this larger than
+needed. When specifying this value, keep in mind that part of the space
+will not be available to the user program because of overhead.
+
+The format is an integer, optionally followed by @code{k} or @code{K}
+for a unit of kilobytes, @code{m} or @code{M} for a unit of megabytes
+and @code{g} or @code{G} for a unit of gitabytes.
+
+For example, if the size of all coarrays is known to be smaller than
+50 megabyte, the syntax could be
+@smallexample
+$ GFORTRAN_SHARED_MEMORY_SIZE=80M ./a.out
+@end smallexample
+
+The default is 256 kilobyte for 32-bit systems and 256 gigabyte for
+64-bit systems.
+
@c =====================================================================
@c PART II: LANGUAGE REFERENCE
@c =====================================================================
diff --git a/gcc/fortran/invoke.texi b/gcc/fortran/invoke.texi
index 0fb7e1a..e9f89cb 100644
--- a/gcc/fortran/invoke.texi
+++ b/gcc/fortran/invoke.texi
@@ -188,7 +188,7 @@ and warnings}.
-fbounds-check -ftail-call-workaround -ftail-call-workaround=@var{n} @gol
-fcheck-array-temporaries @gol
-fcheck=@var{<all|array-temps|bits|bounds|do|mem|pointer|recursion>} @gol
--fcoarray=@var{<none|single|lib>} -fexternal-blas -ff2c @gol
+-fcoarray=@var{<none|single|lib|shared>} -fexternal-blas -ff2c @gol
-ffrontend-loop-interchange -ffrontend-optimize @gol
-finit-character=@var{n} -finit-integer=@var{n} -finit-local-zero @gol
-finit-derived -finit-logical=@var{<true|false>} @gol
@@ -1607,6 +1607,13 @@ Single-image mode, i.e. @code{num_images()} is always one.
@item @samp{lib}
Library-based coarray parallelization; a suitable GNU Fortran coarray
library needs to be linked.
+
+@item @samp{shared}
+This enables an experimental shared-memory implementation of
+coarrays. Expect bugs and incomplete implementation. Currently,
+this depends on POSIX shared mutexes, so this option is not supported
+on systems which do not have them. There is no Windows implementation
+at the moment.
@end table
diff --git a/libgfortran/caf_shared/coarraynative.c b/libgfortran/caf_shared/coarraynative.c
index 1ae0c40..cf72433 100644
--- a/libgfortran/caf_shared/coarraynative.c
+++ b/libgfortran/caf_shared/coarraynative.c
@@ -35,6 +35,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#include <string.h>
#define GFORTRAN_ENV_NUM_IMAGES "GFORTRAN_NUM_IMAGES"
+#define GFORTRAN_ENV_SHARED_MEMORY_SIZE "GFORTRAN_SHARED_MEMORY_SIZE"
nca_local_data *local = NULL;
@@ -55,6 +56,54 @@ get_environ_image_num (void)
return nimages;
}
+/* Get the amount of memory for the shared memory block. This is picked from
+ an environment variable. If that is not there, pick a reasonable default.
+ Note that on a 64-bit system which allows overcommit, there is no penalty in
+ reserving a large space and then not using it. */
+
+static size_t
+get_memory_size (void)
+{
+ char *e;
+ size_t sz = 0;
+ e = getenv (GFORTRAN_ENV_SHARED_MEMORY_SIZE);
+ if (e)
+ {
+ char *num, suffix;
+ int rv;
+ rv = sscanf (e, "%zu%1s",&sz, &suffix);
+ if (rv == 2)
+ {
+ switch (suffix)
+ {
+ case 'k':
+ case 'K':
+ sz *= ((size_t) 1) << 10;
+ break;
+ case 'm':
+ case 'M':
+ sz *= ((size_t) 1) << 20;
+ break;
+ case 'g':
+ case 'G':
+ sz *= ((size_t) 1) << 30;
+ break;
+ default:
+ sz = 0;
+ }
+ }
+ }
+ if (sz == 0)
+ {
+ /* Use 256 MB for 32-bit systems and 256 GB for 64-bit systems. */
+ if (sizeof (size_t) == 4)
+ sz = ((size_t) 1) << 28;
+ else
+ sz = ((size_t) 1) << 38;
+ }
+ return sz;
+}
+
/* Get a master. */
static master *
@@ -79,6 +128,8 @@ get_master (void)
void
ensure_initialization (void)
{
+ size_t shmem_size;
+
if (local)
return;
@@ -86,8 +137,9 @@ ensure_initialization (void)
// that point? Maybe use
// mmap(MAP_ANON) instead
pagesize = sysconf (_SC_PAGE_SIZE);
+ shmem_size = round_to_pagesize (get_memory_size());
local->total_num_images = get_environ_image_num ();
- shared_memory_init (&local->sm);
+ shared_memory_init (&local->sm, shmem_size);
shared_memory_prepare (&local->sm);
if (this_image.m == NULL) /* A bit of a hack, but we
need the master early. */
diff --git a/libgfortran/caf_shared/shared_memory.c b/libgfortran/caf_shared/shared_memory.c
index 0c0b36c..bc1a2e9 100644
--- a/libgfortran/caf_shared/shared_memory.c
+++ b/libgfortran/caf_shared/shared_memory.c
@@ -186,21 +186,11 @@ shared_memory_prepare (shared_memory_act **pmem)
shared memory is stored at the beginning. */
void
-shared_memory_init (shared_memory_act **pmem)
+shared_memory_init (shared_memory_act **pmem, size_t initial_size)
{
shared_memory_act *mem;
int fd;
- /* Darwin does not appear to be able to grow shared memory segments. Choose
- 256 GB; that will likely be enough. If not, the ftruncate will fail
- noisily. */
-
-#ifdef __APPLE__
- size_t initial_size = ((size_t) 1) << 38;
-#else
- size_t initial_size = round_to_pagesize (sizeof (global_shared_memory_meta));
-#endif
-
mem = malloc (get_shared_memory_act_size (1));
fd = get_shmem_fd ();
diff --git a/libgfortran/caf_shared/shared_memory.h b/libgfortran/caf_shared/shared_memory.h
index 09692fc..dd03227 100644
--- a/libgfortran/caf_shared/shared_memory.h
+++ b/libgfortran/caf_shared/shared_memory.h
@@ -53,7 +53,7 @@ typedef struct shared_mem_ptr
ssize_t offset;
} shared_mem_ptr;
-void shared_memory_init (shared_memory *);
+void shared_memory_init (shared_memory *, size_t);
internal_proto (shared_memory_init);
void shared_memory_prepare (shared_memory *);