1 /* Common declarations for all of GNU Fortran libcaf implementations.
2    Copyright (C) 2011-2019 Free Software Foundation, Inc.
3    Contributed by Tobias Burnus <burnus@net-b.de>
4 
5 This file is part of the GNU Fortran Coarray Runtime Library (libcaf).
6 
7 Libcaf is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
11 
12 Libcaf is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16 
17 Under Section 7 of GPL version 3, you are granted additional
18 permissions described in the GCC Runtime Library Exception, version
19 3.1, as published by the Free Software Foundation.
20 
21 You should have received a copy of the GNU General Public License and
22 a copy of the GCC Runtime Library Exception along with this program;
23 see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24 <http://www.gnu.org/licenses/>.  */
25 
26 #ifndef LIBCAF_H
27 #define LIBCAF_H
28 
29 #include <stdbool.h>
30 #include <stddef.h>	/* For size_t.  */
31 
32 #include "libgfortran.h"
33 
34 #if 0
35 #ifndef __GNUC__
36 #define __attribute__(x)
37 #define likely(x)       (x)
38 #define unlikely(x)     (x)
39 #else
40 #define likely(x)       __builtin_expect(!!(x), 1)
41 #define unlikely(x)     __builtin_expect(!!(x), 0)
42 #endif
43 #endif
44 
45 /* Definitions of the Fortran 2008 standard; need to kept in sync with
46    ISO_FORTRAN_ENV, cf. gcc/fortran/libgfortran.h.  */
47 typedef enum
48 {
49   CAF_STAT_UNLOCKED = 0,
50   CAF_STAT_LOCKED,
51   CAF_STAT_LOCKED_OTHER_IMAGE,
52   CAF_STAT_STOPPED_IMAGE = 6000,
53   CAF_STAT_FAILED_IMAGE  = 6001
54 }
55 caf_stat_codes_t;
56 
57 
58 /* Describes what type of array we are registerring.  Keep in sync with
59    gcc/fortran/trans.h.  */
60 typedef enum caf_register_t {
61   CAF_REGTYPE_COARRAY_STATIC,
62   CAF_REGTYPE_COARRAY_ALLOC,
63   CAF_REGTYPE_LOCK_STATIC,
64   CAF_REGTYPE_LOCK_ALLOC,
65   CAF_REGTYPE_CRITICAL,
66   CAF_REGTYPE_EVENT_STATIC,
67   CAF_REGTYPE_EVENT_ALLOC,
68   CAF_REGTYPE_COARRAY_ALLOC_REGISTER_ONLY,
69   CAF_REGTYPE_COARRAY_ALLOC_ALLOCATE_ONLY
70 }
71 caf_register_t;
72 
73 /* Describes the action to take on _caf_deregister.  Keep in sync with
74    gcc/fortran/trans.h.  */
75 typedef enum caf_deregister_t {
76   CAF_DEREGTYPE_COARRAY_DEREGISTER,
77   CAF_DEREGTYPE_COARRAY_DEALLOCATE_ONLY
78 }
79 caf_deregister_t;
80 
81 typedef void* caf_token_t;
82 typedef void * caf_team_t;
83 typedef gfc_array_void gfc_descriptor_t;
84 
85 /* Linked list of static coarrays registered.  */
86 typedef struct caf_static_t {
87   caf_token_t token;
88   struct caf_static_t *prev;
89 }
90 caf_static_t;
91 
92 /* When there is a vector subscript in this dimension, nvec == 0, otherwise,
93    lower_bound, upper_bound, stride contains the bounds relative to the declared
94    bounds; kind denotes the integer kind of the elements of vector[].  */
95 typedef struct caf_vector_t {
96   size_t nvec;
97   union {
98     struct {
99       void *vector;
100       int kind;
101     } v;
102     struct {
103       ptrdiff_t lower_bound, upper_bound, stride;
104     } triplet;
105   } u;
106 }
107 caf_vector_t;
108 
109 typedef enum caf_ref_type_t {
110   /* Reference a component of a derived type, either regular one or an
111      allocatable or pointer type.  For regular ones idx in caf_reference_t is
112      set to -1.  */
113   CAF_REF_COMPONENT,
114   /* Reference an allocatable array.  */
115   CAF_REF_ARRAY,
116   /* Reference a non-allocatable/non-pointer array.  */
117   CAF_REF_STATIC_ARRAY
118 } caf_ref_type_t;
119 
120 typedef enum caf_array_ref_t {
121   /* No array ref.  This terminates the array ref.  */
122   CAF_ARR_REF_NONE = 0,
123   /* Reference array elements given by a vector.  Only for this mode
124      caf_reference_t.u.a.dim[i].v is valid.  */
125   CAF_ARR_REF_VECTOR,
126   /* A full array ref (:).  */
127   CAF_ARR_REF_FULL,
128   /* Reference a range on elements given by start, end and stride.  */
129   CAF_ARR_REF_RANGE,
130   /* Only a single item is referenced given in the start member.  */
131   CAF_ARR_REF_SINGLE,
132   /* An array ref of the kind (i:), where i is an arbitrary valid index in the
133      array.  The index i is given in the start member.  */
134   CAF_ARR_REF_OPEN_END,
135   /* An array ref of the kind (:i), where the lower bound of the array ref
136      is given by the remote side.  The index i is given in the end member.  */
137   CAF_ARR_REF_OPEN_START
138 } caf_array_ref_t;
139 
140 /* References to remote components of a derived type.  */
141 typedef struct caf_reference_t {
142   /* A pointer to the next ref or NULL.  */
143   struct caf_reference_t *next;
144   /* The type of the reference.  */
145   /* caf_ref_type_t, replaced by int to allow specification in fortran FE.  */
146   int type;
147   /* The size of an item referenced in bytes.  I.e. in an array ref this is
148      the factor to advance the array pointer with to get to the next item.
149      For component refs this gives just the size of the element referenced.  */
150   size_t item_size;
151   union {
152     struct {
153       /* The offset (in bytes) of the component in the derived type.  */
154       ptrdiff_t offset;
155       /* The offset (in bytes) to the caf_token associated with this
156 	 component.  NULL, when not allocatable/pointer ref.  */
157       ptrdiff_t caf_token_offset;
158     } c;
159     struct {
160       /* The mode of the array ref.  See CAF_ARR_REF_*.  */
161       /* caf_array_ref_t, replaced by unsigend char to allow specification in
162 	 fortran FE.  */
163       unsigned char mode[GFC_MAX_DIMENSIONS];
164       /* The type of a static array.  Unset for array's with descriptors.  */
165       int static_array_type;
166       /* Subscript refs (s) or vector refs (v).  */
167       union {
168 	struct {
169 	  /* The start and end boundary of the ref and the stride.  */
170 	  index_type start, end, stride;
171 	} s;
172 	struct {
173 	  /* nvec entries of kind giving the elements to reference.  */
174 	  void *vector;
175 	  /* The number of entries in vector.  */
176 	  size_t nvec;
177 	  /* The integer kind used for the elements in vector.  */
178 	  int kind;
179 	} v;
180       } dim[GFC_MAX_DIMENSIONS];
181     } a;
182   } u;
183 } caf_reference_t;
184 
185 void _gfortran_caf_init (int *, char ***);
186 void _gfortran_caf_finalize (void);
187 
188 int _gfortran_caf_this_image (int);
189 int _gfortran_caf_num_images (int, int);
190 
191 void _gfortran_caf_register (size_t, caf_register_t, caf_token_t *,
192 			     gfc_descriptor_t *, int *, char *, size_t);
193 void _gfortran_caf_deregister (caf_token_t *, caf_deregister_t, int *, char *,
194 			       size_t);
195 
196 void _gfortran_caf_sync_all (int *, char *, size_t);
197 void _gfortran_caf_sync_memory (int *, char *, size_t);
198 void _gfortran_caf_sync_images (int, int[], int *, char *, size_t);
199 
200 void _gfortran_caf_stop_numeric (int, bool)
201      __attribute__ ((noreturn));
202 void _gfortran_caf_stop_str (const char *, size_t, bool)
203      __attribute__ ((noreturn));
204 void _gfortran_caf_error_stop_str (const char *, size_t, bool)
205      __attribute__ ((noreturn));
206 void _gfortran_caf_error_stop (int, bool) __attribute__ ((noreturn));
207 void _gfortran_caf_fail_image (void) __attribute__ ((noreturn));
208 
209 void _gfortran_caf_co_broadcast (gfc_descriptor_t *, int, int *, char *, size_t);
210 void _gfortran_caf_co_sum (gfc_descriptor_t *, int, int *, char *, size_t);
211 void _gfortran_caf_co_min (gfc_descriptor_t *, int, int *, char *, int, size_t);
212 void _gfortran_caf_co_max (gfc_descriptor_t *, int, int *, char *, int, size_t);
213 void _gfortran_caf_co_reduce (gfc_descriptor_t *, void* (*) (void *, void*),
214 			      int, int, int *, char *, int, size_t);
215 
216 void _gfortran_caf_get (caf_token_t, size_t, int, gfc_descriptor_t *,
217 			caf_vector_t *, gfc_descriptor_t *, int, int, bool,
218 			int *);
219 void _gfortran_caf_send (caf_token_t, size_t, int, gfc_descriptor_t *,
220 			 caf_vector_t *, gfc_descriptor_t *, int, int, bool,
221 			 int *);
222 void _gfortran_caf_sendget (caf_token_t, size_t, int, gfc_descriptor_t *,
223 			    caf_vector_t *, caf_token_t, size_t, int,
224 			    gfc_descriptor_t *, caf_vector_t *, int, int, bool);
225 
226 void _gfortran_caf_get_by_ref (caf_token_t token, int image_idx,
227 	gfc_descriptor_t *dst, caf_reference_t *refs, int dst_kind,
228 	int src_kind, bool may_require_tmp, bool dst_reallocatable, int *stat,
229 	int src_type);
230 void _gfortran_caf_send_by_ref (caf_token_t token, int image_index,
231 	gfc_descriptor_t *src, caf_reference_t *refs, int dst_kind,
232 	int src_kind, bool may_require_tmp, bool dst_reallocatable, int *stat,
233 	int dst_type);
234 void _gfortran_caf_sendget_by_ref (
235 	caf_token_t dst_token, int dst_image_index, caf_reference_t *dst_refs,
236 	caf_token_t src_token, int src_image_index, caf_reference_t *src_refs,
237 	int dst_kind, int src_kind, bool may_require_tmp, int *dst_stat,
238 	int *src_stat, int dst_type, int src_type);
239 
240 void _gfortran_caf_atomic_define (caf_token_t, size_t, int, void *, int *,
241 				  int, int);
242 void _gfortran_caf_atomic_ref (caf_token_t, size_t, int, void *, int *,
243 			       int, int);
244 void _gfortran_caf_atomic_cas (caf_token_t, size_t, int, void *, void *,
245 			       void *, int *, int, int);
246 void _gfortran_caf_atomic_op (int, caf_token_t, size_t, int, void *, void *,
247 			      int *, int, int);
248 
249 void _gfortran_caf_lock (caf_token_t, size_t, int, int *, int *, char *, size_t);
250 void _gfortran_caf_unlock (caf_token_t, size_t, int, int *, char *, size_t);
251 void _gfortran_caf_event_post (caf_token_t, size_t, int, int *, char *, size_t);
252 void _gfortran_caf_event_wait (caf_token_t, size_t, int, int *, char *, size_t);
253 void _gfortran_caf_event_query (caf_token_t, size_t, int, int *, int *);
254 
255 void _gfortran_caf_failed_images (gfc_descriptor_t *,
256 				  caf_team_t * __attribute__ ((unused)), int *);
257 int _gfortran_caf_image_status (int, caf_team_t * __attribute__ ((unused)));
258 void _gfortran_caf_stopped_images (gfc_descriptor_t *,
259 				   caf_team_t * __attribute__ ((unused)),
260 				   int *);
261 
262 int _gfortran_caf_is_present (caf_token_t, int, caf_reference_t *);
263 
264 #endif  /* LIBCAF_H  */
265