1 /* One-sided MPI implementation of Libcaf
2 
3 Copyright (c) 2012-2016, Sourcery, Inc.
4 All rights reserved.
5 
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met:
8     * Redistributions of source code must retain the above copyright
9       notice, this list of conditions and the following disclaimer.
10     * Redistributions in binary form must reproduce the above copyright
11       notice, this list of conditions and the following disclaimer in the
12       documentation and/or other materials provided with the distribution.
13     * Neither the name of the Sourcery, Inc., nor the
14       names of its contributors may be used to endorse or promote products
15       derived from this software without specific prior written permission.
16 
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 DISCLAIMED. IN NO EVENT SHALL SOURCERY, INC., BE LIABLE FOR ANY
21 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  */
27 
28 #ifndef LIBCAF_H
29 #define LIBCAF_H
30 
31 #include <stddef.h>     /* For size_t.  */
32 #include <stdbool.h>
33 
34 #include "libcaf-version-def.h"
35 #include "libcaf-gfortran-descriptor.h"
36 
37 #ifdef HAVE_MPI
38 #include <mpi.h>
39 #endif
40 
41 #ifndef __GNUC__
42 #define __attribute__(x)
43 #define likely(x)       (x)
44 #define unlikely(x)     (x)
45 #else
46 #define likely(x)       __builtin_expect(!!(x), 1)
47 #define unlikely(x)     __builtin_expect(!!(x), 0)
48 #endif
49 
50 #ifdef PREFIX_NAME
51 #define PREFIX3(X,Y) X ## Y
52 #define PREFIX2(X,Y) PREFIX3(X,Y)
53 #define PREFIX(X) PREFIX2(PREFIX_NAME,X)
54 #else
55 #define PREFIX(X) X
56 #endif
57 
58 
59 /* Definitions of the Fortran 2008 standard; need to kept in sync with
60    ISO_FORTRAN_ENV, cf. libgfortran.h.  */
61 #define STAT_UNLOCKED           0
62 #define STAT_LOCKED             1
63 #define STAT_LOCKED_OTHER_IMAGE 2
64 #define STAT_DUP_SYNC_IMAGES    3
65 #define STAT_STOPPED_IMAGE      6000
66 #define STAT_FAILED_IMAGE       6001
67 
68 /* Describes what type of array we are registerring. Keep in sync with
69    gcc/fortran/trans.h.  */
70 typedef enum caf_register_t {
71   CAF_REGTYPE_COARRAY_STATIC,
72   CAF_REGTYPE_COARRAY_ALLOC,
73   CAF_REGTYPE_LOCK_STATIC,
74   CAF_REGTYPE_LOCK_ALLOC,
75   CAF_REGTYPE_CRITICAL,
76   CAF_REGTYPE_EVENT_STATIC,
77   CAF_REGTYPE_EVENT_ALLOC,
78   CAF_REGTYPE_COARRAY_ALLOC_REGISTER_ONLY,
79   CAF_REGTYPE_COARRAY_ALLOC_ALLOCATE_ONLY
80 }
81 caf_register_t;
82 
83 /* Describes the action to take on _caf_deregister. Keep in sync with
84    gcc/fortran/trans.h.  */
85 typedef enum caf_deregister_t {
86   CAF_DEREGTYPE_COARRAY_DEREGISTER,
87   CAF_DEREGTYPE_COARRAY_DEALLOCATE_ONLY
88 }
89 caf_deregister_t;
90 
91 typedef void* caf_token_t;
92 /** Add a dummy type representing teams in coarrays. */
93 
94 typedef void * caf_team_t;
95 
96 typedef struct caf_teams_list {
97   caf_team_t team;
98   int team_id;
99   struct caf_teams_list *prev;
100 } caf_teams_list;
101 
102 typedef struct caf_used_teams_list {
103   struct caf_teams_list *team_list_elem;
104   struct caf_used_teams_list *prev;
105 } caf_used_teams_list;
106 
107 
108 /* When there is a vector subscript in this dimension, nvec == 0, otherwise,
109    lower_bound, upper_bound, stride contains the bounds relative to the declared
110    bounds; kind denotes the integer kind of the elements of vector[].  */
111 typedef struct caf_vector_t {
112   size_t nvec;
113   union {
114     struct {
115       void *vector;
116       int kind;
117     } v;
118     struct {
119       ptrdiff_t lower_bound, upper_bound, stride;
120     } triplet;
121   } u;
122 } caf_vector_t;
123 
124 
125 #ifdef GCC_GE_7
126 /* Keep in sync with gcc/libgfortran/caf/libcaf.h.  */
127 typedef enum caf_ref_type_t {
128   /* Reference a component of a derived type, either regular one or an
129      allocatable or pointer type.  For regular ones idx in caf_reference_t is
130      set to -1.  */
131   CAF_REF_COMPONENT,
132   /* Reference an allocatable array.  */
133   CAF_REF_ARRAY,
134   /* Reference a non-allocatable/non-pointer array.  */
135   CAF_REF_STATIC_ARRAY
136 } caf_ref_type_t;
137 
138 /* Keep in sync with gcc/libgfortran/caf/libcaf.h.  */
139 typedef enum caf_array_ref_t {
140   /* No array ref.  This terminates the array ref.  */
141   CAF_ARR_REF_NONE = 0,
142   /* Reference array elements given by a vector.  Only for this mode
143      caf_reference_t.u.a.dim[i].v is valid.  */
144   CAF_ARR_REF_VECTOR,
145   /* A full array ref (:).  */
146   CAF_ARR_REF_FULL,
147   /* Reference a range on elements given by start, end and stride.  */
148   CAF_ARR_REF_RANGE,
149   /* Only a single item is referenced given in the start member.  */
150   CAF_ARR_REF_SINGLE,
151   /* An array ref of the kind (i:), where i is an arbitrary valid index in the
152      array.  The index i is given in the start member.  */
153   CAF_ARR_REF_OPEN_END,
154   /* An array ref of the kind (:i), where the lower bound of the array ref
155      is given by the remote side.  The index i is given in the end member.  */
156   CAF_ARR_REF_OPEN_START
157 } caf_array_ref_t;
158 
159 /* References to remote components of a derived type.
160    Keep in sync with gcc/libgfortran/caf/libcaf.h.  */
161 typedef struct caf_reference_t {
162   /* A pointer to the next ref or NULL.  */
163   struct caf_reference_t *next;
164   /* The type of the reference.  */
165   /* caf_ref_type_t, replaced by int to allow specification in fortran FE.  */
166   int type;
167   /* The size of an item referenced in bytes.  I.e. in an array ref this is
168      the factor to advance the array pointer with to get to the next item.
169      For component refs this gives just the size of the element referenced.  */
170   size_t item_size;
171   union {
172     struct {
173       /* The offset (in bytes) of the component in the derived type.  */
174       ptrdiff_t offset;
175       /* The offset (in bytes) to the caf_token associated with this
176          component.  NULL, when not allocatable/pointer ref.  */
177       ptrdiff_t caf_token_offset;
178     } c;
179     struct {
180       /* The mode of the array ref.  See CAF_ARR_REF_*.  */
181       /* caf_array_ref_t, replaced by unsigend char to allow specification in
182          fortran FE.  */
183       unsigned char mode[GFC_MAX_DIMENSIONS];
184       /* The type of a static array.  Unset for array's with descriptors.  */
185       int static_array_type;
186       /* Subscript refs (s) or vector refs (v).  */
187       union {
188         struct {
189           /* The start and end boundary of the ref and the stride.  */
190           ptrdiff_t start, end, stride;
191         } s;
192         struct {
193           /* nvec entries of kind giving the elements to reference.  */
194           void *vector;
195           /* The number of entries in vector.  */
196           size_t nvec;
197           /* The integer kind used for the elements in vector.  */
198           int kind;
199         } v;
200       } dim[GFC_MAX_DIMENSIONS];
201     } a;
202   } u;
203 } caf_reference_t;
204 #endif
205 
206 
207 /* The following defines give the bits in the opr_flags argument to CO_REDUCE.
208   Keep in sync with the libgfortran.h file of gcc/fortran.  */
209 #define GFC_CAF_BYREF      (1<<0)
210 #define GFC_CAF_HIDDENLEN  (1<<1)
211 #define GFC_CAF_ARG_VALUE  (1<<2)
212 #define GFC_CAF_ARG_DESC   (1<<3)
213 
214 /* The type to use for string lengths.  */
215 #ifdef GCC_GE_8
216 typedef size_t charlen_t;
217 #define QUIETARG , bool
218 #else
219 typedef int charlen_t;
220 #define QUIETARG
221 #endif
222 
223 /* Common auxiliary functions: caf_auxiliary.c.  */
224 
225 bool PREFIX (is_contiguous) (gfc_descriptor_t *);
226 
227 /* Header for the specific implementation.  */
228 
229 void PREFIX (init) (int *, char ***);
230 void PREFIX (finalize) (void);
231 
232 int PREFIX (this_image) (int);
233 int PREFIX (num_images) (int, int);
234 
235 #ifdef GCC_GE_7
236 void PREFIX (register) (size_t, caf_register_t, caf_token_t *,
237                         gfc_descriptor_t *, int *, char *, charlen_t);
238 void PREFIX (deregister) (caf_token_t *, int, int *, char *, charlen_t);
239 #else
240 void * PREFIX (register) (size_t, caf_register_t, caf_token_t *, int *, char *,
241                           int);
242 void PREFIX (deregister) (caf_token_t *, int *, char *, int);
243 #endif
244 
245 void PREFIX (caf_get) (caf_token_t, size_t, int, gfc_descriptor_t *,
246                        caf_vector_t *, gfc_descriptor_t *, int, int, bool,
247                        int *);
248 void PREFIX (caf_send) (caf_token_t, size_t, int, gfc_descriptor_t *,
249                         caf_vector_t *, gfc_descriptor_t *, int, int, bool,
250                         int *);
251 
252 void PREFIX (caf_sendget) (caf_token_t, size_t, int, gfc_descriptor_t *,
253                            caf_vector_t *, caf_token_t, size_t, int,
254                            gfc_descriptor_t *, caf_vector_t *, int, int, bool,
255                            int *);
256 
257 #ifdef GCC_GE_8
258 void PREFIX(get_by_ref) (caf_token_t, int,
259                          gfc_descriptor_t *dst, caf_reference_t *refs,
260                          int dst_kind, int src_kind, bool may_require_tmp,
261                          bool dst_reallocatable, int *stat, int src_type);
262 void PREFIX(send_by_ref) (caf_token_t token, int image_index,
263                           gfc_descriptor_t *src, caf_reference_t *refs,
264                           int dst_kind, int src_kind, bool may_require_tmp,
265                           bool dst_reallocatable, int *stat, int dst_type);
266 void PREFIX(sendget_by_ref) (caf_token_t dst_token, int dst_image_index,
267                              caf_reference_t *dst_refs, caf_token_t src_token,
268                              int src_image_index, caf_reference_t *src_refs,
269                              int dst_kind, int src_kind, bool may_require_tmp,
270                              int *dst_stat, int *src_stat, int dst_type,
271                              int src_type);
272 #elif defined(GCC_GE_7)
273 void PREFIX(get_by_ref) (caf_token_t, int,
274                          gfc_descriptor_t *dst, caf_reference_t *refs,
275                          int dst_kind, int src_kind, bool may_require_tmp,
276                          bool dst_reallocatable, int *stat);
277 void PREFIX(send_by_ref) (caf_token_t token, int image_index,
278                           gfc_descriptor_t *src, caf_reference_t *refs,
279                           int dst_kind, int src_kind, bool may_require_tmp,
280                           bool dst_reallocatable, int *stat);
281 void PREFIX(sendget_by_ref) (caf_token_t dst_token, int dst_image_index,
282                              caf_reference_t *dst_refs, caf_token_t src_token,
283                              int src_image_index, caf_reference_t *src_refs,
284                              int dst_kind, int src_kind, bool may_require_tmp,
285                              int *dst_stat, int *src_stat);
286 #endif
287 #ifdef GCC_GE_7
288 int PREFIX(is_present) (caf_token_t, int, caf_reference_t *refs);
289 #endif
290 
291 void PREFIX (co_broadcast) (gfc_descriptor_t *, int, int *, char *, charlen_t);
292 void PREFIX (co_max) (gfc_descriptor_t *, int, int *, char *, int, charlen_t);
293 void PREFIX (co_min) (gfc_descriptor_t *, int, int *, char *, int, charlen_t);
294 void PREFIX (co_reduce) (gfc_descriptor_t *, void *(*opr) (void *, void *),
295                          int, int, int *, char *, int , charlen_t);
296 void PREFIX (co_sum) (gfc_descriptor_t *, int, int *, char *, charlen_t);
297 
298 void PREFIX (sync_all) (int *, char *, charlen_t);
299 void PREFIX (sync_images) (int, int[], int *, char *, charlen_t);
300 void PREFIX (sync_memory) (int *, char *, charlen_t);
301 
302 void PREFIX (stop_str) (const char *, charlen_t QUIETARG)
303                         __attribute__ ((noreturn));
304 void PREFIX (stop) (int QUIETARG) __attribute__ ((noreturn));
305 void PREFIX (error_stop_str) (const char *, charlen_t QUIETARG)
306                               __attribute__ ((noreturn));
307 void PREFIX (error_stop) (int QUIETARG) __attribute__ ((noreturn));
308 
309 void PREFIX (fail_image) (void) __attribute__ ((noreturn));
310 
311 void PREFIX (form_team) (int, caf_team_t *, int);
312 void PREFIX (change_team) (caf_team_t *, int);
313 void PREFIX (end_team) (caf_team_t *);
314 void PREFIX (sync_team) (caf_team_t *, int);
315 int PREFIX (team_number) (caf_team_t *);
316 
317 int PREFIX (image_status) (int);
318 void PREFIX (failed_images) (gfc_descriptor_t *, int, int *);
319 void PREFIX (stopped_images) (gfc_descriptor_t *, int, int *);
320 
321 void PREFIX (atomic_define) (caf_token_t, size_t, int, void *, int *, int, int);
322 void PREFIX (atomic_ref) (caf_token_t, size_t, int, void *, int *, int, int);
323 void PREFIX (atomic_cas) (caf_token_t, size_t, int, void *, void *,
324                           void *, int *, int, int);
325 void PREFIX (atomic_op) (int, caf_token_t, size_t, int, void *, void *,
326                          int *, int, int);
327 
328 void PREFIX (lock) (caf_token_t, size_t, int, int *, int *, char *, charlen_t);
329 void PREFIX (unlock) (caf_token_t, size_t, int, int *, char *, charlen_t);
330 void PREFIX (event_post) (caf_token_t, size_t, int, int *, char *, charlen_t);
331 void PREFIX (event_wait) (caf_token_t, size_t, int, int *, char *, charlen_t);
332 void PREFIX (event_query) (caf_token_t, size_t, int, int *, int *);
333 
334 /* Language extension */
335 #ifdef HAVE_MPI
336 MPI_Fint PREFIX (get_communicator) (caf_team_t *);
337 #endif
338 
339 #endif  /* LIBCAF_H  */
340