1212
1313#include <stdio.h>
1414#include <stdlib.h>
15- #include <mpi.h>
16- #include <arpa/inet.h>
1715
18- static int verbose = 0 ;
16+ #include "ompi_config.h"
17+ #include "ompi/datatype/ompi_datatype.h"
18+ #include "opal/runtime/opal.h"
19+ #include "opal/datatype/opal_convertor.h"
20+ #include "opal/datatype/opal_datatype_internal.h"
21+ // #include <mpi.h>
1922
20- void dump_hex (void * what , size_t length )
23+ static int pack_unpack_datatype ( void * send_data , ompi_datatype_t * datatype , int count ,
24+ void * recv_data );
25+
26+ static void dump_hex (void * what , size_t length );
27+
28+ static void dump_hex (void * what , size_t length )
2129{
22- int i ;
30+ size_t i ;
2331 for ( i = 0 ; i < length ; i ++ ) {
2432 printf ("%02x" , (unsigned int )(((unsigned char * )what )[i ]));
2533 }
2634}
2735
28- typedef int (* checker_t )(void * , void * , MPI_Datatype , int , void * );
36+ int MPI_Pack_external_size (const char datarep [], int incount ,
37+ ompi_datatype_t * datatype , MPI_Aint * size )
38+ {
39+ opal_convertor_t local_convertor ;
40+ size_t length ;
41+
42+ OBJ_CONSTRUCT (& local_convertor , opal_convertor_t );
43+
44+ /* the resulting convertor will be set to the position ZERO */
45+ opal_convertor_copy_and_prepare_for_recv ( ompi_mpi_external32_convertor ,
46+ & (datatype -> super ), incount , NULL ,
47+ CONVERTOR_SEND_CONVERSION ,
48+ & local_convertor );
2949
30- int check_contiguous ( void * send_buffer , void * packed ,
31- MPI_Datatype datatype , int count , void * arg )
50+ opal_convertor_get_unpacked_size ( & local_convertor , & length );
51+ * size = (MPI_Aint )length ;
52+ OBJ_DESTRUCT ( & local_convertor );
53+
54+ return OMPI_SUCCESS ;
55+ }
56+
57+ int MPI_Pack_external (const char datarep [], const void * inbuf , int incount ,
58+ ompi_datatype_t * datatype , void * outbuf ,
59+ MPI_Aint outsize , MPI_Aint * position )
3260{
33- int i , resultlen ;
34- char typename [MPI_MAX_OBJECT_NAME ];
35-
36- MPI_Type_get_name (datatype , typename , & resultlen );
37-
38- if ( (datatype == MPI_INT ) || (datatype == MPI_INT32_T ) ) {
39- uint32_t val ;
40- for ( i = 0 ; i < count ; i ++ ) {
41- val = htonl (((uint32_t * )send_buffer )[i ]);
42- if ( val != ((uint32_t * )packed )[i ] ) {
43- printf ("Error at position %d expected %x found %x (type %s)\n" ,
44- i , ((uint32_t * )packed )[i ], ((uint32_t * )send_buffer )[i ], typename );
45- return -1 ;
46- }
47- }
48- } else if ( (datatype == MPI_SHORT ) || (datatype == MPI_INT16_T ) ) {
49- uint16_t val ;
50- for ( i = 0 ; i < count ; i ++ ) {
51- val = htons (((uint16_t * )send_buffer )[i ]);
52- if ( val != ((uint16_t * )packed )[i ] ) {
53- printf ("Error at position %d expected %x found %x (type %s)\n" ,
54- i , ((uint16_t * )packed )[i ], ((uint16_t * )send_buffer )[i ], typename );
55- return -1 ;
56- }
57- }
58- } else {
59- printf ("Unknown type\n" );
60- return -1 ;
61+ int rc = MPI_SUCCESS ;
62+ opal_convertor_t local_convertor ;
63+ struct iovec invec ;
64+ unsigned int iov_count ;
65+ size_t size ;
66+
67+ OBJ_CONSTRUCT (& local_convertor , opal_convertor_t );
68+
69+ /* The resulting convertor will be set to the position zero. We have to use
70+ * CONVERTOR_SEND_CONVERSION in order to force the convertor to do anything
71+ * more than just packing the data.
72+ */
73+ opal_convertor_copy_and_prepare_for_send ( ompi_mpi_external32_convertor ,
74+ & (datatype -> super ), incount , (void * ) inbuf ,
75+ CONVERTOR_SEND_CONVERSION ,
76+ & local_convertor );
77+
78+ /* Check for truncation */
79+ opal_convertor_get_packed_size ( & local_convertor , & size );
80+ if ( (* position + size ) > (size_t )outsize ) { /* we can cast as we already checked for < 0 */
81+ OBJ_DESTRUCT ( & local_convertor );
82+ return MPI_ERR_TRUNCATE ;
6183 }
62- return 0 ;
84+
85+ /* Prepare the iovec with all informations */
86+ invec .iov_base = (char * ) outbuf + (* position );
87+ invec .iov_len = size ;
88+
89+ /* Do the actual packing */
90+ iov_count = 1 ;
91+ rc = opal_convertor_pack ( & local_convertor , & invec , & iov_count , & size );
92+ * position += size ;
93+ OBJ_DESTRUCT ( & local_convertor );
94+
95+ /* All done. Note that the convertor returns 1 upon success, not
96+ OMPI_SUCCESS. */
97+ return (rc == 1 ) ? OMPI_SUCCESS : OMPI_ERROR ;
6398}
6499
65- int check_vector ( void * send_buffer , void * packed ,
66- MPI_Datatype datatype , int count , void * arg )
100+ int MPI_Unpack_external (const char datarep [], const void * inbuf , MPI_Aint insize ,
101+ MPI_Aint * position , void * outbuf , int outcount ,
102+ ompi_datatype_t * datatype )
67103{
68- int i , resultlen ;
69- char typename [MPI_MAX_OBJECT_NAME ];
70- MPI_Datatype origtype = (MPI_Datatype )arg ;
71-
72- MPI_Type_get_name (datatype , typename , & resultlen );
73-
74- if ( (origtype == MPI_INT ) || (origtype == MPI_INT32_T ) ) {
75- uint32_t val ;
76- for ( i = 0 ; i < count ; i ++ ) {
77- val = htonl (((uint32_t * )send_buffer )[2 * i ]);
78- if ( val != ((uint32_t * )packed )[i ] ) {
79- printf ("Error at position %d expected %x found %x (type %s)\n" ,
80- i , ((uint32_t * )packed )[i ], ((uint32_t * )send_buffer )[2 * i ], typename );
81- return -1 ;
82- }
83- }
84- } else if ( (origtype == MPI_SHORT ) || (origtype == MPI_INT16_T ) ) {
85- uint16_t val ;
86- for ( i = 0 ; i < count ; i ++ ) {
87- val = htons (((uint16_t * )send_buffer )[2 * i ]);
88- if ( val != ((uint16_t * )packed )[i ] ) {
89- printf ("Error at position %d expected %x found %x (type %s)\n" ,
90- i , ((uint16_t * )packed )[i ], ((uint16_t * )send_buffer )[2 * i ], typename );
91- return -1 ;
92- }
93- }
94- } else {
95- printf ("Unknown %s type\n" , typename );
96- return -1 ;
104+ int rc = MPI_SUCCESS ;
105+ opal_convertor_t local_convertor ;
106+ struct iovec outvec ;
107+ unsigned int iov_count ;
108+ size_t size ;
109+
110+ OBJ_CONSTRUCT (& local_convertor , opal_convertor_t );
111+
112+ /* the resulting convertor will be set to the position ZERO */
113+ opal_convertor_copy_and_prepare_for_recv ( ompi_mpi_external32_convertor ,
114+ & (datatype -> super ), outcount , outbuf ,
115+ 0 ,
116+ & local_convertor );
117+
118+ /* Check for truncation */
119+ opal_convertor_get_packed_size ( & local_convertor , & size );
120+ if ( (* position + size ) > (unsigned int )insize ) {
121+ OBJ_DESTRUCT ( & local_convertor );
122+ return MPI_ERR_TRUNCATE ;
97123 }
98- return 0 ;
124+
125+ /* Prepare the iovec with all informations */
126+ outvec .iov_base = (char * ) inbuf + (* position );
127+ outvec .iov_len = size ;
128+
129+ /* Do the actual unpacking */
130+ iov_count = 1 ;
131+ rc = opal_convertor_unpack ( & local_convertor , & outvec , & iov_count , & size );
132+ * position += size ;
133+ OBJ_DESTRUCT ( & local_convertor );
134+
135+ /* All done. Note that the convertor returns 1 upon success, not
136+ OMPI_SUCCESS. */
137+ return (rc == 1 ) ? OMPI_SUCCESS : OMPI_ERROR ;
99138}
100139
101- int pack_unpack_datatype ( void * send_data , MPI_Datatype datatype , int count ,
102- void * recv_data ,
103- checker_t validator , void * validator_arg )
140+ static int pack_unpack_datatype ( void * send_data , ompi_datatype_t * datatype , int count ,
141+ void * recv_data )
104142{
105143 MPI_Aint position = 0 , buffer_size ;
106144 void * buffer ;
@@ -121,7 +159,7 @@ int pack_unpack_datatype( void* send_data, MPI_Datatype datatype, int count,
121159 return -1 ;
122160 }
123161
124- printf ("packed " ); dump_hex (buffer , buffer_size ); printf ("\n" );
162+ printf ("packed %ld bytes into a %ld bytes buffer " , position , buffer_size ); dump_hex (buffer , position ); printf ("\n" );
125163
126164 position = 0 ;
127165 error = MPI_Unpack_external ("external32" , buffer , buffer_size , & position ,
@@ -135,7 +173,8 @@ int pack_unpack_datatype( void* send_data, MPI_Datatype datatype, int count,
135173
136174int main (int argc , char * argv [])
137175{
138- MPI_Init (& argc , & argv );
176+ opal_init_util (& argc , & argv );
177+ ompi_datatype_init ();
139178
140179 /* Simple contiguous data: MPI_INT32_T */
141180 {
@@ -173,59 +212,43 @@ int main(int argc, char *argv[])
173212 printf ("recv data %08x %08x \n" , recv_data [0 ], recv_data [1 ]);
174213 }
175214 if ( (send_data [0 ] != recv_data [0 ]) || (send_data [1 ] != recv_data [1 ]) ) {
176- printf ("Error during external32 pack/unack for contiguous types (MPI_INT16_T) \n" );
215+ printf ("Error during external32 pack/unack for contiguous types\n" );
177216 exit (-1 );
178217 }
179218 }
180219
181220 /* Vector datatype */
182221 printf ("\n\nVector datatype\n\n" );
183222 {
184- int32_t send_data [3 ] = {1234 , 0 , 5678 };
185- int32_t recv_data [3 ] = {-1 , -1 , -1 };
186- MPI_Datatype ddt ;
223+ int count = 2 , blocklength = 1 , stride = 2 ;
224+ int send_data [3 ] = {1234 , 0 , 5678 };
225+ int recv_data [3 ] = {-1 , -1 , -1 };
226+ ompi_datatype_t * ddt ;
187227
188- MPI_Type_vector (2 , 1 , 2 , MPI_INT32_T , & ddt );
189- MPI_Type_commit (& ddt );
190- if ( verbose ) {
191- printf ("send data %08x %x08x %08x \n" , send_data [0 ], send_data [1 ], send_data [2 ]);
192- printf ("data " ); dump_hex (& send_data , sizeof (int32_t ) * 3 ); printf ("\n" );
193- }
194- (void )pack_unpack_datatype ( send_data , ddt , 1 , recv_data , check_vector , (void * )(ptrdiff_t )MPI_INT32_T );
195- if ( verbose ) {
196- printf ("recv " ); dump_hex (& recv_data , sizeof (int32_t ) * 3 ); printf ("\n" );
197- printf ("recv data %08x %08x %08x \n" , recv_data [0 ], recv_data [1 ], recv_data [2 ]);
198- }
199- MPI_Type_free (& ddt );
200- if ( (send_data [0 ] != recv_data [0 ]) || (send_data [2 ] != recv_data [2 ]) ) {
201- printf ("Error duing external32 pack/unack for vector types (MPI_INT32_T)\n" );
202- exit (-1 );
203- }
204- }
205- {
206- int16_t send_data [3 ] = {1234 , 0 , 5678 };
207- int16_t recv_data [3 ] = {-1 , -1 , -1 };
208- MPI_Datatype ddt ;
228+ ompi_datatype_create_vector ( count , blocklength , stride , & ompi_mpi_int .dt , & ddt );
229+ {
230+ const int * a_i [3 ] = {& count , & blocklength , & stride };
231+ ompi_datatype_t * type = & ompi_mpi_int .dt ;
209232
210- MPI_Type_vector (2 , 1 , 2 , MPI_INT16_T , & ddt );
211- MPI_Type_commit (& ddt );
212- if ( verbose ) {
213- printf ("send data %08x %x08x %08x \n" , send_data [0 ], send_data [1 ], send_data [2 ]);
214- printf ("data " ); dump_hex (& send_data , sizeof (int16_t ) * 3 ); printf ("\n" );
233+ ompi_datatype_set_args ( ddt , 3 , a_i , 0 , NULL , 1 , & type , MPI_COMBINER_VECTOR );
215234 }
216- (void )pack_unpack_datatype ( send_data , ddt , 1 , recv_data , check_vector , (void * )(ptrdiff_t )MPI_INT16_T );
217- if ( verbose ) {
218- printf ("recv " ); dump_hex (& recv_data , sizeof (int16_t ) * 3 ); printf ("\n" );
219- printf ("recv data %08x %08x %08x \n" , recv_data [0 ], recv_data [1 ], recv_data [2 ]);
220- }
221- MPI_Type_free (& ddt );
235+ ompi_datatype_commit (& ddt );
236+
237+ printf ("send data %08x %x08x %08x \n" , send_data [0 ], send_data [1 ], send_data [2 ]);
238+ printf ("data " ); dump_hex (& send_data , sizeof (int ) * 3 ); printf ("\n" );
239+
240+ (void )pack_unpack_datatype ( send_data , ddt , 1 , recv_data );
241+
242+ printf ("recv " ); dump_hex (& recv_data , sizeof (int ) * 3 ); printf ("\n" );
243+ printf ("recv data %08x %08x %08x \n" , recv_data [0 ], recv_data [1 ], recv_data [2 ]);
244+ ompi_datatype_destroy (& ddt );
222245 if ( (send_data [0 ] != recv_data [0 ]) || (send_data [2 ] != recv_data [2 ]) ) {
223- printf ("Error duing external32 pack/unack for vector types (MPI_INT16_T) \n" );
246+ printf ("Error during external32 pack/unack for vector types\n" );
224247 exit (-1 );
225248 }
226249 }
227250
228- MPI_Finalize ();
251+ ompi_datatype_finalize ();
229252
230253 return 0 ;
231254}
0 commit comments