1212
1313#include <stdio.h>
1414#include <stdlib.h>
15- #include <mpi.h>
1615
17- void dump_hex (void * what , size_t length )
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>
22+
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 )
1829{
19- int i ;
30+ size_t i ;
2031 for ( i = 0 ; i < length ; i ++ ) {
2132 printf ("%02x" , (unsigned int )(((unsigned char * )what )[i ]));
2233 }
2334}
2435
25- int pack_unpack_datatype ( void * send_data , MPI_Datatype datatype , int count ,
26- void * recv_data )
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 );
49+
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 )
60+ {
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 ;
83+ }
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 ;
98+ }
99+
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 )
103+ {
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 ;
123+ }
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 ;
138+ }
139+
140+ static int pack_unpack_datatype ( void * send_data , ompi_datatype_t * datatype , int count ,
141+ void * recv_data )
27142{
28143 MPI_Aint position = 0 , buffer_size ;
29144 void * buffer ;
@@ -40,7 +155,7 @@ int pack_unpack_datatype( void* send_data, MPI_Datatype datatype, int count,
40155 buffer , buffer_size , & position );
41156 if ( MPI_SUCCESS != error ) goto return_error_code ;
42157
43- printf ("packed " ); dump_hex (buffer , buffer_size ); printf ("\n" );
158+ printf ("packed %ld bytes into a %ld bytes buffer " , position , buffer_size ); dump_hex (buffer , position ); printf ("\n" );
44159
45160 position = 0 ;
46161 error = MPI_Unpack_external ("external32" , buffer , buffer_size , & position ,
@@ -54,7 +169,8 @@ int pack_unpack_datatype( void* send_data, MPI_Datatype datatype, int count,
54169
55170int main (int argc , char * argv [])
56171{
57- MPI_Init (& argc , & argv );
172+ opal_init_util (& argc , & argv );
173+ ompi_datatype_init ();
58174
59175 /* Simple contiguous data */
60176 {
@@ -70,35 +186,43 @@ int main(int argc, char *argv[])
70186 printf ("recv " ); dump_hex (& recv_data , sizeof (int ) * 2 ); printf ("\n" );
71187 printf ("recv data %08x %08x \n" , recv_data [0 ], recv_data [1 ]);
72188 if ( (send_data [0 ] != recv_data [0 ]) || (send_data [1 ] != recv_data [1 ]) ) {
73- printf ("Error duing external32 pack/unack for contiguous types\n" );
189+ printf ("Error during external32 pack/unack for contiguous types\n" );
74190 exit (-1 );
75191 }
76192 }
77193
78194 /* Vector datatype */
79195 printf ("\n\nVector datatype\n\n" );
80196 {
197+ int count = 2 , blocklength = 1 , stride = 2 ;
81198 int send_data [3 ] = {1234 , 0 , 5678 };
82199 int recv_data [3 ] = {-1 , -1 , -1 };
83- MPI_Datatype ddt ;
200+ ompi_datatype_t * ddt ;
201+
202+ ompi_datatype_create_vector ( count , blocklength , stride , & ompi_mpi_int .dt , & ddt );
203+ {
204+ const int * a_i [3 ] = {& count , & blocklength , & stride };
205+ ompi_datatype_t * type = & ompi_mpi_int .dt ;
206+
207+ ompi_datatype_set_args ( ddt , 3 , a_i , 0 , NULL , 1 , & type , MPI_COMBINER_VECTOR );
208+ }
209+ ompi_datatype_commit (& ddt );
84210
85- MPI_Type_vector (2 , 1 , 2 , MPI_INT , & ddt );
86- MPI_Type_commit (& ddt );
87211 printf ("send data %08x %x08x %08x \n" , send_data [0 ], send_data [1 ], send_data [2 ]);
88212 printf ("data " ); dump_hex (& send_data , sizeof (int ) * 3 ); printf ("\n" );
89213
90214 (void )pack_unpack_datatype ( send_data , ddt , 1 , recv_data );
91215
92216 printf ("recv " ); dump_hex (& recv_data , sizeof (int ) * 3 ); printf ("\n" );
93217 printf ("recv data %08x %08x %08x \n" , recv_data [0 ], recv_data [1 ], recv_data [2 ]);
94- MPI_Type_free (& ddt );
218+ ompi_datatype_destroy (& ddt );
95219 if ( (send_data [0 ] != recv_data [0 ]) || (send_data [2 ] != recv_data [2 ]) ) {
96- printf ("Error duing external32 pack/unack for vector types\n" );
220+ printf ("Error during external32 pack/unack for vector types\n" );
97221 exit (-1 );
98222 }
99223 }
100224
101- MPI_Finalize ();
225+ ompi_datatype_finalize ();
102226
103227 return 0 ;
104228}
0 commit comments