# Only the python scripts are embeeded in the archive, and the C test files are generated at config time using these scripts.
# These python scripts are copied over from the MBI repository with as little changes as possible.
-set(generator_scripts CollMatchingGenerator.py ResleakGenerator.py) # More generators to come
+set(generator_scripts
+ CollArgGenerator.py
+ CollComGenerator.py
+ CollLocalConcurrencyGenerator.py
+ CollMatchingGenerator.py
+ CollP2PMatchingGenerator.py
+ CollP2PMessageRaceGenerator.py
+ CollTopoGenerator.py
+ MissingWaitandStartGenerator.py
+ P2PArgGenerator.py
+ P2PComGenerator.py
+ P2PInvalidComGenerator.py
+ P2PLocalConcurrencyGenerator.py
+ P2PMatchingANYSRCGenerator.py
+ P2PMatchingGenerator.py
+ P2PProbeGenerator.py
+ ResleakGenerator.py
+ RMAArgGenerator.py
+ RMAInvalidArgGenerator.py
+ RMALocalLocalConcurrencyGenerator.py
+ # RMAP2PGlobalConcurrencyGenerator.py
+ RMARemoteLocalConcurrencyGenerator.py
+ RMARemoteRemoteConcurrencyGenerator.py
+ RMAReqLifecycleGenerator.py
+ RMAWinBufferGenerator.py)
if (enable_smpi_MBI_testsuite)
if (NOT enable_smpi)
--- /dev/null
+#! /usr/bin/python3
+import os
+import sys
+from generator_utils import *
+
+template = """// @{generatedby}@
+/* ///////////////////////// The MPI Bugs Initiative ////////////////////////
+
+ Origin: MBI
+
+ Description: @{shortdesc}@
+ @{longdesc}@
+
+ Version of MPI: Conforms to MPI 1.1, does not require MPI 2 implementation
+
+BEGIN_MPI_FEATURES
+ P2P!basic: Lacking
+ P2P!nonblocking: Lacking
+ P2P!persistent: Lacking
+ COLL!basic: @{collfeature}@
+ COLL!nonblocking: @{icollfeature}@
+ COLL!persistent: Lacking
+ COLL!tools: @{toolfeature}@
+ RMA: Lacking
+END_MPI_FEATURES
+
+BEGIN_MBI_TESTS
+ $ mpirun -np 2 ${EXE}
+ | @{outcome}@
+ | @{errormsg}@
+END_MBI_TESTS
+////////////////////// End of MBI headers /////////////////// */
+
+#include <mpi.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define buff_size 128
+
+int main(int argc, char **argv) {
+ int nprocs = -1;
+ int rank = -1;
+ int root = 0;
+ int size = 1, j=0, color=0;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ printf("Hello from rank %d \\n", rank);
+
+ if (nprocs < 2)
+ printf("MBI ERROR: This test needs at least 2 processes to produce a bug!\\n");
+
+ MPI_Comm newcom = MPI_COMM_WORLD;
+ MPI_Op op = MPI_SUM;
+ MPI_Datatype type = MPI_INT;
+
+ int dbs = sizeof(int)*nprocs; /* Size of the dynamic buffers for alltoall and friends */
+
+ @{init}@
+ @{start}@
+
+ @{change_arg}@
+ @{operation}@ /* MBIERROR2 */
+ @{fini}@
+ @{free}@
+
+ MPI_Finalize();
+ printf("Rank %d finished normally\\n", rank);
+ return 0;
+}
+"""
+
+#####################################################
+# Generate code with color mismatch in MPI_Comm_split
+#####################################################
+
+for c in tcoll4color:
+ patterns = {}
+ patterns = {'c': c}
+ patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.'
+ patterns['collfeature'] = 'Lacking'
+ patterns['icollfeature'] = 'Lacking'
+ patterns['toolfeature'] = 'Yes' if c in tcoll4color else 'Lacking'
+ patterns['c'] = c
+ patterns['init'] = init[c]("1")
+ patterns['start'] = start[c]("1")
+ patterns['operation'] = operation[c]("1")
+ patterns['fini'] = fini[c]("1")
+ patterns['free'] = free[c]("1")
+ patterns['change_arg'] = ''
+
+ # Generate the code with invalid color
+ replace = patterns
+ replace['shortdesc'] = 'Invalid color in @{c}@'
+ replace['longdesc'] = 'invalid color in @{c}@'
+ replace['outcome'] = 'ERROR: InvalidOtherArg'
+ replace['errormsg'] = 'Invalid Argument in collective. @{c}@ at line @{line:MBIERROR2}@ has an invalid color'
+ replace['change_arg'] = 'color=-10; /* MBIERROR1*/'
+ make_file(template, f'InvalidParam_OtherArg_{c}_nok.c', replace)
+
+
+##################################
+# Generate code with root mismatch
+##################################
+
+for c in coll4root + icoll4root:
+ patterns = {}
+ patterns = {'c': c}
+ patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.'
+ patterns['collfeature'] = 'Yes' if c in coll4root else 'Lacking'
+ patterns['icollfeature'] = 'Yes' if c in icoll4root else 'Lacking'
+ patterns['toolfeature'] = 'Lacking'
+ patterns['c'] = c
+ patterns['init'] = init[c]("1")
+ patterns['start'] = start[c]("1")
+ patterns['fini'] = fini[c]("1")
+ patterns['free'] = free[c]("1")
+ patterns['operation'] = operation[c]("1")
+ patterns['change_arg'] = ''
+
+ # Generate an incorrect root matching (root mismatch)
+ replace = patterns
+ replace['shortdesc'] = 'Collective @{c}@ with a root mismatch'
+ replace['longdesc'] = f'Odd ranks use 0 as a root while even ranks use 1 as a root'
+ replace['outcome'] = 'ERROR: RootMatching'
+ replace['errormsg'] = 'Collective root mistmatch. @{c}@ at @{filename}@:@{line:MBIERROR2}@ has 0 or 1 as a root.'
+ replace['change_arg'] = 'if (rank % 2)\n root = 1; /* MBIERROR1 */'
+ make_file(template, f'ParamMatching_Root_{c}_nok.c', replace)
+
+ # Generate the call with root=-1 (invalid root)
+ replace = patterns
+ replace['shortdesc'] = f'Collective {c} with root = -1'
+ replace['longdesc'] = f'Collective {c} with root = -1'
+ replace['outcome'] = 'ERROR: InvalidRoot'
+ 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.'
+ replace['change_arg'] = 'root = -1; /* MBIERROR1 */'
+ make_file(template, f'InvalidParam_RootNeg_{c}_nok.c', replace)
+
+ # Generate the call with root=2 (root not in communicator)
+ replace = patterns
+ replace['shortdesc'] = f'Collective {c} with root out of the communicator'
+ replace['longdesc'] = f'Collective {c} with root = 2 (there is only 2 ranks)'
+ replace['outcome'] = 'ERROR: InvalidRoot'
+ 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.'
+ replace['change_arg'] = 'root = nprocs; /* MBIERROR1 */'
+ make_file(template, f'InvalidParam_RootTooLarge_{c}_nok.c', replace)
+
+
+##################################
+# Generate code with type mismatch
+##################################
+
+for c in coll + icoll:
+ if c != 'MPI_Barrier': # Barrier has no Data to mismatch or to nullify
+ patterns = {}
+ patterns = {'c': c}
+ patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.'
+ patterns['collfeature'] = 'Yes' if c in coll else 'Lacking'
+ patterns['icollfeature'] = 'Yes' if c in icoll + ibarrier else 'Lacking'
+ patterns['toolfeature'] = 'Lacking'
+ patterns['c'] = c
+ patterns['init'] = init[c]("1")
+ patterns['start'] = start[c]("1")
+ patterns['fini'] = fini[c]("1")
+ patterns['operation'] = operation[c]("1")
+ patterns['free'] = free[c]("1")
+ patterns['change_arg'] = ''
+
+ # Generate the incorrect matching (datatype Mmismatch)
+ replace = patterns
+ replace['shortdesc'] = 'Collective @{c}@ with a datatype mismatch'
+ replace['longdesc'] = f'Odd ranks use MPI_INT as the datatype while even ranks use MPI_FLOAT'
+ replace['outcome'] = 'ERROR: DatatypeMatching'
+ replace['errormsg'] = 'Collective datatype mistmatch. @{c}@ at @{filename}@:@{line:MBIERROR2}@ has MPI_INT or MPI_FLOAT as a datatype.'
+ replace['change_arg'] = 'if (rank % 2)\n type = MPI_FLOAT; /* MBIERROR1 */'
+ make_file(template, f'ParamMatching_Data_{c}_nok.c', replace)
+
+ # Generate the call with null type (invalid datatype)
+ replace = patterns
+ replace['shortdesc'] = 'Collective @{c}@ with an invalid datatype '
+ replace['longdesc'] = 'Collective @{c}@ with an invalid datatype '
+ replace['outcome'] = 'ERROR: InvalidDatatype'
+ replace['errormsg'] = 'Invalid Datatype. @{c}@ at @{filename}@:@{line:MBIERROR2}@ has an invalid datatype.'
+ replace['change_arg'] = 'type=MPI_DATATYPE_NULL; /* MBIERROR1 */'
+ make_file(template, f'InvalidParam_DataNull_{c}_nok.c', replace)
+
+
+##################################
+# Generate code with Op mismatch
+##################################
+
+for c in coll4op + icoll4op:
+ patterns = {}
+ patterns = {'c': c}
+ patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.'
+ patterns['collfeature'] = 'Yes' if c in coll4op else 'Lacking'
+ patterns['icollfeature'] = 'Yes' if c in icoll4op else 'Lacking'
+ patterns['toolfeature'] = 'Lacking'
+ patterns['c'] = c
+ patterns['init'] = init[c]("1")
+ patterns['start'] = start[c]("1")
+ patterns['fini'] = fini[c]("1")
+ patterns['operation'] = operation[c]("1")
+ patterns['free'] = free[c]("1")
+ patterns['change_arg'] = ''
+
+ # Generate the incorrect matching (op mismatch)
+ replace = patterns
+ replace['shortdesc'] = 'Collective @{c}@ with an operator mismatch'
+ replace['longdesc'] = f'Odd ranks use MPI_SUM as the operator while even ranks use MPI_MAX'
+ replace['outcome'] = 'ERROR: OperatorMatching'
+ replace['errormsg'] = 'Collective operator mistmatch. @{c}@ at @{filename}@:@{line:MBIERROR2}@ has MPI_MAX or MPI_SUM as an operator.'
+ replace['change_arg'] = 'if (rank % 2)\n op = MPI_MAX; /* MBIERROR1 */'
+ make_file(template, f'ParamMatching_Op_{c}_nok.c', replace)
+
+ # Generate the call with Op=MPI_OP_NULL (invalid op)
+ replace = patterns
+ replace['shortdesc'] = 'Collective @{c}@ with an invalid operator '
+ replace['longdesc'] = 'Collective @{c}@ with an invalid operator '
+ replace['outcome'] = 'ERROR: InvalidOperator'
+ replace['errormsg'] = 'Invalid Operator. @{c}@ at @{filename}@:@{line:MBIERROR2}@ has MPI_OP_NULL as an operator.'
+ replace['change_arg'] = 'op = MPI_OP_NULL; /* MBIERROR1 */'
+ make_file(template, f'InvalidParam_OpNull_{c}_nok.c', replace)
--- /dev/null
+#! /usr/bin/python3
+import os
+import sys
+from generator_utils import *
+
+template = """// @{generatedby}@
+/* ///////////////////////// The MPI Bugs Initiative ////////////////////////
+
+ Origin: MBI
+
+ Description: @{shortdesc}@
+ @{longdesc}@
+
+ Version of MPI: Conforms to MPI 1.1, does not require MPI 2 implementation
+
+BEGIN_MPI_FEATURES
+ P2P!basic: Lacking
+ P2P!nonblocking: Lacking
+ P2P!persistent: Lacking
+ COLL!basic: @{collfeature}@
+ COLL!nonblocking: @{icollfeature}@
+ COLL!persistent: Lacking
+ COLL!tools: Yes
+ RMA: Lacking
+END_MPI_FEATURES
+
+BEGIN_MBI_TESTS
+ $ mpirun -np 2 ${EXE}
+ | @{outcome}@
+ | @{errormsg}@
+END_MBI_TESTS
+////////////////////// End of MBI headers /////////////////// */
+
+#include <mpi.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define buff_size 128
+
+int main(int argc, char **argv) {
+ int nprocs = -1;
+ int rank = -1;
+ int root = 0;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ printf("Hello from rank %d \\n", rank);
+
+ if (nprocs < 2)
+ printf("MBI ERROR: This test needs at least 2 processes to produce a bug!\\n");
+
+ MPI_Op op = MPI_SUM;
+ MPI_Datatype type = MPI_INT;
+ MPI_Comm newcom;
+ MPI_Comm_split(MPI_COMM_WORLD, 0, nprocs - rank, &newcom);
+
+ @{change_com}@
+
+ int dbs = sizeof(int)*nprocs; /* Size of the dynamic buffers for alltoall and friends */
+ @{init}@
+ @{start}@
+ @{operation}@ /* MBIERROR */
+ @{fini}@
+ @{free}@
+
+ if(newcom != MPI_COMM_NULL && newcom != MPI_COMM_WORLD)
+ MPI_Comm_free(&newcom);
+
+ MPI_Finalize();
+ printf("Rank %d finished normally\\n", rank);
+ return 0;
+}
+"""
+
+
+# Generate code with one collective
+for c in coll + icoll + ibarrier:
+ patterns = {}
+ patterns = {'c': c}
+ patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.'
+ patterns['collfeature'] = 'Yes' if c in coll else 'Lacking'
+ patterns['icollfeature'] = 'Yes' if c in icoll + ibarrier else 'Lacking'
+ patterns['c'] = c
+ patterns['init'] = init[c]("1")
+ patterns['start'] = start[c]("1")
+ patterns['fini'] = fini[c]("1")
+ patterns['free'] = free[c]("1")
+ patterns['operation'] = operation[c]("1")
+
+ # Generate the correct code => to remove?
+ replace = patterns
+ replace['shortdesc'] = 'Collective @{c}@ with correct arguments'
+ replace['longdesc'] = f'All ranks in newcom call {c} with correct arguments'
+ replace['outcome'] = 'OK'
+ replace['errormsg'] = ''
+ replace['change_com'] = '/* No error injected here */'
+ make_file(template, f'ParamMatching_Com_{c}_ok.c', replace)
+
+ # Generate the incorrect communicator matching
+ replace = patterns
+ replace['shortdesc'] = 'Collective @{c}@ with a communicator mismatch'
+ replace['longdesc'] = f'Odd ranks call the collective on newcom while even ranks call the collective on MPI_COMM_WORLD'
+ replace['outcome'] = 'ERROR: CommunicatorMatching'
+ replace['errormsg'] = 'Communicator mistmatch in collectives. @{c}@ at @{filename}@:@{line:MBIERROR}@ has newcom or MPI_COMM_WORLD as a communicator.'
+ replace['change_com'] = 'if (rank % 2)\n newcom = MPI_COMM_WORLD; /* MBIERROR */'
+ make_file(template, f'ParamMatching_Com_{c}_nok.c', replace)
+
+ # Generate the coll with newcom=MPI_COMM_NULL
+ replace = patterns
+ replace['shortdesc'] = f'Collective @{c}@ with newcom=MPI_COMM_NULL'
+ replace['longdesc'] = f'Collective @{c}@ with newcom=MPI_COMM_NULL'
+ replace['outcome'] = 'ERROR: InvalidCommunicator'
+ replace['errormsg'] = 'Invalid communicator. @{c}@ at @{filename}@:@{line:MBIERROR}@ has MPI_COMM_NULL as a communicator.'
+ replace['change_com'] = 'newcom = MPI_COMM_NULL; /* MBIERROR */'
+ make_file(template, f'InvalidParam_ComNull_{c}_nok.c', replace)
--- /dev/null
+#! /usr/bin/python3
+import os
+import sys
+from generator_utils import *
+
+template = """// @{generatedby}@
+/* ///////////////////////// The MPI Bugs Initiative ////////////////////////
+
+ Origin: MBI
+
+ Description: @{shortdesc}@
+ @{longdesc}@
+
+ Version of MPI: Conforms to MPI 3, requires MPI 3 implementation
+
+BEGIN_MPI_FEATURES
+ P2P!basic: Lacking
+ P2P!nonblocking: Lacking
+ P2P!persistent: Lacking
+ COLL!basic: Lacking
+ COLL!nonblocking: @{icollfeature}@
+ COLL!persistent: @{pcollfeature}@
+ COLL!tools: Lacking
+ RMA: Lacking
+END_MPI_FEATURES
+
+BEGIN_MBI_TESTS
+ $ mpirun -np 2 ${EXE}
+ | @{outcome}@
+ | @{errormsg}@
+END_MBI_TESTS
+////////////////////// End of MBI headers /////////////////// */
+
+#include <mpi.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define buff_size 128
+
+int main(int argc, char **argv) {
+ int nprocs = -1;
+ int rank = -1;
+ int root = 0;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ printf("Hello from rank %d \\n", rank);
+
+ if (nprocs < 2)
+ printf("MBI ERROR: This test needs at least 2 processes to produce a bug!\\n");
+
+ int dbs = sizeof(int)*nprocs; /* Size of the dynamic buffers for alltoall and friends */
+ MPI_Op op = MPI_SUM;
+ MPI_Comm newcom = MPI_COMM_WORLD;
+ MPI_Datatype type = MPI_INT;
+
+ @{init}@
+ @{start}@
+ @{operation}@
+ @{write}@ /* MBIERROR */
+ @{fini}@
+ @{free}@
+
+ MPI_Finalize();
+ printf("Rank %d finished normally\\n", rank);
+ return 0;
+}
+"""
+
+for c in icoll + pcoll:
+ patterns = {}
+ patterns = {'c': c}
+ patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.'
+ patterns['icollfeature'] = 'Yes' if c in icoll else 'Lacking'
+ patterns['pcollfeature'] = 'Yes' if c in pcoll else 'Lacking'
+ patterns['c'] = c
+ patterns['init'] = init[c]("1")
+ patterns['start'] = start[c]("1")
+ patterns['fini'] = fini[c]("1")
+ patterns['operation'] = operation[c]("1")
+ patterns['write'] = write[c]("1")
+ patterns['free'] = free[c]("1")
+
+ replace = patterns
+ replace['shortdesc'] = 'Local concurrency with a collective'
+ replace['longdesc'] = f'The buffer in {c} is modified before the call has been completed.'
+ replace['outcome'] = 'ERROR: LocalConcurrency'
+ replace['errormsg'] = 'Local Concurrency with a collective. The buffer in @{c}@ is modified at @{filename}@:@{line:MBIERROR}@ whereas there is no guarantee the call has been completed.'
+ make_file(template, f'LocalConcurrency_{c}_nok.c', replace)
--- /dev/null
+#! /usr/bin/python3
+import os
+import sys
+from generator_utils import *
+
+template = """// @{generatedby}@
+/* ///////////////////////// The MPI Bugs Initiative ////////////////////////
+
+ Origin: MBI
+
+ Description: @{shortdesc}@
+ @{longdesc}@
+
+ Version of MPI: Conforms to MPI 1.1, does not require MPI 2 implementation
+
+BEGIN_MPI_FEATURES
+ P2P!basic: @{p2pfeature}@
+ P2P!nonblocking: @{ip2pfeature}@
+ P2P!persistent: Lacking
+ COLL!basic: @{collfeature}@
+ COLL!nonblocking: Lacking
+ COLL!persistent: Lacking
+ COLL!tools: Lacking
+ RMA: Lacking
+END_MPI_FEATURES
+
+BEGIN_MBI_TESTS
+ $ mpirun -np 2 ${EXE}
+ | @{outcome}@
+ | @{errormsg}@
+END_MBI_TESTS
+////////////////////// End of MBI headers /////////////////// */
+
+#include <mpi.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+int main(int argc, char **argv) {
+ int nprocs = -1;
+ int rank = -1;
+ int dest, src;
+ int root = 0;
+ int stag = 0, rtag = 0;
+ int buff_size = 1;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ printf("Hello from rank %d \\n", rank);
+
+ if (nprocs < 2)
+ printf("MBI ERROR: This test needs at least 2 processes to produce a bug!\\n");
+
+ int dbs = sizeof(int)*nprocs; /* Size of the dynamic buffers for alltoall and friends */
+ MPI_Comm newcom = MPI_COMM_WORLD;
+ MPI_Datatype type = MPI_INT;
+ MPI_Op op = MPI_SUM;
+
+ @{init1}@
+ @{init2}@
+ @{init3}@
+ if (rank == 0) {
+ dest=1;src=1;
+ @{operation3}@ /* MBIERROR1 */
+ @{fini3}@
+ @{operation1}@
+ @{fini1}@
+ }else if (rank==1) {
+ dest=0;src=0;
+ @{operation2}@ /* MBIERROR2 */
+ @{fini2}@
+ @{operation3}@
+ @{fini3}@
+ }
+
+ @{free1}@
+ @{free2}@
+ @{free3}@
+
+ MPI_Finalize();
+ printf("Rank %d finished normally\\n", rank);
+ return 0;
+}
+"""
+
+
+for s in send + isend:
+ for r in recv + irecv:
+ for c in coll:
+ patterns = {}
+ patterns = {'s': s, 'r': r, 'c': c}
+ patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.'
+ patterns['p2pfeature'] = 'Yes' if s in send or r in recv else 'Lacking'
+ patterns['ip2pfeature'] = 'Yes' if s in isend or r in irecv else 'Lacking'
+ patterns['collfeature'] = 'Yes' if c in coll else 'Lacking'
+ patterns['s'] = s
+ patterns['r'] = r
+ patterns['c'] = c
+ patterns['init1'] = init[s]("1")
+ patterns['init2'] = init[r]("2")
+ patterns['init3'] = init[c]("3")
+ patterns['fini1'] = fini[s]("1")
+ patterns['fini2'] = fini[r]("2")
+ patterns['fini3'] = fini[c]("3")
+ patterns['free1'] = free[s]("1")
+ patterns['free2'] = free[r]("2")
+ patterns['free3'] = free[c]("3")
+ patterns['operation1'] = operation[s]("1")
+ patterns['operation2'] = operation[r]("2")
+ patterns['operation3'] = operation[c]("3")
+
+ # Generate the incorrect matching because of the conditional
+ replace = patterns
+ replace['shortdesc'] = 'Point to point & collective mismatch'
+ replace['longdesc'] = 'Point to point @{r}@ is matched with @{c}@ which causes a deadlock.'
+ replace['outcome'] = 'ERROR: CallMatching'
+ replace['errormsg'] = 'P2P & Collective mistmatch. @{r}@ at @{filename}@:@{line:MBIERROR2}@ is matched with @{c}@ at @{filename}@:@{line:MBIERROR1}@ wich causes a deadlock.'
+ make_file(template, f'CallOrdering_{r}_{s}_{c}_nok.c', replace)
+
+ # Generate the incorrect code depending on buffering
+ # replace = patterns
+ # replace['shortdesc'] = 'Point to point & collective mismatch'
+ # replace['longdesc'] = 'Point to point @{s}@ is matched with @{c}@ which causes a deadlock depending on the buffering mode.'
+ # replace['outcome'] = 'ERROR: BufferingHazard'
+ # replace['errormsg'] = 'P2P & Collective mistmatch. @{s}@ at @{filename}@:@{line:MBIERROR2}@ is matched with @{c}@ at @{filename}@:@{line:MBIERROR1}@ wich causes a deadlock.'
+ # replace['init1'] = init[s]("1")
+ # replace['init2'] = init[r]("2")
+ # replace['operation1'] = operation[r]("2")
+ # replace['operation2'] = operation[s]("1")
+ # replace['fini1'] = fini[r]("2")
+ # replace['fini2'] = fini[s]("1")
+ # make_file(template, f'CollP2PBuffering_{r}_{s}_{c}_nok.c', replace)
+
--- /dev/null
+#! /usr/bin/python3
+import os
+import sys
+from generator_utils import *
+
+template = """// @{generatedby}@
+/* ///////////////////////// The MPI Bugs Initiative ////////////////////////
+
+ Origin: MBI
+
+ Description: @{shortdesc}@
+ @{longdesc}@
+
+ Version of MPI: Conforms to MPI 1.1, does not require MPI 2 implementation
+
+BEGIN_MPI_FEATURES
+ P2P!basic: @{p2pfeature}@
+ P2P!nonblocking: @{ip2pfeature}@
+ P2P!persistent: Lacking
+ COLL!basic: @{collfeature}@
+ COLL!nonblocking: Lacking
+ COLL!persistent: Lacking
+ COLL!tools: Lacking
+ RMA: Lacking
+END_MPI_FEATURES
+
+BEGIN_MBI_TESTS
+ $ mpirun -np 4 ${EXE}
+ | @{outcome}@
+ | @{errormsg}@
+END_MBI_TESTS
+////////////////////// End of MBI headers /////////////////// */
+
+#include <mpi.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+int main(int argc, char **argv) {
+ int nprocs = -1;
+ int rank = -1;
+ int dest, src;
+ int i=0;
+ int root = 0;
+ int stag = 0, rtag = 0;
+ int buff_size = 1;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ printf("Hello from rank %d \\n", rank);
+
+ if (nprocs != 4)
+ printf("MBI ERROR: This test needs 4 processes to produce a bug!\\n");
+
+ int dbs = sizeof(int)*nprocs; /* Size of the dynamic buffers for alltoall and friends */
+ MPI_Comm newcom = MPI_COMM_WORLD;
+ MPI_Datatype type = MPI_INT;
+ MPI_Op op = MPI_SUM;
+
+
+
+ @{init1}@
+ @{init2}@
+ @{init3}@
+ @{init4}@
+ if (rank == 0) {
+ dest=1;
+ @{operation1}@
+ @{fini1}@
+ @{operation2}@
+ @{fini2}@
+ }else if (rank==2) {
+ dest=1;
+ @{operation1}@
+ @{fini1}@
+ @{operation2}@
+ @{fini2}@
+ }else if (rank==1) {
+ src = MPI_ANY_SOURCE;
+ rtag = MPI_ANY_TAG;
+ @{operation3}@ /* MBIERROR1 */
+ @{operation1}@
+ @{fini1}@
+ @{operation4}@ /* MBIERROR2 */
+ @{fini3}@
+ @{fini4}@
+ }else if (rank==3) {
+ @{operation1}@
+ @{fini1}@
+ }
+
+ @{free1}@
+ @{free2}@
+ @{free3}@
+ @{free4}@
+
+ MPI_Finalize();
+ printf("Rank %d finished normally\\n", rank);
+ return 0;
+}
+"""
+
+
+for s in send + isend:
+ for r in irecv:
+ for c in coll:
+ patterns = {}
+ patterns = {'s': s, 'r': r, 'c': c}
+ patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.'
+ patterns['p2pfeature'] = 'Yes' if s in send or r in recv else 'Lacking'
+ patterns['ip2pfeature'] = 'Yes' if s in isend or r in irecv else 'Lacking'
+ patterns['collfeature'] = 'Yes' if c in coll else 'Lacking'
+ patterns['s'] = s
+ patterns['r'] = r
+ patterns['c'] = c
+ patterns['init1'] = init[c]("1")
+ patterns['init2'] = init[s]("2")
+ patterns['init3'] = init[r]("3")
+ patterns['init4'] = init[r]("4")
+ patterns['fini1'] = fini[c]("1")
+ patterns['fini2'] = fini[s]("2")
+ patterns['fini3'] = fini[r]("3")
+ patterns['fini4'] = fini[r]("4")
+ patterns['free1'] = free[c]("1")
+ patterns['free2'] = free[s]("2")
+ patterns['free3'] = free[r]("3")
+ patterns['free4'] = free[r]("4")
+ patterns['operation1'] = operation[c]("1")
+ patterns['operation2'] = operation[s]("2")
+ patterns['operation3'] = operation[r]("3")
+ patterns['operation4'] = operation[r]("4")
+
+ # Generate the incorrect matching because of the conditional
+ replace = patterns
+ replace['shortdesc'] = 'Message race'
+ replace['longdesc'] = 'Message race in @{r}@ with @{c}@.'
+ replace['outcome'] = 'ERROR: MessageRace'
+ replace['errormsg'] = 'Message race. The use of wildcard receive calls (@{r}@ at @{filename}@:@{line:MBIERROR1}@ and @{r}@ at @{filename}@:@{line:MBIERROR2}@) leads to nondeterministic matching.'
+ make_file(template, f'MessageRace_{c}_{s}_{r}_nok.c', replace)
--- /dev/null
+#! /usr/bin/python3
+import os
+import sys
+from generator_utils import *
+
+template = """// @{generatedby}@
+/* ///////////////////////// The MPI Bugs Initiative ////////////////////////
+
+ Origin: MBI
+
+ Description: @{shortdesc}@
+ @{longdesc}@
+
+ Version of MPI: Conforms to MPI 1.1, does not require MPI 2 implementation
+
+BEGIN_MPI_FEATURES
+ P2P!basic: Lacking
+ P2P!nonblocking: Lacking
+ P2P!persistent: Lacking
+ COLL!basic: Lacking
+ COLL!nonblocking: Lacking
+ COLL!persistent: Lacking
+ COLL!tools: @{toolfeature}@
+ RMA: Lacking
+END_MPI_FEATURES
+
+BEGIN_MBI_TESTS
+ $ mpirun -np 2 ${EXE}
+ | @{outcome}@
+ | @{errormsg}@
+END_MBI_TESTS
+////////////////////// End of MBI headers /////////////////// */
+
+#include <mpi.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define buff_size 128
+
+int main(int argc, char **argv) {
+ int nprocs = -1;
+ int rank = -1;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ printf("Hello from rank %d \\n", rank);
+
+ if (nprocs < 2)
+ printf("MBI ERROR: This test needs at least 2 processes to produce a bug!\\n");
+
+ MPI_Comm newcom;
+ int dims[2], periods[2], coords[2];
+ int source, dest;
+ dims[0] = 2;
+ dims[1] = 1;
+ periods[0] = 1;
+ periods[1] = 1;
+
+ @{change_dims}@
+
+ MPI_Cart_create(MPI_COMM_WORLD, 2, dims, periods, 0, &newcom); /* create a cartesian communicator */
+
+ @{change_com}@
+
+ @{init}@
+ @{operation}@ /* MBIERROR2 */
+ @{fini}@
+
+ if (newcom != MPI_COMM_NULL)
+ MPI_Comm_free(&newcom);
+
+ MPI_Finalize();
+ printf("Rank %d finished normally\\n", rank);
+ return 0;
+}
+"""
+
+for c in tcoll4topo:
+ patterns = {}
+ patterns = {'c': c}
+ patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.'
+ patterns['toolfeature'] = 'Yes' if c in tcoll4topo else 'Lacking'
+ patterns['c'] = c
+ patterns['init'] = init[c]("1")
+ patterns['fini'] = fini[c]("1")
+ patterns['operation'] = operation[c]("1")
+
+ # Generate the correct code
+ replace = patterns
+ replace['shortdesc'] = 'Function @{c}@ with correct arguments'
+ replace['longdesc'] = f'All ranks in comm call {c} with correct arguments'
+ replace['outcome'] = 'OK'
+ replace['errormsg'] = ''
+ replace['change_com'] = '/* No error injected here */'
+ replace['change_dims'] = '/* No error injected here */'
+ make_file(template, f'InvalidParam_{c}_ok.c', replace)
+
+ # Generate the incorrect code
+ replace = patterns
+ replace['shortdesc'] = 'The code tries to get cartesian information of MPI_COMM_WORLD.'
+ replace['longdesc'] = 'The code creates a cartesian communicator, and tries to get cartesian information of MPI_COMM_WORLD.'
+ replace['outcome'] = 'ERROR: InvalidCommunicator'
+ replace['errormsg'] = 'Invalid Communicator in a collective. @{c}@ at @{filename}@:@{line:MBIERROR2}@ tries to get cartesian information of MPI_COMM_WORLD.'
+ replace['change_com'] = 'newcom = MPI_COMM_WORLD; /* MBIERROR1 */'
+ make_file(template, f'InvalidParam_Com_{c}_nok.c', replace)
+
+ # Generate the code with newcom=MPI_COMM_NULL
+ replace = patterns
+ replace['shortdesc'] = 'Function @{c}@ called with comm=MPI_COMM_NULL'
+ replace['longdesc'] = 'Function @{c}@ called with comm=MPI_COMM_NULL'
+ replace['outcome'] = 'ERROR: InvalidCommunicator'
+ replace['errormsg'] = 'Invalid communicator. @{c}@ at @{filename}@:@{line:MBIERROR2}@ has MPI_COMM_NULL as a communicator.'
+ replace['change_com'] = 'newcom = MPI_COMM_NULL; /* MBIERROR1 */'
+ make_file(template, f'InvalidParam_ComNull_{c}_nok.c', replace)
+
+ # Generate the code with invalid dimension
+ replace = patterns
+ replace['shortdesc'] = 'Creates a cartesian communicator with a negative entry in the dims attribute'
+ replace['longdesc'] = 'Creates a cartesian communicator with a negative entry in the dims attribute, which is a usage error'
+ replace['outcome'] = 'ERROR: InvalidOtherArg'
+ replace['errormsg'] = 'Invalid Argument. MPI_Cart_create has invalid dimensions.'
+ replace['change_com'] = ""
+ replace['change_dims'] = 'dims[0] = -2; dims[1] = -1; /* MBIERROR1 */'
+ make_file(template, f'InvalidParam_Dim_MPI_Cart_create_nok.c', replace)
--- /dev/null
+#! /usr/bin/python3
+import os
+import sys
+from generator_utils import *
+
+template = """// @{generatedby}@
+/* ///////////////////////// The MPI Bugs Initiative ////////////////////////
+
+ Origin: MBI
+
+ Description: @{shortdesc}@
+ @{longdesc}@
+
+ Version of MPI: Conforms to MPI 1.1, does not require MPI 2 implementation
+
+BEGIN_MPI_FEATURES
+ P2P!basic: Lacking
+ P2P!nonblocking: @{ip2pfeature}@
+ P2P!persistent: @{persfeature}@
+ COLL!basic: Lacking
+ COLL!nonblocking: @{icollfeature}@
+ COLL!persistent: @{cpersfeature}@
+ COLL!tools: Lacking
+ RMA: Lacking
+END_MPI_FEATURES
+
+BEGIN_MBI_TESTS
+ $ mpirun -np 2 ${EXE}
+ | @{outcome}@
+ | @{errormsg}@
+END_MBI_TESTS
+////////////////////// End of MBI headers /////////////////// */
+
+#include <mpi.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+int main(int argc, char **argv) {
+ int nprocs = -1;
+ int rank = -1;
+ int root = 0;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ printf("Hello from rank %d \\n", rank);
+
+ if (nprocs < 2)
+ printf("MBI ERROR: This test needs at least 2 processes to produce a bug!\\n");
+
+ MPI_Comm newcom = MPI_COMM_WORLD;
+ MPI_Datatype type = MPI_INT;
+ MPI_Op op = MPI_SUM;
+ int stag = 0, rtag = 0;
+ int buff_size = 1;
+
+ int dbs = sizeof(int)*nprocs; /* Size of the dynamic buffers for alltoall and friends */
+
+ int dest = (rank == nprocs - 1) ? (0) : (rank + 1);
+ int src = (rank == 0) ? (nprocs - 1) : (rank - 1);
+
+ @{init1}@
+ @{init2}@
+
+ @{operation1}@ /* MBIERROR */
+ @{start1}@
+ @{operation2}@
+ @{start2}@
+
+ @{fini1}@
+ @{fini2}@
+
+ @{free1}@
+ @{free2}@
+
+ MPI_Finalize();
+ printf("Rank %d finished normally\\n", rank);
+ return 0;
+}
+"""
+
+
+for s in isend + psend:
+ for r in irecv + precv:
+ patterns = {}
+ patterns = {'s': s, 'r': r}
+ patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.'
+ patterns['persfeature'] = 'Yes' if s in psend or r in precv else 'Lacking'
+ patterns['ip2pfeature'] = 'Yes' if s in isend or r in irecv else 'Lacking'
+ patterns['icollfeature'] = 'Lacking'
+ patterns['cpersfeature'] = 'Lacking'
+ patterns['s'] = s
+ patterns['r'] = r
+ patterns['init1'] = init[s]("1")
+ patterns['init2'] = init[r]("2")
+ patterns['start1'] = start[s]("1")
+ startPers = patterns['start1']
+ patterns['start2'] = start[r]("2")
+ patterns['operation1'] = operation[s]("1")
+ patterns['operation2'] = operation[r]("2")
+ patterns['fini1'] = fini[s]("1")
+ wait = patterns['fini1']
+ patterns['fini2'] = fini[r]("2")
+ patterns['free1'] = free[s]("1")
+ Reqfree = patterns['free1']
+ patterns['free2'] = free[r]("2")
+
+ # Generate the correct code
+ replace = patterns
+ replace['shortdesc'] = 'Correct matching'
+ replace['longdesc'] = f'No error'
+ replace['outcome'] = 'OK'
+ replace['errormsg'] = 'OK'
+ make_file(template, f'ReqLifecycle_{s}_{r}_ok.c', replace)
+
+ # Generate the code with a missing wait
+ replace = patterns
+ replace['shortdesc'] = 'Missing wait'
+ replace['longdesc'] = 'Missing Wait. @{s}@ at @{filename}@:@{line:MBIERROR}@ has no completion.'
+ replace['outcome'] = 'ERROR: MissingWait'
+ replace['errormsg'] = 'ERROR: MissingWait'
+ replace['fini1'] = ' /* MBIERROR MISSING: ' + wait + ' */'
+ make_file(template, f'ReqLifecycle_MissingWait_{s}_{r}_nok.c', replace)
+
+ if s in psend:
+ # Generate the code with a missing start - persistent only
+ replace = patterns
+ replace['shortdesc'] = 'Missing start'
+ replace['longdesc'] = 'Missing start. @{s}@ at @{filename}@:@{line:MBIERROR}@ has no start'
+ replace['outcome'] = 'ERROR: MissingStart'
+ replace['errormsg'] = 'ERROR: MissingStart'
+ replace['fini1'] = fini[s]("1")
+ replace['start1'] = ' /* MBIERROR MISSING: ' + startPers + ' */'
+ make_file(template, f'ReqLifecycle_MissingStart_{s}_{r}_nok.c', replace)
+ # Generate the code with a missing free - persistent only
+ replace = patterns
+ replace['shortdesc'] = 'Missing free'
+ replace['longdesc'] = 'Missing free. @{s}@ at @{filename}@:@{line:MBIERROR}@ has no free'
+ replace['outcome'] = 'ERROR: RequestLeak'
+ replace['errormsg'] = 'ERROR: RequestLeak'
+ replace['start1'] = start[s]("1")
+ replace['free1'] = ' /* MBIERROR MISSING: ' + Reqfree + ' */'
+ make_file(template, f'ResLeak_nofree_{s}_{r}_nok.c', replace)
+
+
+# Collectives only
+for c in pcoll + icoll + ibarrier:
+ patterns = {}
+ patterns = {'c': c}
+ patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.'
+ patterns['persfeature'] = 'Lacking'
+ patterns['ip2pfeature'] = 'Lacking'
+ patterns['cpersfeature'] = 'Yes' if c in pcoll else 'Lacking'
+ patterns['icollfeature'] = 'Yes' if c in icoll + ibarrier else 'Lacking'
+ patterns['c'] = c
+ patterns['init1'] = init[c]("1")
+ patterns['operation1'] = operation[c]("1")
+ patterns['start1'] = start[c]("1")
+ patterns['fini1'] = fini[c]("1")
+ patterns['free1'] = free[c]("1")
+ opstart = patterns['start1']
+ opwait = patterns['fini1']
+ opfree = patterns['free1']
+ patterns['init2'] = ""
+ patterns['operation2'] = ""
+ patterns['start2'] = ""
+ patterns['fini2'] = ""
+ patterns['free2'] = ""
+
+ # Generate the code with a missing wait
+ replace = patterns
+ replace['shortdesc'] = 'Missing wait'
+ replace['longdesc'] = 'Missing Wait. @{c}@ at @{filename}@:@{line:MBIERROR}@ has no completion'
+ replace['outcome'] = 'ERROR: MissingWait'
+ replace['errormsg'] = 'ERROR: MissingWait'
+ replace['fini1'] = ' /* MBIERROR MISSING: ' + opwait + ' */'
+ replace['free1'] = ' /* MISSING: ' + replace['free1'] + ' (to not free the buffer before an internal wait */'
+ make_file(template, f'ReqLifecycle_MissingWait_{c}_nok.c', replace)
+
+ if c in pcoll:
+ # Generate the code with a missing start - persistent only
+ replace = patterns
+ replace['shortdesc'] = 'Missing start functio'
+ replace['longdesc'] = 'Missing Start. @{c}@ at @{filename}@:@{line:MBIERROR}@ has no start'
+ replace['outcome'] = 'ERROR: MissingStart'
+ replace['errormsg'] = 'ERROR: MissingStart'
+ replace['fini1'] = fini[c]("1")
+ replace['start1'] = ' /* MBIERROR MISSING: ' + opstart + ' */'
+ make_file(template, f'ReqLifecycle_MissingStart_{c}_nok.c', replace)
+
+ # Generate the code with a resleak (no free) - persistent only
+ replace = patterns
+ replace['shortdesc'] = 'Missing free'
+ replace['longdesc'] = 'Missing free. @{c}@ at @{filename}@:@{line:MBIERROR}@ has no free'
+ replace['outcome'] = 'ERROR: RequestLeak'
+ replace['errormsg'] = 'ERROR: RequestLeak'
+ replace['start1'] = start[c]("1")
+ replace['free1'] = ' /* MBIERROR MISSING: ' + opfree + ' */'
+ make_file(template, f'ResLeak_nofree_{c}_nok.c', replace)
--- /dev/null
+#! /usr/bin/python3
+import os
+import sys
+from generator_utils import *
+
+template = """// @{generatedby}@
+/* ///////////////////////// The MPI Bugs Initiative ////////////////////////
+
+ Origin: MBI
+
+ Description: @{shortdesc}@
+ @{longdesc}@
+
+ Version of MPI: Conforms to MPI 1.1, does not require MPI 2 implementation
+
+BEGIN_MPI_FEATURES
+ P2P!basic: @{p2pfeature}@
+ P2P!nonblocking: @{ip2pfeature}@
+ P2P!persistent: @{persfeature}@
+ COLL!basic: Lacking
+ COLL!nonblocking: Lacking
+ COLL!persistent: Lacking
+ COLL!tools: Lacking
+ RMA: Lacking
+END_MPI_FEATURES
+
+BEGIN_MBI_TESTS
+ $ mpirun -np 2 ${EXE}
+ | @{outcome}@
+ | @{errormsg}@
+END_MBI_TESTS
+////////////////////// End of MBI headers /////////////////// */
+
+#include <mpi.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+int main(int argc, char **argv) {
+ int nprocs = -1;
+ int rank = -1;
+ int src=0, dest=1;
+ int stag=0, rtag=0;
+ int buff_size = 1;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ printf("Hello from rank %d \\n", rank);
+
+ if (nprocs < 2)
+ printf("MBI ERROR: This test needs at least 2 processes to produce a bug!\\n");
+
+ MPI_Comm newcom = MPI_COMM_WORLD;
+ MPI_Datatype type = MPI_INT;
+
+ @{change_arg}@
+
+ @{init1}@
+ @{init2}@
+ if (rank == 0) {
+ @{operation1}@ /* MBIERROR1 */
+ @{start1}@
+ @{fini1}@
+ }else if (rank == 1) {
+ @{operation2}@ /* MBIERROR2 */
+ @{start2}@
+ @{fini2}@
+ }
+ @{free1}@
+ @{free2}@
+
+ MPI_Finalize();
+ printf("Rank %d finished normally\\n", rank);
+ return 0;
+}
+"""
+
+##################################
+# Generate code with type mismatch
+##################################
+
+for p1 in allsend:
+ for p2 in allrecv:
+ patterns = {}
+ patterns = {'p1': p1, 'p2': p2}
+ patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.'
+ patterns['p2pfeature'] = 'Yes' if p1 in send + ssend + bsend or p2 in recv else 'Lacking'
+ patterns['ip2pfeature'] = 'Yes' if p1 in isend or p2 in irecv else 'Lacking'
+ patterns['persfeature'] = 'Yes' if p1 in psend or p2 in precv else 'Lacking'
+ patterns['p1'] = p1
+ patterns['p2'] = p2
+ patterns['init1'] = init[p1]("1")
+ patterns['init2'] = init[p2]("2")
+ patterns['start1'] = start[p1]("1")
+ patterns['start2'] = start[p2]("2")
+ patterns['fini1'] = fini[p1]("1")
+ patterns['fini2'] = fini[p2]("2")
+ patterns['operation1'] = operation[p1]("1") #send
+ patterns['operation2'] = operation[p2]("2") #recv
+ patterns['free1'] = free[p1]("1")
+ patterns['free2'] = free[p2]("2")
+
+ # Generate the incorrect matching
+ replace = patterns
+ replace['shortdesc'] = 'Point to point @{p1}@ and @{p2}@ have a datatype mismatch'
+ replace['longdesc'] = 'Process 0 uses MPI_FLOAT as the datatype while process 1 uses MPI_INT.'
+ replace['outcome'] = 'ERROR: DatatypeMatching'
+ replace['errormsg'] = 'P2P Datatype mismatch. @{p1}@ at @{filename}@:@{line:MBIERROR1}@ and @{p2}@ at @{filename}@:@{line:MBIERROR2}@ have MPI_INT and MPI_FLOAT as a datatype'
+ replace['change_arg'] = 'if (rank == 0)\n type = MPI_FLOAT; /* MBIERROR3 */'
+ make_file(template, f'ParamMatching_Data_{p1}_{p2}_nok.c', replace)
+
+ # Generate code with a null type
+ replace = patterns
+ replace['shortdesc'] = 'Use of invalid datatype in point-to-point communication'
+ replace['longdesc'] = 'Point to point @{p1}@ and @{p2}@ have MPI_DATATYPE_NULL as a type'
+ replace['outcome'] = 'ERROR: InvalidDatatype'
+ replace['errormsg'] = 'Invalid datatype in P2P. @{p1}@ at @{filename}@:@{line:MBIERROR1}@ and @{p2}@ at @{filename}@:@{line:MBIERROR2}@ have MPI_DATATYPE_NULL as a type'
+ replace['change_arg'] = 'type = MPI_DATATYPE_NULL; /* MBIERROR3 */'
+ make_file(template, f'InvalidParam_DatatypeNull_{p1}_{p2}_nok.c', replace)
+
+ # Generate code with an invalid datatype
+ replace = patterns
+ replace['shortdesc'] = 'Use of invalid datatype in point-to-point communication'
+ replace['longdesc'] = 'Point to point @{p1}@ and @{p2}@ have an invalid datatype'
+ replace['outcome'] = 'ERROR: InvalidDatatype'
+ replace['errormsg'] = 'Invalid datatype in P2P. @{p1}@ at @{filename}@:@{line:MBIERROR1}@ and @{p2}@ at @{filename}@:@{line:MBIERROR2}@ have an invalid datatype'
+ replace['change_arg'] = 'MPI_Type_contiguous (2, MPI_INT, &type); MPI_Type_commit(&type);MPI_Type_free(&type); /* MBIERROR3 */'
+ make_file(template, f'InvalidParam_Datatype_{p1}_{p2}_nok.c', replace)
+
+#################################
+# Generate code with tag mismatch
+#################################
+
+for p1 in allsend:
+ for p2 in allrecv:
+ patterns = {}
+ patterns = {'p1': p1, 'p2': p2}
+ patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.'
+ patterns['p2pfeature'] = 'Yes' if p1 in send + ssend + bsend or p2 in recv else 'Lacking'
+ patterns['ip2pfeature'] = 'Yes' if p1 in isend or p2 in irecv else 'Lacking'
+ patterns['persfeature'] = 'Yes' if p1 in psend or p2 in precv else 'Lacking'
+ patterns['p1'] = p1
+ patterns['p2'] = p2
+ patterns['init1'] = init[p1]("1")
+ patterns['init2'] = init[p2]("2")
+ patterns['start1'] = start[p1]("1")
+ patterns['start2'] = start[p2]("2")
+ patterns['fini1'] = fini[p1]("1")
+ patterns['fini2'] = fini[p2]("2")
+ patterns['operation1'] = operation[p1]("1") #send
+ patterns['operation2'] = operation[p2]("2") #recv
+ patterns['free1'] = free[p1]("1")
+ patterns['free2'] = free[p2]("2")
+ patterns['change_arg'] = ""
+
+ # Generate the incorrect tag matching
+ replace = patterns
+ replace['shortdesc'] = 'Point to point @{p1}@ and @{p2}@ have a tag mismatch'
+ replace['longdesc'] = 'Point to point @{p1}@ and @{p2}@ have a tag mismatch.'
+ replace['outcome'] = 'ERROR: TagMatching'
+ replace['errormsg'] = 'P2P tag mismatch. @{p1}@ at @{filename}@:@{line:MBIERROR1}@ and @{p2}@ at @{filename}@:@{line:MBIERROR2}@ use different tag.'
+ replace['change_arg'] = 'stag=0; rtag=1;/* MBIERROR */'
+ make_file(template, f'ParamMatching_Tag_{p1}_{p2}_nok.c', replace)
+
+ # Generate the code with an invalid tag
+ replace = patterns
+ replace['shortdesc'] = 'Point to point @{p1}@ and @{p2}@ have an invalid tag'
+ replace['longdesc'] = 'Point to point @{p1}@ and @{p2}@ have an invalid tag.'
+ replace['outcome'] = 'ERROR: InvalidTag'
+ replace['errormsg'] = 'Invalid Tag. @{p1}@ at @{filename}@:@{line:MBIERROR1}@ and @{p2}@ at @{filename}@:@{line:MBIERROR2}@ use an invalid tag.'
+ replace['change_arg'] = 'stag=-1; rtag=-2;/* MBIERROR */'
+ make_file(template, f'InvalidParam_Tag_{p1}_{p2}_nok.c', replace)
+
+ # Generate a correct code using MPI_ANY_TAG
+ replace = patterns
+ replace['shortdesc'] = 'Correct code'
+ replace['longdesc'] = 'Correct code'
+ replace['outcome'] = 'OK'
+ replace['errormsg'] = 'OK'
+ replace['change_arg'] = 'rtag=MPI_ANY_TAG;'
+ make_file(template, f'ParamMatching_Tag_{p1}_{p2}_ok.c', replace)
--- /dev/null
+#! /usr/bin/python3
+import os
+import sys
+from generator_utils import *
+
+template = """// @{generatedby}@
+/* ///////////////////////// The MPI Bugs Initiative ////////////////////////
+
+ Origin: @{origin}@
+
+ Description: @{shortdesc}@
+ @{longdesc}@
+
+ Version of MPI: Conforms to MPI 1.1, does not require MPI 2 implementation
+
+BEGIN_MPI_FEATURES
+ P2P!basic: @{p2pfeature}@
+ P2P!nonblocking: @{ip2pfeature}@
+ P2P!persistent: @{persfeature}@
+ COLL!basic: Lacking
+ COLL!nonblocking: Lacking
+ COLL!persistent: Lacking
+ COLL!tools: Yes
+ RMA: Lacking
+END_MPI_FEATURES
+
+BEGIN_MBI_TESTS
+ $ mpirun -np 2 ${EXE}
+ | @{outcome}@
+ | @{errormsg}@
+END_MBI_TESTS
+////////////////////// End of MBI headers /////////////////// */
+
+#include <mpi.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+int main(int argc, char **argv) {
+ int nprocs = -1;
+ int rank = -1;
+ int src=0, dest=1;
+ int stag = 0, rtag = 0;
+ int buff_size = 1;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ printf("Hello from rank %d \\n", rank);
+
+ if (nprocs < 2)
+ printf("MBI ERROR: This test needs at least 2 processes to produce a bug!\\n");
+
+ MPI_Datatype type = MPI_INT;
+ MPI_Comm newcom;
+ MPI_Comm_split(MPI_COMM_WORLD, 0, nprocs - rank, &newcom);
+ @{change_com}@
+ @{change_srcdest}@
+
+ @{init1}@
+ @{init2}@
+ if (rank == 0) {
+ @{operation1}@ /* MBIERROR1 */
+ @{start1}@
+ @{fini1}@
+ }else if (rank == 1) {
+ @{operation2}@ /* MBIERROR2 */
+ @{start2}@
+ @{fini2}@
+ }
+ @{free1}@
+ @{free2}@
+
+ if(newcom != MPI_COMM_NULL && newcom != MPI_COMM_WORLD)
+ MPI_Comm_free(&newcom);
+
+ MPI_Finalize();
+ printf("Rank %d finished normally\\n", rank);
+ return 0;
+}
+"""
+
+
+for p1 in send + isend + psend:
+ for p2 in recv + irecv + precv:
+ patterns = {}
+ patterns = {'p1': p1, 'p2': p2}
+ patterns['origin'] = "MBI"
+ patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.'
+ patterns['p2pfeature'] = 'Yes' if p1 in send or p2 in recv else 'Lacking'
+ patterns['ip2pfeature'] = 'Yes' if p1 in isend or p2 in irecv else 'Lacking'
+ patterns['persfeature'] = 'Yes' if p1 in psend or p2 in precv else 'Lacking'
+ patterns['p1'] = p1
+ patterns['p2'] = p2
+ patterns['init1'] = init[p1]("1")
+ patterns['init2'] = init[p2]("2")
+ patterns['start1'] = start[p1]("1")
+ patterns['start2'] = start[p2]("2")
+ patterns['fini1'] = fini[p1]("1")
+ patterns['fini2'] = fini[p2]("2")
+ patterns['operation1'] = operation[p1]("1") #send
+ patterns['operation2'] = operation[p2]("2") #recv
+ patterns['free1'] = free[p1]("1")
+ patterns['free2'] = free[p2]("2")
+ patterns['change_srcdest'] = ""
+
+ # Generate the incorrect matching
+ replace = patterns
+ replace['shortdesc'] = 'Point to point @{p1}@ and @{p2}@ have a communicator mismatch'
+ replace['longdesc'] = 'Process 1 uses newcom as the communicator while process 0 uses MPI_COMM_WORLD.'
+ replace['outcome'] = 'ERROR: CommunicatorMatching'
+ replace['errormsg'] = 'P2P Communicator mismatch. @{p1}@ at @{filename}@:@{line:MBIERROR1}@ and @{p2}@ at @{filename}@:@{line:MBIERROR2}@ have newcom or MPI_COMM_WORLD as a communicator.'
+ replace['change_com'] = 'if (rank==0)\n newcom = MPI_COMM_WORLD; /* MBIERROR */'
+ make_file(template, f'ParamMatching_Com_{p1}_{p2}_nok.c', replace)
+
+ # Generate the code with an invalid communicator
+ replace = patterns
+ replace['shortdesc'] = 'Point to point @{p1}@ and @{p2}@ have an invalid communicator'
+ replace['longdesc'] = 'Point to point @{p1}@ and @{p2}@ have an invalid communicator.'
+ replace['outcome'] = 'ERROR: InvalidCommunicator'
+ replace['errormsg'] = 'Invalid Communicator. @{p1}@ at @{filename}@:@{line:MBIERROR1}@ and @{p2}@ at @{filename}@:@{line:MBIERROR2}@ use a communicator that is freed line @{line:MBIERROR}@.'
+ replace['change_com'] = 'MPI_Comm_free(&newcom); /* MBIERROR */'
+ make_file(template, f'InvalidParam_Com_{p1}_{p2}_nok.c', replace)
+
+ # Generate the code with an invalid communicator ==> TO CHECK
+ #replace = patterns
+ #replace['shortdesc'] = 'Point to point @{p1}@ and @{p2}@ have an invalid communicator'
+ # replace['longdesc'] = 'Point to point @{p1}@ and @{p2}@ have an invalid communicator.'
+ # replace['outcome'] = 'ERROR: InvalidCommunicator'
+ # replace['errormsg'] = 'Invalid Communicator. @{p1}@ at @{filename}@:@{line:MBIERROR1}@ and @{p2}@ at @{filename}@:@{line:MBIERROR2}@ use different communicators'
+ # replace['origin'] = "MPI-Corrbench"
+ # replace['change_com'] = ""
+ # make_file(template, f'InvalidParam_Com_{p1}_{p2}_nok.c', replace)
+
+ # Generate the code with an invalid dest
+ replace = patterns
+ replace['origin'] = "MBI"
+ replace['shortdesc'] = 'Point to point @{p1}@ has an invalid argument'
+ replace['longdesc'] = 'Point to point @{p1}@ and @{p2}@ have an invalid communicator.'
+ replace['outcome'] = 'ERROR: InvalidSrcDest'
+ replace['errormsg'] = 'InvalidSrcDest. @{p1}@ at @{filename}@:@{line:MBIERROR1}@ performs a send with a dest not in communicator (dest is changed line @{line:MBIERROR}@).'
+ replace['change_com'] = ""
+ replace['change_srcdest'] = 'dest=4; /* MBIERROR */'
+ make_file(template, f'InvalidParam_Dest_{p1}_{p2}_nok.c', replace)
+
+ # Generate the code with an invalid src
+ replace = patterns
+ replace['shortdesc'] = 'Point to point @{p2}@ has an invalid argument'
+ replace['longdesc'] = 'Point to point @{p1}@ and @{p2}@ have an invalid communicator.'
+ replace['outcome'] = 'ERROR: InvalidSrcDest'
+ replace['errormsg'] = 'InvalidSrcDest. @{p2}@ at @{filename}@:@{line:MBIERROR2}@ performs a recv with a negative integer as source (src is changed line @{line:MBIERROR}@).'
+ replace['change_srcdest'] = 'src=-1; /* MBIERROR */'
+ make_file(template, f'InvalidParam_Src_{p1}_{p2}_nok.c', replace)
--- /dev/null
+#! /usr/bin/python3
+import os
+import sys
+from generator_utils import *
+
+template = """// @{generatedby}@
+/* ///////////////////////// The MPI Bugs Initiative ////////////////////////
+
+ Origin: @{origin}@
+
+ Description: @{shortdesc}@
+ @{longdesc}@
+
+ Version of MPI: Conforms to MPI 1.1, does not require MPI 2 implementation
+
+BEGIN_MPI_FEATURES
+ P2P!basic: @{p2pfeature}@
+ P2P!nonblocking: @{ip2pfeature}@
+ P2P!persistent: @{persfeature}@
+ COLL!basic: Lacking
+ COLL!nonblocking: Lacking
+ COLL!persistent: Lacking
+ COLL!tools: Yes
+ RMA: Lacking
+END_MPI_FEATURES
+
+BEGIN_MBI_TESTS
+ $ mpirun -np 2 ${EXE}
+ | @{outcome}@
+ | @{errormsg}@
+END_MBI_TESTS
+////////////////////// End of MBI headers /////////////////// */
+
+#include <mpi.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+int main(int argc, char **argv) {
+ int nprocs = -1;
+ int rank = -1;
+ int src=0, dest=1;
+ int stag = 0, rtag = 0;
+ int buff_size = 1;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ printf("Hello from rank %d \\n", rank);
+
+ MPI_Datatype type = MPI_INT;
+ MPI_Comm newcom = MPI_COMM_WORLD;
+
+ @{init1}@
+ @{init2}@
+ if (rank == 0) {
+ @{change_com1}@
+ @{operation1}@ /* MBIERROR1 */
+ @{start1}@
+ @{fini1}@
+ }else if (rank == 1) {
+ @{change_com2}@
+ @{operation2}@ /* MBIERROR2 */
+ @{start2}@
+ @{fini2}@
+ }
+ @{free1}@
+ @{free2}@
+
+ if(newcom != MPI_COMM_NULL && newcom != MPI_COMM_WORLD)
+ MPI_Comm_free(&newcom);
+
+ MPI_Finalize();
+ printf("Rank %d finished normally\\n", rank);
+ return 0;
+}
+"""
+
+
+for p1 in send + isend + psend:
+ for p2 in recv + irecv + precv:
+ patterns = {}
+ patterns = {'p1': p1, 'p2': p2}
+ patterns['origin'] = "MBI"
+ patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.'
+ patterns['p2pfeature'] = 'Yes' if p1 in send or p2 in recv else 'Lacking'
+ patterns['ip2pfeature'] = 'Yes' if p1 in isend or p2 in irecv else 'Lacking'
+ patterns['persfeature'] = 'Yes' if p1 in psend or p2 in precv else 'Lacking'
+ patterns['p1'] = p1
+ patterns['p2'] = p2
+ patterns['init1'] = init[p1]("1")
+ patterns['init2'] = init[p2]("2")
+ patterns['start1'] = start[p1]("1")
+ patterns['start2'] = start[p2]("2")
+ patterns['fini1'] = fini[p1]("1")
+ patterns['fini2'] = fini[p2]("2")
+ patterns['operation1'] = operation[p1]("1") #send
+ patterns['operation2'] = operation[p2]("2") #recv
+ patterns['free1'] = free[p1]("1")
+ patterns['free2'] = free[p2]("2")
+ patterns['change_com1'] = ""
+ patterns['change_com2'] = ""
+
+ replace = patterns
+ replace['origin'] = "inspired from MPI-Corrbench"
+ replace['shortdesc'] = 'Point to point @{p2}@ has an invalid communicator'
+ replace['longdesc'] = 'MPI_COMM_NULL used in point to point @{p2}@'
+ replace['outcome'] = 'ERROR: InvalidCommunicator'
+ replace['errormsg'] = 'Invalid Communicator. @{p2}@ at @{filename}@:@{line:MBIERROR2}@ uses a null communicator.'
+ replace['change_com2'] = 'newcom = MPI_COMM_NULL;'
+ make_file(template, f'InvalidParam_ComNull_{p2}_{p1}nok.c', replace)
+
+ replace = patterns
+ replace['shortdesc'] = 'Point to point @{p2}@ has an invalid communicator'
+ replace['longdesc'] = 'MPI_COMM_NULL used in point to point @{p2}@'
+ replace['outcome'] = 'ERROR: InvalidCommunicator'
+ replace['errormsg'] = 'Invalid Communicator. @{p1}@ at @{filename}@:@{line:MBIERROR1}@ uses a null communicator.'
+ replace['change_com1'] = 'newcom = MPI_COMM_NULL;'
+ replace['change_com2'] = ""
+ make_file(template, f'InvalidParam_ComNull_{p1}_{p2}nok.c', replace)
+
--- /dev/null
+#! /usr/bin/python3
+import os
+import sys
+from generator_utils import *
+
+template = """// @{generatedby}@
+/* ///////////////////////// The MPI Bugs Initiative ////////////////////////
+
+ Origin: MBI
+
+ Description: @{shortdesc}@
+ @{longdesc}@
+
+ Version of MPI: Conforms to MPI 1.1, does not require MPI 2 implementation
+
+BEGIN_MPI_FEATURES
+ P2P!basic: @{p2pfeature}@
+ P2P!nonblocking: @{ip2pfeature}@
+ P2P!persistent: @{persfeature}@
+ COLL!basic: Lacking
+ COLL!nonblocking: Lacking
+ COLL!persistent: Lacking
+ COLL!tools: Lacking
+ RMA: Lacking
+END_MPI_FEATURES
+
+BEGIN_MBI_TESTS
+ $ mpirun -np 2 ${EXE}
+ | @{outcome}@
+ | @{errormsg}@
+END_MBI_TESTS
+////////////////////// End of MBI headers /////////////////// */
+
+#include <mpi.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+int main(int argc, char **argv) {
+ int nprocs = -1;
+ int rank = -1;
+ int dest=0, src=0;
+ int stag = 0, rtag = 0;
+ int buff_size = 1;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ printf("Hello from rank %d \\n", rank);
+
+ if (nprocs < 2)
+ printf("MBI ERROR: This test needs at least 2 processes to produce a bug!\\n");
+
+ MPI_Comm newcom = MPI_COMM_WORLD;
+ MPI_Datatype type = MPI_INT;
+
+ @{init1}@
+ @{init2}@
+ if (rank == 0) {
+ dest = 1; src = 1;
+ @{operation1}@
+ @{start1}@
+ @{write1}@ /* MBIERROR1 */
+ @{fini1}@
+ @{free1}@
+ }else if (rank == 1){
+ dest = 0; src = 0;
+ @{operation2}@
+ @{start2}@
+ @{write2}@ /* MBIERROR2 */
+ @{fini2}@
+ @{free2}@
+ }
+
+ MPI_Finalize();
+ printf("Rank %d finished normally\\n", rank);
+ return 0;
+}
+"""
+
+
+for s in send + isend + psend:
+ for r in irecv + precv + recv:
+ patterns = {}
+ patterns = {'s': s, 'r': r}
+ patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.'
+ patterns['p2pfeature'] = 'Yes' if s in send else 'Lacking'
+ patterns['ip2pfeature'] = 'Yes' if r in irecv else 'Lacking'
+ patterns['persfeature'] = 'Yes' if r in precv else 'Lacking'
+ patterns['s'] = s
+ patterns['r'] = r
+ patterns['init1'] = init[s]("1")
+ patterns['init2'] = init[r]("2")
+ patterns['fini1'] = fini[s]("1")
+ patterns['fini2'] = fini[r]("2")
+ patterns['start1'] = start[s]("1")
+ patterns['start2'] = start[r]("2")
+ patterns['operation1'] = operation[s]("1")
+ patterns['operation2'] = operation[r]("2")
+ patterns['write1'] = write[s]("1")
+ patterns['write2'] = write[r]("2")
+ patterns['free1'] = free[s]("1")
+ patterns['free2'] = free[r]("2")
+
+ # Generate a message race
+ if s in send and r in irecv + precv:
+ replace = patterns
+ replace['shortdesc'] = ' Local Concurrency with a P2P'
+ replace['longdesc'] = f'The message buffer in {r} is modified before the call has been completed.'
+ replace['outcome'] = 'ERROR: LocalConcurrency'
+ replace['errormsg'] = 'Local Concurrency with a P2P. The receive buffer in @{r}@ is modified at @{filename}@:@{line:MBIERROR2}@ whereas there is no guarantee the message has been received.'
+ make_file(template, f'LocalConcurrency_{r}_{s}_nok.c', replace)
+ if s in isend + psend and r in recv:
+ replace = patterns
+ replace['shortdesc'] = ' Local Concurrency with a P2P'
+ replace['longdesc'] = f'The message buffer in {s} is modified before the call has been completed.'
+ replace['outcome'] = 'ERROR: LocalConcurrency'
+ replace['errormsg'] = 'Local Concurrency with a P2P. The send buffer in @{s}@ is modified at @{filename}@:@{line:MBIERROR1}@ whereas there is no guarantee the message has been sent.'
+ make_file(template, f'LocalConcurrency_{r}_{s}_nok.c', replace)
+ if s in isend + psend and r in irecv + precv:
+ replace = patterns
+ replace['shortdesc'] = ' Local Concurrency with a P2P'
+ replace['longdesc'] = f'The message buffer in {s} and {r} are modified before the calls have completed.'
+ replace['outcome'] = 'ERROR: LocalConcurrency'
+ replace['errormsg'] = 'Local Concurrency with a P2P. The message buffers in @{s}@ and @{r}@ are modified at @{filename}@:@{line:MBIERROR1}@ and @{filename}@:@{line:MBIERROR2}@ whereas there is no guarantee the calls have been completed.'
+ make_file(template, f'LocalConcurrency_{r}_{s}_nok.c', replace)
--- /dev/null
+#! /usr/bin/python3
+import os
+import sys
+from generator_utils import *
+
+template = """// @{generatedby}@
+/* ///////////////////////// The MPI Bugs Initiative ////////////////////////
+
+ Origin: MBI
+
+ Description: @{shortdesc}@
+ @{longdesc}@
+
+ Version of MPI: Conforms to MPI 1.1, does not require MPI 2 implementation
+
+BEGIN_MPI_FEATURES
+ P2P!basic: @{p2pfeature}@
+ P2P!nonblocking: @{ip2pfeature}@
+ P2P!persistent: Lacking
+ COLL!basic: Lacking
+ COLL!nonblocking: Lacking
+ COLL!persistent: Lacking
+ COLL!tools: Lacking
+ RMA: Lacking
+END_MPI_FEATURES
+
+BEGIN_MBI_TESTS
+ $ mpirun -np 4 ${EXE}
+ | @{outcome}@
+ | @{errormsg}@
+END_MBI_TESTS
+////////////////////// End of MBI headers /////////////////// */
+
+#include <mpi.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+int main(int argc, char **argv) {
+ int nprocs = -1;
+ int rank = -1;
+ int src=MPI_ANY_SOURCE, dest=0;
+ int stag = 42, rtag = MPI_ANY_TAG;
+ int buff_size = 1;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ printf("Hello from rank %d \\n", rank);
+
+ if (nprocs < 2)
+ printf("MBI ERROR: This test needs at least 2 processes to produce a bug!\\n");
+
+ int recv_buffer=-1;
+ int send_buffer=rank;
+
+ MPI_Datatype type = MPI_INT;
+ MPI_Comm newcom = MPI_COMM_WORLD;
+
+ @{init1}@
+ @{init2}@
+
+ if (rank == 0) {
+ for (int i = 0; i < nprocs - 1; i++) {
+ @{operation1}@ /* MBIERROR */
+ @{fini1}@
+ }
+ if (@{cond}@ != 3) {
+ printf("MBI_MSG_RACE: The last received message is not 3 but %d!\\n", recv_buffer);
+ fflush(stdout);
+ abort();
+ }
+ }else{
+ @{operation2}@
+ @{fini2}@
+ }
+
+
+ MPI_Finalize();
+ printf("Rank %d finished normally\\n", rank);
+ return 0;
+}
+"""
+
+
+for s in send + isend:
+ for r in recv + irecv:
+ patterns = {}
+ patterns = {'s': s, 'r': r}
+ patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.'
+ patterns['p2pfeature'] = 'Yes' if s in send or r in recv else 'Lacking'
+ patterns['ip2pfeature'] = 'Yes' if s in isend or r in irecv else 'Lacking'
+ patterns['s'] = s
+ patterns['r'] = r
+ patterns['cond'] = 'buf1'
+ patterns['init2'] = init[s]("2")
+ patterns['init1'] = init[r]("1")
+ patterns['fini2'] = fini[s]("2")
+ patterns['fini1'] = fini[r]("1")
+ patterns['operation2'] = operation[s]("2")
+ patterns['operation1'] = operation[r]("1")
+
+ # Generate the incorrect matching
+ replace = patterns
+ replace['shortdesc'] = 'The message ordering is non-deterministic.'
+ replace['longdesc'] = f'The code assumes a fixed order in the reception of messages while the message ordering is non-deterministic.'
+ replace['outcome'] = 'ERROR: MessageRace'
+ replace['errormsg'] = 'P2P message race which can cause a deadlock. @{r}@ at @{filename}@:@{line:MBIERROR}@ is called with ANY_SRC.'
+ make_file(template, f'MessageRace_{r}_{s}_nok.c', replace)
+
--- /dev/null
+#! /usr/bin/python3
+import os
+import sys
+from generator_utils import *
+
+template = """// @{generatedby}@
+/* ///////////////////////// The MPI Bugs Initiative ////////////////////////
+
+ Origin: MBI
+
+ Description: @{shortdesc}@
+ @{longdesc}@
+
+ Version of MPI: Conforms to MPI 1.1, does not require MPI 2 implementation
+
+BEGIN_MPI_FEATURES
+ P2P!basic: @{p2pfeature}@
+ P2P!nonblocking: @{ip2pfeature}@
+ P2P!persistent: @{persfeature}0@
+ COLL!basic: Lacking
+ COLL!nonblocking: Lacking
+ COLL!persistent: Lacking
+ COLL!tools: Lacking
+ RMA: Lacking
+END_MPI_FEATURES
+
+BEGIN_MBI_TESTS
+ $ mpirun -np 2 ${EXE}
+ | @{outcome}@
+ | @{errormsg}@
+END_MBI_TESTS
+////////////////////// End of MBI headers /////////////////// */
+
+#include <mpi.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define buff_size 128
+
+int main(int argc, char **argv) {
+ int nprocs = -1;
+ int rank = -1;
+ int its_raining = 0;
+ int src=0, dest=1;
+ int stag=0, rtag=0;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ printf("Hello from rank %d \\n", rank);
+
+ if (nprocs < 2)
+ printf("MBI ERROR: This test needs at least 2 processes to produce a bug!\\n");
+
+ MPI_Comm newcom = MPI_COMM_WORLD;
+ MPI_Datatype type = MPI_INT;
+
+ @{init1}@
+ @{init2}@
+ if (rank == 0) {
+ @{operation1}@ /* MBIERROR1 */
+ @{fini1}@
+ }else if (@{change_cond}@){
+ @{operation2}@ /* MBIERROR2 */
+ @{fini2}@
+ }
+
+ MPI_Finalize();
+ printf("Rank %d finished normally\\n", rank);
+ return 0;
+}
+"""
+
+
+for p in send + ssend + bsend + recv + irecv + isend:
+ patterns = {}
+ patterns = {'p': p}
+ patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.'
+ patterns['p2pfeature'] = 'Yes' if p in send + bsend + ssend + recv else 'Lacking'
+ patterns['ip2pfeature'] = 'Yes' if p in isend + irecv else 'Lacking'
+ patterns['persfeature'] = 'Lacking'
+ #patterns['persfeature'] = 'Yes' if p in psend + precv else 'Lacking'
+ patterns['p'] = p
+ patterns['init1'] = init[p]("1")
+ patterns['init2'] = '' #init[p2]("2")
+ patterns['fini1'] = fini[p]("1")
+ patterns['fini2'] = '' #fini[p2]("2")
+ patterns['operation1'] = operation[p]("1")
+ patterns['operation2'] = '' #operation[p2]("2")
+ patterns['change_cond'] = 'rank == 1'
+
+ # Generate the incorrect matching with one call
+ replace = patterns
+ replace['shortdesc'] = 'Point to point @{p}@ is not matched'
+ replace['longdesc'] = 'Process 0 calls @{p}@ and is not matched'
+ replace['outcome'] = 'ERROR: CallMatching'
+ replace['errormsg'] = 'P2P mistmatch. @{p}@ at @{filename}@:@{line:MBIERROR1}@ is not matched.'
+ make_file(template, f'CallOrdering_{p}_nok.c', replace)
+
+ # Generate the incorrect matching with two calls
+ replace = patterns
+ replace['shortdesc'] = 'Both point to point @{p}@ are not matched'
+ replace['longdesc'] = 'Processes 0 and 1 both call @{p}@ which are not matched'
+ replace['outcome'] = 'ERROR: CallMatching'
+ replace['errormsg'] = 'P2P mismatch. @{p}@ at @{filename}@:@{line:MBIERROR1}@ and @{p}@ at @{filename}@:@{line:MBIERROR2}@ are not matched.'
+ replace['operation2'] = operation[p]("1")
+ replace['fini2'] = fini[p]("1")
+ make_file(template, f'CallOrdering_{p}_{p}_nok.c', replace)
+
+for s in send + isend + ssend + bsend:
+ for r in recv + irecv:
+ patterns = {}
+ patterns = {'s': s, 'r': r}
+ patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.'
+ patterns['p2pfeature'] = 'Yes' if s in send or r in recv else 'Lacking'
+ patterns['ip2pfeature'] = 'Yes' if s in isend or r in irecv else 'Lacking'
+ patterns['s'] = s
+ patterns['r'] = r
+ patterns['init1'] = init[s]("1")
+ patterns['init2'] = init[r]("2")
+ patterns['fini1'] = fini[s]("1")
+ patterns['fini2'] = fini[r]("2")
+ patterns['operation1'] = operation[s]("1")
+ patterns['operation2'] = operation[r]("2")
+ patterns['change_cond'] = '(rank == 1) && (its_raining)'
+
+ # Generate the incorrect matching because of the conditional
+ replace = patterns
+ replace['shortdesc'] = 'Point to point @{r}@ is never called.'
+ replace['longdesc'] = 'Point to point @{r}@ is never executed. Process 1 calls MPI_Finalize and causes a deadlock.'
+ replace['outcome'] = 'ERROR: CallMatching'
+ replace['errormsg'] = 'P2P mistmatch. @{r}@ at @{filename}@:@{line:MBIERROR2}@ is never called because of the conditional (@{change_cond}@).'
+ replace['operation1'] = operation[s]("1")
+ replace['operation2'] = operation[r]("2")
+ make_file(template, f'CallOrdering_{r}_{s}_nok.c', replace)
+
--- /dev/null
+#! /usr/bin/python3
+import os
+import sys
+from generator_utils import *
+
+template = """// @{generatedby}@
+/* ///////////////////////// The MPI Bugs Initiative ////////////////////////
+
+ Origin: MBI
+
+ Description: @{shortdesc}@
+ @{longdesc}@
+
+ Version of MPI: Conforms to MPI 1.1, does not require MPI 2 implementation
+
+BEGIN_MPI_FEATURES
+ P2P!basic: @{p2pfeature}@
+ P2P!nonblocking: @{ip2pfeature}@
+ P2P!persistent: Lacking
+ COLL!basic: Lacking
+ COLL!nonblocking: Lacking
+ COLL!persistent: Lacking
+ COLL!tools: Lacking
+ RMA: Lacking
+END_MPI_FEATURES
+
+BEGIN_MBI_TESTS
+ $ mpirun -np 2 ${EXE}
+ | @{outcome}@
+ | @{errormsg}@
+END_MBI_TESTS
+////////////////////// End of MBI headers /////////////////// */
+
+#include <mpi.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+int main(int argc, char **argv) {
+ int nprocs = -1;
+ int rank = -1;
+ MPI_Status sta;
+ int src,dest;
+ int stag=0, rtag=0;
+ int buff_size = 1;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ printf("Hello from rank %d \\n", rank);
+
+ if (nprocs < 2)
+ printf("MBI ERROR: This test needs at least 2 processes to produce a bug!\\n");
+
+ MPI_Comm newcom = MPI_COMM_WORLD;
+ MPI_Datatype type = MPI_INT;
+
+ @{init1a}@
+ @{init1b}@
+ @{init1c}@
+ @{init2a}@
+ @{init2b}@
+ @{init2c}@
+
+ if (rank == 0) {
+ dest=1, src=1;
+ @{operation1a}@ /* MBIERROR1 */
+ @{operation1b}@
+ @{operation1c}@
+ @{fini1a}@
+ @{fini1b}@
+ @{fini1c}@
+ }else if (rank == 1){
+ dest=0, src=0;
+ @{operation2a}@ /* MBIERROR2 */
+ @{operation2b}@
+ @{operation2c}@
+ @{fini2a}@
+ @{fini2b}@
+ @{fini2c}@
+ }
+ @{free1a}@
+ @{free1b}@
+ @{free1c}@
+ @{free2a}@
+ @{free2b}@
+ @{free2c}@
+
+ MPI_Finalize();
+ printf("Rank %d finished normally\\n", rank);
+ return 0;
+}
+"""
+
+
+for p in probe:
+ for s in send + isend:
+ for r in recv + irecv:
+ patterns = {}
+ patterns = {'p':p, 's': s, 'r': r}
+ patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.'
+ patterns['p2pfeature'] = 'Yes' if s in send or r in recv else 'Lacking'
+ patterns['ip2pfeature'] = 'Yes' if s in isend or r in irecv else 'Lacking'
+ patterns['s'] = s
+ patterns['r'] = r
+ patterns['p'] = p
+ patterns['init1a'] = init[p]("1")
+ patterns['init1b'] = init[s]("1")
+ patterns['init1c'] = init[r]("2")
+ patterns['init2a'] = init[p]("1")
+ patterns['init2b'] = init[r]("3")
+ patterns['init2c'] = init[s]("4")
+ patterns['fini1a'] = fini[p]("1")
+ patterns['fini1b'] = fini[s]("1")
+ patterns['fini1c'] = fini[r]("2")
+ patterns['fini2a'] = fini[p]("1")
+ patterns['fini2b'] = fini[r]("3")
+ patterns['fini2c'] = fini[s]("4")
+ patterns['free1a'] = free[p]("1")
+ patterns['free1b'] = free[s]("1")
+ patterns['free1c'] = free[r]("2")
+ patterns['free2a'] = free[p]("1")
+ patterns['free2b'] = free[r]("3")
+ patterns['free2c'] = free[s]("4")
+ patterns['operation1a'] = operation[p]("1")
+ patterns['operation1b'] = operation[s]("1")
+ patterns['operation1c'] = operation[r]("2")
+ patterns['operation2a'] = operation[p]("1")
+ patterns['operation2b'] = operation[r]("3")
+ patterns['operation2c'] = operation[s]("4")
+
+ # Generate the incorrect matching
+ replace = patterns
+ replace['shortdesc'] = 'MPI_Probe is called before MPI_Recv.'
+ replace['longdesc'] = 'MPI_Probe is a blocking call that returns only after a matching message has been found. By calling MPI_Probe before MPI_Recv, a deadlock is created.'
+ replace['outcome'] = 'ERROR: CallMatching'
+ replace['errormsg'] = 'P2P mistmatch. @{p}@ at @{filename}@:@{line:MBIERROR1}@ and @{filename}@:@{line:MBIERROR2}@ are called before @{r}@.'
+ make_file(template, f'CallOrdering_{p}_{r}_{s}_nok.c', replace)
+
+ # Generate a correct matching
+ replace = patterns
+ replace['shortdesc'] = 'Correct use of MPI_Probe.'
+ replace['longdesc'] = 'Correct use of MPI_Probe.'
+ replace['outcome'] = 'OK'
+ replace['errormsg'] = 'OK'
+ replace['operation1a'] = operation[s]("1")
+ replace['operation1b'] = operation[p]("1")
+ make_file(template, f'CallOrdering_{p}_{r}_{s}_ok.c', replace)
--- /dev/null
+#! /usr/bin/python3
+import os
+import sys
+from generator_utils import *
+
+template = """// @{generatedby}@
+/* ///////////////////////// The MPI Bugs Initiative ////////////////////////
+
+ Origin: @{origin}@
+
+ Description: @{shortdesc}@
+ @{longdesc}@
+
+
+BEGIN_MPI_FEATURES
+ P2P!basic: Lacking
+ P2P!nonblocking: Lacking
+ P2P!persistent: Lacking
+ COLL!basic: Lacking
+ COLL!nonblocking: Lacking
+ COLL!persistent: Lacking
+ COLL!tools: Lacking
+ RMA: @{rmafeature}@
+END_MPI_FEATURES
+
+BEGIN_MBI_TESTS
+ $ mpirun -np 2 ${EXE}
+ | @{outcome}@
+ | @{errormsg}@
+END_MBI_TESTS
+////////////////////// End of MBI headers /////////////////// */
+
+#include <mpi.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define N 10
+
+int main(int argc, char **argv) {
+ int rank, numProcs;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_size(MPI_COMM_WORLD, &numProcs);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+ int *winbuf = malloc(N * sizeof(int));
+
+ MPI_Win win;
+ MPI_Win_create(&winbuf, N * sizeof(int), 1, MPI_INFO_NULL, MPI_COMM_WORLD, &win);
+
+ MPI_Datatype type = MPI_INT;
+ int target = (rank + 1) % numProcs;
+
+ if(rank == 0){
+ @{epoch}@
+ @{change_arg}@
+ @{init}@
+ @{operation}@ /* MBIERROR2 */
+
+ @{finEpoch}@
+ } else {
+ @{epoch}@
+
+ @{finEpoch}@
+ }
+
+ MPI_Win_free(&win);
+
+ free(winbuf);
+
+ MPI_Finalize();
+ return 0;
+}
+"""
+
+
+for e in epoch:
+ for p in rma:
+ patterns = {}
+ patterns = {'e': e, 'p': p}
+ patterns['origin'] = "MBI"
+ patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.'
+ patterns['rmafeature'] = 'Yes'
+ patterns['p'] = p
+ patterns['e'] = e
+ patterns['epoch'] = epoch[e]("1")
+ patterns['finEpoch'] = finEpoch[e]("1")
+ patterns['init'] = init[p]("1")
+ patterns['operation'] = operation[p]("1")
+ patterns['change_arg'] = ""
+
+ # Generate a code with a null type
+ replace = patterns
+ replace['shortdesc'] = 'Invalid argument in one-sided operation.'
+ replace['longdesc'] = 'A one-sided operation has MPI_DATATYPE_NULL as a type.'
+ replace['outcome'] = 'ERROR: InvalidDatatype'
+ replace['change_arg'] = 'type = MPI_DATATYPE_NULL;'
+ replace['errormsg'] = '@{p}@ at @{filename}@:@{line:MBIERROR}@ has MPI_DATATYPE_NULL as a type'
+ make_file(template, f'InvalidParam_BufferNullCond_{e}_{p}_nok.c', replace)
+
+ # Generate a code with an invalid type
+ replace = patterns
+ replace['shortdesc'] = 'Invalid argument in one-sided operation.'
+ replace['longdesc'] = 'Use of an invalid datatype in one-sided operation.'
+ replace['outcome'] = 'ERROR: InvalidDatatype'
+ replace['change_arg'] = 'MPI_Type_contiguous (2, MPI_INT, &type); MPI_Type_commit(&type);MPI_Type_free(&type); /* MBIERROR2 */'
+ replace['errormsg'] = 'Invalid Datatype in @{p}@ at @{filename}@:@{line:MBIERROR}@'
+ make_file(template, f'InvalidParam_DatatypeCond_{e}_{p}_nok.c', replace)
+
--- /dev/null
+#! /usr/bin/python3
+import os
+import sys
+from generator_utils import *
+
+template = """// @{generatedby}@
+/* ///////////////////////// The MPI Bugs Initiative ////////////////////////
+
+ Origin: @{origin}@
+
+ Description: @{shortdesc}@
+ @{longdesc}@
+
+ Version of MPI: Conforms to MPI 1.1, does not require MPI 2 implementation
+
+BEGIN_MPI_FEATURES
+ P2P!basic: Lacking
+ P2P!nonblocking: Lacking
+ P2P!persistent: Lacking
+ COLL!basic: Lacking
+ COLL!nonblocking: Lacking
+ COLL!persistent: Lacking
+ COLL!tools: Lacking
+ RMA: @{rmafeature}@
+END_MPI_FEATURES
+
+BEGIN_MBI_TESTS
+ $ mpirun -np 2 ${EXE}
+ | @{outcome}@
+ | @{errormsg}@
+END_MBI_TESTS
+////////////////////// End of MBI headers /////////////////// */
+
+#include <mpi.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define N 10
+
+int main(int argc, char **argv) {
+ int nprocs = -1 , rank = -1;
+ MPI_Win win;
+ int *winbuf = @{malloc}@ // Window buffer
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+ if (nprocs < 2)
+ printf("MBI ERROR: This test needs at least 2 processes to produce a bug!\\n");
+
+ MPI_Datatype type = MPI_INT;
+ int target = (rank + 1) % nprocs;
+
+ MPI_Win_create(winbuf, N * sizeof(int), 1, MPI_INFO_NULL, MPI_COMM_WORLD, &win);
+
+
+ @{epoch}@
+
+ @{init}@
+ @{change_arg}@
+ @{operation}@ /* MBIERROR */
+
+ @{finEpoch}@
+
+ MPI_Win_free(&win);
+ free(winbuf);
+
+ MPI_Finalize();
+ printf("Rank %d finished normally\\n", rank);
+ return 0;
+}
+"""
+
+
+for e in epoch:
+ for p in rma:
+ patterns = {}
+ patterns = {'e': e, 'p': p}
+ patterns['origin'] = "MBI"
+ patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.'
+ patterns['rmafeature'] = 'Yes'
+ patterns['p'] = p
+ patterns['e'] = e
+ patterns['epoch'] = epoch[e]("1")
+ patterns['finEpoch'] = finEpoch[e]("1")
+ patterns['init'] = init[p]("1")
+ patterns['operation'] = operation[p]("1")
+ patterns['change_arg'] = ""
+ patterns['malloc'] = "malloc(N * sizeof(int));"
+
+ # Generate a code with a null type
+ replace = patterns
+ replace['shortdesc'] = 'Invalid argument in one-sided operation.'
+ replace['longdesc'] = 'A one-sided operation has MPI_DATATYPE_NULL as a type.'
+ replace['outcome'] = 'ERROR: InvalidDatatype'
+ replace['change_arg'] = 'type = MPI_DATATYPE_NULL;'
+ replace['errormsg'] = '@{p}@ at @{filename}@:@{line:MBIERROR}@ has MPI_DATATYPE_NULL as a type'
+ make_file(template, f'InvalidParam_DatatypeNull_{e}_{p}_nok.c', replace)
+
+ # Generate a code with a null buffer (move to RMAWinBufferGenerator)
+ # replace = patterns
+ # replace['origin'] = 'MPI-Corrbench'
+ # replace['shortdesc'] = 'nullptr is invalid in one-sided operation.'
+ # replace['longdesc'] = 'A one-sided operation has an invalid buffer.'
+ # replace['outcome'] = 'ERROR: InvalidBuffer'
+ # replace['init'] = 'int * localbuf1 = malloc(sizeof(int));'
+ # replace['change_arg'] = 'localbuf1 = NULL;'
+ # replace['operation'] = operation[p]("1").replace('&localbuf1', 'localbuf1')
+ # replace['errormsg'] = '@{p}@ at @{filename}@:@{line:MBIERROR}@ has an invalid buffer'
+ # make_file(template, f'InvalidParam_BufferNull_{e}_{p}_nok.c', replace)
+
+ # Generate a code with an invalid type
+ replace = patterns
+ replace['origin'] = 'MBI'
+ replace['shortdesc'] = 'Invalid argument in one-sided operation.'
+ replace['longdesc'] = 'Use of an invalid datatype in one-sided operation.'
+ replace['outcome'] = 'ERROR: InvalidDatatype'
+ replace['change_arg'] = 'MPI_Type_contiguous (2, MPI_INT, &type); MPI_Type_commit(&type);MPI_Type_free(&type); /* MBIERROR2 */'
+ replace['errormsg'] = 'Invalid Datatype in @{p}@ at @{filename}@:@{line:MBIERROR}@'
+ make_file(template, f'InvalidParam_Datatype_{e}_{p}_nok.c', replace)
+
+ # Generate a code with invalid buffer
+ replace = patterns
+ patterns['origin'] = "MPI-Corrbench"
+ replace['shortdesc'] = 'Invalid invalid buffer (buffer must be allocated)'
+ replace['longdesc'] = 'Use of an invalid buffer in MPI_Win_create.'
+ replace['outcome'] = 'ERROR: InvalidBuffer'
+ patterns['malloc'] = "NULL; /* MBIERROR2 */"
+ patterns['operation'] = ""
+ replace['change_arg'] = ""
+ replace['errormsg'] = 'Invalid buffer in Win_create at @{filename}@:@{line:MBIERROR2}@'
+ make_file(template, f'InvalidParam_InvalidBufferWinCreate_{e}_{p}_nok.c', replace)
--- /dev/null
+#! /usr/bin/python3
+import os
+import sys
+from generator_utils import *
+
+template = """// @{generatedby}@
+/* ///////////////////////// The MPI Bugs Initiative ////////////////////////
+
+ Origin: MBI
+
+ Description: @{shortdesc}@
+ @{longdesc}@
+
+ Version of MPI: Conforms to MPI 2, requires MPI 3 implementation (for lock_all/unlock_all epochs)
+
+BEGIN_MPI_FEATURES
+ P2P!basic: Lacking
+ P2P!nonblocking: Lacking
+ P2P!persistent: Lacking
+ COLL!basic: Lacking
+ COLL!nonblocking: Lacking
+ COLL!persistent: Lacking
+ COLL!tools: Lacking
+ RMA: @{rmafeature}@
+END_MPI_FEATURES
+
+BEGIN_MBI_TESTS
+ $ mpirun -np 2 ${EXE}
+ | @{outcome}@
+ | @{errormsg}@
+END_MBI_TESTS
+////////////////////// End of MBI headers /////////////////// */
+
+#include <mpi.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define N 1
+
+int main(int argc, char **argv) {
+ int nprocs = -1;
+ int rank = -1;
+ MPI_Win win;
+ int winbuf[100] = {0};
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ printf("Hello from rank %d \\n", rank);
+
+ if (nprocs < 2)
+ printf("MBI ERROR: This test needs at least 2 processes to produce a bug!\\n");
+
+ MPI_Datatype type = MPI_INT;
+ int target = 1;
+
+ MPI_Win_create(&winbuf, 100 * sizeof(int), sizeof(int), MPI_INFO_NULL, MPI_COMM_WORLD, &win);
+
+ winbuf[0] = 12345;
+ @{init1}@
+
+ @{epoch}@
+
+ if (rank == 0) {
+ @{operation1}@ /* MBIERROR1 */
+ @{operation2}@ /* MBIERROR2 */
+ }
+
+ @{finEpoch}@
+
+ MPI_Win_free(&win);
+
+ MPI_Finalize();
+ return 0;
+}
+"""
+
+
+for e in epoch:
+ for p1 in get:
+ for p2 in put + store + load + get + loadstore:
+ patterns = {}
+ patterns = {'e': e, 'p1': p1, 'p2': p2}
+ patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.'
+ patterns['rmafeature'] = 'Yes'
+ patterns['p1'] = p1
+ patterns['p2'] = p2
+ patterns['e'] = e
+ patterns['epoch'] = epoch[e]("1")
+ patterns['finEpoch'] = finEpoch[e]("1")
+ patterns['init1'] = init[p1]("1")
+ patterns['operation1'] = operation[p1]("1")
+ patterns['operation2'] = operation[p2]("1")
+
+ # Generate a data race (Get + Get/load/store/Put)
+ replace = patterns
+ replace['shortdesc'] = 'Local Concurrency error.'
+ replace['longdesc'] = 'Local Concurrency error. @{p2}@ conflicts with @{p1}@'
+ replace['outcome'] = 'ERROR: LocalConcurrency'
+ replace['errormsg'] = 'Local Concurrency error. @{p2}@ at @{filename}@:@{line:MBIERROR2}@ conflicts with @{p1}@ line @{line:MBIERROR1}@'
+ make_file(template, f'LocalConcurrency_lloutwindow_{e}_{p1}_{p2}_nok.c', replace)
+ # Generate a correct code by switching operation1 and operation2
+ if p2 in store + load + loadstore:
+ replace = patterns
+ replace['shortdesc'] = 'Correct code using RMA operations'
+ replace['longdesc'] = 'Correct code using RMA operations'
+ replace['outcome'] = 'OK'
+ replace['errormsg'] = 'OK'
+ replace['operation1'] = operation[p2]("1")
+ replace['operation2'] = operation[p1]("1")
+ make_file(template, f'LocalConcurrency_lloutwindow_{e}_{p2}_{p1}_ok.c', replace)
+ # Generate a correct code by removing operation2
+ replace = patterns
+ replace['shortdesc'] = 'Correct code using RMA operations'
+ replace['longdesc'] = 'Correct code using RMA operations'
+ replace['outcome'] = 'OK'
+ replace['errormsg'] = 'OK'
+ replace['operation1'] = operation[p1]("1")
+ replace['operation2'] = ''
+ make_file(template, f'LocalConcurrency_{e}_{p1}_ok.c', replace)
+
+
+for e in epoch:
+ for p1 in put:
+ for p2 in store:
+ patterns = {}
+ patterns = {'e': e, 'p1': p1, 'p2': p2}
+ patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.'
+ patterns['rmafeature'] = 'Yes'
+ patterns['p1'] = p1
+ patterns['p2'] = p2
+ patterns['e'] = e
+ patterns['epoch'] = epoch[e]("1")
+ patterns['finEpoch'] = finEpoch[e]("1")
+ patterns['init1'] = init[p1]("1")
+ patterns['operation1'] = operation[p1]("1")
+ patterns['operation2'] = operation[p2]("1")
+
+ # Generate a data race (Put + store)
+ replace = patterns
+ replace['shortdesc'] = 'Local Concurrency error.'
+ replace['longdesc'] = 'Local Concurrency error. @{p2}@ conflicts with @{p1}@'
+ replace['outcome'] = 'ERROR: LocalConcurrency'
+ replace['errormsg'] = 'Local Concurrency error. @{p2}@ at @{filename}@:@{line:MBIERROR2}@ conflicts with @{p1}@ line @{line:MBIERROR1}@'
+ make_file(template, f'LocalConcurrency_lloutwindow_{e}_{p1}_{p2}_nok.c', replace)
+ # Generate a correct code by switching operation1 and operation2
+ replace = patterns
+ replace['shortdesc'] = 'Correct code using RMA operations'
+ replace['longdesc'] = 'Correct code using RMA operations'
+ replace['outcome'] = 'OK'
+ replace['errormsg'] = 'OK'
+ replace['operation1'] = operation[p2]("1")
+ replace['operation2'] = operation[p1]("1")
+ make_file(template, f'LocalConcurrency_lloutwindow_{e}_{p2}_{p1}_ok.c', replace)
+
+ # Generate a correct code by removing operation2
+ replace = patterns
+ replace['shortdesc'] = 'Correct code using RMA operations'
+ replace['longdesc'] = 'Correct code using RMA operations'
+ replace['outcome'] = 'OK'
+ replace['errormsg'] = 'OK'
+ replace['operation1'] = operation[p1]("1")
+ replace['operation2'] = ''
+ make_file(template, f'LocalConcurrency_{e}_{p1}_ok.c', replace)
--- /dev/null
+#! /usr/bin/python3
+import os
+import sys
+from generator_utils import *
+
+template = """// @{generatedby}@
+/* ///////////////////////// The MPI Bugs Initiative ////////////////////////
+
+ Origin: MBI
+
+ Description: @{shortdesc}@
+ @{longdesc}@
+
+ Version of MPI: Conforms to MPI 2, does not require MPI 3 implementation
+
+BEGIN_MPI_FEATURES
+ P2P!basic: @{p2pfeature}@
+ P2P!nonblocking: @{ip2pfeature}@
+ P2P!persistent: Lacking
+ COLL!basic: Lacking
+ COLL!nonblocking: Lacking
+ COLL!persistent: Lacking
+ COLL!tools: Lacking
+ RMA: @{rmafeature}@
+END_MPI_FEATURES
+
+BEGIN_MBI_TESTS
+ $ mpirun -np 4 ${EXE}
+ | @{outcome}@
+ | @{errormsg}@
+END_MBI_TESTS
+////////////////////// End of MBI headers /////////////////// */
+
+#include <mpi.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define N 1
+
+int main(int argc, char **argv) {
+ int nprocs = -1;
+ int rank = -1;
+ MPI_Win win;
+ int * winbuf = malloc(N * sizeof(int)); // Window buffer
+ int buff_size = 1;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ printf("Hello from rank %d \\n", rank);
+
+ if (nprocs < 4)
+ printf("MBI ERROR: This test needs at least 4 processes to produce a bug!\\n");
+
+ MPI_Comm newcom = MPI_COMM_WORLD;
+ MPI_Datatype type = MPI_INT;
+ int stag=0, rtag=0;
+ winbuf[0] = nprocs;
+
+ MPI_Win_create(winbuf, N*sizeof(int), sizeof(int), MPI_INFO_NULL, MPI_COMM_WORLD, &win);
+
+
+ @{init1}@
+ @{init2}@
+ @{init3}@
+
+ if (rank == 0) {
+ int target=1;
+ MPI_Win_lock(MPI_LOCK_EXCLUSIVE, 1, 0, win);
+ @{operation1}@
+ localbuf1[0] = 12345; /* MBIERROR1 */
+ MPI_Win_unlock(1, win);
+ }else if (rank == 2){
+ int dest=1;
+ @{operation2}@
+ @{fini2}@
+ }else if (rank == 1){
+ int src=2;
+ buf3 = winbuf[0];
+ @{operation3}@
+ winbuf[0] = buf3; /* MBIERROR2 */
+ @{fini3}@
+ }
+
+ MPI_Win_free(&win);
+ free(winbuf);
+
+ MPI_Finalize();
+ printf("Rank %d finished normally\\n", rank);
+ return 0;
+}
+"""
+
+
+for p in put + get:
+ for s in send + isend:
+ for r in recv + irecv:
+ patterns = {}
+ patterns = {'p': p, 's': s, 'r': r}
+ patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.'
+ patterns['rmafeature'] = 'Yes'
+ patterns['p2pfeature'] = 'Yes' if s in send or r in recv else 'Lacking'
+ patterns['ip2pfeature'] = 'Yes' if s in isend or r in irecv else 'Lacking'
+ patterns['p'] = p
+ patterns['s'] = s
+ patterns['r'] = r
+ patterns['init1'] = init[p]("1")
+ patterns['init2'] = init[s]("2")
+ patterns['init3'] = init[r]("3")
+ patterns['fini2'] = fini[s]("2")
+ patterns['fini3'] = fini[r]("3")
+ patterns['operation1'] = operation[p]("1") #put or get
+ patterns['operation2'] = operation[s]("2") #send
+ patterns['operation3'] = operation[r]("3") #recv
+
+ replace = patterns
+ replace['shortdesc'] = 'Global Concurrency error.'
+ replace['longdesc'] = 'Global Concurrency error. Concurrent access of variable winbuf by @{p}@ and @{r}@'
+ replace['outcome'] = 'ERROR: GlobalConcurrency'
+ replace['errormsg'] = 'Global Concurrency error. @{p}@ at @{filename}@:@{line:MBIERROR1}@ accesses the window of process 1. Process 1 receives data from process 2 and uses variable winbuf. winbuf in process 1 is then nondeterministic.'
+ make_file(template, f'GlobalConcurrency_{p}_{s}_{r}_nok.c', replace)
--- /dev/null
+#! /usr/bin/python3
+import os
+import sys
+from generator_utils import *
+
+template = """// @{generatedby}@
+/* ///////////////////////// The MPI Bugs Initiative ////////////////////////
+
+ Origin: MBI
+
+ Description: @{shortdesc}@
+ @{longdesc}@
+
+ Version of MPI: Conforms to MPI 2, requires MPI 3 implementation (for lock_all/unlock_all epochs)
+
+BEGIN_MPI_FEATURES
+ P2P!basic: Lacking
+ P2P!nonblocking: Lacking
+ P2P!persistent: Lacking
+ COLL!basic: Lacking
+ COLL!nonblocking: Lacking
+ COLL!persistent: Lacking
+ COLL!tools: Lacking
+ RMA: @{rmafeature}@
+END_MPI_FEATURES
+
+BEGIN_MBI_TESTS
+ $ mpirun -np 2 ${EXE}
+ | @{outcome}@
+ | @{errormsg}@
+END_MBI_TESTS
+////////////////////// End of MBI headers /////////////////// */
+
+#include <mpi.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define N 1
+
+int main(int argc, char **argv) {
+ int nprocs = -1;
+ int rank = -1;
+ MPI_Win win;
+ int winbuf[100] = {0};
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ printf("Hello from rank %d \\n", rank);
+
+ if (nprocs < 2)
+ printf("MBI ERROR: This test needs at least 2 processes to produce a bug!\\n");
+
+ MPI_Datatype type = MPI_INT;
+ int target = 1;
+
+ MPI_Win_create(&winbuf, 100 * sizeof(int), sizeof(int), MPI_INFO_NULL, MPI_COMM_WORLD, &win);
+
+ @{init1}@
+
+ @{epoch}@
+
+ if (rank == 0) {
+ @{operation1}@ /* MBIERROR1 */
+ }
+ if(rank == 1){
+ target = 0;
+ @{operation2}@ /* MBIERROR2 */
+ }
+
+ @{finEpoch}@
+
+ MPI_Win_free(&win);
+
+ MPI_Finalize();
+ return 0;
+}
+"""
+
+
+for e in epoch:
+ for p1 in get:
+ for p2 in rput + rstore + rload + rget :
+ patterns = {}
+ patterns = {'e': e, 'p1': p1, 'p2': p2}
+ patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.'
+ patterns['rmafeature'] = 'Yes'
+ patterns['p1'] = p1
+ patterns['p2'] = p2
+ patterns['e'] = e
+ patterns['epoch'] = epoch[e]("1")
+ patterns['finEpoch'] = finEpoch[e]("1")
+ patterns['init1'] = init[p1]("1")
+ patterns['operation1'] = operation[p1]("1")
+ patterns['operation2'] = operation[p2]("1")
+
+ # Generate a data race (Get + Get/load/store/Put)
+ replace = patterns
+ replace['shortdesc'] = 'Global Concurrency error.'
+ replace['longdesc'] = 'Global Concurrency error. @{p2}@ conflicts with @{p1}@'
+ replace['outcome'] = 'ERROR: GlobalConcurrency'
+ replace['errormsg'] = 'Global Concurrency error. @{p2}@ at @{filename}@:@{line:MBIERROR2}@ conflicts with @{p1}@ line @{line:MBIERROR1}@'
+ make_file(template, f'GlobalConcurrency_rl_{e}_{p1}_{p2}_nok.c', replace)
+
+
+for e in epoch:
+ for p1 in put:
+ for p2 in rstore + rload + rput:
+ patterns = {}
+ patterns = {'e': e, 'p1': p1, 'p2': p2}
+ patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.'
+ patterns['rmafeature'] = 'Yes'
+ patterns['p1'] = p1
+ patterns['p2'] = p2
+ patterns['e'] = e
+ patterns['epoch'] = epoch[e]("1")
+ patterns['finEpoch'] = finEpoch[e]("1")
+ patterns['init1'] = init[p1]("1")
+ patterns['operation1'] = operation[p1]("1")
+ patterns['operation2'] = operation[p2]("1")
+
+ # Generate a data race (Put + store)
+ replace = patterns
+ replace['shortdesc'] = 'Global Concurrency error.'
+ replace['longdesc'] = 'Global Concurrency error. @{p2}@ conflicts with @{p1}@'
+ replace['outcome'] = 'ERROR: LocalConcurrency'
+ replace['errormsg'] = 'Global Concurrency error. @{p2}@ at @{filename}@:@{line:MBIERROR2}@ conflicts with @{p1}@ line @{line:MBIERROR1}@'
+ make_file(template, f'GlobalConcurrency_rl_{e}_{p1}_{p2}_nok.c', replace)
--- /dev/null
+#! /usr/bin/python3
+import os
+import sys
+from generator_utils import *
+
+template = """// @{generatedby}@
+/* ///////////////////////// The MPI Bugs Initiative ////////////////////////
+
+ Origin: MBI
+
+ Description: @{shortdesc}@
+ @{longdesc}@
+
+ Version of MPI: Conforms to MPI 2, requires MPI 3 implementation (for lock_all/unlock_all epochs)
+
+BEGIN_MPI_FEATURES
+ P2P!basic: Lacking
+ P2P!nonblocking: Lacking
+ P2P!persistent: Lacking
+ COLL!basic: Lacking
+ COLL!nonblocking: Lacking
+ COLL!persistent: Lacking
+ COLL!tools: Lacking
+ RMA: @{rmafeature}@
+END_MPI_FEATURES
+
+BEGIN_MBI_TESTS
+ $ mpirun -np 2 ${EXE}
+ | @{outcome}@
+ | @{errormsg}@
+END_MBI_TESTS
+////////////////////// End of MBI headers /////////////////// */
+
+#include <mpi.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define N 1
+
+int main(int argc, char **argv) {
+ int nprocs = -1;
+ int rank = -1;
+ MPI_Win win;
+ int winbuf[100] = {0};
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ printf("Hello from rank %d \\n", rank);
+
+ if (nprocs < 2)
+ printf("MBI ERROR: This test needs at least 2 processes to produce a bug!\\n");
+
+ MPI_Datatype type = MPI_INT;
+ int target = 1;
+
+ MPI_Win_create(&winbuf, 100 * sizeof(int), sizeof(int), MPI_INFO_NULL, MPI_COMM_WORLD, &win);
+
+ @{init1}@
+
+ @{epoch}@
+
+ if (rank == 0 || rank == 2) {
+ @{operation1}@ /* MBIERROR1 */
+ }
+
+ @{finEpoch}@
+
+ MPI_Win_free(&win);
+
+ MPI_Finalize();
+ return 0;
+}
+"""
+
+
+for e in epoch:
+ for p1 in get + put:
+ patterns = {}
+ patterns = {'e': e, 'p1': p1}
+ patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.'
+ patterns['rmafeature'] = 'Yes'
+ patterns['p1'] = p1
+ patterns['e'] = e
+ patterns['epoch'] = epoch[e]("1")
+ patterns['finEpoch'] = finEpoch[e]("1")
+ patterns['init1'] = init[p1]("1")
+ patterns['operation1'] = operation[p1]("1")
+
+ # Generate a data race (Get + Get/load/store/Put)
+ replace = patterns
+ replace['shortdesc'] = 'Global Concurrency error.'
+ replace['longdesc'] = 'Global Concurrency error. Both processes 0 and 2 access the window in process 1 with @{p1}@'
+ replace['outcome'] = 'ERROR: GlobalConcurrency'
+ replace['errormsg'] = 'Global Concurrency error. @{p1}@ at @{filename}@:@{line:MBIERROR1}@ conflicts in process 1'
+ make_file(template, f'GlobalConcurrency_rr_{e}_{p1}_nok.c', replace)
+
--- /dev/null
+#! /usr/bin/python3
+import os
+import sys
+from generator_utils import *
+
+template = """// @{generatedby}@
+/* ///////////////////////// The MPI Bugs Initiative ////////////////////////
+
+ Origin: @{origin}@
+
+ Description: @{shortdesc}@
+ @{longdesc}@
+
+ Version of MPI: Conforms to MPI 1.1, does not require MPI 2 implementation
+
+BEGIN_MPI_FEATURES
+ P2P!basic: Lacking
+ P2P!nonblocking: Lacking
+ P2P!persistent: Lacking
+ COLL!basic: Lacking
+ COLL!nonblocking: Lacking
+ COLL!persistent: Lacking
+ COLL!tools: Lacking
+ RMA: @{rmafeature}@
+END_MPI_FEATURES
+
+BEGIN_MBI_TESTS
+ $ mpirun -np 2 ${EXE}
+ | @{outcome}@
+ | @{errormsg}@
+END_MBI_TESTS
+////////////////////// End of MBI headers /////////////////// */
+
+#include <mpi.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define N 20
+
+int main(int argc, char **argv) {
+ int rank, numProcs;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_size(MPI_COMM_WORLD, &numProcs);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+ if (numProcs < 2)
+ printf("MBI ERROR: This test needs at least 2 processes to produce a bug!\\n");
+
+ int *winbuf = malloc(N * sizeof(int));
+
+ MPI_Win win;
+ MPI_Win_create(winbuf, N * sizeof(int), 1, MPI_INFO_NULL, MPI_COMM_WORLD, &win);
+
+ MPI_Datatype type = MPI_INT;
+ int target = 1;
+
+ @{epoch}@
+
+ if (rank == 0) {
+ @{epoch2}@
+
+ @{init}@
+ @{operation}@
+
+ @{finEpoch2}@
+ }
+
+ @{finEpoch}@
+
+ MPI_Win_free(&win);
+
+ free(winbuf);
+
+ MPI_Finalize();
+
+ printf("Rank %d finished normally\\n", rank);
+ return 0;
+}
+"""
+
+
+for e1 in epoch:
+ for p in rma:
+ patterns = {}
+ patterns = {'e1': e1, 'p': p}
+ patterns['origin'] = "MPI-Corrbench"
+ patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.'
+ patterns['rmafeature'] = 'Yes'
+ patterns['p'] = p
+ patterns['e1'] = e1
+ patterns['epoch'] = epoch[e1]("1")
+ patterns['finEpoch'] = finEpoch[e1]("1")
+ patterns['epoch2'] = ""
+ patterns['finEpoch2'] = ""
+ patterns['init'] = init[p]("1")
+ patterns['operation'] = operation[p]("1")
+
+ # Generate a code correct
+ replace = patterns
+ replace['shortdesc'] = 'Correct code'
+ replace['longdesc'] = 'Correct code'
+ replace['outcome'] = 'OK'
+ replace['errormsg'] = 'OK'
+ make_file(template, f'ReqLifecycle_RMA_{e1}_{p}_ok.c', replace)
+
+ # Generate a code with missing open epoch
+ replace = patterns
+ replace['shortdesc'] = f"Request lifecycle, missing open {e1} epoch"
+ replace['longdesc'] = f"Request lifecycle, missing open {e1} epoch"
+ replace['outcome'] = 'ERROR: MissingStart'
+ replace['errormsg'] = '@{e1}@ at @{filename}@:@{line:MBIERROR}@ has missing'
+ replace['epoch'] = f"/* MBIERROR MISSING: {epoch[e1]('1')} */"
+ make_file(template, f'ReqLifecycle_RMA_MissingOpen_{e1}_{p}_nok.c', replace)
+
+ # Generate a code with missing close epoch
+ replace = patterns
+ replace['shortdesc'] = f"Request lifecycle, missing close {e1} epoch"
+ replace['longdesc'] = f"Request lifecycle, missing close {e1} epoch"
+ replace['outcome'] = 'ERROR: MissingWait'
+ replace['errormsg'] = '@{e1}@ at @{filename}@:@{line:MBIERROR}@ has missing'
+ replace['epoch'] = epoch[e1]("1")
+ replace['finEpoch'] = f"/* MBIERROR MISSING: {finEpoch[e1]('1')} */"
+ make_file(template, f'ReqLifecycle_RMA_MissingClose_{e1}_{p}_nok.c', replace)
+
+for e1 in epoch:
+ for e2 in epoch:
+ for p in rma:
+ patterns = {}
+ patterns = {'e1': e1, 'e2': e2, 'p': p}
+ patterns['origin'] = "MPI-Corrbench"
+ patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.'
+ patterns['rmafeature'] = 'Yes'
+ patterns['p'] = p
+ patterns['e1'] = e1
+ patterns['e2'] = e2
+ patterns['epoch'] = epoch[e1]("1")
+ patterns['finEpoch'] = finEpoch[e1]("1")
+ patterns['epoch2'] = epoch[e2]("1") + " /* MBIERROR */"
+ patterns['finEpoch2'] = finEpoch[e2]("1") + " /* MBIERROR */"
+ patterns['init'] = init[p]("1")
+ patterns['operation'] = operation[p]("1")
+
+ # Generate a code with epoch into an epoch
+ replace = patterns
+ replace['shortdesc'] = f"Request lifecycle, {e2} epoch into {e1} epoch"
+ replace['longdesc'] = f"Request lifecycle, {e2} epoch into {e1} epoch"
+ replace['outcome'] = 'ERROR: MissingWait' #FIXME: New type of error
+ replace['errormsg'] = '@{e2}@ at @{filename}@:@{line:MBIERROR}@ has in an other epoch'
+ make_file(template, f'ReqLifecycle_RMA_TwoEpoch_{e1}_{e2}_{p}_nok.c', replace)
--- /dev/null
+#! /usr/bin/python3
+import os
+import sys
+from generator_utils import *
+
+template = """// @{generatedby}@
+/* ///////////////////////// The MPI Bugs Initiative ////////////////////////
+
+ Origin: @{origin}@
+
+ Description: @{shortdesc}@
+ @{longdesc}@
+
+
+BEGIN_MPI_FEATURES
+ P2P!basic: Lacking
+ P2P!nonblocking: Lacking
+ P2P!persistent: Lacking
+ COLL!basic: Lacking
+ COLL!nonblocking: Lacking
+ COLL!persistent: Lacking
+ COLL!tools: Lacking
+ RMA: @{rmafeature}@
+END_MPI_FEATURES
+
+BEGIN_MBI_TESTS
+ $ mpirun -np 2 ${EXE}
+ | @{outcome}@
+ | @{errormsg}@
+END_MBI_TESTS
+////////////////////// End of MBI headers /////////////////// */
+
+#include <mpi.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define N 10
+
+int * buffer;
+
+void get_win(MPI_Win *win) {
+ @{bufferalloc}@
+
+ MPI_Win_create(@{buffer}@, N * sizeof(int), 1, MPI_INFO_NULL, MPI_COMM_WORLD, win);
+
+ return;
+}
+
+int main(int argc, char *argv[]) {
+ int rank, numProcs;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_size(MPI_COMM_WORLD, &numProcs);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ printf("Hello from rank %d \\n", rank);
+
+ MPI_Win win;
+
+ get_win(&win);
+
+ MPI_Win_free(&win);
+
+ @{bufferfree}@
+
+ MPI_Finalize();
+ printf("Rank %d finished normally\\n", rank);
+ return 0;
+}
+
+"""
+
+
+for b in ['stack', 'missing', 'null', 'malloc', 'bufferSize']:
+ patterns = {}
+ patterns = {'b': b}
+ patterns['origin'] = "MPI-CorrBench"
+ patterns['generatedby'] = f'DO NOT EDIT: this file was generated by {os.path.basename(sys.argv[0])}. DO NOT EDIT.'
+ patterns['rmafeature'] = 'Yes'
+
+ replace = patterns
+ replace['shortdesc'] = 'Invalid buffer in window creation.'
+ replace['longdesc'] = 'Invalid buffer in window creation.'
+ replace['outcome'] = 'ERROR: InvalidBuffer'
+ replace['errormsg'] = '@{b}@ at @{filename}@:@{line:MBIERROR}@ has an invalid buffer'
+ replace['bufferfree'] = ''
+
+ ok = 'nok'
+ replace['buffer'] = 'buffer'
+
+ if b == 'stack':
+ replace['bufferalloc'] = 'int buffer[N]; /* MBIERROR1 */'
+ replace['buffer'] = '&buffer'
+ replace['longdesc'] = 'Use a stack oriented buffer in window creation, buffer on temporary stack memory.'
+ elif b == 'missing':
+ replace['bufferalloc'] = '/* MBIERROR1 */'
+ replace['longdesc'] = 'Uninitialized buffer in window creation.'
+ elif b == 'null':
+ replace['bufferalloc'] = 'buffer = NULL; /* MBIERROR1 */'
+ replace['longdesc'] = 'Use NULL buffer in window creation.'
+ elif b == 'bufferSize':
+ replace['bufferalloc'] = 'buffer = malloc((N/2) * sizeof(int)); /* MBIERROR1 */'
+ replace['bufferfree'] = 'free(buffer);'
+ replace['longdesc'] = 'Unmatched size of buffer in window creation.'
+ else:
+ replace['bufferalloc'] = 'buffer = malloc(N * sizeof(int));'
+ replace['bufferfree'] = 'free(buffer);'
+ replace['longdesc'] = 'Correct initialized buffer in window creation.'
+ replace['outcome'] = 'OK'
+ replace['errormsg'] = ''
+ ok = 'ok'
+
+ make_file(template, f'InvalidParam_WinBuffer_{b}_{ok}.c', replace)