This source file includes following definitions.
- opal_datatype_optimize_short
- opal_datatype_commit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 #include "opal_config.h"
25
26 #include <stddef.h>
27 #include <stdlib.h>
28
29 #include "opal/datatype/opal_datatype.h"
30 #include "opal/datatype/opal_convertor.h"
31 #include "opal/datatype/opal_datatype_internal.h"
32
33 #define SET_EMPTY_ELEMENT( ELEM ) \
34 do { \
35 ddt_elem_desc_t* _elem = (ELEM); \
36 _elem->common.flags = OPAL_DATATYPE_FLAG_BASIC; \
37 _elem->common.type = OPAL_DATATYPE_LOOP; \
38 _elem->count = 0; \
39 _elem->disp = 0; \
40 _elem->extent = 0; \
41 } while (0)
42
43 static int32_t
44 opal_datatype_optimize_short( opal_datatype_t* pData,
45 size_t count,
46 dt_type_desc_t* pTypeDesc )
47 {
48 dt_elem_desc_t* pElemDesc;
49 ddt_elem_desc_t opt_elem;
50 dt_stack_t* pOrigStack;
51 dt_stack_t* pStack;
52 int32_t pos_desc = 0;
53 int32_t stack_pos = 0, last_type = OPAL_DATATYPE_UINT1;
54 int32_t type = OPAL_DATATYPE_LOOP, nbElems = 0, continuity;
55 ptrdiff_t total_disp = 0, last_extent = 1, last_disp = 0;
56 uint16_t last_flags = 0xFFFF;
57 uint32_t i;
58 size_t last_length = 0;
59
60 pOrigStack = pStack = (dt_stack_t*)malloc( sizeof(dt_stack_t) * (pData->loops+2) );
61 SAVE_STACK( pStack, -1, 0, count, 0 );
62
63 pTypeDesc->length = 2 * pData->desc.used + 1 ;
64 pTypeDesc->desc = pElemDesc = (dt_elem_desc_t*)malloc( sizeof(dt_elem_desc_t) * pTypeDesc->length );
65 pTypeDesc->used = 0;
66
67 SET_EMPTY_ELEMENT( &opt_elem );
68 assert( OPAL_DATATYPE_END_LOOP == pData->desc.desc[pData->desc.used].elem.common.type );
69 opt_elem.common.type = OPAL_DATATYPE_LOOP;
70 opt_elem.common.flags = 0xFFFF;
71 opt_elem.count = 0;
72 opt_elem.disp = pData->desc.desc[pData->desc.used].end_loop.first_elem_disp;
73 opt_elem.extent = 0;
74
75 while( stack_pos >= 0 ) {
76 if( OPAL_DATATYPE_END_LOOP == pData->desc.desc[pos_desc].elem.common.type ) {
77 ddt_endloop_desc_t* end_loop = &(pData->desc.desc[pos_desc].end_loop);
78 if( last_length != 0 ) {
79 CREATE_ELEM( pElemDesc, last_type, OPAL_DATATYPE_FLAG_BASIC, last_length, last_disp, last_extent );
80 pElemDesc++; nbElems++;
81 last_disp += last_length;
82 last_length = 0;
83 }
84 CREATE_LOOP_END( pElemDesc, nbElems - pStack->index + 1,
85 end_loop->first_elem_disp, end_loop->size, end_loop->common.flags );
86 pElemDesc++; nbElems++;
87 if( --stack_pos >= 0 ) {
88 ddt_loop_desc_t* pStartLoop = &(pTypeDesc->desc[pStack->index - 1].loop);
89 pStartLoop->items = end_loop->items;
90 total_disp = pStack->disp;
91 }
92 pStack--;
93 pos_desc++;
94 continue;
95 }
96 if( OPAL_DATATYPE_LOOP == pData->desc.desc[pos_desc].elem.common.type ) {
97 ddt_loop_desc_t* loop = (ddt_loop_desc_t*)&(pData->desc.desc[pos_desc]);
98 ddt_endloop_desc_t* end_loop = (ddt_endloop_desc_t*)&(pData->desc.desc[pos_desc + loop->items]);
99 int index = GET_FIRST_NON_LOOP( &(pData->desc.desc[pos_desc]) );
100 ptrdiff_t loop_disp = pData->desc.desc[pos_desc + index].elem.disp;
101
102 continuity = ((last_disp + (ptrdiff_t)last_length * (ptrdiff_t)opal_datatype_basicDatatypes[last_type]->size)
103 == (total_disp + loop_disp));
104 if( loop->common.flags & OPAL_DATATYPE_FLAG_CONTIGUOUS ) {
105
106 if( loop->extent == (ptrdiff_t)end_loop->size ) {
107
108 if( !continuity ) {
109 if( 0 != last_length ) {
110 CREATE_ELEM( pElemDesc, last_type, OPAL_DATATYPE_FLAG_BASIC,
111 last_length, last_disp, last_extent );
112 pElemDesc++; nbElems++;
113 last_length = 0;
114 }
115 last_disp = total_disp + loop_disp;
116 }
117 last_length = (last_length * opal_datatype_basicDatatypes[last_type]->size
118 + loop->loops * end_loop->size);
119 last_type = OPAL_DATATYPE_UINT1;
120 last_extent = 1;
121 } else {
122 int counter = loop->loops;
123 ptrdiff_t merged_disp = 0;
124
125 if( last_length != 0 ) {
126 if( continuity ) {
127 last_length *= opal_datatype_basicDatatypes[last_type]->size;
128 last_length += end_loop->size;
129 last_type = OPAL_DATATYPE_UINT1;
130 last_extent = 1;
131 counter--;
132 merged_disp = loop->extent;
133 }
134 CREATE_ELEM( pElemDesc, last_type, OPAL_DATATYPE_FLAG_BASIC,
135 last_length, last_disp, last_extent );
136 pElemDesc++; nbElems++;
137 last_disp += last_length;
138 last_length = 0;
139 last_type = OPAL_DATATYPE_LOOP;
140 }
141
142
143
144
145
146
147
148 if( counter <= 2 ) {
149 merged_disp += end_loop->first_elem_disp;
150 while( counter > 0 ) {
151 CREATE_ELEM( pElemDesc, OPAL_DATATYPE_UINT1, OPAL_DATATYPE_FLAG_BASIC,
152 end_loop->size, merged_disp, 1);
153 pElemDesc++; nbElems++; counter--;
154 merged_disp += loop->extent;
155 }
156 } else {
157 CREATE_LOOP_START( pElemDesc, counter, 2, loop->extent, loop->common.flags );
158 pElemDesc++; nbElems++;
159 CREATE_ELEM( pElemDesc, OPAL_DATATYPE_UINT1, OPAL_DATATYPE_FLAG_BASIC,
160 end_loop->size, loop_disp, 1);
161 pElemDesc++; nbElems++;
162 CREATE_LOOP_END( pElemDesc, 2, end_loop->first_elem_disp + merged_disp,
163 end_loop->size, end_loop->common.flags );
164 pElemDesc++; nbElems++;
165 }
166 }
167 pos_desc += loop->items + 1;
168 } else {
169 ddt_elem_desc_t* elem = (ddt_elem_desc_t*)&(pData->desc.desc[pos_desc+1]);
170 if( last_length != 0 ) {
171 CREATE_ELEM( pElemDesc, last_type, OPAL_DATATYPE_FLAG_BASIC, last_length, last_disp, last_extent );
172 pElemDesc++; nbElems++;
173 last_disp += last_length;
174 last_length = 0;
175 last_type = OPAL_DATATYPE_LOOP;
176 }
177 if( 2 == loop->items ) {
178 if( (1 == elem->count)
179 && (elem->extent == (ptrdiff_t)opal_datatype_basicDatatypes[elem->common.type]->size) ) {
180 CREATE_ELEM( pElemDesc, elem->common.type, elem->common.flags & ~OPAL_DATATYPE_FLAG_CONTIGUOUS,
181 loop->loops, elem->disp, loop->extent );
182 pElemDesc++; nbElems++;
183 pos_desc += loop->items + 1;
184 goto complete_loop;
185 } else if( loop->loops < 3 ) {
186 ptrdiff_t elem_displ = elem->disp;
187 for( i = 0; i < loop->loops; i++ ) {
188 CREATE_ELEM( pElemDesc, elem->common.type, elem->common.flags,
189 elem->count, elem_displ, elem->extent );
190 elem_displ += loop->extent;
191 pElemDesc++; nbElems++;
192 }
193 pos_desc += loop->items + 1;
194 goto complete_loop;
195 }
196 }
197 CREATE_LOOP_START( pElemDesc, loop->loops, loop->items, loop->extent, loop->common.flags );
198 pElemDesc++; nbElems++;
199 PUSH_STACK( pStack, stack_pos, nbElems, OPAL_DATATYPE_LOOP, loop->loops, total_disp );
200 pos_desc++;
201 DDT_DUMP_STACK( pStack, stack_pos, pData->desc.desc, "advance loops" );
202 }
203 complete_loop:
204 total_disp = pStack->disp;
205 continue;
206 }
207 while( pData->desc.desc[pos_desc].elem.common.flags & OPAL_DATATYPE_FLAG_DATA ) {
208
209 type = pData->desc.desc[pos_desc].elem.common.type;
210 continuity = ((last_disp + (ptrdiff_t)last_length * (ptrdiff_t)opal_datatype_basicDatatypes[last_type]->size)
211 == (total_disp + pData->desc.desc[pos_desc].elem.disp));
212
213 if( (pData->desc.desc[pos_desc].elem.common.flags & OPAL_DATATYPE_FLAG_CONTIGUOUS) && continuity &&
214 (pData->desc.desc[pos_desc].elem.extent == (int32_t)opal_datatype_basicDatatypes[type]->size) ) {
215 if( type == last_type ) {
216 last_length += pData->desc.desc[pos_desc].elem.count;
217 last_extent = pData->desc.desc[pos_desc].elem.extent;
218 } else {
219 if( last_length == 0 ) {
220 last_type = type;
221 last_length = pData->desc.desc[pos_desc].elem.count;
222 last_extent = pData->desc.desc[pos_desc].elem.extent;
223 } else {
224 last_length = last_length * opal_datatype_basicDatatypes[last_type]->size +
225 pData->desc.desc[pos_desc].elem.count * opal_datatype_basicDatatypes[type]->size;
226 last_type = OPAL_DATATYPE_UINT1;
227 last_extent = 1;
228 }
229 }
230 last_flags &= pData->desc.desc[pos_desc].elem.common.flags;
231 } else {
232 if( last_length != 0 ) {
233 CREATE_ELEM( pElemDesc, last_type, OPAL_DATATYPE_FLAG_BASIC, last_length, last_disp, last_extent );
234 pElemDesc++; nbElems++;
235 }
236 last_disp = total_disp + pData->desc.desc[pos_desc].elem.disp;
237 last_length = pData->desc.desc[pos_desc].elem.count;
238 last_extent = pData->desc.desc[pos_desc].elem.extent;
239 last_type = type;
240 }
241 pos_desc++;
242 }
243 }
244
245 if( last_length != 0 ) {
246 CREATE_ELEM( pElemDesc, last_type, OPAL_DATATYPE_FLAG_BASIC, last_length, last_disp, last_extent );
247 pElemDesc++; nbElems++;
248 }
249
250 pTypeDesc->used = nbElems - 1;
251 free(pOrigStack);
252 return OPAL_SUCCESS;
253 }
254
255 int32_t opal_datatype_commit( opal_datatype_t * pData )
256 {
257 ddt_endloop_desc_t* pLast = &(pData->desc.desc[pData->desc.used].end_loop);
258 ptrdiff_t first_elem_disp = 0;
259
260 if( pData->flags & OPAL_DATATYPE_FLAG_COMMITTED ) return OPAL_SUCCESS;
261 pData->flags |= OPAL_DATATYPE_FLAG_COMMITTED;
262
263
264
265
266 if( 0 != pData->size ) {
267 int index;
268 dt_elem_desc_t* pElem = pData->desc.desc;
269
270 index = GET_FIRST_NON_LOOP( pElem );
271 assert( pElem[index].elem.common.flags & OPAL_DATATYPE_FLAG_DATA );
272 first_elem_disp = pElem[index].elem.disp;
273 }
274
275
276
277
278 pLast->common.type = OPAL_DATATYPE_END_LOOP;
279 pLast->common.flags = 0;
280 pLast->items = pData->desc.used;
281 pLast->first_elem_disp = first_elem_disp;
282 pLast->size = pData->size;
283
284
285 if( 0 == pData->desc.used ) {
286 pData->opt_desc.length = 0;
287 pData->opt_desc.desc = NULL;
288 pData->opt_desc.used = 0;
289 return OPAL_SUCCESS;
290 }
291
292
293
294
295 (void)opal_datatype_optimize_short( pData, 1, &(pData->opt_desc) );
296 if( 0 != pData->opt_desc.used ) {
297
298
299
300 pLast = &(pData->opt_desc.desc[pData->opt_desc.used].end_loop);
301 pLast->common.type = OPAL_DATATYPE_END_LOOP;
302 pLast->common.flags = 0;
303 pLast->items = pData->opt_desc.used;
304 pLast->first_elem_disp = first_elem_disp;
305 pLast->size = pData->size;
306 }
307 return OPAL_SUCCESS;
308 }