OpenMPI  0.1.1
opal_datatype_pack.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_PACK_H_HAS_BEEN_INCLUDED
16 #define OPAL_DATATYPE_PACK_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 static inline void pack_predefined_data( opal_convertor_t* CONVERTOR,
33  dt_elem_desc_t* ELEM,
34  uint32_t* COUNT,
35  unsigned char** SOURCE,
36  unsigned char** DESTINATION,
37  size_t* SPACE )
38 {
39  uint32_t _copy_count = *(COUNT);
40  size_t _copy_blength;
41  ddt_elem_desc_t* _elem = &((ELEM)->elem);
42  unsigned char* _source = (*SOURCE) + _elem->disp;
43 
44  _copy_blength = opal_datatype_basicDatatypes[_elem->common.type]->size;
45  if( (_copy_count * _copy_blength) > *(SPACE) ) {
46  _copy_count = (uint32_t)(*(SPACE) / _copy_blength);
47  if( 0 == _copy_count ) return; /* nothing to do */
48  }
49 
50  if( (OPAL_PTRDIFF_TYPE)_copy_blength == _elem->extent ) {
51  _copy_blength *= _copy_count;
52  /* the extent and the size of the basic datatype are equal */
53  OPAL_DATATYPE_SAFEGUARD_POINTER( _source, _copy_blength, (CONVERTOR)->pBaseBuf,
54  (CONVERTOR)->pDesc, (CONVERTOR)->count );
55  DO_DEBUG( opal_output( 0, "pack 1. memcpy( %p, %p, %lu ) => space %lu\n",
56  *(DESTINATION), _source, (unsigned long)_copy_blength, (unsigned long)(*(SPACE)) ); );
57  MEMCPY_CSUM( *(DESTINATION), _source, _copy_blength, (CONVERTOR) );
58  _source += _copy_blength;
59  *(DESTINATION) += _copy_blength;
60  } else {
61  uint32_t _i;
62  for( _i = 0; _i < _copy_count; _i++ ) {
63  OPAL_DATATYPE_SAFEGUARD_POINTER( _source, _copy_blength, (CONVERTOR)->pBaseBuf,
64  (CONVERTOR)->pDesc, (CONVERTOR)->count );
65  DO_DEBUG( opal_output( 0, "pack 2. memcpy( %p, %p, %lu ) => space %lu\n",
66  *(DESTINATION), _source, (unsigned long)_copy_blength, (unsigned long)(*(SPACE) - (_i * _copy_blength)) ); );
67  MEMCPY_CSUM( *(DESTINATION), _source, _copy_blength, (CONVERTOR) );
68  *(DESTINATION) += _copy_blength;
69  _source += _elem->extent;
70  }
71  _copy_blength *= _copy_count;
72  }
73  *(SOURCE) = _source - _elem->disp;
74  *(SPACE) -= _copy_blength;
75  *(COUNT) -= _copy_count;
76 }
77 
78 static inline void pack_contiguous_loop( opal_convertor_t* CONVERTOR,
79  dt_elem_desc_t* ELEM,
80  uint32_t* COUNT,
81  unsigned char** SOURCE,
82  unsigned char** DESTINATION,
83  size_t* SPACE )
84 {
85  ddt_loop_desc_t *_loop = (ddt_loop_desc_t*)(ELEM);
86  ddt_endloop_desc_t* _end_loop = (ddt_endloop_desc_t*)((ELEM) + _loop->items);
87  unsigned char* _source = (*SOURCE) + _end_loop->first_elem_disp;
88  uint32_t _copy_loops = *(COUNT);
89  uint32_t _i;
90 
91  if( (_copy_loops * _end_loop->size) > *(SPACE) )
92  _copy_loops = (uint32_t)(*(SPACE) / _end_loop->size);
93  for( _i = 0; _i < _copy_loops; _i++ ) {
94  OPAL_DATATYPE_SAFEGUARD_POINTER( _source, _end_loop->size, (CONVERTOR)->pBaseBuf,
95  (CONVERTOR)->pDesc, (CONVERTOR)->count );
96  DO_DEBUG( opal_output( 0, "pack 3. memcpy( %p, %p, %lu ) => space %lu\n",
97  *(DESTINATION), _source, (unsigned long)_end_loop->size, (unsigned long)(*(SPACE) - _i * _end_loop->size) ); );
98  MEMCPY_CSUM( *(DESTINATION), _source, _end_loop->size, (CONVERTOR) );
99  *(DESTINATION) += _end_loop->size;
100  _source += _loop->extent;
101  }
102  *(SOURCE) = _source - _end_loop->first_elem_disp;
103  *(SPACE) -= _copy_loops * _end_loop->size;
104  *(COUNT) -= _copy_loops;
105 }
106 
107 #define PACK_PREDEFINED_DATATYPE( CONVERTOR, /* the convertor */ \
108  ELEM, /* the basic element to be packed */ \
109  COUNT, /* the number of elements */ \
110  SOURCE, /* the source pointer (char*) */ \
111  DESTINATION, /* the destination pointer (char*) */ \
112  SPACE ) /* the space in the destination buffer */ \
113 pack_predefined_data( (CONVERTOR), (ELEM), &(COUNT), &(SOURCE), &(DESTINATION), &(SPACE) )
114 
115 #define PACK_CONTIGUOUS_LOOP( CONVERTOR, ELEM, COUNT, SOURCE, DESTINATION, SPACE ) \
116  pack_contiguous_loop( (CONVERTOR), (ELEM), &(COUNT), &(SOURCE), &(DESTINATION), &(SPACE) )
117 
118 #endif /* OPAL_DATATYPE_PACK_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