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