3 # Copyright 2021-2022. The MBI project. All rights reserved.
4 # This program is free software; you can redistribute it and/or modify it under the terms of the license (GNU GPL).
8 import generator_utils as gen
10 template = """// @{generatedby}@
11 /* ///////////////////////// The MPI Bugs Initiative ////////////////////////
15 Description: @{shortdesc}@
18 Version of MPI: Conforms to MPI 1.1, does not require MPI 2 implementation
22 P2P!nonblocking: Lacking
23 P2P!persistent: Lacking
24 COLL!basic: @{collfeature}@
25 COLL!nonblocking: @{icollfeature}@
26 COLL!persistent: Lacking
36 ////////////////////// End of MBI headers /////////////////// */
44 int main(int argc, char **argv) {
49 MPI_Init(&argc, &argv);
50 MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
51 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
52 printf("Hello from rank %d \\n", rank);
55 printf("MBI ERROR: This test needs at least 2 processes to produce a bug.\\n");
57 MPI_Comm newcom = MPI_COMM_WORLD;
58 MPI_Datatype type = MPI_INT;
61 int dbs = sizeof(int)*nprocs; /* Size of the dynamic buffers for alltoall and friends */
65 if (@{change_cond}@) {
66 @{operation1a}@ /* MBIERROR1 */
71 @{operation1b}@ /* MBIERROR2 */
81 printf("Rank %d finished normally\\n", rank);
86 for c1 in gen.coll + gen.icoll + gen.ibarrier:
87 for c2 in gen.coll + gen.icoll + gen.ibarrier:
89 patterns = {'c1': c1, 'c2': c2}
90 patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.'
91 patterns['collfeature'] = 'Yes' if c1 in gen.coll or c2 in gen.coll else 'Lacking'
92 patterns['icollfeature'] = 'Yes' if c1 in gen.icoll + gen.ibarrier or c2 in gen.icoll + gen.ibarrier else 'Lacking'
95 patterns['init1'] = gen.init[c1]("1")
96 patterns['init2'] = gen.init[c2]("2")
97 patterns['fini1a'] = gen.fini[c1]("1")
98 patterns['fini2a'] = gen.fini[c2]("2")
99 patterns['fini1b'] = gen.fini[c1]("1")
100 patterns['fini2b'] = gen.fini[c2]("2")
101 patterns['free1'] = gen.free[c1]("1")
102 patterns['free2'] = gen.free[c2]("2")
103 patterns['operation1a'] = gen.operation[c1]("1")
104 patterns['operation1b'] = gen.operation[c1]("1")
105 patterns['operation2a'] = gen.operation[c2]("2")
106 patterns['operation2b'] = gen.operation[c2]("2")
107 patterns['change_cond'] = 'rank % 2'
108 shortdesc = ' collective ordering'
111 # Generate the correct code using the same collective twice
112 replace = patterns.copy()
113 replace['shortdesc'] = 'Correct' + shortdesc
114 replace['longdesc'] = f'All ranks call {c1} twice'
115 replace['outcome'] = 'OK'
116 replace['errormsg'] = ''
117 replace['change_cond'] = 'rank < nprocs'
118 replace['operation1b'] = ''
119 replace['operation2b'] = ''
120 replace['fini1b'] = ''
121 replace['fini2b'] = ''
122 gen.make_file(template, f'CallOrdering_{c1}_{c2}_ok.c', replace)
123 # Generate the correct code using the collective once
124 replace = patterns.copy()
125 replace['shortdesc'] = 'Correct' + shortdesc
126 replace['longdesc'] = f'All ranks call {c1} once'
127 replace['outcome'] = 'OK'
128 replace['errormsg'] = ''
129 replace['init2'] = ''
130 replace['change_cond'] = 'rank < nprocs'
131 replace['operation2a'] = ''
132 replace['operation1b'] = ''
133 replace['operation2b'] = ''
134 replace['fini2a'] = ''
135 replace['fini1b'] = ''
136 replace['fini2b'] = ''
137 replace['free2'] = ''
138 gen.make_file(template, f'CallOrdering_{c1}_ok.c', replace)
140 # Generate the correct ordering with two different collectives
141 replace = patterns.copy()
142 replace['shortdesc'] = 'Correct' + shortdesc
143 replace['longdesc'] = f'All ranks call {c1} and then {c2}'
144 replace['outcome'] = 'OK'
145 replace['errormsg'] = ''
146 replace['change_cond'] = 'rank < nprocs'
147 replace['operation1b'] = ''
148 replace['operation2b'] = ''
149 replace['fini1b'] = ''
150 replace['fini2b'] = ''
151 gen.make_file(template, f'CallOrdering_{c1}_{c2}_ok.c', replace)
152 # Generate the incorrect ordering with two different collectives
153 replace = patterns.copy()
154 replace['shortdesc'] = 'Incorrect' + shortdesc
155 replace['longdesc'] = f'Odd ranks call {c1} and then {c2} while even ranks call these collectives in the other order'
156 replace['outcome'] = 'ERROR: CallMatching'
157 replace['errormsg'] = 'Collective mistmatch. @{c1}@ at @{filename}@:@{line:MBIERROR1}@ is matched with @{c2}@ line @{filename}@:@{line:MBIERROR2}@.'
158 replace['operation1b'] = gen.operation[c2]("2") # Inversion
159 replace['operation2b'] = gen.operation[c1]("1")
160 replace['fini1a'] = gen.fini[c1]("1") # Inversion
161 replace['fini2a'] = gen.fini[c2]("2")
162 replace['fini1b'] = gen.fini[c2]("2") # Inversion
163 replace['fini2b'] = gen.fini[c1]("1")
164 replace['free1'] = gen.free[c2]("2")
165 replace['free2'] = gen.free[c1]("1")
167 gen.make_file(template, f'CallOrdering_{c1}_{c2}_nok.c', replace)
169 # Generate the incorrect ordering with one collective
170 replace = patterns.copy()
171 replace['shortdesc'] = 'Incorrect' + shortdesc
172 replace['longdesc'] = f'Odd ranks call {c1} while even ranks do not call any collective'
173 replace['outcome'] = 'ERROR: CallMatching'
174 replace['errormsg'] = 'Collective mistmatch. @{c1}@ at @{filename}@:@{line:MBIERROR1}@ is not matched.'
175 replace['operation1b'] = '' # Remove functions
176 replace['operation2b'] = ''
177 replace['operation2a'] = ''
178 replace['init2'] = ''
179 replace['fini1b'] = ''
180 replace['fini2a'] = ''
181 replace['fini2b'] = ''
182 replace['free1'] = gen.free[c1]("1")
183 replace['free2'] = ''
184 gen.make_file(template, f'CallOrdering_{c1}_none_nok.c', replace)
185 # Generate a correct ordering with a conditional not depending on ranks
186 replace = patterns.copy()
187 replace['shortdesc'] = 'Correct' + shortdesc
188 replace['longdesc'] = f'All ranks call {c1}'
189 replace['outcome'] = 'OK'
190 replace['errormsg'] = ''
191 replace['change_cond'] = 'rank < nprocs'
192 replace['operation1b'] = '' # Remove functions
193 replace['operation2b'] = ''
194 replace['operation2a'] = ''
195 replace['init2'] = ''
196 replace['fini1b'] = ''
197 replace['fini2a'] = ''
198 replace['fini2b'] = ''
199 replace['free1'] = gen.free[c1]("1")
200 replace['free2'] = ''
201 gen.make_file(template, f'CallOrdering_{c1}_none_ok.c', replace)