1 /*
2 * Copyright (C) by Argonne National Laboratory
3 * See COPYRIGHT in top-level directory
4 */
5
6 #include "mpiimpl.h"
7
8 /* -- Begin Profiling Symbol Block for routine MPI_Unpack */
9 #if defined(HAVE_PRAGMA_WEAK)
10 #pragma weak MPI_Unpack = PMPI_Unpack
11 #elif defined(HAVE_PRAGMA_HP_SEC_DEF)
12 #pragma _HP_SECONDARY_DEF PMPI_Unpack MPI_Unpack
13 #elif defined(HAVE_PRAGMA_CRI_DUP)
14 #pragma _CRI duplicate MPI_Unpack as PMPI_Unpack
15 #elif defined(HAVE_WEAK_ATTRIBUTE)
16 int MPI_Unpack(const void *inbuf, int insize, int *position, void *outbuf, int outcount,
17 MPI_Datatype datatype, MPI_Comm comm) __attribute__ ((weak, alias("PMPI_Unpack")));
18 #endif
19 /* -- End Profiling Symbol Block */
20
21 /* Define MPICH_MPI_FROM_PMPI if weak symbols are not supported to build
22 the MPI routines */
23 #ifndef MPICH_MPI_FROM_PMPI
24 #undef MPI_Unpack
25 #define MPI_Unpack PMPI_Unpack
26 #endif
27
28 /*@
29 MPI_Unpack - Unpack a buffer according to a datatype into contiguous memory
30
31 Input Parameters:
32 + inbuf - input buffer start (choice)
33 . insize - size of input buffer, in bytes (integer)
34 . outcount - number of items to be unpacked (integer)
35 . datatype - datatype of each output data item (handle)
36 - comm - communicator for packed message (handle)
37
38 Output Parameters:
39 . outbuf - output buffer start (choice)
40
41 Inout/Output Parameters:
42 . position - current position in bytes (integer)
43
44
45 .N ThreadSafe
46
47 .N Fortran
48
49 .N Errors
50 .N MPI_SUCCESS
51 .N MPI_ERR_COMM
52 .N MPI_ERR_COUNT
53 .N MPI_ERR_TYPE
54 .N MPI_ERR_ARG
55
56 .seealso: MPI_Pack, MPI_Pack_size
57 @*/
MPI_Unpack(const void * inbuf,int insize,int * position,void * outbuf,int outcount,MPI_Datatype datatype,MPI_Comm comm)58 int MPI_Unpack(const void *inbuf, int insize, int *position,
59 void *outbuf, int outcount, MPI_Datatype datatype, MPI_Comm comm)
60 {
61 int mpi_errno = MPI_SUCCESS;
62 MPI_Aint position_x;
63 MPIR_Comm *comm_ptr = NULL;
64 MPIR_FUNC_TERSE_STATE_DECL(MPID_STATE_MPI_UNPACK);
65
66 MPIR_ERRTEST_INITIALIZED_ORDIE();
67
68 MPIR_FUNC_TERSE_ENTER(MPID_STATE_MPI_UNPACK);
69
70 /* Validate parameters, especially handles needing to be converted */
71 #ifdef HAVE_ERROR_CHECKING
72 {
73 MPID_BEGIN_ERROR_CHECKS;
74 {
75 MPIR_ERRTEST_COMM(comm, mpi_errno);
76 }
77 MPID_END_ERROR_CHECKS;
78 }
79 #endif
80
81 /* Convert MPI object handles to object pointers */
82 MPIR_Comm_get_ptr(comm, comm_ptr);
83
84 /* Validate parameters and objects (post conversion) */
85 #ifdef HAVE_ERROR_CHECKING
86 {
87 MPID_BEGIN_ERROR_CHECKS;
88 {
89 if (insize > 0) {
90 MPIR_ERRTEST_ARGNULL(inbuf, "input buffer", mpi_errno);
91 }
92 /* Note: outbuf could be MPI_BOTTOM; don't test for NULL */
93 MPIR_ERRTEST_COUNT(insize, mpi_errno);
94 MPIR_ERRTEST_COUNT(outcount, mpi_errno);
95
96 /* Validate comm_ptr */
97 MPIR_Comm_valid_ptr(comm_ptr, mpi_errno, FALSE);
98 if (mpi_errno != MPI_SUCCESS)
99 goto fn_fail;
100 /* If comm_ptr is not valid, it will be reset to null */
101
102 MPIR_ERRTEST_DATATYPE(datatype, "datatype", mpi_errno);
103
104 if (datatype != MPI_DATATYPE_NULL && !HANDLE_IS_BUILTIN(datatype)) {
105 MPIR_Datatype *datatype_ptr = NULL;
106
107 MPIR_Datatype_get_ptr(datatype, datatype_ptr);
108 MPIR_Datatype_valid_ptr(datatype_ptr, mpi_errno);
109 MPIR_Datatype_committed_ptr(datatype_ptr, mpi_errno);
110 }
111 if (mpi_errno != MPI_SUCCESS)
112 goto fn_fail;
113 }
114 MPID_END_ERROR_CHECKS;
115 }
116 #endif /* HAVE_ERROR_CHECKING */
117
118 /* ... body of routine ... */
119
120 position_x = *position;
121
122 MPI_Aint actual_unpack_bytes;
123 void *buf = (void *) ((char *) inbuf + position_x);
124 mpi_errno =
125 MPIR_Typerep_unpack(buf, insize, outbuf, outcount, datatype, 0, &actual_unpack_bytes);
126 if (mpi_errno)
127 goto fn_fail;
128
129 position_x += actual_unpack_bytes;
130 MPIR_Assign_trunc(*position, position_x, int);
131
132 /* ... end of body of routine ... */
133
134 fn_exit:
135 MPIR_FUNC_TERSE_EXIT(MPID_STATE_MPI_UNPACK);
136 return mpi_errno;
137
138
139 fn_fail:
140 /* --BEGIN ERROR HANDLING-- */
141 #ifdef HAVE_ERROR_CHECKING
142 {
143 mpi_errno =
144 MPIR_Err_create_code(mpi_errno, MPIR_ERR_RECOVERABLE, __func__, __LINE__, MPI_ERR_OTHER,
145 "**mpi_unpack", "**mpi_unpack %p %d %p %p %d %D %C", inbuf, insize,
146 position, outbuf, outcount, datatype, comm);
147 }
148 #endif
149 mpi_errno = MPIR_Err_return_comm(comm_ptr, __func__, mpi_errno);
150 goto fn_exit;
151 /* --END ERROR HANDLING-- */
152 }
153