This source file includes following definitions.
- ompitest_warning
- ompitest_error
- main
- spawn_and_merge
- do_parent
- do_target
1 #define _GNU_SOURCE
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <stdarg.h>
6 #include <unistd.h>
7
8 #include <mpi.h>
9
10 #define NB_SPAWN 4
11
12 static void do_parent(char *argv[], int rank, int count);
13 static void do_target(char* argv[], MPI_Comm parent);
14
15 static char *cmd_argv1 = "b";
16 static char *cmd_argv2 = "c";
17 static char *whoami = "a";
18 static int tag = 201;
19
20 void ompitest_warning( char* filename, int lineno, const char* fmt, ... )
21 {
22 char* buf = NULL;
23 va_list va_list;
24
25 va_start(va_list, fmt);
26 opal_vasprintf( &buf, fmt, va_list );
27 va_end(va_list);
28 printf( "*warning* %s:%d %s\n", filename, lineno, buf );
29 free(buf);
30 }
31
32 void ompitest_error( char* filename, int lineno, const char* fmt, ... )
33 {
34 char* buf = NULL;
35 va_list va_list;
36
37 va_start(va_list, fmt);
38 opal_vasprintf( &buf, fmt, va_list );
39 va_end(va_list);
40 printf( "*error* %s:%d %s\n", filename, lineno, buf );
41 free(buf);
42 }
43
44 int
45 main(int argc, char *argv[])
46 {
47 int rank, size;
48 MPI_Comm parent;
49
50 MPI_Init(&argc, &argv);
51 MPI_Comm_size(MPI_COMM_WORLD, &size);
52 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
53
54
55
56
57
58 parent = MPI_COMM_NULL;
59 MPI_Comm_get_parent(&parent);
60 if (parent != MPI_COMM_NULL) {
61 whoami = argv[1];
62 do_target(argv, parent);
63 } else {
64 do_parent(argv, rank, size);
65 }
66
67
68 MPI_Finalize();
69 return 0;
70 }
71
72 static int
73 spawn_and_merge( char* argv[], char* arg, int count,
74 MPI_Comm* inter, MPI_Comm* intra )
75 {
76 int *errcode, err, i;
77 char *spawn_argv[2];
78
79 errcode = malloc(sizeof(int) * count);
80 if (errcode == NULL)
81 ompitest_error(__FILE__, __LINE__, "Doh! Rank %d was not able to allocate enough memory. MPI test aborted!\n", 0);
82 memset(errcode, -1, count);
83
84
85 spawn_argv[0] = arg;
86 spawn_argv[1] = NULL;
87 err = MPI_Comm_spawn(argv[0], spawn_argv, count, MPI_INFO_NULL, 0,
88 MPI_COMM_WORLD, inter, errcode);
89 for (i = 0; i < count; i++)
90 if (errcode[i] != MPI_SUCCESS)
91 ompitest_error(__FILE__, __LINE__,
92 "ERROR: MPI_Comm_spawn returned errcode[%d] = %d\n",
93 i, errcode[i]);
94 if (err != MPI_SUCCESS)
95 ompitest_error(__FILE__, __LINE__,
96 "ERROR: MPI_Comm_spawn returned errcode = %d\n", err);
97 err = MPI_Intercomm_merge( *inter, 0, intra );
98 free(errcode);
99 return err;
100 }
101
102 static void
103 do_parent(char *argv[], int rank, int count)
104 {
105 MPI_Comm ab_inter, ab_intra, ac_inter, ac_intra, ab_c_inter, abc_intra;
106 int err;
107
108 err = spawn_and_merge( argv, cmd_argv1, count, &ab_inter, &ab_intra );
109 err = spawn_and_merge( argv, cmd_argv2, count, &ac_inter, &ac_intra );
110
111 printf( "%s: MPI_Intercomm_create( ab_intra, 0, ac_intra, %d, %d, &inter) (%d)\n",
112 whoami, count, tag, err );
113 err = MPI_Intercomm_create( ab_intra, 0, ac_intra, count, tag, &ab_c_inter );
114 printf( "%s: intercomm_create (%d)\n", whoami, err );
115
116 printf( "%s: barrier on inter-comm - before\n", whoami );
117 err = MPI_Barrier(ab_c_inter);
118 printf( "%s: barrier on inter-comm - after\n", whoami );
119
120 err = MPI_Intercomm_merge(ab_c_inter, 0, &abc_intra);
121 printf( "%s: intercomm_merge(%d) (%d) [rank %d]\n", whoami, 0, err, rank );
122 err = MPI_Barrier(abc_intra);
123 printf( "%s: barrier (%d)\n", whoami, err );
124
125 MPI_Comm_free(&abc_intra);
126 MPI_Comm_free(&ab_c_inter);
127 MPI_Comm_free(&ab_intra);
128 MPI_Comm_free(&ac_intra);
129
130 MPI_Comm_disconnect(&ab_inter);
131 MPI_Comm_disconnect(&ac_inter);
132 }
133
134
135 static void
136 do_target(char* argv[], MPI_Comm parent)
137 {
138 int rank, first = 0, err;
139 MPI_Comm intra, inter, merge1;
140
141 if( 0 == strcmp(argv[1], cmd_argv1) ) first = 1;
142
143
144
145 err = MPI_Intercomm_merge( parent, 1, &intra );
146 MPI_Comm_rank(intra, &rank);
147
148 if( first ) {
149 printf( "%s: MPI_Intercomm_create( intra, 0, intra, MPI_COMM_NULL, %d, &inter) [rank %d]\n", whoami, tag, rank );
150 err = MPI_Intercomm_create( intra, 0, MPI_COMM_NULL, 0, tag, &inter);
151 printf( "%s: intercomm_create (%d)\n", whoami, err );
152 } else {
153 printf( "%s: MPI_Intercomm_create( MPI_COMM_WORLD, 0, intra, 0, %d, &inter) [rank %d]\n", whoami, tag, rank );
154 err = MPI_Intercomm_create( MPI_COMM_WORLD, 0, intra, 0, tag, &inter);
155 printf( "%s: intercomm_create (%d)\n", whoami, err );
156 }
157 printf( "%s: barrier on inter-comm - before\n", whoami );
158 err = MPI_Barrier(inter);
159 printf( "%s: barrier on inter-comm - after\n", whoami );
160
161 err = MPI_Intercomm_merge( inter, 0, &merge1 );
162 MPI_Comm_rank(merge1, &rank);
163 printf( "%s: intercomm_merge(%d) (%d) [rank %d]\n", whoami, first, err, rank );
164 err = MPI_Barrier(merge1);
165 printf( "%s: barrier (%d)\n", whoami, err );
166
167 MPI_Comm_free(&merge1);
168 MPI_Comm_free(&inter);
169 MPI_Comm_free(&intra);
170
171 MPI_Comm_disconnect(&parent);
172 }