~bkerensa/ubuntu/raring/valgrind/merge-from-deb

« back to all changes in this revision

Viewing changes to auxprogs/libmpiwrap.c

  • Committer: Bazaar Package Importer
  • Author(s): Andrés Roldán
  • Date: 2008-06-13 02:31:40 UTC
  • mto: (1.4.1 upstream) (2.2.1 squeeze)
  • mto: This revision was merged to the branch mainline in revision 24.
  • Revision ID: james.westby@ubuntu.com-20080613023140-iwk33rz9rhvfkr96
Import upstream version 3.3.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
   This file is part of Valgrind, a dynamic binary instrumentation
19
19
   framework.
20
20
 
21
 
   Copyright (C) 2006 OpenWorks LLP.  All rights reserved.
 
21
   Copyright (C) 2006-2007 OpenWorks LLP.  All rights reserved.
22
22
 
23
23
   Redistribution and use in source and binary forms, with or without
24
24
   modification, are permitted provided that the following conditions
83
83
#include "mpi.h"
84
84
 
85
85
/* Where are API symbols?
86
 
   Open MPI  lib/libmpi.so,  soname = libmpi.so.0
87
 
   ditto Quadrics MPI
 
86
   Open MPI      lib/libmpi.so,   soname = libmpi.so.0
 
87
   Quadrics MPI  lib/libmpi.so,   soname = libmpi.so.0
 
88
   MPICH         libmpich.so.1.0, soname = libmpich.so.1.0
 
89
   AIX: in /usr/lpp/ppe.poe/lib/libmpi_r.a(mpicore*_r.o)
 
90
 
 
91
   For the non-AIX targets, a suitable soname to match with
 
92
   is "libmpi*.so*".
88
93
*/
89
 
/* ifdef OpenMPI ... */
90
 
#define I_WRAP_FNNAME_U(_name) I_WRAP_SONAME_FNNAME_ZU(libmpiZdsoZa,_name)
 
94
#if defined(_AIX)
 
95
# define I_WRAP_FNNAME_U(_name) \
 
96
         I_WRAP_SONAME_FNNAME_ZU(libmpiZurZdaZLmpicoreZaZurZdoZR,_name)
 
97
  /* Don't change this without also changing all the names in
 
98
     libmpiwrap.exp. */
 
99
#else
 
100
# define I_WRAP_FNNAME_U(_name) \
 
101
         I_WRAP_SONAME_FNNAME_ZU(libmpiZaZdsoZa,_name)
 
102
 
 
103
#endif
91
104
 
92
105
 
93
106
/*------------------------------------------------------------*/
108
121
#  define offsetof(type,memb) ((int)&((type*)0)->memb)
109
122
#endif
110
123
 
 
124
/* Find the size of long double image (not 'sizeof(long double)').
 
125
   See comments in sizeofOneNamedTy. */
 
126
static long sizeof_long_double_image ( void );
 
127
 
111
128
 
112
129
/*------------------------------------------------------------*/
113
130
/*--- Simple helpers                                       ---*/
119
136
static const char* preamble = "valgrind MPI wrappers";
120
137
 
121
138
/* established at startup */
122
 
static pid_t my_pid        = -1;
123
 
static char* options_str   = NULL;
124
 
static int   opt_verbosity = 1;
125
 
static Bool  opt_missing   = 0; /* 0:silent; 1:warn; 2:abort */
126
 
static Bool  opt_help      = False;
 
139
static pid_t my_pid         = -1;
 
140
static char* options_str    = NULL;
 
141
static int   opt_verbosity  = 1;
 
142
static Bool  opt_missing    = 0; /* 0:silent; 1:warn; 2:abort */
 
143
static Bool  opt_help       = False;
 
144
static Bool  opt_initkludge = False;
127
145
 
128
146
static void before ( char* fnname )
129
147
{
145
163
            opt_verbosity--;
146
164
         if (NULL != strstr(options_str, "help"))
147
165
            opt_help = True;
 
166
         if (NULL != strstr(options_str, "initkludge"))
 
167
            opt_initkludge = True;
148
168
      }
149
169
      if (opt_verbosity > 0)
