Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'add_missing_comm_python_bindings' into 'master'
[simgrid.git] / teshsuite / smpi / MBI / CollArgGenerator.py
1 #! /usr/bin/python3
2 import os
3 import sys
4 import generator_utils as gen
5
6 template = """// @{generatedby}@
7 /* ///////////////////////// The MPI Bugs Initiative ////////////////////////
8
9   Origin: MBI
10
11   Description: @{shortdesc}@
12     @{longdesc}@
13
14   Version of MPI: Conforms to MPI 1.1, does not require MPI 2 implementation
15
16 BEGIN_MPI_FEATURES
17   P2P!basic: Lacking
18   P2P!nonblocking: Lacking
19   P2P!persistent: Lacking
20   COLL!basic: @{collfeature}@
21   COLL!nonblocking: @{icollfeature}@
22   COLL!persistent: Lacking
23   COLL!tools: @{toolfeature}@
24   RMA: Lacking
25 END_MPI_FEATURES
26
27 BEGIN_MBI_TESTS
28   $ mpirun -np 2 ${EXE}
29   | @{outcome}@
30   | @{errormsg}@
31 END_MBI_TESTS
32 //////////////////////       End of MBI headers        /////////////////// */
33
34 #include <mpi.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37
38 #define buff_size 128
39
40 int main(int argc, char **argv) {
41   int nprocs = -1;
42   int rank = -1;
43   int root = 0;
44   int size = 1;
45   int j = 0;
46
47   MPI_Init(&argc, &argv);
48   MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
49   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
50   printf("Hello from rank %d \\n", rank);
51
52   if (nprocs < 2)
53     printf("MBI ERROR: This test needs at least 2 processes to produce a bug!\\n");
54
55   MPI_Comm newcom = MPI_COMM_WORLD;
56   MPI_Op op = MPI_SUM;
57   MPI_Datatype type = MPI_INT;
58
59   int dbs = sizeof(int)*nprocs; /* Size of the dynamic buffers for alltoall and friends */
60
61   @{init}@
62   @{start}@
63
64   @{change_arg}@
65   @{operation}@ /* MBIERROR2 */
66   @{fini}@
67   @{free}@
68
69   MPI_Finalize();
70   printf("Rank %d finished normally\\n", rank);
71   return 0;
72 }
73 """
74
75 #####################################################
76 # Generate code with color mismatch in MPI_Comm_split
77 #####################################################
78
79 for c in gen.tcoll4color:
80     patterns = {}
81     patterns = {'c': c}
82     patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.'
83     patterns['collfeature'] = 'Lacking'
84     patterns['icollfeature'] = 'Lacking'
85     patterns['toolfeature'] = 'Yes' if c in gen.tcoll4color else 'Lacking'
86     patterns['c'] = c
87     patterns['init'] = gen.init[c]("1")
88     patterns['start'] = gen.start[c]("1")
89     patterns['operation'] = gen.operation[c]("1")
90     patterns['fini'] = gen.fini[c]("1")
91     patterns['free'] = gen.free[c]("1")
92     patterns['change_arg'] = ''
93
94     # Generate the code with invalid color
95     replace = patterns.copy()
96     replace['shortdesc'] = 'Invalid color in @{c}@'
97     replace['longdesc'] = 'invalid color in @{c}@'
98     replace['outcome'] = 'ERROR: InvalidOtherArg'
99     replace['errormsg'] = 'Invalid Argument in collective. @{c}@ at line @{line:MBIERROR2}@ has an invalid color'
100     replace['change_arg'] = 'color=-10; /* MBIERROR1*/'
101     gen.make_file(template, f'InvalidParam_OtherArg_{c}_nok.c', replace)
102
103
104 ##################################
105 # Generate code with root mismatch
106 ##################################
107
108 for c in gen.coll4root + gen.icoll4root:
109     patterns = {}
110     patterns = {'c': c}
111     patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.'
112     patterns['collfeature'] = 'Yes' if c in gen.coll4root else 'Lacking'
113     patterns['icollfeature'] = 'Yes' if c in gen.icoll4root else 'Lacking'
114     patterns['toolfeature'] = 'Lacking'
115     patterns['c'] = c
116     patterns['init'] = gen.init[c]("1")
117     patterns['start'] = gen.start[c]("1")
118     patterns['fini'] = gen.fini[c]("1")
119     patterns['free'] = gen.free[c]("1")
120     patterns['operation'] = gen.operation[c]("1")
121     patterns['change_arg'] = ''
122
123     # Generate an incorrect root matching (root mismatch)
124     replace = patterns.copy()
125     replace['shortdesc'] = 'Collective @{c}@ with a root mismatch'
126     replace['longdesc'] = 'Odd ranks use 0 as a root while even ranks use 1 as a root'
127     replace['outcome'] = 'ERROR: RootMatching'
128     replace['errormsg'] = 'Collective root mistmatch. @{c}@ at @{filename}@:@{line:MBIERROR2}@ has 0 or 1 as a root.'
129     replace['change_arg'] = 'if (rank % 2)\n    root = 1; /* MBIERROR1 */'
130     gen.make_file(template, f'ParamMatching_Root_{c}_nok.c', replace)
131
132     # Generate the call with root=-1 (invalid root)
133     replace = patterns.copy()
134     replace['shortdesc'] = f'Collective {c} with root = -1'
135     replace['longdesc'] = f'Collective {c} with root = -1'
136     replace['outcome'] = 'ERROR: InvalidRoot'
137     replace['errormsg'] = 'Invalid collective root.  @{c}@ at @{filename}@:@{line:MBIERROR2}@ has -1 as a root while communicator MPI_COMM_WORLD requires ranks in range 0 to 1.'
138     replace['change_arg'] = 'root = -1; /* MBIERROR1 */'
139     gen.make_file(template, f'InvalidParam_RootNeg_{c}_nok.c', replace)
140
141     # Generate the call with root=2 (root not in communicator)
142     replace = patterns.copy()
143     replace['shortdesc'] = f'Collective {c} with root out of the communicator'
144     replace['longdesc'] = f'Collective {c} with root = 2 (there is only 2 ranks)'
145     replace['outcome'] = 'ERROR: InvalidRoot'
146     replace['errormsg'] = 'Invalid collective root.  @{c}@ at @{filename}@:@{line:MBIERROR2}@ has 2 as a root while communicator MPI_COMM_WORLD requires ranks in range 0 to 1.'
147     replace['change_arg'] = 'root = nprocs; /* MBIERROR1 */'
148     gen.make_file(template, f'InvalidParam_RootTooLarge_{c}_nok.c', replace)
149
150
151 ##################################
152 # Generate code with type mismatch
153 ##################################
154
155 for c in gen.coll + gen.icoll:
156     if c != 'MPI_Barrier': # Barrier has no Data to mismatch or to nullify
157         patterns = {}
158         patterns = {'c': c}
159         patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.'
160         patterns['collfeature'] = 'Yes' if c in gen.coll else 'Lacking'
161         patterns['icollfeature'] = 'Yes' if c in gen.icoll + gen.ibarrier else 'Lacking'
162         patterns['toolfeature'] = 'Lacking'
163         patterns['c'] = c
164         patterns['init'] = gen.init[c]("1")
165         patterns['start'] = gen.start[c]("1")
166         patterns['fini'] = gen.fini[c]("1")
167         patterns['operation'] = gen.operation[c]("1")
168         patterns['free'] = gen.free[c]("1")
169         patterns['change_arg'] = ''
170
171         # Generate the incorrect matching (datatype Mmismatch)
172         replace = patterns.copy()
173         replace['shortdesc'] = 'Collective @{c}@ with a datatype mismatch'
174         replace['longdesc'] = 'Odd ranks use MPI_INT as the datatype while even ranks use MPI_FLOAT'
175         replace['outcome'] = 'ERROR: DatatypeMatching'
176         replace['errormsg'] = 'Collective datatype mistmatch. @{c}@ at @{filename}@:@{line:MBIERROR2}@ has MPI_INT or MPI_FLOAT as a datatype.'
177         replace['change_arg'] = 'if (rank % 2)\n    type = MPI_FLOAT; /* MBIERROR1 */'
178         gen.make_file(template, f'ParamMatching_Data_{c}_nok.c', replace)
179
180         # Generate the call with null type (invalid datatype)
181         replace = patterns.copy()
182         replace['shortdesc'] = 'Collective @{c}@ with an invalid datatype '
183         replace['longdesc'] = 'Collective @{c}@ with an invalid datatype '
184         replace['outcome'] = 'ERROR: InvalidDatatype'
185         replace['errormsg'] = 'Invalid Datatype. @{c}@ at @{filename}@:@{line:MBIERROR2}@ has an invalid datatype.'
186         replace['change_arg'] = 'type=MPI_DATATYPE_NULL; /* MBIERROR1 */'
187         gen.make_file(template, f'InvalidParam_DataNull_{c}_nok.c', replace)
188
189
190 ##################################
191 # Generate code with Op  mismatch
192 ##################################
193
194 for c in gen.coll4op + gen.icoll4op:
195     patterns = {}
196     patterns = {'c': c}
197     patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.'
198     patterns['collfeature'] = 'Yes' if c in  gen.coll4op else 'Lacking'
199     patterns['icollfeature'] = 'Yes' if c in gen.icoll4op else 'Lacking'
200     patterns['toolfeature'] = 'Lacking'
201     patterns['c'] = c
202     patterns['init'] = gen.init[c]("1")
203     patterns['start'] = gen.start[c]("1")
204     patterns['fini'] = gen.fini[c]("1")
205     patterns['operation'] = gen.operation[c]("1")
206     patterns['free'] = gen.free[c]("1")
207     patterns['change_arg'] = ''
208
209     # Generate the incorrect matching (op mismatch)
210     replace = patterns.copy()
211     replace['shortdesc'] = 'Collective @{c}@ with an operator  mismatch'
212     replace['longdesc'] = 'Odd ranks use MPI_SUM as the operator while even ranks use MPI_MAX'
213     replace['outcome'] = 'ERROR: OperatorMatching'
214     replace['errormsg'] = 'Collective operator mistmatch. @{c}@ at @{filename}@:@{line:MBIERROR2}@ has MPI_MAX or MPI_SUM as an operator.'
215     replace['change_arg'] = 'if (rank % 2)\n    op = MPI_MAX; /* MBIERROR1 */'
216     gen.make_file(template, f'ParamMatching_Op_{c}_nok.c', replace)
217
218     # Generate the call with Op=MPI_OP_NULL (invalid op)
219     replace = patterns.copy()
220     replace['shortdesc'] = 'Collective @{c}@ with an invalid operator '
221     replace['longdesc'] = 'Collective @{c}@ with an invalid operator '
222     replace['outcome'] = 'ERROR: InvalidOperator'
223     replace['errormsg'] = 'Invalid Operator. @{c}@ at @{filename}@:@{line:MBIERROR2}@ has MPI_OP_NULL as an operator.'
224     replace['change_arg'] = 'op = MPI_OP_NULL; /* MBIERROR1 */'
225     gen.make_file(template, f'InvalidParam_OpNull_{c}_nok.c', replace)