4 import generator_utils as gen
6 template = """// @{generatedby}@
7 /* ///////////////////////// The MPI Bugs Initiative ////////////////////////
11 Description: @{shortdesc}@
14 Version of MPI: Conforms to MPI 1.1, does not require MPI 2 implementation
18 P2P!nonblocking: Lacking
19 P2P!persistent: Lacking
20 COLL!basic: @{collfeature}@
21 COLL!nonblocking: @{icollfeature}@
22 COLL!persistent: Lacking
32 ////////////////////// End of MBI headers /////////////////// */
40 int main(int argc, char **argv) {
45 MPI_Init(&argc, &argv);
46 MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
47 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
48 printf("Hello from rank %d \\n", rank);
51 printf("MBI ERROR: This test needs at least 2 processes to produce a bug!\\n");
54 MPI_Datatype type = MPI_INT;
56 MPI_Comm_split(MPI_COMM_WORLD, 0, nprocs - rank, &newcom);
60 int dbs = sizeof(int)*nprocs; /* Size of the dynamic buffers for alltoall and friends */
63 @{operation}@ /* MBIERROR */
67 if(newcom != MPI_COMM_NULL && newcom != MPI_COMM_WORLD)
68 MPI_Comm_free(&newcom);
71 printf("Rank %d finished normally\\n", rank);
77 # Generate code with one collective
78 for c in gen.coll + gen.icoll + gen.ibarrier:
81 patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.'
82 patterns['collfeature'] = 'Yes' if c in gen.coll else 'Lacking'
83 patterns['icollfeature'] = 'Yes' if c in gen.icoll + gen.ibarrier else 'Lacking'
85 patterns['init'] = gen.init[c]("1")
86 patterns['start'] = gen.start[c]("1")
87 patterns['fini'] = gen.fini[c]("1")
88 patterns['free'] = gen.free[c]("1")
89 patterns['operation'] = gen.operation[c]("1")
91 # Generate the correct code => to remove?
92 replace = patterns.copy()
93 replace['shortdesc'] = 'Collective @{c}@ with correct arguments'
94 replace['longdesc'] = f'All ranks in newcom call {c} with correct arguments'
95 replace['outcome'] = 'OK'
96 replace['errormsg'] = ''
97 replace['change_com'] = '/* No error injected here */'
98 gen.make_file(template, f'ParamMatching_Com_{c}_ok.c', replace)
100 # Generate the incorrect communicator matching
101 replace = patterns.copy()
102 replace['shortdesc'] = 'Collective @{c}@ with a communicator mismatch'
103 replace['longdesc'] = 'Odd ranks call the collective on newcom while even ranks call the collective on MPI_COMM_WORLD'
104 replace['outcome'] = 'ERROR: CommunicatorMatching'
105 replace['errormsg'] = 'Communicator mistmatch in collectives. @{c}@ at @{filename}@:@{line:MBIERROR}@ has newcom or MPI_COMM_WORLD as a communicator.'
106 replace['change_com'] = 'if (rank % 2)\n newcom = MPI_COMM_WORLD; /* MBIERROR */'
107 gen.make_file(template, f'ParamMatching_Com_{c}_nok.c', replace)
109 # Generate the coll with newcom=MPI_COMM_NULL
110 replace = patterns.copy()
111 replace['shortdesc'] = f'Collective @{c}@ with newcom=MPI_COMM_NULL'
112 replace['longdesc'] = f'Collective @{c}@ with newcom=MPI_COMM_NULL'
113 replace['outcome'] = 'ERROR: InvalidCommunicator'
114 replace['errormsg'] = 'Invalid communicator. @{c}@ at @{filename}@:@{line:MBIERROR}@ has MPI_COMM_NULL as a communicator.'
115 replace['change_com'] = 'newcom = MPI_COMM_NULL; /* MBIERROR */'
116 gen.make_file(template, f'InvalidParam_ComNull_{c}_nok.c', replace)