1 /* -*- Mode: C; c-basic-offset:4 ; -*- */
2 /*
3  *   Copyright (C) 1997 University of Chicago.
4  *   See COPYRIGHT notice in top-level directory.
5  */
6 
7 #include "adio.h"
8 /* #ifdef MPISGI
9 #include "mpisgi2.h"
10 #endif */
11 
12 #if (defined(MPICH) || defined(MPICH2))
13 /* MPICH2 also provides this routine */
14 void MPIR_Datatype_iscontig(MPI_Datatype datatype, int *flag);
15 
ADIOI_Datatype_iscontig(MPI_Datatype datatype,int * flag)16 void ADIOI_Datatype_iscontig(MPI_Datatype datatype, int *flag)
17 {
18     MPIR_Datatype_iscontig(datatype, flag);
19 
20     /* if it is MPICH2 and the datatype is reported as contigous,
21        check if the true_lb is non-zero, and if so, mark the
22        datatype as noncontiguous */
23 #ifdef MPICH2
24     if (*flag) {
25         MPI_Aint true_extent, true_lb;
26 
27         MPI_Type_get_true_extent(datatype, &true_lb, &true_extent);
28 
29         if (true_lb > 0)
30             *flag = 0;
31     }
32 #endif
33 }
34 
35 #elif (defined(MPIHP) && defined(HAVE_MPI_INFO))
36 /* i.e. HPMPI 1.4 only */
37 
38 int hpmp_dtiscontig(MPI_Datatype datatype);
39 
ADIOI_Datatype_iscontig(MPI_Datatype datatype,int * flag)40 void ADIOI_Datatype_iscontig(MPI_Datatype datatype, int *flag)
41 {
42     *flag = hpmp_dtiscontig(datatype);
43 }
44 
45 #elif (defined(MPISGI) && !defined(NO_MPI_SGI_type_is_contig))
46 
47 int MPI_SGI_type_is_contig(MPI_Datatype datatype);
48 
ADIOI_Datatype_iscontig(MPI_Datatype datatype,int * flag)49 void ADIOI_Datatype_iscontig(MPI_Datatype datatype, int *flag)
50 {
51     MPI_Aint displacement;
52     MPI_Type_lb(datatype, &distplacement);
53 
54     /* SGI's MPI_SGI_type_is_contig() returns true for indexed
55      * datatypes with holes at the beginning, which causes
56      * problems with ROMIO's use of this function.
57      */
58     *flag = MPI_SGI_type_is_contig(datatype) && (displacement == 0);
59 }
60 
61 #elif defined(OMPI_BUILDING) && OMPI_BUILDING
62 
63 /* void ADIOI_Datatype_iscontig(MPI_Datatype datatype, int *flag) is defined
64  * and implemented in OpenMPI itself */
65 
66 #else
67 
ADIOI_Datatype_iscontig(MPI_Datatype datatype,int * flag)68 void ADIOI_Datatype_iscontig(MPI_Datatype datatype, int *flag)
69 {
70     int nints, nadds, ntypes, combiner;
71     int *ints, ni, na, nt, cb;
72     MPI_Aint *adds;
73     MPI_Datatype *types;
74 
75     MPI_Type_get_envelope(datatype, &nints, &nadds, &ntypes, &combiner);
76 
77     switch (combiner) {
78     case MPI_COMBINER_NAMED:
79 	*flag = 1;
80 	break;
81     case MPI_COMBINER_CONTIGUOUS:
82 	ints = (int *) ADIOI_Malloc((nints+1)*sizeof(int));
83 	adds = (MPI_Aint *) ADIOI_Malloc((nadds+1)*sizeof(MPI_Aint));
84 	types = (MPI_Datatype *) ADIOI_Malloc((ntypes+1)*sizeof(MPI_Datatype));
85 	MPI_Type_get_contents(datatype, nints, nadds, ntypes, ints,
86 			      adds, types);
87 	ADIOI_Datatype_iscontig(types[0], flag);
88 
89 #ifndef MPISGI
90 /* There is a bug in SGI's impl. of MPI_Type_get_contents. It doesn't
91    return new datatypes. Therefore no need to free. */
92 	MPI_Type_get_envelope(types[0], &ni, &na, &nt, &cb);
93 	if (cb != MPI_COMBINER_NAMED) MPI_Type_free(types);
94 #endif
95 
96 	ADIOI_Free(ints);
97 	ADIOI_Free(adds);
98 	ADIOI_Free(types);
99 	break;
100     default:
101 	*flag = 0;
102 	break;
103     }
104 
105     /* This function needs more work. It should check for contiguity
106        in other cases as well.*/
107 }
108 #endif
109