From 4e03f78d2ffac18f4e8ffa7016a3cec61bbad03a Mon Sep 17 00:00:00 2001 From: Martin Quinson Date: Mon, 21 Mar 2022 00:11:43 +0100 Subject: [PATCH] Add the remaining MBI generators --- teshsuite/smpi/MBI/CMakeLists.txt | 26 +- teshsuite/smpi/MBI/CollArgGenerator.py | 224 ++++++++++++++++++ teshsuite/smpi/MBI/CollComGenerator.py | 116 +++++++++ .../smpi/MBI/CollLocalConcurrencyGenerator.py | 90 +++++++ .../smpi/MBI/CollP2PMatchingGenerator.py | 134 +++++++++++ .../smpi/MBI/CollP2PMessageRaceGenerator.py | 140 +++++++++++ teshsuite/smpi/MBI/CollTopoGenerator.py | 125 ++++++++++ .../smpi/MBI/MissingWaitandStartGenerator.py | 200 ++++++++++++++++ teshsuite/smpi/MBI/P2PArgGenerator.py | 182 ++++++++++++++ teshsuite/smpi/MBI/P2PComGenerator.py | 153 ++++++++++++ teshsuite/smpi/MBI/P2PInvalidComGenerator.py | 121 ++++++++++ .../smpi/MBI/P2PLocalConcurrencyGenerator.py | 126 ++++++++++ .../smpi/MBI/P2PMatchingANYSRCGenerator.py | 110 +++++++++ teshsuite/smpi/MBI/P2PMatchingGenerator.py | 136 +++++++++++ teshsuite/smpi/MBI/P2PProbeGenerator.py | 148 ++++++++++++ teshsuite/smpi/MBI/RMAArgGenerator.py | 110 +++++++++ teshsuite/smpi/MBI/RMAInvalidArgGenerator.py | 133 +++++++++++ .../MBI/RMALocalLocalConcurrencyGenerator.py | 164 +++++++++++++ .../MBI/RMAP2PGlobalConcurrencyGenerator.py | 121 ++++++++++ .../MBI/RMARemoteLocalConcurrencyGenerator.py | 128 ++++++++++ .../RMARemoteRemoteConcurrencyGenerator.py | 97 ++++++++ .../smpi/MBI/RMAReqLifecycleGenerator.py | 150 ++++++++++++ teshsuite/smpi/MBI/RMAWinBufferGenerator.py | 113 +++++++++ 23 files changed, 3046 insertions(+), 1 deletion(-) create mode 100755 teshsuite/smpi/MBI/CollArgGenerator.py create mode 100755 teshsuite/smpi/MBI/CollComGenerator.py create mode 100755 teshsuite/smpi/MBI/CollLocalConcurrencyGenerator.py create mode 100755 teshsuite/smpi/MBI/CollP2PMatchingGenerator.py create mode 100755 teshsuite/smpi/MBI/CollP2PMessageRaceGenerator.py create mode 100755 teshsuite/smpi/MBI/CollTopoGenerator.py create mode 100755 teshsuite/smpi/MBI/MissingWaitandStartGenerator.py create mode 100755 teshsuite/smpi/MBI/P2PArgGenerator.py create mode 100755 teshsuite/smpi/MBI/P2PComGenerator.py create mode 100755 teshsuite/smpi/MBI/P2PInvalidComGenerator.py create mode 100755 teshsuite/smpi/MBI/P2PLocalConcurrencyGenerator.py create mode 100755 teshsuite/smpi/MBI/P2PMatchingANYSRCGenerator.py create mode 100755 teshsuite/smpi/MBI/P2PMatchingGenerator.py create mode 100755 teshsuite/smpi/MBI/P2PProbeGenerator.py create mode 100755 teshsuite/smpi/MBI/RMAArgGenerator.py create mode 100755 teshsuite/smpi/MBI/RMAInvalidArgGenerator.py create mode 100755 teshsuite/smpi/MBI/RMALocalLocalConcurrencyGenerator.py create mode 100755 teshsuite/smpi/MBI/RMAP2PGlobalConcurrencyGenerator.py create mode 100755 teshsuite/smpi/MBI/RMARemoteLocalConcurrencyGenerator.py create mode 100755 teshsuite/smpi/MBI/RMARemoteRemoteConcurrencyGenerator.py create mode 100755 teshsuite/smpi/MBI/RMAReqLifecycleGenerator.py create mode 100755 teshsuite/smpi/MBI/RMAWinBufferGenerator.py diff --git a/teshsuite/smpi/MBI/CMakeLists.txt b/teshsuite/smpi/MBI/CMakeLists.txt index fd2aa91351..94f23c6d2a 100644 --- a/teshsuite/smpi/MBI/CMakeLists.txt +++ b/teshsuite/smpi/MBI/CMakeLists.txt @@ -5,7 +5,31 @@ # 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) diff --git a/teshsuite/smpi/MBI/CollArgGenerator.py b/teshsuite/smpi/MBI/CollArgGenerator.py new file mode 100755 index 0000000000..5e2f619b02 --- /dev/null +++ b/teshsuite/smpi/MBI/CollArgGenerator.py @@ -0,0 +1,224 @@ +#! /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 +#include +#include + +#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) diff --git a/teshsuite/smpi/MBI/CollComGenerator.py b/teshsuite/smpi/MBI/CollComGenerator.py new file mode 100755 index 0000000000..b72574f5a5 --- /dev/null +++ b/teshsuite/smpi/MBI/CollComGenerator.py @@ -0,0 +1,116 @@ +#! /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 +#include +#include + +#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) diff --git a/teshsuite/smpi/MBI/CollLocalConcurrencyGenerator.py b/teshsuite/smpi/MBI/CollLocalConcurrencyGenerator.py new file mode 100755 index 0000000000..c4dbfe3170 --- /dev/null +++ b/teshsuite/smpi/MBI/CollLocalConcurrencyGenerator.py @@ -0,0 +1,90 @@ +#! /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 +#include +#include + +#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) diff --git a/teshsuite/smpi/MBI/CollP2PMatchingGenerator.py b/teshsuite/smpi/MBI/CollP2PMatchingGenerator.py new file mode 100755 index 0000000000..d73d637299 --- /dev/null +++ b/teshsuite/smpi/MBI/CollP2PMatchingGenerator.py @@ -0,0 +1,134 @@ +#! /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 +#include +#include + + +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) + diff --git a/teshsuite/smpi/MBI/CollP2PMessageRaceGenerator.py b/teshsuite/smpi/MBI/CollP2PMessageRaceGenerator.py new file mode 100755 index 0000000000..a39f55325f --- /dev/null +++ b/teshsuite/smpi/MBI/CollP2PMessageRaceGenerator.py @@ -0,0 +1,140 @@ +#! /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 +#include +#include + + +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) diff --git a/teshsuite/smpi/MBI/CollTopoGenerator.py b/teshsuite/smpi/MBI/CollTopoGenerator.py new file mode 100755 index 0000000000..00c06aec62 --- /dev/null +++ b/teshsuite/smpi/MBI/CollTopoGenerator.py @@ -0,0 +1,125 @@ +#! /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 +#include +#include + +#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) diff --git a/teshsuite/smpi/MBI/MissingWaitandStartGenerator.py b/teshsuite/smpi/MBI/MissingWaitandStartGenerator.py new file mode 100755 index 0000000000..1310ee3178 --- /dev/null +++ b/teshsuite/smpi/MBI/MissingWaitandStartGenerator.py @@ -0,0 +1,200 @@ +#! /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 +#include +#include + + +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) diff --git a/teshsuite/smpi/MBI/P2PArgGenerator.py b/teshsuite/smpi/MBI/P2PArgGenerator.py new file mode 100755 index 0000000000..a89c6184cb --- /dev/null +++ b/teshsuite/smpi/MBI/P2PArgGenerator.py @@ -0,0 +1,182 @@ +#! /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 +#include +#include + + +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) diff --git a/teshsuite/smpi/MBI/P2PComGenerator.py b/teshsuite/smpi/MBI/P2PComGenerator.py new file mode 100755 index 0000000000..933d3d60ee --- /dev/null +++ b/teshsuite/smpi/MBI/P2PComGenerator.py @@ -0,0 +1,153 @@ +#! /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 +#include +#include + + +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) diff --git a/teshsuite/smpi/MBI/P2PInvalidComGenerator.py b/teshsuite/smpi/MBI/P2PInvalidComGenerator.py new file mode 100755 index 0000000000..93c45437bc --- /dev/null +++ b/teshsuite/smpi/MBI/P2PInvalidComGenerator.py @@ -0,0 +1,121 @@ +#! /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 +#include +#include + + +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) + diff --git a/teshsuite/smpi/MBI/P2PLocalConcurrencyGenerator.py b/teshsuite/smpi/MBI/P2PLocalConcurrencyGenerator.py new file mode 100755 index 0000000000..049cf480f3 --- /dev/null +++ b/teshsuite/smpi/MBI/P2PLocalConcurrencyGenerator.py @@ -0,0 +1,126 @@ +#! /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 +#include +#include + + +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) diff --git a/teshsuite/smpi/MBI/P2PMatchingANYSRCGenerator.py b/teshsuite/smpi/MBI/P2PMatchingANYSRCGenerator.py new file mode 100755 index 0000000000..4576864e1e --- /dev/null +++ b/teshsuite/smpi/MBI/P2PMatchingANYSRCGenerator.py @@ -0,0 +1,110 @@ +#! /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 +#include +#include + + +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) + diff --git a/teshsuite/smpi/MBI/P2PMatchingGenerator.py b/teshsuite/smpi/MBI/P2PMatchingGenerator.py new file mode 100755 index 0000000000..e6553c1500 --- /dev/null +++ b/teshsuite/smpi/MBI/P2PMatchingGenerator.py @@ -0,0 +1,136 @@ +#! /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 +#include +#include + +#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) + diff --git a/teshsuite/smpi/MBI/P2PProbeGenerator.py b/teshsuite/smpi/MBI/P2PProbeGenerator.py new file mode 100755 index 0000000000..545ca09395 --- /dev/null +++ b/teshsuite/smpi/MBI/P2PProbeGenerator.py @@ -0,0 +1,148 @@ +#! /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 +#include +#include + + +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) diff --git a/teshsuite/smpi/MBI/RMAArgGenerator.py b/teshsuite/smpi/MBI/RMAArgGenerator.py new file mode 100755 index 0000000000..4930ff7106 --- /dev/null +++ b/teshsuite/smpi/MBI/RMAArgGenerator.py @@ -0,0 +1,110 @@ +#! /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 +#include +#include +#include + +#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) + diff --git a/teshsuite/smpi/MBI/RMAInvalidArgGenerator.py b/teshsuite/smpi/MBI/RMAInvalidArgGenerator.py new file mode 100755 index 0000000000..8160671e55 --- /dev/null +++ b/teshsuite/smpi/MBI/RMAInvalidArgGenerator.py @@ -0,0 +1,133 @@ +#! /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 +#include +#include + +#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) diff --git a/teshsuite/smpi/MBI/RMALocalLocalConcurrencyGenerator.py b/teshsuite/smpi/MBI/RMALocalLocalConcurrencyGenerator.py new file mode 100755 index 0000000000..5e57e17e2c --- /dev/null +++ b/teshsuite/smpi/MBI/RMALocalLocalConcurrencyGenerator.py @@ -0,0 +1,164 @@ +#! /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 +#include +#include + +#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) diff --git a/teshsuite/smpi/MBI/RMAP2PGlobalConcurrencyGenerator.py b/teshsuite/smpi/MBI/RMAP2PGlobalConcurrencyGenerator.py new file mode 100755 index 0000000000..b9535e10bc --- /dev/null +++ b/teshsuite/smpi/MBI/RMAP2PGlobalConcurrencyGenerator.py @@ -0,0 +1,121 @@ +#! /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 +#include +#include + +#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) diff --git a/teshsuite/smpi/MBI/RMARemoteLocalConcurrencyGenerator.py b/teshsuite/smpi/MBI/RMARemoteLocalConcurrencyGenerator.py new file mode 100755 index 0000000000..4a8e83ca12 --- /dev/null +++ b/teshsuite/smpi/MBI/RMARemoteLocalConcurrencyGenerator.py @@ -0,0 +1,128 @@ +#! /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 +#include +#include + +#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) diff --git a/teshsuite/smpi/MBI/RMARemoteRemoteConcurrencyGenerator.py b/teshsuite/smpi/MBI/RMARemoteRemoteConcurrencyGenerator.py new file mode 100755 index 0000000000..c856c6d115 --- /dev/null +++ b/teshsuite/smpi/MBI/RMARemoteRemoteConcurrencyGenerator.py @@ -0,0 +1,97 @@ +#! /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 +#include +#include + +#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) + diff --git a/teshsuite/smpi/MBI/RMAReqLifecycleGenerator.py b/teshsuite/smpi/MBI/RMAReqLifecycleGenerator.py new file mode 100755 index 0000000000..5044792cd0 --- /dev/null +++ b/teshsuite/smpi/MBI/RMAReqLifecycleGenerator.py @@ -0,0 +1,150 @@ +#! /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 +#include +#include + +#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) diff --git a/teshsuite/smpi/MBI/RMAWinBufferGenerator.py b/teshsuite/smpi/MBI/RMAWinBufferGenerator.py new file mode 100755 index 0000000000..a737150842 --- /dev/null +++ b/teshsuite/smpi/MBI/RMAWinBufferGenerator.py @@ -0,0 +1,113 @@ +#! /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 +#include +#include +#include + +#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) -- 2.20.1