Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Import (some bits of) the MBI test suite
[simgrid.git] / teshsuite / smpi / MBI / CollMatchingGenerator.py
1 #! /usr/bin/python3
2 import sys
3 from generator_utils import *
4
5 template = """// @{generatedby}@
6 /* ///////////////////////// The MPI Bugs Initiative ////////////////////////
7
8   Origin: MBI
9
10   Description: @{shortdesc}@
11     @{longdesc}@
12
13          Version of MPI: Conforms to MPI 1.1, does not require MPI 2 implementation
14
15 BEGIN_MPI_FEATURES
16         P2P!basic: Lacking
17         P2P!nonblocking: Lacking
18         P2P!persistent: Lacking
19         COLL!basic: @{collfeature}@
20         COLL!nonblocking: @{icollfeature}@
21         COLL!persistent: Lacking
22         COLL!tools: Lacking
23         RMA: Lacking
24 END_MPI_FEATURES
25
26 BEGIN_MBI_TESTS
27   $ mpirun -np 2 ${EXE}
28   | @{outcome}@
29   | @{errormsg}@
30 END_MBI_TESTS
31 //////////////////////       End of MBI headers        /////////////////// */
32
33 #include <mpi.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36
37 #define buff_size 128
38
39 int main(int argc, char **argv) {
40   int nprocs = -1;
41   int rank = -1;
42         int root = 0;
43
44   MPI_Init(&argc, &argv);
45   MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
46   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
47   printf("Hello from rank %d \\n", rank);
48
49   if (nprocs < 2)
50     printf("MBI ERROR: This test needs at least 2 processes to produce a bug.\\n");
51
52         MPI_Comm newcom = MPI_COMM_WORLD;
53         MPI_Datatype type = MPI_INT;
54   MPI_Op op = MPI_SUM;
55
56   int dbs = sizeof(int)*nprocs; /* Size of the dynamic buffers for alltoall and friends */
57   @{init1}@
58   @{init2}@
59
60   if (@{change_cond}@) {
61     @{operation1a}@ /* MBIERROR1 */
62         @{fini1a}@
63     @{operation2a}@
64         @{fini2a}@
65   } else {
66     @{operation1b}@ /* MBIERROR2 */
67         @{fini1b}@
68     @{operation2b}@
69         @{fini2b}@
70   }
71
72   @{free1}@
73   @{free2}@
74   
75   MPI_Finalize();
76   printf("Rank %d finished normally\\n", rank);
77   return 0;
78 }
79 """
80
81 for c1 in coll + icoll + ibarrier:
82     for c2 in coll + icoll + ibarrier:
83         patterns = {}
84         patterns = {'c1': c1, 'c2': c2}
85         patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {sys.argv[0]}. DO NOT EDIT.'
86         patterns['collfeature'] = 'Yes' if c1 in coll or c2 in coll else 'Lacking'
87         patterns['icollfeature'] = 'Yes' if c1 in icoll + ibarrier or c2 in icoll + ibarrier else 'Lacking'
88         patterns['c1'] = c1
89         patterns['c2'] = c2
90         patterns['init1'] = init[c1]("1")
91         patterns['init2'] = init[c2]("2")
92         patterns['fini1a'] = fini[c1]("1")
93         patterns['fini2a'] = fini[c2]("2")
94         patterns['fini1b'] = fini[c1]("1")
95         patterns['fini2b'] = fini[c2]("2")
96         patterns['free1'] = free[c1]("1")
97         patterns['free2'] = free[c2]("2")
98         patterns['operation1a'] = operation[c1]("1")
99         patterns['operation1b'] = operation[c1]("1")
100         patterns['operation2a'] = operation[c2]("2")
101         patterns['operation2b'] = operation[c2]("2")
102         patterns['change_cond'] = 'rank % 2'
103
104         if c1 == c2:
105             # Generate the correct code using the same collective twice
106             replace = patterns
107             replace['shortdesc'] = 'Correct collective ordering'
108             replace['longdesc'] = f'All ranks call {c1} twice'
109             replace['outcome'] = 'OK'
110             replace['errormsg'] = ''
111             make_file(template, f'CallOrdering_{c1}_{c2}_ok.c', replace)
112             # Generate the correct code using the collective once
113             replace = patterns
114             replace['shortdesc'] = 'Correct collective ordering'
115             replace['longdesc'] = f'All ranks call {c1} once'
116             replace['outcome'] = 'OK'
117             replace['errormsg'] = ''
118             replace['init2'] = ''
119             replace['operation2a'] = ''
120             replace['operation2b'] = ''
121             replace['fini2a'] = ''
122             replace['fini2b'] = ''
123             replace['free2'] = ''
124             make_file(template, f'CallOrdering_{c1}_ok.c', replace)
125         else:
126             # Generate the correct ordering with two different collectives
127             replace = patterns
128             replace['shortdesc'] = 'Correct collective ordering'
129             replace['longdesc'] = f'All ranks call {c1} and then {c2}'
130             replace['outcome'] = 'OK'
131             replace['errormsg'] = ''
132             make_file(template, f'CallOrdering_{c1}_{c2}_ok.c', replace)
133             # Generate the incorrect ordering with two different collectives
134             replace = patterns
135             replace['shortdesc'] = 'Incorrect collective ordering'
136             replace['longdesc'] = f'Odd ranks call {c1} and then {c2} while even ranks call these collectives in the other order'
137             replace['outcome'] = 'ERROR: CallMatching'
138             replace['errormsg'] = 'Collective mistmatch. @{c1}@ at @{filename}@:@{line:MBIERROR1}@ is matched with @{c2}@ line @{filename}@:@{line:MBIERROR2}@.'
139             replace['operation1b'] = operation[c2]("2")  # Inversion
140             replace['operation2b'] = operation[c1]("1")
141             replace['fini1a'] = fini[c1]("1") # Inversion
142             replace['fini2a'] = fini[c2]("2")
143             replace['fini1b'] = fini[c2]("2") # Inversion
144             replace['fini2b'] = fini[c1]("1")
145             replace['free1'] = free[c2]("2") 
146             replace['free2'] = free[c1]("1")
147
148             make_file(template, f'CallOrdering_{c1}_{c2}_nok.c', replace)
149
150     # Generate the incorrect ordering with one collective
151     replace = patterns
152     replace['shortdesc'] = 'Incorrect collective ordering'
153     replace['longdesc'] = f'Odd ranks call {c1} while even ranks do not call any collective'
154     replace['outcome'] = 'ERROR: CallMatching'
155     replace['errormsg'] = 'Collective mistmatch. @{c1}@ at @{filename}@:@{line:MBIERROR1}@ is not matched.'
156     replace['operation1b'] = ''  # Remove functions
157     replace['operation2b'] = ''
158     replace['operation2a'] = ''
159     replace['fini1b'] = ''
160     replace['fini2a'] = ''
161     replace['fini2b'] = ''
162     make_file(template, f'CallOrdering_{c1}_none_nok.c', replace)
163     # Generate a correct ordering with a conditional not depending on ranks
164     replace = patterns
165     replace['shortdesc'] = 'Correct collective ordering'
166     replace['longdesc'] = f'All ranks call {c1} and then {c2} or inversely'
167     replace['outcome'] = 'OK'
168     replace['errormsg'] = ''
169     replace['change_cond'] = 'nprocs<256'
170     replace['operation2b'] = '' # Remove functions
171     replace['operation2a'] = ''
172     replace['fini2b'] = ''
173     replace['free2a'] = ''
174     make_file(template, f'CallOrdering_{c1}_none_ok.c', replace)