blob: 488bb13fdf595748609e46daa2ad26100f7e3560 [file] [log] [blame]
sewardjc3a47092006-02-18 23:13:33 +00001
2/*---------------------------------------------------------------*/
3/*--- ---*/
sewardj157a8c42006-03-12 00:35:42 +00004/*--- A library of wrappers for MPI 2 functions. ---*/
sewardjc3a47092006-02-18 23:13:33 +00005/*--- ---*/
6/*---------------------------------------------------------------*/
7
8/* ----------------------------------------------------------------
9
10 Notice that the following BSD-style license applies to this one
11 file (mpiwrap.c) only. The rest of Valgrind is licensed under the
12 terms of the GNU General Public License, version 2, unless
13 otherwise indicated. See the COPYING file in the source
14 distribution for details.
15
16 ----------------------------------------------------------------
17
18 This file is part of Valgrind, a dynamic binary instrumentation
19 framework.
20
Elliott Hughesed398002017-06-21 14:41:24 -070021 Copyright (C) 2006-2017 OpenWorks LLP. All rights reserved.
sewardjc3a47092006-02-18 23:13:33 +000022
23 Redistribution and use in source and binary forms, with or without
24 modification, are permitted provided that the following conditions
25 are met:
26
27 1. Redistributions of source code must retain the above copyright
28 notice, this list of conditions and the following disclaimer.
29
30 2. The origin of this software must not be misrepresented; you must
31 not claim that you wrote the original software. If you use this
32 software in a product, an acknowledgment in the product
33 documentation would be appreciated but is not required.
34
35 3. Altered source versions must be plainly marked as such, and must
36 not be misrepresented as being the original software.
37
38 4. The name of the author may not be used to endorse or promote
39 products derived from this software without specific prior written
40 permission.
41
42 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
43 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
44 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
45 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
46 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
47 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
48 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
49 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
50 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
51 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
52 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
53
54 Neither the names of the U.S. Department of Energy nor the
55 University of California nor the names of its contributors may be
56 used to endorse or promote products derived from this software
57 without prior written permission.
58*/
59
sewardj753ab9d2009-11-05 08:43:38 +000060/* Handling of MPI_STATUS{ES}_IGNORE for MPI_Status* arguments.
61
62 The MPI-2 spec allows many functions which have MPI_Status* purely
63 as an out parameter, to accept the constants MPI_STATUS_IGNORE or
64 MPI_STATUSES_IGNORE there instead, if the caller does not care
65 about the status. See the MPI-2 spec sec 4.5.1 ("Passing
66 MPI_STATUS_IGNORE for Status"). (mpi2-report.pdf, 1615898 bytes,
67 md5=694a5efe2fd291eecf7e8c9875b5f43f).
68
69 This library handles such cases by allocating a fake MPI_Status
70 object (on the stack) or an array thereof (on the heap), and
71 passing that onwards instead. From the outside the caller sees no
72 difference. Unfortunately the simpler approach of merely detecting
73 and handling these special cases at a lower level does not work,
74 because we need to use information returned in MPI_Status*
75 arguments to paint result buffers, even if the caller doesn't
76 supply a real MPI_Status object.
77
78 Eg, MPI_Recv. We can't paint the result buffer without knowing how
79 many items arrived; but we can't find that out without passing a
80 real MPI_Status object to the (real) MPI_Recv call. Hence, if the
81 caller did not supply one, we have no option but to use a temporary
82 stack allocated one for the inner call. Ditto, more indirectly
83 (via maybe_complete) for nonblocking receives and the various
84 associated wait/test calls. */
85
sewardjc3a47092006-02-18 23:13:33 +000086
87/*------------------------------------------------------------*/
sewardjc3a47092006-02-18 23:13:33 +000088/*--- includes ---*/
89/*------------------------------------------------------------*/
90
91#include <stdio.h>
92#include <assert.h>
93#include <unistd.h> /* getpid */
94#include <stdlib.h> /* exit */
95#include <string.h> /* strstr */
96#include <pthread.h> /* pthread_mutex_{lock,unlock} */
97
98/* Include Valgrind magic macros for writing wrappers. */
sewardj20974012006-02-19 14:05:28 +000099#include "../memcheck/memcheck.h"
sewardjc3a47092006-02-18 23:13:33 +0000100
sewardjdc873c02011-07-24 16:02:33 +0000101/* Include macros for VALGRIND_{DIS,EN}ABLE_ERROR_REPORTING.
102 This is somewhat experimental and hence disable-able, by
103 setting cONFIG_DER to zero. */
104#include "../include/valgrind.h"
105
106#define cONFIG_DER 1 /* set to 0 to disable */
107
sewardjc3a47092006-02-18 23:13:33 +0000108
109/*------------------------------------------------------------*/
110/*--- Connect to MPI library ---*/
111/*------------------------------------------------------------*/
112
113/* Include headers for whatever MPI implementation the wrappers are to
sewardj80637752006-03-02 13:48:21 +0000114 be used with. The configure system will tell us what the path to
115 the chosen MPI implementation is, via -I.. to the compiler. */
sewardjc3a47092006-02-18 23:13:33 +0000116#include "mpi.h"
117
118/* Where are API symbols?
sewardjabbad832007-01-06 05:28:27 +0000119 Open MPI lib/libmpi.so, soname = libmpi.so.0
120 Quadrics MPI lib/libmpi.so, soname = libmpi.so.0
121 MPICH libmpich.so.1.0, soname = libmpich.so.1.0
sewardjabbad832007-01-06 05:28:27 +0000122
sewardj6e9de462011-06-28 07:25:29 +0000123 A suitable soname to match with is therefore "libmpi*.so*".
sewardjc3a47092006-02-18 23:13:33 +0000124*/
sewardj6e9de462011-06-28 07:25:29 +0000125#define I_WRAP_FNNAME_U(_name) \
126 I_WRAP_SONAME_FNNAME_ZU(libmpiZaZdsoZa,_name)
sewardjc3a47092006-02-18 23:13:33 +0000127
sewardjcb7fa502006-11-24 15:18:15 +0000128
sewardj753ab9d2009-11-05 08:43:38 +0000129/* Define HAVE_MPI_STATUS_IGNORE iff we have to deal with
130 MPI_STATUS{ES}_IGNORE. */
131#if MPI_VERSION >= 2 \
132 || (defined(MPI_STATUS_IGNORE) && defined(MPI_STATUSES_IGNORE))
133# undef HAVE_MPI_STATUS_IGNORE
134# define HAVE_MPI_STATUS_IGNORE 1
135#else
136# undef HAVE_MPI_STATUS_IGNORE
137#endif
138
139
sewardjc3a47092006-02-18 23:13:33 +0000140/*------------------------------------------------------------*/
141/*--- Decls ---*/
142/*------------------------------------------------------------*/
143
144typedef unsigned char Bool;
145#define False ((Bool)0)
146#define True ((Bool)1)
147
sewardj63daa8a2006-03-09 19:08:20 +0000148/* Word, UWord are machine words - same size as a pointer. This is
149 checked at startup. The wrappers below use 'long' to mean a
150 machine word - this too is tested at startup. */
151typedef signed long Word;
152typedef unsigned long UWord;
153
sewardjcd8aaef2006-03-10 13:43:49 +0000154#if !defined(offsetof)
sewardjcbc2e0e2014-09-06 15:25:08 +0000155# define offsetof(type,memb) ((UWord)&((type*)0)->memb)
sewardjcd8aaef2006-03-10 13:43:49 +0000156#endif
157
sewardjcb7fa502006-11-24 15:18:15 +0000158/* Find the size of long double image (not 'sizeof(long double)').
159 See comments in sizeofOneNamedTy. */
160static long sizeof_long_double_image ( void );
161
sewardjc3a47092006-02-18 23:13:33 +0000162
163/*------------------------------------------------------------*/
164/*--- Simple helpers ---*/
165/*------------------------------------------------------------*/
166
167/* ------ Helpers for debug printing ------ */
168
169/* constant */
170static const char* preamble = "valgrind MPI wrappers";
171
172/* established at startup */
sewardjd465d992006-10-17 01:46:55 +0000173static pid_t my_pid = -1;
174static char* options_str = NULL;
175static int opt_verbosity = 1;
176static Bool opt_missing = 0; /* 0:silent; 1:warn; 2:abort */
177static Bool opt_help = False;
178static Bool opt_initkludge = False;
sewardjc3a47092006-02-18 23:13:33 +0000179
sewardj9c969c32006-03-10 18:37:45 +0000180static void before ( char* fnname )
sewardjc3a47092006-02-18 23:13:33 +0000181{
182 /* This isn't thread-safe wrt 'done' (no locking). It's not
183 critical. */
184 static int done = 0;
185 if (done == 0) {
186 done = 1;
187 my_pid = getpid();
188 options_str = getenv("MPIWRAP_DEBUG");
sewardjec8b6142006-03-09 03:05:17 +0000189 if (options_str) {
sewardj63daa8a2006-03-09 19:08:20 +0000190 if (NULL != strstr(options_str, "warn"))
191 opt_missing = 1;
192 if (NULL != strstr(options_str, "strict"))
193 opt_missing = 2;
sewardjec8b6142006-03-09 03:05:17 +0000194 if (NULL != strstr(options_str, "verbose"))
195 opt_verbosity++;
196 if (NULL != strstr(options_str, "quiet"))
197 opt_verbosity--;
sewardj63daa8a2006-03-09 19:08:20 +0000198 if (NULL != strstr(options_str, "help"))
199 opt_help = True;
sewardjd465d992006-10-17 01:46:55 +0000200 if (NULL != strstr(options_str, "initkludge"))
201 opt_initkludge = True;
sewardjec8b6142006-03-09 03:05:17 +0000202 }
203 if (opt_verbosity > 0)
204 fprintf(stderr, "%s %5d: Active for pid %d\n",
205 preamble, my_pid, my_pid);
sewardj63daa8a2006-03-09 19:08:20 +0000206 /* Sanity check - that Word/UWord really are machine words. */
207 assert(sizeof(Word) == sizeof(void*));
208 assert(sizeof(UWord) == sizeof(void*));
sewardj301a50f2006-03-03 16:14:18 +0000209 /* Sanity check - char is byte-sized (else address calculations
210 in walk_type don't work. */
211 assert(sizeof(char) == 1);
sewardjc3a47092006-02-18 23:13:33 +0000212 if (opt_help) {
213 fprintf(stderr, "\n");
214 fprintf(stderr, "Valid options for the MPIWRAP_DEBUG environment"
215 " variable are:\n");
216 fprintf(stderr, "\n");
sewardjd465d992006-10-17 01:46:55 +0000217 fprintf(stderr, " quiet be silent except for errors\n");
218 fprintf(stderr, " verbose show wrapper entries/exits\n");
219 fprintf(stderr, " strict abort the program if a function"
sewardjc3a47092006-02-18 23:13:33 +0000220 " with no wrapper is used\n");
sewardjd465d992006-10-17 01:46:55 +0000221 fprintf(stderr, " warn give a warning if a function"
sewardj63daa8a2006-03-09 19:08:20 +0000222 " with no wrapper is used\n");
sewardjd465d992006-10-17 01:46:55 +0000223 fprintf(stderr, " help display this message, then exit\n");
224 fprintf(stderr, " initkludge debugging hack; do not use\n");
sewardjc3a47092006-02-18 23:13:33 +0000225 fprintf(stderr, "\n");
226 fprintf(stderr, "Multiple options are allowed, eg"
227 " MPIWRAP_DEBUG=strict,verbose\n");
sewardj63daa8a2006-03-09 19:08:20 +0000228 fprintf(stderr, "Note: 'warn' generates output even if 'quiet'"
229 " is also specified\n");
sewardjc3a47092006-02-18 23:13:33 +0000230 fprintf(stderr, "\n");
231 fprintf(stderr, "%s %5d: exiting now\n", preamble, my_pid );
232 exit(1);
233 }
sewardjec8b6142006-03-09 03:05:17 +0000234 if (opt_verbosity > 0)
235 fprintf(stderr,
236 "%s %5d: Try MPIWRAP_DEBUG=help for possible options\n",
237 preamble, my_pid);
sewardjc3a47092006-02-18 23:13:33 +0000238
239 }
sewardjec8b6142006-03-09 03:05:17 +0000240 if (opt_verbosity > 1)
sewardjc3a47092006-02-18 23:13:33 +0000241 fprintf(stderr, "%s %5d: enter PMPI_%s\n", preamble, my_pid, fnname );
242}
243
sewardjd465d992006-10-17 01:46:55 +0000244static __inline__ void after ( char* fnname, int err )
sewardjc3a47092006-02-18 23:13:33 +0000245{
sewardjec8b6142006-03-09 03:05:17 +0000246 if (opt_verbosity > 1)
sewardjc3a47092006-02-18 23:13:33 +0000247 fprintf(stderr, "%s %5d: exit PMPI_%s (err = %d)\n",
248 preamble, my_pid, fnname, err );
249}
250
251static void barf ( char* msg )
252{
253 fprintf(stderr, "%s %5d: fatal: %s\n", preamble, my_pid, msg);
254 fprintf(stderr, "%s %5d: exiting now\n", preamble, my_pid );
255 exit(1);
256}
257
sewardj533bfda2006-03-08 20:41:44 +0000258/* Half-hearted type-showing function (for debugging). */
259static void showTy ( FILE* f, MPI_Datatype ty )
260{
261 if (ty == MPI_DATATYPE_NULL) fprintf(f,"DATATYPE_NULL");
262 else if (ty == MPI_BYTE) fprintf(f,"BYTE");
263 else if (ty == MPI_PACKED) fprintf(f,"PACKED");
264 else if (ty == MPI_CHAR) fprintf(f,"CHAR");
265 else if (ty == MPI_SHORT) fprintf(f,"SHORT");
266 else if (ty == MPI_INT) fprintf(f,"INT");
267 else if (ty == MPI_LONG) fprintf(f,"LONG");
268 else if (ty == MPI_FLOAT) fprintf(f,"FLOAT");
269 else if (ty == MPI_DOUBLE) fprintf(f,"DOUBLE");
270 else if (ty == MPI_LONG_DOUBLE) fprintf(f,"LONG_DOUBLE");
271 else if (ty == MPI_UNSIGNED_CHAR) fprintf(f,"UNSIGNED_CHAR");
272 else if (ty == MPI_UNSIGNED_SHORT) fprintf(f,"UNSIGNED_SHORT");
273 else if (ty == MPI_UNSIGNED_LONG) fprintf(f,"UNSIGNED_LONG");
274 else if (ty == MPI_UNSIGNED) fprintf(f,"UNSIGNED");
275 else if (ty == MPI_FLOAT_INT) fprintf(f,"FLOAT_INT");
276 else if (ty == MPI_DOUBLE_INT) fprintf(f,"DOUBLE_INT");
277 else if (ty == MPI_LONG_DOUBLE_INT) fprintf(f,"LONG_DOUBLE_INT");
278 else if (ty == MPI_LONG_INT) fprintf(f,"LONG_INT");
279 else if (ty == MPI_SHORT_INT) fprintf(f,"SHORT_INT");
280 else if (ty == MPI_2INT) fprintf(f,"2INT");
281 else if (ty == MPI_UB) fprintf(f,"UB");
282 else if (ty == MPI_LB) fprintf(f,"LB");
283# if defined(MPI_WCHAR)
284 else if (ty == MPI_WCHAR) fprintf(f,"WCHAR");
285# endif
286 else if (ty == MPI_LONG_LONG_INT) fprintf(f,"LONG_LONG_INT");
sewardj87f75f72006-03-12 16:44:05 +0000287# if defined(MPI_LONG_LONG)
sewardj533bfda2006-03-08 20:41:44 +0000288 else if (ty == MPI_LONG_LONG) fprintf(f,"LONG_LONG");
sewardj87f75f72006-03-12 16:44:05 +0000289# endif
sewardj582031b2006-04-13 22:03:16 +0000290# if defined(MPI_UNSIGNED_LONG_LONG)
sewardj533bfda2006-03-08 20:41:44 +0000291 else if (ty == MPI_UNSIGNED_LONG_LONG) fprintf(f,"UNSIGNED_LONG_LONG");
sewardj582031b2006-04-13 22:03:16 +0000292# endif
sewardj443aa372007-04-05 00:35:20 +0000293# if defined(MPI_REAL8)
294 else if (ty == MPI_REAL8) fprintf(f, "REAL8");
295# endif
296# if defined(MPI_REAL4)
297 else if (ty == MPI_REAL4) fprintf(f, "REAL4");
298# endif
sewardja7802962007-06-05 19:51:35 +0000299# if defined(MPI_REAL)
300 else if (ty == MPI_REAL) fprintf(f, "REAL");
301# endif
sewardj443aa372007-04-05 00:35:20 +0000302# if defined(MPI_INTEGER8)
303 else if (ty == MPI_INTEGER8) fprintf(f, "INTEGER8");
304# endif
305# if defined(MPI_INTEGER4)
306 else if (ty == MPI_INTEGER4) fprintf(f, "INTEGER4");
307# endif
sewardja7802962007-06-05 19:51:35 +0000308# if defined(MPI_INTEGER)
309 else if (ty == MPI_INTEGER) fprintf(f, "INTEGER");
310# endif
sewardja8c487f2007-06-04 21:14:36 +0000311# if defined(MPI_DOUBLE_PRECISION)
312 else if (ty == MPI_DOUBLE_PRECISION) fprintf(f, "DOUBLE_PRECISION");
313# endif
sewardja7802962007-06-05 19:51:35 +0000314# if defined(MPI_COMPLEX)
315 else if (ty == MPI_COMPLEX) fprintf(f, "COMPLEX");
316# endif
317# if defined(MPI_DOUBLE_COMPLEX)
318 else if (ty == MPI_DOUBLE_COMPLEX) fprintf(f, "DOUBLE_COMPLEX");
319# endif
320# if defined(MPI_LOGICAL)
321 else if (ty == MPI_LOGICAL) fprintf(f, "LOGICAL");
322# endif
323# if defined(MPI_2INTEGER)
324 else if (ty == MPI_2INTEGER) fprintf(f, "2INTEGER");
325# endif
326# if defined(MPI_2COMPLEX)
327 else if (ty == MPI_2COMPLEX) fprintf(f, "2COMPLEX");
328# endif
329# if defined(MPI_2DOUBLE_COMPLEX)
330 else if (ty == MPI_2DOUBLE_COMPLEX) fprintf(f, "2DOUBLE_COMPLEX");
331# endif
332# if defined(MPI_2REAL)
333 else if (ty == MPI_2REAL) fprintf(f, "2REAL");
334# endif
335# if defined(MPI_2DOUBLE_PRECISION)
336 else if (ty == MPI_2DOUBLE_PRECISION) fprintf(f, "2DOUBLE_PRECISION");
337# endif
338# if defined(MPI_CHARACTER)
339 else if (ty == MPI_CHARACTER) fprintf(f, "CHARACTER");
340# endif
sewardj533bfda2006-03-08 20:41:44 +0000341 else fprintf(f,"showTy:???");
342}
343
344static void showCombiner ( FILE* f, int combiner )
345{
346 switch (combiner) {
347 case MPI_COMBINER_NAMED: fprintf(f, "NAMED"); break;
sewardjcc8c3992006-03-08 21:40:34 +0000348#if defined(MPI_COMBINER_DUP)
sewardj533bfda2006-03-08 20:41:44 +0000349 case MPI_COMBINER_DUP: fprintf(f, "DUP"); break;
sewardjcc8c3992006-03-08 21:40:34 +0000350# endif
sewardj533bfda2006-03-08 20:41:44 +0000351 case MPI_COMBINER_CONTIGUOUS: fprintf(f, "CONTIGUOUS"); break;
352 case MPI_COMBINER_VECTOR: fprintf(f, "VECTOR"); break;
sewardjcc8c3992006-03-08 21:40:34 +0000353#if defined(MPI_COMBINER_HVECTOR_INTEGER)
sewardj533bfda2006-03-08 20:41:44 +0000354 case MPI_COMBINER_HVECTOR_INTEGER: fprintf(f, "HVECTOR_INTEGER"); break;
sewardjcc8c3992006-03-08 21:40:34 +0000355# endif
sewardj533bfda2006-03-08 20:41:44 +0000356 case MPI_COMBINER_HVECTOR: fprintf(f, "HVECTOR"); break;
357 case MPI_COMBINER_INDEXED: fprintf(f, "INDEXED"); break;
sewardjcc8c3992006-03-08 21:40:34 +0000358#if defined(MPI_COMBINER_HINDEXED_INTEGER)
sewardj533bfda2006-03-08 20:41:44 +0000359 case MPI_COMBINER_HINDEXED_INTEGER: fprintf(f, "HINDEXED_INTEGER"); break;
sewardjcc8c3992006-03-08 21:40:34 +0000360# endif
sewardj533bfda2006-03-08 20:41:44 +0000361 case MPI_COMBINER_HINDEXED: fprintf(f, "HINDEXED"); break;
sewardjcc8c3992006-03-08 21:40:34 +0000362#if defined(MPI_COMBINER_INDEXED_BLOCK)
sewardj533bfda2006-03-08 20:41:44 +0000363 case MPI_COMBINER_INDEXED_BLOCK: fprintf(f, "INDEXED_BLOCK"); break;
sewardjcc8c3992006-03-08 21:40:34 +0000364# endif
365#if defined(MPI_COMBINER_STRUCT_INTEGER)
sewardj533bfda2006-03-08 20:41:44 +0000366 case MPI_COMBINER_STRUCT_INTEGER: fprintf(f, "STRUCT_INTEGER"); break;
sewardjcc8c3992006-03-08 21:40:34 +0000367# endif
sewardj533bfda2006-03-08 20:41:44 +0000368 case MPI_COMBINER_STRUCT: fprintf(f, "STRUCT"); break;
sewardjcc8c3992006-03-08 21:40:34 +0000369#if defined(MPI_COMBINER_SUBARRAY)
sewardj533bfda2006-03-08 20:41:44 +0000370 case MPI_COMBINER_SUBARRAY: fprintf(f, "SUBARRAY"); break;
sewardjcc8c3992006-03-08 21:40:34 +0000371# endif
372#if defined(MPI_COMBINER_DARRAY)
sewardj533bfda2006-03-08 20:41:44 +0000373 case MPI_COMBINER_DARRAY: fprintf(f, "DARRAY"); break;
sewardjcc8c3992006-03-08 21:40:34 +0000374# endif
375#if defined(MPI_COMBINER_F90_REAL)
sewardj533bfda2006-03-08 20:41:44 +0000376 case MPI_COMBINER_F90_REAL: fprintf(f, "F90_REAL"); break;
sewardjcc8c3992006-03-08 21:40:34 +0000377# endif
378#if defined(MPI_COMBINER_F90_COMPLEX)
sewardj533bfda2006-03-08 20:41:44 +0000379 case MPI_COMBINER_F90_COMPLEX: fprintf(f, "F90_COMPLEX"); break;
sewardjcc8c3992006-03-08 21:40:34 +0000380# endif
381#if defined(MPI_COMBINER_F90_INTEGER)
sewardj533bfda2006-03-08 20:41:44 +0000382 case MPI_COMBINER_F90_INTEGER: fprintf(f, "F90_INTEGER"); break;
sewardjcc8c3992006-03-08 21:40:34 +0000383# endif
384#if defined(MPI_COMBINER_RESIZED)
sewardj533bfda2006-03-08 20:41:44 +0000385 case MPI_COMBINER_RESIZED: fprintf(f, "RESIZED"); break;
sewardjcc8c3992006-03-08 21:40:34 +0000386# endif
sewardj533bfda2006-03-08 20:41:44 +0000387 default: fprintf(f, "showCombiner:??"); break;
388 }
389}
390
391
sewardjc3a47092006-02-18 23:13:33 +0000392/* ------ Get useful bits of info ------ */
393
394/* Note, PMPI_Comm_rank/size are themselves wrapped. Should work
395 fine. */
396
sewardjd465d992006-10-17 01:46:55 +0000397static __inline__ int comm_rank ( MPI_Comm comm )
sewardjc3a47092006-02-18 23:13:33 +0000398{
399 int err, r;
400 err = PMPI_Comm_rank(comm, &r);
401 return err ? 0/*arbitrary*/ : r;
402}
403
sewardjd465d992006-10-17 01:46:55 +0000404static __inline__ int comm_size ( MPI_Comm comm )
sewardjc3a47092006-02-18 23:13:33 +0000405{
406 int err, r;
407 err = PMPI_Comm_size(comm, &r);
408 return err ? 0/*arbitrary*/ : r;
409}
410
sewardjd465d992006-10-17 01:46:55 +0000411static __inline__ Bool count_from_Status( /*OUT*/int* recv_count,
sewardjc3a47092006-02-18 23:13:33 +0000412 MPI_Datatype datatype,
413 MPI_Status* status)
414{
415 int n;
sewardj26c60a82012-08-23 19:25:12 +0000416 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING;
sewardjc3a47092006-02-18 23:13:33 +0000417 int err = PMPI_Get_count(status, datatype, &n);
sewardj26c60a82012-08-23 19:25:12 +0000418 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING;
sewardjc3a47092006-02-18 23:13:33 +0000419 if (err == MPI_SUCCESS) {
sewardj6dfd4132015-09-07 19:40:20 +0000420 VALGRIND_MAKE_MEM_DEFINED(&n, sizeof(n));
sewardjc3a47092006-02-18 23:13:33 +0000421 *recv_count = n;
422 return True;
423 } else {
424 return False;
425 }
426}
427
428/* It's critical that we can do equality on MPI_Requests.
429 Unfortunately these are opaque objects to us (handles, in the
430 parlance of the MPI 1.1 spec). Fortunately Sec 2.4.1 ("Opaque
431 Objects") specifies that "In C, [...] These [handles] should be
432 types that support assignment and equality operations." Hence the
433 following function should compile for any compliant definition of
434 MPI_Request. */
sewardjd465d992006-10-17 01:46:55 +0000435static __inline__
sewardjc3a47092006-02-18 23:13:33 +0000436Bool eq_MPI_Request ( MPI_Request r1, MPI_Request r2 )
437{
438 return r1 == r2;
439}
440
sewardj753ab9d2009-11-05 08:43:38 +0000441/* Return True if status is MPI_STATUS_IGNORE or MPI_STATUSES_IGNORE.
442 On MPI-1.x platforms which don't have these symbols (and they would
443 only have them if they've been backported from 2.x) always return
444 False. */
445static __inline__
446Bool isMSI ( MPI_Status* status )
447{
448# if defined(HAVE_MPI_STATUS_IGNORE)
449 return status == MPI_STATUSES_IGNORE || status == MPI_STATUS_IGNORE;
450# else
451 return False;
452# endif
453}
454
sewardj8717d1a2006-03-04 02:31:52 +0000455/* Get the 'extent' of a type. Note, as per the MPI spec this
456 includes whatever padding would be required when using 'ty' in an
457 array. */
sewardj301a50f2006-03-03 16:14:18 +0000458static long extentOfTy ( MPI_Datatype ty )
459{
460 int r;
461 MPI_Aint n;
462 r = PMPI_Type_extent(ty, &n);
463 assert(r == MPI_SUCCESS);
464 return (long)n;
465}
466
sewardjcd8aaef2006-03-10 13:43:49 +0000467/* Free up *ty, if it is safe to do so */
sewardj301a50f2006-03-03 16:14:18 +0000468static void maybeFreeTy ( MPI_Datatype* ty )
469{
470 int r, n_ints, n_addrs, n_dtys, tycon;
471
472 r = PMPI_Type_get_envelope( *ty, &n_ints, &n_addrs, &n_dtys, &tycon );
473 assert(r == MPI_SUCCESS);
474
sewardjcd8aaef2006-03-10 13:43:49 +0000475 /* can't free named types */
476 if (tycon == MPI_COMBINER_NAMED)
477 return;
478
479 /* some kinds of structs are predefined so we can't free them
480 either. */
481 if (*ty == MPI_FLOAT_INT || *ty == MPI_DOUBLE_INT
482 || *ty == MPI_LONG_INT || *ty == MPI_2INT
483 || *ty == MPI_SHORT_INT || *ty == MPI_LONG_DOUBLE_INT)
484 return;
485
486 /* Looks OK - free it. */
487 if (0) {
488 /* show me what you're about to free .. */
489 fprintf(stderr, "freeing combiner ");
490 showCombiner(stderr,tycon);
491 fprintf(stderr, " ty= ");
492 showTy(stderr,*ty);
493 fprintf(stderr,"\n");
sewardj301a50f2006-03-03 16:14:18 +0000494 }
sewardjcd8aaef2006-03-10 13:43:49 +0000495 r = PMPI_Type_free(ty);
496 assert(r == MPI_SUCCESS);
sewardj301a50f2006-03-03 16:14:18 +0000497}
498
sewardj8717d1a2006-03-04 02:31:52 +0000499/* How big is a "named" (base) type? Returns 0 if not known. Note.
500 There is a subtlety, which is that this is required to return the
501 exact size of one item of the type, NOT the size of it when padded
502 suitably to make an array of them. In particular that's why the
sewardjcb7fa502006-11-24 15:18:15 +0000503 size of LONG_DOUBLE is computed by looking at the result of doing a
504 long double store, rather than just asking what is the sizeof(long
505 double).
506
507 For LONG_DOUBLE on x86-linux and amd64-linux my impression is that
508 the right answer is 10 even though sizeof(long double) says 12 and
509 16 respectively. On ppc32-linux it appears to be 16.
sewardj3f55c9c2006-03-12 13:37:19 +0000510
511 Ref: MPI 1.1 doc p18 */
sewardj8717d1a2006-03-04 02:31:52 +0000512static long sizeofOneNamedTy ( MPI_Datatype ty )
sewardj1646f752006-03-03 21:03:10 +0000513{
sewardjcd8aaef2006-03-10 13:43:49 +0000514 if (ty == MPI_CHAR) return sizeof(signed char);
515 if (ty == MPI_SHORT) return sizeof(signed short int);
516 if (ty == MPI_INT) return sizeof(signed int);
517 if (ty == MPI_LONG) return sizeof(signed long int);
sewardjc0526f72006-03-08 03:54:37 +0000518 if (ty == MPI_UNSIGNED_CHAR) return sizeof(unsigned char);
519 if (ty == MPI_UNSIGNED_SHORT) return sizeof(unsigned short int);
sewardjcd8aaef2006-03-10 13:43:49 +0000520 if (ty == MPI_UNSIGNED) return sizeof(unsigned int);
521 if (ty == MPI_UNSIGNED_LONG) return sizeof(unsigned long int);
522 if (ty == MPI_FLOAT) return sizeof(float);
523 if (ty == MPI_DOUBLE) return sizeof(double);
sewardjcd8aaef2006-03-10 13:43:49 +0000524 if (ty == MPI_BYTE) return 1;
sewardjcb7fa502006-11-24 15:18:15 +0000525 if (ty == MPI_LONG_DOUBLE) return sizeof_long_double_image();
sewardjee346592007-02-08 12:05:03 +0000526 if (ty == MPI_PACKED) return 1;
sewardja7802962007-06-05 19:51:35 +0000527 if (ty == MPI_LONG_LONG_INT) return sizeof(signed long long int);
sewardjcb7fa502006-11-24 15:18:15 +0000528
sewardj443aa372007-04-05 00:35:20 +0000529# if defined(MPI_REAL8)
sewardja7802962007-06-05 19:51:35 +0000530 if (ty == MPI_REAL8) return 8; /* MPI2 spec */;
sewardj443aa372007-04-05 00:35:20 +0000531# endif
532# if defined(MPI_REAL4)
sewardja7802962007-06-05 19:51:35 +0000533 if (ty == MPI_REAL4) return 4; /* MPI2 spec */;
534# endif
535# if defined(MPI_REAL)
536 if (ty == MPI_REAL) return 4; /* MPI2 spec */;
sewardj443aa372007-04-05 00:35:20 +0000537# endif
538# if defined(MPI_INTEGER8)
sewardja7802962007-06-05 19:51:35 +0000539 if (ty == MPI_INTEGER8) return 8; /* MPI2 spec */;
sewardj443aa372007-04-05 00:35:20 +0000540# endif
541# if defined(MPI_INTEGER4)
sewardja7802962007-06-05 19:51:35 +0000542 if (ty == MPI_INTEGER4) return 4; /* MPI2 spec */;
543# endif
544# if defined(MPI_INTEGER)
545 if (ty == MPI_INTEGER) return 4; /* MPI2 spec */;
sewardj443aa372007-04-05 00:35:20 +0000546# endif
sewardja8c487f2007-06-04 21:14:36 +0000547# if defined(MPI_DOUBLE_PRECISION)
sewardja7802962007-06-05 19:51:35 +0000548 if (ty == MPI_DOUBLE_PRECISION) return 8; /* MPI2 spec */;
sewardja8c487f2007-06-04 21:14:36 +0000549# endif
sewardj443aa372007-04-05 00:35:20 +0000550
sewardjcd8aaef2006-03-10 13:43:49 +0000551 /* new in MPI2: */
sewardj493743f2006-03-10 22:17:57 +0000552# if defined(MPI_WCHAR)
sewardja7802962007-06-05 19:51:35 +0000553 if (ty == MPI_WCHAR) return 2; /* MPI2 spec */;
sewardj493743f2006-03-10 22:17:57 +0000554# endif
555# if defined(MPI_SIGNED_CHAR)
sewardja7802962007-06-05 19:51:35 +0000556 if (ty == MPI_SIGNED_CHAR) return 1; /* MPI2 spec */;
sewardj493743f2006-03-10 22:17:57 +0000557# endif
sewardj582031b2006-04-13 22:03:16 +0000558# if defined(MPI_UNSIGNED_LONG_LONG)
sewardja7802962007-06-05 19:51:35 +0000559 if (ty == MPI_UNSIGNED_LONG_LONG) return 8; /* MPI2 spec */;
sewardj582031b2006-04-13 22:03:16 +0000560# endif
sewardja7802962007-06-05 19:51:35 +0000561# if defined(MPI_COMPLEX)
562 if (ty == MPI_COMPLEX) return 2 * 4; /* MPI2 spec */
563# endif
564# if defined(MPI_DOUBLE_COMPLEX)
565 if (ty == MPI_DOUBLE_COMPLEX) return 2 * 8; /* MPI2 spec */
566# endif
567# if defined(MPI_LOGICAL)
568 if (ty == MPI_LOGICAL) return 4; /* MPI2 spec */
569# endif
570# if defined(MPI_2INTEGER)
571 if (ty == MPI_2INTEGER) return 2 * 4; /* undocumented in MPI2 */
572# endif
573# if defined(MPI_2COMPLEX)
574 if (ty == MPI_2COMPLEX) return 2 * 8; /* undocumented in MPI2 */
575# endif
576# if defined(MPI_2DOUBLE_COMPLEX)
577 /* 32: this is how openmpi-1.2.2 behaves on x86-linux, but I have
578 really no idea if this is right. */
579 if (ty == MPI_2DOUBLE_COMPLEX) return 32; /* undocumented in MPI2 */
580# endif
581# if defined(MPI_2REAL)
582 if (ty == MPI_2REAL) return 2 * 4; /* undocumented in MPI2 */
583# endif
584# if defined(MPI_2DOUBLE_PRECISION)
585 if (ty == MPI_2DOUBLE_PRECISION) return 2 * 8; /* undocumented in MPI2 */
586# endif
587# if defined(MPI_CHARACTER)
588 if (ty == MPI_CHARACTER) return 1; /* MPI2 spec */
589# endif
590
sewardjcd8aaef2006-03-10 13:43:49 +0000591 /* Note: the following are named structs, not named basic types,
592 and so are not handled here:
593 FLOAT_INT DOUBLE_INT LONG_INT 2INT SHORT_INT LONG_DOUBLE_INT
594 My guess is they are probably for doing max-w-index style
595 reductions, the INT carrying the index of the max/min and the
596 other type its actual value.
597 */
sewardj1646f752006-03-03 21:03:10 +0000598 return 0;
599}
600
sewardj301a50f2006-03-03 16:14:18 +0000601
sewardjcb7fa502006-11-24 15:18:15 +0000602/* Find the size of long double image (not 'sizeof(long double)').
603 See comments in sizeofOneNamedTy.
604*/
605static long sizeof_long_double_image ( void )
606{
607 long i;
608 unsigned char* p;
609 static long cached_result = 0;
610
611 /* Hopefully we have it already. */
612 if (cached_result != 0) {
613 assert(cached_result == 10 || cached_result == 16 || cached_result == 8);
614 return cached_result;
615 }
616
617 /* No? Then we'll have to compute it. This isn't thread-safe but
618 it doesn't really matter since all races to compute it should
619 produce the same answer. */
620 p = malloc(64);
621 assert(p);
622 for (i = 0; i < 64; i++)
623 p[i] = 0x55;
624
625 /* Write a value which isn't known at compile time and therefore
626 must come out of a register. If we just store a constant here,
627 some compilers write more data than a store from a machine
628 register would. Therefore we have to force a store from a
629 machine register by storing a value which isn't known at compile
630 time. Since getpid() will return a value < 1 million, turn it
631 into a zero by dividing by 1e+30. */
632 *(long double*)(&p[16]) = (long double)(1.0e-30 * (double)getpid());
633
634 for (i = 0; i < 16; i++) {
635 assert(p[i] == 0x55);
636 assert(p[i+48] == 0x55);
637 }
638 for (i = 16; i <= 48; i++) {
639 if (p[i] == 0x55)
640 break;
641 }
642
643 assert(i < 48);
644 assert(i > 16);
645 free(p);
646 cached_result = i - 16;
647
648 if (0)
649 printf("sizeof_long_double_image: computed %d\n", (int)cached_result);
650
651 assert(cached_result == 10 || cached_result == 16 || cached_result == 8);
652 return cached_result;
653}
654
655
sewardj301a50f2006-03-03 16:14:18 +0000656/*------------------------------------------------------------*/
657/*--- Unpicking datatypes ---*/
658/*------------------------------------------------------------*/
659
sewardjcf375342007-01-16 05:35:46 +0000660static __inline__
sewardj301a50f2006-03-03 16:14:18 +0000661void walk_type_array ( void(*f)(void*,long), char* base,
662 MPI_Datatype ty, long count );
663
664
665/* Walk over all fragments of the object of type 'ty' with base
666 address 'base', and apply 'f' to the start/length of each
667 contiguous fragment. */
668static
669void walk_type ( void(*f)(void*,long), char* base, MPI_Datatype ty )
670{
671 int r, n_ints, n_addrs, n_dtys, tycon;
sewardj1646f752006-03-03 21:03:10 +0000672 long ex, i;
sewardj301a50f2006-03-03 16:14:18 +0000673 int* ints = NULL;
674 MPI_Aint* addrs = NULL;
675 MPI_Datatype* dtys = NULL;
sewardj301a50f2006-03-03 16:14:18 +0000676
sewardj443aa372007-04-05 00:35:20 +0000677 /* Stuff for limiting how much complaining text it spews out */
678 static int complaints = 3;
679 static int last_complained_about_tycon = -987654321; /* presumably bogus */
680
sewardj1646f752006-03-03 21:03:10 +0000681 if (0)
sewardjabbad832007-01-06 05:28:27 +0000682 printf("walk_type %p\n", (void*)(unsigned long)ty);
sewardj301a50f2006-03-03 16:14:18 +0000683
sewardj9c969c32006-03-10 18:37:45 +0000684 r = PMPI_Type_get_envelope( ty, &n_ints, &n_addrs, &n_dtys, &tycon );
sewardj301a50f2006-03-03 16:14:18 +0000685 assert(r == MPI_SUCCESS);
686
687 /* Handle the base cases fast(er/ish). */
688 if (tycon == MPI_COMBINER_NAMED) {
sewardj8717d1a2006-03-04 02:31:52 +0000689 long sz = sizeofOneNamedTy(ty);
sewardjcd8aaef2006-03-10 13:43:49 +0000690 if (sz > 0) {
691 f(base, sz);
692 return;
693 }
694 /* Hmm. Perhaps it's a named struct? Unfortunately we can't
695 take them to bits so we have to do a really ugly hack, which
696 makes assumptions about how the MPI implementation has laid
sewardj558cc222006-03-10 14:51:19 +0000697 out these types. At least Open MPI 1.0.1 appears to put
sewardja7802962007-06-05 19:51:35 +0000698 the 'val' field first. MPICH2 agrees.
sewardjcd8aaef2006-03-10 13:43:49 +0000699 */
sewardj443aa372007-04-05 00:35:20 +0000700 if (ty == MPI_2INT) {
701 typedef struct { int val; int loc; } Ty;
702 f(base + offsetof(Ty,val), sizeof(int));
703 f(base + offsetof(Ty,loc), sizeof(int));
704 return;
705 }
sewardjcd8aaef2006-03-10 13:43:49 +0000706 if (ty == MPI_LONG_INT) {
sewardj558cc222006-03-10 14:51:19 +0000707 typedef struct { long val; int loc; } Ty;
708 f(base + offsetof(Ty,val), sizeof(long));
709 f(base + offsetof(Ty,loc), sizeof(int));
710 return;
711 }
712 if (ty == MPI_DOUBLE_INT) {
713 typedef struct { double val; int loc; } Ty;
714 f(base + offsetof(Ty,val), sizeof(double));
715 f(base + offsetof(Ty,loc), sizeof(int));
716 return;
717 }
718 if (ty == MPI_SHORT_INT) {
719 typedef struct { short val; int loc; } Ty;
720 f(base + offsetof(Ty,val), sizeof(short));
sewardjcd8aaef2006-03-10 13:43:49 +0000721 f(base + offsetof(Ty,loc), sizeof(int));
722 return;
723 }
sewardja7802962007-06-05 19:51:35 +0000724 if (ty == MPI_FLOAT_INT) {
725 typedef struct { float val; int loc; } Ty;
726 f(base + offsetof(Ty,val), sizeof(float));
727 f(base + offsetof(Ty,loc), sizeof(int));
728 return;
729 }
730 if (ty == MPI_LONG_DOUBLE_INT) {
731 typedef struct { long double val; int loc; } Ty;
732 f(base + offsetof(Ty,val), sizeof_long_double_image());
733 f(base + offsetof(Ty,loc), sizeof(int));
734 return;
735 }
sewardj493743f2006-03-10 22:17:57 +0000736 if (ty == MPI_LB || ty == MPI_UB)
737 return; /* have zero size, so nothing needs to be done */
sewardjcd8aaef2006-03-10 13:43:49 +0000738 goto unhandled;
sewardj301a50f2006-03-03 16:14:18 +0000739 /*NOTREACHED*/
740 }
741
sewardj1646f752006-03-03 21:03:10 +0000742 if (0) {
sewardj301a50f2006-03-03 16:14:18 +0000743 ex = extentOfTy(ty);
sewardj157a8c42006-03-12 00:35:42 +0000744 printf("tycon 0x%llx %d %d %d (ext %d)\n",
745 (unsigned long long int)tycon,
746 n_ints, n_addrs, n_dtys, (int)ex );
sewardj301a50f2006-03-03 16:14:18 +0000747 }
748
749 /* Now safe to do MPI_Type_get_contents */
750 assert(n_ints >= 0);
751 assert(n_addrs >= 0);
752 assert(n_dtys >= 0);
753
754 if (n_ints > 0) {
755 ints = malloc(n_ints * sizeof(int));
756 assert(ints);
757 }
758 if (n_addrs > 0) {
759 addrs = malloc(n_addrs * sizeof(MPI_Aint));
760 assert(addrs);
761 }
762 if (n_dtys > 0) {
763 dtys = malloc(n_dtys * sizeof(MPI_Datatype));
764 assert(dtys);
765 }
766
sewardj9c969c32006-03-10 18:37:45 +0000767 r = PMPI_Type_get_contents( ty, n_ints, n_addrs, n_dtys,
768 ints, addrs, dtys );
sewardj301a50f2006-03-03 16:14:18 +0000769 assert(r == MPI_SUCCESS);
770
771 switch (tycon) {
772
773 case MPI_COMBINER_CONTIGUOUS:
774 assert(n_ints == 1 && n_addrs == 0 && n_dtys == 1);
775 walk_type_array( f, base, dtys[0], ints[0] );
776 maybeFreeTy( &dtys[0] );
777 break;
778
sewardjc0526f72006-03-08 03:54:37 +0000779 case MPI_COMBINER_VECTOR:
780 assert(n_ints == 3 && n_addrs == 0 && n_dtys == 1);
781 ex = extentOfTy(dtys[0]);
782 if (0)
783 printf("vector count %d x (bl %d stride %d)\n",
784 (int)ints[0], (int)ints[1], (int)ints[2]);
785 for (i = 0; i < ints[0]; i++) {
786 walk_type_array( f, base + i * ints[2]/*stride*/ * ex,
787 dtys[0], ints[1]/*blocklength*/ );
788 }
789 maybeFreeTy( &dtys[0] );
790 break;
791
792 case MPI_COMBINER_HVECTOR:
793 assert(n_ints == 2 && n_addrs == 1 && n_dtys == 1);
794 ex = extentOfTy(dtys[0]);
795 if (0)
796 printf("hvector count %d x (bl %d hstride %d)\n",
797 (int)ints[0], (int)ints[1], (int)addrs[0]);
798 for (i = 0; i < ints[0]; i++) {
799 walk_type_array( f, base + i * addrs[0]/*hstride*/,
800 dtys[0], ints[1]/*blocklength*/ );
801 }
802 maybeFreeTy( &dtys[0] );
803 break;
804
805 case MPI_COMBINER_INDEXED:
806 assert(n_addrs == 0 && n_dtys == 1);
807 assert(n_ints > 0);
808 assert(n_ints == 2 * ints[0] + 1);
809 ex = extentOfTy(dtys[0]);
810 for (i = 0; i < ints[0]; i++) {
811 if (0)
812 printf("indexed (elem %d) off %d copies %d\n",
813 (int)i, ints[i+1+ints[0]], ints[i+1] );
814 walk_type_array( f, base + ex * ints[i+1+ints[0]],
815 dtys[0], ints[i+1] );
816 }
817 maybeFreeTy( &dtys[0] );
818 break;
819
820 case MPI_COMBINER_HINDEXED:
821 assert(n_ints > 0);
822 assert(n_ints == ints[0] + 1);
823 assert(n_addrs == ints[0] && n_dtys == 1);
824 ex = extentOfTy(dtys[0]);
825 for (i = 0; i < ints[0]; i++) {
826 if (0)
827 printf("hindexed (elem %d) hoff %d copies %d\n",
828 (int)i, (int)addrs[i], ints[i+1] );
829 walk_type_array( f, base + addrs[i],
830 dtys[0], ints[i+1] );
831 }
832 maybeFreeTy( &dtys[0] );
833 break;
834
sewardj301a50f2006-03-03 16:14:18 +0000835 case MPI_COMBINER_STRUCT:
836 assert(n_addrs == n_ints-1);
837 assert(n_dtys == n_ints-1);
sewardjc0526f72006-03-08 03:54:37 +0000838 assert(n_ints > 0);
839 assert(n_ints == ints[0] + 1);
sewardj301a50f2006-03-03 16:14:18 +0000840 for (i = 0; i < ints[0]; i++) {
sewardj1646f752006-03-03 21:03:10 +0000841 if (0)
sewardjc0526f72006-03-08 03:54:37 +0000842 printf("struct (elem %d limit %d) hoff %d copies %d\n",
sewardj301a50f2006-03-03 16:14:18 +0000843 (int)i, (int)ints[0], (int)addrs[i], (int)ints[i+1]);
844 walk_type_array( f, base + addrs[i], dtys[i], (long)ints[i+1] );
845 maybeFreeTy( &dtys[i] );
846 }
847 break;
848
849 default:
850 goto unhandled;
851
852 }
853
854 /* normal exit */
855 if (ints) free(ints);
856 if (addrs) free(addrs);
857 if (dtys) free(dtys);
858 return;
859
860 unhandled:
sewardj443aa372007-04-05 00:35:20 +0000861 /* Complain, but limit the amount of complaining that can happen to
862 the first 3 different unhandled tycons that show up, so as to
863 avoid swamping users with thousands of duplicate messages. */
864 if (complaints > 0 && tycon != last_complained_about_tycon) {
865 complaints--;
866 last_complained_about_tycon = tycon;
867 if (tycon == MPI_COMBINER_NAMED) {
868 fprintf(stderr, "%s %5d: walk_type: unhandled base type 0x%lx ",
869 preamble, my_pid, (long)ty);
870 showTy(stderr, ty);
871 fprintf(stderr, "\n");
872 } else {
873 fprintf(stderr, "%s %5d: walk_type: unhandled combiner 0x%lx\n",
874 preamble, my_pid, (long)tycon);
875 }
sewardj301a50f2006-03-03 16:14:18 +0000876 }
877 if (ints) free(ints);
878 if (addrs) free(addrs);
879 if (dtys) free(dtys);
sewardjcd8aaef2006-03-10 13:43:49 +0000880 if (opt_missing >= 2)
881 barf("walk_type: unhandled combiner, strict checking selected");
sewardj301a50f2006-03-03 16:14:18 +0000882}
883
884
sewardjcd8aaef2006-03-10 13:43:49 +0000885/* Same as walk_type but apply 'f' to every element in an array of
886 'count' items starting at 'base'. The only purpose of pushing this
887 into a different routine is so it can attempt to optimise the case
888 where the array elements are contiguous and packed together without
889 holes. */
sewardjcf375342007-01-16 05:35:46 +0000890static __inline__
sewardj301a50f2006-03-03 16:14:18 +0000891void walk_type_array ( void(*f)(void*,long), char* base,
892 MPI_Datatype elemTy, long count )
893{
894 long i, ex;
sewardj1646f752006-03-03 21:03:10 +0000895
896 assert(sizeof(unsigned long) == sizeof(char*));
897
898 /* First see if we can do this the fast way. */
sewardj8717d1a2006-03-04 02:31:52 +0000899 ex = sizeofOneNamedTy(elemTy);
sewardj1646f752006-03-03 21:03:10 +0000900
901 if ( /* ty is a primitive type with power-of-2 size */
902 (ex == 8 || ex == 4 || ex == 2 || ex == 1)
903 && /* base is suitably aligned for ty */
904 ( ((unsigned long)base) & (ex-1)) == 0) {
905
906 /* We're sure it's contiguous, so just paint/check it in one
907 go. */
908 if (0) printf("walk_type_array fast %ld of size %ld\n", count, ex );
909 f ( base, count * ex );
910
911 } else {
912
913 /* Bad news. We have to futz with each element individually.
sewardj8717d1a2006-03-04 02:31:52 +0000914 This could be very expensive.
915
916 Note: subtle. If ty is LONG_DOUBLE then the extent will be
917 12, so the following loop will jump along in steps of 12, but
918 the size painted by walk_type will be 10 since it uses
919 sizeofOneNamedTy to establish the size of base types. Which
920 is what we need to happen. */
sewardj1646f752006-03-03 21:03:10 +0000921 ex = extentOfTy(elemTy);
922 if (0) printf("walk_type_array SLOW %ld of size %ld\n", count, ex );
923 for (i = 0; i < count; i++)
924 walk_type( f, base + i * ex, elemTy );
925
926 }
sewardj301a50f2006-03-03 16:14:18 +0000927}
928
sewardjc3a47092006-02-18 23:13:33 +0000929
sewardj558cc222006-03-10 14:51:19 +0000930/* Hook so it's visible from outside (can be handy to dlopen/dlsym
931 it) */
932void mpiwrap_walk_type_EXTERNALLY_VISIBLE
sewardjc0526f72006-03-08 03:54:37 +0000933 ( void(*f)(void*,long), char* base, MPI_Datatype ty )
934{
sewardjd465d992006-10-17 01:46:55 +0000935 walk_type(f, base, ty);
sewardjc0526f72006-03-08 03:54:37 +0000936}
937
938
sewardjc3a47092006-02-18 23:13:33 +0000939/*------------------------------------------------------------*/
940/*--- Address-range helpers ---*/
941/*------------------------------------------------------------*/
942
943/* ----------------
sewardjc3a47092006-02-18 23:13:33 +0000944 Do corresponding checks on memory areas defined using a
sewardjcf375342007-01-16 05:35:46 +0000945 straightforward (start, length) description.
sewardjc3a47092006-02-18 23:13:33 +0000946 ----------------
947*/
948
sewardjcf375342007-01-16 05:35:46 +0000949static __inline__
njndbf7ca72006-03-31 11:57:59 +0000950void check_mem_is_defined_untyped ( void* buffer, long nbytes )
sewardjc3a47092006-02-18 23:13:33 +0000951{
952 if (nbytes > 0) {
njndbf7ca72006-03-31 11:57:59 +0000953 VALGRIND_CHECK_MEM_IS_DEFINED(buffer, nbytes);
sewardjc3a47092006-02-18 23:13:33 +0000954 }
955}
956
sewardjcf375342007-01-16 05:35:46 +0000957static __inline__
njndbf7ca72006-03-31 11:57:59 +0000958void check_mem_is_addressable_untyped ( void* buffer, long nbytes )
sewardjc3a47092006-02-18 23:13:33 +0000959{
960 if (nbytes > 0) {
njndbf7ca72006-03-31 11:57:59 +0000961 VALGRIND_CHECK_MEM_IS_ADDRESSABLE(buffer, nbytes);
sewardjc3a47092006-02-18 23:13:33 +0000962 }
963}
964
sewardjcf375342007-01-16 05:35:46 +0000965static __inline__
njndbf7ca72006-03-31 11:57:59 +0000966void make_mem_defined_if_addressable_untyped ( void* buffer, long nbytes )
sewardjc3a47092006-02-18 23:13:33 +0000967{
968 if (nbytes > 0) {
njndbf7ca72006-03-31 11:57:59 +0000969 VALGRIND_MAKE_MEM_DEFINED_IF_ADDRESSABLE(buffer, nbytes);
sewardjc3a47092006-02-18 23:13:33 +0000970 }
971}
972
sewardjcf375342007-01-16 05:35:46 +0000973static __inline__
njndbf7ca72006-03-31 11:57:59 +0000974void make_mem_defined_if_addressable_if_success_untyped ( int err,
sewardjcd8aaef2006-03-10 13:43:49 +0000975 void* buffer, long nbytes )
sewardjc3a47092006-02-18 23:13:33 +0000976{
977 if (err == MPI_SUCCESS && nbytes > 0) {
njndbf7ca72006-03-31 11:57:59 +0000978 VALGRIND_MAKE_MEM_DEFINED_IF_ADDRESSABLE(buffer, nbytes);
sewardjc3a47092006-02-18 23:13:33 +0000979 }
980}
981
sewardjc3a47092006-02-18 23:13:33 +0000982
sewardj301a50f2006-03-03 16:14:18 +0000983/* ----------------
984 Do checks on memory areas defined using the MPI (buffer, count,
985 type) convention.
986 ----------------
987*/
988
989/* Check that the specified area is both addressible and contains
990 initialised data, and cause V to complain if not. */
991
sewardjcf375342007-01-16 05:35:46 +0000992static __inline__
njndbf7ca72006-03-31 11:57:59 +0000993void check_mem_is_defined ( char* buffer, long count, MPI_Datatype datatype )
sewardj301a50f2006-03-03 16:14:18 +0000994{
njndbf7ca72006-03-31 11:57:59 +0000995 walk_type_array( check_mem_is_defined_untyped, buffer, datatype, count );
sewardj301a50f2006-03-03 16:14:18 +0000996}
997
998
999/* Check that the specified area is addressible, and cause V to
1000 complain if not. Doesn't matter whether the data there is
1001 initialised or not. */
1002
sewardjcf375342007-01-16 05:35:46 +00001003static __inline__
njndbf7ca72006-03-31 11:57:59 +00001004void check_mem_is_addressable ( void *buffer, long count, MPI_Datatype datatype )
sewardj301a50f2006-03-03 16:14:18 +00001005{
njndbf7ca72006-03-31 11:57:59 +00001006 walk_type_array( check_mem_is_addressable_untyped, buffer, datatype, count );
sewardj301a50f2006-03-03 16:14:18 +00001007}
1008
1009
sewardjcd8aaef2006-03-10 13:43:49 +00001010/* Set the specified area to 'defined for each byte which is
1011 addressible' state. */
sewardj301a50f2006-03-03 16:14:18 +00001012
sewardjcf375342007-01-16 05:35:46 +00001013static __inline__
njndbf7ca72006-03-31 11:57:59 +00001014void make_mem_defined_if_addressable ( void *buffer, int count, MPI_Datatype datatype )
sewardj301a50f2006-03-03 16:14:18 +00001015{
njndbf7ca72006-03-31 11:57:59 +00001016 walk_type_array( make_mem_defined_if_addressable_untyped,
1017 buffer, datatype, count );
sewardj301a50f2006-03-03 16:14:18 +00001018}
1019
sewardjcf375342007-01-16 05:35:46 +00001020static __inline__
sewardj301a50f2006-03-03 16:14:18 +00001021void
njndbf7ca72006-03-31 11:57:59 +00001022make_mem_defined_if_addressable_if_success ( int err, void *buffer, int count,
1023 MPI_Datatype datatype )
sewardj301a50f2006-03-03 16:14:18 +00001024{
1025 if (err == MPI_SUCCESS)
njndbf7ca72006-03-31 11:57:59 +00001026 make_mem_defined_if_addressable(buffer, count, datatype);
sewardj301a50f2006-03-03 16:14:18 +00001027}
1028
1029
sewardjc3a47092006-02-18 23:13:33 +00001030/*------------------------------------------------------------*/
1031/*--- ---*/
1032/*--- The wrappers proper. They are listed in the order ---*/
1033/*--- in which they appear in "MPI: A Message-Passing ---*/
1034/*--- Interface Standard, MPIF, Nov 15 2003" (the MPI 1.1 ---*/
1035/*--- spec. All unimplemented wrappers are listed at the ---*/
1036/*--- end of the file. The list of function names is ---*/
sewardj9c969c32006-03-10 18:37:45 +00001037/*--- taken from the headers of Open MPI svn r9191. ---*/
1038/*--- Hopefully it is a complete list of all the MPI 2 ---*/
1039/*--- functions. ---*/
sewardjc3a47092006-02-18 23:13:33 +00001040/*--- ---*/
1041/*------------------------------------------------------------*/
1042
1043/* Handy abbreviation */
1044#define WRAPPER_FOR(name) I_WRAP_FNNAME_U(name)
1045
sewardjc3a47092006-02-18 23:13:33 +00001046/* Generates (conceptually) a wrapper which does nothing. In
1047 fact just generate no wrapper at all. */
sewardj9c969c32006-03-10 18:37:45 +00001048#define HAS_NO_WRAPPER(basename) /* */
sewardjc3a47092006-02-18 23:13:33 +00001049
1050
1051/*------------------------------------------------------------*/
1052/*--- ---*/
1053/*--- Sec 3.2, Blocking Send and Receive Operations ---*/
1054/*--- ---*/
1055/*------------------------------------------------------------*/
1056
sewardj9c969c32006-03-10 18:37:45 +00001057/* --- {,B,S,R}Send --- */
sewardjc3a47092006-02-18 23:13:33 +00001058/* pre: rd: (buf,count,datatype) */
sewardj9c969c32006-03-10 18:37:45 +00001059static
1060int generic_Send(void *buf, int count, MPI_Datatype datatype,
1061 int dest, int tag, MPI_Comm comm)
sewardjc3a47092006-02-18 23:13:33 +00001062{
1063 OrigFn fn;
1064 int err;
1065 VALGRIND_GET_ORIG_FN(fn);
sewardj9c969c32006-03-10 18:37:45 +00001066 before("{,B,S,R}Send");
njndbf7ca72006-03-31 11:57:59 +00001067 check_mem_is_defined(buf, count, datatype);
sewardjdc873c02011-07-24 16:02:33 +00001068 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING;
sewardjc3a47092006-02-18 23:13:33 +00001069 CALL_FN_W_6W(err, fn, buf,count,datatype,dest,tag,comm);
sewardjdc873c02011-07-24 16:02:33 +00001070 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING;
sewardj9c969c32006-03-10 18:37:45 +00001071 after("{,B,S,R}Send", err);
sewardjc3a47092006-02-18 23:13:33 +00001072 return err;
1073}
sewardj9c969c32006-03-10 18:37:45 +00001074int WRAPPER_FOR(PMPI_Send)(void *buf, int count, MPI_Datatype datatype,
1075 int dest, int tag, MPI_Comm comm) {
1076 return generic_Send(buf,count,datatype, dest,tag,comm);
1077}
1078int WRAPPER_FOR(PMPI_Bsend)(void *buf, int count, MPI_Datatype datatype,
1079 int dest, int tag, MPI_Comm comm) {
1080 return generic_Send(buf,count,datatype, dest,tag,comm);
1081}
1082int WRAPPER_FOR(PMPI_Ssend)(void *buf, int count, MPI_Datatype datatype,
1083 int dest, int tag, MPI_Comm comm) {
1084 return generic_Send(buf,count,datatype, dest,tag,comm);
1085}
1086int WRAPPER_FOR(PMPI_Rsend)(void *buf, int count, MPI_Datatype datatype,
1087 int dest, int tag, MPI_Comm comm) {
1088 return generic_Send(buf,count,datatype, dest,tag,comm);
1089}
sewardjc3a47092006-02-18 23:13:33 +00001090
sewardjc3a47092006-02-18 23:13:33 +00001091/* --- Recv --- */
1092/* pre: must be writable: (buf,count,datatype)
1093 must be writable: status
1094 post: make readable: (buf,recv_count,datatype)
1095 where recv_count is determined from *status
1096*/
1097int WRAPPER_FOR(PMPI_Recv)(void *buf, int count, MPI_Datatype datatype,
1098 int source, int tag,
1099 MPI_Comm comm, MPI_Status *status)
1100{
sewardj753ab9d2009-11-05 08:43:38 +00001101 OrigFn fn;
1102 int err, recv_count = 0;
1103 MPI_Status fake_status;
sewardjc3a47092006-02-18 23:13:33 +00001104 VALGRIND_GET_ORIG_FN(fn);
1105 before("Recv");
sewardj753ab9d2009-11-05 08:43:38 +00001106 if (isMSI(status))
1107 status = &fake_status;
njndbf7ca72006-03-31 11:57:59 +00001108 check_mem_is_addressable(buf, count, datatype);
1109 check_mem_is_addressable_untyped(status, sizeof(*status));
sewardjdc873c02011-07-24 16:02:33 +00001110 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING;
sewardjc3a47092006-02-18 23:13:33 +00001111 CALL_FN_W_7W(err, fn, buf,count,datatype,source,tag,comm,status);
sewardjdc873c02011-07-24 16:02:33 +00001112 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING;
sewardj26c60a82012-08-23 19:25:12 +00001113 make_mem_defined_if_addressable_if_success_untyped(err, status, sizeof(*status));
sewardjc3a47092006-02-18 23:13:33 +00001114 if (err == MPI_SUCCESS && count_from_Status(&recv_count,datatype,status)) {
njndbf7ca72006-03-31 11:57:59 +00001115 make_mem_defined_if_addressable(buf, recv_count, datatype);
sewardjc3a47092006-02-18 23:13:33 +00001116 }
1117 after("Recv", err);
1118 return err;
1119}
1120
sewardj9c969c32006-03-10 18:37:45 +00001121/* --- Get_count --- */
1122/* pre: must be readable: *status
1123 post: make defined: *count -- don't bother, libmpi will surely do this
1124*/
1125int WRAPPER_FOR(PMPI_Get_count)(MPI_Status* status,
1126 MPI_Datatype ty, int* count )
1127{
1128 OrigFn fn;
1129 int err;
1130 VALGRIND_GET_ORIG_FN(fn);
1131 before("Get_count");
njndbf7ca72006-03-31 11:57:59 +00001132 check_mem_is_defined_untyped(status, sizeof(*status));
sewardjdc873c02011-07-24 16:02:33 +00001133 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING;
sewardj9c969c32006-03-10 18:37:45 +00001134 CALL_FN_W_WWW(err, fn, status,ty,count);
sewardjdc873c02011-07-24 16:02:33 +00001135 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING;
sewardj9c969c32006-03-10 18:37:45 +00001136 after("Get_count", err);
1137 return err;
1138}
1139
sewardjc3a47092006-02-18 23:13:33 +00001140
1141/*------------------------------------------------------------*/
1142/*--- ---*/
1143/*--- Sec 3.7, Nonblocking communication ---*/
1144/*--- ---*/
1145/*------------------------------------------------------------*/
1146
sewardj9c969c32006-03-10 18:37:45 +00001147/* Maintain a table that makes it possible for the wrappers to
1148 complete MPI_Irecv successfully.
1149
1150 The issue is that MPI_Irecv states the recv buffer and returns
1151 immediately, giving a handle (MPI_Request) for the transaction.
1152 Later the user will have to poll for completion with MPI_Wait etc,
1153 and at that point these wrappers have to paint the recv buffer.
1154 But the recv buffer details are not presented to MPI_Wait - only
1155 the handle is. We therefore have to use a shadow table
1156 (sReqs{,_size,_used,_lock}) which associates uncompleted
1157 MPI_Requests with the corresponding buffer address/count/type.
1158
1159 Only read requests are placed in the table, since there is no need
1160 to do any buffer painting following completion of an Isend - all
1161 the checks for that are done at the time Isend is called.
1162
1163 Care has to be take to remove completed requests from the table.
1164
1165 Access to the table is guarded by sReqs_lock so as to make it
1166 thread-safe.
1167*/
1168
sewardjc3a47092006-02-18 23:13:33 +00001169typedef
1170 struct {
1171 Bool inUse;
1172 MPI_Request key;
1173 void* buf;
1174 int count;
1175 MPI_Datatype datatype;
1176 }
1177 ShadowRequest;
1178
1179static ShadowRequest* sReqs = NULL;
1180static int sReqs_size = 0;
1181static int sReqs_used = 0;
sewardj558cc222006-03-10 14:51:19 +00001182static pthread_mutex_t sReqs_lock = PTHREAD_MUTEX_INITIALIZER;
1183
1184#define LOCK_SREQS \
1185 do { int pr = pthread_mutex_lock(&sReqs_lock); \
1186 assert(pr == 0); \
1187 } while (0)
1188
1189#define UNLOCK_SREQS \
1190 do { int pr = pthread_mutex_unlock(&sReqs_lock); \
1191 assert(pr == 0); \
1192 } while (0)
sewardjc3a47092006-02-18 23:13:33 +00001193
1194
1195/* Ensure the sReqs expandable array has at least one free slot, by
1196 copying it into a larger one if necessary. NOTE: sReqs_lock is
1197 held throughout this procedure.*/
1198static void ensure_sReq_space ( void )
1199{
1200 int i;
1201 ShadowRequest* sReqs2;
1202 if (sReqs_used == sReqs_size) {
1203 sReqs_size = sReqs_size==0 ? 2 : 2*sReqs_size;
1204 sReqs2 = malloc( sReqs_size * sizeof(ShadowRequest) );
1205 if (sReqs2 == NULL) {
sewardj558cc222006-03-10 14:51:19 +00001206 UNLOCK_SREQS;
sewardjc3a47092006-02-18 23:13:33 +00001207 barf("add_shadow_Request: malloc failed.\n");
1208 }
1209 for (i = 0; i < sReqs_used; i++)
1210 sReqs2[i] = sReqs[i];
1211 if (sReqs)
1212 free(sReqs);
1213 sReqs = sReqs2;
1214 }
1215 assert(sReqs_used < sReqs_size);
1216}
1217
1218
1219/* Find shadow info for 'request', or NULL if none. */
1220
1221static
1222ShadowRequest* find_shadow_Request ( MPI_Request request )
1223{
1224 ShadowRequest* ret = NULL;
1225 int i;
sewardj558cc222006-03-10 14:51:19 +00001226 LOCK_SREQS;
sewardjc3a47092006-02-18 23:13:33 +00001227 for (i = 0; i < sReqs_used; i++) {
1228 if (sReqs[i].inUse && eq_MPI_Request(sReqs[i].key,request)) {
1229 ret = &sReqs[i];
1230 break;
1231 }
1232 }
sewardj558cc222006-03-10 14:51:19 +00001233 UNLOCK_SREQS;
sewardjc3a47092006-02-18 23:13:33 +00001234 return ret;
1235}
1236
1237
1238/* Delete shadow info for 'request', if any. */
1239
1240static void delete_shadow_Request ( MPI_Request request )
1241{
1242 int i;
sewardj558cc222006-03-10 14:51:19 +00001243 LOCK_SREQS;
sewardjc3a47092006-02-18 23:13:33 +00001244 for (i = 0; i < sReqs_used; i++) {
1245 if (sReqs[i].inUse && eq_MPI_Request(sReqs[i].key,request)) {
1246 sReqs[i].inUse = False;
1247 break;
1248 }
1249 }
sewardj558cc222006-03-10 14:51:19 +00001250 UNLOCK_SREQS;
sewardjc3a47092006-02-18 23:13:33 +00001251}
1252
1253
1254/* Add a shadow for 'request', overwriting any old binding for it. */
1255
1256static
1257void add_shadow_Request( MPI_Request request,
1258 void* buf, int count,
1259 MPI_Datatype datatype )
1260{
1261 int i, ix = -1;
sewardj558cc222006-03-10 14:51:19 +00001262 LOCK_SREQS;
sewardjc3a47092006-02-18 23:13:33 +00001263 assert(sReqs_used >= 0);
1264 assert(sReqs_size >= 0);
1265 assert(sReqs_used <= sReqs_size);
1266 if (sReqs == NULL) assert(sReqs_size == 0);
1267
1268 /* First of all see if we already have a binding for this key; if
1269 so just replace it, and have done. */
1270 for (i = 0; i < sReqs_used; i++) {
1271 if (sReqs[i].inUse && eq_MPI_Request(sReqs[i].key,request)) {
1272 ix = i;
1273 break;
1274 }
1275 }
1276
1277 if (ix < 0) {
1278 /* Ok, we don't have it, so will have to add it. First search
1279 to see if there is an existing empty slot. */
1280 for (i = 0; i < sReqs_used; i++) {
1281 if (!sReqs[i].inUse) {
1282 ix = i;
1283 break;
1284 }
1285 }
1286 }
1287
1288 /* No empty slots. Allocate a new one. */
1289 if (ix < 0) {
1290 ensure_sReq_space();
1291 assert(sReqs_used < sReqs_size);
1292 ix = sReqs_used;
1293 sReqs_used++;
1294 }
1295
1296 assert(ix >= 0 && ix < sReqs_used);
1297 assert(sReqs_used <= sReqs_size);
1298
1299 sReqs[ix].inUse = True;
1300 sReqs[ix].key = request;
1301 sReqs[ix].buf = buf;
1302 sReqs[ix].count = count;
1303 sReqs[ix].datatype = datatype;
1304
sewardj558cc222006-03-10 14:51:19 +00001305 UNLOCK_SREQS;
sewardjec8b6142006-03-09 03:05:17 +00001306 if (opt_verbosity > 1)
sewardjc3a47092006-02-18 23:13:33 +00001307 fprintf(stderr, "%s %5d: sReq+ 0x%lx -> b/c/d %p/%d/0x%lx [slot %d]\n",
1308 preamble, my_pid, (unsigned long)request,
1309 buf, count, (long)datatype, ix);
1310}
1311
sewardj9c969c32006-03-10 18:37:45 +00001312static
1313MPI_Request* clone_Request_array ( int count, MPI_Request* orig )
1314{
1315 MPI_Request* copy;
1316 int i;
1317 LOCK_SREQS;
1318 if (count < 0)
1319 count = 0; /* Hmm. Call Mulder and Scully. */
1320 copy = malloc( count * sizeof(MPI_Request) );
sewardjd465d992006-10-17 01:46:55 +00001321 if (copy == NULL && count > 0) {
sewardj9c969c32006-03-10 18:37:45 +00001322 UNLOCK_SREQS;
1323 barf("clone_Request_array: malloc failed");
1324 }
1325 for (i = 0; i < count; i++)
1326 copy[i] = orig[i];
1327 UNLOCK_SREQS;
1328 return copy;
1329}
1330
sewardj558cc222006-03-10 14:51:19 +00001331#undef LOCK_SREQS
1332#undef UNLOCK_SREQS
sewardjc3a47092006-02-18 23:13:33 +00001333
sewardj9c969c32006-03-10 18:37:45 +00001334
sewardjc3a47092006-02-18 23:13:33 +00001335static void maybe_complete ( Bool error_in_status,
1336 MPI_Request request_before,
1337 MPI_Request request_after,
1338 MPI_Status* status )
1339{
1340 int recv_count = 0;
1341 ShadowRequest* shadow;
1342 /* How do we know if this is an Irecv request that has now
1343 finished successfully?
1344
1345 request_before isn't MPI_REQUEST_NULL
1346 and request_before is found in the shadow table
1347 and request_after *is* MPI_REQUEST_NULL
1348 and (if error_in_status then status.MPI_ERROR is MPI_SUCCESS)
1349
1350 (when error_in_status == False, then we expect not to get
1351 called at all if there was an error.)
1352 */
1353 if (request_before != MPI_REQUEST_NULL
1354 && request_after == MPI_REQUEST_NULL
1355 && (error_in_status ? status->MPI_ERROR == MPI_SUCCESS : True)
1356 && ( (shadow=find_shadow_Request(request_before)) != NULL) ) {
sewardjb727b542006-03-10 21:41:01 +00001357 /* The Irecv detailed in 'shadow' completed. Paint the result
1358 buffer, and delete the entry. */
sewardjc3a47092006-02-18 23:13:33 +00001359 if (count_from_Status(&recv_count, shadow->datatype, status)) {
njndbf7ca72006-03-31 11:57:59 +00001360 make_mem_defined_if_addressable(shadow->buf, recv_count, shadow->datatype);
sewardjec8b6142006-03-09 03:05:17 +00001361 if (opt_verbosity > 1)
sewardjc3a47092006-02-18 23:13:33 +00001362 fprintf(stderr, "%s %5d: sReq- %p (completed)\n",
1363 preamble, my_pid, request_before);
1364 }
1365 delete_shadow_Request(request_before);
1366 }
1367}
1368
1369
sewardjc3a47092006-02-18 23:13:33 +00001370/* --- Isend --- */
1371/* rd: (buf,count,datatype) */
1372/* wr: *request */
sewardjcf375342007-01-16 05:35:46 +00001373static __inline__
sewardj9c969c32006-03-10 18:37:45 +00001374int generic_Isend(void *buf, int count, MPI_Datatype datatype,
1375 int dest, int tag, MPI_Comm comm,
1376 MPI_Request* request)
sewardjc3a47092006-02-18 23:13:33 +00001377{
1378 OrigFn fn;
1379 int err;
1380 VALGRIND_GET_ORIG_FN(fn);
sewardj9c969c32006-03-10 18:37:45 +00001381 before("{,B,S,R}Isend");
njndbf7ca72006-03-31 11:57:59 +00001382 check_mem_is_defined(buf, count, datatype);
1383 check_mem_is_addressable_untyped(request, sizeof(*request));
sewardjdc873c02011-07-24 16:02:33 +00001384 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING;
sewardjc3a47092006-02-18 23:13:33 +00001385 CALL_FN_W_7W(err, fn, buf,count,datatype,dest,tag,comm,request);
sewardjdc873c02011-07-24 16:02:33 +00001386 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING;
njndbf7ca72006-03-31 11:57:59 +00001387 make_mem_defined_if_addressable_if_success_untyped(err, request, sizeof(*request));
sewardj9c969c32006-03-10 18:37:45 +00001388 after("{,B,S,R}Isend", err);
sewardjc3a47092006-02-18 23:13:33 +00001389 return err;
1390}
sewardj9c969c32006-03-10 18:37:45 +00001391int WRAPPER_FOR(PMPI_Isend)(void *buf, int count, MPI_Datatype datatype,
1392 int dest, int tag, MPI_Comm comm,
1393 MPI_Request* request) {
1394 return generic_Isend(buf,count,datatype, dest,tag,comm, request);
1395}
1396int WRAPPER_FOR(PMPI_Ibsend)(void *buf, int count, MPI_Datatype datatype,
1397 int dest, int tag, MPI_Comm comm,
1398 MPI_Request* request) {
1399 return generic_Isend(buf,count,datatype, dest,tag,comm, request);
1400}
1401int WRAPPER_FOR(PMPI_Issend)(void *buf, int count, MPI_Datatype datatype,
1402 int dest, int tag, MPI_Comm comm,
1403 MPI_Request* request) {
1404 return generic_Isend(buf,count,datatype, dest,tag,comm, request);
1405}
1406int WRAPPER_FOR(PMPI_Irsend)(void *buf, int count, MPI_Datatype datatype,
1407 int dest, int tag, MPI_Comm comm,
1408 MPI_Request* request) {
1409 return generic_Isend(buf,count,datatype, dest,tag,comm, request);
1410}
1411
sewardjc3a47092006-02-18 23:13:33 +00001412
sewardjc3a47092006-02-18 23:13:33 +00001413/* --- Irecv --- */
1414/* pre: must be writable: (buf,count,datatype), *request
1415 post: make readable *request
1416 add a request->(buf,count,ty) binding to the
1417 shadow request table.
1418*/
1419int WRAPPER_FOR(PMPI_Irecv)( void* buf, int count, MPI_Datatype datatype,
1420 int source, int tag, MPI_Comm comm,
1421 MPI_Request* request )
1422{
1423 OrigFn fn;
1424 int err;
1425 VALGRIND_GET_ORIG_FN(fn);
1426 before("Irecv");
njndbf7ca72006-03-31 11:57:59 +00001427 check_mem_is_addressable(buf, count, datatype);
1428 check_mem_is_addressable_untyped(request, sizeof(*request));
sewardjdc873c02011-07-24 16:02:33 +00001429 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING;
sewardjc3a47092006-02-18 23:13:33 +00001430 CALL_FN_W_7W(err, fn, buf,count,datatype,source,tag,comm,request);
sewardjdc873c02011-07-24 16:02:33 +00001431 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING;
sewardjc3a47092006-02-18 23:13:33 +00001432 if (err == MPI_SUCCESS) {
njndbf7ca72006-03-31 11:57:59 +00001433 make_mem_defined_if_addressable_untyped(request, sizeof(*request));
sewardjc3a47092006-02-18 23:13:33 +00001434 add_shadow_Request( *request, buf,count,datatype );
1435 }
1436 after("Irecv", err);
1437 return err;
1438}
1439
sewardjc3a47092006-02-18 23:13:33 +00001440/* --- Wait --- */
sewardjb727b542006-03-10 21:41:01 +00001441/* The MPI1 spec (imprecisely) defines 3 request states:
1442 - "null" if the request is MPI_REQUEST_NULL
1443 - "inactive" if not "null" and not associated with ongoing comms
1444 - "active" if not "null" and is associated with ongoing comms
1445*/
sewardjc3a47092006-02-18 23:13:33 +00001446int WRAPPER_FOR(PMPI_Wait)( MPI_Request* request,
1447 MPI_Status* status )
1448{
1449 MPI_Request request_before;
sewardj753ab9d2009-11-05 08:43:38 +00001450 MPI_Status fake_status;
sewardjc3a47092006-02-18 23:13:33 +00001451 OrigFn fn;
1452 int err;
1453 VALGRIND_GET_ORIG_FN(fn);
1454 before("Wait");
sewardj753ab9d2009-11-05 08:43:38 +00001455 if (isMSI(status))
1456 status = &fake_status;
njndbf7ca72006-03-31 11:57:59 +00001457 check_mem_is_addressable_untyped(status, sizeof(MPI_Status));
1458 check_mem_is_defined_untyped(request, sizeof(MPI_Request));
sewardjc3a47092006-02-18 23:13:33 +00001459 request_before = *request;
sewardjdc873c02011-07-24 16:02:33 +00001460 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING;
sewardjc3a47092006-02-18 23:13:33 +00001461 CALL_FN_W_WW(err, fn, request,status);
sewardjdc873c02011-07-24 16:02:33 +00001462 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING;
sewardjc3a47092006-02-18 23:13:33 +00001463 if (err == MPI_SUCCESS) {
1464 maybe_complete(False/*err in status?*/,
1465 request_before, *request, status);
njndbf7ca72006-03-31 11:57:59 +00001466 make_mem_defined_if_addressable_untyped(status, sizeof(MPI_Status));
sewardjc3a47092006-02-18 23:13:33 +00001467 }
1468 after("Wait", err);
1469 return err;
1470}
1471
sewardj982751b2008-05-15 05:48:16 +00001472/* --- Waitany --- */
1473int WRAPPER_FOR(PMPI_Waitany)( int count,
1474 MPI_Request* requests,
1475 int* index,
1476 MPI_Status* status )
1477{
1478 MPI_Request* requests_before = NULL;
sewardj753ab9d2009-11-05 08:43:38 +00001479 MPI_Status fake_status;
sewardj982751b2008-05-15 05:48:16 +00001480 OrigFn fn;
1481 int err, i;
1482 VALGRIND_GET_ORIG_FN(fn);
1483 before("Waitany");
sewardj753ab9d2009-11-05 08:43:38 +00001484 if (isMSI(status))
1485 status = &fake_status;
sewardj982751b2008-05-15 05:48:16 +00001486 if (0) fprintf(stderr, "Waitany: %d\n", count);
1487 check_mem_is_addressable_untyped(index, sizeof(int));
1488 check_mem_is_addressable_untyped(status, sizeof(MPI_Status));
1489 for (i = 0; i < count; i++) {
1490 check_mem_is_defined_untyped(&requests[i], sizeof(MPI_Request));
1491 }
1492 requests_before = clone_Request_array( count, requests );
sewardjdc873c02011-07-24 16:02:33 +00001493 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING;
sewardj982751b2008-05-15 05:48:16 +00001494 CALL_FN_W_WWWW(err, fn, count,requests,index,status);
sewardjdc873c02011-07-24 16:02:33 +00001495 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING;
sewardj982751b2008-05-15 05:48:16 +00001496 if (err == MPI_SUCCESS && *index >= 0 && *index < count) {
1497 maybe_complete(False/*err in status?*/,
1498 requests_before[*index], requests[*index], status);
1499 make_mem_defined_if_addressable_untyped(status, sizeof(MPI_Status));
1500 }
1501 if (requests_before)
1502 free(requests_before);
1503 after("Waitany", err);
1504 return err;
1505}
1506
sewardjc3a47092006-02-18 23:13:33 +00001507/* --- Waitall --- */
1508int WRAPPER_FOR(PMPI_Waitall)( int count,
1509 MPI_Request* requests,
1510 MPI_Status* statuses )
1511{
1512 MPI_Request* requests_before = NULL;
1513 OrigFn fn;
1514 int err, i;
sewardj753ab9d2009-11-05 08:43:38 +00001515 Bool free_sta = False;
sewardjc3a47092006-02-18 23:13:33 +00001516 VALGRIND_GET_ORIG_FN(fn);
1517 before("Waitall");
1518 if (0) fprintf(stderr, "Waitall: %d\n", count);
sewardj753ab9d2009-11-05 08:43:38 +00001519 if (isMSI(statuses)) {
1520 free_sta = True;
1521 statuses = malloc( (count < 0 ? 0 : count) * sizeof(MPI_Status) );
1522 }
sewardjc3a47092006-02-18 23:13:33 +00001523 for (i = 0; i < count; i++) {
njndbf7ca72006-03-31 11:57:59 +00001524 check_mem_is_addressable_untyped(&statuses[i], sizeof(MPI_Status));
1525 check_mem_is_defined_untyped(&requests[i], sizeof(MPI_Request));
sewardjc3a47092006-02-18 23:13:33 +00001526 }
1527 requests_before = clone_Request_array( count, requests );
sewardjdc873c02011-07-24 16:02:33 +00001528 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING;
sewardjc3a47092006-02-18 23:13:33 +00001529 CALL_FN_W_WWW(err, fn, count,requests,statuses);
sewardjdc873c02011-07-24 16:02:33 +00001530 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING;
sewardjc3a47092006-02-18 23:13:33 +00001531 if (err == MPI_SUCCESS /*complete success*/
1532 || err == MPI_ERR_IN_STATUS /* partial success */) {
1533 Bool e_i_s = err == MPI_ERR_IN_STATUS;
1534 for (i = 0; i < count; i++) {
1535 maybe_complete(e_i_s, requests_before[i], requests[i],
1536 &statuses[i]);
njndbf7ca72006-03-31 11:57:59 +00001537 make_mem_defined_if_addressable_untyped(&statuses[i],
1538 sizeof(MPI_Status));
sewardjc3a47092006-02-18 23:13:33 +00001539 }
1540 }
1541 if (requests_before)
1542 free(requests_before);
sewardj753ab9d2009-11-05 08:43:38 +00001543 if (free_sta)
1544 free(statuses);
sewardjc3a47092006-02-18 23:13:33 +00001545 after("Waitall", err);
1546 return err;
1547}
1548
sewardjb727b542006-03-10 21:41:01 +00001549/* --- Test --- */
1550/* nonblocking version of Wait */
1551int WRAPPER_FOR(PMPI_Test)( MPI_Request* request, int* flag,
1552 MPI_Status* status )
1553{
1554 MPI_Request request_before;
sewardj753ab9d2009-11-05 08:43:38 +00001555 MPI_Status fake_status;
sewardjb727b542006-03-10 21:41:01 +00001556 OrigFn fn;
1557 int err;
1558 VALGRIND_GET_ORIG_FN(fn);
1559 before("Test");
sewardj753ab9d2009-11-05 08:43:38 +00001560 if (isMSI(status))
1561 status = &fake_status;
njndbf7ca72006-03-31 11:57:59 +00001562 check_mem_is_addressable_untyped(status, sizeof(MPI_Status));
1563 check_mem_is_addressable_untyped(flag, sizeof(int));
1564 check_mem_is_defined_untyped(request, sizeof(MPI_Request));
sewardjb727b542006-03-10 21:41:01 +00001565 request_before = *request;
sewardjdc873c02011-07-24 16:02:33 +00001566 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING;
sewardjb727b542006-03-10 21:41:01 +00001567 CALL_FN_W_WWW(err, fn, request,flag,status);
sewardjdc873c02011-07-24 16:02:33 +00001568 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING;
sewardjb727b542006-03-10 21:41:01 +00001569 if (err == MPI_SUCCESS && *flag) {
1570 maybe_complete(False/*err in status?*/,
1571 request_before, *request, status);
njndbf7ca72006-03-31 11:57:59 +00001572 make_mem_defined_if_addressable_untyped(status, sizeof(MPI_Status));
sewardjb727b542006-03-10 21:41:01 +00001573 }
1574 after("Test", err);
1575 return err;
1576}
1577
1578/* --- Testall --- */
1579/* nonblocking version of Waitall */
1580int WRAPPER_FOR(PMPI_Testall)( int count, MPI_Request* requests,
1581 int* flag, MPI_Status* statuses )
1582{
1583 MPI_Request* requests_before = NULL;
1584 OrigFn fn;
1585 int err, i;
sewardj753ab9d2009-11-05 08:43:38 +00001586 Bool free_sta = False;
sewardjb727b542006-03-10 21:41:01 +00001587 VALGRIND_GET_ORIG_FN(fn);
1588 before("Testall");
1589 if (0) fprintf(stderr, "Testall: %d\n", count);
sewardj753ab9d2009-11-05 08:43:38 +00001590 if (isMSI(statuses)) {
1591 free_sta = True;
1592 statuses = malloc( (count < 0 ? 0 : count) * sizeof(MPI_Status) );
1593 }
njndbf7ca72006-03-31 11:57:59 +00001594 check_mem_is_addressable_untyped(flag, sizeof(int));
sewardjb727b542006-03-10 21:41:01 +00001595 for (i = 0; i < count; i++) {
njndbf7ca72006-03-31 11:57:59 +00001596 check_mem_is_addressable_untyped(&statuses[i], sizeof(MPI_Status));
1597 check_mem_is_defined_untyped(&requests[i], sizeof(MPI_Request));
sewardjb727b542006-03-10 21:41:01 +00001598 }
1599 requests_before = clone_Request_array( count, requests );
sewardjdc873c02011-07-24 16:02:33 +00001600 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING;
sewardjb727b542006-03-10 21:41:01 +00001601 CALL_FN_W_WWWW(err, fn, count,requests,flag,statuses);
sewardjdc873c02011-07-24 16:02:33 +00001602 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING;
sewardjb727b542006-03-10 21:41:01 +00001603 /* Urk. Is the following "if (...)" really right? I don't know. */
1604 if (*flag
1605 && (err == MPI_SUCCESS /*complete success*/
1606 || err == MPI_ERR_IN_STATUS /* partial success */)) {
1607 Bool e_i_s = err == MPI_ERR_IN_STATUS;
1608 for (i = 0; i < count; i++) {
1609 maybe_complete(e_i_s, requests_before[i], requests[i],
1610 &statuses[i]);
sewardj753ab9d2009-11-05 08:43:38 +00001611 make_mem_defined_if_addressable_untyped(&statuses[i],
1612 sizeof(MPI_Status));
sewardjb727b542006-03-10 21:41:01 +00001613 }
1614 }
1615 if (requests_before)
1616 free(requests_before);
sewardj753ab9d2009-11-05 08:43:38 +00001617 if (free_sta)
1618 free(statuses);
sewardjb727b542006-03-10 21:41:01 +00001619 after("Testall", err);
1620 return err;
1621}
1622
sewardjc3a47092006-02-18 23:13:33 +00001623/* --- Iprobe --- */
sewardjc3a47092006-02-18 23:13:33 +00001624/* pre: must-be-writable: *flag, *status */
1625/* post: make-readable *flag
sewardjb727b542006-03-10 21:41:01 +00001626 if *flag==True make-defined *status */
sewardjc3a47092006-02-18 23:13:33 +00001627int WRAPPER_FOR(PMPI_Iprobe)(int source, int tag,
1628 MPI_Comm comm,
1629 int* flag, MPI_Status* status)
1630{
sewardj753ab9d2009-11-05 08:43:38 +00001631 MPI_Status fake_status;
1632 OrigFn fn;
1633 int err;
sewardjc3a47092006-02-18 23:13:33 +00001634 VALGRIND_GET_ORIG_FN(fn);
1635 before("Iprobe");
sewardj753ab9d2009-11-05 08:43:38 +00001636 if (isMSI(status))
1637 status = &fake_status;
njndbf7ca72006-03-31 11:57:59 +00001638 check_mem_is_addressable_untyped(flag, sizeof(*flag));
1639 check_mem_is_addressable_untyped(status, sizeof(*status));
sewardjdc873c02011-07-24 16:02:33 +00001640 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING;
sewardjc3a47092006-02-18 23:13:33 +00001641 CALL_FN_W_5W(err, fn, source,tag,comm,flag,status);
sewardjdc873c02011-07-24 16:02:33 +00001642 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING;
sewardjc3a47092006-02-18 23:13:33 +00001643 if (err == MPI_SUCCESS) {
njndbf7ca72006-03-31 11:57:59 +00001644 make_mem_defined_if_addressable_untyped(flag, sizeof(*flag));
sewardjc3a47092006-02-18 23:13:33 +00001645 if (*flag)
njndbf7ca72006-03-31 11:57:59 +00001646 make_mem_defined_if_addressable_untyped(status, sizeof(*status));
sewardjc3a47092006-02-18 23:13:33 +00001647 }
1648 after("Iprobe", err);
1649 return err;
1650}
1651
sewardjb727b542006-03-10 21:41:01 +00001652/* --- Probe --- */
1653/* pre: must-be-writable *status */
1654/* post: make-defined *status */
1655int WRAPPER_FOR(PMPI_Probe)(int source, int tag,
1656 MPI_Comm comm, MPI_Status* status)
1657{
sewardj753ab9d2009-11-05 08:43:38 +00001658 MPI_Status fake_status;
1659 OrigFn fn;
1660 int err;
sewardjb727b542006-03-10 21:41:01 +00001661 VALGRIND_GET_ORIG_FN(fn);
1662 before("Probe");
sewardj753ab9d2009-11-05 08:43:38 +00001663 if (isMSI(status))
1664 status = &fake_status;
njndbf7ca72006-03-31 11:57:59 +00001665 check_mem_is_addressable_untyped(status, sizeof(*status));
sewardjdc873c02011-07-24 16:02:33 +00001666 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING;
sewardjb727b542006-03-10 21:41:01 +00001667 CALL_FN_W_WWWW(err, fn, source,tag,comm,status);
sewardjdc873c02011-07-24 16:02:33 +00001668 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING;
njndbf7ca72006-03-31 11:57:59 +00001669 make_mem_defined_if_addressable_if_success_untyped(err, status, sizeof(*status));
sewardjb727b542006-03-10 21:41:01 +00001670 after("Probe", err);
1671 return err;
1672}
1673
1674/* --- Cancel --- */
1675/* Wrapping PMPI_Cancel is interesting only to the extent that we need
1676 to be able to detect when a request should be removed from our
1677 shadow table due to cancellation. */
1678int WRAPPER_FOR(PMPI_Cancel)(MPI_Request* request)
1679{
1680 OrigFn fn;
1681 int err;
1682 MPI_Request tmp;
1683 VALGRIND_GET_ORIG_FN(fn);
1684 before("Cancel");
njndbf7ca72006-03-31 11:57:59 +00001685 check_mem_is_addressable_untyped(request, sizeof(*request));
sewardjb727b542006-03-10 21:41:01 +00001686 tmp = *request;
sewardjdc873c02011-07-24 16:02:33 +00001687 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING;
sewardjb727b542006-03-10 21:41:01 +00001688 CALL_FN_W_W(err, fn, request);
sewardjdc873c02011-07-24 16:02:33 +00001689 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING;
sewardjb727b542006-03-10 21:41:01 +00001690 if (err == MPI_SUCCESS)
1691 delete_shadow_Request(tmp);
1692 after("Cancel", err);
1693 return err;
1694}
1695
sewardjc3a47092006-02-18 23:13:33 +00001696
1697/*------------------------------------------------------------*/
1698/*--- ---*/
1699/*--- Sec 3.10, Send-receive ---*/
1700/*--- ---*/
1701/*------------------------------------------------------------*/
1702
1703/* --- Sendrecv --- */
1704/* pre: must be readable: (sendbuf,sendcount,sendtype)
1705 must be writable: (recvbuf,recvcount,recvtype)
1706 post: make readable: (recvbuf,recvcount_actual,datatype)
1707 where recvcount_actual is determined from *status
1708*/
1709int WRAPPER_FOR(PMPI_Sendrecv)(
1710 void *sendbuf, int sendcount, MPI_Datatype sendtype,
1711 int dest, int sendtag,
1712 void *recvbuf, int recvcount, MPI_Datatype recvtype,
1713 int source, int recvtag,
1714 MPI_Comm comm, MPI_Status *status)
1715{
sewardj753ab9d2009-11-05 08:43:38 +00001716 MPI_Status fake_status;
1717 OrigFn fn;
1718 int err, recvcount_actual = 0;
sewardjc3a47092006-02-18 23:13:33 +00001719 VALGRIND_GET_ORIG_FN(fn);
1720 before("Sendrecv");
sewardj753ab9d2009-11-05 08:43:38 +00001721 if (isMSI(status))
1722 status = &fake_status;
njndbf7ca72006-03-31 11:57:59 +00001723 check_mem_is_defined(sendbuf, sendcount, sendtype);
1724 check_mem_is_addressable(recvbuf, recvcount, recvtype);
sewardj753ab9d2009-11-05 08:43:38 +00001725 check_mem_is_addressable_untyped(status, sizeof(*status));
sewardjdc873c02011-07-24 16:02:33 +00001726 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING;
sewardjc3a47092006-02-18 23:13:33 +00001727 CALL_FN_W_12W(err, fn, sendbuf,sendcount,sendtype,dest,sendtag,
1728 recvbuf,recvcount,recvtype,source,recvtag,
1729 comm,status);
sewardjdc873c02011-07-24 16:02:33 +00001730 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING;
sewardj26c60a82012-08-23 19:25:12 +00001731 make_mem_defined_if_addressable_if_success_untyped(err, status, sizeof(*status));
sewardjc3a47092006-02-18 23:13:33 +00001732 if (err == MPI_SUCCESS
1733 && count_from_Status(&recvcount_actual,recvtype,status)) {
njndbf7ca72006-03-31 11:57:59 +00001734 make_mem_defined_if_addressable(recvbuf, recvcount_actual, recvtype);
sewardjc3a47092006-02-18 23:13:33 +00001735 }
1736 after("Sendrecv", err);
1737 return err;
1738}
1739
sewardjc3a47092006-02-18 23:13:33 +00001740
1741/*------------------------------------------------------------*/
1742/*--- ---*/
1743/*--- Sec 3.12, Derived datatypes ---*/
1744/*--- ---*/
1745/*------------------------------------------------------------*/
1746
1747/* --- Address --- */
1748/* Does this have anything worth checking? */
sewardj9c969c32006-03-10 18:37:45 +00001749HAS_NO_WRAPPER(Address)
1750
1751/* --- MPI 2 stuff --- */
1752/* Type_extent, Type_get_contents and Type_get_envelope sometimes get
1753 used intensively by the type walker (walk_type). There's no reason
1754 why they couldn't be properly wrapped if needed, but doing so slows
1755 everything down, so don't bother until needed. */
1756HAS_NO_WRAPPER(Type_extent)
1757HAS_NO_WRAPPER(Type_get_contents)
1758HAS_NO_WRAPPER(Type_get_envelope)
1759
1760/* --- Type_commit --- */
1761int WRAPPER_FOR(PMPI_Type_commit)( MPI_Datatype* ty )
1762{
1763 OrigFn fn;
1764 int err;
1765 VALGRIND_GET_ORIG_FN(fn);
1766 before("Type_commit");
njndbf7ca72006-03-31 11:57:59 +00001767 check_mem_is_defined_untyped(ty, sizeof(*ty));
sewardjdc873c02011-07-24 16:02:33 +00001768 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING;
sewardj9c969c32006-03-10 18:37:45 +00001769 CALL_FN_W_W(err, fn, ty);
sewardjdc873c02011-07-24 16:02:33 +00001770 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING;
sewardj9c969c32006-03-10 18:37:45 +00001771 after("Type_commit", err);
1772 return err;
1773}
1774
1775/* --- Type_free --- */
1776int WRAPPER_FOR(PMPI_Type_free)( MPI_Datatype* ty )
1777{
1778 OrigFn fn;
1779 int err;
1780 VALGRIND_GET_ORIG_FN(fn);
1781 before("Type_free");
njndbf7ca72006-03-31 11:57:59 +00001782 check_mem_is_defined_untyped(ty, sizeof(*ty));
sewardjdc873c02011-07-24 16:02:33 +00001783 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING;
sewardj9c969c32006-03-10 18:37:45 +00001784 CALL_FN_W_W(err, fn, ty);
sewardjdc873c02011-07-24 16:02:33 +00001785 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING;
sewardj9c969c32006-03-10 18:37:45 +00001786 after("Type_free", err);
1787 return err;
1788}
sewardjc3a47092006-02-18 23:13:33 +00001789
1790
1791/*------------------------------------------------------------*/
1792/*--- ---*/
sewardjee346592007-02-08 12:05:03 +00001793/*--- Sec 3.13, Pack and unpack ---*/
1794/*--- ---*/
1795/*------------------------------------------------------------*/
1796
1797/* --- Pack --- */
1798/* pre: must be readable: position
1799 must be readable: (inbuf,incount,datatype)
1800 must be writable: outbuf[0 .. outsize-1]
1801 must be writable: outbuf[*position ..
1802 *position - 1
1803 + however much space PMPI_Pack_size
1804 says we will need]
1805 post: make readable: outbuf[old *position .. new *position]
1806*/
1807int WRAPPER_FOR(PMPI_Pack)( void* inbuf, int incount, MPI_Datatype datatype,
1808 void* outbuf, int outsize,
1809 int* position, MPI_Comm comm )
1810{
1811 OrigFn fn;
1812 int err, szB = 0;
1813 int position_ORIG = *position;
1814 VALGRIND_GET_ORIG_FN(fn);
1815 before("Pack");
1816 /* stay sane */
1817 check_mem_is_defined_untyped(position, sizeof(*position));
1818 /* check input */
1819 check_mem_is_defined(inbuf, incount, datatype);
1820 /* check output area's stated bounds make sense */
1821 check_mem_is_addressable_untyped(outbuf, outsize);
1822 /* check output area's actual used size properly */
1823 err = PMPI_Pack_size( incount, datatype, comm, &szB );
1824 if (err == MPI_SUCCESS && szB > 0) {
1825 check_mem_is_addressable_untyped(
1826 ((char*)outbuf) + position_ORIG, szB
1827 );
1828 }
1829
sewardjdc873c02011-07-24 16:02:33 +00001830 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING;
sewardjee346592007-02-08 12:05:03 +00001831 CALL_FN_W_7W(err, fn, inbuf,incount,datatype, outbuf,outsize,position, comm);
sewardjdc873c02011-07-24 16:02:33 +00001832 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING;
sewardjee346592007-02-08 12:05:03 +00001833
1834 if (err == MPI_SUCCESS && (*position) > position_ORIG) {
1835 /* paint output */
1836 make_mem_defined_if_addressable_untyped(
1837 ((char*)outbuf) + position_ORIG, *position - position_ORIG
1838 );
1839 }
1840 after("Pack", err);
1841 return err;
1842}
1843
1844/* --- Unpack --- */
1845/* pre: must be readable: position
1846 must be writable: (outbuf,outcount,datatype)
1847 must be writable: outbuf[0 .. outsize-1]
1848 must be writable: outbuf[*position ..
1849 *position - 1
1850 + however much space PMPI_Pack_size
1851 says we will need]
1852 post: make readable: (outbuf,outcount,datatype)
1853 and also do a readability check of
1854 inbuf[old *position .. new *position]
1855*/
1856int WRAPPER_FOR(PMPI_Unpack)( void* inbuf, int insize, int* position,
1857 void* outbuf, int outcount, MPI_Datatype datatype,
1858 MPI_Comm comm )
1859{
1860 OrigFn fn;
1861 int err, szB = 0;
1862 int position_ORIG = *position;
1863 VALGRIND_GET_ORIG_FN(fn);
1864 before("Unpack");
1865 /* stay sane */
1866 check_mem_is_defined_untyped(position, sizeof(*position));
1867 /* check output area is accessible */
1868 check_mem_is_addressable(outbuf, outcount, datatype);
1869 /* check input area's stated bounds make sense */
1870 check_mem_is_addressable_untyped(inbuf, insize);
1871 /* check input area's actual used size properly */
1872 err = PMPI_Pack_size( outcount, datatype, comm, &szB );
1873 if (err == MPI_SUCCESS && szB > 0) {
1874 check_mem_is_addressable_untyped(
1875 ((char*)inbuf) + position_ORIG, szB
1876 );
1877 }
1878
sewardjdc873c02011-07-24 16:02:33 +00001879 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING;
sewardjee346592007-02-08 12:05:03 +00001880 CALL_FN_W_7W(err, fn, inbuf,insize,position, outbuf,outcount,datatype, comm);
sewardjdc873c02011-07-24 16:02:33 +00001881 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING;
sewardjee346592007-02-08 12:05:03 +00001882
1883 if (err == MPI_SUCCESS && (*position) > position_ORIG) {
1884 /* recheck input more carefully */
1885 check_mem_is_defined_untyped(
1886 ((char*)inbuf) + position_ORIG, *position - position_ORIG
1887 );
1888 /* paint output */
1889 make_mem_defined_if_addressable( outbuf, outcount, datatype );
1890 }
1891 after("Unpack", err);
1892 return err;
1893}
1894
1895
1896/*------------------------------------------------------------*/
1897/*--- ---*/
sewardjc3a47092006-02-18 23:13:33 +00001898/*--- Sec 4.4, Broadcast ---*/
1899/*--- ---*/
1900/*------------------------------------------------------------*/
1901
1902/* --- Bcast --- */
1903/* pre: must-be-readable (buffer,count,datatype) for rank==root
1904 must-be-writable (buffer,count,datatype) for rank!=root
1905 post: make-readable (buffer,count,datatype) for all
1906
1907 Resulting behaviour is: if root sends uninitialised stuff, then
1908 V complains, but then all ranks, including itself, see the buffer
1909 as initialised after that.
1910*/
1911int WRAPPER_FOR(PMPI_Bcast)(void *buffer, int count,
1912 MPI_Datatype datatype,
1913 int root, MPI_Comm comm)
1914{
1915 OrigFn fn;
1916 int err;
1917 Bool i_am_sender;
1918 VALGRIND_GET_ORIG_FN(fn);
1919 before("Bcast");
1920 i_am_sender = root == comm_rank(comm);
1921 if (i_am_sender) {
njndbf7ca72006-03-31 11:57:59 +00001922 check_mem_is_defined(buffer, count, datatype);
sewardjc3a47092006-02-18 23:13:33 +00001923 } else {
njndbf7ca72006-03-31 11:57:59 +00001924 check_mem_is_addressable(buffer, count, datatype);
sewardjc3a47092006-02-18 23:13:33 +00001925 }
sewardjdc873c02011-07-24 16:02:33 +00001926 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING;
sewardjc3a47092006-02-18 23:13:33 +00001927 CALL_FN_W_5W(err, fn, buffer,count,datatype,root,comm);
sewardjdc873c02011-07-24 16:02:33 +00001928 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING;
njndbf7ca72006-03-31 11:57:59 +00001929 make_mem_defined_if_addressable_if_success(err, buffer, count, datatype);
sewardjc3a47092006-02-18 23:13:33 +00001930 after("Bcast", err);
1931 return err;
1932}
1933
1934
1935/*------------------------------------------------------------*/
1936/*--- ---*/
1937/*--- Sec 4.5, Gather ---*/
1938/*--- ---*/
1939/*------------------------------------------------------------*/
1940
1941/* --- Gather --- */
1942/* JRS 20060217: I don't really understand this. Each process is
1943 going to send sendcount items of type sendtype to the root. So
1944 the root is going to receive comm_size*sendcount items of type
1945 sendtype (right?) So why specify recvcount and recvtype?
1946
1947 Anyway, assuming the MPI Spec is correct (seems likely :-) we have:
1948
1949 pre: (all) must be readable: (sendbuf,sendcount,sendtype)
1950 (root only): must be writable: (recvbuf,recvcount * comm_size,recvtype)
1951 post: (root only): make readable: (recvbuf,recvcount * comm_size,recvtype)
1952*/
1953int WRAPPER_FOR(PMPI_Gather)(
1954 void *sendbuf, int sendcount, MPI_Datatype sendtype,
1955 void *recvbuf, int recvcount, MPI_Datatype recvtype,
1956 int root, MPI_Comm comm)
1957{
1958 OrigFn fn;
1959 int err, me, sz;
1960 VALGRIND_GET_ORIG_FN(fn);
1961 before("Gather");
1962 me = comm_rank(comm);
1963 sz = comm_size(comm);
njndbf7ca72006-03-31 11:57:59 +00001964 check_mem_is_defined(sendbuf, sendcount, sendtype);
sewardjc3a47092006-02-18 23:13:33 +00001965 if (me == root)
njndbf7ca72006-03-31 11:57:59 +00001966 check_mem_is_addressable(recvbuf, recvcount * sz, recvtype);
sewardjdc873c02011-07-24 16:02:33 +00001967 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING;
sewardjc3a47092006-02-18 23:13:33 +00001968 CALL_FN_W_8W(err, fn, sendbuf,sendcount,sendtype,
1969 recvbuf,recvcount,recvtype,
1970 root,comm);
sewardjdc873c02011-07-24 16:02:33 +00001971 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING;
sewardjb727b542006-03-10 21:41:01 +00001972 if (me == root)
njndbf7ca72006-03-31 11:57:59 +00001973 make_mem_defined_if_addressable_if_success(err, recvbuf, recvcount * sz, recvtype);
sewardjc3a47092006-02-18 23:13:33 +00001974 after("Gather", err);
1975 return err;
1976}
1977
1978
1979/*------------------------------------------------------------*/
1980/*--- ---*/
sewardjb727b542006-03-10 21:41:01 +00001981/*--- Sec 4.6, Scatter ---*/
1982/*--- ---*/
1983/*------------------------------------------------------------*/
1984
1985/* pre: (root only): must be readable: (sendbuf,sendcount * comm_size,sendtype)
1986 (all): must be writable: (recvbuf,recvbuf,recvtype)
1987 post: (all): make defined: (recvbuf,recvbuf,recvtype)
1988*/
1989int WRAPPER_FOR(PMPI_Scatter)(
1990 void* sendbuf, int sendcount, MPI_Datatype sendtype,
1991 void* recvbuf, int recvcount, MPI_Datatype recvtype,
1992 int root, MPI_Comm comm)
1993{
1994 OrigFn fn;
1995 int err, me, sz;
1996 VALGRIND_GET_ORIG_FN(fn);
1997 before("Scatter");
1998 me = comm_rank(comm);
1999 sz = comm_size(comm);
njndbf7ca72006-03-31 11:57:59 +00002000 check_mem_is_addressable(recvbuf, recvcount, recvtype);
sewardjb727b542006-03-10 21:41:01 +00002001 if (me == root)
njndbf7ca72006-03-31 11:57:59 +00002002 check_mem_is_defined(sendbuf, sendcount * sz, sendtype);
sewardjdc873c02011-07-24 16:02:33 +00002003 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING;
sewardjb727b542006-03-10 21:41:01 +00002004 CALL_FN_W_8W(err, fn, sendbuf,sendcount,sendtype,
2005 recvbuf,recvcount,recvtype,
2006 root,comm);
sewardjdc873c02011-07-24 16:02:33 +00002007 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING;
njndbf7ca72006-03-31 11:57:59 +00002008 make_mem_defined_if_addressable_if_success(err, recvbuf, recvcount, recvtype);
sewardjb727b542006-03-10 21:41:01 +00002009 after("Scatter", err);
2010 return err;
2011}
2012
2013
2014/*------------------------------------------------------------*/
2015/*--- ---*/
2016/*--- Sec 4.8, All-to-All Scatter/Gather ---*/
2017/*--- ---*/
2018/*------------------------------------------------------------*/
2019
2020/* pre: (all) must be readable: (sendbuf,sendcount * comm_size,sendtype)
2021 (all) must be writable: (recvbuf,recvcount * comm_size,recvtype)
2022 post: (all) make defined: (recvbuf,recvcount * comm_size,recvtype)
2023*/
2024int WRAPPER_FOR(PMPI_Alltoall)(
2025 void* sendbuf, int sendcount, MPI_Datatype sendtype,
2026 void* recvbuf, int recvcount, MPI_Datatype recvtype,
2027 MPI_Comm comm)
2028{
2029 OrigFn fn;
2030 int err, sz;
2031 VALGRIND_GET_ORIG_FN(fn);
2032 before("Alltoall");
2033 sz = comm_size(comm);
njndbf7ca72006-03-31 11:57:59 +00002034 check_mem_is_defined(sendbuf, sendcount * sz, sendtype);
2035 check_mem_is_addressable(recvbuf, recvcount * sz, recvtype);
sewardjdc873c02011-07-24 16:02:33 +00002036 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING;
sewardjb727b542006-03-10 21:41:01 +00002037 CALL_FN_W_7W(err, fn, sendbuf,sendcount,sendtype,
2038 recvbuf,recvcount,recvtype,
2039 comm);
sewardjdc873c02011-07-24 16:02:33 +00002040 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING;
njndbf7ca72006-03-31 11:57:59 +00002041 make_mem_defined_if_addressable_if_success(err, recvbuf, recvcount * sz, recvtype);
sewardjb727b542006-03-10 21:41:01 +00002042 after("Alltoall", err);
2043 return err;
2044}
2045
2046
2047/*------------------------------------------------------------*/
2048/*--- ---*/
sewardjc3a47092006-02-18 23:13:33 +00002049/*--- Sec 4.9, Global Reduction Operations ---*/
2050/*--- ---*/
2051/*------------------------------------------------------------*/
2052
2053/* --- Reduce --- */
2054/* rd: (sendbuf,count,datatype) for all
2055 wr: (recvbuf,count,datatype) but only for rank == root
2056*/
2057int WRAPPER_FOR(PMPI_Reduce)(void *sendbuf, void *recvbuf,
2058 int count,
2059 MPI_Datatype datatype, MPI_Op op,
2060 int root, MPI_Comm comm)
2061{
2062 OrigFn fn;
2063 int err;
2064 Bool i_am_root;
2065 VALGRIND_GET_ORIG_FN(fn);
2066 before("Reduce");
2067 i_am_root = root == comm_rank(comm);
njndbf7ca72006-03-31 11:57:59 +00002068 check_mem_is_defined(sendbuf, count, datatype);
sewardjc3a47092006-02-18 23:13:33 +00002069 if (i_am_root)
njndbf7ca72006-03-31 11:57:59 +00002070 check_mem_is_addressable(recvbuf, count, datatype);
sewardjdc873c02011-07-24 16:02:33 +00002071 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING;
sewardjc3a47092006-02-18 23:13:33 +00002072 CALL_FN_W_7W(err, fn, sendbuf,recvbuf,count,datatype,op,root,comm);
sewardjdc873c02011-07-24 16:02:33 +00002073 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING;
sewardjc3a47092006-02-18 23:13:33 +00002074 if (i_am_root)
njndbf7ca72006-03-31 11:57:59 +00002075 make_mem_defined_if_addressable_if_success(err, recvbuf, count, datatype);
sewardjc3a47092006-02-18 23:13:33 +00002076 after("Reduce", err);
2077 return err;
2078}
2079
2080
2081/* --- Allreduce --- */
2082/* rd: (sendbuf,count,datatype) for all
2083 wr: (recvbuf,count,datatype) for all
2084*/
2085int WRAPPER_FOR(PMPI_Allreduce)(void *sendbuf, void *recvbuf,
2086 int count,
2087 MPI_Datatype datatype, MPI_Op op,
2088 MPI_Comm comm)
2089{
2090 OrigFn fn;
2091 int err;
2092 VALGRIND_GET_ORIG_FN(fn);
2093 before("Allreduce");
njndbf7ca72006-03-31 11:57:59 +00002094 check_mem_is_defined(sendbuf, count, datatype);
2095 check_mem_is_addressable(recvbuf, count, datatype);
sewardjdc873c02011-07-24 16:02:33 +00002096 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING;
sewardjc3a47092006-02-18 23:13:33 +00002097 CALL_FN_W_6W(err, fn, sendbuf,recvbuf,count,datatype,op,comm);
sewardjdc873c02011-07-24 16:02:33 +00002098 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING;
njndbf7ca72006-03-31 11:57:59 +00002099 make_mem_defined_if_addressable_if_success(err, recvbuf, count, datatype);
sewardjc3a47092006-02-18 23:13:33 +00002100 after("Allreduce", err);
2101 return err;
2102}
2103
2104
2105/* --- Op_create --- */
2106/* This is a bit dubious. I suppose it takes 'function' and
2107 writes something at *op, but who knows what an MPI_Op is?
2108 Can we safely do 'sizeof' on it? */
2109int WRAPPER_FOR(PMPI_Op_create)( MPI_User_function* function,
2110 int commute,
2111 MPI_Op* op )
2112{
2113 OrigFn fn;
2114 int err;
2115 VALGRIND_GET_ORIG_FN(fn);
2116 before("Op_create");
njndbf7ca72006-03-31 11:57:59 +00002117 check_mem_is_addressable_untyped(op, sizeof(*op));
sewardjdc873c02011-07-24 16:02:33 +00002118 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING;
sewardjc3a47092006-02-18 23:13:33 +00002119 CALL_FN_W_WWW(err, fn, function,commute,op);
sewardjdc873c02011-07-24 16:02:33 +00002120 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING;
njndbf7ca72006-03-31 11:57:59 +00002121 make_mem_defined_if_addressable_if_success_untyped(err, op, sizeof(*op));
sewardjc3a47092006-02-18 23:13:33 +00002122 after("Op_create", err);
2123 return err;
2124}
2125
2126
2127/*------------------------------------------------------------*/
2128/*--- ---*/
2129/*--- Sec 5.4, Communicator management ---*/
2130/*--- ---*/
2131/*------------------------------------------------------------*/
2132
2133/* Hardly seems worth wrapping Comm_rank and Comm_size, but
2134 since it's done now .. */
2135
sewardj9c969c32006-03-10 18:37:45 +00002136/* --- Comm_create --- */
2137/* Let normal memcheck tracking handle this. */
2138int WRAPPER_FOR(PMPI_Comm_create)(MPI_Comm comm, MPI_Group group,
2139 MPI_Comm* newcomm)
2140{
2141 OrigFn fn;
2142 int err;
2143 VALGRIND_GET_ORIG_FN(fn);
2144 before("Comm_create");
sewardjdc873c02011-07-24 16:02:33 +00002145 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING;
sewardj9c969c32006-03-10 18:37:45 +00002146 CALL_FN_W_WWW(err, fn, comm,group,newcomm);
sewardjdc873c02011-07-24 16:02:33 +00002147 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING;
sewardj9c969c32006-03-10 18:37:45 +00002148 after("Comm_create", err);
2149 return err;
2150}
2151
2152/* --- Comm_dup --- */
2153/* Let normal memcheck tracking handle this. */
2154int WRAPPER_FOR(PMPI_Comm_dup)(MPI_Comm comm, MPI_Comm* newcomm)
2155{
2156 OrigFn fn;
2157 int err;
2158 VALGRIND_GET_ORIG_FN(fn);
2159 before("Comm_dup");
sewardjdc873c02011-07-24 16:02:33 +00002160 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING;
sewardj9c969c32006-03-10 18:37:45 +00002161 CALL_FN_W_WW(err, fn, comm,newcomm);
sewardjdc873c02011-07-24 16:02:33 +00002162 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING;
sewardj9c969c32006-03-10 18:37:45 +00002163 after("Comm_dup", err);
2164 return err;
2165}
2166
2167/* --- Comm_free --- */
2168/* Let normal memcheck tracking handle this. */
2169int WRAPPER_FOR(PMPI_Comm_free)(MPI_Comm* comm)
2170{
2171 OrigFn fn;
2172 int err;
2173 VALGRIND_GET_ORIG_FN(fn);
2174 before("Comm_free");
sewardjdc873c02011-07-24 16:02:33 +00002175 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING;
sewardj9c969c32006-03-10 18:37:45 +00002176 CALL_FN_W_W(err, fn, comm);
sewardjdc873c02011-07-24 16:02:33 +00002177 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING;
sewardj9c969c32006-03-10 18:37:45 +00002178 after("Comm_free", err);
2179 return err;
2180}
2181
sewardjc3a47092006-02-18 23:13:33 +00002182/* --- Comm_rank --- */
2183/* wr: (rank, sizeof(*rank)) */
2184int WRAPPER_FOR(PMPI_Comm_rank)(MPI_Comm comm, int *rank)
2185{
2186 OrigFn fn;
2187 int err;
2188 VALGRIND_GET_ORIG_FN(fn);
2189 before("Comm_rank");
njndbf7ca72006-03-31 11:57:59 +00002190 check_mem_is_addressable_untyped(rank, sizeof(*rank));
sewardjdc873c02011-07-24 16:02:33 +00002191 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING;
sewardjc3a47092006-02-18 23:13:33 +00002192 CALL_FN_W_WW(err, fn, comm,rank);
sewardjdc873c02011-07-24 16:02:33 +00002193 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING;
njndbf7ca72006-03-31 11:57:59 +00002194 make_mem_defined_if_addressable_if_success_untyped(err, rank, sizeof(*rank));
sewardjc3a47092006-02-18 23:13:33 +00002195 after("Comm_rank", err);
2196 return err;
2197}
2198
sewardjc3a47092006-02-18 23:13:33 +00002199/* --- Comm_size --- */
2200/* wr: (size, sizeof(*size)) */
2201int WRAPPER_FOR(PMPI_Comm_size)(MPI_Comm comm, int *size)
2202{
2203 OrigFn fn;
2204 int err;
2205 VALGRIND_GET_ORIG_FN(fn);
2206 before("Comm_size");
njndbf7ca72006-03-31 11:57:59 +00002207 check_mem_is_addressable_untyped(size, sizeof(*size));
sewardjdc873c02011-07-24 16:02:33 +00002208 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING;
sewardjc3a47092006-02-18 23:13:33 +00002209 CALL_FN_W_WW(err, fn, comm,size);
sewardjdc873c02011-07-24 16:02:33 +00002210 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING;
njndbf7ca72006-03-31 11:57:59 +00002211 make_mem_defined_if_addressable_if_success_untyped(err, size, sizeof(*size));
sewardjc3a47092006-02-18 23:13:33 +00002212 after("Comm_size", err);
2213 return err;
2214}
2215
2216
2217/*------------------------------------------------------------*/
2218/*--- ---*/
2219/*--- Sec 5.7, Caching ---*/
2220/*--- ---*/
2221/*------------------------------------------------------------*/
2222
sewardjc3a47092006-02-18 23:13:33 +00002223
2224/*------------------------------------------------------------*/
2225/*--- ---*/
sewardj7d3f4bb2006-03-08 15:27:37 +00002226/*--- Sec 7.3, Error codes and classes ---*/
2227/*--- ---*/
2228/*------------------------------------------------------------*/
2229
2230/* --- Error_string --- */
sewardj9c969c32006-03-10 18:37:45 +00002231int WRAPPER_FOR(PMPI_Error_string)( int errorcode, char* string,
2232 int* resultlen )
sewardj7d3f4bb2006-03-08 15:27:37 +00002233{
2234 OrigFn fn;
2235 int err;
2236 VALGRIND_GET_ORIG_FN(fn);
2237 before("Error_string");
njndbf7ca72006-03-31 11:57:59 +00002238 check_mem_is_addressable_untyped(resultlen, sizeof(int));
2239 check_mem_is_addressable_untyped(string, MPI_MAX_ERROR_STRING);
sewardjdc873c02011-07-24 16:02:33 +00002240 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING;
sewardj7d3f4bb2006-03-08 15:27:37 +00002241 CALL_FN_W_WWW(err, fn, errorcode,string,resultlen);
sewardjdc873c02011-07-24 16:02:33 +00002242 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING;
sewardj7d3f4bb2006-03-08 15:27:37 +00002243 /* Don't bother to paint the result; we assume the real function
2244 will have filled it with defined characters :-) */
2245 after("Error_string", err);
2246 return err;
2247}
2248
2249
2250/*------------------------------------------------------------*/
2251/*--- ---*/
sewardjc3a47092006-02-18 23:13:33 +00002252/*--- Sec 7.5, Startup ---*/
2253/*--- ---*/
2254/*------------------------------------------------------------*/
2255
2256/* --- Init --- */
2257/* rd: *argc, *argv[0 .. *argc-1] */
sewardjd465d992006-10-17 01:46:55 +00002258long WRAPPER_FOR(PMPI_Init)(int *argc, char ***argv)
sewardjc3a47092006-02-18 23:13:33 +00002259{
2260 OrigFn fn;
2261 int err;
2262 VALGRIND_GET_ORIG_FN(fn);
2263 before("Init");
sewardj1ba0e9b2008-12-08 10:27:31 +00002264 if (argc) {
2265 check_mem_is_defined_untyped(argc, sizeof(int));
2266 }
2267 if (argc && argv) {
2268 check_mem_is_defined_untyped(*argv, *argc * sizeof(char**));
2269 }
sewardjdc873c02011-07-24 16:02:33 +00002270 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING;
sewardjc3a47092006-02-18 23:13:33 +00002271 CALL_FN_W_WW(err, fn, argc,argv);
sewardjdc873c02011-07-24 16:02:33 +00002272 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING;
sewardjc3a47092006-02-18 23:13:33 +00002273 after("Init", err);
sewardjd465d992006-10-17 01:46:55 +00002274 if (opt_initkludge)
2275 return (long)(void*)&mpiwrap_walk_type_EXTERNALLY_VISIBLE;
2276 else
2277 return (long)err;
sewardjc3a47092006-02-18 23:13:33 +00002278}
2279
2280/* --- Initialized --- */
2281int WRAPPER_FOR(PMPI_Initialized)(int* flag)
2282{
2283 OrigFn fn;
2284 int err;
2285 VALGRIND_GET_ORIG_FN(fn);
2286 before("Initialized");
njndbf7ca72006-03-31 11:57:59 +00002287 check_mem_is_addressable_untyped(flag, sizeof(int));
sewardjdc873c02011-07-24 16:02:33 +00002288 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING;
sewardjc3a47092006-02-18 23:13:33 +00002289 CALL_FN_W_W(err, fn, flag);
sewardjdc873c02011-07-24 16:02:33 +00002290 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING;
njndbf7ca72006-03-31 11:57:59 +00002291 make_mem_defined_if_addressable_if_success_untyped(err, flag, sizeof(int));
sewardjc3a47092006-02-18 23:13:33 +00002292 after("Initialized", err);
2293 return err;
2294}
2295
2296/* --- Finalize --- */
2297int WRAPPER_FOR(PMPI_Finalize)(void)
2298{
2299 OrigFn fn;
2300 int err;
2301 VALGRIND_GET_ORIG_FN(fn);
2302 before("Finalize");
sewardjdc873c02011-07-24 16:02:33 +00002303 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING;
sewardjc3a47092006-02-18 23:13:33 +00002304 CALL_FN_W_v(err, fn);
sewardjdc873c02011-07-24 16:02:33 +00002305 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING;
sewardjc3a47092006-02-18 23:13:33 +00002306 after("Finalize", err);
2307 return err;
2308}
2309
2310
2311/*------------------------------------------------------------*/
2312/*--- ---*/
sewardj63daa8a2006-03-09 19:08:20 +00002313/*--- Default wrappers for all remaining functions ---*/
sewardjc3a47092006-02-18 23:13:33 +00002314/*--- ---*/
2315/*------------------------------------------------------------*/
2316
sewardj9c969c32006-03-10 18:37:45 +00002317/* Boilerplate for default wrappers. */
sewardj63daa8a2006-03-09 19:08:20 +00002318#define DEFAULT_WRAPPER_PREAMBLE(basename) \
2319 OrigFn fn; \
2320 UWord res; \
sewardj0d17f242006-03-28 01:02:38 +00002321 static int complaints = 1; \
sewardj63daa8a2006-03-09 19:08:20 +00002322 VALGRIND_GET_ORIG_FN(fn); \
2323 before(#basename); \
2324 if (opt_missing >= 2) { \
2325 barf("no wrapper for PMPI_" #basename \
2326 ",\n\t\t\t and you have " \
2327 "requested strict checking"); \
2328 } \
2329 if (opt_missing == 1 && complaints > 0) { \
2330 fprintf(stderr, "%s %5d: warning: no wrapper " \
2331 "for PMPI_" #basename "\n", \
2332 preamble, my_pid); \
2333 complaints--; \
2334 } \
2335
2336#define DEFAULT_WRAPPER_W_0W(basename) \
2337 UWord WRAPPER_FOR(PMPI_##basename)( void ) \
2338 { \
2339 DEFAULT_WRAPPER_PREAMBLE(basename) \
sewardjdc873c02011-07-24 16:02:33 +00002340 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING; \
sewardj63daa8a2006-03-09 19:08:20 +00002341 CALL_FN_W_v(res, fn); \
sewardjdc873c02011-07-24 16:02:33 +00002342 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING; \
sewardj63daa8a2006-03-09 19:08:20 +00002343 return res; \
2344 }
2345
2346#define DEFAULT_WRAPPER_W_1W(basename) \
2347 UWord WRAPPER_FOR(PMPI_##basename)( UWord a1 ) \
2348 { \
2349 DEFAULT_WRAPPER_PREAMBLE(basename) \
sewardjdc873c02011-07-24 16:02:33 +00002350 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING; \
sewardj63daa8a2006-03-09 19:08:20 +00002351 CALL_FN_W_W(res, fn, a1); \
sewardjdc873c02011-07-24 16:02:33 +00002352 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING; \
sewardj63daa8a2006-03-09 19:08:20 +00002353 return res; \
2354 }
2355
2356#define DEFAULT_WRAPPER_W_2W(basename) \
2357 UWord WRAPPER_FOR(PMPI_##basename)( UWord a1, UWord a2 ) \
2358 { \
2359 DEFAULT_WRAPPER_PREAMBLE(basename) \
sewardjdc873c02011-07-24 16:02:33 +00002360 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING; \
sewardj63daa8a2006-03-09 19:08:20 +00002361 CALL_FN_W_WW(res, fn, a1,a2); \
sewardjdc873c02011-07-24 16:02:33 +00002362 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING; \
sewardj63daa8a2006-03-09 19:08:20 +00002363 return res; \
2364 }
2365
2366#define DEFAULT_WRAPPER_W_3W(basename) \
2367 UWord WRAPPER_FOR(PMPI_##basename) \
2368 ( UWord a1, UWord a2, UWord a3 ) \
2369 { \
2370 DEFAULT_WRAPPER_PREAMBLE(basename) \
sewardjdc873c02011-07-24 16:02:33 +00002371 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING; \
sewardj63daa8a2006-03-09 19:08:20 +00002372 CALL_FN_W_WWW(res, fn, a1,a2,a3); \
sewardjdc873c02011-07-24 16:02:33 +00002373 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING; \
sewardj63daa8a2006-03-09 19:08:20 +00002374 return res; \
2375 }
2376
2377#define DEFAULT_WRAPPER_W_4W(basename) \
2378 UWord WRAPPER_FOR(PMPI_##basename) \
2379 ( UWord a1, UWord a2, UWord a3, UWord a4 ) \
2380 { \
2381 DEFAULT_WRAPPER_PREAMBLE(basename) \
sewardjdc873c02011-07-24 16:02:33 +00002382 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING; \
sewardj63daa8a2006-03-09 19:08:20 +00002383 CALL_FN_W_WWWW(res, fn, a1,a2,a3,a4); \
sewardjdc873c02011-07-24 16:02:33 +00002384 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING; \
sewardj63daa8a2006-03-09 19:08:20 +00002385 return res; \
2386 }
2387
2388#define DEFAULT_WRAPPER_W_5W(basename) \
2389 UWord WRAPPER_FOR(PMPI_##basename) \
2390 ( UWord a1, UWord a2, UWord a3, UWord a4, UWord a5 ) \
2391 { \
2392 DEFAULT_WRAPPER_PREAMBLE(basename) \
sewardjdc873c02011-07-24 16:02:33 +00002393 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING; \
sewardj63daa8a2006-03-09 19:08:20 +00002394 CALL_FN_W_5W(res, fn, a1,a2,a3,a4,a5); \
sewardjdc873c02011-07-24 16:02:33 +00002395 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING; \
sewardj63daa8a2006-03-09 19:08:20 +00002396 return res; \
2397 }
2398
2399#define DEFAULT_WRAPPER_W_6W(basename) \
2400 UWord WRAPPER_FOR(PMPI_##basename) \
2401 ( UWord a1, UWord a2, UWord a3, UWord a4, UWord a5, \
2402 UWord a6 ) \
2403 { \
2404 DEFAULT_WRAPPER_PREAMBLE(basename) \
sewardjdc873c02011-07-24 16:02:33 +00002405 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING; \
sewardj63daa8a2006-03-09 19:08:20 +00002406 CALL_FN_W_6W(res, fn, a1,a2,a3,a4,a5,a6); \
sewardjdc873c02011-07-24 16:02:33 +00002407 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING; \
sewardj63daa8a2006-03-09 19:08:20 +00002408 return res; \
2409 }
2410
2411#define DEFAULT_WRAPPER_W_7W(basename) \
2412 UWord WRAPPER_FOR(PMPI_##basename) \
2413 ( UWord a1, UWord a2, UWord a3, UWord a4, UWord a5, \
2414 UWord a6, UWord a7 ) \
2415 { \
2416 DEFAULT_WRAPPER_PREAMBLE(basename) \
sewardjdc873c02011-07-24 16:02:33 +00002417 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING; \
sewardj63daa8a2006-03-09 19:08:20 +00002418 CALL_FN_W_7W(res, fn, a1,a2,a3,a4,a5,a6,a7); \
sewardjdc873c02011-07-24 16:02:33 +00002419 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING; \
sewardj63daa8a2006-03-09 19:08:20 +00002420 return res; \
2421 }
2422
2423#define DEFAULT_WRAPPER_W_8W(basename) \
2424 UWord WRAPPER_FOR(PMPI_##basename) \
2425 ( UWord a1, UWord a2, UWord a3, UWord a4, UWord a5, \
2426 UWord a6, UWord a7, UWord a8 ) \
2427 { \
2428 DEFAULT_WRAPPER_PREAMBLE(basename) \
sewardjdc873c02011-07-24 16:02:33 +00002429 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING; \
sewardj63daa8a2006-03-09 19:08:20 +00002430 CALL_FN_W_8W(res, fn, a1,a2,a3,a4,a5,a6,a7,a8); \
sewardjdc873c02011-07-24 16:02:33 +00002431 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING; \
sewardj63daa8a2006-03-09 19:08:20 +00002432 return res; \
2433 }
2434
2435#define DEFAULT_WRAPPER_W_9W(basename) \
2436 UWord WRAPPER_FOR(PMPI_##basename) \
2437 ( UWord a1, UWord a2, UWord a3, UWord a4, UWord a5, \
2438 UWord a6, UWord a7, UWord a8, UWord a9 ) \
2439 { \
2440 DEFAULT_WRAPPER_PREAMBLE(basename) \
sewardjdc873c02011-07-24 16:02:33 +00002441 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING; \
sewardj63daa8a2006-03-09 19:08:20 +00002442 CALL_FN_W_9W(res, fn, a1,a2,a3,a4,a5,a6,a7,a8,a9); \
sewardjdc873c02011-07-24 16:02:33 +00002443 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING; \
sewardj63daa8a2006-03-09 19:08:20 +00002444 return res; \
2445 }
2446
2447#define DEFAULT_WRAPPER_W_10W(basename) \
2448 UWord WRAPPER_FOR(PMPI_##basename) \
2449 ( UWord a1, UWord a2, UWord a3, UWord a4, UWord a5, \
2450 UWord a6, UWord a7, UWord a8, UWord a9, UWord a10 ) \
2451 { \
2452 DEFAULT_WRAPPER_PREAMBLE(basename) \
sewardjdc873c02011-07-24 16:02:33 +00002453 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING; \
sewardj63daa8a2006-03-09 19:08:20 +00002454 CALL_FN_W_10W(res, fn, a1,a2,a3,a4,a5,a6,a7,a8,a9,a10); \
sewardjdc873c02011-07-24 16:02:33 +00002455 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING; \
sewardj63daa8a2006-03-09 19:08:20 +00002456 return res; \
2457 }
2458
2459#define DEFAULT_WRAPPER_W_12W(basename) \
2460 UWord WRAPPER_FOR(PMPI_##basename) \
2461 ( UWord a1, UWord a2, UWord a3, UWord a4, UWord a5, \
2462 UWord a6, UWord a7, UWord a8, UWord a9, UWord a10, \
2463 UWord a11, UWord a12 ) \
2464 { \
2465 DEFAULT_WRAPPER_PREAMBLE(basename) \
sewardjdc873c02011-07-24 16:02:33 +00002466 if (cONFIG_DER) VALGRIND_DISABLE_ERROR_REPORTING; \
sewardj63daa8a2006-03-09 19:08:20 +00002467 CALL_FN_W_12W(res, fn, a1,a2,a3,a4,a5,a6, \
2468 a7,a8,a9,a10,a11,a12); \
sewardjdc873c02011-07-24 16:02:33 +00002469 if (cONFIG_DER) VALGRIND_ENABLE_ERROR_REPORTING; \
sewardj63daa8a2006-03-09 19:08:20 +00002470 return res; \
2471 }
2472
2473
2474/* Canned summary of MPI-1.1/MPI-2 entry points, as derived from mpi.h
2475 from Open MPI svn rev 9191 (somewhere between Open MPI versions
2476 1.0.1 and 1.1.0). */
2477
2478/* If a function is commented out in this list, it's because it has a
2479 proper wrapper written elsewhere (above here). */
2480
2481DEFAULT_WRAPPER_W_2W(Abort)
2482DEFAULT_WRAPPER_W_9W(Accumulate)
2483DEFAULT_WRAPPER_W_1W(Add_error_class)
2484DEFAULT_WRAPPER_W_2W(Add_error_code)
2485DEFAULT_WRAPPER_W_2W(Add_error_string)
sewardj9c969c32006-03-10 18:37:45 +00002486/* DEFAULT_WRAPPER_W_2W(Address) */
sewardj63daa8a2006-03-09 19:08:20 +00002487DEFAULT_WRAPPER_W_7W(Allgather)
2488DEFAULT_WRAPPER_W_8W(Allgatherv)
2489DEFAULT_WRAPPER_W_3W(Alloc_mem)
2490/* DEFAULT_WRAPPER_W_6W(Allreduce) */
sewardjb727b542006-03-10 21:41:01 +00002491/* DEFAULT_WRAPPER_W_7W(Alltoall) */
sewardj63daa8a2006-03-09 19:08:20 +00002492DEFAULT_WRAPPER_W_9W(Alltoallv)
2493DEFAULT_WRAPPER_W_9W(Alltoallw)
2494DEFAULT_WRAPPER_W_2W(Attr_delete)
2495DEFAULT_WRAPPER_W_4W(Attr_get)
2496DEFAULT_WRAPPER_W_3W(Attr_put)
2497DEFAULT_WRAPPER_W_1W(Barrier)
2498/* DEFAULT_WRAPPER_W_5W(Bcast) */
sewardj9c969c32006-03-10 18:37:45 +00002499/* DEFAULT_WRAPPER_W_6W(Bsend) */
sewardj63daa8a2006-03-09 19:08:20 +00002500DEFAULT_WRAPPER_W_7W(Bsend_init)
2501DEFAULT_WRAPPER_W_2W(Buffer_attach)
2502DEFAULT_WRAPPER_W_2W(Buffer_detach)
sewardjb727b542006-03-10 21:41:01 +00002503/* DEFAULT_WRAPPER_W_1W(Cancel) */
sewardj63daa8a2006-03-09 19:08:20 +00002504DEFAULT_WRAPPER_W_4W(Cart_coords)
2505DEFAULT_WRAPPER_W_6W(Cart_create)
2506DEFAULT_WRAPPER_W_5W(Cart_get)
2507DEFAULT_WRAPPER_W_5W(Cart_map)
2508DEFAULT_WRAPPER_W_3W(Cart_rank)
2509DEFAULT_WRAPPER_W_5W(Cart_shift)
2510DEFAULT_WRAPPER_W_3W(Cart_sub)
2511DEFAULT_WRAPPER_W_2W(Cartdim_get)
2512DEFAULT_WRAPPER_W_1W(Close_port)
2513DEFAULT_WRAPPER_W_5W(Comm_accept)
2514DEFAULT_WRAPPER_W_1W(Comm_c2f)
2515DEFAULT_WRAPPER_W_2W(Comm_call_errhandler)
2516DEFAULT_WRAPPER_W_3W(Comm_compare)
2517DEFAULT_WRAPPER_W_5W(Comm_connect)
2518DEFAULT_WRAPPER_W_2W(Comm_create_errhandler)
2519DEFAULT_WRAPPER_W_4W(Comm_create_keyval)
sewardj9c969c32006-03-10 18:37:45 +00002520/* DEFAULT_WRAPPER_W_3W(Comm_create) */
sewardj63daa8a2006-03-09 19:08:20 +00002521DEFAULT_WRAPPER_W_2W(Comm_delete_attr)
2522DEFAULT_WRAPPER_W_1W(Comm_disconnect)
sewardj9c969c32006-03-10 18:37:45 +00002523/* DEFAULT_WRAPPER_W_2W(Comm_dup) */
sewardj63daa8a2006-03-09 19:08:20 +00002524DEFAULT_WRAPPER_W_1W(Comm_f2c)
2525DEFAULT_WRAPPER_W_1W(Comm_free_keyval)
sewardj9c969c32006-03-10 18:37:45 +00002526/* DEFAULT_WRAPPER_W_1W(Comm_free) */
sewardj63daa8a2006-03-09 19:08:20 +00002527DEFAULT_WRAPPER_W_4W(Comm_get_attr)
2528DEFAULT_WRAPPER_W_2W(Comm_get_errhandler)
2529DEFAULT_WRAPPER_W_3W(Comm_get_name)
2530DEFAULT_WRAPPER_W_1W(Comm_get_parent)
2531DEFAULT_WRAPPER_W_2W(Comm_group)
2532DEFAULT_WRAPPER_W_2W(Comm_join)
2533/* DEFAULT_WRAPPER_W_2W(Comm_rank) */
2534DEFAULT_WRAPPER_W_2W(Comm_remote_group)
2535DEFAULT_WRAPPER_W_2W(Comm_remote_size)
2536DEFAULT_WRAPPER_W_3W(Comm_set_attr)
2537DEFAULT_WRAPPER_W_2W(Comm_set_errhandler)
2538DEFAULT_WRAPPER_W_2W(Comm_set_name)
2539/* DEFAULT_WRAPPER_W_2W(Comm_size) */
2540DEFAULT_WRAPPER_W_8W(Comm_spawn)
2541DEFAULT_WRAPPER_W_9W(Comm_spawn_multiple)
2542DEFAULT_WRAPPER_W_4W(Comm_split)
2543DEFAULT_WRAPPER_W_2W(Comm_test_inter)
2544DEFAULT_WRAPPER_W_3W(Dims_create)
2545DEFAULT_WRAPPER_W_1W(Errhandler_c2f)
2546DEFAULT_WRAPPER_W_2W(Errhandler_create)
2547DEFAULT_WRAPPER_W_1W(Errhandler_f2c)
2548DEFAULT_WRAPPER_W_1W(Errhandler_free)
2549DEFAULT_WRAPPER_W_2W(Errhandler_get)
2550DEFAULT_WRAPPER_W_2W(Errhandler_set)
2551DEFAULT_WRAPPER_W_2W(Error_class)
2552/* DEFAULT_WRAPPER_W_3W(Error_string) */
2553DEFAULT_WRAPPER_W_6W(Exscan)
2554DEFAULT_WRAPPER_W_1W(File_c2f)
2555DEFAULT_WRAPPER_W_1W(File_f2c)
2556DEFAULT_WRAPPER_W_2W(File_call_errhandler)
2557DEFAULT_WRAPPER_W_2W(File_create_errhandler)
2558DEFAULT_WRAPPER_W_2W(File_set_errhandler)
2559DEFAULT_WRAPPER_W_2W(File_get_errhandler)
2560DEFAULT_WRAPPER_W_5W(File_open)
2561DEFAULT_WRAPPER_W_1W(File_close)
2562DEFAULT_WRAPPER_W_2W(File_delete)
2563DEFAULT_WRAPPER_W_2W(File_set_size)
2564DEFAULT_WRAPPER_W_2W(File_preallocate)
2565DEFAULT_WRAPPER_W_2W(File_get_size)
2566DEFAULT_WRAPPER_W_2W(File_get_group)
2567DEFAULT_WRAPPER_W_2W(File_get_amode)
2568DEFAULT_WRAPPER_W_2W(File_set_info)
2569DEFAULT_WRAPPER_W_2W(File_get_info)
2570DEFAULT_WRAPPER_W_6W(File_set_view)
2571DEFAULT_WRAPPER_W_5W(File_get_view)
2572DEFAULT_WRAPPER_W_6W(File_read_at)
2573DEFAULT_WRAPPER_W_6W(File_read_at_all)
2574DEFAULT_WRAPPER_W_6W(File_write_at)
2575DEFAULT_WRAPPER_W_6W(File_write_at_all)
2576DEFAULT_WRAPPER_W_6W(File_iread_at)
2577DEFAULT_WRAPPER_W_6W(File_iwrite_at)
2578DEFAULT_WRAPPER_W_5W(File_read)
2579DEFAULT_WRAPPER_W_5W(File_read_all)
2580DEFAULT_WRAPPER_W_5W(File_write)
2581DEFAULT_WRAPPER_W_5W(File_write_all)
2582DEFAULT_WRAPPER_W_5W(File_iread)
2583DEFAULT_WRAPPER_W_5W(File_iwrite)
2584DEFAULT_WRAPPER_W_3W(File_seek)
2585DEFAULT_WRAPPER_W_2W(File_get_position)
2586DEFAULT_WRAPPER_W_3W(File_get_byte_offset)
2587DEFAULT_WRAPPER_W_5W(File_read_shared)
2588DEFAULT_WRAPPER_W_5W(File_write_shared)
2589DEFAULT_WRAPPER_W_5W(File_iread_shared)
2590DEFAULT_WRAPPER_W_5W(File_iwrite_shared)
2591DEFAULT_WRAPPER_W_5W(File_read_ordered)
2592DEFAULT_WRAPPER_W_5W(File_write_ordered)
2593DEFAULT_WRAPPER_W_3W(File_seek_shared)
2594DEFAULT_WRAPPER_W_2W(File_get_position_shared)
2595DEFAULT_WRAPPER_W_5W(File_read_at_all_begin)
2596DEFAULT_WRAPPER_W_3W(File_read_at_all_end)
2597DEFAULT_WRAPPER_W_5W(File_write_at_all_begin)
2598DEFAULT_WRAPPER_W_3W(File_write_at_all_end)
2599DEFAULT_WRAPPER_W_4W(File_read_all_begin)
2600DEFAULT_WRAPPER_W_3W(File_read_all_end)
2601DEFAULT_WRAPPER_W_4W(File_write_all_begin)
2602DEFAULT_WRAPPER_W_3W(File_write_all_end)
2603DEFAULT_WRAPPER_W_4W(File_read_ordered_begin)
2604DEFAULT_WRAPPER_W_3W(File_read_ordered_end)
2605DEFAULT_WRAPPER_W_4W(File_write_ordered_begin)
2606DEFAULT_WRAPPER_W_3W(File_write_ordered_end)
2607DEFAULT_WRAPPER_W_3W(File_get_type_extent)
2608DEFAULT_WRAPPER_W_2W(File_set_atomicity)
2609DEFAULT_WRAPPER_W_2W(File_get_atomicity)
2610DEFAULT_WRAPPER_W_1W(File_sync)
2611/* DEFAULT_WRAPPER_W_0W(Finalize) */
2612DEFAULT_WRAPPER_W_1W(Finalized)
2613DEFAULT_WRAPPER_W_1W(Free_mem)
2614/* DEFAULT_WRAPPER_W_8W(Gather) */
2615DEFAULT_WRAPPER_W_9W(Gatherv)
2616DEFAULT_WRAPPER_W_2W(Get_address)
sewardj9c969c32006-03-10 18:37:45 +00002617/* DEFAULT_WRAPPER_W_3W(Get_count) */
sewardj63daa8a2006-03-09 19:08:20 +00002618DEFAULT_WRAPPER_W_3W(Get_elements)
2619DEFAULT_WRAPPER_W_8W(Get)
2620DEFAULT_WRAPPER_W_2W(Get_processor_name)
2621DEFAULT_WRAPPER_W_2W(Get_version)
2622DEFAULT_WRAPPER_W_6W(Graph_create)
2623DEFAULT_WRAPPER_W_5W(Graph_get)
2624DEFAULT_WRAPPER_W_5W(Graph_map)
2625DEFAULT_WRAPPER_W_3W(Graph_neighbors_count)
2626DEFAULT_WRAPPER_W_4W(Graph_neighbors)
2627DEFAULT_WRAPPER_W_3W(Graphdims_get)
2628DEFAULT_WRAPPER_W_1W(Grequest_complete)
2629DEFAULT_WRAPPER_W_5W(Grequest_start)
2630DEFAULT_WRAPPER_W_1W(Group_c2f)
2631DEFAULT_WRAPPER_W_3W(Group_compare)
2632DEFAULT_WRAPPER_W_3W(Group_difference)
2633DEFAULT_WRAPPER_W_4W(Group_excl)
2634DEFAULT_WRAPPER_W_1W(Group_f2c)
2635DEFAULT_WRAPPER_W_1W(Group_free)
2636DEFAULT_WRAPPER_W_4W(Group_incl)
2637DEFAULT_WRAPPER_W_3W(Group_intersection)
2638DEFAULT_WRAPPER_W_4W(Group_range_excl)
2639DEFAULT_WRAPPER_W_4W(Group_range_incl)
2640DEFAULT_WRAPPER_W_2W(Group_rank)
2641DEFAULT_WRAPPER_W_2W(Group_size)
2642DEFAULT_WRAPPER_W_5W(Group_translate_ranks)
2643DEFAULT_WRAPPER_W_3W(Group_union)
sewardj9c969c32006-03-10 18:37:45 +00002644/* DEFAULT_WRAPPER_W_7W(Ibsend) */
sewardj63daa8a2006-03-09 19:08:20 +00002645DEFAULT_WRAPPER_W_1W(Info_c2f)
2646DEFAULT_WRAPPER_W_1W(Info_create)
2647DEFAULT_WRAPPER_W_2W(Info_delete)
2648DEFAULT_WRAPPER_W_2W(Info_dup)
2649DEFAULT_WRAPPER_W_1W(Info_f2c)
2650DEFAULT_WRAPPER_W_1W(Info_free)
2651DEFAULT_WRAPPER_W_5W(Info_get)
2652DEFAULT_WRAPPER_W_2W(Info_get_nkeys)
2653DEFAULT_WRAPPER_W_3W(Info_get_nthkey)
2654DEFAULT_WRAPPER_W_4W(Info_get_valuelen)
2655DEFAULT_WRAPPER_W_3W(Info_set)
2656/* DEFAULT_WRAPPER_W_2W(Init) */
2657/* DEFAULT_WRAPPER_W_1W(Initialized) */
2658DEFAULT_WRAPPER_W_4W(Init_thread)
2659DEFAULT_WRAPPER_W_6W(Intercomm_create)
2660DEFAULT_WRAPPER_W_3W(Intercomm_merge)
2661/* DEFAULT_WRAPPER_W_5W(Iprobe) */
2662/* DEFAULT_WRAPPER_W_7W(Irecv) */
sewardj9c969c32006-03-10 18:37:45 +00002663/* DEFAULT_WRAPPER_W_7W(Irsend) */
sewardj63daa8a2006-03-09 19:08:20 +00002664/* DEFAULT_WRAPPER_W_7W(Isend) */
sewardj9c969c32006-03-10 18:37:45 +00002665/* DEFAULT_WRAPPER_W_7W(Issend) */
sewardj63daa8a2006-03-09 19:08:20 +00002666DEFAULT_WRAPPER_W_1W(Is_thread_main)
2667DEFAULT_WRAPPER_W_4W(Keyval_create)
2668DEFAULT_WRAPPER_W_1W(Keyval_free)
2669DEFAULT_WRAPPER_W_3W(Lookup_name)
2670DEFAULT_WRAPPER_W_1W(Op_c2f)
2671/* DEFAULT_WRAPPER_W_3W(Op_create) */
2672DEFAULT_WRAPPER_W_2W(Open_port)
2673DEFAULT_WRAPPER_W_1W(Op_f2c)
2674DEFAULT_WRAPPER_W_1W(Op_free)
2675DEFAULT_WRAPPER_W_7W(Pack_external)
2676DEFAULT_WRAPPER_W_4W(Pack_external_size)
sewardjee346592007-02-08 12:05:03 +00002677/* DEFAULT_WRAPPER_W_7W(Pack) */
sewardj63daa8a2006-03-09 19:08:20 +00002678DEFAULT_WRAPPER_W_4W(Pack_size)
2679/* int MPI_Pcontrol(const int level, ...) */
sewardjb727b542006-03-10 21:41:01 +00002680/* DEFAULT_WRAPPER_W_4W(Probe) */
sewardj63daa8a2006-03-09 19:08:20 +00002681DEFAULT_WRAPPER_W_3W(Publish_name)
2682DEFAULT_WRAPPER_W_8W(Put)
2683DEFAULT_WRAPPER_W_1W(Query_thread)
2684DEFAULT_WRAPPER_W_7W(Recv_init)
2685/* DEFAULT_WRAPPER_W_7W(Recv) */
2686/* DEFAULT_WRAPPER_W_7W(Reduce) */
2687DEFAULT_WRAPPER_W_6W(Reduce_scatter)
2688DEFAULT_WRAPPER_W_5W(Register_datarep)
2689DEFAULT_WRAPPER_W_1W(Request_c2f)
2690DEFAULT_WRAPPER_W_1W(Request_f2c)
2691DEFAULT_WRAPPER_W_1W(Request_free)
2692DEFAULT_WRAPPER_W_3W(Request_get_status)
sewardj9c969c32006-03-10 18:37:45 +00002693/* DEFAULT_WRAPPER_W_6W(Rsend) */
sewardj63daa8a2006-03-09 19:08:20 +00002694DEFAULT_WRAPPER_W_7W(Rsend_init)
2695DEFAULT_WRAPPER_W_6W(Scan)
sewardjb727b542006-03-10 21:41:01 +00002696/* DEFAULT_WRAPPER_W_8W(Scatter) */
sewardj63daa8a2006-03-09 19:08:20 +00002697DEFAULT_WRAPPER_W_9W(Scatterv)
2698DEFAULT_WRAPPER_W_7W(Send_init)
2699/* DEFAULT_WRAPPER_W_6W(Send) */
2700/* DEFAULT_WRAPPER_W_12W(Sendrecv) */
2701DEFAULT_WRAPPER_W_9W(Sendrecv_replace)
2702DEFAULT_WRAPPER_W_7W(Ssend_init)
sewardj9c969c32006-03-10 18:37:45 +00002703/* DEFAULT_WRAPPER_W_6W(Ssend) */
sewardj63daa8a2006-03-09 19:08:20 +00002704DEFAULT_WRAPPER_W_1W(Start)
2705DEFAULT_WRAPPER_W_2W(Startall)
2706DEFAULT_WRAPPER_W_2W(Status_c2f)
2707DEFAULT_WRAPPER_W_2W(Status_f2c)
2708DEFAULT_WRAPPER_W_2W(Status_set_cancelled)
2709DEFAULT_WRAPPER_W_3W(Status_set_elements)
sewardjb727b542006-03-10 21:41:01 +00002710/* DEFAULT_WRAPPER_W_4W(Testall) */
sewardj63daa8a2006-03-09 19:08:20 +00002711DEFAULT_WRAPPER_W_5W(Testany)
sewardjb727b542006-03-10 21:41:01 +00002712/* DEFAULT_WRAPPER_W_3W(Test) */
sewardj63daa8a2006-03-09 19:08:20 +00002713DEFAULT_WRAPPER_W_2W(Test_cancelled)
2714DEFAULT_WRAPPER_W_5W(Testsome)
2715DEFAULT_WRAPPER_W_2W(Topo_test)
2716DEFAULT_WRAPPER_W_1W(Type_c2f)
sewardj9c969c32006-03-10 18:37:45 +00002717/* DEFAULT_WRAPPER_W_1W(Type_commit) */
sewardj63daa8a2006-03-09 19:08:20 +00002718DEFAULT_WRAPPER_W_3W(Type_contiguous)
2719DEFAULT_WRAPPER_W_10W(Type_create_darray)
2720DEFAULT_WRAPPER_W_3W(Type_create_f90_complex)
2721DEFAULT_WRAPPER_W_2W(Type_create_f90_integer)
2722DEFAULT_WRAPPER_W_3W(Type_create_f90_real)
2723DEFAULT_WRAPPER_W_5W(Type_create_hindexed)
2724DEFAULT_WRAPPER_W_5W(Type_create_hvector)
2725DEFAULT_WRAPPER_W_4W(Type_create_keyval)
2726DEFAULT_WRAPPER_W_5W(Type_create_indexed_block)
2727DEFAULT_WRAPPER_W_5W(Type_create_struct)
2728DEFAULT_WRAPPER_W_7W(Type_create_subarray)
2729DEFAULT_WRAPPER_W_4W(Type_create_resized)
2730DEFAULT_WRAPPER_W_2W(Type_delete_attr)
2731DEFAULT_WRAPPER_W_2W(Type_dup)
sewardj9c969c32006-03-10 18:37:45 +00002732/* DEFAULT_WRAPPER_W_2W(Type_extent) */
2733/* DEFAULT_WRAPPER_W_1W(Type_free) */
sewardj63daa8a2006-03-09 19:08:20 +00002734DEFAULT_WRAPPER_W_1W(Type_free_keyval)
2735DEFAULT_WRAPPER_W_1W(Type_f2c)
2736DEFAULT_WRAPPER_W_4W(Type_get_attr)
sewardj9c969c32006-03-10 18:37:45 +00002737/* DEFAULT_WRAPPER_W_7W(Type_get_contents) */
2738/* DEFAULT_WRAPPER_W_5W(Type_get_envelope) */
sewardj63daa8a2006-03-09 19:08:20 +00002739DEFAULT_WRAPPER_W_3W(Type_get_extent)
2740DEFAULT_WRAPPER_W_3W(Type_get_name)
2741DEFAULT_WRAPPER_W_3W(Type_get_true_extent)
2742DEFAULT_WRAPPER_W_5W(Type_hindexed)
2743DEFAULT_WRAPPER_W_5W(Type_hvector)
2744DEFAULT_WRAPPER_W_5W(Type_indexed)
2745DEFAULT_WRAPPER_W_2W(Type_lb)
2746DEFAULT_WRAPPER_W_3W(Type_match_size)
2747DEFAULT_WRAPPER_W_3W(Type_set_attr)
2748DEFAULT_WRAPPER_W_2W(Type_set_name)
2749DEFAULT_WRAPPER_W_2W(Type_size)
2750DEFAULT_WRAPPER_W_5W(Type_struct)
2751DEFAULT_WRAPPER_W_2W(Type_ub)
2752DEFAULT_WRAPPER_W_5W(Type_vector)
sewardjee346592007-02-08 12:05:03 +00002753/* DEFAULT_WRAPPER_W_7W(Unpack) */
sewardj63daa8a2006-03-09 19:08:20 +00002754DEFAULT_WRAPPER_W_3W(Unpublish_name)
2755DEFAULT_WRAPPER_W_7W(Unpack_external)
2756/* DEFAULT_WRAPPER_W_3W(Waitall) */
sewardj982751b2008-05-15 05:48:16 +00002757/* DEFAULT_WRAPPER_W_4W(Waitany) */
sewardj63daa8a2006-03-09 19:08:20 +00002758/* DEFAULT_WRAPPER_W_2W(Wait) */
2759DEFAULT_WRAPPER_W_5W(Waitsome)
2760DEFAULT_WRAPPER_W_1W(Win_c2f)
2761DEFAULT_WRAPPER_W_2W(Win_call_errhandler)
2762DEFAULT_WRAPPER_W_1W(Win_complete)
2763DEFAULT_WRAPPER_W_6W(Win_create)
2764DEFAULT_WRAPPER_W_2W(Win_create_errhandler)
2765DEFAULT_WRAPPER_W_4W(Win_create_keyval)
2766DEFAULT_WRAPPER_W_2W(Win_delete_attr)
2767DEFAULT_WRAPPER_W_1W(Win_f2c)
2768DEFAULT_WRAPPER_W_2W(Win_fence)
2769DEFAULT_WRAPPER_W_1W(Win_free)
2770DEFAULT_WRAPPER_W_1W(Win_free_keyval)
2771DEFAULT_WRAPPER_W_4W(Win_get_attr)
2772DEFAULT_WRAPPER_W_2W(Win_get_errhandler)
2773DEFAULT_WRAPPER_W_2W(Win_get_group)
2774DEFAULT_WRAPPER_W_3W(Win_get_name)
2775DEFAULT_WRAPPER_W_4W(Win_lock)
2776DEFAULT_WRAPPER_W_3W(Win_post)
2777DEFAULT_WRAPPER_W_3W(Win_set_attr)
2778DEFAULT_WRAPPER_W_2W(Win_set_errhandler)
2779DEFAULT_WRAPPER_W_2W(Win_set_name)
2780DEFAULT_WRAPPER_W_3W(Win_start)
2781DEFAULT_WRAPPER_W_2W(Win_test)
2782DEFAULT_WRAPPER_W_2W(Win_unlock)
2783DEFAULT_WRAPPER_W_1W(Win_wait)
2784/* double MPI_Wtick(void) */
2785/* double MPI_Wtime(void) */
2786
2787
sewardjc3a47092006-02-18 23:13:33 +00002788/*------------------------------------------------------------*/
2789/*--- ---*/
2790/*--- ---*/
2791/*--- ---*/
2792/*------------------------------------------------------------*/
2793
sewardjc3a47092006-02-18 23:13:33 +00002794/*---------------------------------------------------------------*/
2795/*--- end mpiwrap.c ---*/
2796/*---------------------------------------------------------------*/