1/* Common declarations for all of GNU Fortran libcaf implementations.
2   Copyright (C) 2011-2020 Free Software Foundation, Inc.
3   Contributed by Tobias Burnus <burnus@net-b.de>
4
5This file is part of the GNU Fortran Coarray Runtime Library (libcaf).
6
7Libcaf is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 3, or (at your option)
10any later version.
11
12Libcaf is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15GNU General Public License for more details.
16
17Under Section 7 of GPL version 3, you are granted additional
18permissions described in the GCC Runtime Library Exception, version
193.1, as published by the Free Software Foundation.
20
21You should have received a copy of the GNU General Public License and
22a copy of the GCC Runtime Library Exception along with this program;
23see 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.  */
47typedef 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}
55caf_stat_codes_t;
56
57
58/* Describes what type of array we are registerring.  Keep in sync with
59   gcc/fortran/trans.h.  */
60typedef 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}
71caf_register_t;
72
73/* Describes the action to take on _caf_deregister.  Keep in sync with
74   gcc/fortran/trans.h.  */
75typedef enum caf_deregister_t {
76  CAF_DEREGTYPE_COARRAY_DEREGISTER,
77  CAF_DEREGTYPE_COARRAY_DEALLOCATE_ONLY
78}
79caf_deregister_t;
80
81typedef void* caf_token_t;
82typedef void * caf_team_t;
83typedef gfc_array_void gfc_descriptor_t;
84
85/* Linked list of static coarrays registered.  */
86typedef struct caf_static_t {
87  caf_token_t token;
88  struct caf_static_t *prev;
89}
90caf_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[].  */
95typedef 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}
107caf_vector_t;
108
109typedef 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
120typedef 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.  */
141typedef 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
185void _gfortran_caf_init (int *, char ***);
186void _gfortran_caf_finalize (void);
187
188int _gfortran_caf_this_image (int);
189int _gfortran_caf_num_images (int, int);
190
191void _gfortran_caf_register (size_t, caf_register_t, caf_token_t *,
192			     gfc_descriptor_t *, int *, char *, size_t);
193void _gfortran_caf_deregister (caf_token_t *, caf_deregister_t, int *, char *,
194			       size_t);
195
196void _gfortran_caf_sync_all (int *, char *, size_t);
197void _gfortran_caf_sync_memory (int *, char *, size_t);
198void _gfortran_caf_sync_images (int, int[], int *, char *, size_t);
199
200void _gfortran_caf_stop_numeric (int, bool)
201     __attribute__ ((noreturn));
202void _gfortran_caf_stop_str (const char *, size_t, bool)
203     __attribute__ ((noreturn));
204void _gfortran_caf_error_stop_str (const char *, size_t, bool)
205     __attribute__ ((noreturn));
206void _gfortran_caf_error_stop (int, bool) __attribute__ ((noreturn));
207void _gfortran_caf_fail_image (void) __attribute__ ((noreturn));
208
209void _gfortran_caf_co_broadcast (gfc_descriptor_t *, int, int *, char *, size_t);
210void _gfortran_caf_co_sum (gfc_descriptor_t *, int, int *, char *, size_t);
211void _gfortran_caf_co_min (gfc_descriptor_t *, int, int *, char *, int, size_t);
212void _gfortran_caf_co_max (gfc_descriptor_t *, int, int *, char *, int, size_t);
213void _gfortran_caf_co_reduce (gfc_descriptor_t *, void* (*) (void *, void*),
214			      int, int, int *, char *, int, size_t);
215
216void _gfortran_caf_get (caf_token_t, size_t, int, gfc_descriptor_t *,
217			caf_vector_t *, gfc_descriptor_t *, int, int, bool,
218			int *);
219void _gfortran_caf_send (caf_token_t, size_t, int, gfc_descriptor_t *,
220			 caf_vector_t *, gfc_descriptor_t *, int, int, bool,
221			 int *);
222void _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
226void _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);
230void _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);
234void _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
240void _gfortran_caf_atomic_define (caf_token_t, size_t, int, void *, int *,
241				  int, int);
242void _gfortran_caf_atomic_ref (caf_token_t, size_t, int, void *, int *,
243			       int, int);
244void _gfortran_caf_atomic_cas (caf_token_t, size_t, int, void *, void *,
245			       void *, int *, int, int);
246void _gfortran_caf_atomic_op (int, caf_token_t, size_t, int, void *, void *,
247			      int *, int, int);
248
249void _gfortran_caf_lock (caf_token_t, size_t, int, int *, int *, char *, size_t);
250void _gfortran_caf_unlock (caf_token_t, size_t, int, int *, char *, size_t);
251void _gfortran_caf_event_post (caf_token_t, size_t, int, int *, char *, size_t);
252void _gfortran_caf_event_wait (caf_token_t, size_t, int, int *, char *, size_t);
253void _gfortran_caf_event_query (caf_token_t, size_t, int, int *, int *);
254
255void _gfortran_caf_failed_images (gfc_descriptor_t *,
256				  caf_team_t * __attribute__ ((unused)), int *);
257int _gfortran_caf_image_status (int, caf_team_t * __attribute__ ((unused)));
258void _gfortran_caf_stopped_images (gfc_descriptor_t *,
259				   caf_team_t * __attribute__ ((unused)),
260				   int *);
261
262int _gfortran_caf_is_present (caf_token_t, int, caf_reference_t *);
263
264#endif  /* LIBCAF_H  */
265