1 /*
2  * Copyright (C) by Argonne National Laboratory
3  *     See COPYRIGHT in top-level directory
4  */
5 
6 #ifndef YAKSI_H_INCLUDED
7 #define YAKSI_H_INCLUDED
8 
9 #include <stdio.h>
10 #include <stdbool.h>
11 #include <sys/uio.h>
12 #include <yuthash.h>
13 #include "yaksa_config.h"
14 #include "yaksa.h"
15 #include "yaksu.h"
16 #include "yaksur_pre.h"
17 
18 #if !defined ATTRIBUTE
19 #if defined HAVE_GCC_ATTRIBUTE
20 #define ATTRIBUTE(a_) __attribute__(a_)
21 #else /* MPL_HAVE_GCC_ATTRIBUTE */
22 #define ATTRIBUTE(a_)
23 #endif /* MPL_HAVE_GCC_ATTRIBUTE */
24 #endif /* ATTRIBUTE */
25 
26 #define YAKSI_ENV_DEFAULT_NESTING_LEVEL  (3)
27 
28 extern yaksu_atomic_int yaksi_is_initialized;
29 
30 typedef enum {
31     YAKSI_TYPE_KIND__BUILTIN,
32     YAKSI_TYPE_KIND__CONTIG,
33     YAKSI_TYPE_KIND__DUP,
34     YAKSI_TYPE_KIND__RESIZED,
35     YAKSI_TYPE_KIND__HVECTOR,
36     YAKSI_TYPE_KIND__BLKHINDX,
37     YAKSI_TYPE_KIND__HINDEXED,
38     YAKSI_TYPE_KIND__STRUCT,
39     YAKSI_TYPE_KIND__SUBARRAY,
40 } yaksi_type_kind_e;
41 
42 struct yaksi_type_s;
43 struct yaksi_request_s;
44 
45 /*
46  * The type handle is divided into the following parts:
47  *
48  *    32 bits -- unused
49  *    32 bits -- type object id
50  */
51 #define YAKSI_TYPE_UNUSED_BITS                  (32)
52 #define YAKSI_TYPE_OBJECT_ID_BITS               (32)
53 
54 #define YAKSI_TYPE_GET_OBJECT_ID(handle) \
55     ((handle) << (64 - YAKSI_TYPE_OBJECT_ID_BITS) >> (64 - YAKSI_TYPE_OBJECT_ID_BITS))
56 #define YAKSI_TYPE_SET_OBJECT_ID(handle, obj_id)                        \
57     do {                                                                \
58         assert((obj_id) < ((yaksa_type_t) 1 << YAKSI_TYPE_OBJECT_ID_BITS)); \
59         (handle) = (((handle) & ~((((yaksa_type_t) 1) << YAKSI_TYPE_OBJECT_ID_BITS) - 1)) + (obj_id)); \
60     } while (0)
61 
62 /*
63  * The request handle is divided into the following parts:
64  *
65  *    32 bits -- unused
66  *    32 bits -- request object id
67  */
68 #define YAKSI_REQUEST_UNUSED_BITS                  (32)
69 #define YAKSI_REQUEST_OBJECT_ID_BITS               (32)
70 
71 #define YAKSI_REQUEST_GET_OBJECT_ID(handle) \
72     ((handle) << (64 - YAKSI_REQUEST_OBJECT_ID_BITS) >> (64 - YAKSI_REQUEST_OBJECT_ID_BITS))
73 
74 /* global variables */
75 typedef struct {
76     yaksu_handle_pool_s type_handle_pool;
77     yaksu_handle_pool_s request_handle_pool;
78 } yaksi_global_s;
79 extern yaksi_global_s yaksi_global;
80 
81 typedef struct yaksi_type_s {
82     yaksu_atomic_int refcount;
83 
84     yaksi_type_kind_e kind;
85     int tree_depth;
86 
87     uint8_t alignment;
88     uintptr_t size;
89     intptr_t extent;
90     intptr_t lb;
91     intptr_t ub;
92     intptr_t true_lb;
93     intptr_t true_ub;
94 
95     /* "is_contig" is set to true only when an array of this type is
96      * contiguous, not just one element */
97     bool is_contig;
98     uintptr_t num_contig;
99 
100     union {
101         struct {
102             int count;
103             int blocklength;
104             intptr_t stride;
105             struct yaksi_type_s *child;
106         } hvector;
107         struct {
108             int count;
109             int blocklength;
110             intptr_t *array_of_displs;
111             struct yaksi_type_s *child;
112         } blkhindx;
113         struct {
114             int count;
115             int *array_of_blocklengths;
116             intptr_t *array_of_displs;
117             struct yaksi_type_s *child;
118         } hindexed;
119         struct {
120             int count;
121             int *array_of_blocklengths;
122             intptr_t *array_of_displs;
123             struct yaksi_type_s **array_of_types;
124         } str;
125         struct {
126             struct yaksi_type_s *child;
127         } resized;
128         struct {
129             int count;
130             struct yaksi_type_s *child;
131         } contig;
132         struct {
133             int ndims;
134             struct yaksi_type_s *primary;
135         } subarray;
136         struct {
137             struct yaksi_type_s *child;
138         } dup;
139         struct {
140             yaksa_type_t handle;
141         } builtin;
142     } u;
143 
144     /* give some private space for the backend to store content */
145     yaksur_type_s backend;
146 } yaksi_type_s;
147 
148 typedef struct yaksi_request_s {
149     yaksu_handle_t id;
150     yaksu_atomic_int cc;        /* completion counter */
151 
152     /* give some private space for the backend to store content */
153     yaksur_request_s backend;
154 
155     UT_hash_handle hh;
156 } yaksi_request_s;
157 
158 typedef struct yaksi_info_s {
159     yaksu_atomic_int refcount;
160     yaksur_info_s backend;
161 } yaksi_info_s;
162 
163 
164 /* pair types */
165 typedef struct {
166     float x;
167     int y;
168 } yaksi_float_int_s;
169 
170 typedef struct {
171     double x;
172     int y;
173 } yaksi_double_int_s;
174 
175 typedef struct {
176     long x;
177     int y;
178 } yaksi_long_int_s;
179 
180 typedef struct {
181     int x;
182     int y;
183 } yaksi_2int_s;
184 
185 typedef struct {
186     short x;
187     int y;
188 } yaksi_short_int_s;
189 
190 typedef struct {
191     long double x;
192     int y;
193 } yaksi_long_double_int_s;
194 
195 typedef struct {
196     float x;
197     float y;
198 } yaksi_c_complex_s;
199 
200 typedef struct {
201     double x;
202     double y;
203 } yaksi_c_double_complex_s;
204 
205 typedef struct {
206     long double x;
207     long double y;
208 } yaksi_c_long_double_complex_s;
209 
210 
211 /* post headers come after the type declarations */
212 #include "yaksur_post.h"
213 
214 
215 /* function declarations come at the very end */
216 int yaksi_type_create_hvector(int count, int blocklength, intptr_t stride, yaksi_type_s * intype,
217                               yaksi_type_s ** outtype);
218 int yaksi_type_create_contig(int count, yaksi_type_s * intype, yaksi_type_s ** outtype);
219 int yaksi_type_create_dup(yaksi_type_s * intype, yaksi_type_s ** outtype);
220 int yaksi_type_create_hindexed(int count, const int *array_of_blocklengths,
221                                const intptr_t * array_of_displacements, yaksi_type_s * intype,
222                                yaksi_type_s ** outtype);
223 int yaksi_type_create_hindexed_block(int count, int blocklength,
224                                      const intptr_t * array_of_displacements, yaksi_type_s * intype,
225                                      yaksi_type_s ** outtype);
226 int yaksi_type_create_resized(yaksi_type_s * intype, intptr_t lb, intptr_t extent,
227                               yaksi_type_s ** outtype);
228 int yaksi_type_create_struct(int count, const int *array_of_blocklengths,
229                              const intptr_t * array_of_displacements,
230                              yaksi_type_s ** array_of_intypes, yaksi_type_s ** outtype);
231 int yaksi_type_create_subarray(int ndims, const int *array_of_sizes, const int *array_of_subsizes,
232                                const int *array_of_starts, yaksa_subarray_order_e order,
233                                yaksi_type_s * intype, yaksi_type_s ** outtype);
234 int yaksi_type_free(yaksi_type_s * type);
235 
236 int yaksi_ipack(const void *inbuf, uintptr_t incount, yaksi_type_s * type, uintptr_t inoffset,
237                 void *outbuf, uintptr_t max_pack_bytes, uintptr_t * actual_pack_bytes,
238                 yaksi_info_s * info, yaksi_request_s * request);
239 int yaksi_ipack_backend(const void *inbuf, void *outbuf, uintptr_t count, yaksi_type_s * type,
240                         yaksi_info_s * info, yaksi_request_s * request);
241 int yaksi_ipack_element(const void *inbuf, yaksi_type_s * type, uintptr_t inoffset, void *outbuf,
242                         uintptr_t max_pack_bytes, uintptr_t * actual_pack_bytes,
243                         yaksi_info_s * info, yaksi_request_s * request);
244 
245 int yaksi_iunpack(const void *inbuf, uintptr_t insize, void *outbuf, uintptr_t outcount,
246                   yaksi_type_s * type, uintptr_t outoffset, uintptr_t * actual_unpack_bytes,
247                   yaksi_info_s * info, yaksi_request_s * request);
248 int yaksi_iunpack_backend(const void *inbuf, void *outbuf, uintptr_t outcount, yaksi_type_s * type,
249                           yaksi_info_s * info, yaksi_request_s * request);
250 int yaksi_iunpack_element(const void *inbuf, uintptr_t insize, void *outbuf, yaksi_type_s * type,
251                           uintptr_t outoffset, uintptr_t * actual_unpack_bytes,
252                           yaksi_info_s * info, yaksi_request_s * request);
253 
254 int yaksi_iov_len(uintptr_t count, yaksi_type_s * type, uintptr_t * iov_len);
255 int yaksi_iov(const char *buf, uintptr_t count, yaksi_type_s * type, uintptr_t iov_offset,
256               struct iovec *iov, uintptr_t max_iov_len, uintptr_t * actual_iov_len);
257 
258 int yaksi_flatten_size(yaksi_type_s * type, uintptr_t * flattened_type_size);
259 
260 /* type pool */
261 int yaksi_type_handle_alloc(yaksi_type_s * type, yaksa_type_t * handle);
262 int yaksi_type_handle_dealloc(yaksa_type_t handle, yaksi_type_s ** type);
263 int yaksi_type_get(yaksa_type_t type, yaksi_type_s ** yaksi_type);
264 
265 /* request pool */
266 int yaksi_request_create(yaksi_request_s ** request);
267 int yaksi_request_free(yaksi_request_s * request);
268 int yaksi_request_get(yaksa_request_t request, yaksi_request_s ** yaksi_request);
269 
270 #endif /* YAKSI_H_INCLUDED */
271