1 /* -*- Mode: C; c-basic-offset:4 ; -*- */
2
3 /*
4 * (C) 2001 by Argonne National Laboratory.
5 * See COPYRIGHT in top-level directory.
6 */
7
8 #ifndef DATALOOP_PARTS_H
9 #define DATALOOP_PARTS_H
10
11 /* Check that all the appropriate defines are present */
12 #ifndef PREPEND_PREFIX
13 #error "PREPEND_PREFIX must be defined before dataloop_parts.h is included."
14 #endif
15
16 #ifndef DLOOP_Offset
17 #error "DLOOP_Offset must be defined before dataloop_parts.h is included."
18 #endif
19
20 #ifndef DLOOP_Count
21 #error "DLOOP_Count must be defined before dataloop_parts.h is included."
22 #endif
23
24 #ifndef DLOOP_Handle
25 #error "DLOOP_Handle must be defined before dataloop_parts.h is included."
26 #endif
27
28 #ifndef DLOOP_Buffer
29 #error "DLOOP_Buffer must be defined before dataloop_parts.h is included."
30 #endif
31
32 #ifndef DLOOP_Type
33 #error "DLOOP_Type must be defined before dataloop_parts.h is included."
34 #endif
35
36 /* Redefine all of the internal structures in terms of the prefix */
37 #define DLOOP_Dataloop PREPEND_PREFIX(Dataloop)
38 #define DLOOP_Dataloop_contig PREPEND_PREFIX(Dataloop_contig)
39 #define DLOOP_Dataloop_vector PREPEND_PREFIX(Dataloop_vector)
40 #define DLOOP_Dataloop_blockindexed PREPEND_PREFIX(Dataloop_blockindexed)
41 #define DLOOP_Dataloop_indexed PREPEND_PREFIX(Dataloop_indexed)
42 #define DLOOP_Dataloop_struct PREPEND_PREFIX(Dataloop_struct)
43 #define DLOOP_Dataloop_common PREPEND_PREFIX(Dataloop_common)
44 #define DLOOP_Segment PREPEND_PREFIX(Segment)
45 #define DLOOP_Dataloop_stackelm PREPEND_PREFIX(Dataloop_stackelm)
46
47 /* These flags are used at creation time to specify what types of
48 * optimizations may be applied. They are also passed in at Segment_init
49 * time to specify which dataloop to use.
50 *
51 * Note: The flag to MPID_Segment_init() was originally simply "hetero"
52 * and was a boolean value (0 meaning homogeneous). Some MPICH2 code
53 * may still rely on HOMOGENEOUS being "0" and HETEROGENEOUS being "1".
54 */
55 #define DLOOP_DATALOOP_HOMOGENEOUS 0
56 #define DLOOP_DATALOOP_HETEROGENEOUS 1
57 #define DLOOP_DATALOOP_ALL_BYTES 2
58
59 /* NOTE: ASSUMING LAST TYPE IS SIGNED */
60 #define SEGMENT_IGNORE_LAST ((DLOOP_Offset) -1)
61 /*
62 * Each of the MPI datatypes can be mapped into one of 5 very simple
63 * loops. This loop has the following parameters:
64 * - count
65 * - blocksize[]
66 * - offset[]
67 * - stride
68 * - datatype[]
69 *
70 * where each [] indicates that a field may be *either* an array or a scalar.
71 * For each such type, we define a struct that describes these parameters
72 */
73
74 /*S
75 DLOOP_Dataloop_contig - Description of a contiguous dataloop
76
77 Fields:
78 + count - Number of elements
79 - dataloop - Dataloop of the elements
80
81 Module:
82 Datatype
83 S*/
84 typedef struct DLOOP_Dataloop_contig {
85 DLOOP_Count count;
86 struct DLOOP_Dataloop *dataloop;
87 } DLOOP_Dataloop_contig;
88
89 /*S
90 DLOOP_Dataloop_vector - Description of a vector or strided dataloop
91
92 Fields:
93 + count - Number of elements
94 . blocksize - Number of dataloops in each element
95 . stride - Stride (in bytes) between each block
96 - dataloop - Dataloop of each element
97
98 Module:
99 Datatype
100 S*/
101 typedef struct DLOOP_Dataloop_vector {
102 DLOOP_Count count;
103 struct DLOOP_Dataloop *dataloop;
104 DLOOP_Count blocksize;
105 DLOOP_Offset stride;
106 } DLOOP_Dataloop_vector;
107
108 /*S
109 DLOOP_Dataloop_blockindexed - Description of a block-indexed dataloop
110
111 Fields:
112 + count - Number of blocks
113 . blocksize - Number of elements in each block
114 . offset_array - Array of offsets (in bytes) to each block
115 . total_blocks - count of total blocks in the array (cached value)
116 - dataloop - Dataloop of each element
117
118 Module:
119 Datatype
120
121 S*/
122 typedef struct DLOOP_Dataloop_blockindexed {
123 DLOOP_Count count;
124 struct DLOOP_Dataloop *dataloop;
125 DLOOP_Count blocksize;
126 DLOOP_Offset *offset_array;
127 } DLOOP_Dataloop_blockindexed;
128
129 /*S
130 DLOOP_Dataloop_indexed - Description of an indexed dataloop
131
132 Fields:
133 + count - Number of blocks
134 . blocksize_array - Array giving the number of elements in each block
135 . offset_array - Array of offsets (in bytes) to each block
136 . total_blocks - count of total blocks in the array (cached value)
137 - dataloop - Dataloop of each element
138
139 Module:
140 Datatype
141
142 S*/
143 typedef struct DLOOP_Dataloop_indexed {
144 DLOOP_Count count;
145 struct DLOOP_Dataloop *dataloop;
146 DLOOP_Count *blocksize_array;
147 DLOOP_Offset *offset_array;
148 DLOOP_Count total_blocks;
149 } DLOOP_Dataloop_indexed;
150
151 /*S
152 DLOOP_Dataloop_struct - Description of a structure dataloop
153
154 Fields:
155 + count - Number of blocks
156 . blocksize_array - Array giving the number of elements in each block
157 . offset_array - Array of offsets (in bytes) to each block
158 - dataloop_array - Array of dataloops describing the elements of each block
159
160 Module:
161 Datatype
162
163 S*/
164 typedef struct DLOOP_Dataloop_struct {
165 DLOOP_Count count;
166 struct DLOOP_Dataloop **dataloop_array;
167 DLOOP_Count *blocksize_array;
168 DLOOP_Offset *offset_array;
169 DLOOP_Offset *el_extent_array; /* need more than one */
170 } DLOOP_Dataloop_struct;
171
172 /* In many cases, we need the count and the next dataloop item. This
173 common structure gives a quick access to both. Note that all other
174 structures must use the same ordering of elements.
175 Question: should we put the pointer first in case
176 sizeof(pointer)>sizeof(int) ?
177 */
178 typedef struct DLOOP_Dataloop_common {
179 DLOOP_Count count;
180 struct DLOOP_Dataloop *dataloop;
181 } DLOOP_Dataloop_common;
182
183 /*S
184 DLOOP_Dataloop - Description of the structure used to hold a dataloop
185 description
186
187 Fields:
188 + kind - Describes the type of the dataloop. This is divided into three
189 separate bit fields\:
190 .vb
191 Dataloop type (e.g., DLOOP_CONTIG etc.). 3 bits
192 IsFinal (a "leaf" dataloop; see text) 1 bit
193 Element Size (units for fields.) 2 bits
194 Element size has 4 values
195 0 - Elements are in units of bytes
196 1 - Elements are in units of 2 bytes
197 2 - Elements are in units of 4 bytes
198 3 - Elements are in units of 8 bytes
199 .ve
200 The dataloop type is one of 'DLOOP_CONTIG', 'DLOOP_VECTOR',
201 'DLOOP_BLOCKINDEXED', 'DLOOP_INDEXED', or 'DLOOP_STRUCT'.
202 . loop_parms - A union containing the 5 dataloop structures, e.g.,
203 'DLOOP_Dataloop_contig', 'DLOOP_Dataloop_vector', etc. A sixth element in
204 this union, 'count', allows quick access to the shared 'count' field in the
205 five dataloop structure.
206 . extent - The extent of the dataloop
207
208 Module:
209 Datatype
210
211 S*/
212 typedef struct DLOOP_Dataloop {
213 int kind; /* Contains both the loop type
214 (contig, vector, blockindexed, indexed,
215 or struct) and a bit that indicates
216 whether the dataloop is a leaf type. */
217 union {
218 DLOOP_Count count;
219 DLOOP_Dataloop_contig c_t;
220 DLOOP_Dataloop_vector v_t;
221 DLOOP_Dataloop_blockindexed bi_t;
222 DLOOP_Dataloop_indexed i_t;
223 DLOOP_Dataloop_struct s_t;
224 DLOOP_Dataloop_common cm_t;
225 } loop_params;
226 DLOOP_Offset el_size;
227 DLOOP_Offset el_extent;
228 DLOOP_Type el_type;
229 } DLOOP_Dataloop;
230
231 #define DLOOP_FINAL_MASK 0x00000008
232 #define DLOOP_KIND_MASK 0x00000007
233 #define DLOOP_KIND_CONTIG 0x1
234 #define DLOOP_KIND_VECTOR 0x2
235 #define DLOOP_KIND_BLOCKINDEXED 0x3
236 #define DLOOP_KIND_INDEXED 0x4
237 #define DLOOP_KIND_STRUCT 0x5
238
239 /* The max datatype depth is the maximum depth of the stack used to
240 evaluate datatypes. It represents the length of the chain of
241 datatype dependencies. Defining this and testing when a datatype
242 is created removes a test in the datatype evaluation loop. */
243 #define DLOOP_MAX_DATATYPE_DEPTH 16
244
245 /*S
246 DLOOP_Dataloop_stackelm - Structure for an element of the stack used
247 to process dataloops
248
249 Fields:
250 + curcount - Current loop count value (between 0 and
251 loop.loop_params.count-1)
252 . orig_count - original count value (cached so we don't have to look it up)
253 . curoffset - Offset into memory relative to the pointer to the buffer
254 passed in by the user. Used to maintain our position as we
255 move up and down the stack. NEED MORE NOTES ON THIS!!!
256 . orig_offset - original offset, set before the stackelm is processed, so that
257 we know where the offset was. this is used in processing indexed
258 types and possibly others. it is set for all types, but not
259 referenced in some cases.
260 . curblock - Current block value...NEED MORE NOTES ON THIS!!!
261 . orig_block - original block value (caches so we don't have to look it up);
262 INVALID FOR INDEX AND STRUCT TYPES.
263 - loop_p - pointer to Loop-based description of the dataloop
264
265 S*/
266 typedef struct DLOOP_Dataloop_stackelm {
267 int may_require_reloading; /* indicates that items below might
268 * need reloading (e.g. this is a struct)
269 */
270
271 DLOOP_Count curcount;
272 DLOOP_Offset curoffset;
273 DLOOP_Count curblock;
274
275 DLOOP_Count orig_count;
276 DLOOP_Offset orig_offset;
277 DLOOP_Count orig_block;
278
279 struct DLOOP_Dataloop *loop_p;
280 } DLOOP_Dataloop_stackelm;
281
282 /*S
283 DLOOP_Segment - Description of the Segment datatype
284
285 Notes:
286 This has no corresponding MPI datatype.
287
288 Module:
289 Segment
290
291 Questions:
292 Should this have an id for allocation and similarity purposes?
293 S*/
294 typedef struct DLOOP_Segment {
295 void *ptr; /* pointer to datatype buffer */
296 DLOOP_Handle handle;
297 DLOOP_Offset stream_off; /* next offset into data stream resulting from datatype
298 * processing. in other words, how many bytes have
299 * we created/used by parsing so far? that amount + 1.
300 */
301 DLOOP_Dataloop_stackelm stackelm[DLOOP_MAX_DATATYPE_DEPTH];
302 int cur_sp; /* Current stack pointer when using dataloop */
303 int valid_sp; /* maximum valid stack pointer. This is used to
304 maintain information on the stack after it has
305 been placed there by following the datatype field
306 in a DLOOP_Dataloop_st for any type except struct */
307
308 struct DLOOP_Dataloop builtin_loop; /* used for both predefined types (which
309 * won't have a loop already) and for
310 * situations where a count is passed in
311 * and we need to create a contig loop
312 * to handle it
313 */
314 /* other, device-specific information */
315 } DLOOP_Segment;
316
317 /* Dataloop functions (dataloop.c) */
318 void PREPEND_PREFIX(Dataloop_copy)(void *dest,
319 void *src,
320 int size);
321 void PREPEND_PREFIX(Dataloop_update)(DLOOP_Dataloop *dataloop,
322 DLOOP_Offset ptrdiff);
323 DLOOP_Offset
324 PREPEND_PREFIX(Dataloop_stream_size)(DLOOP_Dataloop *dl_p,
325 DLOOP_Offset (*sizefn)(DLOOP_Type el_type));
326 void PREPEND_PREFIX(Dataloop_print)(DLOOP_Dataloop *dataloop,
327 int depth);
328
329 void PREPEND_PREFIX(Dataloop_alloc)(int kind,
330 DLOOP_Count count,
331 DLOOP_Dataloop **new_loop_p,
332 int *new_loop_sz_p);
333 void PREPEND_PREFIX(Dataloop_alloc_and_copy)(int kind,
334 DLOOP_Count count,
335 DLOOP_Dataloop *old_loop,
336 int old_loop_sz,
337 DLOOP_Dataloop **new_loop_p,
338 int *new_loop_sz_p);
339 void PREPEND_PREFIX(Dataloop_struct_alloc)(DLOOP_Count count,
340 int old_loop_sz,
341 int basic_ct,
342 DLOOP_Dataloop **old_loop_p,
343 DLOOP_Dataloop **new_loop_p,
344 int *new_loop_sz_p);
345 void PREPEND_PREFIX(Dataloop_dup)(DLOOP_Dataloop *old_loop,
346 int old_loop_sz,
347 DLOOP_Dataloop **new_loop_p);
348
349 void PREPEND_PREFIX(Dataloop_free)(DLOOP_Dataloop **dataloop);
350
351 /* Segment functions (segment.c) */
352 DLOOP_Segment * PREPEND_PREFIX(Segment_alloc)(void);
353
354 void PREPEND_PREFIX(Segment_free)(DLOOP_Segment *segp);
355
356 int PREPEND_PREFIX(Segment_init)(const DLOOP_Buffer buf,
357 DLOOP_Count count,
358 DLOOP_Handle handle,
359 DLOOP_Segment *segp,
360 int hetero);
361
362 void
363 PREPEND_PREFIX(Segment_manipulate)(DLOOP_Segment *segp,
364 DLOOP_Offset first,
365 DLOOP_Offset *lastp,
366 int (*piecefn) (DLOOP_Offset *blocks_p,
367 DLOOP_Type el_type,
368 DLOOP_Offset rel_off,
369 DLOOP_Buffer bufp,
370 void *v_paramp),
371 int (*vectorfn) (DLOOP_Offset *blocks_p,
372 DLOOP_Count count,
373 DLOOP_Count blklen,
374 DLOOP_Offset stride,
375 DLOOP_Type el_type,
376 DLOOP_Offset rel_off,
377 DLOOP_Buffer bufp,
378 void *v_paramp),
379 int (*blkidxfn) (DLOOP_Offset *blocks_p,
380 DLOOP_Count count,
381 DLOOP_Count blklen,
382 DLOOP_Offset *offsetarray,
383 DLOOP_Type el_type,
384 DLOOP_Offset rel_off,
385 DLOOP_Buffer bufp,
386 void *v_paramp),
387 int (*indexfn) (DLOOP_Offset *blocks_p,
388 DLOOP_Count count,
389 DLOOP_Count *blockarray,
390 DLOOP_Offset *offsetarray,
391 DLOOP_Type el_type,
392 DLOOP_Offset rel_off,
393 DLOOP_Buffer bufp,
394 void *v_paramp),
395 DLOOP_Offset (*sizefn) (DLOOP_Type el_type),
396 void *pieceparams);
397
398 /* Common segment operations (segment_ops.c) */
399 void PREPEND_PREFIX(Segment_count_contig_blocks)(DLOOP_Segment *segp,
400 DLOOP_Offset first,
401 DLOOP_Offset *lastp,
402 DLOOP_Count *countp);
403 void PREPEND_PREFIX(Segment_mpi_flatten)(DLOOP_Segment *segp,
404 DLOOP_Offset first,
405 DLOOP_Offset *lastp,
406 int *blklens,
407 MPI_Aint *disps,
408 int *lengthp);
409
410 #define DLOOP_M2M_TO_USERBUF 0
411 #define DLOOP_M2M_FROM_USERBUF 1
412
PREPEND_PREFIX(m2m_params)413 struct PREPEND_PREFIX(m2m_params) {
414 int direction; /* M2M_TO_USERBUF or M2M_FROM_USERBUF */
415 char *streambuf;
416 char *userbuf;
417 };
418
419 void PREPEND_PREFIX(Segment_pack)(struct DLOOP_Segment *segp,
420 DLOOP_Offset first,
421 DLOOP_Offset *lastp,
422 void *streambuf);
423 void PREPEND_PREFIX(Segment_unpack)(struct DLOOP_Segment *segp,
424 DLOOP_Offset first,
425 DLOOP_Offset *lastp,
426 void *streambuf);
427
428 /* Segment piece functions that are used in specific cases elsewhere */
429 int PREPEND_PREFIX(Segment_contig_m2m)(DLOOP_Offset *blocks_p,
430 DLOOP_Type el_type,
431 DLOOP_Offset rel_off,
432 void *bufp, /* unused */
433 void *v_paramp);
434 int PREPEND_PREFIX(Segment_vector_m2m)(DLOOP_Offset *blocks_p,
435 DLOOP_Count count, /* unused */
436 DLOOP_Count blksz,
437 DLOOP_Offset stride,
438 DLOOP_Type el_type,
439 DLOOP_Offset rel_off,
440 void *bufp, /* unused */
441 void *v_paramp);
442 int PREPEND_PREFIX(Segment_blkidx_m2m)(DLOOP_Offset *blocks_p,
443 DLOOP_Count count,
444 DLOOP_Count blocklen,
445 DLOOP_Offset *offsetarray,
446 DLOOP_Type el_type,
447 DLOOP_Offset rel_off,
448 void *bufp, /*unused */
449 void *v_paramp);
450 int PREPEND_PREFIX(Segment_index_m2m)(DLOOP_Offset *blocks_p,
451 DLOOP_Count count,
452 DLOOP_Count *blockarray,
453 DLOOP_Offset *offsetarray,
454 DLOOP_Type el_type,
455 DLOOP_Offset rel_off,
456 void *bufp, /*unused */
457 void *v_paramp);
458 #endif
459
460
461
462