blob: 45a0298b219496c0004f69e2afb2ef99408722ae [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
21 Copyright (C) 2006 OpenWorks LLP. All rights reserved.
22
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
60
61/*------------------------------------------------------------*/
sewardjc3a47092006-02-18 23:13:33 +000062/*--- includes ---*/
63/*------------------------------------------------------------*/
64
65#include <stdio.h>
66#include <assert.h>
67#include <unistd.h> /* getpid */
68#include <stdlib.h> /* exit */
69#include <string.h> /* strstr */
70#include <pthread.h> /* pthread_mutex_{lock,unlock} */
71
72/* Include Valgrind magic macros for writing wrappers. */
sewardj20974012006-02-19 14:05:28 +000073#include "../memcheck/memcheck.h"
sewardjc3a47092006-02-18 23:13:33 +000074
75
76/*------------------------------------------------------------*/
77/*--- Connect to MPI library ---*/
78/*------------------------------------------------------------*/
79
80/* Include headers for whatever MPI implementation the wrappers are to
sewardj80637752006-03-02 13:48:21 +000081 be used with. The configure system will tell us what the path to
82 the chosen MPI implementation is, via -I.. to the compiler. */
sewardjc3a47092006-02-18 23:13:33 +000083#include "mpi.h"
84
85/* Where are API symbols?
sewardj63daa8a2006-03-09 19:08:20 +000086 Open MPI lib/libmpi.so, soname = libmpi.so.0
sewardjd465d992006-10-17 01:46:55 +000087 AIX: in /usr/lpp/ppe.poe/lib/libmpi_r.a(mpicore*_r.o)
sewardj63daa8a2006-03-09 19:08:20 +000088 ditto Quadrics MPI
sewardjc3a47092006-02-18 23:13:33 +000089*/
90/* ifdef OpenMPI ... */
sewardjd465d992006-10-17 01:46:55 +000091#if defined(_AIX)
92# define I_WRAP_FNNAME_U(_name) \
93 I_WRAP_SONAME_FNNAME_ZU(libmpiZurZdaZLmpicoreZaZurZdoZR,_name)
94 /* Don't change this without also changing all the names in
95 libmpiwrap.exp. */
96#else
97# define I_WRAP_FNNAME_U(_name) \
98 I_WRAP_SONAME_FNNAME_ZU(libmpiZdsoZa,_name)
sewardjc3a47092006-02-18 23:13:33 +000099
sewardjd465d992006-10-17 01:46:55 +0000100#endif
sewardjc3a47092006-02-18 23:13:33 +0000101
102/*------------------------------------------------------------*/
103/*--- Decls ---*/
104/*------------------------------------------------------------*/
105
106typedef unsigned char Bool;
107#define False ((Bool)0)
108#define True ((Bool)1)
109
sewardj63daa8a2006-03-09 19:08:20 +0000110/* Word, UWord are machine words - same size as a pointer. This is
111 checked at startup. The wrappers below use 'long' to mean a
112 machine word - this too is tested at startup. */
113typedef signed long Word;
114typedef unsigned long UWord;
115
sewardjcd8aaef2006-03-10 13:43:49 +0000116#if !defined(offsetof)
117# define offsetof(type,memb) ((int)&((type*)0)->memb)
118#endif
119
sewardjc3a47092006-02-18 23:13:33 +0000120
121/*------------------------------------------------------------*/
122/*--- Simple helpers ---*/
123/*------------------------------------------------------------*/
124
125/* ------ Helpers for debug printing ------ */
126
127/* constant */
128static const char* preamble = "valgrind MPI wrappers";
129
130/* established at startup */
sewardjd465d992006-10-17 01:46:55 +0000131static pid_t my_pid = -1;
132static char* options_str = NULL;
133static int opt_verbosity = 1;
134static Bool opt_missing = 0; /* 0:silent; 1:warn; 2:abort */
135static Bool opt_help = False;
136static Bool opt_initkludge = False;
sewardjc3a47092006-02-18 23:13:33 +0000137
sewardj9c969c32006-03-10 18:37:45 +0000138static void before ( char* fnname )
sewardjc3a47092006-02-18 23:13:33 +0000139{
140 /* This isn't thread-safe wrt 'done' (no locking). It's not
141 critical. */
142 static int done = 0;
143 if (done == 0) {
144 done = 1;
145 my_pid = getpid();
146 options_str = getenv("MPIWRAP_DEBUG");
sewardjec8b6142006-03-09 03:05:17 +0000147 if (options_str) {
sewardj63daa8a2006-03-09 19:08:20 +0000148 if (NULL != strstr(options_str, "warn"))
149 opt_missing = 1;
150 if (NULL != strstr(options_str, "strict"))
151 opt_missing = 2;
sewardjec8b6142006-03-09 03:05:17 +0000152 if (NULL != strstr(options_str, "verbose"))
153 opt_verbosity++;
154 if (NULL != strstr(options_str, "quiet"))
155 opt_verbosity--;
sewardj63daa8a2006-03-09 19:08:20 +0000156 if (NULL != strstr(options_str, "help"))
157 opt_help = True;
sewardjd465d992006-10-17 01:46:55 +0000158 if (NULL != strstr(options_str, "initkludge"))
159 opt_initkludge = True;
sewardjec8b6142006-03-09 03:05:17 +0000160 }
161 if (opt_verbosity > 0)
162 fprintf(stderr, "%s %5d: Active for pid %d\n",
163 preamble, my_pid, my_pid);
sewardj63daa8a2006-03-09 19:08:20 +0000164 /* Sanity check - that Word/UWord really are machine words. */
165 assert(sizeof(Word) == sizeof(void*));
166 assert(sizeof(UWord) == sizeof(void*));
sewardj301a50f2006-03-03 16:14:18 +0000167 /* Sanity check - char is byte-sized (else address calculations
168 in walk_type don't work. */
169 assert(sizeof(char) == 1);
sewardjc3a47092006-02-18 23:13:33 +0000170 if (opt_help) {
171 fprintf(stderr, "\n");
172 fprintf(stderr, "Valid options for the MPIWRAP_DEBUG environment"
173 " variable are:\n");
174 fprintf(stderr, "\n");
sewardjd465d992006-10-17 01:46:55 +0000175 fprintf(stderr, " quiet be silent except for errors\n");
176 fprintf(stderr, " verbose show wrapper entries/exits\n");
177 fprintf(stderr, " strict abort the program if a function"
sewardjc3a47092006-02-18 23:13:33 +0000178 " with no wrapper is used\n");
sewardjd465d992006-10-17 01:46:55 +0000179 fprintf(stderr, " warn give a warning if a function"
sewardj63daa8a2006-03-09 19:08:20 +0000180 " with no wrapper is used\n");
sewardjd465d992006-10-17 01:46:55 +0000181 fprintf(stderr, " help display this message, then exit\n");
182 fprintf(stderr, " initkludge debugging hack; do not use\n");
sewardjc3a47092006-02-18 23:13:33 +0000183 fprintf(stderr, "\n");
184 fprintf(stderr, "Multiple options are allowed, eg"
185 " MPIWRAP_DEBUG=strict,verbose\n");
sewardj63daa8a2006-03-09 19:08:20 +0000186 fprintf(stderr, "Note: 'warn' generates output even if 'quiet'"
187 " is also specified\n");
sewardjc3a47092006-02-18 23:13:33 +0000188 fprintf(stderr, "\n");
189 fprintf(stderr, "%s %5d: exiting now\n", preamble, my_pid );
190 exit(1);
191 }
sewardjec8b6142006-03-09 03:05:17 +0000192 if (opt_verbosity > 0)
193 fprintf(stderr,
194 "%s %5d: Try MPIWRAP_DEBUG=help for possible options\n",
195 preamble, my_pid);
sewardjc3a47092006-02-18 23:13:33 +0000196
197 }
sewardjec8b6142006-03-09 03:05:17 +0000198 if (opt_verbosity > 1)
sewardjc3a47092006-02-18 23:13:33 +0000199 fprintf(stderr, "%s %5d: enter PMPI_%s\n", preamble, my_pid, fnname );
200}
201
sewardjd465d992006-10-17 01:46:55 +0000202static __inline__ void after ( char* fnname, int err )
sewardjc3a47092006-02-18 23:13:33 +0000203{
sewardjec8b6142006-03-09 03:05:17 +0000204 if (opt_verbosity > 1)
sewardjc3a47092006-02-18 23:13:33 +0000205 fprintf(stderr, "%s %5d: exit PMPI_%s (err = %d)\n",
206 preamble, my_pid, fnname, err );
207}
208
209static void barf ( char* msg )
210{
211 fprintf(stderr, "%s %5d: fatal: %s\n", preamble, my_pid, msg);
212 fprintf(stderr, "%s %5d: exiting now\n", preamble, my_pid );
213 exit(1);
214}
215
sewardj533bfda2006-03-08 20:41:44 +0000216/* Half-hearted type-showing function (for debugging). */
217static void showTy ( FILE* f, MPI_Datatype ty )
218{
219 if (ty == MPI_DATATYPE_NULL) fprintf(f,"DATATYPE_NULL");
220 else if (ty == MPI_BYTE) fprintf(f,"BYTE");
221 else if (ty == MPI_PACKED) fprintf(f,"PACKED");
222 else if (ty == MPI_CHAR) fprintf(f,"CHAR");
223 else if (ty == MPI_SHORT) fprintf(f,"SHORT");
224 else if (ty == MPI_INT) fprintf(f,"INT");
225 else if (ty == MPI_LONG) fprintf(f,"LONG");
226 else if (ty == MPI_FLOAT) fprintf(f,"FLOAT");
227 else if (ty == MPI_DOUBLE) fprintf(f,"DOUBLE");
228 else if (ty == MPI_LONG_DOUBLE) fprintf(f,"LONG_DOUBLE");
229 else if (ty == MPI_UNSIGNED_CHAR) fprintf(f,"UNSIGNED_CHAR");
230 else if (ty == MPI_UNSIGNED_SHORT) fprintf(f,"UNSIGNED_SHORT");
231 else if (ty == MPI_UNSIGNED_LONG) fprintf(f,"UNSIGNED_LONG");
232 else if (ty == MPI_UNSIGNED) fprintf(f,"UNSIGNED");
233 else if (ty == MPI_FLOAT_INT) fprintf(f,"FLOAT_INT");
234 else if (ty == MPI_DOUBLE_INT) fprintf(f,"DOUBLE_INT");
235 else if (ty == MPI_LONG_DOUBLE_INT) fprintf(f,"LONG_DOUBLE_INT");
236 else if (ty == MPI_LONG_INT) fprintf(f,"LONG_INT");
237 else if (ty == MPI_SHORT_INT) fprintf(f,"SHORT_INT");
238 else if (ty == MPI_2INT) fprintf(f,"2INT");
239 else if (ty == MPI_UB) fprintf(f,"UB");
240 else if (ty == MPI_LB) fprintf(f,"LB");
241# if defined(MPI_WCHAR)
242 else if (ty == MPI_WCHAR) fprintf(f,"WCHAR");
243# endif
244 else if (ty == MPI_LONG_LONG_INT) fprintf(f,"LONG_LONG_INT");
sewardj87f75f72006-03-12 16:44:05 +0000245# if defined(MPI_LONG_LONG)
sewardj533bfda2006-03-08 20:41:44 +0000246 else if (ty == MPI_LONG_LONG) fprintf(f,"LONG_LONG");
sewardj87f75f72006-03-12 16:44:05 +0000247# endif
sewardj582031b2006-04-13 22:03:16 +0000248# if defined(MPI_UNSIGNED_LONG_LONG)
sewardj533bfda2006-03-08 20:41:44 +0000249 else if (ty == MPI_UNSIGNED_LONG_LONG) fprintf(f,"UNSIGNED_LONG_LONG");
sewardj582031b2006-04-13 22:03:16 +0000250# endif
sewardj533bfda2006-03-08 20:41:44 +0000251 else fprintf(f,"showTy:???");
252}
253
254static void showCombiner ( FILE* f, int combiner )
255{
256 switch (combiner) {
257 case MPI_COMBINER_NAMED: fprintf(f, "NAMED"); break;
sewardjcc8c3992006-03-08 21:40:34 +0000258#if defined(MPI_COMBINER_DUP)
sewardj533bfda2006-03-08 20:41:44 +0000259 case MPI_COMBINER_DUP: fprintf(f, "DUP"); break;
sewardjcc8c3992006-03-08 21:40:34 +0000260# endif
sewardj533bfda2006-03-08 20:41:44 +0000261 case MPI_COMBINER_CONTIGUOUS: fprintf(f, "CONTIGUOUS"); break;
262 case MPI_COMBINER_VECTOR: fprintf(f, "VECTOR"); break;
sewardjcc8c3992006-03-08 21:40:34 +0000263#if defined(MPI_COMBINER_HVECTOR_INTEGER)
sewardj533bfda2006-03-08 20:41:44 +0000264 case MPI_COMBINER_HVECTOR_INTEGER: fprintf(f, "HVECTOR_INTEGER"); break;
sewardjcc8c3992006-03-08 21:40:34 +0000265# endif
sewardj533bfda2006-03-08 20:41:44 +0000266 case MPI_COMBINER_HVECTOR: fprintf(f, "HVECTOR"); break;
267 case MPI_COMBINER_INDEXED: fprintf(f, "INDEXED"); break;
sewardjcc8c3992006-03-08 21:40:34 +0000268#if defined(MPI_COMBINER_HINDEXED_INTEGER)
sewardj533bfda2006-03-08 20:41:44 +0000269 case MPI_COMBINER_HINDEXED_INTEGER: fprintf(f, "HINDEXED_INTEGER"); break;
sewardjcc8c3992006-03-08 21:40:34 +0000270# endif
sewardj533bfda2006-03-08 20:41:44 +0000271 case MPI_COMBINER_HINDEXED: fprintf(f, "HINDEXED"); break;
sewardjcc8c3992006-03-08 21:40:34 +0000272#if defined(MPI_COMBINER_INDEXED_BLOCK)
sewardj533bfda2006-03-08 20:41:44 +0000273 case MPI_COMBINER_INDEXED_BLOCK: fprintf(f, "INDEXED_BLOCK"); break;
sewardjcc8c3992006-03-08 21:40:34 +0000274# endif
275#if defined(MPI_COMBINER_STRUCT_INTEGER)
sewardj533bfda2006-03-08 20:41:44 +0000276 case MPI_COMBINER_STRUCT_INTEGER: fprintf(f, "STRUCT_INTEGER"); break;
sewardjcc8c3992006-03-08 21:40:34 +0000277# endif
sewardj533bfda2006-03-08 20:41:44 +0000278 case MPI_COMBINER_STRUCT: fprintf(f, "STRUCT"); break;
sewardjcc8c3992006-03-08 21:40:34 +0000279#if defined(MPI_COMBINER_SUBARRAY)
sewardj533bfda2006-03-08 20:41:44 +0000280 case MPI_COMBINER_SUBARRAY: fprintf(f, "SUBARRAY"); break;
sewardjcc8c3992006-03-08 21:40:34 +0000281# endif
282#if defined(MPI_COMBINER_DARRAY)
sewardj533bfda2006-03-08 20:41:44 +0000283 case MPI_COMBINER_DARRAY: fprintf(f, "DARRAY"); break;
sewardjcc8c3992006-03-08 21:40:34 +0000284# endif
285#if defined(MPI_COMBINER_F90_REAL)
sewardj533bfda2006-03-08 20:41:44 +0000286 case MPI_COMBINER_F90_REAL: fprintf(f, "F90_REAL"); break;
sewardjcc8c3992006-03-08 21:40:34 +0000287# endif
288#if defined(MPI_COMBINER_F90_COMPLEX)
sewardj533bfda2006-03-08 20:41:44 +0000289 case MPI_COMBINER_F90_COMPLEX: fprintf(f, "F90_COMPLEX"); break;
sewardjcc8c3992006-03-08 21:40:34 +0000290# endif
291#if defined(MPI_COMBINER_F90_INTEGER)
sewardj533bfda2006-03-08 20:41:44 +0000292 case MPI_COMBINER_F90_INTEGER: fprintf(f, "F90_INTEGER"); break;
sewardjcc8c3992006-03-08 21:40:34 +0000293# endif
294#if defined(MPI_COMBINER_RESIZED)
sewardj533bfda2006-03-08 20:41:44 +0000295 case MPI_COMBINER_RESIZED: fprintf(f, "RESIZED"); break;
sewardjcc8c3992006-03-08 21:40:34 +0000296# endif
sewardj533bfda2006-03-08 20:41:44 +0000297 default: fprintf(f, "showCombiner:??"); break;
298 }
299}
300
301
sewardjc3a47092006-02-18 23:13:33 +0000302/* ------ Get useful bits of info ------ */
303
304/* Note, PMPI_Comm_rank/size are themselves wrapped. Should work
305 fine. */
306
sewardjd465d992006-10-17 01:46:55 +0000307static __inline__ int comm_rank ( MPI_Comm comm )
sewardjc3a47092006-02-18 23:13:33 +0000308{
309 int err, r;
310 err = PMPI_Comm_rank(comm, &r);
311 return err ? 0/*arbitrary*/ : r;
312}
313
sewardjd465d992006-10-17 01:46:55 +0000314static __inline__ int comm_size ( MPI_Comm comm )
sewardjc3a47092006-02-18 23:13:33 +0000315{
316 int err, r;
317 err = PMPI_Comm_size(comm, &r);
318 return err ? 0/*arbitrary*/ : r;
319}
320
sewardjd465d992006-10-17 01:46:55 +0000321static __inline__ Bool count_from_Status( /*OUT*/int* recv_count,
sewardjc3a47092006-02-18 23:13:33 +0000322 MPI_Datatype datatype,
323 MPI_Status* status)
324{
325 int n;
326 int err = PMPI_Get_count(status, datatype, &n);
327 if (err == MPI_SUCCESS) {
328 *recv_count = n;
329 return True;
330 } else {
331 return False;
332 }
333}
334
335/* It's critical that we can do equality on MPI_Requests.
336 Unfortunately these are opaque objects to us (handles, in the
337 parlance of the MPI 1.1 spec). Fortunately Sec 2.4.1 ("Opaque
338 Objects") specifies that "In C, [...] These [handles] should be
339 types that support assignment and equality operations." Hence the
340 following function should compile for any compliant definition of
341 MPI_Request. */
sewardjd465d992006-10-17 01:46:55 +0000342static __inline__
sewardjc3a47092006-02-18 23:13:33 +0000343Bool eq_MPI_Request ( MPI_Request r1, MPI_Request r2 )
344{
345 return r1 == r2;
346}
347
sewardj8717d1a2006-03-04 02:31:52 +0000348/* Get the 'extent' of a type. Note, as per the MPI spec this
349 includes whatever padding would be required when using 'ty' in an
350 array. */
sewardj301a50f2006-03-03 16:14:18 +0000351static long extentOfTy ( MPI_Datatype ty )
352{
353 int r;
354 MPI_Aint n;
355 r = PMPI_Type_extent(ty, &n);
356 assert(r == MPI_SUCCESS);
357 return (long)n;
358}
359
sewardjcd8aaef2006-03-10 13:43:49 +0000360/* Free up *ty, if it is safe to do so */
sewardj301a50f2006-03-03 16:14:18 +0000361static void maybeFreeTy ( MPI_Datatype* ty )
362{
363 int r, n_ints, n_addrs, n_dtys, tycon;
364
365 r = PMPI_Type_get_envelope( *ty, &n_ints, &n_addrs, &n_dtys, &tycon );
366 assert(r == MPI_SUCCESS);
367
sewardjcd8aaef2006-03-10 13:43:49 +0000368 /* can't free named types */
369 if (tycon == MPI_COMBINER_NAMED)
370 return;
371
372 /* some kinds of structs are predefined so we can't free them
373 either. */
374 if (*ty == MPI_FLOAT_INT || *ty == MPI_DOUBLE_INT
375 || *ty == MPI_LONG_INT || *ty == MPI_2INT
376 || *ty == MPI_SHORT_INT || *ty == MPI_LONG_DOUBLE_INT)
377 return;
378
379 /* Looks OK - free it. */
380 if (0) {
381 /* show me what you're about to free .. */
382 fprintf(stderr, "freeing combiner ");
383 showCombiner(stderr,tycon);
384 fprintf(stderr, " ty= ");
385 showTy(stderr,*ty);
386 fprintf(stderr,"\n");
sewardj301a50f2006-03-03 16:14:18 +0000387 }
sewardjcd8aaef2006-03-10 13:43:49 +0000388 r = PMPI_Type_free(ty);
389 assert(r == MPI_SUCCESS);
sewardj301a50f2006-03-03 16:14:18 +0000390}
391
sewardj8717d1a2006-03-04 02:31:52 +0000392/* How big is a "named" (base) type? Returns 0 if not known. Note.
393 There is a subtlety, which is that this is required to return the
394 exact size of one item of the type, NOT the size of it when padded
395 suitably to make an array of them. In particular that's why the
396 size of LONG_DOUBLE is 10 and not sizeof(long double), since the
sewardj3f55c9c2006-03-12 13:37:19 +0000397 latter is 12 at least on x86. Except if sizeof(long double) is
398 claimed to be 8 then we'd better respect that.
399
400 Ref: MPI 1.1 doc p18 */
sewardj8717d1a2006-03-04 02:31:52 +0000401static long sizeofOneNamedTy ( MPI_Datatype ty )
sewardj1646f752006-03-03 21:03:10 +0000402{
sewardjcd8aaef2006-03-10 13:43:49 +0000403 if (ty == MPI_CHAR) return sizeof(signed char);
404 if (ty == MPI_SHORT) return sizeof(signed short int);
405 if (ty == MPI_INT) return sizeof(signed int);
406 if (ty == MPI_LONG) return sizeof(signed long int);
sewardjc0526f72006-03-08 03:54:37 +0000407 if (ty == MPI_UNSIGNED_CHAR) return sizeof(unsigned char);
408 if (ty == MPI_UNSIGNED_SHORT) return sizeof(unsigned short int);
sewardjcd8aaef2006-03-10 13:43:49 +0000409 if (ty == MPI_UNSIGNED) return sizeof(unsigned int);
410 if (ty == MPI_UNSIGNED_LONG) return sizeof(unsigned long int);
411 if (ty == MPI_FLOAT) return sizeof(float);
412 if (ty == MPI_DOUBLE) return sizeof(double);
sewardjcd8aaef2006-03-10 13:43:49 +0000413 if (ty == MPI_BYTE) return 1;
sewardj3f55c9c2006-03-12 13:37:19 +0000414 if (ty == MPI_LONG_DOUBLE)
415 return sizeof(long double)==8
416 ? 8 : 10; /* NOT: sizeof(long double); */
sewardjcd8aaef2006-03-10 13:43:49 +0000417 /* MPI_PACKED */
418 /* new in MPI2: */
sewardj493743f2006-03-10 22:17:57 +0000419# if defined(MPI_WCHAR)
sewardjcd8aaef2006-03-10 13:43:49 +0000420 if (ty == MPI_WCHAR) return sizeof(wchar_t);
sewardj493743f2006-03-10 22:17:57 +0000421# endif
422# if defined(MPI_SIGNED_CHAR)
sewardjcd8aaef2006-03-10 13:43:49 +0000423 if (ty == MPI_SIGNED_CHAR) return sizeof(signed char);
sewardj493743f2006-03-10 22:17:57 +0000424# endif
sewardj582031b2006-04-13 22:03:16 +0000425# if defined(MPI_UNSIGNED_LONG_LONG)
sewardjcd8aaef2006-03-10 13:43:49 +0000426 if (ty == MPI_UNSIGNED_LONG_LONG) return sizeof(unsigned long long int);
sewardj582031b2006-04-13 22:03:16 +0000427# endif
sewardjcd8aaef2006-03-10 13:43:49 +0000428 if (ty == MPI_LONG_LONG_INT) return sizeof(signed long long int);
429 /* Note: the following are named structs, not named basic types,
430 and so are not handled here:
431 FLOAT_INT DOUBLE_INT LONG_INT 2INT SHORT_INT LONG_DOUBLE_INT
432 My guess is they are probably for doing max-w-index style
433 reductions, the INT carrying the index of the max/min and the
434 other type its actual value.
435 */
sewardj1646f752006-03-03 21:03:10 +0000436 return 0;
437}
438
sewardj301a50f2006-03-03 16:14:18 +0000439
440/*------------------------------------------------------------*/
441/*--- Unpicking datatypes ---*/
442/*------------------------------------------------------------*/
443
444static
445void walk_type_array ( void(*f)(void*,long), char* base,
446 MPI_Datatype ty, long count );
447
448
449/* Walk over all fragments of the object of type 'ty' with base
450 address 'base', and apply 'f' to the start/length of each
451 contiguous fragment. */
452static
453void walk_type ( void(*f)(void*,long), char* base, MPI_Datatype ty )
454{
455 int r, n_ints, n_addrs, n_dtys, tycon;
sewardj1646f752006-03-03 21:03:10 +0000456 long ex, i;
sewardj301a50f2006-03-03 16:14:18 +0000457 int* ints = NULL;
458 MPI_Aint* addrs = NULL;
459 MPI_Datatype* dtys = NULL;
sewardj301a50f2006-03-03 16:14:18 +0000460
sewardj1646f752006-03-03 21:03:10 +0000461 if (0)
sewardj301a50f2006-03-03 16:14:18 +0000462 printf("walk_type %p\n", (void*)ty);
sewardj301a50f2006-03-03 16:14:18 +0000463
sewardj9c969c32006-03-10 18:37:45 +0000464 r = PMPI_Type_get_envelope( ty, &n_ints, &n_addrs, &n_dtys, &tycon );
sewardj301a50f2006-03-03 16:14:18 +0000465 assert(r == MPI_SUCCESS);
466
467 /* Handle the base cases fast(er/ish). */
468 if (tycon == MPI_COMBINER_NAMED) {
sewardj8717d1a2006-03-04 02:31:52 +0000469 long sz = sizeofOneNamedTy(ty);
sewardjcd8aaef2006-03-10 13:43:49 +0000470 if (sz > 0) {
471 f(base, sz);
472 return;
473 }
474 /* Hmm. Perhaps it's a named struct? Unfortunately we can't
475 take them to bits so we have to do a really ugly hack, which
476 makes assumptions about how the MPI implementation has laid
sewardj558cc222006-03-10 14:51:19 +0000477 out these types. At least Open MPI 1.0.1 appears to put
478 the 'val' field first.
sewardjcd8aaef2006-03-10 13:43:49 +0000479 */
480 if (ty == MPI_LONG_INT) {
sewardj558cc222006-03-10 14:51:19 +0000481 typedef struct { long val; int loc; } Ty;
482 f(base + offsetof(Ty,val), sizeof(long));
483 f(base + offsetof(Ty,loc), sizeof(int));
484 return;
485 }
486 if (ty == MPI_DOUBLE_INT) {
487 typedef struct { double val; int loc; } Ty;
488 f(base + offsetof(Ty,val), sizeof(double));
489 f(base + offsetof(Ty,loc), sizeof(int));
490 return;
491 }
492 if (ty == MPI_SHORT_INT) {
493 typedef struct { short val; int loc; } Ty;
494 f(base + offsetof(Ty,val), sizeof(short));
sewardjcd8aaef2006-03-10 13:43:49 +0000495 f(base + offsetof(Ty,loc), sizeof(int));
496 return;
497 }
sewardj493743f2006-03-10 22:17:57 +0000498 if (ty == MPI_LB || ty == MPI_UB)
499 return; /* have zero size, so nothing needs to be done */
sewardjcd8aaef2006-03-10 13:43:49 +0000500 goto unhandled;
sewardj301a50f2006-03-03 16:14:18 +0000501 /*NOTREACHED*/
502 }
503
sewardj1646f752006-03-03 21:03:10 +0000504 if (0) {
sewardj301a50f2006-03-03 16:14:18 +0000505 ex = extentOfTy(ty);
sewardj157a8c42006-03-12 00:35:42 +0000506 printf("tycon 0x%llx %d %d %d (ext %d)\n",
507 (unsigned long long int)tycon,
508 n_ints, n_addrs, n_dtys, (int)ex );
sewardj301a50f2006-03-03 16:14:18 +0000509 }
510
511 /* Now safe to do MPI_Type_get_contents */
512 assert(n_ints >= 0);
513 assert(n_addrs >= 0);
514 assert(n_dtys >= 0);
515
516 if (n_ints > 0) {
517 ints = malloc(n_ints * sizeof(int));
518 assert(ints);
519 }
520 if (n_addrs > 0) {
521 addrs = malloc(n_addrs * sizeof(MPI_Aint));
522 assert(addrs);
523 }
524 if (n_dtys > 0) {
525 dtys = malloc(n_dtys * sizeof(MPI_Datatype));
526 assert(dtys);
527 }
528
sewardj9c969c32006-03-10 18:37:45 +0000529 r = PMPI_Type_get_contents( ty, n_ints, n_addrs, n_dtys,
530 ints, addrs, dtys );
sewardj301a50f2006-03-03 16:14:18 +0000531 assert(r == MPI_SUCCESS);
532
533 switch (tycon) {
534
535 case MPI_COMBINER_CONTIGUOUS:
536 assert(n_ints == 1 && n_addrs == 0 && n_dtys == 1);
537 walk_type_array( f, base, dtys[0], ints[0] );
538 maybeFreeTy( &dtys[0] );
539 break;
540
sewardjc0526f72006-03-08 03:54:37 +0000541 case MPI_COMBINER_VECTOR:
542 assert(n_ints == 3 && n_addrs == 0 && n_dtys == 1);
543 ex = extentOfTy(dtys[0]);
544 if (0)
545 printf("vector count %d x (bl %d stride %d)\n",
546 (int)ints[0], (int)ints[1], (int)ints[2]);
547 for (i = 0; i < ints[0]; i++) {
548 walk_type_array( f, base + i * ints[2]/*stride*/ * ex,
549 dtys[0], ints[1]/*blocklength*/ );
550 }
551 maybeFreeTy( &dtys[0] );
552 break;
553
554 case MPI_COMBINER_HVECTOR:
555 assert(n_ints == 2 && n_addrs == 1 && n_dtys == 1);
556 ex = extentOfTy(dtys[0]);
557 if (0)
558 printf("hvector count %d x (bl %d hstride %d)\n",
559 (int)ints[0], (int)ints[1], (int)addrs[0]);
560 for (i = 0; i < ints[0]; i++) {
561 walk_type_array( f, base + i * addrs[0]/*hstride*/,
562 dtys[0], ints[1]/*blocklength*/ );
563 }
564 maybeFreeTy( &dtys[0] );
565 break;
566
567 case MPI_COMBINER_INDEXED:
568 assert(n_addrs == 0 && n_dtys == 1);
569 assert(n_ints > 0);
570 assert(n_ints == 2 * ints[0] + 1);
571 ex = extentOfTy(dtys[0]);
572 for (i = 0; i < ints[0]; i++) {
573 if (0)
574 printf("indexed (elem %d) off %d copies %d\n",
575 (int)i, ints[i+1+ints[0]], ints[i+1] );
576 walk_type_array( f, base + ex * ints[i+1+ints[0]],
577 dtys[0], ints[i+1] );
578 }
579 maybeFreeTy( &dtys[0] );
580 break;
581
582 case MPI_COMBINER_HINDEXED:
583 assert(n_ints > 0);
584 assert(n_ints == ints[0] + 1);
585 assert(n_addrs == ints[0] && n_dtys == 1);
586 ex = extentOfTy(dtys[0]);
587 for (i = 0; i < ints[0]; i++) {
588 if (0)
589 printf("hindexed (elem %d) hoff %d copies %d\n",
590 (int)i, (int)addrs[i], ints[i+1] );
591 walk_type_array( f, base + addrs[i],
592 dtys[0], ints[i+1] );
593 }
594 maybeFreeTy( &dtys[0] );
595 break;
596
sewardj301a50f2006-03-03 16:14:18 +0000597 case MPI_COMBINER_STRUCT:
598 assert(n_addrs == n_ints-1);
599 assert(n_dtys == n_ints-1);
sewardjc0526f72006-03-08 03:54:37 +0000600 assert(n_ints > 0);
601 assert(n_ints == ints[0] + 1);
sewardj301a50f2006-03-03 16:14:18 +0000602 for (i = 0; i < ints[0]; i++) {
sewardj1646f752006-03-03 21:03:10 +0000603 if (0)
sewardjc0526f72006-03-08 03:54:37 +0000604 printf("struct (elem %d limit %d) hoff %d copies %d\n",
sewardj301a50f2006-03-03 16:14:18 +0000605 (int)i, (int)ints[0], (int)addrs[i], (int)ints[i+1]);
606 walk_type_array( f, base + addrs[i], dtys[i], (long)ints[i+1] );
607 maybeFreeTy( &dtys[i] );
608 }
609 break;
610
611 default:
612 goto unhandled;
613
614 }
615
616 /* normal exit */
617 if (ints) free(ints);
618 if (addrs) free(addrs);
619 if (dtys) free(dtys);
620 return;
621
622 unhandled:
623 if (tycon == MPI_COMBINER_NAMED) {
sewardj1646f752006-03-03 21:03:10 +0000624 fprintf(stderr, "%s %5d: walk_type: unhandled base type 0x%lx ",
sewardj301a50f2006-03-03 16:14:18 +0000625 preamble, my_pid, (long)ty);
sewardj1646f752006-03-03 21:03:10 +0000626 showTy(stderr, ty);
627 fprintf(stderr, "\n");
sewardj301a50f2006-03-03 16:14:18 +0000628 } else {
629 fprintf(stderr, "%s %5d: walk_type: unhandled combiner 0x%lx\n",
630 preamble, my_pid, (long)tycon);
631 }
632 if (ints) free(ints);
633 if (addrs) free(addrs);
634 if (dtys) free(dtys);
sewardjcd8aaef2006-03-10 13:43:49 +0000635 if (opt_missing >= 2)
636 barf("walk_type: unhandled combiner, strict checking selected");
sewardj301a50f2006-03-03 16:14:18 +0000637}
638
639
sewardjcd8aaef2006-03-10 13:43:49 +0000640/* Same as walk_type but apply 'f' to every element in an array of
641 'count' items starting at 'base'. The only purpose of pushing this
642 into a different routine is so it can attempt to optimise the case
643 where the array elements are contiguous and packed together without
644 holes. */
sewardj301a50f2006-03-03 16:14:18 +0000645static
646void walk_type_array ( void(*f)(void*,long), char* base,
647 MPI_Datatype elemTy, long count )
648{
649 long i, ex;
sewardj1646f752006-03-03 21:03:10 +0000650
651 assert(sizeof(unsigned long) == sizeof(char*));
652
653 /* First see if we can do this the fast way. */
sewardj8717d1a2006-03-04 02:31:52 +0000654 ex = sizeofOneNamedTy(elemTy);
sewardj1646f752006-03-03 21:03:10 +0000655
656 if ( /* ty is a primitive type with power-of-2 size */
657 (ex == 8 || ex == 4 || ex == 2 || ex == 1)
658 && /* base is suitably aligned for ty */
659 ( ((unsigned long)base) & (ex-1)) == 0) {
660
661 /* We're sure it's contiguous, so just paint/check it in one
662 go. */
663 if (0) printf("walk_type_array fast %ld of size %ld\n", count, ex );
664 f ( base, count * ex );
665
666 } else {
667
668 /* Bad news. We have to futz with each element individually.
sewardj8717d1a2006-03-04 02:31:52 +0000669 This could be very expensive.
670
671 Note: subtle. If ty is LONG_DOUBLE then the extent will be
672 12, so the following loop will jump along in steps of 12, but
673 the size painted by walk_type will be 10 since it uses
674 sizeofOneNamedTy to establish the size of base types. Which
675 is what we need to happen. */
sewardj1646f752006-03-03 21:03:10 +0000676 ex = extentOfTy(elemTy);
677 if (0) printf("walk_type_array SLOW %ld of size %ld\n", count, ex );
678 for (i = 0; i < count; i++)
679 walk_type( f, base + i * ex, elemTy );
680
681 }
sewardj301a50f2006-03-03 16:14:18 +0000682}
683
sewardjc3a47092006-02-18 23:13:33 +0000684
sewardj558cc222006-03-10 14:51:19 +0000685/* Hook so it's visible from outside (can be handy to dlopen/dlsym
686 it) */
687void mpiwrap_walk_type_EXTERNALLY_VISIBLE
sewardjc0526f72006-03-08 03:54:37 +0000688 ( void(*f)(void*,long), char* base, MPI_Datatype ty )
689{
sewardjd465d992006-10-17 01:46:55 +0000690 walk_type(f, base, ty);
sewardjc0526f72006-03-08 03:54:37 +0000691}
692
693
sewardjc3a47092006-02-18 23:13:33 +0000694/*------------------------------------------------------------*/
695/*--- Address-range helpers ---*/
696/*------------------------------------------------------------*/
697
698/* ----------------
sewardjc3a47092006-02-18 23:13:33 +0000699 Do corresponding checks on memory areas defined using a
700 straightforward (start, length) description.
701 ----------------
702*/
703
sewardjd465d992006-10-17 01:46:55 +0000704static __inline__
njndbf7ca72006-03-31 11:57:59 +0000705void check_mem_is_defined_untyped ( void* buffer, long nbytes )
sewardjc3a47092006-02-18 23:13:33 +0000706{
707 if (nbytes > 0) {
njndbf7ca72006-03-31 11:57:59 +0000708 VALGRIND_CHECK_MEM_IS_DEFINED(buffer, nbytes);
sewardjc3a47092006-02-18 23:13:33 +0000709 }
710}
711
sewardjd465d992006-10-17 01:46:55 +0000712static __inline__
njndbf7ca72006-03-31 11:57:59 +0000713void check_mem_is_addressable_untyped ( void* buffer, long nbytes )
sewardjc3a47092006-02-18 23:13:33 +0000714{
715 if (nbytes > 0) {
njndbf7ca72006-03-31 11:57:59 +0000716 VALGRIND_CHECK_MEM_IS_ADDRESSABLE(buffer, nbytes);
sewardjc3a47092006-02-18 23:13:33 +0000717 }
718}
719
sewardjd465d992006-10-17 01:46:55 +0000720static __inline__
njndbf7ca72006-03-31 11:57:59 +0000721void make_mem_defined_if_addressable_untyped ( void* buffer, long nbytes )
sewardjc3a47092006-02-18 23:13:33 +0000722{
723 if (nbytes > 0) {
njndbf7ca72006-03-31 11:57:59 +0000724 VALGRIND_MAKE_MEM_DEFINED_IF_ADDRESSABLE(buffer, nbytes);
sewardjc3a47092006-02-18 23:13:33 +0000725 }
726}
727
sewardjd465d992006-10-17 01:46:55 +0000728static __inline__
njndbf7ca72006-03-31 11:57:59 +0000729void make_mem_defined_if_addressable_if_success_untyped ( int err,
sewardjcd8aaef2006-03-10 13:43:49 +0000730 void* buffer, long nbytes )
sewardjc3a47092006-02-18 23:13:33 +0000731{
732 if (err == MPI_SUCCESS && nbytes > 0) {
njndbf7ca72006-03-31 11:57:59 +0000733 VALGRIND_MAKE_MEM_DEFINED_IF_ADDRESSABLE(buffer, nbytes);
sewardjc3a47092006-02-18 23:13:33 +0000734 }
735}
736
737/* Set the specified area to 'addressible but undefined'
738 (safe-to-write) state. */
739
sewardjd465d992006-10-17 01:46:55 +0000740static __inline__
njndbf7ca72006-03-31 11:57:59 +0000741void make_mem_undefined_untyped ( void* buffer, long nbytes )
sewardjc3a47092006-02-18 23:13:33 +0000742{
743 if (nbytes > 0) {
njndbf7ca72006-03-31 11:57:59 +0000744 VALGRIND_MAKE_MEM_UNDEFINED(buffer, nbytes);
sewardjc3a47092006-02-18 23:13:33 +0000745 }
746}
747
748
sewardj301a50f2006-03-03 16:14:18 +0000749/* ----------------
750 Do checks on memory areas defined using the MPI (buffer, count,
751 type) convention.
752 ----------------
753*/
754
755/* Check that the specified area is both addressible and contains
756 initialised data, and cause V to complain if not. */
757
758static
njndbf7ca72006-03-31 11:57:59 +0000759void check_mem_is_defined ( char* buffer, long count, MPI_Datatype datatype )
sewardj301a50f2006-03-03 16:14:18 +0000760{
njndbf7ca72006-03-31 11:57:59 +0000761 walk_type_array( check_mem_is_defined_untyped, buffer, datatype, count );
sewardj301a50f2006-03-03 16:14:18 +0000762}
763
764
765/* Check that the specified area is addressible, and cause V to
766 complain if not. Doesn't matter whether the data there is
767 initialised or not. */
768
769static
njndbf7ca72006-03-31 11:57:59 +0000770void check_mem_is_addressable ( void *buffer, long count, MPI_Datatype datatype )
sewardj301a50f2006-03-03 16:14:18 +0000771{
njndbf7ca72006-03-31 11:57:59 +0000772 walk_type_array( check_mem_is_addressable_untyped, buffer, datatype, count );
sewardj301a50f2006-03-03 16:14:18 +0000773}
774
775
sewardjcd8aaef2006-03-10 13:43:49 +0000776/* Set the specified area to 'defined for each byte which is
777 addressible' state. */
sewardj301a50f2006-03-03 16:14:18 +0000778
779static
njndbf7ca72006-03-31 11:57:59 +0000780void make_mem_defined_if_addressable ( void *buffer, int count, MPI_Datatype datatype )
sewardj301a50f2006-03-03 16:14:18 +0000781{
njndbf7ca72006-03-31 11:57:59 +0000782 walk_type_array( make_mem_defined_if_addressable_untyped,
783 buffer, datatype, count );
sewardj301a50f2006-03-03 16:14:18 +0000784}
785
786static
787void
njndbf7ca72006-03-31 11:57:59 +0000788make_mem_defined_if_addressable_if_success ( int err, void *buffer, int count,
789 MPI_Datatype datatype )
sewardj301a50f2006-03-03 16:14:18 +0000790{
791 if (err == MPI_SUCCESS)
njndbf7ca72006-03-31 11:57:59 +0000792 make_mem_defined_if_addressable(buffer, count, datatype);
sewardj301a50f2006-03-03 16:14:18 +0000793}
794
795
sewardjc3a47092006-02-18 23:13:33 +0000796/*------------------------------------------------------------*/
797/*--- ---*/
798/*--- The wrappers proper. They are listed in the order ---*/
799/*--- in which they appear in "MPI: A Message-Passing ---*/
800/*--- Interface Standard, MPIF, Nov 15 2003" (the MPI 1.1 ---*/
801/*--- spec. All unimplemented wrappers are listed at the ---*/
802/*--- end of the file. The list of function names is ---*/
sewardj9c969c32006-03-10 18:37:45 +0000803/*--- taken from the headers of Open MPI svn r9191. ---*/
804/*--- Hopefully it is a complete list of all the MPI 2 ---*/
805/*--- functions. ---*/
sewardjc3a47092006-02-18 23:13:33 +0000806/*--- ---*/
807/*------------------------------------------------------------*/
808
809/* Handy abbreviation */
810#define WRAPPER_FOR(name) I_WRAP_FNNAME_U(name)
811
sewardjc3a47092006-02-18 23:13:33 +0000812/* Generates (conceptually) a wrapper which does nothing. In
813 fact just generate no wrapper at all. */
sewardj9c969c32006-03-10 18:37:45 +0000814#define HAS_NO_WRAPPER(basename) /* */
sewardjc3a47092006-02-18 23:13:33 +0000815
816
817/*------------------------------------------------------------*/
818/*--- ---*/
819/*--- Sec 3.2, Blocking Send and Receive Operations ---*/
820/*--- ---*/
821/*------------------------------------------------------------*/
822
sewardj9c969c32006-03-10 18:37:45 +0000823/* --- {,B,S,R}Send --- */
sewardjc3a47092006-02-18 23:13:33 +0000824/* pre: rd: (buf,count,datatype) */
sewardj9c969c32006-03-10 18:37:45 +0000825static
826int generic_Send(void *buf, int count, MPI_Datatype datatype,
827 int dest, int tag, MPI_Comm comm)
sewardjc3a47092006-02-18 23:13:33 +0000828{
829 OrigFn fn;
830 int err;
831 VALGRIND_GET_ORIG_FN(fn);
sewardj9c969c32006-03-10 18:37:45 +0000832 before("{,B,S,R}Send");
njndbf7ca72006-03-31 11:57:59 +0000833 check_mem_is_defined(buf, count, datatype);
sewardjc3a47092006-02-18 23:13:33 +0000834 CALL_FN_W_6W(err, fn, buf,count,datatype,dest,tag,comm);
sewardj9c969c32006-03-10 18:37:45 +0000835 after("{,B,S,R}Send", err);
sewardjc3a47092006-02-18 23:13:33 +0000836 return err;
837}
sewardj9c969c32006-03-10 18:37:45 +0000838int WRAPPER_FOR(PMPI_Send)(void *buf, int count, MPI_Datatype datatype,
839 int dest, int tag, MPI_Comm comm) {
840 return generic_Send(buf,count,datatype, dest,tag,comm);
841}
842int WRAPPER_FOR(PMPI_Bsend)(void *buf, int count, MPI_Datatype datatype,
843 int dest, int tag, MPI_Comm comm) {
844 return generic_Send(buf,count,datatype, dest,tag,comm);
845}
846int WRAPPER_FOR(PMPI_Ssend)(void *buf, int count, MPI_Datatype datatype,
847 int dest, int tag, MPI_Comm comm) {
848 return generic_Send(buf,count,datatype, dest,tag,comm);
849}
850int WRAPPER_FOR(PMPI_Rsend)(void *buf, int count, MPI_Datatype datatype,
851 int dest, int tag, MPI_Comm comm) {
852 return generic_Send(buf,count,datatype, dest,tag,comm);
853}
sewardjc3a47092006-02-18 23:13:33 +0000854
sewardjc3a47092006-02-18 23:13:33 +0000855/* --- Recv --- */
856/* pre: must be writable: (buf,count,datatype)
857 must be writable: status
858 post: make readable: (buf,recv_count,datatype)
859 where recv_count is determined from *status
860*/
861int WRAPPER_FOR(PMPI_Recv)(void *buf, int count, MPI_Datatype datatype,
862 int source, int tag,
863 MPI_Comm comm, MPI_Status *status)
864{
865 OrigFn fn;
866 int err, recv_count = 0;
867 VALGRIND_GET_ORIG_FN(fn);
868 before("Recv");
njndbf7ca72006-03-31 11:57:59 +0000869 check_mem_is_addressable(buf, count, datatype);
870 check_mem_is_addressable_untyped(status, sizeof(*status));
sewardjc3a47092006-02-18 23:13:33 +0000871 CALL_FN_W_7W(err, fn, buf,count,datatype,source,tag,comm,status);
872 if (err == MPI_SUCCESS && count_from_Status(&recv_count,datatype,status)) {
njndbf7ca72006-03-31 11:57:59 +0000873 make_mem_defined_if_addressable(buf, recv_count, datatype);
sewardjc3a47092006-02-18 23:13:33 +0000874 }
875 after("Recv", err);
876 return err;
877}
878
sewardj9c969c32006-03-10 18:37:45 +0000879/* --- Get_count --- */
880/* pre: must be readable: *status
881 post: make defined: *count -- don't bother, libmpi will surely do this
882*/
883int WRAPPER_FOR(PMPI_Get_count)(MPI_Status* status,
884 MPI_Datatype ty, int* count )
885{
886 OrigFn fn;
887 int err;
888 VALGRIND_GET_ORIG_FN(fn);
889 before("Get_count");
sewardjd465d992006-10-17 01:46:55 +0000890# if defined(_AIX)
891 check_mem_is_addressable_untyped(status, sizeof(*status));
892# else
njndbf7ca72006-03-31 11:57:59 +0000893 check_mem_is_defined_untyped(status, sizeof(*status));
sewardjd465d992006-10-17 01:46:55 +0000894# endif
sewardj9c969c32006-03-10 18:37:45 +0000895 CALL_FN_W_WWW(err, fn, status,ty,count);
896 after("Get_count", err);
897 return err;
898}
899
sewardjc3a47092006-02-18 23:13:33 +0000900
901/*------------------------------------------------------------*/
902/*--- ---*/
903/*--- Sec 3.7, Nonblocking communication ---*/
904/*--- ---*/
905/*------------------------------------------------------------*/
906
sewardj9c969c32006-03-10 18:37:45 +0000907/* Maintain a table that makes it possible for the wrappers to
908 complete MPI_Irecv successfully.
909
910 The issue is that MPI_Irecv states the recv buffer and returns
911 immediately, giving a handle (MPI_Request) for the transaction.
912 Later the user will have to poll for completion with MPI_Wait etc,
913 and at that point these wrappers have to paint the recv buffer.
914 But the recv buffer details are not presented to MPI_Wait - only
915 the handle is. We therefore have to use a shadow table
916 (sReqs{,_size,_used,_lock}) which associates uncompleted
917 MPI_Requests with the corresponding buffer address/count/type.
918
919 Only read requests are placed in the table, since there is no need
920 to do any buffer painting following completion of an Isend - all
921 the checks for that are done at the time Isend is called.
922
923 Care has to be take to remove completed requests from the table.
924
925 Access to the table is guarded by sReqs_lock so as to make it
926 thread-safe.
927*/
928
sewardjc3a47092006-02-18 23:13:33 +0000929typedef
930 struct {
931 Bool inUse;
932 MPI_Request key;
933 void* buf;
934 int count;
935 MPI_Datatype datatype;
936 }
937 ShadowRequest;
938
939static ShadowRequest* sReqs = NULL;
940static int sReqs_size = 0;
941static int sReqs_used = 0;
sewardj558cc222006-03-10 14:51:19 +0000942static pthread_mutex_t sReqs_lock = PTHREAD_MUTEX_INITIALIZER;
943
944#define LOCK_SREQS \
945 do { int pr = pthread_mutex_lock(&sReqs_lock); \
946 assert(pr == 0); \
947 } while (0)
948
949#define UNLOCK_SREQS \
950 do { int pr = pthread_mutex_unlock(&sReqs_lock); \
951 assert(pr == 0); \
952 } while (0)
sewardjc3a47092006-02-18 23:13:33 +0000953
954
955/* Ensure the sReqs expandable array has at least one free slot, by
956 copying it into a larger one if necessary. NOTE: sReqs_lock is
957 held throughout this procedure.*/
958static void ensure_sReq_space ( void )
959{
960 int i;
961 ShadowRequest* sReqs2;
962 if (sReqs_used == sReqs_size) {
963 sReqs_size = sReqs_size==0 ? 2 : 2*sReqs_size;
964 sReqs2 = malloc( sReqs_size * sizeof(ShadowRequest) );
965 if (sReqs2 == NULL) {
sewardj558cc222006-03-10 14:51:19 +0000966 UNLOCK_SREQS;
sewardjc3a47092006-02-18 23:13:33 +0000967 barf("add_shadow_Request: malloc failed.\n");
968 }
969 for (i = 0; i < sReqs_used; i++)
970 sReqs2[i] = sReqs[i];
971 if (sReqs)
972 free(sReqs);
973 sReqs = sReqs2;
974 }
975 assert(sReqs_used < sReqs_size);
976}
977
978
979/* Find shadow info for 'request', or NULL if none. */
980
981static
982ShadowRequest* find_shadow_Request ( MPI_Request request )
983{
984 ShadowRequest* ret = NULL;
985 int i;
sewardj558cc222006-03-10 14:51:19 +0000986 LOCK_SREQS;
sewardjc3a47092006-02-18 23:13:33 +0000987 for (i = 0; i < sReqs_used; i++) {
988 if (sReqs[i].inUse && eq_MPI_Request(sReqs[i].key,request)) {
989 ret = &sReqs[i];
990 break;
991 }
992 }
sewardj558cc222006-03-10 14:51:19 +0000993 UNLOCK_SREQS;
sewardjc3a47092006-02-18 23:13:33 +0000994 return ret;
995}
996
997
998/* Delete shadow info for 'request', if any. */
999
1000static void delete_shadow_Request ( MPI_Request request )
1001{
1002 int i;
sewardj558cc222006-03-10 14:51:19 +00001003 LOCK_SREQS;
sewardjc3a47092006-02-18 23:13:33 +00001004 for (i = 0; i < sReqs_used; i++) {
1005 if (sReqs[i].inUse && eq_MPI_Request(sReqs[i].key,request)) {
1006 sReqs[i].inUse = False;
1007 break;
1008 }
1009 }
sewardj558cc222006-03-10 14:51:19 +00001010 UNLOCK_SREQS;
sewardjc3a47092006-02-18 23:13:33 +00001011}
1012
1013
1014/* Add a shadow for 'request', overwriting any old binding for it. */
1015
1016static
1017void add_shadow_Request( MPI_Request request,
1018 void* buf, int count,
1019 MPI_Datatype datatype )
1020{
1021 int i, ix = -1;
sewardj558cc222006-03-10 14:51:19 +00001022 LOCK_SREQS;
sewardjc3a47092006-02-18 23:13:33 +00001023 assert(sReqs_used >= 0);
1024 assert(sReqs_size >= 0);
1025 assert(sReqs_used <= sReqs_size);
1026 if (sReqs == NULL) assert(sReqs_size == 0);
1027
1028 /* First of all see if we already have a binding for this key; if
1029 so just replace it, and have done. */
1030 for (i = 0; i < sReqs_used; i++) {
1031 if (sReqs[i].inUse && eq_MPI_Request(sReqs[i].key,request)) {
1032 ix = i;
1033 break;
1034 }
1035 }
1036
1037 if (ix < 0) {
1038 /* Ok, we don't have it, so will have to add it. First search
1039 to see if there is an existing empty slot. */
1040 for (i = 0; i < sReqs_used; i++) {
1041 if (!sReqs[i].inUse) {
1042 ix = i;
1043 break;
1044 }
1045 }
1046 }
1047
1048 /* No empty slots. Allocate a new one. */
1049 if (ix < 0) {
1050 ensure_sReq_space();
1051 assert(sReqs_used < sReqs_size);
1052 ix = sReqs_used;
1053 sReqs_used++;
1054 }
1055
1056 assert(ix >= 0 && ix < sReqs_used);
1057 assert(sReqs_used <= sReqs_size);
1058
1059 sReqs[ix].inUse = True;
1060 sReqs[ix].key = request;
1061 sReqs[ix].buf = buf;
1062 sReqs[ix].count = count;
1063 sReqs[ix].datatype = datatype;
1064
sewardj558cc222006-03-10 14:51:19 +00001065 UNLOCK_SREQS;
sewardjec8b6142006-03-09 03:05:17 +00001066 if (opt_verbosity > 1)
sewardjc3a47092006-02-18 23:13:33 +00001067 fprintf(stderr, "%s %5d: sReq+ 0x%lx -> b/c/d %p/%d/0x%lx [slot %d]\n",
1068 preamble, my_pid, (unsigned long)request,
1069 buf, count, (long)datatype, ix);
1070}
1071
sewardj9c969c32006-03-10 18:37:45 +00001072static
1073MPI_Request* clone_Request_array ( int count, MPI_Request* orig )
1074{
1075 MPI_Request* copy;
1076 int i;
1077 LOCK_SREQS;
1078 if (count < 0)
1079 count = 0; /* Hmm. Call Mulder and Scully. */
1080 copy = malloc( count * sizeof(MPI_Request) );
sewardjd465d992006-10-17 01:46:55 +00001081 if (copy == NULL && count > 0) {
sewardj9c969c32006-03-10 18:37:45 +00001082 UNLOCK_SREQS;
1083 barf("clone_Request_array: malloc failed");
1084 }
1085 for (i = 0; i < count; i++)
1086 copy[i] = orig[i];
1087 UNLOCK_SREQS;
1088 return copy;
1089}
1090
sewardj558cc222006-03-10 14:51:19 +00001091#undef LOCK_SREQS
1092#undef UNLOCK_SREQS
sewardjc3a47092006-02-18 23:13:33 +00001093
sewardj9c969c32006-03-10 18:37:45 +00001094
sewardjc3a47092006-02-18 23:13:33 +00001095static void maybe_complete ( Bool error_in_status,
1096 MPI_Request request_before,
1097 MPI_Request request_after,
1098 MPI_Status* status )
1099{
1100 int recv_count = 0;
1101 ShadowRequest* shadow;
1102 /* How do we know if this is an Irecv request that has now
1103 finished successfully?
1104
1105 request_before isn't MPI_REQUEST_NULL
1106 and request_before is found in the shadow table
1107 and request_after *is* MPI_REQUEST_NULL
1108 and (if error_in_status then status.MPI_ERROR is MPI_SUCCESS)
1109
1110 (when error_in_status == False, then we expect not to get
1111 called at all if there was an error.)
1112 */
1113 if (request_before != MPI_REQUEST_NULL
1114 && request_after == MPI_REQUEST_NULL
1115 && (error_in_status ? status->MPI_ERROR == MPI_SUCCESS : True)
1116 && ( (shadow=find_shadow_Request(request_before)) != NULL) ) {
sewardjb727b542006-03-10 21:41:01 +00001117 /* The Irecv detailed in 'shadow' completed. Paint the result
1118 buffer, and delete the entry. */
sewardjc3a47092006-02-18 23:13:33 +00001119 if (count_from_Status(&recv_count, shadow->datatype, status)) {
njndbf7ca72006-03-31 11:57:59 +00001120 make_mem_defined_if_addressable(shadow->buf, recv_count, shadow->datatype);
sewardjec8b6142006-03-09 03:05:17 +00001121 if (opt_verbosity > 1)
sewardjc3a47092006-02-18 23:13:33 +00001122 fprintf(stderr, "%s %5d: sReq- %p (completed)\n",
1123 preamble, my_pid, request_before);
1124 }
1125 delete_shadow_Request(request_before);
1126 }
1127}
1128
1129
sewardjc3a47092006-02-18 23:13:33 +00001130/* --- Isend --- */
1131/* rd: (buf,count,datatype) */
1132/* wr: *request */
sewardj9c969c32006-03-10 18:37:45 +00001133static
1134int generic_Isend(void *buf, int count, MPI_Datatype datatype,
1135 int dest, int tag, MPI_Comm comm,
1136 MPI_Request* request)
sewardjc3a47092006-02-18 23:13:33 +00001137{
1138 OrigFn fn;
1139 int err;
1140 VALGRIND_GET_ORIG_FN(fn);
sewardj9c969c32006-03-10 18:37:45 +00001141 before("{,B,S,R}Isend");
njndbf7ca72006-03-31 11:57:59 +00001142 check_mem_is_defined(buf, count, datatype);
1143 check_mem_is_addressable_untyped(request, sizeof(*request));
sewardjc3a47092006-02-18 23:13:33 +00001144 CALL_FN_W_7W(err, fn, buf,count,datatype,dest,tag,comm,request);
njndbf7ca72006-03-31 11:57:59 +00001145 make_mem_defined_if_addressable_if_success_untyped(err, request, sizeof(*request));
sewardj9c969c32006-03-10 18:37:45 +00001146 after("{,B,S,R}Isend", err);
sewardjc3a47092006-02-18 23:13:33 +00001147 return err;
1148}
sewardj9c969c32006-03-10 18:37:45 +00001149int WRAPPER_FOR(PMPI_Isend)(void *buf, int count, MPI_Datatype datatype,
1150 int dest, int tag, MPI_Comm comm,
1151 MPI_Request* request) {
1152 return generic_Isend(buf,count,datatype, dest,tag,comm, request);
1153}
1154int WRAPPER_FOR(PMPI_Ibsend)(void *buf, int count, MPI_Datatype datatype,
1155 int dest, int tag, MPI_Comm comm,
1156 MPI_Request* request) {
1157 return generic_Isend(buf,count,datatype, dest,tag,comm, request);
1158}
1159int WRAPPER_FOR(PMPI_Issend)(void *buf, int count, MPI_Datatype datatype,
1160 int dest, int tag, MPI_Comm comm,
1161 MPI_Request* request) {
1162 return generic_Isend(buf,count,datatype, dest,tag,comm, request);
1163}
1164int WRAPPER_FOR(PMPI_Irsend)(void *buf, int count, MPI_Datatype datatype,
1165 int dest, int tag, MPI_Comm comm,
1166 MPI_Request* request) {
1167 return generic_Isend(buf,count,datatype, dest,tag,comm, request);
1168}
1169
sewardjc3a47092006-02-18 23:13:33 +00001170
sewardjc3a47092006-02-18 23:13:33 +00001171/* --- Irecv --- */
1172/* pre: must be writable: (buf,count,datatype), *request
1173 post: make readable *request
1174 add a request->(buf,count,ty) binding to the
1175 shadow request table.
1176*/
1177int WRAPPER_FOR(PMPI_Irecv)( void* buf, int count, MPI_Datatype datatype,
1178 int source, int tag, MPI_Comm comm,
1179 MPI_Request* request )
1180{
1181 OrigFn fn;
1182 int err;
1183 VALGRIND_GET_ORIG_FN(fn);
1184 before("Irecv");
njndbf7ca72006-03-31 11:57:59 +00001185 check_mem_is_addressable(buf, count, datatype);
1186 check_mem_is_addressable_untyped(request, sizeof(*request));
sewardjc3a47092006-02-18 23:13:33 +00001187 CALL_FN_W_7W(err, fn, buf,count,datatype,source,tag,comm,request);
1188 if (err == MPI_SUCCESS) {
njndbf7ca72006-03-31 11:57:59 +00001189 make_mem_defined_if_addressable_untyped(request, sizeof(*request));
sewardjc3a47092006-02-18 23:13:33 +00001190 add_shadow_Request( *request, buf,count,datatype );
1191 }
1192 after("Irecv", err);
1193 return err;
1194}
1195
sewardjc3a47092006-02-18 23:13:33 +00001196/* --- Wait --- */
sewardjb727b542006-03-10 21:41:01 +00001197/* The MPI1 spec (imprecisely) defines 3 request states:
1198 - "null" if the request is MPI_REQUEST_NULL
1199 - "inactive" if not "null" and not associated with ongoing comms
1200 - "active" if not "null" and is associated with ongoing comms
1201*/
sewardjc3a47092006-02-18 23:13:33 +00001202int WRAPPER_FOR(PMPI_Wait)( MPI_Request* request,
1203 MPI_Status* status )
1204{
1205 MPI_Request request_before;
1206 OrigFn fn;
1207 int err;
1208 VALGRIND_GET_ORIG_FN(fn);
1209 before("Wait");
njndbf7ca72006-03-31 11:57:59 +00001210 check_mem_is_addressable_untyped(status, sizeof(MPI_Status));
1211 check_mem_is_defined_untyped(request, sizeof(MPI_Request));
sewardjc3a47092006-02-18 23:13:33 +00001212 request_before = *request;
1213 CALL_FN_W_WW(err, fn, request,status);
1214 if (err == MPI_SUCCESS) {
1215 maybe_complete(False/*err in status?*/,
1216 request_before, *request, status);
njndbf7ca72006-03-31 11:57:59 +00001217 make_mem_defined_if_addressable_untyped(status, sizeof(MPI_Status));
sewardjc3a47092006-02-18 23:13:33 +00001218 }
1219 after("Wait", err);
1220 return err;
1221}
1222
sewardjc3a47092006-02-18 23:13:33 +00001223/* --- Waitall --- */
1224int WRAPPER_FOR(PMPI_Waitall)( int count,
1225 MPI_Request* requests,
1226 MPI_Status* statuses )
1227{
1228 MPI_Request* requests_before = NULL;
1229 OrigFn fn;
1230 int err, i;
1231 VALGRIND_GET_ORIG_FN(fn);
1232 before("Waitall");
1233 if (0) fprintf(stderr, "Waitall: %d\n", count);
1234 for (i = 0; i < count; i++) {
njndbf7ca72006-03-31 11:57:59 +00001235 check_mem_is_addressable_untyped(&statuses[i], sizeof(MPI_Status));
1236 check_mem_is_defined_untyped(&requests[i], sizeof(MPI_Request));
sewardjc3a47092006-02-18 23:13:33 +00001237 }
1238 requests_before = clone_Request_array( count, requests );
1239 CALL_FN_W_WWW(err, fn, count,requests,statuses);
1240 if (err == MPI_SUCCESS /*complete success*/
1241 || err == MPI_ERR_IN_STATUS /* partial success */) {
1242 Bool e_i_s = err == MPI_ERR_IN_STATUS;
1243 for (i = 0; i < count; i++) {
1244 maybe_complete(e_i_s, requests_before[i], requests[i],
1245 &statuses[i]);
njndbf7ca72006-03-31 11:57:59 +00001246 make_mem_defined_if_addressable_untyped(&statuses[i],
1247 sizeof(MPI_Status));
sewardjc3a47092006-02-18 23:13:33 +00001248 }
1249 }
1250 if (requests_before)
1251 free(requests_before);
1252 after("Waitall", err);
1253 return err;
1254}
1255
sewardjb727b542006-03-10 21:41:01 +00001256/* --- Test --- */
1257/* nonblocking version of Wait */
1258int WRAPPER_FOR(PMPI_Test)( MPI_Request* request, int* flag,
1259 MPI_Status* status )
1260{
1261 MPI_Request request_before;
1262 OrigFn fn;
1263 int err;
1264 VALGRIND_GET_ORIG_FN(fn);
1265 before("Test");
njndbf7ca72006-03-31 11:57:59 +00001266 check_mem_is_addressable_untyped(status, sizeof(MPI_Status));
1267 check_mem_is_addressable_untyped(flag, sizeof(int));
1268 check_mem_is_defined_untyped(request, sizeof(MPI_Request));
sewardjb727b542006-03-10 21:41:01 +00001269 request_before = *request;
1270 CALL_FN_W_WWW(err, fn, request,flag,status);
1271 if (err == MPI_SUCCESS && *flag) {
1272 maybe_complete(False/*err in status?*/,
1273 request_before, *request, status);
njndbf7ca72006-03-31 11:57:59 +00001274 make_mem_defined_if_addressable_untyped(status, sizeof(MPI_Status));
sewardjb727b542006-03-10 21:41:01 +00001275 }
1276 after("Test", err);
1277 return err;
1278}
1279
1280/* --- Testall --- */
1281/* nonblocking version of Waitall */
1282int WRAPPER_FOR(PMPI_Testall)( int count, MPI_Request* requests,
1283 int* flag, MPI_Status* statuses )
1284{
1285 MPI_Request* requests_before = NULL;
1286 OrigFn fn;
1287 int err, i;
1288 VALGRIND_GET_ORIG_FN(fn);
1289 before("Testall");
1290 if (0) fprintf(stderr, "Testall: %d\n", count);
njndbf7ca72006-03-31 11:57:59 +00001291 check_mem_is_addressable_untyped(flag, sizeof(int));
sewardjb727b542006-03-10 21:41:01 +00001292 for (i = 0; i < count; i++) {
njndbf7ca72006-03-31 11:57:59 +00001293 check_mem_is_addressable_untyped(&statuses[i], sizeof(MPI_Status));
1294 check_mem_is_defined_untyped(&requests[i], sizeof(MPI_Request));
sewardjb727b542006-03-10 21:41:01 +00001295 }
1296 requests_before = clone_Request_array( count, requests );
1297 CALL_FN_W_WWWW(err, fn, count,requests,flag,statuses);
1298 /* Urk. Is the following "if (...)" really right? I don't know. */
1299 if (*flag
1300 && (err == MPI_SUCCESS /*complete success*/
1301 || err == MPI_ERR_IN_STATUS /* partial success */)) {
1302 Bool e_i_s = err == MPI_ERR_IN_STATUS;
1303 for (i = 0; i < count; i++) {
1304 maybe_complete(e_i_s, requests_before[i], requests[i],
1305 &statuses[i]);
njndbf7ca72006-03-31 11:57:59 +00001306 make_mem_defined_if_addressable_untyped(&statuses[i], sizeof(MPI_Status));
sewardjb727b542006-03-10 21:41:01 +00001307 }
1308 }
1309 if (requests_before)
1310 free(requests_before);
1311 after("Testall", err);
1312 return err;
1313}
1314
sewardjc3a47092006-02-18 23:13:33 +00001315/* --- Iprobe --- */
sewardjc3a47092006-02-18 23:13:33 +00001316/* pre: must-be-writable: *flag, *status */
1317/* post: make-readable *flag
sewardjb727b542006-03-10 21:41:01 +00001318 if *flag==True make-defined *status */
sewardjc3a47092006-02-18 23:13:33 +00001319int WRAPPER_FOR(PMPI_Iprobe)(int source, int tag,
1320 MPI_Comm comm,
1321 int* flag, MPI_Status* status)
1322{
1323 OrigFn fn;
1324 int err;
1325 VALGRIND_GET_ORIG_FN(fn);
1326 before("Iprobe");
njndbf7ca72006-03-31 11:57:59 +00001327 check_mem_is_addressable_untyped(flag, sizeof(*flag));
1328 check_mem_is_addressable_untyped(status, sizeof(*status));
sewardjc3a47092006-02-18 23:13:33 +00001329 CALL_FN_W_5W(err, fn, source,tag,comm,flag,status);
1330 if (err == MPI_SUCCESS) {
njndbf7ca72006-03-31 11:57:59 +00001331 make_mem_defined_if_addressable_untyped(flag, sizeof(*flag));
sewardjc3a47092006-02-18 23:13:33 +00001332 if (*flag)
njndbf7ca72006-03-31 11:57:59 +00001333 make_mem_defined_if_addressable_untyped(status, sizeof(*status));
sewardjc3a47092006-02-18 23:13:33 +00001334 }
1335 after("Iprobe", err);
1336 return err;
1337}
1338
sewardjb727b542006-03-10 21:41:01 +00001339/* --- Probe --- */
1340/* pre: must-be-writable *status */
1341/* post: make-defined *status */
1342int WRAPPER_FOR(PMPI_Probe)(int source, int tag,
1343 MPI_Comm comm, MPI_Status* status)
1344{
1345 OrigFn fn;
1346 int err;
1347 VALGRIND_GET_ORIG_FN(fn);
1348 before("Probe");
njndbf7ca72006-03-31 11:57:59 +00001349 check_mem_is_addressable_untyped(status, sizeof(*status));
sewardjb727b542006-03-10 21:41:01 +00001350 CALL_FN_W_WWWW(err, fn, source,tag,comm,status);
njndbf7ca72006-03-31 11:57:59 +00001351 make_mem_defined_if_addressable_if_success_untyped(err, status, sizeof(*status));
sewardjb727b542006-03-10 21:41:01 +00001352 after("Probe", err);
1353 return err;
1354}
1355
1356/* --- Cancel --- */
1357/* Wrapping PMPI_Cancel is interesting only to the extent that we need
1358 to be able to detect when a request should be removed from our
1359 shadow table due to cancellation. */
1360int WRAPPER_FOR(PMPI_Cancel)(MPI_Request* request)
1361{
1362 OrigFn fn;
1363 int err;
1364 MPI_Request tmp;
1365 VALGRIND_GET_ORIG_FN(fn);
1366 before("Cancel");
njndbf7ca72006-03-31 11:57:59 +00001367 check_mem_is_addressable_untyped(request, sizeof(*request));
sewardjb727b542006-03-10 21:41:01 +00001368 tmp = *request;
1369 CALL_FN_W_W(err, fn, request);
1370 if (err == MPI_SUCCESS)
1371 delete_shadow_Request(tmp);
1372 after("Cancel", err);
1373 return err;
1374}
1375
sewardjc3a47092006-02-18 23:13:33 +00001376
1377/*------------------------------------------------------------*/
1378/*--- ---*/
1379/*--- Sec 3.10, Send-receive ---*/
1380/*--- ---*/
1381/*------------------------------------------------------------*/
1382
1383/* --- Sendrecv --- */
1384/* pre: must be readable: (sendbuf,sendcount,sendtype)
1385 must be writable: (recvbuf,recvcount,recvtype)
1386 post: make readable: (recvbuf,recvcount_actual,datatype)
1387 where recvcount_actual is determined from *status
1388*/
1389int WRAPPER_FOR(PMPI_Sendrecv)(
1390 void *sendbuf, int sendcount, MPI_Datatype sendtype,
1391 int dest, int sendtag,
1392 void *recvbuf, int recvcount, MPI_Datatype recvtype,
1393 int source, int recvtag,
1394 MPI_Comm comm, MPI_Status *status)
1395{
1396 OrigFn fn;
1397 int err, recvcount_actual = 0;
1398 VALGRIND_GET_ORIG_FN(fn);
1399 before("Sendrecv");
njndbf7ca72006-03-31 11:57:59 +00001400 check_mem_is_defined(sendbuf, sendcount, sendtype);
1401 check_mem_is_addressable(recvbuf, recvcount, recvtype);
sewardjc3a47092006-02-18 23:13:33 +00001402 CALL_FN_W_12W(err, fn, sendbuf,sendcount,sendtype,dest,sendtag,
1403 recvbuf,recvcount,recvtype,source,recvtag,
1404 comm,status);
1405 if (err == MPI_SUCCESS
1406 && count_from_Status(&recvcount_actual,recvtype,status)) {
njndbf7ca72006-03-31 11:57:59 +00001407 make_mem_defined_if_addressable(recvbuf, recvcount_actual, recvtype);
sewardjc3a47092006-02-18 23:13:33 +00001408 }
1409 after("Sendrecv", err);
1410 return err;
1411}
1412
sewardjc3a47092006-02-18 23:13:33 +00001413
1414/*------------------------------------------------------------*/
1415/*--- ---*/
1416/*--- Sec 3.12, Derived datatypes ---*/
1417/*--- ---*/
1418/*------------------------------------------------------------*/
1419
1420/* --- Address --- */
1421/* Does this have anything worth checking? */
sewardj9c969c32006-03-10 18:37:45 +00001422HAS_NO_WRAPPER(Address)
1423
1424/* --- MPI 2 stuff --- */
1425/* Type_extent, Type_get_contents and Type_get_envelope sometimes get
1426 used intensively by the type walker (walk_type). There's no reason
1427 why they couldn't be properly wrapped if needed, but doing so slows
1428 everything down, so don't bother until needed. */
1429HAS_NO_WRAPPER(Type_extent)
1430HAS_NO_WRAPPER(Type_get_contents)
1431HAS_NO_WRAPPER(Type_get_envelope)
1432
1433/* --- Type_commit --- */
1434int WRAPPER_FOR(PMPI_Type_commit)( MPI_Datatype* ty )
1435{
1436 OrigFn fn;
1437 int err;
1438 VALGRIND_GET_ORIG_FN(fn);
1439 before("Type_commit");
njndbf7ca72006-03-31 11:57:59 +00001440 check_mem_is_defined_untyped(ty, sizeof(*ty));
sewardj9c969c32006-03-10 18:37:45 +00001441 CALL_FN_W_W(err, fn, ty);
1442 after("Type_commit", err);
1443 return err;
1444}
1445
1446/* --- Type_free --- */
1447int WRAPPER_FOR(PMPI_Type_free)( MPI_Datatype* ty )
1448{
1449 OrigFn fn;
1450 int err;
1451 VALGRIND_GET_ORIG_FN(fn);
1452 before("Type_free");
njndbf7ca72006-03-31 11:57:59 +00001453 check_mem_is_defined_untyped(ty, sizeof(*ty));
sewardj9c969c32006-03-10 18:37:45 +00001454 CALL_FN_W_W(err, fn, ty);
1455 after("Type_free", err);
1456 return err;
1457}
sewardjc3a47092006-02-18 23:13:33 +00001458
1459
1460/*------------------------------------------------------------*/
1461/*--- ---*/
1462/*--- Sec 4.4, Broadcast ---*/
1463/*--- ---*/
1464/*------------------------------------------------------------*/
1465
1466/* --- Bcast --- */
1467/* pre: must-be-readable (buffer,count,datatype) for rank==root
1468 must-be-writable (buffer,count,datatype) for rank!=root
1469 post: make-readable (buffer,count,datatype) for all
1470
1471 Resulting behaviour is: if root sends uninitialised stuff, then
1472 V complains, but then all ranks, including itself, see the buffer
1473 as initialised after that.
1474*/
1475int WRAPPER_FOR(PMPI_Bcast)(void *buffer, int count,
1476 MPI_Datatype datatype,
1477 int root, MPI_Comm comm)
1478{
1479 OrigFn fn;
1480 int err;
1481 Bool i_am_sender;
1482 VALGRIND_GET_ORIG_FN(fn);
1483 before("Bcast");
1484 i_am_sender = root == comm_rank(comm);
1485 if (i_am_sender) {
njndbf7ca72006-03-31 11:57:59 +00001486 check_mem_is_defined(buffer, count, datatype);
sewardjc3a47092006-02-18 23:13:33 +00001487 } else {
njndbf7ca72006-03-31 11:57:59 +00001488 check_mem_is_addressable(buffer, count, datatype);
sewardjc3a47092006-02-18 23:13:33 +00001489 }
1490 CALL_FN_W_5W(err, fn, buffer,count,datatype,root,comm);
njndbf7ca72006-03-31 11:57:59 +00001491 make_mem_defined_if_addressable_if_success(err, buffer, count, datatype);
sewardjc3a47092006-02-18 23:13:33 +00001492 after("Bcast", err);
1493 return err;
1494}
1495
1496
1497/*------------------------------------------------------------*/
1498/*--- ---*/
1499/*--- Sec 4.5, Gather ---*/
1500/*--- ---*/
1501/*------------------------------------------------------------*/
1502
1503/* --- Gather --- */
1504/* JRS 20060217: I don't really understand this. Each process is
1505 going to send sendcount items of type sendtype to the root. So
1506 the root is going to receive comm_size*sendcount items of type
1507 sendtype (right?) So why specify recvcount and recvtype?
1508
1509 Anyway, assuming the MPI Spec is correct (seems likely :-) we have:
1510
1511 pre: (all) must be readable: (sendbuf,sendcount,sendtype)
1512 (root only): must be writable: (recvbuf,recvcount * comm_size,recvtype)
1513 post: (root only): make readable: (recvbuf,recvcount * comm_size,recvtype)
1514*/
1515int WRAPPER_FOR(PMPI_Gather)(
1516 void *sendbuf, int sendcount, MPI_Datatype sendtype,
1517 void *recvbuf, int recvcount, MPI_Datatype recvtype,
1518 int root, MPI_Comm comm)
1519{
1520 OrigFn fn;
1521 int err, me, sz;
1522 VALGRIND_GET_ORIG_FN(fn);
1523 before("Gather");
1524 me = comm_rank(comm);
1525 sz = comm_size(comm);
njndbf7ca72006-03-31 11:57:59 +00001526 check_mem_is_defined(sendbuf, sendcount, sendtype);
sewardjc3a47092006-02-18 23:13:33 +00001527 if (me == root)
njndbf7ca72006-03-31 11:57:59 +00001528 check_mem_is_addressable(recvbuf, recvcount * sz, recvtype);
sewardjc3a47092006-02-18 23:13:33 +00001529 CALL_FN_W_8W(err, fn, sendbuf,sendcount,sendtype,
1530 recvbuf,recvcount,recvtype,
1531 root,comm);
sewardjb727b542006-03-10 21:41:01 +00001532 if (me == root)
njndbf7ca72006-03-31 11:57:59 +00001533 make_mem_defined_if_addressable_if_success(err, recvbuf, recvcount * sz, recvtype);
sewardjc3a47092006-02-18 23:13:33 +00001534 after("Gather", err);
1535 return err;
1536}
1537
1538
1539/*------------------------------------------------------------*/
1540/*--- ---*/
sewardjb727b542006-03-10 21:41:01 +00001541/*--- Sec 4.6, Scatter ---*/
1542/*--- ---*/
1543/*------------------------------------------------------------*/
1544
1545/* pre: (root only): must be readable: (sendbuf,sendcount * comm_size,sendtype)
1546 (all): must be writable: (recvbuf,recvbuf,recvtype)
1547 post: (all): make defined: (recvbuf,recvbuf,recvtype)
1548*/
1549int WRAPPER_FOR(PMPI_Scatter)(
1550 void* sendbuf, int sendcount, MPI_Datatype sendtype,
1551 void* recvbuf, int recvcount, MPI_Datatype recvtype,
1552 int root, MPI_Comm comm)
1553{
1554 OrigFn fn;
1555 int err, me, sz;
1556 VALGRIND_GET_ORIG_FN(fn);
1557 before("Scatter");
1558 me = comm_rank(comm);
1559 sz = comm_size(comm);
njndbf7ca72006-03-31 11:57:59 +00001560 check_mem_is_addressable(recvbuf, recvcount, recvtype);
sewardjb727b542006-03-10 21:41:01 +00001561 if (me == root)
njndbf7ca72006-03-31 11:57:59 +00001562 check_mem_is_defined(sendbuf, sendcount * sz, sendtype);
sewardjb727b542006-03-10 21:41:01 +00001563 CALL_FN_W_8W(err, fn, sendbuf,sendcount,sendtype,
1564 recvbuf,recvcount,recvtype,
1565 root,comm);
njndbf7ca72006-03-31 11:57:59 +00001566 make_mem_defined_if_addressable_if_success(err, recvbuf, recvcount, recvtype);
sewardjb727b542006-03-10 21:41:01 +00001567 after("Scatter", err);
1568 return err;
1569}
1570
1571
1572/*------------------------------------------------------------*/
1573/*--- ---*/
1574/*--- Sec 4.8, All-to-All Scatter/Gather ---*/
1575/*--- ---*/
1576/*------------------------------------------------------------*/
1577
1578/* pre: (all) must be readable: (sendbuf,sendcount * comm_size,sendtype)
1579 (all) must be writable: (recvbuf,recvcount * comm_size,recvtype)
1580 post: (all) make defined: (recvbuf,recvcount * comm_size,recvtype)
1581*/
1582int WRAPPER_FOR(PMPI_Alltoall)(
1583 void* sendbuf, int sendcount, MPI_Datatype sendtype,
1584 void* recvbuf, int recvcount, MPI_Datatype recvtype,
1585 MPI_Comm comm)
1586{
1587 OrigFn fn;
1588 int err, sz;
1589 VALGRIND_GET_ORIG_FN(fn);
1590 before("Alltoall");
1591 sz = comm_size(comm);
njndbf7ca72006-03-31 11:57:59 +00001592 check_mem_is_defined(sendbuf, sendcount * sz, sendtype);
1593 check_mem_is_addressable(recvbuf, recvcount * sz, recvtype);
sewardjb727b542006-03-10 21:41:01 +00001594 CALL_FN_W_7W(err, fn, sendbuf,sendcount,sendtype,
1595 recvbuf,recvcount,recvtype,
1596 comm);
njndbf7ca72006-03-31 11:57:59 +00001597 make_mem_defined_if_addressable_if_success(err, recvbuf, recvcount * sz, recvtype);
sewardjb727b542006-03-10 21:41:01 +00001598 after("Alltoall", err);
1599 return err;
1600}
1601
1602
1603/*------------------------------------------------------------*/
1604/*--- ---*/
sewardjc3a47092006-02-18 23:13:33 +00001605/*--- Sec 4.9, Global Reduction Operations ---*/
1606/*--- ---*/
1607/*------------------------------------------------------------*/
1608
1609/* --- Reduce --- */
1610/* rd: (sendbuf,count,datatype) for all
1611 wr: (recvbuf,count,datatype) but only for rank == root
1612*/
1613int WRAPPER_FOR(PMPI_Reduce)(void *sendbuf, void *recvbuf,
1614 int count,
1615 MPI_Datatype datatype, MPI_Op op,
1616 int root, MPI_Comm comm)
1617{
1618 OrigFn fn;
1619 int err;
1620 Bool i_am_root;
1621 VALGRIND_GET_ORIG_FN(fn);
1622 before("Reduce");
1623 i_am_root = root == comm_rank(comm);
njndbf7ca72006-03-31 11:57:59 +00001624 check_mem_is_defined(sendbuf, count, datatype);
sewardjc3a47092006-02-18 23:13:33 +00001625 if (i_am_root)
njndbf7ca72006-03-31 11:57:59 +00001626 check_mem_is_addressable(recvbuf, count, datatype);
sewardjc3a47092006-02-18 23:13:33 +00001627 CALL_FN_W_7W(err, fn, sendbuf,recvbuf,count,datatype,op,root,comm);
1628 if (i_am_root)
njndbf7ca72006-03-31 11:57:59 +00001629 make_mem_defined_if_addressable_if_success(err, recvbuf, count, datatype);
sewardjc3a47092006-02-18 23:13:33 +00001630 after("Reduce", err);
1631 return err;
1632}
1633
1634
1635/* --- Allreduce --- */
1636/* rd: (sendbuf,count,datatype) for all
1637 wr: (recvbuf,count,datatype) for all
1638*/
1639int WRAPPER_FOR(PMPI_Allreduce)(void *sendbuf, void *recvbuf,
1640 int count,
1641 MPI_Datatype datatype, MPI_Op op,
1642 MPI_Comm comm)
1643{
1644 OrigFn fn;
1645 int err;
1646 VALGRIND_GET_ORIG_FN(fn);
1647 before("Allreduce");
njndbf7ca72006-03-31 11:57:59 +00001648 check_mem_is_defined(sendbuf, count, datatype);
1649 check_mem_is_addressable(recvbuf, count, datatype);
sewardjc3a47092006-02-18 23:13:33 +00001650 CALL_FN_W_6W(err, fn, sendbuf,recvbuf,count,datatype,op,comm);
njndbf7ca72006-03-31 11:57:59 +00001651 make_mem_defined_if_addressable_if_success(err, recvbuf, count, datatype);
sewardjc3a47092006-02-18 23:13:33 +00001652 after("Allreduce", err);
1653 return err;
1654}
1655
1656
1657/* --- Op_create --- */
1658/* This is a bit dubious. I suppose it takes 'function' and
1659 writes something at *op, but who knows what an MPI_Op is?
1660 Can we safely do 'sizeof' on it? */
1661int WRAPPER_FOR(PMPI_Op_create)( MPI_User_function* function,
1662 int commute,
1663 MPI_Op* op )
1664{
1665 OrigFn fn;
1666 int err;
1667 VALGRIND_GET_ORIG_FN(fn);
1668 before("Op_create");
njndbf7ca72006-03-31 11:57:59 +00001669 check_mem_is_addressable_untyped(op, sizeof(*op));
sewardjc3a47092006-02-18 23:13:33 +00001670 CALL_FN_W_WWW(err, fn, function,commute,op);
njndbf7ca72006-03-31 11:57:59 +00001671 make_mem_defined_if_addressable_if_success_untyped(err, op, sizeof(*op));
sewardjc3a47092006-02-18 23:13:33 +00001672 after("Op_create", err);
1673 return err;
1674}
1675
1676
1677/*------------------------------------------------------------*/
1678/*--- ---*/
1679/*--- Sec 5.4, Communicator management ---*/
1680/*--- ---*/
1681/*------------------------------------------------------------*/
1682
1683/* Hardly seems worth wrapping Comm_rank and Comm_size, but
1684 since it's done now .. */
1685
sewardj9c969c32006-03-10 18:37:45 +00001686/* --- Comm_create --- */
1687/* Let normal memcheck tracking handle this. */
1688int WRAPPER_FOR(PMPI_Comm_create)(MPI_Comm comm, MPI_Group group,
1689 MPI_Comm* newcomm)
1690{
1691 OrigFn fn;
1692 int err;
1693 VALGRIND_GET_ORIG_FN(fn);
1694 before("Comm_create");
1695 CALL_FN_W_WWW(err, fn, comm,group,newcomm);
1696 after("Comm_create", err);
1697 return err;
1698}
1699
1700/* --- Comm_dup --- */
1701/* Let normal memcheck tracking handle this. */
1702int WRAPPER_FOR(PMPI_Comm_dup)(MPI_Comm comm, MPI_Comm* newcomm)
1703{
1704 OrigFn fn;
1705 int err;
1706 VALGRIND_GET_ORIG_FN(fn);
1707 before("Comm_dup");
1708 CALL_FN_W_WW(err, fn, comm,newcomm);
1709 after("Comm_dup", err);
1710 return err;
1711}
1712
1713/* --- Comm_free --- */
1714/* Let normal memcheck tracking handle this. */
1715int WRAPPER_FOR(PMPI_Comm_free)(MPI_Comm* comm)
1716{
1717 OrigFn fn;
1718 int err;
1719 VALGRIND_GET_ORIG_FN(fn);
1720 before("Comm_free");
1721 CALL_FN_W_W(err, fn, comm);
1722 after("Comm_free", err);
1723 return err;
1724}
1725
sewardjc3a47092006-02-18 23:13:33 +00001726/* --- Comm_rank --- */
1727/* wr: (rank, sizeof(*rank)) */
1728int WRAPPER_FOR(PMPI_Comm_rank)(MPI_Comm comm, int *rank)
1729{
1730 OrigFn fn;
1731 int err;
1732 VALGRIND_GET_ORIG_FN(fn);
1733 before("Comm_rank");
njndbf7ca72006-03-31 11:57:59 +00001734 check_mem_is_addressable_untyped(rank, sizeof(*rank));
sewardjc3a47092006-02-18 23:13:33 +00001735 CALL_FN_W_WW(err, fn, comm,rank);
njndbf7ca72006-03-31 11:57:59 +00001736 make_mem_defined_if_addressable_if_success_untyped(err, rank, sizeof(*rank));
sewardjc3a47092006-02-18 23:13:33 +00001737 after("Comm_rank", err);
1738 return err;
1739}
1740
sewardjc3a47092006-02-18 23:13:33 +00001741/* --- Comm_size --- */
1742/* wr: (size, sizeof(*size)) */
1743int WRAPPER_FOR(PMPI_Comm_size)(MPI_Comm comm, int *size)
1744{
1745 OrigFn fn;
1746 int err;
1747 VALGRIND_GET_ORIG_FN(fn);
1748 before("Comm_size");
njndbf7ca72006-03-31 11:57:59 +00001749 check_mem_is_addressable_untyped(size, sizeof(*size));
sewardjc3a47092006-02-18 23:13:33 +00001750 CALL_FN_W_WW(err, fn, comm,size);
njndbf7ca72006-03-31 11:57:59 +00001751 make_mem_defined_if_addressable_if_success_untyped(err, size, sizeof(*size));
sewardjc3a47092006-02-18 23:13:33 +00001752 after("Comm_size", err);
1753 return err;
1754}
1755
1756
1757/*------------------------------------------------------------*/
1758/*--- ---*/
1759/*--- Sec 5.7, Caching ---*/
1760/*--- ---*/
1761/*------------------------------------------------------------*/
1762
sewardjc3a47092006-02-18 23:13:33 +00001763
1764/*------------------------------------------------------------*/
1765/*--- ---*/
sewardj7d3f4bb2006-03-08 15:27:37 +00001766/*--- Sec 7.3, Error codes and classes ---*/
1767/*--- ---*/
1768/*------------------------------------------------------------*/
1769
1770/* --- Error_string --- */
sewardj9c969c32006-03-10 18:37:45 +00001771int WRAPPER_FOR(PMPI_Error_string)( int errorcode, char* string,
1772 int* resultlen )
sewardj7d3f4bb2006-03-08 15:27:37 +00001773{
1774 OrigFn fn;
1775 int err;
1776 VALGRIND_GET_ORIG_FN(fn);
1777 before("Error_string");
njndbf7ca72006-03-31 11:57:59 +00001778 check_mem_is_addressable_untyped(resultlen, sizeof(int));
1779 check_mem_is_addressable_untyped(string, MPI_MAX_ERROR_STRING);
sewardj7d3f4bb2006-03-08 15:27:37 +00001780 CALL_FN_W_WWW(err, fn, errorcode,string,resultlen);
1781 /* Don't bother to paint the result; we assume the real function
1782 will have filled it with defined characters :-) */
1783 after("Error_string", err);
1784 return err;
1785}
1786
1787
1788/*------------------------------------------------------------*/
1789/*--- ---*/
sewardjc3a47092006-02-18 23:13:33 +00001790/*--- Sec 7.5, Startup ---*/
1791/*--- ---*/
1792/*------------------------------------------------------------*/
1793
1794/* --- Init --- */
1795/* rd: *argc, *argv[0 .. *argc-1] */
sewardjd465d992006-10-17 01:46:55 +00001796long WRAPPER_FOR(PMPI_Init)(int *argc, char ***argv)
sewardjc3a47092006-02-18 23:13:33 +00001797{
1798 OrigFn fn;
1799 int err;
1800 VALGRIND_GET_ORIG_FN(fn);
1801 before("Init");
njndbf7ca72006-03-31 11:57:59 +00001802 check_mem_is_defined_untyped(argc, sizeof(int));
1803 check_mem_is_defined_untyped(*argv, *argc * sizeof(char**));
sewardjc3a47092006-02-18 23:13:33 +00001804 CALL_FN_W_WW(err, fn, argc,argv);
1805 after("Init", err);
sewardjd465d992006-10-17 01:46:55 +00001806 if (opt_initkludge)
1807 return (long)(void*)&mpiwrap_walk_type_EXTERNALLY_VISIBLE;
1808 else
1809 return (long)err;
sewardjc3a47092006-02-18 23:13:33 +00001810}
1811
1812/* --- Initialized --- */
1813int WRAPPER_FOR(PMPI_Initialized)(int* flag)
1814{
1815 OrigFn fn;
1816 int err;
1817 VALGRIND_GET_ORIG_FN(fn);
1818 before("Initialized");
njndbf7ca72006-03-31 11:57:59 +00001819 check_mem_is_addressable_untyped(flag, sizeof(int));
sewardjc3a47092006-02-18 23:13:33 +00001820 CALL_FN_W_W(err, fn, flag);
njndbf7ca72006-03-31 11:57:59 +00001821 make_mem_defined_if_addressable_if_success_untyped(err, flag, sizeof(int));
sewardjc3a47092006-02-18 23:13:33 +00001822 after("Initialized", err);
1823 return err;
1824}
1825
1826/* --- Finalize --- */
1827int WRAPPER_FOR(PMPI_Finalize)(void)
1828{
1829 OrigFn fn;
1830 int err;
1831 VALGRIND_GET_ORIG_FN(fn);
1832 before("Finalize");
1833 CALL_FN_W_v(err, fn);
1834 after("Finalize", err);
1835 return err;
1836}
1837
1838
1839/*------------------------------------------------------------*/
1840/*--- ---*/
sewardj63daa8a2006-03-09 19:08:20 +00001841/*--- Default wrappers for all remaining functions ---*/
sewardjc3a47092006-02-18 23:13:33 +00001842/*--- ---*/
1843/*------------------------------------------------------------*/
1844
sewardj9c969c32006-03-10 18:37:45 +00001845/* Boilerplate for default wrappers. */
sewardj63daa8a2006-03-09 19:08:20 +00001846#define DEFAULT_WRAPPER_PREAMBLE(basename) \
1847 OrigFn fn; \
1848 UWord res; \
sewardj0d17f242006-03-28 01:02:38 +00001849 static int complaints = 1; \
sewardj63daa8a2006-03-09 19:08:20 +00001850 VALGRIND_GET_ORIG_FN(fn); \
1851 before(#basename); \
1852 if (opt_missing >= 2) { \
1853 barf("no wrapper for PMPI_" #basename \
1854 ",\n\t\t\t and you have " \
1855 "requested strict checking"); \
1856 } \
1857 if (opt_missing == 1 && complaints > 0) { \
1858 fprintf(stderr, "%s %5d: warning: no wrapper " \
1859 "for PMPI_" #basename "\n", \
1860 preamble, my_pid); \
1861 complaints--; \
1862 } \
1863
1864#define DEFAULT_WRAPPER_W_0W(basename) \
1865 UWord WRAPPER_FOR(PMPI_##basename)( void ) \
1866 { \
1867 DEFAULT_WRAPPER_PREAMBLE(basename) \
1868 CALL_FN_W_v(res, fn); \
1869 return res; \
1870 }
1871
1872#define DEFAULT_WRAPPER_W_1W(basename) \
1873 UWord WRAPPER_FOR(PMPI_##basename)( UWord a1 ) \
1874 { \
1875 DEFAULT_WRAPPER_PREAMBLE(basename) \
1876 CALL_FN_W_W(res, fn, a1); \
1877 return res; \
1878 }
1879
1880#define DEFAULT_WRAPPER_W_2W(basename) \
1881 UWord WRAPPER_FOR(PMPI_##basename)( UWord a1, UWord a2 ) \
1882 { \
1883 DEFAULT_WRAPPER_PREAMBLE(basename) \
1884 CALL_FN_W_WW(res, fn, a1,a2); \
1885 return res; \
1886 }
1887
1888#define DEFAULT_WRAPPER_W_3W(basename) \
1889 UWord WRAPPER_FOR(PMPI_##basename) \
1890 ( UWord a1, UWord a2, UWord a3 ) \
1891 { \
1892 DEFAULT_WRAPPER_PREAMBLE(basename) \
1893 CALL_FN_W_WWW(res, fn, a1,a2,a3); \
1894 return res; \
1895 }
1896
1897#define DEFAULT_WRAPPER_W_4W(basename) \
1898 UWord WRAPPER_FOR(PMPI_##basename) \
1899 ( UWord a1, UWord a2, UWord a3, UWord a4 ) \
1900 { \
1901 DEFAULT_WRAPPER_PREAMBLE(basename) \
1902 CALL_FN_W_WWWW(res, fn, a1,a2,a3,a4); \
1903 return res; \
1904 }
1905
1906#define DEFAULT_WRAPPER_W_5W(basename) \
1907 UWord WRAPPER_FOR(PMPI_##basename) \
1908 ( UWord a1, UWord a2, UWord a3, UWord a4, UWord a5 ) \
1909 { \
1910 DEFAULT_WRAPPER_PREAMBLE(basename) \
1911 CALL_FN_W_5W(res, fn, a1,a2,a3,a4,a5); \
1912 return res; \
1913 }
1914
1915#define DEFAULT_WRAPPER_W_6W(basename) \
1916 UWord WRAPPER_FOR(PMPI_##basename) \
1917 ( UWord a1, UWord a2, UWord a3, UWord a4, UWord a5, \
1918 UWord a6 ) \
1919 { \
1920 DEFAULT_WRAPPER_PREAMBLE(basename) \
1921 CALL_FN_W_6W(res, fn, a1,a2,a3,a4,a5,a6); \
1922 return res; \
1923 }
1924
1925#define DEFAULT_WRAPPER_W_7W(basename) \
1926 UWord WRAPPER_FOR(PMPI_##basename) \
1927 ( UWord a1, UWord a2, UWord a3, UWord a4, UWord a5, \
1928 UWord a6, UWord a7 ) \
1929 { \
1930 DEFAULT_WRAPPER_PREAMBLE(basename) \
1931 CALL_FN_W_7W(res, fn, a1,a2,a3,a4,a5,a6,a7); \
1932 return res; \
1933 }
1934
1935#define DEFAULT_WRAPPER_W_8W(basename) \
1936 UWord WRAPPER_FOR(PMPI_##basename) \
1937 ( UWord a1, UWord a2, UWord a3, UWord a4, UWord a5, \
1938 UWord a6, UWord a7, UWord a8 ) \
1939 { \
1940 DEFAULT_WRAPPER_PREAMBLE(basename) \
1941 CALL_FN_W_8W(res, fn, a1,a2,a3,a4,a5,a6,a7,a8); \
1942 return res; \
1943 }
1944
1945#define DEFAULT_WRAPPER_W_9W(basename) \
1946 UWord WRAPPER_FOR(PMPI_##basename) \
1947 ( UWord a1, UWord a2, UWord a3, UWord a4, UWord a5, \
1948 UWord a6, UWord a7, UWord a8, UWord a9 ) \
1949 { \
1950 DEFAULT_WRAPPER_PREAMBLE(basename) \
1951 CALL_FN_W_9W(res, fn, a1,a2,a3,a4,a5,a6,a7,a8,a9); \
1952 return res; \
1953 }
1954
1955#define DEFAULT_WRAPPER_W_10W(basename) \
1956 UWord WRAPPER_FOR(PMPI_##basename) \
1957 ( UWord a1, UWord a2, UWord a3, UWord a4, UWord a5, \
1958 UWord a6, UWord a7, UWord a8, UWord a9, UWord a10 ) \
1959 { \
1960 DEFAULT_WRAPPER_PREAMBLE(basename) \
1961 CALL_FN_W_10W(res, fn, a1,a2,a3,a4,a5,a6,a7,a8,a9,a10); \
1962 return res; \
1963 }
1964
1965#define DEFAULT_WRAPPER_W_12W(basename) \
1966 UWord WRAPPER_FOR(PMPI_##basename) \
1967 ( UWord a1, UWord a2, UWord a3, UWord a4, UWord a5, \
1968 UWord a6, UWord a7, UWord a8, UWord a9, UWord a10, \
1969 UWord a11, UWord a12 ) \
1970 { \
1971 DEFAULT_WRAPPER_PREAMBLE(basename) \
1972 CALL_FN_W_12W(res, fn, a1,a2,a3,a4,a5,a6, \
1973 a7,a8,a9,a10,a11,a12); \
1974 return res; \
1975 }
1976
1977
1978/* Canned summary of MPI-1.1/MPI-2 entry points, as derived from mpi.h
1979 from Open MPI svn rev 9191 (somewhere between Open MPI versions
1980 1.0.1 and 1.1.0). */
1981
1982/* If a function is commented out in this list, it's because it has a
1983 proper wrapper written elsewhere (above here). */
1984
1985DEFAULT_WRAPPER_W_2W(Abort)
1986DEFAULT_WRAPPER_W_9W(Accumulate)
1987DEFAULT_WRAPPER_W_1W(Add_error_class)
1988DEFAULT_WRAPPER_W_2W(Add_error_code)
1989DEFAULT_WRAPPER_W_2W(Add_error_string)
sewardj9c969c32006-03-10 18:37:45 +00001990/* DEFAULT_WRAPPER_W_2W(Address) */
sewardj63daa8a2006-03-09 19:08:20 +00001991DEFAULT_WRAPPER_W_7W(Allgather)
1992DEFAULT_WRAPPER_W_8W(Allgatherv)
1993DEFAULT_WRAPPER_W_3W(Alloc_mem)
1994/* DEFAULT_WRAPPER_W_6W(Allreduce) */
sewardjb727b542006-03-10 21:41:01 +00001995/* DEFAULT_WRAPPER_W_7W(Alltoall) */
sewardj63daa8a2006-03-09 19:08:20 +00001996DEFAULT_WRAPPER_W_9W(Alltoallv)
1997DEFAULT_WRAPPER_W_9W(Alltoallw)
1998DEFAULT_WRAPPER_W_2W(Attr_delete)
1999DEFAULT_WRAPPER_W_4W(Attr_get)
2000DEFAULT_WRAPPER_W_3W(Attr_put)
2001DEFAULT_WRAPPER_W_1W(Barrier)
2002/* DEFAULT_WRAPPER_W_5W(Bcast) */
sewardj9c969c32006-03-10 18:37:45 +00002003/* DEFAULT_WRAPPER_W_6W(Bsend) */
sewardj63daa8a2006-03-09 19:08:20 +00002004DEFAULT_WRAPPER_W_7W(Bsend_init)
2005DEFAULT_WRAPPER_W_2W(Buffer_attach)
2006DEFAULT_WRAPPER_W_2W(Buffer_detach)
sewardjb727b542006-03-10 21:41:01 +00002007/* DEFAULT_WRAPPER_W_1W(Cancel) */
sewardj63daa8a2006-03-09 19:08:20 +00002008DEFAULT_WRAPPER_W_4W(Cart_coords)
2009DEFAULT_WRAPPER_W_6W(Cart_create)
2010DEFAULT_WRAPPER_W_5W(Cart_get)
2011DEFAULT_WRAPPER_W_5W(Cart_map)
2012DEFAULT_WRAPPER_W_3W(Cart_rank)
2013DEFAULT_WRAPPER_W_5W(Cart_shift)
2014DEFAULT_WRAPPER_W_3W(Cart_sub)
2015DEFAULT_WRAPPER_W_2W(Cartdim_get)
2016DEFAULT_WRAPPER_W_1W(Close_port)
2017DEFAULT_WRAPPER_W_5W(Comm_accept)
2018DEFAULT_WRAPPER_W_1W(Comm_c2f)
2019DEFAULT_WRAPPER_W_2W(Comm_call_errhandler)
2020DEFAULT_WRAPPER_W_3W(Comm_compare)
2021DEFAULT_WRAPPER_W_5W(Comm_connect)
2022DEFAULT_WRAPPER_W_2W(Comm_create_errhandler)
2023DEFAULT_WRAPPER_W_4W(Comm_create_keyval)
sewardj9c969c32006-03-10 18:37:45 +00002024/* DEFAULT_WRAPPER_W_3W(Comm_create) */
sewardj63daa8a2006-03-09 19:08:20 +00002025DEFAULT_WRAPPER_W_2W(Comm_delete_attr)
2026DEFAULT_WRAPPER_W_1W(Comm_disconnect)
sewardj9c969c32006-03-10 18:37:45 +00002027/* DEFAULT_WRAPPER_W_2W(Comm_dup) */
sewardj63daa8a2006-03-09 19:08:20 +00002028DEFAULT_WRAPPER_W_1W(Comm_f2c)
2029DEFAULT_WRAPPER_W_1W(Comm_free_keyval)
sewardj9c969c32006-03-10 18:37:45 +00002030/* DEFAULT_WRAPPER_W_1W(Comm_free) */
sewardj63daa8a2006-03-09 19:08:20 +00002031DEFAULT_WRAPPER_W_4W(Comm_get_attr)
2032DEFAULT_WRAPPER_W_2W(Comm_get_errhandler)
2033DEFAULT_WRAPPER_W_3W(Comm_get_name)
2034DEFAULT_WRAPPER_W_1W(Comm_get_parent)
2035DEFAULT_WRAPPER_W_2W(Comm_group)
2036DEFAULT_WRAPPER_W_2W(Comm_join)
2037/* DEFAULT_WRAPPER_W_2W(Comm_rank) */
2038DEFAULT_WRAPPER_W_2W(Comm_remote_group)
2039DEFAULT_WRAPPER_W_2W(Comm_remote_size)
2040DEFAULT_WRAPPER_W_3W(Comm_set_attr)
2041DEFAULT_WRAPPER_W_2W(Comm_set_errhandler)
2042DEFAULT_WRAPPER_W_2W(Comm_set_name)
2043/* DEFAULT_WRAPPER_W_2W(Comm_size) */
2044DEFAULT_WRAPPER_W_8W(Comm_spawn)
2045DEFAULT_WRAPPER_W_9W(Comm_spawn_multiple)
2046DEFAULT_WRAPPER_W_4W(Comm_split)
2047DEFAULT_WRAPPER_W_2W(Comm_test_inter)
2048DEFAULT_WRAPPER_W_3W(Dims_create)
2049DEFAULT_WRAPPER_W_1W(Errhandler_c2f)
2050DEFAULT_WRAPPER_W_2W(Errhandler_create)
2051DEFAULT_WRAPPER_W_1W(Errhandler_f2c)
2052DEFAULT_WRAPPER_W_1W(Errhandler_free)
2053DEFAULT_WRAPPER_W_2W(Errhandler_get)
2054DEFAULT_WRAPPER_W_2W(Errhandler_set)
2055DEFAULT_WRAPPER_W_2W(Error_class)
2056/* DEFAULT_WRAPPER_W_3W(Error_string) */
2057DEFAULT_WRAPPER_W_6W(Exscan)
2058DEFAULT_WRAPPER_W_1W(File_c2f)
2059DEFAULT_WRAPPER_W_1W(File_f2c)
2060DEFAULT_WRAPPER_W_2W(File_call_errhandler)
2061DEFAULT_WRAPPER_W_2W(File_create_errhandler)
2062DEFAULT_WRAPPER_W_2W(File_set_errhandler)
2063DEFAULT_WRAPPER_W_2W(File_get_errhandler)
2064DEFAULT_WRAPPER_W_5W(File_open)
2065DEFAULT_WRAPPER_W_1W(File_close)
2066DEFAULT_WRAPPER_W_2W(File_delete)
2067DEFAULT_WRAPPER_W_2W(File_set_size)
2068DEFAULT_WRAPPER_W_2W(File_preallocate)
2069DEFAULT_WRAPPER_W_2W(File_get_size)
2070DEFAULT_WRAPPER_W_2W(File_get_group)
2071DEFAULT_WRAPPER_W_2W(File_get_amode)
2072DEFAULT_WRAPPER_W_2W(File_set_info)
2073DEFAULT_WRAPPER_W_2W(File_get_info)
2074DEFAULT_WRAPPER_W_6W(File_set_view)
2075DEFAULT_WRAPPER_W_5W(File_get_view)
2076DEFAULT_WRAPPER_W_6W(File_read_at)
2077DEFAULT_WRAPPER_W_6W(File_read_at_all)
2078DEFAULT_WRAPPER_W_6W(File_write_at)
2079DEFAULT_WRAPPER_W_6W(File_write_at_all)
2080DEFAULT_WRAPPER_W_6W(File_iread_at)
2081DEFAULT_WRAPPER_W_6W(File_iwrite_at)
2082DEFAULT_WRAPPER_W_5W(File_read)
2083DEFAULT_WRAPPER_W_5W(File_read_all)
2084DEFAULT_WRAPPER_W_5W(File_write)
2085DEFAULT_WRAPPER_W_5W(File_write_all)
2086DEFAULT_WRAPPER_W_5W(File_iread)
2087DEFAULT_WRAPPER_W_5W(File_iwrite)
2088DEFAULT_WRAPPER_W_3W(File_seek)
2089DEFAULT_WRAPPER_W_2W(File_get_position)
2090DEFAULT_WRAPPER_W_3W(File_get_byte_offset)
2091DEFAULT_WRAPPER_W_5W(File_read_shared)
2092DEFAULT_WRAPPER_W_5W(File_write_shared)
2093DEFAULT_WRAPPER_W_5W(File_iread_shared)
2094DEFAULT_WRAPPER_W_5W(File_iwrite_shared)
2095DEFAULT_WRAPPER_W_5W(File_read_ordered)
2096DEFAULT_WRAPPER_W_5W(File_write_ordered)
2097DEFAULT_WRAPPER_W_3W(File_seek_shared)
2098DEFAULT_WRAPPER_W_2W(File_get_position_shared)
2099DEFAULT_WRAPPER_W_5W(File_read_at_all_begin)
2100DEFAULT_WRAPPER_W_3W(File_read_at_all_end)
2101DEFAULT_WRAPPER_W_5W(File_write_at_all_begin)
2102DEFAULT_WRAPPER_W_3W(File_write_at_all_end)
2103DEFAULT_WRAPPER_W_4W(File_read_all_begin)
2104DEFAULT_WRAPPER_W_3W(File_read_all_end)
2105DEFAULT_WRAPPER_W_4W(File_write_all_begin)
2106DEFAULT_WRAPPER_W_3W(File_write_all_end)
2107DEFAULT_WRAPPER_W_4W(File_read_ordered_begin)
2108DEFAULT_WRAPPER_W_3W(File_read_ordered_end)
2109DEFAULT_WRAPPER_W_4W(File_write_ordered_begin)
2110DEFAULT_WRAPPER_W_3W(File_write_ordered_end)
2111DEFAULT_WRAPPER_W_3W(File_get_type_extent)
2112DEFAULT_WRAPPER_W_2W(File_set_atomicity)
2113DEFAULT_WRAPPER_W_2W(File_get_atomicity)
2114DEFAULT_WRAPPER_W_1W(File_sync)
2115/* DEFAULT_WRAPPER_W_0W(Finalize) */
2116DEFAULT_WRAPPER_W_1W(Finalized)
2117DEFAULT_WRAPPER_W_1W(Free_mem)
2118/* DEFAULT_WRAPPER_W_8W(Gather) */
2119DEFAULT_WRAPPER_W_9W(Gatherv)
2120DEFAULT_WRAPPER_W_2W(Get_address)
sewardj9c969c32006-03-10 18:37:45 +00002121/* DEFAULT_WRAPPER_W_3W(Get_count) */
sewardj63daa8a2006-03-09 19:08:20 +00002122DEFAULT_WRAPPER_W_3W(Get_elements)
2123DEFAULT_WRAPPER_W_8W(Get)
2124DEFAULT_WRAPPER_W_2W(Get_processor_name)
2125DEFAULT_WRAPPER_W_2W(Get_version)
2126DEFAULT_WRAPPER_W_6W(Graph_create)
2127DEFAULT_WRAPPER_W_5W(Graph_get)
2128DEFAULT_WRAPPER_W_5W(Graph_map)
2129DEFAULT_WRAPPER_W_3W(Graph_neighbors_count)
2130DEFAULT_WRAPPER_W_4W(Graph_neighbors)
2131DEFAULT_WRAPPER_W_3W(Graphdims_get)
2132DEFAULT_WRAPPER_W_1W(Grequest_complete)
2133DEFAULT_WRAPPER_W_5W(Grequest_start)
2134DEFAULT_WRAPPER_W_1W(Group_c2f)
2135DEFAULT_WRAPPER_W_3W(Group_compare)
2136DEFAULT_WRAPPER_W_3W(Group_difference)
2137DEFAULT_WRAPPER_W_4W(Group_excl)
2138DEFAULT_WRAPPER_W_1W(Group_f2c)
2139DEFAULT_WRAPPER_W_1W(Group_free)
2140DEFAULT_WRAPPER_W_4W(Group_incl)
2141DEFAULT_WRAPPER_W_3W(Group_intersection)
2142DEFAULT_WRAPPER_W_4W(Group_range_excl)
2143DEFAULT_WRAPPER_W_4W(Group_range_incl)
2144DEFAULT_WRAPPER_W_2W(Group_rank)
2145DEFAULT_WRAPPER_W_2W(Group_size)
2146DEFAULT_WRAPPER_W_5W(Group_translate_ranks)
2147DEFAULT_WRAPPER_W_3W(Group_union)
sewardj9c969c32006-03-10 18:37:45 +00002148/* DEFAULT_WRAPPER_W_7W(Ibsend) */
sewardj63daa8a2006-03-09 19:08:20 +00002149DEFAULT_WRAPPER_W_1W(Info_c2f)
2150DEFAULT_WRAPPER_W_1W(Info_create)
2151DEFAULT_WRAPPER_W_2W(Info_delete)
2152DEFAULT_WRAPPER_W_2W(Info_dup)
2153DEFAULT_WRAPPER_W_1W(Info_f2c)
2154DEFAULT_WRAPPER_W_1W(Info_free)
2155DEFAULT_WRAPPER_W_5W(Info_get)
2156DEFAULT_WRAPPER_W_2W(Info_get_nkeys)
2157DEFAULT_WRAPPER_W_3W(Info_get_nthkey)
2158DEFAULT_WRAPPER_W_4W(Info_get_valuelen)
2159DEFAULT_WRAPPER_W_3W(Info_set)
2160/* DEFAULT_WRAPPER_W_2W(Init) */
2161/* DEFAULT_WRAPPER_W_1W(Initialized) */
2162DEFAULT_WRAPPER_W_4W(Init_thread)
2163DEFAULT_WRAPPER_W_6W(Intercomm_create)
2164DEFAULT_WRAPPER_W_3W(Intercomm_merge)
2165/* DEFAULT_WRAPPER_W_5W(Iprobe) */
2166/* DEFAULT_WRAPPER_W_7W(Irecv) */
sewardj9c969c32006-03-10 18:37:45 +00002167/* DEFAULT_WRAPPER_W_7W(Irsend) */
sewardj63daa8a2006-03-09 19:08:20 +00002168/* DEFAULT_WRAPPER_W_7W(Isend) */
sewardj9c969c32006-03-10 18:37:45 +00002169/* DEFAULT_WRAPPER_W_7W(Issend) */
sewardj63daa8a2006-03-09 19:08:20 +00002170DEFAULT_WRAPPER_W_1W(Is_thread_main)
2171DEFAULT_WRAPPER_W_4W(Keyval_create)
2172DEFAULT_WRAPPER_W_1W(Keyval_free)
2173DEFAULT_WRAPPER_W_3W(Lookup_name)
2174DEFAULT_WRAPPER_W_1W(Op_c2f)
2175/* DEFAULT_WRAPPER_W_3W(Op_create) */
2176DEFAULT_WRAPPER_W_2W(Open_port)
2177DEFAULT_WRAPPER_W_1W(Op_f2c)
2178DEFAULT_WRAPPER_W_1W(Op_free)
2179DEFAULT_WRAPPER_W_7W(Pack_external)
2180DEFAULT_WRAPPER_W_4W(Pack_external_size)
2181DEFAULT_WRAPPER_W_7W(Pack)
2182DEFAULT_WRAPPER_W_4W(Pack_size)
2183/* int MPI_Pcontrol(const int level, ...) */
sewardjb727b542006-03-10 21:41:01 +00002184/* DEFAULT_WRAPPER_W_4W(Probe) */
sewardj63daa8a2006-03-09 19:08:20 +00002185DEFAULT_WRAPPER_W_3W(Publish_name)
2186DEFAULT_WRAPPER_W_8W(Put)
2187DEFAULT_WRAPPER_W_1W(Query_thread)
2188DEFAULT_WRAPPER_W_7W(Recv_init)
2189/* DEFAULT_WRAPPER_W_7W(Recv) */
2190/* DEFAULT_WRAPPER_W_7W(Reduce) */
2191DEFAULT_WRAPPER_W_6W(Reduce_scatter)
2192DEFAULT_WRAPPER_W_5W(Register_datarep)
2193DEFAULT_WRAPPER_W_1W(Request_c2f)
2194DEFAULT_WRAPPER_W_1W(Request_f2c)
2195DEFAULT_WRAPPER_W_1W(Request_free)
2196DEFAULT_WRAPPER_W_3W(Request_get_status)
sewardj9c969c32006-03-10 18:37:45 +00002197/* DEFAULT_WRAPPER_W_6W(Rsend) */
sewardj63daa8a2006-03-09 19:08:20 +00002198DEFAULT_WRAPPER_W_7W(Rsend_init)
2199DEFAULT_WRAPPER_W_6W(Scan)
sewardjb727b542006-03-10 21:41:01 +00002200/* DEFAULT_WRAPPER_W_8W(Scatter) */
sewardj63daa8a2006-03-09 19:08:20 +00002201DEFAULT_WRAPPER_W_9W(Scatterv)
2202DEFAULT_WRAPPER_W_7W(Send_init)
2203/* DEFAULT_WRAPPER_W_6W(Send) */
2204/* DEFAULT_WRAPPER_W_12W(Sendrecv) */
2205DEFAULT_WRAPPER_W_9W(Sendrecv_replace)
2206DEFAULT_WRAPPER_W_7W(Ssend_init)
sewardj9c969c32006-03-10 18:37:45 +00002207/* DEFAULT_WRAPPER_W_6W(Ssend) */
sewardj63daa8a2006-03-09 19:08:20 +00002208DEFAULT_WRAPPER_W_1W(Start)
2209DEFAULT_WRAPPER_W_2W(Startall)
2210DEFAULT_WRAPPER_W_2W(Status_c2f)
2211DEFAULT_WRAPPER_W_2W(Status_f2c)
2212DEFAULT_WRAPPER_W_2W(Status_set_cancelled)
2213DEFAULT_WRAPPER_W_3W(Status_set_elements)
sewardjb727b542006-03-10 21:41:01 +00002214/* DEFAULT_WRAPPER_W_4W(Testall) */
sewardj63daa8a2006-03-09 19:08:20 +00002215DEFAULT_WRAPPER_W_5W(Testany)
sewardjb727b542006-03-10 21:41:01 +00002216/* DEFAULT_WRAPPER_W_3W(Test) */
sewardj63daa8a2006-03-09 19:08:20 +00002217DEFAULT_WRAPPER_W_2W(Test_cancelled)
2218DEFAULT_WRAPPER_W_5W(Testsome)
2219DEFAULT_WRAPPER_W_2W(Topo_test)
2220DEFAULT_WRAPPER_W_1W(Type_c2f)
sewardj9c969c32006-03-10 18:37:45 +00002221/* DEFAULT_WRAPPER_W_1W(Type_commit) */
sewardj63daa8a2006-03-09 19:08:20 +00002222DEFAULT_WRAPPER_W_3W(Type_contiguous)
2223DEFAULT_WRAPPER_W_10W(Type_create_darray)
2224DEFAULT_WRAPPER_W_3W(Type_create_f90_complex)
2225DEFAULT_WRAPPER_W_2W(Type_create_f90_integer)
2226DEFAULT_WRAPPER_W_3W(Type_create_f90_real)
2227DEFAULT_WRAPPER_W_5W(Type_create_hindexed)
2228DEFAULT_WRAPPER_W_5W(Type_create_hvector)
2229DEFAULT_WRAPPER_W_4W(Type_create_keyval)
2230DEFAULT_WRAPPER_W_5W(Type_create_indexed_block)
2231DEFAULT_WRAPPER_W_5W(Type_create_struct)
2232DEFAULT_WRAPPER_W_7W(Type_create_subarray)
2233DEFAULT_WRAPPER_W_4W(Type_create_resized)
2234DEFAULT_WRAPPER_W_2W(Type_delete_attr)
2235DEFAULT_WRAPPER_W_2W(Type_dup)
sewardj9c969c32006-03-10 18:37:45 +00002236/* DEFAULT_WRAPPER_W_2W(Type_extent) */
2237/* DEFAULT_WRAPPER_W_1W(Type_free) */
sewardj63daa8a2006-03-09 19:08:20 +00002238DEFAULT_WRAPPER_W_1W(Type_free_keyval)
2239DEFAULT_WRAPPER_W_1W(Type_f2c)
2240DEFAULT_WRAPPER_W_4W(Type_get_attr)
sewardj9c969c32006-03-10 18:37:45 +00002241/* DEFAULT_WRAPPER_W_7W(Type_get_contents) */
2242/* DEFAULT_WRAPPER_W_5W(Type_get_envelope) */
sewardj63daa8a2006-03-09 19:08:20 +00002243DEFAULT_WRAPPER_W_3W(Type_get_extent)
2244DEFAULT_WRAPPER_W_3W(Type_get_name)
2245DEFAULT_WRAPPER_W_3W(Type_get_true_extent)
2246DEFAULT_WRAPPER_W_5W(Type_hindexed)
2247DEFAULT_WRAPPER_W_5W(Type_hvector)
2248DEFAULT_WRAPPER_W_5W(Type_indexed)
2249DEFAULT_WRAPPER_W_2W(Type_lb)
2250DEFAULT_WRAPPER_W_3W(Type_match_size)
2251DEFAULT_WRAPPER_W_3W(Type_set_attr)
2252DEFAULT_WRAPPER_W_2W(Type_set_name)
2253DEFAULT_WRAPPER_W_2W(Type_size)
2254DEFAULT_WRAPPER_W_5W(Type_struct)
2255DEFAULT_WRAPPER_W_2W(Type_ub)
2256DEFAULT_WRAPPER_W_5W(Type_vector)
2257DEFAULT_WRAPPER_W_7W(Unpack)
2258DEFAULT_WRAPPER_W_3W(Unpublish_name)
2259DEFAULT_WRAPPER_W_7W(Unpack_external)
2260/* DEFAULT_WRAPPER_W_3W(Waitall) */
2261DEFAULT_WRAPPER_W_4W(Waitany)
2262/* DEFAULT_WRAPPER_W_2W(Wait) */
2263DEFAULT_WRAPPER_W_5W(Waitsome)
2264DEFAULT_WRAPPER_W_1W(Win_c2f)
2265DEFAULT_WRAPPER_W_2W(Win_call_errhandler)
2266DEFAULT_WRAPPER_W_1W(Win_complete)
2267DEFAULT_WRAPPER_W_6W(Win_create)
2268DEFAULT_WRAPPER_W_2W(Win_create_errhandler)
2269DEFAULT_WRAPPER_W_4W(Win_create_keyval)
2270DEFAULT_WRAPPER_W_2W(Win_delete_attr)
2271DEFAULT_WRAPPER_W_1W(Win_f2c)
2272DEFAULT_WRAPPER_W_2W(Win_fence)
2273DEFAULT_WRAPPER_W_1W(Win_free)
2274DEFAULT_WRAPPER_W_1W(Win_free_keyval)
2275DEFAULT_WRAPPER_W_4W(Win_get_attr)
2276DEFAULT_WRAPPER_W_2W(Win_get_errhandler)
2277DEFAULT_WRAPPER_W_2W(Win_get_group)
2278DEFAULT_WRAPPER_W_3W(Win_get_name)
2279DEFAULT_WRAPPER_W_4W(Win_lock)
2280DEFAULT_WRAPPER_W_3W(Win_post)
2281DEFAULT_WRAPPER_W_3W(Win_set_attr)
2282DEFAULT_WRAPPER_W_2W(Win_set_errhandler)
2283DEFAULT_WRAPPER_W_2W(Win_set_name)
2284DEFAULT_WRAPPER_W_3W(Win_start)
2285DEFAULT_WRAPPER_W_2W(Win_test)
2286DEFAULT_WRAPPER_W_2W(Win_unlock)
2287DEFAULT_WRAPPER_W_1W(Win_wait)
2288/* double MPI_Wtick(void) */
2289/* double MPI_Wtime(void) */
2290
2291
sewardjc3a47092006-02-18 23:13:33 +00002292/*------------------------------------------------------------*/
2293/*--- ---*/
2294/*--- ---*/
2295/*--- ---*/
2296/*------------------------------------------------------------*/
2297
sewardjc3a47092006-02-18 23:13:33 +00002298/*---------------------------------------------------------------*/
2299/*--- end mpiwrap.c ---*/
2300/*---------------------------------------------------------------*/