1 /*
2  * Copyright (C) by Argonne National Laboratory
3  *     See COPYRIGHT in top-level directory
4  */
5 
6 #include "mpi.h"
7 #include "mpitestconf.h"
8 #ifdef HAVE_IOSTREAM
9 // Not all C++ compilers have iostream instead of iostream.h
10 #include <iostream>
11 #ifdef HAVE_NAMESPACE_STD
12 // Those that do often need the std namespace; otherwise, a bare "cout"
13 // is likely to fail to compile
14 using namespace std;
15 #endif
16 #else
17 #include <iostream.h>
18 #endif
19 #include <stdio.h>
20 #include "mpitestcxx.h"
21 #ifdef HAVE_STRING_H
22 #include <string.h>
23 #endif
24 
25 static char MTEST_Descrip[] = "Test comm_call_errhandler";
26 
27 static int calls = 0;
28 static int errs = 0;
29 static MPI::Intracomm mycomm;
eh(MPI::Comm & comm,int * err,...)30 void eh(MPI::Comm & comm, int *err, ...)
31 {
32     if (*err != MPI_ERR_OTHER) {
33         errs++;
34         cout << "Unexpected error code\n";
35     }
36     if (comm != mycomm) {
37         char cname[MPI_MAX_OBJECT_NAME];
38         int len;
39         errs++;
40         cout << "Unexpected communicator\n";
41         comm.Get_name(cname, len);
42         cout << "Comm is " << cname << "\n";
43         mycomm.Get_name(cname, len);
44         cout << "mycomm is " << cname << "\n";
45     }
46     calls++;
47     return;
48 }
49 
main(int argc,char * argv[])50 int main(int argc, char *argv[])
51 {
52     MPI::Intracomm comm;
53     MPI::Errhandler newerr;
54     int i;
55     int reset_handler;
56 
57     MTest_Init();
58 
59     comm = MPI::COMM_WORLD;
60     mycomm = comm;
61     mycomm.Set_name("dup of comm_world");
62 
63     newerr = MPI::Comm::Create_errhandler(eh);
64 
65     comm.Set_errhandler(newerr);
66     comm.Call_errhandler(MPI_ERR_OTHER);
67     newerr.Free();
68     if (calls != 1) {
69         errs++;
70         cout << "Error handler not called\n";
71     }
72     // Here we apply the test to many copies of a communicator
73     for (reset_handler = 0; reset_handler <= 1; ++reset_handler) {
74         for (i = 0; i < 1000; i++) {
75             MPI::Intracomm comm2;
76             calls = 0;
77             comm = MPI::COMM_WORLD.Dup();
78             mycomm = comm;
79             mycomm.Set_name("dup of comm_world");
80             newerr = MPI::Comm::Create_errhandler(eh);
81 
82             comm.Set_errhandler(newerr);
83             comm.Call_errhandler(MPI_ERR_OTHER);
84             if (calls != 1) {
85                 errs++;
86                 cout << "Error handler not called\n";
87             }
88             comm2 = comm.Dup();
89             calls = 0;
90             mycomm = comm2;
91             mycomm.Set_name("dup of dup of comm_world");
92             // comm2 must inherit the error handler from comm
93             comm2.Call_errhandler(MPI_ERR_OTHER);
94             if (calls != 1) {
95                 errs++;
96                 cout << "Error handler not called\n";
97             }
98 
99             if (reset_handler) {
100                 // extra checking of the reference count handling
101                 comm.Set_errhandler(MPI::ERRORS_THROW_EXCEPTIONS);
102             }
103             newerr.Free();
104             comm.Free();
105             comm2.Free();
106         }
107     }
108 
109     MTest_Finalize(errs);
110     return 0;
111 }
112