|
From: <sv...@va...> - 2006-03-04 02:32:00
|
Author: sewardj
Date: 2006-03-04 02:31:52 +0000 (Sat, 04 Mar 2006)
New Revision: 5712
Log:
Fix a type-size subtlety.
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-03 21:03:10 UTC (rev 5711)
+++ trunk/auxprogs/mpiwrap.c 2006-03-04 02:31:52 UTC (rev 5712)
@@ -229,6 +229,9 @@
return r1 =3D=3D r2;
}
=20
+/* Get the 'extent' of a type. Note, as per the MPI spec this
+ includes whatever padding would be required when using 'ty' in an
+ array. */
static long extentOfTy ( MPI_Datatype ty )
{
int r;
@@ -284,15 +287,20 @@
else fprintf(f,"showTy:???\n");
}
=20
-/* How big is a "named" (base) type? Returns 0 if not known. */
-static long sizeofNamedTy ( MPI_Datatype ty )
+/* How big is a "named" (base) type? Returns 0 if not known. Note.
+ There is a subtlety, which is that this is required to return the
+ exact size of one item of the type, NOT the size of it when padded
+ suitably to make an array of them. In particular that's why the
+ size of LONG_DOUBLE is 10 and not sizeof(long double), since the
+ latter is 12 at least on x86. */
+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 sizeof(long double);
+ 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);
return 0;
@@ -329,7 +337,7 @@
=20
/* Handle the base cases fast(er/ish). */
if (tycon =3D=3D MPI_COMBINER_NAMED) {
- long sz =3D sizeofNamedTy(ty);
+ long sz =3D sizeofOneNamedTy(ty);
if (sz =3D=3D 0)=20
goto unhandled;
f(base,sz);
@@ -423,7 +431,7 @@
assert(sizeof(unsigned long) =3D=3D sizeof(char*));
=20
/* First see if we can do this the fast way. */
- ex =3D sizeofNamedTy(elemTy);
+ ex =3D sizeofOneNamedTy(elemTy);
=20
if ( /* ty is a primitive type with power-of-2 size */
(ex =3D=3D 8 || ex =3D=3D 4 || ex =3D=3D 2 || ex =3D=3D 1)
@@ -438,7 +446,13 @@
} else {
=20
/* Bad news. We have to futz with each element individually.
- This could be very expensive. */
+ This could be very expensive.
+
+ Note: subtle. If ty is LONG_DOUBLE then the extent will be
+ 12, so the following loop will jump along in steps of 12, but
+ the size painted by walk_type will be 10 since it uses
+ sizeofOneNamedTy to establish the size of base types. Which
+ is what we need to happen. */
ex =3D extentOfTy(elemTy);
if (0) printf("walk_type_array SLOW %ld of size %ld\n", count, ex =
);
for (i =3D 0; i < count; i++)
|