1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
2 /*  (C) 2012 by Argonne National Laboratory.
3  *      See COPYRIGHT in top-level directory.
4  */
5 
6 #include "mpioimpl.h"
7 #include "mpiu_external32.h"
8 
9 #ifdef HAVE_WEAK_SYMBOLS
10 /* Include mapping from MPI->PMPI */
11 #define MPIO_BUILD_PROFILING
12 #include "mpioprof.h"
13 #endif
14 
MPIU_write_external32_conversion_fn(const void * userbuf,MPI_Datatype datatype,int count,void * filebuf)15 int MPIU_write_external32_conversion_fn (const void *userbuf, MPI_Datatype datatype,
16         int count, void *filebuf)
17 {
18     int position_i = 0;
19     MPI_Aint position = 0;
20     MPI_Aint bytes = 0;
21     int mpi_errno = MPI_SUCCESS;
22     int is_contig = 0;
23 
24     ADIOI_Datatype_iscontig(datatype, &is_contig);
25     mpi_errno = MPI_Pack_external_size("external32", count, datatype, &bytes);
26     if (mpi_errno != MPI_SUCCESS)
27         goto fn_exit;
28 
29     if (is_contig)
30     {
31 #ifdef HAVE_MPIIO_CONST
32         mpi_errno = MPI_Pack_external("external32", userbuf, count,
33                 datatype, filebuf, bytes, &position);
34 #else
35         mpi_errno = MPI_Pack_external("external32", (void *)userbuf, count,
36                 datatype, filebuf, bytes, &position);
37 #endif
38         if (mpi_errno != MPI_SUCCESS)
39             goto fn_exit;
40     }
41     else
42     {
43         void *tmp_buf = NULL;
44         tmp_buf = ADIOI_Malloc(bytes);
45         if (!tmp_buf)
46         {
47             mpi_errno = MPI_ERR_NO_MEM;
48             goto fn_exit;
49         }
50 
51 #ifdef HAVE_MPIIO_CONST
52         mpi_errno = MPI_Pack_external("external32", userbuf, count,
53                 datatype, tmp_buf, bytes, &position);
54 #else
55         mpi_errno = MPI_Pack_external("external32", (void *)userbuf, count,
56                 datatype, tmp_buf, bytes, &position);
57 #endif
58         if (mpi_errno != MPI_SUCCESS)
59         {
60             ADIOI_Free(tmp_buf);
61             goto fn_exit;
62         }
63 
64         mpi_errno = MPI_Unpack(tmp_buf, bytes, &position_i, filebuf, count,
65                 datatype, MPI_COMM_WORLD);
66         if (mpi_errno != MPI_SUCCESS)
67         {
68             ADIOI_Free(tmp_buf);
69             goto fn_exit;
70         }
71 
72         ADIOI_Free(tmp_buf);
73     }
74 fn_exit:
75     return mpi_errno;
76 }
77 
MPIU_read_external32_conversion_fn(void * userbuf,MPI_Datatype datatype,int count,void * filebuf)78 int MPIU_read_external32_conversion_fn(void *userbuf, MPI_Datatype datatype,
79         int count, void *filebuf)
80 {
81     int position_i = 0;
82     MPI_Aint position = 0;
83     MPI_Aint bytes = 0;
84     int mpi_errno = MPI_SUCCESS;
85     int is_contig = 0;
86 
87     ADIOI_Datatype_iscontig(datatype, &is_contig);
88     mpi_errno = MPI_Pack_external_size("external32", count, datatype, &bytes);
89     if (mpi_errno != MPI_SUCCESS)
90         goto fn_exit;
91 
92     if (is_contig)
93     {
94         mpi_errno = MPI_Unpack_external("external32", filebuf, bytes,
95                 &position, userbuf, count,  datatype);
96         if (mpi_errno != MPI_SUCCESS)
97             goto fn_exit;
98     }
99     else
100     {
101         void *tmp_buf = NULL;
102         tmp_buf = ADIOI_Malloc(bytes);
103         if (!tmp_buf)
104         {
105             mpi_errno = MPI_ERR_NO_MEM;
106             goto fn_exit;
107         }
108 
109         mpi_errno = MPI_Pack(filebuf, count, datatype, tmp_buf, bytes,
110                 &position_i, MPI_COMM_WORLD);
111         if (mpi_errno != MPI_SUCCESS)
112         {
113             ADIOI_Free(tmp_buf);
114             goto fn_exit;
115         }
116 
117         mpi_errno = MPI_Unpack_external("external32", tmp_buf, bytes,
118                 &position, userbuf, count, datatype);
119         if (mpi_errno != MPI_SUCCESS)
120         {
121             ADIOI_Free(tmp_buf);
122             goto fn_exit;
123         }
124 
125         ADIOI_Free(tmp_buf);
126     }
127 fn_exit:
128     return mpi_errno;
129 }
MPIU_datatype_full_size(MPI_Datatype datatype,MPI_Aint * size)130 int MPIU_datatype_full_size(MPI_Datatype datatype, MPI_Aint *size)
131 {
132     int error_code = MPI_SUCCESS;
133     MPI_Aint true_extent = 0;
134     MPI_Aint true_lb = 0;
135 
136     error_code = MPI_Type_get_true_extent(datatype, &true_lb, &true_extent);
137     if (error_code != MPI_SUCCESS)
138         goto fn_exit;
139 
140     *size = true_extent;
141 fn_exit:
142     return error_code;
143 }
144 
145 /* given a buffer, count, and datatype, return an apropriately allocated, sized
146  * and external32-formatted buffer, suitable for handing off to a subsequent
147  * write routine.  Caller is responsible for freeing 'newbuf' */
MPIU_external32_buffer_setup(const void * buf,int count,MPI_Datatype type,void ** newbuf)148 int MPIU_external32_buffer_setup(const void * buf, int count, MPI_Datatype type, void **newbuf)
149 {
150 
151     MPI_Aint datatype_size=0, bytes=0;
152     int error_code;
153 
154     error_code = MPIU_datatype_full_size(type, &datatype_size);
155     if (error_code != MPI_SUCCESS)
156 	return error_code;
157 
158     bytes = datatype_size * count;
159     *newbuf = ADIOI_Malloc(bytes);
160 
161     error_code = MPIU_write_external32_conversion_fn(buf, type, count, *newbuf);
162     if (error_code != MPI_SUCCESS) {
163 	ADIOI_Free(*newbuf);
164 	return error_code;
165     }
166     return MPI_SUCCESS;
167 }
168 
169 
170 /*
171  * vim: ts=8 sts=4 sw=4 noexpandtab
172  */
173