From d9c13d050086f7b47e27e4808e6a0589fe7d2f29 Mon Sep 17 00:00:00 2001 From: Patrick Lavin Date: Wed, 24 Apr 2024 15:05:38 -0600 Subject: [PATCH] add first draft of MPI tests --- .../elements/ariel/tests/testMPI/reduce.cc | 5 ++-- .../elements/ariel/tests/testMPI/test-mpi.py | 2 +- .../ariel/tests/testsuite_mpi_Ariel.py | 23 +++++++++++++------ 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/sst/elements/ariel/tests/testMPI/reduce.cc b/src/sst/elements/ariel/tests/testMPI/reduce.cc index 55c59b1c3f..a889167dc1 100644 --- a/src/sst/elements/ariel/tests/testMPI/reduce.cc +++ b/src/sst/elements/ariel/tests/testMPI/reduce.cc @@ -8,11 +8,12 @@ #include "arielapi.h" #define DEBUG 0 -#define TIMING 0 +#define TIMING 1 int main(int argc, char* argv[]) { - MPI_Init(&argc, &argv); + int prov; + MPI_Init_thread(&argc, &argv, MPI_THREAD_FUNNELED, &prov); if (argc < 2) { printf("Too few args\n"); diff --git a/src/sst/elements/ariel/tests/testMPI/test-mpi.py b/src/sst/elements/ariel/tests/testMPI/test-mpi.py index e739e3c43c..5c42eff908 100644 --- a/src/sst/elements/ariel/tests/testMPI/test-mpi.py +++ b/src/sst/elements/ariel/tests/testMPI/test-mpi.py @@ -11,7 +11,7 @@ parser.add_argument('-r', dest='ranks', default=1, help='How many ranks of the traced program to run.') parser.add_argument('-a', dest='tracerank', default=0, help='Which of the MPI ranks will be traced.') parser.add_argument('-t', dest='threads', default=1, help='The number of OpenMP threads to use per rank.') -parser.add_argument('-s', dest='size', default=1024, help='The input value for the "reduce" program') +parser.add_argument('-s', dest='size', default=2048, help='The input value for the "reduce" program') parser.add_argument('-o', dest='output', help='Optional argument to both programs to change stdout') args = parser.parse_args() diff --git a/src/sst/elements/ariel/tests/testsuite_mpi_Ariel.py b/src/sst/elements/ariel/tests/testsuite_mpi_Ariel.py index 4604aec62b..4f8992270c 100644 --- a/src/sst/elements/ariel/tests/testsuite_mpi_Ariel.py +++ b/src/sst/elements/ariel/tests/testsuite_mpi_Ariel.py @@ -61,6 +61,16 @@ def file_contains(self, filename, strings): for s in strings: self.assertTrue(s in lines, "Output {0} does not contain expected line {1}".format(filename, s)) + + def assert_nonzero_stat(self, filename, stat): + with open(filename, 'r') as file: + lines = file.readlines() + for ln in lines: + l = ln.split(' ') + if l[0] == stat: + stat_value = int(l[12].split(';')[0]) + self.assertTrue(stat_value > 0, f"Statistics file `{filename}` did not have a positive value for stat `{stat}`. Line was:\n\t{ln}") + pin_loaded = testing_is_PIN_loaded() pin_error_msg = "Ariel: Requires PIN, but Env Var 'INTEL_PIN_DIRECTORY' is not found or path does not exist." @@ -117,7 +127,7 @@ def test_reduce_03(self): ##TODO add reduce tests - def ariel_Template(self, threads, ranks, program="hello", tracerank=0, testtimeout=60): + def ariel_Template(self, threads, ranks, program="hello", tracerank=0, testtimeout=60, size=250000000): # Set the paths to the various directories testcase = inspect.stack()[1][3] # name the test after the calling function @@ -144,8 +154,9 @@ def ariel_Template(self, threads, ranks, program="hello", tracerank=0, testtimeo outfile = "{0}/{1}.out".format(outdir, testDataFileName) errfile = "{0}/{1}.err".format(outdir, testDataFileName) mpioutfiles = "{0}/{1}.testfile".format(outdir, testDataFileName) + statfile = f"{ArielElementTestMPIDir}/stats.csv" program_output = f"{tmpdir}/ariel_testmpi_{testcase}.out" - other_args = f'--model-options="{program} -o {program_output} -r {ranks} -t {threads} -a {tracerank}"' + other_args = f'--model-options="{program} -o {program_output} -r {ranks} -t {threads} -a {tracerank} -s {size}"' log_debug("testcase = {0}".format(testcase)) log_debug("sdl file = {0}".format(sdlfile)) @@ -170,18 +181,16 @@ def ariel_Template(self, threads, ranks, program="hello", tracerank=0, testtimeo grep_result = os.system(cmd) != 0 self.assertTrue(grep_result, "Output file {0} contains the word 'FATAL'...".format(outfile)) - hello_string_traced = [f"Hello from rank {tracerank} of {ranks}, thread {i}! (Launched by pin)\n" for i in range(threads)] - hello_string_normal = [f"Hello from rank {tracerank} of {ranks}, thread {i}!\n" for i in range(threads)] - # Test for expected output for i in range(ranks): if program == "hello": self.file_contains(f'{program_output}_{i}', get_hello_string(i, ranks, tracerank, threads)) else: - self.file_contains(f'{program_output}_{i}', get_reduce_string(i, ranks, 1024)) + self.file_contains(f'{program_output}_{i}', get_reduce_string(i, ranks, size)) # Test to make sure that each core did some work - #TODO + for i in range(threads): + self.assert_nonzero_stat(statfile, f"cache_{i}.stateEvent_GetS_M") #######################