This source file includes following definitions.
- create_segments
- shuffle_segments
- pack_segments
- unpack_segments
- dump_ldi
- bytes_dump
- main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 #include "ompi_config.h"
18 #include <stdio.h>
19 #include <string.h>
20
21 #include "opal/datatype/opal_convertor.h"
22 #include "ompi/datatype/ompi_datatype.h"
23 #include "opal/util/output.h"
24 #include "opal/runtime/opal.h"
25
26
27
28
29
30
31
32
33 static int fragment_size = 113;
34 static int data_count = 2048;
35
36 typedef struct {
37 size_t position;
38 size_t size;
39 void* buffer;
40 } ddt_segment_t;
41
42 static int
43 create_segments( ompi_datatype_t* datatype, int count,
44 size_t segment_length,
45 ddt_segment_t** segments, int* seg_count )
46 {
47 size_t data_size, total_length, position;
48 opal_convertor_t* convertor;
49 int i;
50 ddt_segment_t* segment;
51
52 ompi_datatype_type_size( datatype, &data_size );
53 data_size *= count;
54 *seg_count = data_size / segment_length;
55 if( ((*seg_count) * segment_length) != data_size )
56 *seg_count += 1;
57 allocate_segments:
58 *segments = (ddt_segment_t*)malloc( (*seg_count) * sizeof(ddt_segment_t) );
59
60 convertor = opal_convertor_create( opal_local_arch, 0 );
61 opal_convertor_prepare_for_send( convertor, &(datatype->super), count, NULL );
62
63 position = 0;
64 total_length = 0;
65 for( i = 0; i < (*seg_count); i++ ) {
66 segment = &((*segments)[i]);
67 segment->buffer = malloc(segment_length);
68 segment->position = position;
69
70
71 position += segment_length;
72 opal_convertor_set_position( convertor, &position );
73 segment->size = position - segment->position;
74 total_length += segment->size;
75 }
76 OBJ_RELEASE(convertor);
77 if( total_length != data_size ) {
78 for( i = 0; i < (*seg_count); i++ ) {
79 segment = &((*segments)[i]);
80 free(segment->buffer);
81 }
82 free( *segments );
83 (*seg_count) += 1;
84 goto allocate_segments;
85 }
86 return 0;
87 }
88
89 static int
90 shuffle_segments( ddt_segment_t* segments, int seg_count )
91 {
92 ddt_segment_t temporary;
93 int i;
94
95 for( i = 0; i < (seg_count/2); i += 2 ) {
96 temporary = segments[i];
97 segments[i] = segments[seg_count - i - 1];
98 segments[seg_count - i - 1] = temporary;
99 }
100 return 0;
101 }
102
103 static int
104 pack_segments( ompi_datatype_t* datatype, int count,
105 size_t segment_size,
106 ddt_segment_t* segments, int seg_count,
107 void* buffer )
108 {
109 size_t max_size, position;
110 opal_convertor_t* convertor;
111 struct iovec iov;
112 int i;
113 uint32_t iov_count;
114
115 convertor = opal_convertor_create( opal_local_arch, 0 );
116 opal_convertor_prepare_for_send( convertor, &(datatype->super), count, buffer );
117
118 for( i = 0; i < seg_count; i++ ) {
119 iov.iov_len = segments[i].size;
120 iov.iov_base = segments[i].buffer;
121 max_size = iov.iov_len;
122 position = segments[i].position;
123 opal_convertor_set_position( convertor, &position );
124 if( position != segments[i].position ) {
125 opal_output( 0, "Setting position failed (%lu != %lu)\n",
126 (unsigned long)segments[i].position, (unsigned long)position );
127 break;
128 }
129
130 iov_count = 1;
131 opal_convertor_pack( convertor, &iov, &iov_count, &max_size );
132 if( max_size != segments[i].size ) {
133 opal_output( 0, "Amount of packed data do not match (%lu != %lu)\n",
134 (unsigned long)max_size, (unsigned long)segments[i].size );
135 opal_output( 0, "Segment %d position %lu size %lu\n", i,
136 (unsigned long)segments[i].position, segments[i].size );
137 }
138 }
139 OBJ_RELEASE(convertor);
140 return i;
141 }
142
143 static int
144 unpack_segments( ompi_datatype_t* datatype, int count,
145 size_t segment_size,
146 ddt_segment_t* segments, int seg_count,
147 void* buffer )
148 {
149 opal_convertor_t* convertor;
150 size_t max_size, position;
151 int i;
152 uint32_t iov_count;
153 struct iovec iov;
154
155 convertor = opal_convertor_create( opal_local_arch, 0 );
156 opal_convertor_prepare_for_recv( convertor, &(datatype->super), count, buffer );
157
158 for( i = 0; i < seg_count; i++ ) {
159 iov.iov_len = segments[i].size;
160 iov.iov_base = segments[i].buffer;
161 max_size = iov.iov_len;
162
163 position = segments[i].position;
164 opal_convertor_set_position( convertor, &position );
165 if( position != segments[i].position ) {
166 opal_output( 0, "Setting position failed (%lu != %lu)\n",
167 (unsigned long)segments[i].position, (unsigned long)position );
168 break;
169 }
170
171 iov_count = 1;
172 opal_convertor_unpack( convertor, &iov, &iov_count, &max_size );
173 if( max_size != segments[i].size ) {
174 opal_output( 0, "Amount of unpacked data do not match (%lu != %lu)\n",
175 (unsigned long)max_size, (unsigned long)segments[i].size );
176 opal_output( 0, "Segment %d position %lu size %lu\n", i,
177 (unsigned long)segments[i].position, segments[i].size );
178 }
179 }
180 OBJ_RELEASE(convertor);
181 return 0;
182 }
183
184 typedef struct {
185 long double ld;
186 int i;
187 } ddt_ldi_t;
188
189 #if 0
190
191 static void dump_ldi( ddt_ldi_t* buffer, int start_pos, int end_pos )
192 {
193 int i;
194
195 for( i = start_pos; i < end_pos; i++ ) {
196 printf( "buffer[%d] = (%Lf, %d)\n", i, buffer[i].ld, buffer[i].i );
197
198 }
199 }
200 #endif
201
202 #if (OPAL_ENABLE_DEBUG == 1) && (OPAL_C_HAVE_VISIBILITY == 0)
203 extern bool opal_unpack_debug;
204 extern bool opal_pack_debug;
205 extern bool opal_position_debug ;
206 #endif
207
208 static char* bytes_dump( void* src, size_t cnt )
209 {
210 static char text[1024];
211 int index, i;
212
213 index = sprintf( text, "0x" );
214 for( i = 0; i < (int)cnt; i++ )
215 index += sprintf( text + index, "%x", (int)(((char*)src)[i]) );
216 *(text + index) = '\0';
217 return text;
218 }
219
220 int main( int argc, char* argv[] )
221 {
222 ddt_segment_t* segments;
223 ddt_ldi_t *send_buffer, *recv_buffer;
224 int i, seg_count, errors;
225 int show_only_first_error = 1;
226 ompi_datatype_t* datatype = MPI_LONG_DOUBLE_INT;
227
228 send_buffer = malloc( sizeof(ddt_ldi_t) * data_count );
229 recv_buffer = malloc( sizeof(ddt_ldi_t) * data_count );
230
231 for( i = 0; i < data_count; i++ ) {
232 send_buffer[i].ld = (long double)i + (long double)i / 100000.0;
233 send_buffer[i].i = i;
234 }
235 memcpy(recv_buffer, send_buffer, sizeof(ddt_ldi_t) * data_count );
236
237 opal_init_util (NULL, NULL);
238 ompi_datatype_init();
239
240 #if (OPAL_ENABLE_DEBUG == 1) && (OPAL_C_HAVE_VISIBILITY == 0)
241 opal_unpack_debug = false;
242 opal_pack_debug = false;
243 opal_position_debug = false;
244 #endif
245
246 create_segments( datatype, data_count, fragment_size,
247 &segments, &seg_count );
248
249
250 shuffle_segments( segments, seg_count );
251
252
253 pack_segments( datatype, data_count, fragment_size, segments, seg_count,
254 send_buffer );
255
256
257 unpack_segments( datatype, data_count, fragment_size, segments, seg_count,
258 recv_buffer );
259
260
261 for( errors = i = 0; i < data_count; i++ ) {
262
263 if( (send_buffer[i].ld != recv_buffer[i].ld) ||
264 (send_buffer[i].i != recv_buffer[i].i) ) {
265 if( (show_only_first_error && (0 == errors)) ||
266 !show_only_first_error ) {
267 printf( "error at %4d [*(%s,%d)\n"
268 " != (%s,%d)\n", i,
269 bytes_dump( &send_buffer[i].ld, sizeof(long double)), send_buffer[i].i,
270 bytes_dump( &recv_buffer[i].ld, sizeof(long double)), recv_buffer[i].i );
271 }
272 errors++;
273 }
274 }
275 printf( "Found %d errors\n", errors );
276 free(send_buffer); free(recv_buffer);
277
278 for( i = 0; i < seg_count; i++ ) {
279 free( segments[i].buffer );
280 }
281 free(segments);
282
283 ompi_datatype_finalize();
284 opal_finalize_util ();
285
286 return (0 == errors ? 0 : -1);
287 }