|
From: <sv...@va...> - 2006-03-03 21:03:14
|
Author: sewardj
Date: 2006-03-03 21:03:10 +0000 (Fri, 03 Mar 2006)
New Revision: 5711
Log:
More futzing with the machinery for traversing datatypes.
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:02:18 UTC (rev 5710)
+++ trunk/auxprogs/mpiwrap.c 2006-03-03 21:03:10 UTC (rev 5711)
@@ -136,7 +136,6 @@
opt_strict =3D NULL !=3D strstr(options_str, "strict");
fprintf(stderr, "%s %5d: Active for pid %d\n",=20
preamble, my_pid, my_pid);
-
/* Sanity check - that 'long' really is a machine word. */
assert(sizeof(long) =3D=3D sizeof(void*));
/* Sanity check - char is byte-sized (else address calculations
@@ -248,12 +247,58 @@
assert(r =3D=3D MPI_SUCCESS);
=20
if (tycon !=3D MPI_COMBINER_NAMED) {
- r =3D MPI_Type_free(ty);
+ r =3D PMPI_Type_free(ty);
assert(r =3D=3D MPI_SUCCESS);
}
}
=20
+/* Half-hearted type-showing function (for debugging). */
+static void showTy ( FILE* f, MPI_Datatype ty )
+{
+ if (ty =3D=3D MPI_DATATYPE_NULL) fprintf(f,"DATATYPE_NULL\n");
+ else if (ty =3D=3D MPI_BYTE) fprintf(f,"BYTE\n");
+ else if (ty =3D=3D MPI_PACKED) fprintf(f,"PACKED\n");
+ else if (ty =3D=3D MPI_CHAR) fprintf(f,"CHAR\n");
+ else if (ty =3D=3D MPI_SHORT) fprintf(f,"SHORT\n");
+ else if (ty =3D=3D MPI_INT) fprintf(f,"INT\n");
+ else if (ty =3D=3D MPI_LONG) fprintf(f,"LONG\n");
+ else if (ty =3D=3D MPI_FLOAT) fprintf(f,"FLOAT\n");
+ else if (ty =3D=3D MPI_DOUBLE) fprintf(f,"DOUBLE\n");
+ else if (ty =3D=3D MPI_LONG_DOUBLE) fprintf(f,"LONG_DOUBLE\n");
+ else if (ty =3D=3D MPI_UNSIGNED_CHAR) fprintf(f,"UNSIGNED_CHAR\n");
+ else if (ty =3D=3D MPI_UNSIGNED_SHORT) fprintf(f,"UNSIGNED_SHORT\n");
+ else if (ty =3D=3D MPI_UNSIGNED_LONG) fprintf(f,"UNSIGNED_LONG\n");
+ else if (ty =3D=3D MPI_UNSIGNED) fprintf(f,"UNSIGNED\n");
+ else if (ty =3D=3D MPI_FLOAT_INT) fprintf(f,"FLOAT_INT\n");
+ else if (ty =3D=3D MPI_DOUBLE_INT) fprintf(f,"DOUBLE_INT\n");
+ else if (ty =3D=3D MPI_LONG_DOUBLE_INT) fprintf(f,"LONG_DOUBLE_INT\n"=
);
+ else if (ty =3D=3D MPI_LONG_INT) fprintf(f,"LONG_INT\n");
+ else if (ty =3D=3D MPI_SHORT_INT) fprintf(f,"SHORT_INT\n");
+ else if (ty =3D=3D MPI_2INT) fprintf(f,"2INT\n");
+ else if (ty =3D=3D MPI_UB) fprintf(f,"UB\n");
+ else if (ty =3D=3D MPI_LB) fprintf(f,"LB\n");
+ else if (ty =3D=3D MPI_WCHAR) fprintf(f,"WCHAR\n");
+ else if (ty =3D=3D MPI_LONG_LONG_INT) fprintf(f,"LONG_LONG_INT\n");
+ else if (ty =3D=3D MPI_LONG_LONG) fprintf(f,"LONG_LONG\n");
+ else if (ty =3D=3D MPI_UNSIGNED_LONG_LONG) fprintf(f,"UNSIGNED_LONG_L=
ONG\n");
+ else fprintf(f,"showTy:???\n");
+}
=20
+/* How big is a "named" (base) type? Returns 0 if not known. */
+static long sizeofNamedTy ( 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);
+ /* 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;
+}
+
+
/*------------------------------------------------------------*/
/*--- Unpicking datatypes ---*/
/*------------------------------------------------------------*/
@@ -270,58 +315,29 @@
void walk_type ( void(*f)(void*,long), char* base, MPI_Datatype ty )
{
int r, n_ints, n_addrs, n_dtys, tycon;
- long ex, count, i;
+ long ex, i;
int* ints =3D NULL;
MPI_Aint* addrs =3D NULL;
MPI_Datatype* dtys =3D NULL;
// MPI_Datatype elemTy;
=20
- if (1) {=20
+ if (0)
printf("walk_type %p\n", (void*)ty);
- if (ty =3D=3D MPI_DATATYPE_NULL) printf("MPI_DATATYPE_NULL\n");
- else if (ty =3D=3D MPI_BYTE) printf("MPI_BYTE\n");
- else if (ty =3D=3D MPI_PACKED) printf("MPI_PACKED\n");
- else if (ty =3D=3D MPI_CHAR) printf("MPI_CHAR\n");
- else if (ty =3D=3D MPI_SHORT) printf("MPI_SHORT\n");
- else if (ty =3D=3D MPI_INT) printf("MPI_INT\n");
- else if (ty =3D=3D MPI_LONG) printf("MPI_LONG\n");
- else if (ty =3D=3D MPI_FLOAT) printf("MPI_FLOAT\n");
- else if (ty =3D=3D MPI_DOUBLE) printf("MPI_DOUBLE\n");
- else if (ty =3D=3D MPI_LONG_DOUBLE) printf("MPI_LONG_DOUBLE\n");
- else if (ty =3D=3D MPI_UNSIGNED_CHAR) printf("MPI_UNSIGNED_CHAR\n"=
);
- else if (ty =3D=3D MPI_UNSIGNED_SHORT) printf("MPI_UNSIGNED_SHORT\=
n");
- else if (ty =3D=3D MPI_UNSIGNED_LONG) printf("MPI_UNSIGNED_LONG\n"=
);
- else if (ty =3D=3D MPI_UNSIGNED) printf("MPI_UNSIGNED\n");
- else if (ty =3D=3D MPI_FLOAT_INT) printf("MPI_FLOAT_INT\n");
- else if (ty =3D=3D MPI_DOUBLE_INT) printf("MPI_DOUBLE_INT\n");
- else if (ty =3D=3D MPI_LONG_DOUBLE_INT) printf("MPI_LONG_DOUBLE_IN=
T\n");
- else if (ty =3D=3D MPI_LONG_INT) printf("MPI_LONG_INT\n");
- else if (ty =3D=3D MPI_SHORT_INT) printf("MPI_SHORT_INT\n");
- else if (ty =3D=3D MPI_2INT) printf("MPI_2INT\n");
- else if (ty =3D=3D MPI_UB) printf("MPI_UB\n");
- else if (ty =3D=3D MPI_LB) printf("MPI_LB\n");
- else if (ty =3D=3D MPI_WCHAR) printf("MPI_WCHAR\n");
- else if (ty =3D=3D MPI_LONG_LONG_INT) printf("MPI_LONG_LONG_INT\n"=
);
- else if (ty =3D=3D MPI_LONG_LONG) printf("MPI_LONG_LONG\n");
- else if (ty =3D=3D MPI_UNSIGNED_LONG_LONG) printf("MPI_UNSIGNED_LO=
NG_LONG\n");
- else printf("???\n");
- }
- assert(ty !=3D MPI_DATATYPE_NULL);
=20
r =3D MPI_Type_get_envelope( ty, &n_ints, &n_addrs, &n_dtys, &tycon )=
;
assert(r =3D=3D MPI_SUCCESS);
=20
/* Handle the base cases fast(er/ish). */
if (tycon =3D=3D MPI_COMBINER_NAMED) {
- if (ty =3D=3D MPI_DOUBLE) { f(base,sizeof(double)); return; }
- if (ty =3D=3D MPI_INT) { f(base,sizeof(signed int)); return; =
}
- if (ty =3D=3D MPI_CHAR) { f(base,sizeof(signed char)); return;=
}
- if (ty =3D=3D MPI_UNSIGNED) { f(base,sizeof(unsigned int)); return=
; }
- goto unhandled;
+ long sz =3D sizeofNamedTy(ty);
+ if (sz =3D=3D 0)=20
+ goto unhandled;
+ f(base,sz);
+ return;
/*NOTREACHED*/
}
=20
- if (1) {
+ if (0) {
ex =3D extentOfTy(ty);
printf("tycon %p %d %d %d (ext %d)\n",
(void*)tycon, n_ints, n_addrs, n_dtys, (int)ex );
@@ -361,6 +377,7 @@
assert(n_addrs =3D=3D n_ints-1);
assert(n_dtys =3D=3D n_ints-1);
for (i =3D 0; i < ints[0]; i++) {
+ if (0)
printf("struct (elem %d limit %d) off %d copies %d\n",=20
(int)i, (int)ints[0], (int)addrs[i], (int)ints[i+1]);
walk_type_array( f, base + addrs[i], dtys[i], (long)ints[i+1=
] );
@@ -381,8 +398,10 @@
=20
unhandled:
if (tycon =3D=3D MPI_COMBINER_NAMED) {
- fprintf(stderr, "%s %5d: walk_type: unhandled base type 0x%lx\n",
+ fprintf(stderr, "%s %5d: walk_type: unhandled base type 0x%lx ",
preamble, my_pid, (long)ty);
+ showTy(stderr, ty);
+ fprintf(stderr, "\n");
} else {
fprintf(stderr, "%s %5d: walk_type: unhandled combiner 0x%lx\n",
preamble, my_pid, (long)tycon);
@@ -400,9 +419,32 @@
MPI_Datatype elemTy, long count )
{
long i, ex;
- ex =3D extentOfTy(elemTy);
- for (i =3D 0; i < count; i++)
- walk_type( f, base + i * ex, elemTy );
+
+ assert(sizeof(unsigned long) =3D=3D sizeof(char*));
+
+ /* First see if we can do this the fast way. */
+ ex =3D sizeofNamedTy(elemTy);
+
+ 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)
+ && /* base is suitably aligned for ty */
+ ( ((unsigned long)base) & (ex-1)) =3D=3D 0) {
+
+ /* We're sure it's contiguous, so just paint/check it in one
+ go. */
+ if (0) printf("walk_type_array fast %ld of size %ld\n", count, ex )=
;
+ f ( base, count * ex );
+
+ } else {
+
+ /* Bad news. We have to futz with each element individually.
+ This could be very expensive. */
+ 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++)
+ walk_type( f, base + i * ex, elemTy );
+
+ }
}
=20
=20
@@ -1393,7 +1435,7 @@
UNIMPLEMENTED_WRAPPER(Type_create_darray)
UNIMPLEMENTED_WRAPPER(Type_create_subarray)
NO_OP_WRAPPER(Type_extent)
-UNIMPLEMENTED_WRAPPER(Type_free)
+NO_OP_WRAPPER(Type_free)
NO_OP_WRAPPER(Type_get_contents)
NO_OP_WRAPPER(Type_get_envelope)
UNIMPLEMENTED_WRAPPER(Type_get_name)
|