150
170
         fprintf(stderr, "%s %5d: Active for pid %d\n", 
160
180
         fprintf(stderr, "Valid options for the MPIWRAP_DEBUG environment"
161
181
                         " variable are:\n");
162
182
         fprintf(stderr, "\n");
163
 
         fprintf(stderr, "   quiet      be silent except for errors\n");
164
 
         fprintf(stderr, "   verbose    show wrapper entries/exits\n");
165
 
         fprintf(stderr, "   strict     abort the program if a function"
166
 
                         " with no wrapper is used\n");
167
 
         fprintf(stderr, "   warn       give a warning if a function"
168
 
                         " with no wrapper is used\n");
169
 
         fprintf(stderr, "   help       display this message, then exit\n");
 
183
         fprintf(stderr, "   quiet       be silent except for errors\n");
 
184
         fprintf(stderr, "   verbose     show wrapper entries/exits\n");
 
185
         fprintf(stderr, "   strict      abort the program if a function"
 
186
                         " with no wrapper is used\n");
 
187
         fprintf(stderr, "   warn        give a warning if a function"
 
188
                         " with no wrapper is used\n");
 
189
         fprintf(stderr, "   help        display this message, then exit\n");
 
190
         fprintf(stderr, "   initkludge  debugging hack; do not use\n");
170
191
         fprintf(stderr, "\n");
171
192
         fprintf(stderr, "Multiple options are allowed, eg"
172
193
                         " MPIWRAP_DEBUG=strict,verbose\n");
186
207
      fprintf(stderr, "%s %5d: enter PMPI_%s\n", preamble,  my_pid, fnname );
187
208
}
188
209
 
189
 
static inline void after ( char* fnname, int err )
 
