OpenMPI 0.1.1

- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

opal_datatype_copy.h
1 /* -*- Mode: C; c-basic-offset:4 ; -*- */
2 /*
3 * Copyright (c) 2004-2012 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$
8 *
9 * Additional copyrights may follow
10 *
11 * $HEADER$
12 */
13
14 #if !defined(MEM_OP_NAME)
15 #error
16 #endif /* !defined((MEM_OP_NAME) */
17 #if !defined(MEM_OP)
18 #error
19 #endif /* !defined(MEM_OP) */
20
21 #ifndef STRINGIFY
22 # define STRINGIFY_(arg) #arg
23 # define STRINGIFY(arg) STRINGIFY_(arg)
24 #endif
25
26 #ifndef DT_CONCAT
27 # define DT__CONCAT(a, b) a##b
28 # define DT_CONCAT(a, b) DT__CONCAT(a, b)
29 #endif
30
31
32 #define _predefined_data DT_CONCAT(MEM_OP_NAME,_predefined_data)
33 #define _contiguous_loop DT_CONCAT(MEM_OP_NAME,_contiguous_loop)
34 #define _copy_content_same_ddt DT_CONCAT(MEM_OP_NAME,_copy_content_same_ddt)
35
36 static inline void _predefined_data( const dt_elem_desc_t* ELEM,
37 const opal_datatype_t* DATATYPE,
38 unsigned char* SOURCE_BASE,
39 size_t TOTAL_COUNT,
40 uint32_t COUNT,
41 unsigned char* SOURCE,
42 unsigned char* DESTINATION,
43 size_t* SPACE )
44 {
45 uint32_t _copy_count = (COUNT);
46 size_t _copy_blength;
47 const ddt_elem_desc_t* _elem = &((ELEM)->elem);
48 unsigned char* _source = (SOURCE) + _elem->disp;
49 unsigned char* _destination = (DESTINATION) + _elem->disp;
50
51 _copy_blength = opal_datatype_basicDatatypes[_elem->common.type]->size;
52
53 if( _copy_blength == (uint32_t)_elem->extent ) {
54 _copy_blength *= _copy_count;
55 OPAL_DATATYPE_SAFEGUARD_POINTER( _source, _copy_blength, (SOURCE_BASE),
56 (DATATYPE), (TOTAL_COUNT) );
57 /* the extent and the size of the basic datatype are equals */
58 DO_DEBUG( opal_output( 0, "copy 1. %s( %p, %p, %lu ) => space %lu\n",
59 STRINGIFY(MEM_OP_NAME), _destination, _source, (unsigned long)_copy_blength, (unsigned long)(*(SPACE)) ); );
60 MEM_OP( _destination, _source, _copy_blength );
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( _source, _copy_blength, (SOURCE_BASE),
67 (DATATYPE), (TOTAL_COUNT) );
68 DO_DEBUG( opal_output( 0, "copy 2. %s( %p, %p, %lu ) => space %lu\n",
69 STRINGIFY(MEM_OP_NAME), _destination, _source, (unsigned long)_copy_blength, (unsigned long)(*(SPACE) - (_i * _copy_blength)) ); );
70 MEM_OP( _destination, _source, _copy_blength );
71 _source += _elem->extent;
72 _destination += _elem->extent;
73 }
74 _copy_blength *= _copy_count;
75 }
76 *(SPACE) -= _copy_blength;
77 }
78
79 static inline void _contiguous_loop( const dt_elem_desc_t* ELEM,
80 const opal_datatype_t* DATATYPE,
81 unsigned char* SOURCE_BASE,
82 size_t TOTAL_COUNT,
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* _source = (SOURCE) + _end_loop->first_elem_disp;
91 unsigned char* _destination = (DESTINATION) + _end_loop->first_elem_disp;
92 size_t _copy_loops = (COUNT);
93 uint32_t _i;
94
95 if( _loop->extent == (OPAL_PTRDIFF_TYPE)_end_loop->size ) { /* the loop is contiguous */
96 _copy_loops *= _end_loop->size;
97 OPAL_DATATYPE_SAFEGUARD_POINTER( _source, _copy_loops, (SOURCE_BASE),
98 (DATATYPE), (TOTAL_COUNT) );
99 MEM_OP( _destination, _source, _copy_loops );
100 } else {
101 for( _i = 0; _i < _copy_loops; _i++ ) {
102 OPAL_DATATYPE_SAFEGUARD_POINTER( _source, _end_loop->size, (SOURCE_BASE),
103 (DATATYPE), (TOTAL_COUNT) );
104 DO_DEBUG( opal_output( 0, "copy 3. %s( %p, %p, %lu ) => space %lu\n",
105 STRINGIFY(MEM_OP_NAME), _destination, _source, (unsigned long)_end_loop->size, (unsigned long)(*(SPACE) - _i * _end_loop->size) ); );
106 MEM_OP( _destination, _source, _end_loop->size );
107 _source += _loop->extent;
108 _destination += _loop->extent;
109 }
110 _copy_loops *= _end_loop->size;
111 }
112 *(SPACE) -= _copy_loops;
113 }
114
115 static inline int32_t _copy_content_same_ddt( const opal_datatype_t* datatype, int32_t count,
116 char* destination_base, char* source_base )
117 {
118 dt_stack_t* pStack; /* pointer to the position on the stack */
119 int32_t stack_pos; /* index of the stack level */
120 uint32_t pos_desc; /* actual position in the description of the derived datatype */
121 uint32_t count_desc; /* the number of items already done in the actual pos_desc */
122 dt_elem_desc_t* description;
123 dt_elem_desc_t* pElem;
124 size_t iov_len_local;
125 unsigned char *source = (unsigned char*)source_base,
126 *destination = (unsigned char*)destination_base;
127
128 DO_DEBUG( opal_output( 0, "_copy_content_same_ddt( %p, %d, dst %p, src %p )\n",
129 (void*)datatype, count, destination_base, source_base ); );
130
131 iov_len_local = count * datatype->size;
132
133 /* If we have to copy a contiguous datatype then simply
134 * do a MEM_OP.
135 */
136 if( datatype->flags & OPAL_DATATYPE_FLAG_CONTIGUOUS ) {
137 OPAL_PTRDIFF_TYPE extent = (datatype->ub - datatype->lb);
138 /* Now that we know the datatype is contiguous, we should move the 2 pointers
139 * source and destination to the correct displacement.
140 */
141 destination += datatype->true_lb;
142 source += datatype->true_lb;
143 if( (OPAL_PTRDIFF_TYPE)datatype->size == extent ) { /* all contiguous == no gaps around */
144 size_t total_length = iov_len_local;
145 size_t memop_chunk = opal_datatype_memop_block_size;
146 while( total_length > 0 ) {
147 if( memop_chunk > total_length ) memop_chunk = total_length;
148 OPAL_DATATYPE_SAFEGUARD_POINTER( destination, memop_chunk,
149 (unsigned char*)destination_base, datatype, count );
150 OPAL_DATATYPE_SAFEGUARD_POINTER( source, memop_chunk,
151 (unsigned char*)source_base, datatype, count );
152 DO_DEBUG( opal_output( 0, "copy c1. %s( %p, %p, %lu ) => space %lu\n",
153 STRINGIFY(MEM_OP_NAME), destination, source, (unsigned long)memop_chunk, (unsigned long)total_length ); );
154 MEM_OP( destination, source, memop_chunk );
155 destination += memop_chunk;
156 source += memop_chunk;
157 total_length -= memop_chunk;
158 }
159 return 0; /* completed */
160 }
161 for( pos_desc = 0; (int32_t)pos_desc < count; pos_desc++ ) {
162 OPAL_DATATYPE_SAFEGUARD_POINTER( destination, datatype->size,
163 (unsigned char*)destination_base, datatype, count );
164 OPAL_DATATYPE_SAFEGUARD_POINTER( source, datatype->size,
165 (unsigned char*)source_base, datatype, count );
166 DO_DEBUG( opal_output( 0, "copy c2. %s( %p, %p, %lu ) => space %lu\n",
167 STRINGIFY(MEM_OP_NAME), destination, source, (unsigned long)datatype->size,
168 (unsigned long)(iov_len_local - (pos_desc * datatype->size)) ); );
169 MEM_OP( destination, source, datatype->size );
170 destination += extent;
171 source += extent;
172 }
173 return 0; /* completed */
174 }
175
176 pStack = (dt_stack_t*)alloca( sizeof(dt_stack_t) * (datatype->btypes[OPAL_DATATYPE_LOOP] + 1) );
177 pStack->count = count;
178 pStack->index = -1;
179 pStack->disp = 0;
180 pos_desc = 0;
181 stack_pos = 0;
182
183 if( datatype->opt_desc.desc != NULL ) {
184 description = datatype->opt_desc.desc;
185 } else {
186 description = datatype->desc.desc;
187 }
188
189 if( description[0].elem.common.type == OPAL_DATATYPE_LOOP )
190 count_desc = description[0].loop.loops;
191 else
192 count_desc = description[0].elem.count;
193 pElem = &(description[pos_desc]);
194
195 while( 1 ) {
196 while( OPAL_LIKELY(pElem->elem.common.flags & OPAL_DATATYPE_FLAG_DATA) ) {
197 /* now here we have a basic datatype */
198 _predefined_data( pElem, datatype, (unsigned char*)source_base, count, count_desc,
199 source, destination, &iov_len_local );
200 pos_desc++; /* advance to the next data */
201 UPDATE_INTERNAL_COUNTERS( description, pos_desc, pElem, count_desc );
202 }
203 if( OPAL_DATATYPE_END_LOOP == pElem->elem.common.type ) { /* end of the current loop */
204 DO_DEBUG( opal_output( 0, "copy end_loop count %d stack_pos %d pos_desc %d disp %ld space %lu\n",
205 (int)pStack->count, stack_pos, pos_desc, (long)pStack->disp, (unsigned long)iov_len_local ); );
206 if( --(pStack->count) == 0 ) { /* end of loop */
207 if( stack_pos == 0 ) {
208 assert( iov_len_local == 0 );
209 return 0; /* completed */
210 }
211 stack_pos--;
212 pStack--;
213 pos_desc++;
214 } else {
215 pos_desc = pStack->index + 1;
216 if( pStack->index == -1 ) {
217 pStack->disp += (datatype->ub - datatype->lb);
218 } else {
219 assert( OPAL_DATATYPE_LOOP == description[pStack->index].loop.common.type );
220 pStack->disp += description[pStack->index].loop.extent;
221 }
222 }
223 source = (unsigned char*)source_base + pStack->disp;
224 destination = (unsigned char*)destination_base + pStack->disp;
225 UPDATE_INTERNAL_COUNTERS( description, pos_desc, pElem, count_desc );
226 DO_DEBUG( opal_output( 0, "copy new_loop count %d stack_pos %d pos_desc %d disp %ld space %lu\n",
227 (int)pStack->count, stack_pos, pos_desc, (long)pStack->disp, (unsigned long)iov_len_local ); );
228 }
229 if( OPAL_DATATYPE_LOOP == pElem->elem.common.type ) {
230 OPAL_PTRDIFF_TYPE local_disp = (OPAL_PTRDIFF_TYPE)source;
231 if( pElem->loop.common.flags & OPAL_DATATYPE_FLAG_CONTIGUOUS ) {
232 _contiguous_loop( pElem, datatype, (unsigned char*)source_base, count, count_desc,
233 source, destination, &iov_len_local );
234 pos_desc += pElem->loop.items + 1;
235 goto update_loop_description;
236 }
237 local_disp = (OPAL_PTRDIFF_TYPE)source - local_disp;
238 PUSH_STACK( pStack, stack_pos, pos_desc, OPAL_DATATYPE_LOOP, count_desc,
239 pStack->disp + local_disp);
240 pos_desc++;
241 update_loop_description: /* update the current state */
242 source = (unsigned char*)source_base + pStack->disp;
243 destination = (unsigned char*)destination_base + pStack->disp;
244 UPDATE_INTERNAL_COUNTERS( description, pos_desc, pElem, count_desc );
245 DDT_DUMP_STACK( pStack, stack_pos, pElem, "advance loop" );
246 continue;
247 }
248 }
249 }
opal_datatype_t::flags
uint16_t flags
the flags
Definition: opal_datatype.h:105
ddt_elem_desc::extent
OPAL_PTRDIFF_TYPE extent
extent of each block (in bytes)
Definition: opal_datatype_internal.h:161
ddt_endloop_desc
Definition: opal_datatype_internal.h:175
ddt_endloop_desc::first_elem_disp
OPAL_PTRDIFF_TYPE first_elem_disp
the displacement of the first block in the loop
Definition: opal_datatype_internal.h:180
ddt_loop_desc::loops
uint32_t loops
number of elements
Definition: opal_datatype_internal.h:168
dt_elem_desc
Definition: opal_datatype_internal.h:184
ddt_loop_desc
Definition: opal_datatype_internal.h:166
dt_stack_t::count
size_t count
number of times we still have to do it
Definition: opal_convertor.h:80
opal_datatype_t::desc
dt_type_desc_t desc
the data description
Definition: opal_datatype.h:121
opal_datatype_t::lb
OPAL_PTRDIFF_TYPE lb
lower bound in memory
Definition: opal_datatype.h:112
opal_datatype_t::ub
OPAL_PTRDIFF_TYPE ub
upper bound in memory
Definition: opal_datatype.h:113
ddt_loop_desc::items
uint32_t items
number of items in the loop
Definition: opal_datatype_internal.h:169
ddt_elem_desc::common
ddt_elem_id_description common
basic data description and flags
Definition: opal_datatype_internal.h:158
ddt_elem_id_description::type
uint16_t type
the basic data type id
Definition: opal_datatype_internal.h:150
ddt_elem_desc::count
uint32_t count
number of blocks
Definition: opal_datatype_internal.h:159
opal_output
OPAL_DECLSPEC void opal_output(int output_id, const char *format,...) __opal_attribute_format__(__printf__
Main function to send output to a stream.
dt_stack_t
Definition: opal_convertor.h:77
ddt_endloop_desc::size
size_t size
real size of the data in the loop
Definition: opal_datatype_internal.h:179
opal_datatype_t::size
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
ddt_loop_desc::extent
OPAL_PTRDIFF_TYPE extent
extent of the whole loop
Definition: opal_datatype_internal.h:171
opal_datatype_t
Definition: opal_datatype.h:103
ddt_loop_desc::common
ddt_elem_id_description common
basic data description and flags
Definition: opal_datatype_internal.h:167
ddt_elem_id_description::flags
uint16_t flags
flags for the record
Definition: opal_datatype_internal.h:149
opal_datatype_t::btypes
uint32_t btypes[OPAL_DATATYPE_MAX_SUPPORTED]
basic elements count used to compute the size of the datatype for remote nodes.
Definition: opal_datatype.h:125
opal_datatype_t::opt_desc
dt_type_desc_t opt_desc
short description of the data used when conversion is useless or in the send case (without conversion...
Definition: opal_datatype.h:122
ddt_elem_desc
Definition: opal_datatype_internal.h:157
opal_datatype_t::true_lb
OPAL_PTRDIFF_TYPE true_lb
the true lb of the data without user defined lb and ub
Definition: opal_datatype.h:110
dt_stack_t::index
int32_t index
index in the element description
Definition: opal_convertor.h:78
dt_stack_t::disp
OPAL_PTRDIFF_TYPE disp
actual displacement depending on the count field
Definition: opal_convertor.h:81
ddt_elem_desc::disp
OPAL_PTRDIFF_TYPE disp
displacement of the first block
Definition: opal_datatype_internal.h:162