|
From: <sv...@va...> - 2006-03-10 13:43:53
|
Author: sewardj
Date: 2006-03-10 13:43:49 +0000 (Fri, 10 Mar 2006)
New Revision: 5737
Log:
- Improve handling of MPI base types
- Use MAKE_DEFINED rather than MAKE_READABLE, as the latter's
behaviour - changing A bits as well as V bits - can hide=20
addressing problems later
Modified:
trunk/auxprogs/mpiwrap.c
Modified: trunk/auxprogs/mpiwrap.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/auxprogs/mpiwrap.c 2006-03-10 13:41:58 UTC (rev 5736)
+++ trunk/auxprogs/mpiwrap.c 2006-03-10 13:43:49 UTC (rev 5737)
@@ -109,7 +109,11 @@
typedef signed long Word;
typedef unsigned long UWord;
=20
+#if !defined(offsetof)
+# define offsetof(type,memb) ((int)&((type*)0)->memb)
+#endif
=20
+
/*------------------------------------------------------------*/
/*--- Simple helpers ---*/
/*------------------------------------------------------------*/
@@ -341,7 +345,7 @@
return (long)n;
}
=20
-/* Free up *ty, if it is not a named type */
+/* Free up *ty, if it is safe to do so */
static void maybeFreeTy ( MPI_Datatype* ty )
{
int r, n_ints, n_addrs, n_dtys, tycon;
@@ -349,23 +353,28 @@
r =3D PMPI_Type_get_envelope( *ty, &n_ints, &n_addrs, &n_dtys, &tycon=
);
assert(r =3D=3D MPI_SUCCESS);
=20
- if (tycon !=3D MPI_COMBINER_NAMED
- /* Don't ask me how ty can be a primitive type and yet not be
- marked as MPI_COMBINER_NAMED. It does appear to happen
- though. */
- && *ty !=3D MPI_LONG_INT
- ) {
- if (0) {
- /* show me what you're about to free .. */
- fprintf(stderr, "freeing combiner ");
- showCombiner(stderr,tycon);
- fprintf(stderr, " ty=3D ");
- showTy(stderr,*ty);
- fprintf(stderr,"\n");
- }
- r =3D PMPI_Type_free(ty);
- assert(r =3D=3D MPI_SUCCESS);
+ /* can't free named types */
+ if (tycon =3D=3D MPI_COMBINER_NAMED)
+ return;
+
+ /* some kinds of structs are predefined so we can't free them
+ either. */
+ if (*ty =3D=3D MPI_FLOAT_INT || *ty =3D=3D MPI_DOUBLE_INT=20
+ || *ty =3D=3D MPI_LONG_INT || *ty =3D=3D MPI_2INT=20
+ || *ty =3D=3D MPI_SHORT_INT || *ty =3D=3D MPI_LONG_DOUBLE_INT)
+ return;
+
+ /* Looks OK - free it. */
+ if (0) {
+ /* show me what you're about to free .. */
+ fprintf(stderr, "freeing combiner ");
+ showCombiner(stderr,tycon);
+ fprintf(stderr, " ty=3D ");
+ showTy(stderr,*ty);
+ fprintf(stderr,"\n");
}
+ r =3D PMPI_Type_free(ty);
+ assert(r =3D=3D MPI_SUCCESS);
}
=20
/* How big is a "named" (base) type? Returns 0 if not known. Note.
@@ -376,19 +385,31 @@
latter is 12 at least on x86. Ref: MPI 1.1 doc p18 */
static long sizeofOneNamedTy ( MPI_Datatype ty )
{
- if (ty =3D=3D MPI_DOUBLE) return sizeof(double);
- if (ty =3D=3D MPI_INT) return sizeof(signed int);
- if (ty =3D=3D MPI_CHAR) return sizeof(signed char);
- if (ty =3D=3D MPI_UNSIGNED) return sizeof(unsigned int);
- if (ty =3D=3D MPI_LONG) return sizeof(signed long int);
- if (ty =3D=3D MPI_LONG_DOUBLE) return 10; /* NOT: sizeof(long double)=
; */
- /* MPI1.1 does not define MPI_LONG_INT, hence the following is a gues=
s */
- if (ty =3D=3D MPI_LONG_INT) return sizeof(signed long int);
- if (ty =3D=3D MPI_BYTE) return 1;
- if (ty =3D=3D MPI_FLOAT) return sizeof(float);
- if (ty =3D=3D MPI_SHORT) return sizeof(signed short int);
+ if (ty =3D=3D MPI_CHAR) return sizeof(signed char);
+ if (ty =3D=3D MPI_SHORT) return sizeof(signed short int);
+ if (ty =3D=3D MPI_INT) return sizeof(signed int);
+ if (ty =3D=3D MPI_LONG) return sizeof(signed long int);
if (ty =3D=3D MPI_UNSIGNED_CHAR) return sizeof(unsigned char);
if (ty =3D=3D MPI_UNSIGNED_SHORT) return sizeof(unsigned short int);
+ if (ty =3D=3D MPI_UNSIGNED) return sizeof(unsigned int);
+ if (ty =3D=3D MPI_UNSIGNED_LONG) return sizeof(unsigned long int);
+ if (ty =3D=3D MPI_FLOAT) return sizeof(float);
+ if (ty =3D=3D MPI_DOUBLE) return sizeof(double);
+ if (ty =3D=3D MPI_LONG_DOUBLE) return 10; /* NOT: sizeof(long doub=
le); */
+ if (ty =3D=3D MPI_BYTE) return 1;
+ /* MPI_PACKED */
+ /* new in MPI2: */
+ if (ty =3D=3D MPI_WCHAR) return sizeof(wchar_t);
+ if (ty =3D=3D MPI_SIGNED_CHAR) return sizeof(signed char);
+ if (ty =3D=3D MPI_UNSIGNED_LONG_LONG) return sizeof(unsigned long lon=
g int);
+ if (ty =3D=3D MPI_LONG_LONG_INT) return sizeof(signed long long =
int);
+ /* Note: the following are named structs, not named basic types,
+ and so are not handled here:
+ FLOAT_INT DOUBLE_INT LONG_INT 2INT SHORT_INT LONG_DOUBLE_INT
+ My guess is they are probably for doing max-w-index style
+ reductions, the INT carrying the index of the max/min and the
+ other type its actual value.
+ */
return 0;
}
=20
@@ -423,10 +444,22 @@
/* Handle the base cases fast(er/ish). */
if (tycon =3D=3D MPI_COMBINER_NAMED) {
long sz =3D sizeofOneNamedTy(ty);
- if (sz =3D=3D 0)=20
- goto unhandled;
- f(base,sz);
- return;
+ if (sz > 0) {
+ f(base, sz);
+ return;
+ }
+ /* Hmm. Perhaps it's a named struct? Unfortunately we can't
+ take them to bits so we have to do a really ugly hack, which
+ makes assumptions about how the MPI implementation has laid
+ out these types.
+ */
+ if (ty =3D=3D MPI_LONG_INT) {
+ typedef struct { long dbl; int loc; } Ty;
+ f(base + offsetof(Ty,dbl), sizeof(long));
+ f(base + offsetof(Ty,loc), sizeof(int));
+ return;
+ }
+ goto unhandled;
/*NOTREACHED*/
}
=20
@@ -560,11 +593,16 @@
if (ints) free(ints);
if (addrs) free(addrs);
if (dtys) free(dtys);
+ if (opt_missing >=3D 2)
+ barf("walk_type: unhandled combiner, strict checking selected");
}
=20
=20
-/* Same as walk_type but apply 'f' to every element in an array
- of 'count' items starting at 'base'. */
+/* Same as walk_type but apply 'f' to every element in an array of
+ 'count' items starting at 'base'. The only purpose of pushing this
+ into a different routine is so it can attempt to optimise the case
+ where the array elements are contiguous and packed together without
+ holes. */
static=20
void walk_type_array ( void(*f)(void*,long), char* base,=20
MPI_Datatype elemTy, long count )
@@ -639,19 +677,19 @@
}
=20
static inline
-void make_readable_untyped ( void* buffer, long nbytes )
+void make_defined_untyped ( void* buffer, long nbytes )
{
if (nbytes > 0) {
- VALGRIND_MAKE_READABLE(buffer, nbytes);
+ VALGRIND_MAKE_DEFINED(buffer, nbytes);
}
}
=20
static inline
-void make_readable_if_success_untyped ( int err,=20
- void* buffer, long nbytes )
+void make_defined_if_success_untyped ( int err,=20
+ void* buffer, long nbytes )
{
if (err =3D=3D MPI_SUCCESS && nbytes > 0) {
- VALGRIND_MAKE_READABLE(buffer, nbytes);
+ VALGRIND_MAKE_DEFINED(buffer, nbytes);
}
}
=20
@@ -694,22 +732,22 @@
}
=20
=20
-/* Set the specified area to 'addressible and defined' (safe-to-read)
- state. */
+/* Set the specified area to 'defined for each byte which is
+ addressible' state. */
=20
static
-void make_readable ( void *buffer, int count, MPI_Datatype datatype )
+void make_defined ( void *buffer, int count, MPI_Datatype datatype )
{
- walk_type_array( make_readable_untyped, buffer, datatype, count );
+ walk_type_array( make_defined_untyped, buffer, datatype, count );
}
=20
static
void=20
-make_readable_if_success ( int err, void *buffer, int count,=20
- MPI_Datatype datatype )
+make_defined_if_success ( int err, void *buffer, int count,=20
+ MPI_Datatype datatype )
{
if (err =3D=3D MPI_SUCCESS)
- make_readable(buffer, count, datatype);
+ make_defined(buffer, count, datatype);
}
=20
=20
@@ -784,7 +822,7 @@
check_writable_untyped(status, sizeof(*status));
CALL_FN_W_7W(err, fn, buf,count,datatype,source,tag,comm,status);
if (err =3D=3D MPI_SUCCESS && count_from_Status(&recv_count,datatype,=
status)) {
- make_readable(buf, recv_count, datatype);
+ make_defined(buf, recv_count, datatype);
}
after("Recv", err);
return err;
@@ -956,7 +994,7 @@
/* The Irecv detailed in 'shadow' completed. Make the result
buffer, and delete the entry. */
if (count_from_Status(&recv_count, shadow->datatype, status)) {
- make_readable(shadow->buf, recv_count, shadow->datatype);
+ make_defined(shadow->buf, recv_count, shadow->datatype);
if (opt_verbosity > 1)
fprintf(stderr, "%s %5d: sReq- %p (completed)\n",=20
preamble, my_pid, request_before);
@@ -996,7 +1034,7 @@
check_readable(buf, count, datatype);
check_writable_untyped(request, sizeof(*request));
CALL_FN_W_7W(err, fn, buf,count,datatype,dest,tag,comm,request);
- make_readable_if_success_untyped(err, request, sizeof(*request));
+ make_defined_if_success_untyped(err, request, sizeof(*request));
after("Isend", err);
return err;
}
@@ -1019,7 +1057,7 @@
check_writable_untyped(request, sizeof(*request));
CALL_FN_W_7W(err, fn, buf,count,datatype,source,tag,comm,request);
if (err =3D=3D MPI_SUCCESS) {
- make_readable_untyped(request, sizeof(*request));
+ make_defined_untyped(request, sizeof(*request));
add_shadow_Request( *request, buf,count,datatype );
}
after("Irecv", err);
@@ -1043,7 +1081,7 @@
if (err =3D=3D MPI_SUCCESS) {
maybe_complete(False/*err in status?*/,=20
request_before, *request, status);
- make_readable_untyped(status, sizeof(MPI_Status));
+ make_defined_untyped(status, sizeof(MPI_Status));
}
after("Wait", err);
return err;
@@ -1073,7 +1111,7 @@
for (i =3D 0; i < count; i++) {
maybe_complete(e_i_s, requests_before[i], requests[i],=20
&statuses[i]);
- make_readable_untyped(&statuses[i], sizeof(MPI_Status));
+ make_defined_untyped(&statuses[i], sizeof(MPI_Status));
}
}
if (requests_before)
@@ -1100,9 +1138,9 @@
check_writable_untyped(status, sizeof(*status));
CALL_FN_W_5W(err, fn, source,tag,comm,flag,status);
if (err =3D=3D MPI_SUCCESS) {
- make_readable_untyped(flag, sizeof(*flag));
+ make_defined_untyped(flag, sizeof(*flag));
if (*flag)
- make_readable_untyped(status, sizeof(*status));
+ make_defined_untyped(status, sizeof(*status));
else
make_writable_untyped(status, sizeof(*status));
}
@@ -1141,7 +1179,7 @@
comm,status);
if (err =3D=3D MPI_SUCCESS=20
&& count_from_Status(&recvcount_actual,recvtype,status)) {
- make_readable(recvbuf, recvcount_actual, recvtype);
+ make_defined(recvbuf, recvcount_actual, recvtype);
}
after("Sendrecv", err);
return err;
@@ -1189,7 +1227,7 @@
check_writable(buffer, count, datatype);
}
CALL_FN_W_5W(err, fn, buffer,count,datatype,root,comm);
- make_readable_if_success(err, buffer, count, datatype);
+ make_defined_if_success(err, buffer, count, datatype);
after("Bcast", err);
return err;=20
}
@@ -1230,7 +1268,7 @@
CALL_FN_W_8W(err, fn, sendbuf,sendcount,sendtype,
recvbuf,recvcount,recvtype,
root,comm);
- make_readable_if_success(err, recvbuf, recvcount * sz, recvtype);
+ make_defined_if_success(err, recvbuf, recvcount * sz, recvtype);
after("Gather", err);
return err;
}
@@ -1262,7 +1300,7 @@
check_writable(recvbuf, count, datatype);
CALL_FN_W_7W(err, fn, sendbuf,recvbuf,count,datatype,op,root,comm);
if (i_am_root)
- make_readable_if_success(err, recvbuf, count, datatype);
+ make_defined_if_success(err, recvbuf, count, datatype);
after("Reduce", err);
return err;
}
@@ -1284,7 +1322,7 @@
check_readable(sendbuf, count, datatype);
check_writable(recvbuf, count, datatype);
CALL_FN_W_6W(err, fn, sendbuf,recvbuf,count,datatype,op,comm);
- make_readable_if_success(err, recvbuf, count, datatype);
+ make_defined_if_success(err, recvbuf, count, datatype);
after("Allreduce", err);
return err;
}
@@ -1304,7 +1342,7 @@
before("Op_create");
check_writable_untyped(op, sizeof(*op));
CALL_FN_W_WWW(err, fn, function,commute,op);
- make_readable_if_success_untyped(err, op, sizeof(*op));
+ make_defined_if_success_untyped(err, op, sizeof(*op));
after("Op_create", err);
return err;
}
@@ -1329,7 +1367,7 @@
before("Comm_rank");
check_writable_untyped(rank, sizeof(*rank));
CALL_FN_W_WW(err, fn, comm,rank);
- make_readable_if_success_untyped(err, rank, sizeof(*rank));
+ make_defined_if_success_untyped(err, rank, sizeof(*rank));
after("Comm_rank", err);
return err;
}
@@ -1344,7 +1382,7 @@
before("Comm_size");
check_writable_untyped(size, sizeof(*size));
CALL_FN_W_WW(err, fn, comm,size);
- make_readable_if_success_untyped(err, size, sizeof(*size));
+ make_defined_if_success_untyped(err, size, sizeof(*size));
after("Comm_size", err);
return err;
}
@@ -1410,7 +1448,7 @@
before("Initialized");
check_writable_untyped(flag, sizeof(int));
CALL_FN_W_W(err, fn, flag);
- make_readable_if_success_untyped(err, flag, sizeof(int));
+ make_defined_if_success_untyped(err, flag, sizeof(int));
after("Initialized", err);
return err;
}
|