210
static __inline__ void after ( char* fnname, int err )
190
211
{
191
212
   if (opt_verbosity > 1)
192
213
      fprintf(stderr, "%s %5d:  exit PMPI_%s (err = %d)\n", 
235
256
#  if defined(MPI_UNSIGNED_LONG_LONG)
236
257
   else if (ty == MPI_UNSIGNED_LONG_LONG) fprintf(f,"UNSIGNED_LONG_LONG");
237
258
#  endif
 
259
#  if defined(MPI_REAL8)
 
260
   else if (ty == MPI_REAL8)          fprintf(f, "REAL8");
 
261
#  endif
 
262
#  if defined(MPI_REAL4)
 
263
   else if (ty == MPI_REAL4)          fprintf(f, "REAL4");
 
264
#  endif
 
265
#  if defined(MPI_REAL)
 
266
   else if (ty == MPI_REAL)           fprintf(f, "REAL");
 
267
#  endif
 
268
#  if defined(MPI_INTEGER8)
 
269
   else if (ty == MPI_INTEGER8)       fprintf(f, "INTEGER8");
 
270
#  endif
 
271
#  if defined(MPI_INTEGER4)
 
272
   else if (ty == MPI_INTEGER4)       fprintf(f, "INTEGER4");
 
273
#  endif
 
274
#  if defined(MPI_INTEGER)
 
275
   else if (ty == MPI_INTEGER)        fprintf(f, "INTEGER");
 
276
#  endif
 
277
#  if defined(MPI_DOUBLE_PRECISION)
 
278
   else if (ty == MPI_DOUBLE_PRECISION) fprintf(f, "DOUBLE_PRECISION");
 
279
#  endif
 
280
#  if defined(MPI_COMPLEX)
 
281
   else if (ty == MPI_COMPLEX)          fprintf(f, "COMPLEX");
 
282
#  endif
 
283
#  if defined(MPI_DOUBLE_COMPLEX)
 
284
   else if (ty == MPI_DOUBLE_COMPLEX)   fprintf(f, "DOUBLE_COMPLEX");
 
285
#  endif
 
286
#  if defined(MPI_LOGICAL)
 
287
   else if (ty == MPI_LOGICAL)          fprintf(f, "LOGICAL");
 
288
#  endif
 
289
#  if defined(MPI_2INTEGER)
 
290
   else if (ty == MPI_2INTEGER)         fprintf(f, "2INTEGER");
 
291
#  endif
 
292
#  if defined(MPI_2COMPLEX)
 
293
   else if (ty == MPI_2COMPLEX)         fprintf(f, "2COMPLEX");
 
294
#  endif
 
295
#  if defined(MPI_2DOUBLE_COMPLEX)
 
296
   else if (ty == MPI_2DOUBLE_COMPLEX)  fprintf(f, "2DOUBLE_COMPLEX");
 
297
#  endif
 
298
#  if defined(MPI_2REAL)
 
299
   else if (ty == MPI_2REAL)            fprintf(f, "2REAL");
 
300
#  endif
 
301
#  if defined(MPI_2DOUBLE_PRECISION)
 
302
   else if (ty == MPI_2DOUBLE_PRECISION) fprintf(f, "2DOUBLE_PRECISION");
 
303
#  endif
 
304
#  if defined(MPI_CHARACTER)
 
305
   else if (ty == MPI_CHARACTER)         fprintf(f, "CHARACTER");
 
306
#  endif
238
307
   else fprintf(f,"showTy:???");
239
308
}
240
309
 
291
360
/* Note, PMPI_Comm_rank/size are themselves wrapped.  Should work
292
361
   fine. */
293
362
 
294
 
static inline int comm_rank ( MPI_Comm comm ) 
 
363
static __inline__ int comm_rank ( MPI_Comm comm ) 
295
364
{
296
365
   int err, r;
297
366
   err = PMPI_Comm_rank(comm, &r);
298
367
   return err ? 0/*arbitrary*/ : r;
299
368
}
300
369
 
301
 
static inline int comm_size ( MPI_Comm comm ) 
 
370
static __inline__ int comm_size ( MPI_Comm comm ) 
302
371
{
303
372
   int err, r;
304
373
   err = PMPI_Comm_size(comm, &r);
305
374
   return err ? 0/*arbitrary*/ : r;
306
375
}
307
376
 
308
 
static inline Bool count_from_Status( /*OUT*/int* recv_count, 
 
377
static __inline__ Bool count_from_Status( /*OUT*/int* recv_count, 
309
378
                                      MPI_Datatype datatype, 
310
379
                                      MPI_Status* status)
311
380
{
326
395
   types that support assignment and equality operations."  Hence the
327
396
   following function should compile for any compliant definition of
328
397
   MPI_Request. */
329
 
static inline 
 
398
static __inline__ 
330
399
Bool eq_MPI_Request ( MPI_Request r1, MPI_Request r2 )
331
400
{
332
401
   return r1 == r2;
380
449
   There is a subtlety, which is that this is required to return the
381
450
   exact size of one item of the type, NOT the size of it when padded
382
451
   suitably to make an array of them.  In particular that's why the
383
 
   size of LONG_DOUBLE is 10 and not sizeof(long double), since the
384
 
   latter is 12 at least on x86.  Except if sizeof(long double) is
385
 
   claimed to be 8 then we'd better respect that.
 
452
   size of LONG_DOUBLE is computed by looking at the result of doing a
 
453
   long double store, rather than just asking what is the sizeof(long
 
454
   double).
 
455
 
 
456
   For LONG_DOUBLE on x86-linux and amd64-linux my impression is that
 
457
   the right answer is 10 even though sizeof(long double) says 12 and
 
458
   16 respectively.  On ppc32-linux it appears to be 16.
386
459
 
387
460
   Ref: MPI 1.1 doc p18 */
388
461
static long sizeofOneNamedTy ( MPI_Datatype ty )
398
471
   if (ty == MPI_FLOAT)          return sizeof(float);
399
472
   if (ty == MPI_DOUBLE)         return sizeof(double);
400
473
   if (ty == MPI_BYTE)           return 1;
401
 
   if (ty == MPI_LONG_DOUBLE)
402
 
      return sizeof(long double)==8 
403
 
                ? 8 : 10; /* NOT: sizeof(long double); */
404
 
   /* MPI_PACKED */
 
474
   if (ty == MPI_LONG_DOUBLE)    return sizeof_long_double_image();
 
475
   if (ty == MPI_PACKED)         return 1;
 
476
   if (ty == MPI_LONG_LONG_INT)  return sizeof(signed long long int);
 
477
 
 
478
#  if defined(MPI_REAL8)
 
479
   if (ty == MPI_REAL8)          return 8; /* MPI2 spec */;
 
480
#  endif
 
481
#  if defined(MPI_REAL4)
 
482
   if (ty == MPI_REAL4)          return 4; /* MPI2 spec */;
 
483
#  endif
 
484
#  if defined(MPI_REAL)
 
485
   if (ty == MPI_REAL)           return 4; /* MPI2 spec */;
 
486
#  endif
 
487
#  if defined(MPI_INTEGER8)
 
488
   if (ty == MPI_INTEGER8)       return 8; /* MPI2 spec */;
 
489
#  endif
 
490
#  if defined(MPI_INTEGER4)
 
491
   if (ty == MPI_INTEGER4)       return 4; /* MPI2 spec */;
 
492
#  endif
 
493
#  if defined(MPI_INTEGER)
 
494
   if (ty == MPI_INTEGER)        return 4; /* MPI2 spec */;
 
495
#  endif
 
496
#  if defined(MPI_DOUBLE_PRECISION)
 
497
   if (ty == MPI_DOUBLE_PRECISION) return 8; /* MPI2 spec */;
 
498
#  endif
 
499
 
405
500
   /* new in MPI2: */
406
501
#  if defined(MPI_WCHAR)
407
 
   if (ty == MPI_WCHAR)              return sizeof(wchar_t);
 
502
   if (ty == MPI_WCHAR)              return 2; /* MPI2 spec */;
408
503
#  endif
409
504
#  if defined(MPI_SIGNED_CHAR)
410
 
   if (ty == MPI_SIGNED_CHAR)        return sizeof(signed char);
 
505
   if (ty == MPI_SIGNED_CHAR)        return 1; /* MPI2 spec */;
411
506
#  endif
412
507
#  if defined(MPI_UNSIGNED_LONG_LONG)
413
 
   if (ty == MPI_UNSIGNED_LONG_LONG) return sizeof(unsigned long long int);
414
 
#  endif
415
 
   if (ty == MPI_LONG_LONG_INT)      return sizeof(signed long long int);
 
508
   if (ty == MPI_UNSIGNED_LONG_LONG) return 8; /* MPI2 spec */;
 
509
#  endif
 
510
#  if defined(MPI_COMPLEX)
 
511
   if (ty == MPI_COMPLEX)            return 2 * 4; /* MPI2 spec */
 
512
#  endif
 
513
#  if defined(MPI_DOUBLE_COMPLEX)
 
514
   if (ty == MPI_DOUBLE_COMPLEX)     return 2 * 8; /* MPI2 spec */
 
515
#  endif
 
516
#  if defined(MPI_LOGICAL)
 
517
   if (ty == MPI_LOGICAL)            return 4; /* MPI2 spec */
 
518
#  endif
 
519
#  if defined(MPI_2INTEGER)
 
520
   if (ty == MPI_2INTEGER)      return 2 * 4; /* undocumented in MPI2 */
 
521
#  endif
 
522
#  if defined(MPI_2COMPLEX)
 
523
   if (ty == MPI_2COMPLEX)      return 2 * 8; /* undocumented in MPI2 */
 
524
#  endif
 
525
#  if defined(MPI_2DOUBLE_COMPLEX)
 
526
   /* 32: this is how openmpi-1.2.2 behaves on x86-linux, but I have
 
527
      really no idea if this is right. */
 
528
   if (ty == MPI_2DOUBLE_COMPLEX)   return 32; /* undocumented in MPI2 */
 
529
#  endif
 
530
#  if defined(MPI_2REAL)
 
531
   if (ty == MPI_2REAL)              return 2 * 4; /* undocumented in MPI2 */
 
532
#  endif
 
533
#  if defined(MPI_2DOUBLE_PRECISION)
 
534
   if (ty == MPI_2DOUBLE_PRECISION)  return 2 * 8; /* undocumented in MPI2 */
 
535
#  endif
 
536
#  if defined(MPI_CHARACTER)
 
537
   if (ty == MPI_CHARACTER)          return 1; /* MPI2 spec */
 
538
#  endif
 
539
 
416
540
   /* Note: the following are named structs, not named basic types,
417
541
      and so are not handled here:
418
542
         FLOAT_INT DOUBLE_INT LONG_INT 2INT SHORT_INT LONG_DOUBLE_INT
424
548
}
425
549
 
426
550
 
 
551
/* Find the size of long double image (not 'sizeof(long double)').
 
552
   See comments in sizeofOneNamedTy. 
 
553
*/
 
554
static long sizeof_long_double_image ( void )
 
555
{
 
556
   long i;
 
557
   unsigned char* p;
 
558
   static long cached_result = 0;
 
559
 
 
560
   /* Hopefully we have it already. */
 
561
   if (cached_result != 0) {
 
562
      assert(cached_result == 10 || cached_result == 16 || cached_result == 8);
 
563
      return cached_result;
 
564
   }
 
565
 
 
566
   /* No?  Then we'll have to compute it.  This isn't thread-safe but
 
567
      it doesn't really matter since all races to compute it should
 
568
      produce the same answer. */
 
569
   p = malloc(64);
 
570
   assert(p);
 
571
   for (i = 0; i < 64; i++)
 
572
      p[i] = 0x55;
 
573
 
 
574
   /* Write a value which isn't known at compile time and therefore
 
575
      must come out of a register.  If we just store a constant here,
 
576
      some compilers write more data than a store from a machine
 
577
      register would.  Therefore we have to force a store from a
 
578
      machine register by storing a value which isn't known at compile
 
579
      time.  Since getpid() will return a value < 1 million, turn it
 
580
      into a zero by dividing by 1e+30. */
 
581
   *(long double*)(&p[16]) = (long double)(1.0e-30 * (double)getpid());
 
582
 
 
583
   for (i = 0; i < 16; i++) {
 
584
      assert(p[i] == 0x55);
 
585
      assert(p[i+48] == 0x55);
 
586
   }
 
587
   for (i = 16; i <= 48; i++) {
 
588
      if (p[i] == 0x55)
 
589
         break;
 
590
   }
 
591
 
 
592
   assert(i < 48);
 
593
   assert(i > 16);
 
594
   free(p);
 
595
   cached_result = i - 16;
 
596
 
 
597
   if (0) 
 
598
      printf("sizeof_long_double_image: computed %d\n", (int)cached_result);
 
599
 
 
600
   assert(cached_result == 10 || cached_result == 16 || cached_result == 8);
 
601
   return cached_result;
 
602
}
 
603
 
 
604
 
427
605
/*------------------------------------------------------------*/
428
606
/*--- Unpicking datatypes                                  ---*/
429
607
/*------------------------------------------------------------*/
430
608
 
431
 
static 
 
609
static __inline__
432
610
void walk_type_array ( void(*f)(void*,long), char* base, 
433
611
                       MPI_Datatype ty, long count );
434
612
 
445
623
   MPI_Aint*     addrs = NULL;
446
624
   MPI_Datatype* dtys  = NULL;
447
625
 
 
626
   /* Stuff for limiting how much complaining text it spews out */
 
627
   static int complaints = 3;
 
628
   static int last_complained_about_tycon = -987654321; /* presumably bogus */
 
629
 
448
630
   if (0)
449
 
      printf("walk_type %p\n", (void*)ty);
 
631
      printf("walk_type %p\n", (void*)(unsigned long)ty);
450
632
 
451
633
   r = PMPI_Type_get_envelope( ty, &n_ints, &n_addrs, &n_dtys, &tycon );
452
634
   assert(r == MPI_SUCCESS);
462
644
         take them to bits so we have to do a really ugly hack, which
463
645
         makes assumptions about how the MPI implementation has laid
464
646
         out these types.  At least Open MPI 1.0.1 appears to put
465
 
         the 'val' field first.
 
647
         the 'val' field first.  MPICH2 agrees.
466
648
      */
 
649
      if (ty == MPI_2INT) {
 
650
         typedef struct { int val; int loc; } Ty;
 
651
         f(base + offsetof(Ty,val), sizeof(int));
 
652
         f(base + offsetof(Ty,loc), sizeof(int));
 
653
         return;
 
654
      }
467
655
      if (ty == MPI_LONG_INT) {
468
656
         typedef struct { long val; int loc; } Ty;
469
657
         f(base + offsetof(Ty,val), sizeof(long));
482
670
         f(base + offsetof(Ty,loc), sizeof(int));
483
671
         return;
484
672
      }
 
673
      if (ty == MPI_FLOAT_INT) {
 
674
         typedef struct { float val; int loc; } Ty;
 
675
         f(base + offsetof(Ty,val), sizeof(float));
 
676
         f(base + offsetof(Ty,loc), sizeof(int));
 
677
         return;
 
678
      }
 
679
      if (ty == MPI_LONG_DOUBLE_INT) {
 
680
         typedef struct { long double val; int loc; } Ty;
 
681
         f(base + offsetof(Ty,val), sizeof_long_double_image());
 
682
         f(base + offsetof(Ty,loc), sizeof(int));
 
683
         return;
 
684
      }
485
685
      if (ty == MPI_LB || ty == MPI_UB)
486
686
         return; /* have zero size, so nothing needs to be done */
487
687
      goto unhandled;
607
807
   return;
608
808
 
609
809
  unhandled:
610
 
   if (tycon == MPI_COMBINER_NAMED) {
611
 
      fprintf(stderr, "%s %5d: walk_type: unhandled base type 0x%lx ",
612
 
                      preamble, my_pid, (long)ty);
613
 
      showTy(stderr, ty);
614
 
      fprintf(stderr, "\n");
615
 
   } else {
616
 
      fprintf(stderr, "%s %5d: walk_type: unhandled combiner 0x%lx\n",
617
 
                      preamble, my_pid, (long)tycon);
 
810
   /* Complain, but limit the amount of complaining that can happen to
 
811
      the first 3 different unhandled tycons that show up, so as to
 
812
      avoid swamping users with thousands of duplicate messages. */
 
813
   if (complaints > 0 && tycon != last_complained_about_tycon) {
 
814
      complaints--;
 
815
      last_complained_about_tycon = tycon;
 
816
      if (tycon == MPI_COMBINER_NAMED) {
 
817
         fprintf(stderr, "%s %5d: walk_type: unhandled base type 0x%lx ",
 
818
                         preamble, my_pid, (long)ty);
 
819
         showTy(stderr, ty);
 
820
         fprintf(stderr, "\n");
 
821
      } else {
 
822
         fprintf(stderr, "%s %5d: walk_type: unhandled combiner 0x%lx\n",
 
823
                         preamble, my_pid, (long)tycon);
 
824
      }
618
825
   }
619
826
   if (ints)  free(ints);
620
827
   if (addrs) free(addrs);
629
836
   into a different routine is so it can attempt to optimise the case
630
837
   where the array elements are contiguous and packed together without
631
838
   holes. */
632
 
static 
 
839
static __inline__
633
840
void walk_type_array ( void(*f)(void*,long), char* base, 
634
841
                       MPI_Datatype elemTy, long count )
635
842
{
674
881
void mpiwrap_walk_type_EXTERNALLY_VISIBLE
675
882
    ( void(*f)(void*,long), char* base, MPI_Datatype ty )
676
883
{
677
 
   return walk_type(f, base, ty);
 
884
   walk_type(f, base, ty);
678
885
}
679
886
 
680
887
 
688
895
   ----------------
689
896
*/
690
897
 
691
 
static inline
 
898
static __inline__
692
899
void check_mem_is_defined_untyped ( void* buffer, long nbytes )
693
900
{
694
901
   if (nbytes > 0) {
696
903
   }
697
904
}
698
905
 
699
 
static inline
 
906
static __inline__
700
907
void check_mem_is_addressable_untyped ( void* buffer, long nbytes )
701
908
{
702
909
   if (nbytes > 0) {
704
911
   }
705
912
}
706
913
 
707
 
static inline
 
914
static __inline__
708
915
void make_mem_defined_if_addressable_untyped ( void* buffer, long nbytes )
709
916
{
710
917
   if (nbytes > 0) {
712
919
   }
713
920
}
714
921
 
715
 
static inline
 
922
static __inline__
716
923
void make_mem_defined_if_addressable_if_success_untyped ( int err, 
717
924
                                       void* buffer, long nbytes )
718
925
{
721
928
   }
722
929
}
723
930
 
724
 
/* Set the specified area to 'addressible but undefined'
725
 
   (safe-to-write) state. */
726
 
 
727
 
static inline
728
 
void make_mem_undefined_untyped ( void* buffer, long nbytes )
729
 
{
730
 
   if (nbytes > 0) {
731
 
      VALGRIND_MAKE_MEM_UNDEFINED(buffer, nbytes);
732
 
   }
733
 
}
734
 
 
735
931
 
736
932
/* ----------------
737
933
   Do checks on memory areas defined using the MPI (buffer, count,
742
938
/* Check that the specified area is both addressible and contains
743
939
   initialised data, and cause V to complain if not. */
744
940
 
745
 
static
 
941
static __inline__
746
942
void check_mem_is_defined ( char* buffer, long count, MPI_Datatype datatype )
747
943
{
748
944
   walk_type_array( check_mem_is_defined_untyped, buffer, datatype, count );
753
949
   complain if not. Doesn't matter whether the data there is
754
950
   initialised or not. */
755
951
 
756
 
static
 
952
static __inline__
757
953
void check_mem_is_addressable ( void *buffer, long count, MPI_Datatype datatype )
758
954
{
759
955
   walk_type_array( check_mem_is_addressable_untyped, buffer, datatype, count );
763
959
/* Set the specified area to 'defined for each byte which is
764
960
   addressible' state. */
765
961
 
766
 
static
 
962
static __inline__
767
963
void make_mem_defined_if_addressable ( void *buffer, int count, MPI_Datatype datatype )
768
964
{
769
965
   walk_type_array( make_mem_defined_if_addressable_untyped,
770
966
                    buffer, datatype, count );
771
967
}
772
968
 
773
 
static
 
969
static __inline__
774
970
void 
775
971
make_mem_defined_if_addressable_if_success ( int err, void *buffer, int count, 
776
972
                                             MPI_Datatype datatype )
874
1070
   int    err;
875
1071
   VALGRIND_GET_ORIG_FN(fn);
876
1072
   before("Get_count");
 
1073
#  if defined(_AIX)
 
1074
   check_mem_is_addressable_untyped(status, sizeof(*status));
 
1075
#  else
877
1076
   check_mem_is_defined_untyped(status, sizeof(*status));
 
1077
#  endif
878
1078
   CALL_FN_W_WWW(err, fn, status,ty,count);
879
1079
   after("Get_count", err);
880
1080
   return err;
1061
1261
   if (count < 0) 
1062
1262
      count = 0; /* Hmm.  Call Mulder and Scully. */
1063
1263
   copy = malloc( count * sizeof(MPI_Request) );
1064
 
   if (copy == NULL) {
 
1264
   if (copy == NULL && count > 0) {
1065
1265
      UNLOCK_SREQS;
1066
1266
      barf("clone_Request_array: malloc failed");
1067
1267
   }
1113
1313
/* --- Isend --- */
1114
1314
/* rd: (buf,count,datatype) */
1115
1315
/* wr: *request */
1116
 
static
 
1316
static __inline__
1117
1317
int generic_Isend(void *buf, int count, MPI_Datatype datatype, 
1118
1318
                             int dest, int tag, MPI_Comm comm, 
1119
1319
                             MPI_Request* request)
1203
1403
   return err;
1204
1404
}
1205
1405
 
 
1406
/* --- Waitany --- */
 
1407
int WRAPPER_FOR(PMPI_Waitany)( int count,
 
1408
                               MPI_Request* requests,
 
1409
                               int* index,
 
1410
                               MPI_Status* status )
 
1411
{
 
1412
   MPI_Request* requests_before = NULL;
 
1413
   OrigFn       fn;
 
1414
   int          err, i;
 
1415
   VALGRIND_GET_ORIG_FN(fn);
 
1416
   before("Waitany");
 
1417
   if (0) fprintf(stderr, "Waitany: %d\n", count);
 
1418
   check_mem_is_addressable_untyped(index, sizeof(int));
 
1419
   check_mem_is_addressable_untyped(status, sizeof(MPI_Status));
 
1420
   for (i = 0; i < count; i++) {
 
1421
      check_mem_is_defined_untyped(&requests[i], sizeof(MPI_Request));
 
1422
   }
 
1423
   requests_before = clone_Request_array( count, requests );
 
1424
   CALL_FN_W_WWWW(err, fn, count,requests,index,status);
 
1425
   if (err == MPI_SUCCESS && *index >= 0 && *index < count) {
 
1426
      maybe_complete(False/*err in status?*/, 
 
1427
                     requests_before[*index], requests[*index], status);
 
1428
      make_mem_defined_if_addressable_untyped(status, sizeof(MPI_Status));
 
1429
   }
 
1430
   if (requests_before)
 
1431
      free(requests_before);
 
1432
   after("Waitany", err);
 
1433
   return err;
 
1434
}
 
1435
 
1206
1436
/* --- Waitall --- */
1207
1437
int WRAPPER_FOR(PMPI_Waitall)( int count, 
1208
1438
                               MPI_Request* requests,
1442
1672
 
1443
1673
/*------------------------------------------------------------*/
1444
1674
/*---                                                      ---*/
 
1675
/*--- Sec 3.13, Pack and unpack                            ---*/
 
1676
/*---                                                      ---*/
 
1677
/*------------------------------------------------------------*/
 
1678
 
 
1679
/* --- Pack --- */
 
1680
/* pre: must be readable: position
 
1681
        must be readable: (inbuf,incount,datatype)
 
1682
        must be writable: outbuf[0 .. outsize-1]
 
1683
        must be writable: outbuf[*position .. 
 
1684
                                 *position - 1 
 
1685
                                 + however much space PMPI_Pack_size 
 
1686
                                   says we will need]
 
1687
   post: make readable: outbuf[old *position .. new *position]
 
1688
*/
 
1689
int WRAPPER_FOR(PMPI_Pack)( void* inbuf, int incount, MPI_Datatype datatype, 
 
1690
                            void* outbuf, int outsize, 
 
1691
                            int* position, MPI_Comm comm ) 
 
1692
{
 
1693
   OrigFn fn;
 
1694
   int    err, szB = 0;
 
1695
   int    position_ORIG = *position;
 
1696
   VALGRIND_GET_ORIG_FN(fn);
 
1697
   before("Pack");
 
1698
   /* stay sane */
 
1699
   check_mem_is_defined_untyped(position, sizeof(*position));
 
1700
   /* check input */
 
1701
   check_mem_is_defined(inbuf, incount, datatype);
 
1702
   /* check output area's stated bounds make sense */
 
1703
   check_mem_is_addressable_untyped(outbuf, outsize);
 
1704
   /* check output area's actual used size properly */
 
1705
   err = PMPI_Pack_size( incount, datatype, comm, &szB );
 
1706
   if (err == MPI_SUCCESS && szB > 0) {
 
1707
      check_mem_is_addressable_untyped( 
 
1708
         ((char*)outbuf) + position_ORIG, szB
 
1709
      );
 
1710
   }
 
1711
 
 
1712
   CALL_FN_W_7W(err, fn, inbuf,incount,datatype, outbuf,outsize,position, comm);
 
1713
 
 
1714
   if (err == MPI_SUCCESS && (*position) > position_ORIG) {
 
1715
      /* paint output */
 
1716
      make_mem_defined_if_addressable_untyped( 
 
1717
         ((char*)outbuf) + position_ORIG, *position - position_ORIG
 
1718
      );
 
1719
   }
 
1720
   after("Pack", err);
 
1721
   return err;
 
1722
}
 
1723
 
 
1724
/* --- Unpack --- */
 
1725
/* pre: must be readable: position
 
1726
        must be writable: (outbuf,outcount,datatype)
 
1727
        must be writable: outbuf[0 .. outsize-1]
 
1728
        must be writable: outbuf[*position .. 
 
1729
                                 *position - 1 
 
1730
                                 + however much space PMPI_Pack_size 
 
1731
                                   says we will need]
 
1732
   post: make readable: (outbuf,outcount,datatype)
 
1733
         and also do a readability check of
 
1734
         inbuf[old *position .. new *position]
 
1735
*/
 
1736
int WRAPPER_FOR(PMPI_Unpack)( void* inbuf, int insize, int* position,
 
1737
                              void* outbuf, int outcount, MPI_Datatype datatype, 
 
1738
                              MPI_Comm comm )
 
1739
{
 
1740
   OrigFn fn;
 
1741
   int    err, szB = 0;
 
1742
   int    position_ORIG = *position;
 
1743
   VALGRIND_GET_ORIG_FN(fn);
 
1744
   before("Unpack");
 
1745
   /* stay sane */
 
1746
   check_mem_is_defined_untyped(position, sizeof(*position));
 
1747
   /* check output area is accessible */
 
1748
   check_mem_is_addressable(outbuf, outcount, datatype);
 
1749
   /* check input area's stated bounds make sense */
 
1750
   check_mem_is_addressable_untyped(inbuf, insize);
 
1751
   /* check input area's actual used size properly */
 
1752
   err = PMPI_Pack_size( outcount, datatype, comm, &szB );
 
1753
   if (err == MPI_SUCCESS && szB > 0) {
 
1754
      check_mem_is_addressable_untyped( 
 
1755
         ((char*)inbuf) + position_ORIG, szB
 
1756
      );
 
1757
   }
 
1758
 
 
1759
   CALL_FN_W_7W(err, fn, inbuf,insize,position, outbuf,outcount,datatype, comm);
 
1760
 
 
1761
   if (err == MPI_SUCCESS && (*position) > position_ORIG) {
 
1762
      /* recheck input more carefully */
 
1763
      check_mem_is_defined_untyped( 
 
1764
         ((char*)inbuf) + position_ORIG, *position - position_ORIG
 
1765
      );
 
1766
      /* paint output */
 
1767
      make_mem_defined_if_addressable( outbuf, outcount, datatype );
 
1768
   }
 
1769
   after("Unpack", err);
 
1770
   return err;
 
1771
}
 
1772
 
 
1773
 
 
1774
/*------------------------------------------------------------*/
 
1775
/*---                                                      ---*/
1445
1776
/*--- Sec 4.4, Broadcast                                   ---*/
1446
1777
/*---                                                      ---*/
1447
1778
/*------------------------------------------------------------*/
1776
2107
 
1777
2108
/* --- Init --- */
1778
2109
/* rd: *argc, *argv[0 .. *argc-1] */
1779
 
int WRAPPER_FOR(PMPI_Init)(int *argc, char ***argv)
 
2110
long WRAPPER_FOR(PMPI_Init)(int *argc, char ***argv)
1780
2111
{
1781
2112
   OrigFn fn;
1782
2113
   int    err;
1786
2117
   check_mem_is_defined_untyped(*argv, *argc * sizeof(char**));
1787
2118
   CALL_FN_W_WW(err, fn, argc,argv);
1788
2119
   after("Init", err);
1789
 
   return err;
 
2120
   if (opt_initkludge)
 
2121
      return (long)(void*)&mpiwrap_walk_type_EXTERNALLY_VISIBLE;
 
2122
   else
 
2123
      return (long)err;
1790
2124
}
1791
2125
 
1792
2126
/* --- Initialized --- */
2158
2492
DEFAULT_WRAPPER_W_1W(Op_free)
2159
2493
DEFAULT_WRAPPER_W_7W(Pack_external)
2160
2494
DEFAULT_WRAPPER_W_4W(Pack_external_size)
2161
 
DEFAULT_WRAPPER_W_7W(Pack)
 
2495
/* DEFAULT_WRAPPER_W_7W(Pack) */
2162
2496
DEFAULT_WRAPPER_W_4W(Pack_size)
2163
2497
/* int MPI_Pcontrol(const int level, ...) */
2164
2498
/* DEFAULT_WRAPPER_W_4W(Probe) */
2234
2568
DEFAULT_WRAPPER_W_5W(Type_struct)
2235
2569
DEFAULT_WRAPPER_W_2W(Type_ub)
2236
2570
DEFAULT_WRAPPER_W_5W(Type_vector)
2237
 
DEFAULT_WRAPPER_W_7W(Unpack)
 
2571
/* DEFAULT_WRAPPER_W_7W(Unpack) */
2238
2572
DEFAULT_WRAPPER_W_3W(Unpublish_name)
2239
2573
DEFAULT_WRAPPER_W_7W(Unpack_external)
2240
2574
/* DEFAULT_WRAPPER_W_3W(Waitall) */
2241
 
DEFAULT_WRAPPER_W_4W(Waitany)
 
2575
/* DEFAULT_WRAPPER_W_4W(Waitany) */
2242
2576
/* DEFAULT_WRAPPER_W_2W(Wait) */
2243
2577
DEFAULT_WRAPPER_W_5W(Waitsome)
2244
2578
DEFAULT_WRAPPER_W_1W(Win_c2f)