OpenMPI  0.1.1
opal_datatype_unpack.h
1 /* -*- Mode: C; c-basic-offset:4 ; -*- */
2 /*
3  * Copyright (c) 2004-2009 The University of Tennessee and The University
4  * of Tennessee Research Foundation. All rights
5  * reserved.
6  * Copyright (c) 2009 Oak Ridge National Labs. All rights reserved.
7  * Copyright (c) 2011 NVIDIA Corporation. All rights reserved.
8  * $COPYRIGHT$
9  *
10  * Additional copyrights may follow
11  *
12  * $HEADER$
13  */
14 
15 #ifndef OPAL_DATATYPE_UNPACK_H_HAS_BEEN_INCLUDED
16 #define OPAL_DATATYPE_UNPACK_H_HAS_BEEN_INCLUDED
17 
18 #include "opal_config.h"
19 
20 #include <stddef.h>
21 #ifdef HAVE_STDINT_H
22 #include <stdint.h>
23 #endif
24 
25 #if !defined(CHECKSUM) && OPAL_CUDA_SUPPORT
26 /* Make use of existing macro to do CUDA style memcpy */
27 #undef MEMCPY_CSUM
28 #define MEMCPY_CSUM( DST, SRC, BLENGTH, CONVERTOR ) \
29  CONVERTOR->cbmemcpy( (DST), (SRC), (BLENGTH) )
30 #endif
31 
32 #include "opal/datatype/opal_convertor.h"
33 
34 
35 static inline void unpack_predefined_data( opal_convertor_t* CONVERTOR, /* the convertor */
36  dt_elem_desc_t* ELEM, /* the element description */
37  uint32_t* COUNT, /* the number of elements */
38  unsigned char** SOURCE, /* the source pointer */
39  unsigned char** DESTINATION, /* the destination pointer */
40  size_t* SPACE ) /* the space in the destination buffer */
41 {
42  uint32_t _copy_count = *(COUNT);
43  size_t _copy_blength;
44  ddt_elem_desc_t* _elem = &((ELEM)->elem);
45  unsigned char* _destination = (*DESTINATION) + _elem->disp;
46 
47  _copy_blength = opal_datatype_basicDatatypes[_elem->common.type]->size;
48  if( (_copy_count * _copy_blength) > *(SPACE) ) {
49  _copy_count = (uint32_t)(*(SPACE) / _copy_blength);
50  if( 0 == _copy_count ) return; /* nothing to do */
51  }
52 
53  if( (OPAL_PTRDIFF_TYPE)_copy_blength == _elem->extent ) {
54  _copy_blength *= _copy_count;
55  /* the extent and the size of the basic datatype are equal */
56  OPAL_DATATYPE_SAFEGUARD_POINTER( _destination, _copy_blength, (CONVERTOR)->pBaseBuf,
57  (CONVERTOR)->pDesc, (CONVERTOR)->count );
58  DO_DEBUG( opal_output( 0, "unpack 1. memcpy( %p, %p, %lu ) => space %lu\n",
59  _destination, *(SOURCE), (unsigned long)_copy_blength, (unsigned long)(*(SPACE)) ); );
60  MEMCPY_CSUM( _destination, *(SOURCE), _copy_blength, (CONVERTOR) );
61  *(SOURCE) += _copy_blength;
62  _destination += _copy_blength;
63  } else {
64  uint32_t _i;
65  for( _i = 0; _i < _copy_count; _i++ ) {
66  OPAL_DATATYPE_SAFEGUARD_POINTER( _destination, _copy_blength, (CONVERTOR)->pBaseBuf,
67  (CONVERTOR)->pDesc, (CONVERTOR)->count );
68  DO_DEBUG( opal_output( 0, "unpack 2. memcpy( %p, %p, %lu ) => space %lu\n",
69  _destination, *(SOURCE), (unsigned long)_copy_blength, (unsigned long)(*(SPACE) - (_i * _copy_blength)) ); );
70  MEMCPY_CSUM( _destination, *(SOURCE), _copy_blength, (CONVERTOR) );
71  *(SOURCE) += _copy_blength;
72  _destination += _elem->extent;
73  }
74  _copy_blength *= _copy_count;
75  }
76  (*DESTINATION) = _destination - _elem->disp;
77  *(SPACE) -= _copy_blength;
78  *(COUNT) -= _copy_count;
79 }
80 
81 static inline void unpack_contiguous_loop( opal_convertor_t* CONVERTOR,
82  dt_elem_desc_t* ELEM,
83  uint32_t* COUNT,
84  unsigned char** SOURCE,
85  unsigned char** DESTINATION,
86  size_t* SPACE )
87 {
88  ddt_loop_desc_t *_loop = (ddt_loop_desc_t*)(ELEM);
89  ddt_endloop_desc_t* _end_loop = (ddt_endloop_desc_t*)((ELEM) + _loop->items);
90  unsigned char* _destination = (*DESTINATION) + _end_loop->first_elem_disp;
91  uint32_t _copy_loops = *(COUNT);
92  uint32_t _i;
93 
94  if( (_copy_loops * _end_loop->size) > *(SPACE) )
95  _copy_loops = (uint32_t)(*(SPACE) / _end_loop->size);
96  for( _i = 0; _i < _copy_loops; _i++ ) {
97  OPAL_DATATYPE_SAFEGUARD_POINTER( _destination, _end_loop->size, (CONVERTOR)->pBaseBuf,
98  (CONVERTOR)->pDesc, (CONVERTOR)->count );
99  DO_DEBUG( opal_output( 0, "unpack 3. memcpy( %p, %p, %lu ) => space %lu\n",
100  _destination, *(SOURCE), (unsigned long)_end_loop->size, (unsigned long)(*(SPACE) - _i * _end_loop->size) ); );
101  MEMCPY_CSUM( _destination, *(SOURCE), _end_loop->size, (CONVERTOR) );
102  *(SOURCE) += _end_loop->size;
103  _destination += _loop->extent;
104  }
105  *(DESTINATION) = _destination - _end_loop->first_elem_disp;
106  *(SPACE) -= _copy_loops * _end_loop->size;
107  *(COUNT) -= _copy_loops;
108 }
109 
110 #define UNPACK_PREDEFINED_DATATYPE( CONVERTOR, ELEM, COUNT, SOURCE, DESTINATION, SPACE ) \
111  unpack_predefined_data( (CONVERTOR), (ELEM), &(COUNT), &(SOURCE), &(DESTINATION), &(SPACE) )
112 
113 #define UNPACK_CONTIGUOUS_LOOP( CONVERTOR, ELEM, COUNT, SOURCE, DESTINATION, SPACE ) \
114  unpack_contiguous_loop( (CONVERTOR), (ELEM), &(COUNT), &(SOURCE), &(DESTINATION), &(SPACE) )
115 
116 #endif /* OPAL_DATATYPE_UNPACK_H_HAS_BEEN_INCLUDED */
OPAL_PTRDIFF_TYPE extent
extent of each block (in bytes)
Definition: opal_datatype_internal.h:161
Definition: opal_datatype_internal.h:175
OPAL_PTRDIFF_TYPE first_elem_disp
the displacement of the first block in the loop
Definition: opal_datatype_internal.h:180
Definition: opal_datatype_internal.h:184
Definition: opal_datatype_internal.h:166
uint32_t items
number of items in the loop
Definition: opal_datatype_internal.h:169
ddt_elem_id_description common
basic data description and flags
Definition: opal_datatype_internal.h:158
uint16_t type
the basic data type id
Definition: opal_datatype_internal.h:150
OPAL_DECLSPEC void opal_output(int output_id, const char *format,...) __opal_attribute_format__(__printf__
Main function to send output to a stream.
size_t size
real size of the data in the loop
Definition: opal_datatype_internal.h:179
size_t size
total size in bytes of the memory used by the data if the data is put on a contiguous buffer ...
Definition: opal_datatype.h:108
OPAL_PTRDIFF_TYPE extent
extent of the whole loop
Definition: opal_datatype_internal.h:171
Definition: opal_convertor.h:90
Definition: opal_datatype_internal.h:157
OPAL_PTRDIFF_TYPE disp
displacement of the first block
Definition: opal_datatype_internal.h:162