This source file includes following definitions.
- opal_unpack_homogeneous_contig_function
- opal_unpack_partial_datatype
- opal_generic_simple_unpack_function
- opal_unpack_general_function
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 #include "opal_config.h"
26
27 #include <stddef.h>
28 #include <stdio.h>
29
30 #include "opal/datatype/opal_convertor_internal.h"
31 #include "opal/datatype/opal_datatype_internal.h"
32
33 #if OPAL_ENABLE_DEBUG
34 #include "opal/util/output.h"
35
36 #define DO_DEBUG(INST) if( opal_unpack_debug ) { INST }
37 #else
38 #define DO_DEBUG(INST)
39 #endif
40
41 #include "opal/datatype/opal_datatype_checksum.h"
42 #include "opal/datatype/opal_datatype_unpack.h"
43 #include "opal/datatype/opal_datatype_prototypes.h"
44
45 #if defined(CHECKSUM)
46 #define opal_unpack_general_function opal_unpack_general_checksum
47 #define opal_unpack_homogeneous_contig_function opal_unpack_homogeneous_contig_checksum
48 #define opal_generic_simple_unpack_function opal_generic_simple_unpack_checksum
49 #else
50 #define opal_unpack_general_function opal_unpack_general
51 #define opal_unpack_homogeneous_contig_function opal_unpack_homogeneous_contig
52 #define opal_generic_simple_unpack_function opal_generic_simple_unpack
53 #endif
54
55
56
57
58
59
60
61
62
63
64
65 int32_t
66 opal_unpack_homogeneous_contig_function( opal_convertor_t* pConv,
67 struct iovec* iov,
68 uint32_t* out_size,
69 size_t* max_data )
70 {
71 const opal_datatype_t *pData = pConv->pDesc;
72 unsigned char *user_memory, *packed_buffer;
73 uint32_t iov_count, i;
74 size_t bConverted, remaining, length, initial_bytes_converted = pConv->bConverted;
75 dt_stack_t* stack = pConv->pStack;
76 ptrdiff_t extent = pData->ub - pData->lb;
77 ptrdiff_t initial_displ = pConv->use_desc->desc[pConv->use_desc->used].end_loop.first_elem_disp;
78
79 DO_DEBUG( opal_output( 0, "unpack_homogeneous_contig( pBaseBuf %p, iov_count %d )\n",
80 (void*)pConv->pBaseBuf, *out_size ); );
81 if( stack[1].type != opal_datatype_uint1.id ) {
82 stack[1].count *= opal_datatype_basicDatatypes[stack[1].type]->size;
83 stack[1].type = opal_datatype_uint1.id;
84 }
85 for( iov_count = 0; iov_count < (*out_size); iov_count++ ) {
86 remaining = pConv->local_size - pConv->bConverted;
87 if( 0 == remaining ) break;
88 if( remaining > iov[iov_count].iov_len )
89 remaining = iov[iov_count].iov_len;
90 packed_buffer = (unsigned char*)iov[iov_count].iov_base;
91 bConverted = remaining;
92 user_memory = pConv->pBaseBuf + initial_displ;
93
94 if( (ptrdiff_t)pData->size == extent ) {
95 user_memory += pConv->bConverted;
96 DO_DEBUG( opal_output( 0, "unpack_homogeneous_contig( user_memory %p, packed_buffer %p length %lu\n",
97 (void*)user_memory, (void*)packed_buffer, (unsigned long)remaining ); );
98
99
100 OPAL_DATATYPE_SAFEGUARD_POINTER( user_memory, remaining,
101 pConv->pBaseBuf, pData, pConv->count );
102 DO_DEBUG( opal_output( 0, "1. unpack contig dest %p src %p length %lu\n",
103 (void*)user_memory, (void*)packed_buffer, (unsigned long)remaining ); );
104 MEMCPY_CSUM( user_memory, packed_buffer, remaining, pConv );
105 } else {
106 user_memory += stack[0].disp + stack[1].disp;
107
108 DO_DEBUG( opal_output( 0, "unpack_homogeneous_contig( user_memory %p, packed_buffer %p length %lu\n",
109 (void*)user_memory, (void*)packed_buffer, (unsigned long)remaining ); );
110
111 length = (0 == pConv->stack_pos ? 0 : stack[1].count);
112
113 if( (0 != length) && (length <= remaining) ) {
114 OPAL_DATATYPE_SAFEGUARD_POINTER( user_memory, length, pConv->pBaseBuf,
115 pData, pConv->count );
116 DO_DEBUG( opal_output( 0, "2. unpack dest %p src %p length %lu\n",
117 (void*)user_memory, (void*)packed_buffer, (unsigned long)length ); );
118 MEMCPY_CSUM( user_memory, packed_buffer, length, pConv );
119 packed_buffer += length;
120 user_memory += (extent - (pData->size - length));
121 remaining -= length;
122 stack[1].count -= length;
123 if( 0 == stack[1].count) {
124 stack[0].count--;
125 stack[0].disp += extent;
126 if( 0 != stack[0].count ) {
127 stack[1].count = pData->size;
128 stack[1].disp = 0;
129 }
130 }
131 }
132 for( i = 0; pData->size <= remaining; i++ ) {
133 OPAL_DATATYPE_SAFEGUARD_POINTER( user_memory, pData->size, pConv->pBaseBuf,
134 pData, pConv->count );
135 DO_DEBUG( opal_output( 0, "3. unpack dest %p src %p length %lu\n",
136 (void*)user_memory, (void*)packed_buffer, (unsigned long)pData->size ); );
137 MEMCPY_CSUM( user_memory, packed_buffer, pData->size, pConv );
138 packed_buffer += pData->size;
139 user_memory += extent;
140 remaining -= pData->size;
141 }
142 stack[0].count -= i;
143 stack[0].disp += (i * extent);
144 stack[1].disp += remaining;
145
146 if( 0 != remaining ) {
147 OPAL_DATATYPE_SAFEGUARD_POINTER( user_memory, remaining, pConv->pBaseBuf,
148 pData, pConv->count );
149 DO_DEBUG( opal_output( 0, "4. unpack dest %p src %p length %lu\n",
150 (void*)user_memory, (void*)packed_buffer, (unsigned long)remaining ); );
151 MEMCPY_CSUM( user_memory, packed_buffer, remaining, pConv );
152 user_memory += remaining;
153 stack[1].count -= remaining;
154 }
155 }
156 pConv->bConverted += bConverted;
157 }
158 *out_size = iov_count;
159 *max_data = (pConv->bConverted - initial_bytes_converted);
160 if( pConv->bConverted == pConv->local_size ) {
161 pConv->flags |= CONVERTOR_COMPLETED;
162 return 1;
163 }
164 return 0;
165 }
166
167
168
169
170
171
172
173
174
175
176
177
178
179 static inline void
180 opal_unpack_partial_datatype( opal_convertor_t* pConvertor, dt_elem_desc_t* pElem,
181 unsigned char* partial_data,
182 ptrdiff_t start_position, ptrdiff_t length,
183 unsigned char** user_buffer )
184 {
185 char unused_byte = 0x7F, saved_data[16];
186 unsigned char temporary[16], *temporary_buffer = temporary;
187 unsigned char* user_data = *user_buffer + pElem->elem.disp;
188 size_t count_desc = 1;
189 size_t data_length = opal_datatype_basicDatatypes[pElem->elem.common.type]->size;
190
191 DO_DEBUG( opal_output( 0, "unpack partial data start %lu end %lu data_length %lu user %p\n"
192 "\tbConverted %lu total_length %lu count %ld\n",
193 (unsigned long)start_position, (unsigned long)start_position + length, (unsigned long)data_length, (void*)*user_buffer,
194 (unsigned long)pConvertor->bConverted, (unsigned long)pConvertor->local_size, pConvertor->count ); );
195
196
197 find_unused_byte:
198 for(ptrdiff_t i = 0; i < length; i++ ) {
199 if( unused_byte == partial_data[i] ) {
200 unused_byte--;
201 goto find_unused_byte;
202 }
203 }
204
205
206 memset( temporary, unused_byte, data_length );
207 MEMCPY( temporary + start_position, partial_data, length );
208
209 #if OPAL_CUDA_SUPPORT
210
211
212
213 pConvertor->cbmemcpy(saved_data, user_data, data_length, pConvertor );
214 #else
215
216 MEMCPY( saved_data, user_data, data_length );
217 #endif
218
219
220 UNPACK_PREDEFINED_DATATYPE( pConvertor, pElem, count_desc,
221 temporary_buffer, *user_buffer, data_length );
222
223
224 data_length = opal_datatype_basicDatatypes[pElem->elem.common.type]->size;
225
226
227
228
229 #if OPAL_CUDA_SUPPORT
230
231
232
233
234 {
235 char resaved_data[16];
236 pConvertor->cbmemcpy(resaved_data, user_data, data_length, pConvertor );
237 for(size_t i = 0; i < data_length; i++ ) {
238 if( unused_byte == resaved_data[i] )
239 pConvertor->cbmemcpy(&user_data[i], &saved_data[i], 1, pConvertor);
240 }
241 }
242 #else
243 for(size_t i = 0; i < data_length; i++ ) {
244 if( unused_byte == user_data[i] )
245 user_data[i] = saved_data[i];
246 }
247 #endif
248 }
249
250
251
252
253
254
255
256
257
258
259
260 int32_t
261 opal_generic_simple_unpack_function( opal_convertor_t* pConvertor,
262 struct iovec* iov, uint32_t* out_size,
263 size_t* max_data )
264 {
265 dt_stack_t* pStack;
266 uint32_t pos_desc;
267 size_t count_desc;
268 size_t total_unpacked = 0;
269 dt_elem_desc_t* description;
270 dt_elem_desc_t* pElem;
271 const opal_datatype_t *pData = pConvertor->pDesc;
272 unsigned char *conv_ptr, *iov_ptr;
273 size_t iov_len_local;
274 uint32_t iov_count;
275
276 DO_DEBUG( opal_output( 0, "opal_convertor_generic_simple_unpack( %p, {%p, %lu}, %u )\n",
277 (void*)pConvertor, (void*)iov[0].iov_base, (unsigned long)iov[0].iov_len, *out_size ); );
278
279 description = pConvertor->use_desc->desc;
280
281
282
283
284
285 pStack = pConvertor->pStack + pConvertor->stack_pos;
286 pos_desc = pStack->index;
287 conv_ptr = pConvertor->pBaseBuf + pStack->disp;
288 count_desc = pStack->count;
289 pStack--;
290 pConvertor->stack_pos--;
291 pElem = &(description[pos_desc]);
292
293 DO_DEBUG( opal_output( 0, "unpack start pos_desc %d count_desc %" PRIsize_t " disp %ld\n"
294 "stack_pos %d pos_desc %d count_desc %" PRIsize_t " disp %ld\n",
295 pos_desc, count_desc, (long)(conv_ptr - pConvertor->pBaseBuf),
296 pConvertor->stack_pos, pStack->index, pStack->count, (long)(pStack->disp) ); );
297
298 for( iov_count = 0; iov_count < (*out_size); iov_count++ ) {
299 iov_ptr = (unsigned char *) iov[iov_count].iov_base;
300 iov_len_local = iov[iov_count].iov_len;
301 if( 0 != pConvertor->partial_length ) {
302 size_t element_length = opal_datatype_basicDatatypes[pElem->elem.common.type]->size;
303 size_t missing_length = element_length - pConvertor->partial_length;
304
305 assert( pElem->elem.common.flags & OPAL_DATATYPE_FLAG_DATA );
306 COMPUTE_CSUM( iov_ptr, missing_length, pConvertor );
307 opal_unpack_partial_datatype( pConvertor, pElem,
308 iov_ptr,
309 pConvertor->partial_length, element_length - pConvertor->partial_length,
310 &conv_ptr );
311 --count_desc;
312 if( 0 == count_desc ) {
313 conv_ptr = pConvertor->pBaseBuf + pStack->disp;
314 pos_desc++;
315 UPDATE_INTERNAL_COUNTERS( description, pos_desc, pElem, count_desc );
316 }
317 iov_ptr += missing_length;
318 iov_len_local -= missing_length;
319 pConvertor->partial_length = 0;
320 }
321 while( 1 ) {
322 while( pElem->elem.common.flags & OPAL_DATATYPE_FLAG_DATA ) {
323
324 UNPACK_PREDEFINED_DATATYPE( pConvertor, pElem, count_desc,
325 iov_ptr, conv_ptr, iov_len_local );
326 if( 0 == count_desc ) {
327 conv_ptr = pConvertor->pBaseBuf + pStack->disp;
328 pos_desc++;
329 UPDATE_INTERNAL_COUNTERS( description, pos_desc, pElem, count_desc );
330 continue;
331 }
332 assert( pElem->elem.common.type < OPAL_DATATYPE_MAX_PREDEFINED );
333 if( 0 != iov_len_local ) {
334 unsigned char* temp = conv_ptr;
335
336
337
338 assert( iov_len_local < opal_datatype_basicDatatypes[pElem->elem.common.type]->size );
339 COMPUTE_CSUM( iov_ptr, iov_len_local, pConvertor );
340
341 opal_unpack_partial_datatype( pConvertor, pElem,
342 iov_ptr, 0, iov_len_local,
343 &temp );
344
345 pConvertor->partial_length = iov_len_local;
346 iov_len_local = 0;
347 }
348 goto complete_loop;
349 }
350 if( OPAL_DATATYPE_END_LOOP == pElem->elem.common.type ) {
351 DO_DEBUG( opal_output( 0, "unpack end_loop count %" PRIsize_t " stack_pos %d pos_desc %d disp %ld space %lu\n",
352 pStack->count, pConvertor->stack_pos, pos_desc,
353 pStack->disp, (unsigned long)iov_len_local ); );
354 if( --(pStack->count) == 0 ) {
355 if( 0 == pConvertor->stack_pos ) {
356
357 iov[iov_count].iov_len -= iov_len_local;
358 total_unpacked += iov[iov_count].iov_len;
359 iov_count++;
360 goto complete_conversion;
361 }
362 pConvertor->stack_pos--;
363 pStack--;
364 pos_desc++;
365 } else {
366 pos_desc = pStack->index + 1;
367 if( pStack->index == -1 ) {
368 pStack->disp += (pData->ub - pData->lb);
369 } else {
370 assert( OPAL_DATATYPE_LOOP == description[pStack->index].loop.common.type );
371 pStack->disp += description[pStack->index].loop.extent;
372 }
373 }
374 conv_ptr = pConvertor->pBaseBuf + pStack->disp;
375 UPDATE_INTERNAL_COUNTERS( description, pos_desc, pElem, count_desc );
376 DO_DEBUG( opal_output( 0, "unpack new_loop count %" PRIsize_t " stack_pos %d pos_desc %d disp %ld space %lu\n",
377 pStack->count, pConvertor->stack_pos, pos_desc,
378 pStack->disp, (unsigned long)iov_len_local ); );
379 }
380 if( OPAL_DATATYPE_LOOP == pElem->elem.common.type ) {
381 ptrdiff_t local_disp = (ptrdiff_t)conv_ptr;
382 if( pElem->loop.common.flags & OPAL_DATATYPE_FLAG_CONTIGUOUS ) {
383 UNPACK_CONTIGUOUS_LOOP( pConvertor, pElem, count_desc,
384 iov_ptr, conv_ptr, iov_len_local );
385 if( 0 == count_desc ) {
386 pos_desc += pElem->loop.items + 1;
387 goto update_loop_description;
388 }
389
390 }
391 local_disp = (ptrdiff_t)conv_ptr - local_disp;
392 PUSH_STACK( pStack, pConvertor->stack_pos, pos_desc, OPAL_DATATYPE_LOOP, count_desc,
393 pStack->disp + local_disp);
394 pos_desc++;
395 update_loop_description:
396 conv_ptr = pConvertor->pBaseBuf + pStack->disp;
397 UPDATE_INTERNAL_COUNTERS( description, pos_desc, pElem, count_desc );
398 DDT_DUMP_STACK( pConvertor->pStack, pConvertor->stack_pos, pElem, "advance loop" );
399 continue;
400 }
401 }
402 complete_loop:
403 iov[iov_count].iov_len -= iov_len_local;
404 total_unpacked += iov[iov_count].iov_len;
405 }
406 complete_conversion:
407 *max_data = total_unpacked;
408 pConvertor->bConverted += total_unpacked;
409 *out_size = iov_count;
410 if( pConvertor->bConverted == pConvertor->remote_size ) {
411 pConvertor->flags |= CONVERTOR_COMPLETED;
412 return 1;
413 }
414
415 PUSH_STACK( pStack, pConvertor->stack_pos, pos_desc, pElem->elem.common.type, count_desc,
416 conv_ptr - pConvertor->pBaseBuf );
417 DO_DEBUG( opal_output( 0, "unpack save stack stack_pos %d pos_desc %d count_desc %" PRIsize_t " disp %ld\n",
418 pConvertor->stack_pos, pStack->index, pStack->count, (long)pStack->disp ); );
419 return 0;
420 }
421
422
423
424
425
426
427
428
429
430
431
432
433
434 int32_t
435 opal_unpack_general_function( opal_convertor_t* pConvertor,
436 struct iovec* iov, uint32_t* out_size,
437 size_t* max_data )
438 {
439 dt_stack_t* pStack;
440 uint32_t pos_desc;
441 size_t count_desc;
442 uint16_t type = OPAL_DATATYPE_MAX_PREDEFINED;
443 size_t total_unpacked = 0;
444 dt_elem_desc_t* description;
445 dt_elem_desc_t* pElem;
446 const opal_datatype_t *pData = pConvertor->pDesc;
447 unsigned char *conv_ptr, *iov_ptr;
448 uint32_t iov_count;
449 size_t iov_len_local;
450
451 const opal_convertor_master_t* master = pConvertor->master;
452 ptrdiff_t advance;
453 size_t rc;
454
455 DO_DEBUG( opal_output( 0, "opal_convertor_general_unpack( %p, {%p, %lu}, %d )\n",
456 (void*)pConvertor, (void*)iov[0].iov_base, (unsigned long)iov[0].iov_len, *out_size ); );
457
458 description = pConvertor->use_desc->desc;
459
460
461
462
463
464 pStack = pConvertor->pStack + pConvertor->stack_pos;
465 pos_desc = pStack->index;
466 conv_ptr = pConvertor->pBaseBuf + pStack->disp;
467 count_desc = pStack->count;
468 pStack--;
469 pConvertor->stack_pos--;
470 pElem = &(description[pos_desc]);
471
472 DO_DEBUG( opal_output( 0, "unpack start pos_desc %d count_desc %" PRIsize_t " disp %ld\n"
473 "stack_pos %d pos_desc %d count_desc %" PRIsize_t " disp %ld\n",
474 pos_desc, count_desc, (long)(conv_ptr - pConvertor->pBaseBuf),
475 pConvertor->stack_pos, pStack->index, pStack->count, (long)(pStack->disp) ); );
476
477 for( iov_count = 0; iov_count < (*out_size); iov_count++ ) {
478 iov_ptr = (unsigned char *) iov[iov_count].iov_base;
479 iov_len_local = iov[iov_count].iov_len;
480 assert( 0 == pConvertor->partial_length );
481 while( 1 ) {
482 while( pElem->elem.common.flags & OPAL_DATATYPE_FLAG_DATA ) {
483
484 type = description[pos_desc].elem.common.type;
485 OPAL_DATATYPE_SAFEGUARD_POINTER( conv_ptr + pElem->elem.disp, pData->size, pConvertor->pBaseBuf,
486 pData, pConvertor->count );
487 DO_DEBUG( opal_output( 0, "unpack (%p, %ld) -> (%p:%ld, %" PRIsize_t ", %ld) type %s\n",
488 (void*)iov_ptr, iov_len_local,
489 (void*)pConvertor->pBaseBuf, conv_ptr + pElem->elem.disp - pConvertor->pBaseBuf,
490 count_desc, description[pos_desc].elem.extent,
491 opal_datatype_basicDatatypes[type]->name ); );
492 rc = master->pFunctions[type]( pConvertor, count_desc,
493 iov_ptr, iov_len_local, opal_datatype_basicDatatypes[type]->size,
494 conv_ptr + pElem->elem.disp,
495 (pConvertor->pDesc->ub - pConvertor->pDesc->lb) * pConvertor->count,
496 description[pos_desc].elem.extent, &advance );
497 iov_len_local -= advance;
498 iov_ptr += advance;
499 count_desc -= rc;
500 if( 0 == count_desc ) {
501 conv_ptr = pConvertor->pBaseBuf + pStack->disp;
502 pos_desc++;
503 UPDATE_INTERNAL_COUNTERS( description, pos_desc, pElem, count_desc );
504 if( 0 == iov_len_local ) goto complete_loop;
505 continue;
506 }
507 conv_ptr += rc * description[pos_desc].elem.extent;
508 assert( pElem->elem.common.type < OPAL_DATATYPE_MAX_PREDEFINED );
509 assert( 0 == iov_len_local );
510 if( 0 != iov_len_local ) {
511 unsigned char* temp = conv_ptr;
512
513
514
515 assert( iov_len_local < opal_datatype_basicDatatypes[pElem->elem.common.type]->size );
516 COMPUTE_CSUM( iov_ptr, iov_len_local, pConvertor );
517
518 opal_unpack_partial_datatype( pConvertor, pElem,
519 iov_ptr, 0, iov_len_local,
520 &temp );
521
522 pConvertor->partial_length = iov_len_local;
523 iov_len_local = 0;
524 }
525 goto complete_loop;
526 }
527 if( OPAL_DATATYPE_END_LOOP == pElem->elem.common.type ) {
528 DO_DEBUG( opal_output( 0, "unpack end_loop count %" PRIsize_t " stack_pos %d pos_desc %d disp %ld space %lu\n",
529 pStack->count, pConvertor->stack_pos, pos_desc,
530 pStack->disp, (unsigned long)iov_len_local ); );
531 if( --(pStack->count) == 0 ) {
532 if( 0 == pConvertor->stack_pos ) {
533
534 iov[iov_count].iov_len -= iov_len_local;
535 total_unpacked += iov[iov_count].iov_len;
536 iov_count++;
537 goto complete_conversion;
538 }
539 pConvertor->stack_pos--;
540 pStack--;
541 pos_desc++;
542 } else {
543 pos_desc = pStack->index + 1;
544 if( pStack->index == -1 ) {
545 pStack->disp += (pData->ub - pData->lb);
546 } else {
547 assert( OPAL_DATATYPE_LOOP == description[pStack->index].loop.common.type );
548 pStack->disp += description[pStack->index].loop.extent;
549 }
550 }
551 conv_ptr = pConvertor->pBaseBuf + pStack->disp;
552 UPDATE_INTERNAL_COUNTERS( description, pos_desc, pElem, count_desc );
553 DO_DEBUG( opal_output( 0, "unpack new_loop count %" PRIsize_t " stack_pos %d pos_desc %d disp %ld space %lu\n",
554 pStack->count, pConvertor->stack_pos, pos_desc,
555 pStack->disp, (unsigned long)iov_len_local ); );
556 }
557 if( OPAL_DATATYPE_LOOP == pElem->elem.common.type ) {
558 PUSH_STACK( pStack, pConvertor->stack_pos, pos_desc, OPAL_DATATYPE_LOOP, count_desc,
559 pStack->disp );
560 pos_desc++;
561 conv_ptr = pConvertor->pBaseBuf + pStack->disp;
562 UPDATE_INTERNAL_COUNTERS( description, pos_desc, pElem, count_desc );
563 DDT_DUMP_STACK( pConvertor->pStack, pConvertor->stack_pos, pElem, "advance loop" );
564 continue;
565 }
566 }
567 complete_loop:
568 iov[iov_count].iov_len -= iov_len_local;
569 total_unpacked += iov[iov_count].iov_len;
570 }
571 complete_conversion:
572 *max_data = total_unpacked;
573 pConvertor->bConverted += total_unpacked;
574 *out_size = iov_count;
575 if( pConvertor->bConverted == pConvertor->remote_size ) {
576 pConvertor->flags |= CONVERTOR_COMPLETED;
577 return 1;
578 }
579
580 PUSH_STACK( pStack, pConvertor->stack_pos, pos_desc, pElem->elem.common.type, count_desc,
581 conv_ptr - pConvertor->pBaseBuf );
582 DO_DEBUG( opal_output( 0, "unpack save stack stack_pos %d pos_desc %d count_desc %" PRIsize_t" disp %ld\n",
583 pConvertor->stack_pos, pStack->index, pStack->count, (long)pStack->disp ); );
584 return 0;
585 }