This source file includes following definitions.
- test_upper
- compute_buffer_length
- local_copy_ddt_count
- local_copy_with_convertor_2datatypes
- local_copy_with_convertor
- main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 #include "ompi_config.h"
22 #include "ddt_lib.h"
23 #include "opal/runtime/opal.h"
24 #include "opal/datatype/opal_convertor.h"
25 #include <time.h>
26 #include <stdlib.h>
27 #ifdef HAVE_SYS_TIME_H
28 #include <sys/time.h>
29 #endif
30 #include <stdio.h>
31 #include <string.h>
32
33
34
35
36
37 #define TIMER_DATA_TYPE struct timeval
38 #define GET_TIME(TV) gettimeofday( &(TV), NULL )
39 #define ELAPSED_TIME(TSTART, TEND) (((TEND).tv_sec - (TSTART).tv_sec) * 1000000 + ((TEND).tv_usec - (TSTART).tv_usec))
40
41 #define DUMP_DATA_AFTER_COMMIT 0x00000001
42 #define CHECK_PACK_UNPACK 0x00000002
43
44 uint32_t remote_arch = 0xffffffff;
45
46 static int test_upper( unsigned int length )
47 {
48 double *mat1, *mat2, *inbuf;
49 ompi_datatype_t *pdt;
50 opal_convertor_t * pConv;
51 char *ptr;
52 int rc;
53 unsigned int i, j, iov_count, split_chunk, total_length;
54 size_t max_data;
55 struct iovec a;
56 TIMER_DATA_TYPE start, end;
57 long total_time;
58
59 printf( "test upper matrix\n" );
60 pdt = upper_matrix( length );
61
62
63 mat1 = malloc( length * length * sizeof(double) );
64 init_random_upper_matrix( length, mat1 );
65 mat2 = calloc( length * length, sizeof(double) );
66
67 total_length = length * (length + 1) * ( sizeof(double) / 2);
68 inbuf = (double*)malloc( total_length );
69 ptr = (char*)inbuf;
70
71 for( i = 0; i < length; i++ ) {
72 uint32_t pos = i * length + i;
73 for( j = i; j < length; j++, pos++ ) {
74 *inbuf = mat1[pos];
75 inbuf++;
76 }
77 }
78 inbuf = (double*)ptr;
79 pConv = opal_convertor_create( remote_arch, 0 );
80 if( OPAL_SUCCESS != opal_convertor_prepare_for_recv( pConv, &(pdt->super), 1, mat2 ) ) {
81 printf( "Cannot attach the datatype to a convertor\n" );
82 return OMPI_ERROR;
83 }
84
85 GET_TIME( start );
86 split_chunk = (length + 1) * sizeof(double);
87
88 for( i = total_length; i > 0; ) {
89 if( i <= split_chunk ) {
90 split_chunk = i;
91 }
92 a.iov_base = ptr;
93 a.iov_len = split_chunk;
94 iov_count = 1;
95 max_data = split_chunk;
96 opal_convertor_unpack( pConv, &a, &iov_count, &max_data );
97 ptr += max_data;
98 i -= max_data;
99 if( mat2[0] != inbuf[0] ) assert(0);
100 }
101 GET_TIME( end );
102 total_time = ELAPSED_TIME( start, end );
103 printf( "complete unpacking in %ld microsec\n", total_time );
104 free( inbuf );
105 rc = check_diag_matrix( length, mat1, mat2 );
106 free( mat1 );
107 free( mat2 );
108
109
110 ompi_datatype_destroy( &pdt ); assert( pdt == NULL );
111
112 OBJ_RELEASE( pConv );
113 return rc;
114 }
115
116
117
118
119
120
121 static size_t compute_buffer_length(ompi_datatype_t* pdt, int count)
122 {
123 MPI_Aint extent, lb, true_extent, true_lb;
124 size_t length;
125
126 ompi_datatype_get_extent(pdt, &lb, &extent);
127 ompi_datatype_get_true_extent(pdt, &true_lb, &true_extent); (void)true_lb;
128 length = true_lb + true_extent + (count - 1) * extent;
129
130 return length;
131 }
132
133
134
135
136
137
138
139
140
141
142 static int local_copy_ddt_count( ompi_datatype_t* pdt, int count )
143 {
144 void *pdst, *psrc;
145 TIMER_DATA_TYPE start, end;
146 long total_time;
147 size_t length;
148
149 length = compute_buffer_length(pdt, count);
150
151 pdst = malloc(length);
152 psrc = malloc(length);
153
154 for( size_t i = 0; i < length; i++ )
155 ((char*)psrc)[i] = i % 128 + 32;
156 memset(pdst, 0, length);
157
158 cache_trash();
159
160 GET_TIME( start );
161 if( OMPI_SUCCESS != ompi_datatype_copy_content_same_ddt( pdt, count, pdst, psrc ) ) {
162 printf( "Unable to copy the datatype in the function local_copy_ddt_count."
163 " Is the datatype committed ?\n" );
164 }
165 GET_TIME( end );
166 total_time = ELAPSED_TIME( start, end );
167 printf( "direct local copy in %ld microsec\n", total_time );
168 free(pdst);
169 free(psrc);
170
171 return OMPI_SUCCESS;
172 }
173
174 static int
175 local_copy_with_convertor_2datatypes( ompi_datatype_t* send_type, int send_count,
176 ompi_datatype_t* recv_type, int recv_count,
177 int chunk )
178 {
179 void *pdst = NULL, *psrc = NULL, *ptemp = NULL;
180 opal_convertor_t *send_convertor = NULL, *recv_convertor = NULL;
181 struct iovec iov;
182 uint32_t iov_count;
183 size_t max_data;
184 int32_t length = 0, done1 = 0, done2 = 0;
185 TIMER_DATA_TYPE start, end, unpack_start, unpack_end;
186 long total_time, unpack_time = 0;
187 size_t slength, rlength;
188
189 rlength = compute_buffer_length(recv_type, recv_count);
190 slength = compute_buffer_length(send_type, send_count);
191 pdst = malloc( rlength );
192 psrc = malloc( slength );
193 ptemp = malloc( chunk );
194
195
196 for( size_t i = 0; i < slength; i++ )
197 ((char*)psrc)[i] = i % 128 + 32;
198 memset(pdst, 0, rlength);
199
200 send_convertor = opal_convertor_create( remote_arch, 0 );
201 if( OPAL_SUCCESS != opal_convertor_prepare_for_send( send_convertor, &(send_type->super), send_count, psrc ) ) {
202 printf( "Unable to create the send convertor. Is the datatype committed ?\n" );
203 goto clean_and_return;
204 }
205 recv_convertor = opal_convertor_create( remote_arch, 0 );
206 if( OPAL_SUCCESS != opal_convertor_prepare_for_recv( recv_convertor, &(recv_type->super), recv_count, pdst ) ) {
207 printf( "Unable to create the recv convertor. Is the datatype committed ?\n" );
208 goto clean_and_return;
209 }
210
211 cache_trash();
212
213 GET_TIME( start );
214 while( (done1 & done2) != 1 ) {
215
216 if( done1 | done2 ) {
217 printf( "WRONG !!! the send is %s but the receive is %s in local_copy_with_convertor_2datatypes\n",
218 (done1 ? "finish" : "not finish"),
219 (done2 ? "finish" : "not finish") );
220 }
221
222 max_data = chunk;
223 iov_count = 1;
224 iov.iov_base = ptemp;
225 iov.iov_len = chunk;
226
227 if( done1 == 0 ) {
228 done1 = opal_convertor_pack( send_convertor, &iov, &iov_count, &max_data );
229 }
230
231 if( done2 == 0 ) {
232 GET_TIME( unpack_start );
233 done2 = opal_convertor_unpack( recv_convertor, &iov, &iov_count, &max_data );
234 GET_TIME( unpack_end );
235 unpack_time += ELAPSED_TIME( unpack_start, unpack_end );
236 }
237
238 length += max_data;
239 }
240 GET_TIME( end );
241 total_time = ELAPSED_TIME( start, end );
242 printf( "copying different data-types using convertors in %ld microsec\n", total_time );
243 printf( "\t unpack in %ld microsec [pack in %ld microsec]\n", unpack_time,
244 total_time - unpack_time );
245 clean_and_return:
246 if( send_convertor != NULL ) {
247 OBJ_RELEASE( send_convertor ); assert( send_convertor == NULL );
248 }
249 if( recv_convertor != NULL ) {
250 OBJ_RELEASE( recv_convertor ); assert( recv_convertor == NULL );
251 }
252 if( NULL != pdst ) free( pdst );
253 if( NULL != psrc ) free( psrc );
254 if( NULL != ptemp ) free( ptemp );
255 return OMPI_SUCCESS;
256 }
257
258 static int local_copy_with_convertor( ompi_datatype_t* pdt, int count, int chunk )
259 {
260 void *pdst = NULL, *psrc = NULL, *ptemp = NULL;
261 opal_convertor_t *send_convertor = NULL, *recv_convertor = NULL;
262 struct iovec iov;
263 uint32_t iov_count;
264 size_t max_data;
265 int32_t length = 0, done1 = 0, done2 = 0;
266 TIMER_DATA_TYPE start, end, unpack_start, unpack_end;
267 long total_time, unpack_time = 0;
268
269 max_data = compute_buffer_length(pdt, count);
270
271 pdst = malloc(max_data);
272 psrc = malloc(max_data);
273 ptemp = malloc(chunk);
274
275 for( int i = 0; i < length; ((char*)psrc)[i] = i % 128 + 32, i++ );
276 memset( pdst, 0, length );
277
278 send_convertor = opal_convertor_create( remote_arch, 0 );
279 if( OPAL_SUCCESS != opal_convertor_prepare_for_send( send_convertor, &(pdt->super), count, psrc ) ) {
280 printf( "Unable to create the send convertor. Is the datatype committed ?\n" );
281 goto clean_and_return;
282 }
283
284 recv_convertor = opal_convertor_create( remote_arch, 0 );
285 if( OPAL_SUCCESS != opal_convertor_prepare_for_recv( recv_convertor, &(pdt->super), count, pdst ) ) {
286 printf( "Unable to create the recv convertor. Is the datatype committed ?\n" );
287 goto clean_and_return;
288 }
289
290 cache_trash();
291
292 GET_TIME( start );
293 while( (done1 & done2) != 1 ) {
294
295 if( done1 | done2 ) {
296 printf( "WRONG !!! the send is %s but the receive is %s in local_copy_with_convertor\n",
297 (done1 ? "finish" : "not finish"),
298 (done2 ? "finish" : "not finish") );
299 }
300
301 max_data = chunk;
302 iov_count = 1;
303 iov.iov_base = ptemp;
304 iov.iov_len = chunk;
305
306 if( done1 == 0 ) {
307 done1 = opal_convertor_pack( send_convertor, &iov, &iov_count, &max_data );
308 }
309
310 if( done2 == 0 ) {
311 GET_TIME( unpack_start );
312 done2 = opal_convertor_unpack( recv_convertor, &iov, &iov_count, &max_data );
313 GET_TIME( unpack_end );
314 unpack_time += ELAPSED_TIME( unpack_start, unpack_end );
315 }
316
317 length += max_data;
318 }
319 GET_TIME( end );
320 total_time = ELAPSED_TIME( start, end );
321 printf( "copying same data-type using convertors in %ld microsec\n", total_time );
322 printf( "\t unpack in %ld microsec [pack in %ld microsec]\n", unpack_time,
323 total_time - unpack_time );
324 clean_and_return:
325 if( NULL != send_convertor ) OBJ_RELEASE( send_convertor );
326 if( NULL != recv_convertor ) OBJ_RELEASE( recv_convertor );
327
328 if( NULL != pdst ) free( pdst );
329 if( NULL != psrc ) free( psrc );
330 if( NULL != ptemp ) free( ptemp );
331 return OMPI_SUCCESS;
332 }
333
334
335
336
337
338
339
340
341 int main( int argc, char* argv[] )
342 {
343 ompi_datatype_t *pdt, *pdt1, *pdt2, *pdt3;
344 int rc, length = 500;
345
346 opal_init_util(&argc, &argv);
347 ompi_datatype_init();
348
349
350
351
352 remote_arch = opal_local_arch;
353 printf( "\n\n#\n * TEST INVERSED VECTOR\n #\n\n" );
354 pdt = create_inversed_vector( &ompi_mpi_int.dt, 10 );
355 if( outputFlags & CHECK_PACK_UNPACK ) {
356 local_copy_ddt_count(pdt, 100);
357 local_copy_with_convertor(pdt, 100, 956);
358 }
359 OBJ_RELEASE( pdt ); assert( pdt == NULL );
360 printf( "\n\n#\n * TEST STRANGE DATATYPE\n #\n\n" );
361 pdt = create_strange_dt();
362 if( outputFlags & CHECK_PACK_UNPACK ) {
363 local_copy_ddt_count(pdt, 1);
364 local_copy_with_convertor(pdt, 1, 956);
365 }
366 OBJ_RELEASE( pdt ); assert( pdt == NULL );
367
368 printf( "\n\n#\n * TEST UPPER TRIANGULAR MATRIX (size 100)\n #\n\n" );
369 pdt = upper_matrix(100);
370 if( outputFlags & CHECK_PACK_UNPACK ) {
371 local_copy_ddt_count(pdt, 1);
372 local_copy_with_convertor(pdt, 1, 48);
373 }
374 OBJ_RELEASE( pdt ); assert( pdt == NULL );
375
376 printf( "\n\n#\n * TEST UPPER MATRIX\n #\n\n" );
377 rc = test_upper( length );
378 if( rc == 0 )
379 printf( "decode [PASSED]\n" );
380 else
381 printf( "decode [NOT PASSED]\n" );
382
383 printf( "\n\n#\n * TEST MATRIX BORDERS\n #\n\n" );
384 pdt = test_matrix_borders( length, 100 );
385 if( outputFlags & DUMP_DATA_AFTER_COMMIT ) {
386 ompi_datatype_dump( pdt );
387 }
388 OBJ_RELEASE( pdt ); assert( pdt == NULL );
389
390 printf( "\n\n#\n * TEST CONTIGUOUS\n #\n\n" );
391 pdt = test_contiguous();
392 OBJ_RELEASE( pdt ); assert( pdt == NULL );
393 printf( "\n\n#\n * TEST STRUCT\n #\n\n" );
394 pdt = test_struct();
395 OBJ_RELEASE( pdt ); assert( pdt == NULL );
396
397 ompi_datatype_create_contiguous(0, &ompi_mpi_datatype_null.dt, &pdt1);
398 ompi_datatype_create_contiguous(0, &ompi_mpi_datatype_null.dt, &pdt2);
399 ompi_datatype_create_contiguous(0, &ompi_mpi_datatype_null.dt, &pdt3);
400
401 ompi_datatype_add( pdt3, &ompi_mpi_int.dt, 10, 0, -1 );
402 ompi_datatype_add( pdt3, &ompi_mpi_float.dt, 5, 10 * sizeof(int), -1 );
403
404 ompi_datatype_add( pdt2, &ompi_mpi_float.dt, 1, 0, -1 );
405 ompi_datatype_add( pdt2, pdt3, 3, sizeof(int) * 1, -1 );
406
407 ompi_datatype_add( pdt1, &ompi_mpi_long_long_int.dt, 5, 0, -1 );
408 ompi_datatype_add( pdt1, &ompi_mpi_long_double.dt, 2, sizeof(long long) * 5, -1 );
409
410 printf( ">>--------------------------------------------<<\n" );
411 if( outputFlags & DUMP_DATA_AFTER_COMMIT ) {
412 ompi_datatype_dump( pdt1 );
413 }
414 printf( ">>--------------------------------------------<<\n" );
415 if( outputFlags & DUMP_DATA_AFTER_COMMIT ) {
416 ompi_datatype_dump( pdt2 );
417 }
418 printf( ">>--------------------------------------------<<\n" );
419 if( outputFlags & DUMP_DATA_AFTER_COMMIT ) {
420 ompi_datatype_dump( pdt3 );
421 }
422
423 OBJ_RELEASE( pdt1 ); assert( pdt1 == NULL );
424 OBJ_RELEASE( pdt2 ); assert( pdt2 == NULL );
425 OBJ_RELEASE( pdt3 ); assert( pdt3 == NULL );
426
427 printf( ">>--------------------------------------------<<\n" );
428 printf( " Contiguous data-type (MPI_DOUBLE)\n" );
429 pdt = MPI_DOUBLE;
430 if( outputFlags & CHECK_PACK_UNPACK ) {
431 local_copy_ddt_count(pdt, 4500);
432 local_copy_with_convertor( pdt, 4500, 12 );
433 local_copy_with_convertor_2datatypes( pdt, 4500, pdt, 4500, 12 );
434 }
435 printf( ">>--------------------------------------------<<\n" );
436
437 printf( ">>--------------------------------------------<<\n" );
438 if( outputFlags & CHECK_PACK_UNPACK ) {
439 printf( "Contiguous multiple data-type (4500*1)\n" );
440 pdt = create_contiguous_type( MPI_DOUBLE, 4500 );
441 local_copy_ddt_count(pdt, 1);
442 local_copy_with_convertor( pdt, 1, 12 );
443 local_copy_with_convertor_2datatypes( pdt, 1, pdt, 1, 12 );
444 OBJ_RELEASE( pdt ); assert( pdt == NULL );
445 printf( "Contiguous multiple data-type (450*10)\n" );
446 pdt = create_contiguous_type( MPI_DOUBLE, 450 );
447 local_copy_ddt_count(pdt, 10);
448 local_copy_with_convertor( pdt, 10, 12 );
449 local_copy_with_convertor_2datatypes( pdt, 10, pdt, 10, 12 );
450 OBJ_RELEASE( pdt ); assert( pdt == NULL );
451 printf( "Contiguous multiple data-type (45*100)\n" );
452 pdt = create_contiguous_type( MPI_DOUBLE, 45 );
453 local_copy_ddt_count(pdt, 100);
454 local_copy_with_convertor( pdt, 100, 12 );
455 local_copy_with_convertor_2datatypes( pdt, 100, pdt, 100, 12 );
456 OBJ_RELEASE( pdt ); assert( pdt == NULL );
457 printf( "Contiguous multiple data-type (100*45)\n" );
458 pdt = create_contiguous_type( MPI_DOUBLE, 100 );
459 local_copy_ddt_count(pdt, 45);
460 local_copy_with_convertor( pdt, 45, 12 );
461 local_copy_with_convertor_2datatypes( pdt, 45, pdt, 45, 12 );
462 OBJ_RELEASE( pdt ); assert( pdt == NULL );
463 printf( "Contiguous multiple data-type (10*450)\n" );
464 pdt = create_contiguous_type( MPI_DOUBLE, 10 );
465 local_copy_ddt_count(pdt, 450);
466 local_copy_with_convertor( pdt, 450, 12 );
467 local_copy_with_convertor_2datatypes( pdt, 450, pdt, 450, 12 );
468 OBJ_RELEASE( pdt ); assert( pdt == NULL );
469 printf( "Contiguous multiple data-type (1*4500)\n" );
470 pdt = create_contiguous_type( MPI_DOUBLE, 1 );
471 local_copy_ddt_count(pdt, 4500);
472 local_copy_with_convertor( pdt, 4500, 12 );
473 local_copy_with_convertor_2datatypes( pdt, 4500, pdt, 4500, 12 );
474 OBJ_RELEASE( pdt ); assert( pdt == NULL );
475 }
476 printf( ">>--------------------------------------------<<\n" );
477 printf( ">>--------------------------------------------<<\n" );
478 printf( "Vector data-type (450 times 10 double stride 11)\n" );
479 pdt = create_vector_type( MPI_DOUBLE, 450, 10, 11 );
480 ompi_datatype_dump( pdt );
481 if( outputFlags & CHECK_PACK_UNPACK ) {
482 local_copy_ddt_count(pdt, 1);
483 local_copy_with_convertor( pdt, 1, 12 );
484 local_copy_with_convertor_2datatypes( pdt, 1, pdt, 1, 12 );
485 local_copy_with_convertor( pdt, 1, 82 );
486 local_copy_with_convertor_2datatypes( pdt, 1, pdt, 1, 82 );
487 local_copy_with_convertor( pdt, 1, 6000 );
488 local_copy_with_convertor_2datatypes( pdt, 1, pdt, 1, 6000 );
489 local_copy_with_convertor( pdt, 1, 36000 );
490 local_copy_with_convertor_2datatypes( pdt, 1, pdt, 1, 36000 );
491 }
492 printf( ">>--------------------------------------------<<\n" );
493 OBJ_RELEASE( pdt ); assert( pdt == NULL );
494
495 printf( ">>--------------------------------------------<<\n" );
496 pdt = test_struct_char_double();
497 if( outputFlags & CHECK_PACK_UNPACK ) {
498 local_copy_ddt_count(pdt, 4500);
499 local_copy_with_convertor( pdt, 4500, 12 );
500 local_copy_with_convertor_2datatypes( pdt, 4500, pdt, 4500, 12 );
501 }
502 printf( ">>--------------------------------------------<<\n" );
503 OBJ_RELEASE( pdt ); assert( pdt == NULL );
504
505 printf( ">>--------------------------------------------<<\n" );
506 pdt = test_create_twice_two_doubles();
507 if( outputFlags & CHECK_PACK_UNPACK ) {
508 local_copy_ddt_count(pdt, 4500);
509 local_copy_with_convertor( pdt, 4500, 12 );
510 local_copy_with_convertor_2datatypes( pdt, 4500, pdt, 4500, 12 );
511 }
512 printf( ">>--------------------------------------------<<\n" );
513 OBJ_RELEASE( pdt ); assert( pdt == NULL );
514
515 printf( ">>--------------------------------------------<<\n" );
516 pdt = test_create_blacs_type();
517 if( outputFlags & CHECK_PACK_UNPACK ) {
518 ompi_datatype_dump( pdt );
519 local_copy_ddt_count(pdt, 2);
520 local_copy_ddt_count(pdt, 4500);
521 local_copy_with_convertor( pdt, 4500, 956 );
522 local_copy_with_convertor_2datatypes( pdt, 4500, pdt, 4500, 956 );
523 local_copy_with_convertor( pdt, 4500, 16*1024 );
524 local_copy_with_convertor_2datatypes( pdt, 4500, pdt, 4500, 16*1024 );
525 local_copy_with_convertor( pdt, 4500, 64*1024 );
526 local_copy_with_convertor_2datatypes( pdt, 4500, pdt, 4500, 64*1024 );
527 }
528 printf( ">>--------------------------------------------<<\n" );
529 OBJ_RELEASE( pdt ); assert( pdt == NULL );
530
531 printf( ">>--------------------------------------------<<\n" );
532 pdt1 = test_create_blacs_type1( &ompi_mpi_int.dt );
533 pdt2 = test_create_blacs_type2( &ompi_mpi_int.dt );
534 if( outputFlags & CHECK_PACK_UNPACK ) {
535 local_copy_with_convertor_2datatypes( pdt1, 1, pdt2, 1, 100 );
536 }
537 printf( ">>--------------------------------------------<<\n" );
538 OBJ_RELEASE( pdt1 ); assert( pdt1 == NULL );
539 OBJ_RELEASE( pdt2 ); assert( pdt2 == NULL );
540
541
542 ompi_datatype_finalize();
543
544 return OMPI_SUCCESS;
545 }