1 /*
2    (C) 2004 by Argonne National Laboratory.
3        See COPYRIGHT in top-level directory.
4 */
5 #include "collchk.h"
6 
7 
8 static const char* CollChk_get_op_string(MPI_Op op);
CollChk_get_op_string(MPI_Op op)9 static const char* CollChk_get_op_string(MPI_Op op)
10 {
11     if ( op == MPI_MAX )
12         return "MPI_MAX";
13     else if ( op == MPI_MIN )
14         return "MPI_MIN";
15     else if ( op == MPI_SUM )
16         return "MPI_SUM";
17     else if ( op == MPI_PROD )
18         return "MPI_PROD";
19     else if ( op == MPI_LAND )
20         return "MPI_LAND";
21     else if ( op == MPI_BAND )
22         return "MPI_BAND";
23     else if ( op == MPI_LOR )
24         return "MPI_LOR";
25     else if ( op == MPI_BOR )
26         return "MPI_BOR";
27     else if ( op == MPI_LXOR )
28         return "MPI_LXOR";
29     else if ( op == MPI_BXOR )
30         return "MPI_BXOR";
31     else if ( op == MPI_MAXLOC )
32         return "MPI_MAXLOC";
33     else if ( op == MPI_MINLOC )
34         return "MPI_MINLOC";
35     else
36         return "USER_OP\0";
37 }
38 
39 
CollChk_same_op(MPI_Comm comm,MPI_Op op,char * call)40 int CollChk_same_op(MPI_Comm comm, MPI_Op op, char* call)
41 {
42     int r, s, i, go, ok;    /* rank, size, counter, go flag, ok flag */
43     char buff[COLLCHK_SM_STRLEN];          /* temp communication buffer */
44     char op_str[15];        /* the operation name in string format */
45     char err_str[COLLCHK_STD_STRLEN];      /* error string */
46     int tag=0;              /* needed for communication */
47     MPI_Status st;
48 
49     /* get rank and size */
50     MPI_Comm_rank(comm, &r);
51     MPI_Comm_size(comm, &s);
52 
53     sprintf(err_str, COLLCHK_NO_ERROR_STR);
54     sprintf(op_str, "%s", CollChk_get_op_string(op));
55 
56     if (r == 0) {
57         /* send the name of the op to the other processes */
58         strcpy(buff, op_str);
59         PMPI_Bcast(buff, 15, MPI_CHAR, 0, comm);
60         /* ask the other processes if they are ok to continue */
61         go = 1;     /* sets the go flag */
62         for(i=1; i<s; i++) {
63             MPI_Recv(&ok, 1, MPI_INT, i, tag, comm, &st);
64             /* if a process has made a bad call unset the go flag */
65             if (ok != 1)
66                go = 0;
67         }
68 
69         /* broadcast to the go flag */
70         PMPI_Bcast(&go, 1, MPI_INT, 0, comm);
71     }
72     else {
73         /* recieve 0's op name */
74         PMPI_Bcast(buff, 15, MPI_CHAR, 0, comm);
75         /* check it against the local op name */
76         if (strcmp(buff, op_str) != 0) {
77             /* at this point the op is not consistant */
78             /* print an error message and send a unset ok flag to 0 */
79             ok = 0;
80             sprintf(err_str, "Inconsistent operation (%s) to "
81                              "Rank 0's operation(%s).", op_str, buff);
82             MPI_Send(&ok, 1, MPI_INT, 0, tag, comm);
83         }
84         else {
85             /* at this point the op is consistant */
86             /* send an set ok flag to 0 */
87             ok = 1;
88             MPI_Send(&ok, 1, MPI_INT, 0, tag, comm);
89         }
90         /* get the go flag from 0 */
91         PMPI_Bcast(&go, 1, MPI_INT, 0, comm);
92     }
93     /* if the go flag is not set exit else return */
94     if (go != 1) {
95         return CollChk_err_han(err_str, COLLCHK_ERR_OP, call, comm);
96     }
97 
98     return MPI_SUCCESS;
99 }
100