From 04159595f6b18a8c37663250eb3384f439dcaa03 Mon Sep 17 00:00:00 2001 From: Rok Cesnovar Date: Mon, 6 Jul 2020 11:22:33 +0200 Subject: [PATCH 1/5] use jumbo in prim --- Jenkinsfile | 6 ++-- runTests.py | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 91 insertions(+), 7 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 07d547b598c..0128f675aef 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -3,8 +3,7 @@ import org.stan.Utils def runTests(String testPath) { - sh "./runTests.py -j${env.PARALLEL} ${testPath} --make-only" - try { sh "./runTests.py -j${env.PARALLEL} ${testPath}" } + try { sh "./runTests.py -j${env.PARALLEL} ${testPath} --jumbo" } finally { junit 'test/**/*.xml' } } @@ -14,8 +13,7 @@ def runTestsWin(String testPath, boolean buildLibs = true) { if (buildLibs){ bat "mingw32-make.exe -f make/standalone math-libs" } - bat "runTests.py -j${env.PARALLEL} ${testPath} --make-only" - try { bat "runTests.py -j${env.PARALLEL} ${testPath}" } + try { bat "runTests.py -j${env.PARALLEL} ${testPath} --jumbo" } finally { junit 'test/**/*.xml' } } } diff --git a/runTests.py b/runTests.py index abb32c6d98e..9f5f411b5d4 100755 --- a/runTests.py +++ b/runTests.py @@ -18,6 +18,38 @@ winsfx = ".exe" testsfx = "_test.cpp" +allowed_paths_with_jumbo = [ + "test/unit/math/prim/", + "test/unit/math/", + # "test/unit/math/rev/", + # "test/unit/math/fwd/", + # "test/unit/math/mix/" +] + +jumbo_folders = [ + "test/unit/math/prim/core", + "test/unit/math/prim/err", + "test/unit/math/prim/fun", + "test/unit/math/prim/functor", + "test/unit/math/prim/meta", + "test/unit/math/prim/prob", + # "test/unit/math/rev/core", + # "test/unit/math/rev/err", + # "test/unit/math/rev/fun", + # "test/unit/math/rev/functor", + # "test/unit/math/rev/meta", + # "test/unit/math/rev/prob", + # "test/unit/math/fwd/core", + # "test/unit/math/fwd/fun", + # "test/unit/math/fwd/functor", + # "test/unit/math/fwd/meta", + # "test/unit/math/fwd/prob", + # "test/unit/math/mix/core", + # "test/unit/math/mix/fun", + # "test/unit/math/mix/functor", + # "test/unit/math/mix/meta", + # "test/unit/math/mix/prob" +] def processCLIArgs(): """ @@ -49,7 +81,8 @@ def processCLIArgs(): action="store_true", help="Don't run tests, just try to make them.") parser.add_argument("--run-all", dest="run_all", action="store_true", help="Don't stop at the first test failure, run all of them.") - + parser.add_argument("--jumbo-test", dest="do_jumbo", action="store_true", + help="Build/run jumbo tests.") # And parse the command line against those rules return parser.parse_args() @@ -97,6 +130,42 @@ def generateTests(j): else: doCommand('make -j%d generate-tests -s' % (j or 1)) +def divide_chunks(l, n): + # looping till length l + for i in range(0, len(l), n): + yield l[i:i + n] + +def generateJumboTests(paths): + jumbo_files_to_create = [] + jumbo_files = [] + for p in paths: + if not p.endswith(testsfx) and not p.endswith("/"): + p = p + "/" + if p in allowed_paths_with_jumbo: + jumbo_files_to_create.extend( + [x for x in jumbo_folders if x.startswith(p)] + ) + else: + stopErr('The --jumbo flag is only allowed with top level folders.', 10) + for jf in jumbo_files_to_create: + tests_in_subfolder = sorted([x for x in os.listdir(jf) if x.endswith(testsfx)]) + chunked_tests = divide_chunks(tests_in_subfolder, 30) + i = 0 + for tests in chunked_tests: + i = i + 1 + jumbo_file_path = jf + "_" + str(i) + testsfx + jumbo_files.append(jumbo_file_path) + f = open(jumbo_file_path, "w") + for t in tests: + f.write("#include <"+jf+"/"+t+">\n") + f.close() + return jumbo_files + +def cleanupJumboTests(paths): + for f in paths: + if os.path.exists(f): + os.remove(f) + def makeTest(name, j): """Run the make command for a given single test.""" if isWin(): @@ -127,7 +196,7 @@ def runTest(name, run_all=False, mpi=False, j=1): command = "mpirun -np {} {}".format(j, command) doCommand(command, not run_all) -def findTests(base_path, filter_names): +def findTests(base_path, filter_names, do_jumbo = False): folders = filter(os.path.isdir, base_path) nonfolders = list(set(base_path) - set(folders)) tests = nonfolders + [os.path.join(root, n) @@ -140,6 +209,18 @@ def findTests(base_path, filter_names): for test in tests if all(filter_name in test for filter_name in filter_names)] + if do_jumbo: + filtered_jumbo_tests = [] + for t in tests: + add = True + for k in jumbo_folders: + k = k + "/" + if t.startswith(k): + add = False + break + if add: + filtered_jumbo_tests.append(t) + tests = filtered_jumbo_tests return tests def batched(tests): @@ -159,7 +240,11 @@ def main(): if any(['test/prob' in arg for arg in inputs.tests]): generateTests(inputs.j) - tests = findTests(inputs.tests, inputs.f) + if inputs.do_jumbo: + jumboFiles = generateJumboTests(inputs.tests) + + jumboFiles = [] + tests = findTests(inputs.tests, inputs.f, inputs.do_jumbo) if not tests: stopErr("No matching tests found.", -1) if inputs.debug: @@ -178,6 +263,7 @@ def main(): print("run single test: %s" % testname) runTest(t, inputs.run_all, mpi = stan_mpi, j = inputs.j) + cleanupJumboTests(jumboFiles) if __name__ == "__main__": main() From b9ba5d0ec1e2e6e3a93ed34b7583cac894c57d8a Mon Sep 17 00:00:00 2001 From: Rok Cesnovar Date: Mon, 6 Jul 2020 12:32:50 +0200 Subject: [PATCH 2/5] dont error with rev --jumbo, just run normally --- runTests.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/runTests.py b/runTests.py index 9f5f411b5d4..f6c41e4a5a9 100755 --- a/runTests.py +++ b/runTests.py @@ -21,9 +21,9 @@ allowed_paths_with_jumbo = [ "test/unit/math/prim/", "test/unit/math/", - # "test/unit/math/rev/", - # "test/unit/math/fwd/", - # "test/unit/math/mix/" + "test/unit/math/rev/", + "test/unit/math/fwd/", + "test/unit/math/mix/" ] jumbo_folders = [ From 0ec341e3dcc01542937cb21d9dc0c7b95ac7fa2d Mon Sep 17 00:00:00 2001 From: Rok Cesnovar Date: Mon, 6 Jul 2020 14:06:00 +0200 Subject: [PATCH 3/5] allow test/unit --- runTests.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/runTests.py b/runTests.py index f6c41e4a5a9..c1c2946b169 100755 --- a/runTests.py +++ b/runTests.py @@ -20,10 +20,11 @@ allowed_paths_with_jumbo = [ "test/unit/math/prim/", - "test/unit/math/", + "test/unit/math/", "test/unit/math/rev/", "test/unit/math/fwd/", - "test/unit/math/mix/" + "test/unit/math/mix/", + "test/unit" ] jumbo_folders = [ From 131bf6fabe4cf8447f761614430fbf6393110b45 Mon Sep 17 00:00:00 2001 From: Rok Cesnovar Date: Mon, 6 Jul 2020 14:33:26 +0200 Subject: [PATCH 4/5] missing / --- runTests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runTests.py b/runTests.py index c1c2946b169..1667c59aa16 100755 --- a/runTests.py +++ b/runTests.py @@ -24,7 +24,7 @@ "test/unit/math/rev/", "test/unit/math/fwd/", "test/unit/math/mix/", - "test/unit" + "test/unit/" ] jumbo_folders = [ From 20b2d6f828b592d3c308c26db24b0b49f7a854db Mon Sep 17 00:00:00 2001 From: rok-cesnovar Date: Tue, 7 Jul 2020 07:58:00 +0200 Subject: [PATCH 5/5] jumbo as arg to runTests Jenkins function --- Jenkinsfile | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 0128f675aef..4111436c167 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -2,18 +2,30 @@ @Library('StanUtils') import org.stan.Utils -def runTests(String testPath) { - try { sh "./runTests.py -j${env.PARALLEL} ${testPath} --jumbo" } - finally { junit 'test/**/*.xml' } +def runTests(String testPath, boolean jumbo = false) { + try { + if (jumbo) { + sh "./runTests.py -j${env.PARALLEL} ${testPath} --jumbo" + } else { + sh "./runTests.py -j${env.PARALLEL} ${testPath}" + } + } + finally { junit 'test/**/*.xml' } } -def runTestsWin(String testPath, boolean buildLibs = true) { +def runTestsWin(String testPath, boolean buildLibs = true, boolean jumbo = false) { withEnv(['PATH+TBB=./lib/tbb']) { bat "echo $PATH" if (buildLibs){ bat "mingw32-make.exe -f make/standalone math-libs" } - try { bat "runTests.py -j${env.PARALLEL} ${testPath} --jumbo" } + try { + if (jumbo) { + bat "runTests.py -j${env.PARALLEL} ${testPath} --jumbo" + } else { + bat "runTests.py -j${env.PARALLEL} ${testPath}" + } + } finally { junit 'test/**/*.xml' } } } @@ -192,15 +204,15 @@ pipeline { if (isUnix()) { deleteDir() unstash 'MathSetup' - runTests("test/unit/math/prim") - runTests("test/unit/math/rev") - runTests("test/unit") + runTests("test/unit/math/prim", true) + runTests("test/unit/math/rev", true) + runTests("test/unit", true) } else { deleteDirWin() unstash 'MathSetup' - runTestsWin("test/unit/math/prim") - runTestsWin("test/unit/math/rev") - runTestsWin("test/unit") + runTestsWin("test/unit/math/prim", true) + runTestsWin("test/unit/math/rev", true) + runTestsWin("test/unit", true) } } } @@ -333,7 +345,7 @@ pipeline { unstash 'MathSetup' bat "mingw32-make.exe -f make/standalone math-libs" bat "mingw32-make -j${env.PARALLEL} test-headers" - runTestsWin("test/unit", false) + runTestsWin("test/unit", false, true) } } }