root/mpich2/trunk/src/mpi/coll/opminloc.c @ 4891

Revision 4891, 4.5 KB (checked in by buntinas, 5 months ago)

squashed float == warnings in opminloc and opmaxloc, and refactored code

Line 
1/* -*- Mode: C; c-basic-offset:4 ; -*- */
2/*
3 *
4 *  (C) 2001 by Argonne National Laboratory.
5 *      See COPYRIGHT in top-level directory.
6 */
7
8#include "mpiimpl.h"
9
10/* MINLOC and MAXLOC structures */
11typedef struct MPIR_2int_loctype {
12  int  value;
13  int  loc;
14} MPIR_2int_loctype;
15
16typedef struct MPIR_floatint_loctype {
17  float  value;
18  int    loc;
19} MPIR_floatint_loctype;
20
21typedef struct MPIR_longint_loctype {
22  long  value;
23  int    loc;
24} MPIR_longint_loctype;
25
26typedef struct MPIR_shortint_loctype {
27  short  value;
28  int    loc;
29} MPIR_shortint_loctype;
30
31typedef struct MPIR_doubleint_loctype {
32  double  value;
33  int     loc;
34} MPIR_doubleint_loctype;
35
36#if defined(HAVE_LONG_DOUBLE)
37typedef struct MPIR_longdoubleint_loctype {
38  long double   value;
39  int           loc;
40} MPIR_longdoubleint_loctype;
41#endif
42
43/* Note a subtlety in these two macros which avoids compiler warnings.
44   The compiler complains about using == on floats, but the standard
45   requires that we set loc to min of the locs if the two values are
46   equal.  So we do "if a>b {} else if a>=b Y" which is the same as
47   "if a>b X else if a==b Y" but avoids the warning. */
48#define MPIR_MINLOC_C_CASE(c_type_) {                   \
49        c_type_ *a = (c_type_ *)inoutvec;               \
50        c_type_ *b = (c_type_ *)invec;                  \
51        for (i=0; i<len; i++) {                         \
52            if (a[i].value > b[i].value) {              \
53                a[i].value = b[i].value;                \
54                a[i].loc   = b[i].loc;                  \
55            } else if (a[i].value >= b[i].value)        \
56                a[i].loc = MPIR_MIN(a[i].loc,b[i].loc); \
57        }                                               \
58    }                                                   \
59    break
60
61#define MPIR_MINLOC_F_CASE(f_type_) {                   \
62        f_type_ *a = (f_type_ *)inoutvec;               \
63        f_type_ *b = (f_type_ *)invec;                  \
64        for ( i=0; i<flen; i+=2 ) {                     \
65            if (a[i] > b[i]) {                          \
66                a[i]   = b[i];                          \
67                a[i+1] = b[i+1];                        \
68            } else if (a[i] >= b[i])                    \
69                a[i+1] = MPIR_MIN(a[i+1],b[i+1]);       \
70        }                                               \
71    }                                                   \
72    break
73
74#undef FUNCNAME
75#define FUNCNAME MPIR_MINLOC
76#undef FCNAME
77#define FCNAME MPIU_QUOTE(FUNCNAME)
78void MPIR_MINLOC( 
79        void *invec, 
80        void *inoutvec, 
81        int *Len, 
82        MPI_Datatype *type )
83{
84    int mpi_errno = MPI_SUCCESS;
85    int i, len = *Len, flen;
86   
87    flen = len * 2; /* used for Fortran types */
88
89    switch (*type) {
90    /* first the C types */
91    case MPI_2INT:       MPIR_MINLOC_C_CASE(MPIR_2int_loctype);       
92    case MPI_FLOAT_INT:  MPIR_MINLOC_C_CASE(MPIR_floatint_loctype);
93    case MPI_LONG_INT:   MPIR_MINLOC_C_CASE(MPIR_longint_loctype);
94    case MPI_SHORT_INT:  MPIR_MINLOC_C_CASE(MPIR_shortint_loctype);
95    case MPI_DOUBLE_INT: MPIR_MINLOC_C_CASE(MPIR_doubleint_loctype);
96#if defined(HAVE_LONG_DOUBLE)
97    case MPI_LONG_DOUBLE_INT: MPIR_MINLOC_C_CASE(MPIR_longdoubleint_loctype);
98#endif
99
100    /* now the Fortran types */
101#ifdef HAVE_FORTRAN_BINDING
102#ifndef HAVE_NO_FORTRAN_MPI_TYPES_IN_C
103    case MPI_2INTEGER:          MPIR_MINLOC_F_CASE(int);
104    case MPI_2REAL:             MPIR_MINLOC_F_CASE(float);
105    case MPI_2DOUBLE_PRECISION: MPIR_MINLOC_F_CASE(double);
106#endif
107#endif
108        /* --BEGIN ERROR HANDLING-- */
109    default: {
110        MPIU_THREADPRIV_DECL;
111        MPIU_THREADPRIV_GET;
112        MPIU_ERR_SET1(mpi_errno, MPI_ERR_OP, "**opundefined","**opundefined %s", "MPI_MINLOC" );
113        MPIU_THREADPRIV_FIELD(op_errno) = mpi_errno;
114        break;
115    }
116        /* --END ERROR HANDLING-- */
117    }
118
119}
120
121
122
123
124#undef FUNCNAME
125#define FUNCNAME MPIR_MINLOC_check_dtype
126#undef FCNAME
127#define FCNAME MPIU_QUOTE(FUNCNAME)
128int MPIR_MINLOC_check_dtype( MPI_Datatype type )
129{
130    int mpi_errno = MPI_SUCCESS;
131   
132    switch (type) {
133    /* first the C types */
134    case MPI_2INT: 
135    case MPI_FLOAT_INT: 
136    case MPI_LONG_INT: 
137    case MPI_SHORT_INT: 
138    case MPI_DOUBLE_INT: 
139#if defined(HAVE_LONG_DOUBLE)
140    case MPI_LONG_DOUBLE_INT: 
141#endif
142   /* now the Fortran types */
143#ifdef HAVE_FORTRAN_BINDING
144#ifndef HAVE_NO_FORTRAN_MPI_TYPES_IN_C
145    case MPI_2INTEGER: 
146    case MPI_2REAL: 
147    case MPI_2DOUBLE_PRECISION: 
148#endif
149#endif
150        break;
151
152    default: MPIU_ERR_SET1(mpi_errno, MPI_ERR_OP, "**opundefined", "**opundefined %s", "MPI_MINLOC");
153    }
154   
155    return mpi_errno;
156}
Note: See TracBrowser for help on using the browser.