This source file includes following definitions.
- create_segments
- shuffle_segments
- pack_segments
- unpack_segments
- 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
35 typedef struct {
36 size_t position;
37 size_t size;
38 void* buffer;
39 } ddt_segment_t;
40
41 static int
42 create_segments( ompi_datatype_t* datatype, int count,
43 size_t segment_length,
44 ddt_segment_t** segments, int* seg_count )
45 {
46 size_t data_size, total_length, position;
47 opal_convertor_t* convertor;
48 int i;
49 ddt_segment_t* segment;
50
51 ompi_datatype_type_size( datatype, &data_size );
52 data_size *= count;
53 *seg_count = data_size / segment_length;
54 if( ((*seg_count) * segment_length) != data_size )
55 *seg_count += 1;
56 allocate_segments:
57 *segments = (ddt_segment_t*)malloc( (*seg_count) * sizeof(ddt_segment_t) );
58
59 convertor = opal_convertor_create( opal_local_arch, 0 );
60 opal_convertor_prepare_for_send( convertor, &(datatype->super), count, NULL );
61
62 position = 0;
63 total_length = 0;
64 for( i = 0; i < (*seg_count); i++ ) {
65 segment = &((*segments)[i]);
66 segment->buffer = malloc(segment_length);
67 segment->position = position;
68
69
70 position += segment_length;
71 opal_convertor_set_position( convertor, &position );
72 segment->size = position - segment->position;
73 total_length += segment->size;
74 }
75 OBJ_RELEASE(convertor);
76 if( total_length != data_size ) {
77 for( i = 0; i < (*seg_count); i++ ) {
78 segment = &((*segments)[i]);
79 free(segment->buffer);
80 }
81 free( *segments );
82 (*seg_count) += 1;
83 goto allocate_segments;
84 }
85 return 0;
86 }
87
88 static int
89 shuffle_segments( ddt_segment_t* segments, int seg_count )
90 {
91 ddt_segment_t temporary;
92 int i;
93
94 for( i = 0; i < (seg_count/2); i += 2 ) {
95 temporary = segments[i];
96 segments[i] = segments[seg_count - i - 1];
97 segments[seg_count - i - 1] = temporary;
98 }
99 return 0;
100 }
101
102 static int
103 pack_segments( ompi_datatype_t* datatype, int count,
104 size_t segment_size,
105 ddt_segment_t* segments, int seg_count,
106 void* buffer )
107 {
108 size_t max_size, position;
109 opal_convertor_t* convertor;
110 struct iovec iov;
111 int i;
112 uint32_t iov_count;
113
114 convertor = opal_convertor_create( opal_local_arch, 0 );
115 opal_convertor_prepare_for_send( convertor, &(datatype->super), count, buffer );
116
117 for( i = 0; i < seg_count; i++ ) {
118 iov.iov_len = segments[i].size;
119 iov.iov_base = segments[i].buffer;
120 max_size = iov.iov_len;
121 position = segments[i].position;
122 opal_convertor_set_position( convertor, &position );
123 if( position != segments[i].position ) {
124 opal_output( 0, "Setting position failed (%lu != %lu)\n",
125 (unsigned long)segments[i].position, (unsigned long)position );
126 break;
127 }
128
129 iov_count = 1;
130 opal_convertor_pack( convertor, &iov, &iov_count, &max_size );
131 if( max_size != segments[i].size ) {
132 opal_output( 0, "Amount of packed data do not match (%lu != %lu)\n",
133 (unsigned long)max_size, (unsigned long)segments[i].size );
134 opal_output( 0, "Segment %d position %lu size %lu\n", i,
135 (unsigned long)segments[i].position, segments[i].size );
136 }
137 }
138 OBJ_RELEASE(convertor);
139 return i;
140 }
141
142 static int
143 unpack_segments( ompi_datatype_t* datatype, int count,
144 size_t segment_size,
145 ddt_segment_t* segments, int seg_count,
146 void* buffer )
147 {
148 opal_convertor_t* convertor;
149 size_t max_size, position;
150 int i;
151 uint32_t iov_count;
152 struct iovec iov;
153
154 convertor = opal_convertor_create( opal_local_arch, 0 );
155 opal_convertor_prepare_for_recv( convertor, &(datatype->super), count, buffer );
156
157 for( i = 0; i < seg_count; i++ ) {
158 iov.iov_len = segments[i].size;
159 iov.iov_base = segments[i].buffer;
160 max_size = iov.iov_len;
161
162 position = segments[i].position;
163 opal_convertor_set_position( convertor, &position );
164 if( position != segments[i].position ) {
165 opal_output( 0, "Setting position failed (%lu != %lu)\n",
166 (unsigned long)segments[i].position, (unsigned long)position );
167 break;
168 }
169
170 iov_count = 1;
171 opal_convertor_unpack( convertor, &iov, &iov_count, &max_size );
172 if( max_size != segments[i].size ) {
173 opal_output( 0, "Amount of unpacked data do not match (%lu != %lu)\n",
174 (unsigned long)max_size, (unsigned long)segments[i].size );
175 opal_output( 0, "Segment %d position %lu size %lu\n", i,
176 (unsigned long)segments[i].position, segments[i].size );
177 }
178 }
179 OBJ_RELEASE(convertor);
180 return 0;
181 }
182
183 #if (OPAL_ENABLE_DEBUG == 1) && (OPAL_C_HAVE_VISIBILITY == 0)
184 extern bool opal_unpack_debug;
185 extern bool opal_pack_debug;
186 extern bool opal_position_debug ;
187 #endif
188
189 int main( int argc, char* argv[] )
190 {
191 ddt_segment_t* segments;
192 int *send_buffer, *recv_buffer;
193 int i, seg_count, errors;
194 int show_only_first_error = 1;
195 ompi_datatype_t* datatype = MPI_DATATYPE_NULL;
196
197 #define NELT (300)
198 send_buffer = malloc(NELT*sizeof(int));
199 recv_buffer = malloc(NELT*sizeof(int));
200 for (i = 0; i < NELT; ++i) {
201 send_buffer[i] = i;
202 recv_buffer[i] = 0xdeadbeef;
203 }
204
205 opal_init_util (NULL, NULL);
206 ompi_datatype_init();
207
208 ompi_datatype_create_vector(NELT/2, 1, 2, MPI_INT, &datatype);
209 ompi_datatype_commit(&datatype);
210
211 #if (OPAL_ENABLE_DEBUG == 1) && (OPAL_C_HAVE_VISIBILITY == 0)
212 opal_unpack_debug = false;
213 opal_pack_debug = false;
214 opal_position_debug = false;
215 #endif
216
217 create_segments( datatype, 1, fragment_size,
218 &segments, &seg_count );
219
220
221 shuffle_segments( segments, seg_count );
222
223
224 pack_segments( datatype, 1, fragment_size, segments, seg_count,
225 send_buffer );
226
227
228 unpack_segments( datatype, 1, fragment_size, segments, seg_count,
229 recv_buffer );
230
231
232 for( errors = i = 0; i < NELT; i++ ) {
233 int expected = ((i % 2) ? (int)0xdeadbeef : i);
234 if (recv_buffer[i] != expected) {
235 if( (show_only_first_error && (0 == errors)) ||
236 !show_only_first_error ) {
237 printf("error at index %4d: 0x%08x != 0x%08x\n", i, recv_buffer[i], expected);
238 }
239 errors++;
240 }
241 }
242 printf( "Found %d errors\n", errors );
243 free(send_buffer); free(recv_buffer);
244
245 for( i = 0; i < seg_count; i++ ) {
246 free( segments[i].buffer );
247 }
248 free(segments);
249
250 ompi_datatype_finalize();
251 opal_finalize_util ();
252
253 return (0 == errors ? 0 : -1);
254 }