37#include <pybind11/embed.h>
38#include <unordered_map>
64 output += shambase::format(
"- [{}/{}] :", test_num + 1, test_count);
67 bool any_node_cnt = test.world_size == -1;
69 output += (
" [any] ");
71 output += shambase::format(
" [{:03}] ", test.world_size);
74 output +=
"\033[;34m" + test.name +
"\033[0m\n";
86 for (
int rank = 0; rank < rank_results.size(); rank++) {
87 auto &res = rank_results[rank];
89 for (
unsigned int j = 0; j < res.asserts.asserts.size(); j++) {
92 printf(
" Rank %3d [%d/%zu] : ", rank, j + 1, res.asserts.asserts.size());
93 printf(
"%-20s", res.asserts.asserts[j].name.c_str());
95 if (res.asserts.asserts[j].value) {
96 std::cout <<
" (\033[;32mSuccess\033[0m)\n";
98 std::cout <<
" (\033[1;31m Fail \033[0m)\n";
99 if (!res.asserts.asserts[j].comment.empty()) {
100 std::cout <<
"----- logs : \n"
101 << res.asserts.asserts[j].comment <<
"\n-----" << std::endl;
108 u32 assert_count = 0;
110 for (
int rank = 0; rank < rank_results.size(); rank++) {
111 auto &res = rank_results[rank];
112 for (
unsigned int j = 0; j < res.asserts.asserts.size(); j++) {
113 if (res.asserts.asserts[j].value) {
120 if (success_cnt == assert_count) {
121 std::cout <<
" -> Result : \033[;32mSuccess\033[0m";
123 std::cout <<
" -> Result : \033[1;31m Fail \033[0m";
126 std::string s_assert = shambase::format(
" [{}/{}] ", success_cnt, assert_count);
127 printf(
"%-15s", s_assert.c_str());
128 std::cout <<
" (" << timer.
get_time_str() <<
")" << std::endl;
131 if (success_cnt != assert_count) {
132 logger::raw_ln(shambase::format(
"##[error]Test {} failed", rank_results[0].name));
136 std::cout << std::endl;
164 std::string out =
"";
166 std::string sep =
"\n-------------------------------------\n";
168 out +=
" - Test : \033[;34m" + res.
name
169 +
"\033[0m world_rank = " + std::to_string(res.
world_rank);
170 out +=
"\n Assertion list :\n";
174 out += shambase::format_printf(
" - [%d/%zu] ", j + 1, res.
asserts.
asserts.size());
175 out += shambase::format_printf(
"%-20s", res.
asserts.
asserts[j].name.c_str());
178 out +=
" (\033[;32mSuccess\033[0m)\n";
180 out +=
" (\033[1;31m Fail \033[0m)\n";
184 out +=
" -> failed assert logs : " + sep + res.
asserts.
asserts[j].comment + sep;
210 u32 test_count = results.size();
213 std::string log =
"";
223 std::cout <<
"Test suite status : ";
224 if (fail_count == 0) {
225 std::cout <<
" (\033[;32mSuccess\033[0m)";
226 printf(
" [%d/%d] \n", succ_count, test_count);
228 std::cout <<
" (\033[1;31m Fail \033[0m)";
229 printf(
" [%d/%d] \n", succ_count, test_count);
230 std::cout <<
"\nFailed tests : \n\n" << log;
240 std::vector<details::TestResult> rank_result,
usize &gather_bytecount) {
246 std::basic_stringstream<byte> outrank;
250 std::basic_string<byte> gathered;
257 gather_bytecount = gathered.size();
259 std::basic_stringstream<byte> reader(gathered);
261 std::vector<details::TestResult> out;
284 if (test.type == t) {
285 if (test.world_size == -1) {
286 printf(
"- [any] %-15s\n", test.name.c_str());
288 printf(
"- [%03d] %-15s\n", test.world_size, test.name.c_str());
294 printf(
"--- Benchmark ---\n");
296 print_list(Benchmark);
298 printf(
"--- LongBenchmark ---\n");
300 print_list(LongBenchmark);
302 printf(
"--- ValidationTest ---\n");
304 print_list(ValidationTest);
306 printf(
"--- LongValidationTest ---\n");
308 print_list(LongValidationTest);
310 printf(
"--- Unittest ---\n");
312 print_list(Unittest);
321 std::stringstream rank_test_res_out;
323 rank_test_res_out << res.serialize_json() <<
",";
326 std::string out_res_string = rank_test_res_out.str();
330 if (out_res_string.back() ==
',') {
331 out_res_string = out_res_string.substr(0, out_res_string.size() - 1);
338 s_out += R
"( "commit_hash" : ")" + git_commit_hash + "\",\n";
341#if defined(SYCL_COMP_INTEL_LLVM)
342 s_out += R
"( "compiler" : "DPCPP",)"
344#elif defined(SYCL_COMP_HIPSYCL)
345 s_out += R
"( "compiler" : "HipSYCL",)"
348 s_out += R
"( "compiler" : "Unknown",)"
352 s_out += R
"( "comp_args" : ")" + compile_arg + "\",\n";
354 s_out += R
"( "results" : )"
378 std::vector<u32> select_print_tests(
TestConfig cfg) {
387 bool any_node_cnt = (t.world_size == -1);
390 bool can_run_type =
false;
392 auto test_type = t.type;
393 can_run_type |= (run_unit_test && (Unittest == test_type));
394 can_run_type |= (run_validation_test && (ValidationTest == test_type));
395 can_run_type |= (run_longvalidation_test && (LongValidationTest == test_type));
396 can_run_type |= (run_benchmark_test && (Benchmark == test_type));
397 can_run_type |= (run_longbenchmark_test && (LongBenchmark == test_type));
399 return can_run_type && (any_node_cnt || world_size_ok);
402 auto print_test = [&](shamtest::details::Test &t,
bool enabled) {
405 std::string output =
"";
410 output += (
" - [\033[;32many\033[0m] ");
412 output += shambase::format(
" - [\033[;32m{:03}\033[0m] ", t.
world_size);
414 output +=
"\033[;32m" + t.
name +
"\033[0m\n";
418 output += (
" - [\033[;31many\033[0m] ");
420 output += shambase::format(
" - [\033[;31m{:03}\033[0m] ", t.
world_size);
422 output +=
"\033[;31m" + t.
name +
"\033[0m\n";
425 printf(
"%s", output.c_str());
428 using namespace shamtest::details;
430 std::vector<u32> selected_tests;
432 auto run_only_check = [&](std::string test_name) ->
bool {
442 if (static_init_vec_tests[i].type == t) {
444 bool run_test = can_run(static_init_vec_tests[i])
445 && run_only_check(static_init_vec_tests[i].name);
447 ON_RANK_0(print_test(static_init_vec_tests[i], run_test));
450 selected_tests.push_back(i);
456 ON_RANK_0(printf(
"\n------------ Tests list --------------\n"));
457 if (run_benchmark_test) {
458 ON_RANK_0(printf(
"--- Benchmark ---\n"));
459 test_loop(Benchmark);
462 if (run_benchmark_test) {
463 ON_RANK_0(printf(
"--- LongBenchmark ---\n"));
464 test_loop(LongBenchmark);
467 if (run_validation_test) {
468 ON_RANK_0(printf(
"--- ValidationTest ---\n"));
469 test_loop(ValidationTest);
472 if (run_longvalidation_test) {
473 ON_RANK_0(printf(
"--- LongValidationTest ---\n"));
474 test_loop(LongValidationTest);
481 ON_RANK_0(printf(
"--------------------------------------\n\n"));
483 return selected_tests;
491 mpi::barrier(MPI_COMM_WORLD);
492 std::vector<u32> selected_tests = select_print_tests(cfg);
493 mpi::barrier(MPI_COMM_WORLD);
495 u32 test_loc_cnt = 0;
497 bool has_error =
false;
500 py::initialize_interpreter();
512 std::filesystem::create_directories("tests/figures");
519 std::vector<TestResult> results;
520 for (
u32 i : selected_tests) {
528 mpi::barrier(MPI_COMM_WORLD);
533 mpi::barrier(MPI_COMM_WORLD);
535 usize gather_bytecount = 0;
536 std::vector<TestResult> gathered =
gather_tests({res}, gather_bytecount);
538 logger::raw_ln(
"Test result gathered :", gather_bytecount,
"bytes");
542 results.push_back(std::move(res));
548 py::finalize_interpreter();
550 usize gather_bytecount = 0;
551 results =
gather_tests(std::move(results), gather_bytecount);
555 logger::raw_ln(
"Test result gathered :", gather_bytecount,
"bytes");
577 mpi::barrier(MPI_COMM_WORLD);
582 mpi::barrier(MPI_COMM_WORLD);
593 std::array rank_list{1, 2, 3, 4};
595 auto get_pref_type = [](
TestType t) -> std::string {
597 case Benchmark :
return "Benchmark";
598 case LongBenchmark :
return "LongBenchmark";
599 case ValidationTest :
return "ValidationTest";
600 case LongValidationTest:
return "LongValidationTest";
601 case Unittest :
return "Unittest";
605 auto get_arg = [](
TestType t) -> std::string {
607 case Benchmark :
return "--benchmark";
608 case LongBenchmark :
return "--long-test --benchmark";
609 case ValidationTest :
return "--validation";
610 case LongValidationTest:
return "--long-test --validation";
611 case Unittest :
return "--unittest";
615 auto get_test_name = [&](
Test t,
int ranks) -> std::string {
616 std::string name = get_pref_type(t.
type) +
"/" + t.
name
626 std::ofstream filestream;
627 filestream.open(std::string(outfile));
629 std::vector<std::string> cmake_test_list;
631 auto add_test = [&](
Test t,
int ranks) {
632 std::string tname = get_test_name(t, ranks);
633 cmake_test_list.push_back(tname);
635 std::string ret =
"add_test(\"";
639 ret +=
" mpirun -n " + std::to_string(ranks) +
" ../shamrock_test --sycl-cfg 0:0";
641 ret +=
" ../shamrock_test --sycl-cfg 0:0";
643 ret +=
" --run-only \"" + std::string(t.
name) +
"\"";
644 ret +=
" " + get_arg(t.
type);
649 for (
const Test &t : static_init_vec_tests) {
650 if (t.
type == Benchmark || t.
type == LongBenchmark)
653 for (
int ncount : rank_list) {
665 if (REF_FILES_PATH) {
666 filestream <<
"set_tests_properties(\n";
667 for (
auto tname : cmake_test_list) {
668 filestream <<
" \"" << tname <<
"\"\n";
670 filestream <<
" PROPERTIES\n";
671 filestream <<
" ENVIRONMENT \"REF_FILES_PATH=" + *REF_FILES_PATH <<
"\"\n";
This header does the MPI include and wrap MPI calls.
Header file describing a Node Instance.
void close()
close the NodeInstance Aka : Finalize both MPI & SYCL
header describing return type of a test, and the type of the test
TestType
Describe the type of the performed test.
std::uint32_t u32
32 bit unsigned integer
std::size_t usize
size_t alias
std::int32_t i32
32 bit integer
Class Timer measures the time elapsed since the timer was started.
std::string get_time_str() const
Converts the stored nanosecond time to a string representation.
void start()
Starts the timer.
void stop()
Stops the timer and stores the elapsed time in nanoseconds.
Scoped exception generator callback.
This header file contains utility functions related to exception handling in the code.
MPI string gather / allgather helpers (declarations; implementations in shamalgs/src/collective/gathe...
void gather_basic_str(const std::basic_string< byte > &send_vec, std::basic_string< byte > &recv_vec)
same as gather_str but with std::basic_string
Namespace for internal details of the logs module.
void stream_read_vector(std::basic_stringstream< byte > &stream, std::vector< T > &vec)
read a vector from the bytestream Note : this appends read objects to the vector without resetting it
void write_string_to_file(std::string filename, std::string s)
dump a string to a file
std::string increase_indent(std::string in, std::string delim="\n ")
Increase indentation of a string.
void stream_write_vector(std::basic_stringstream< byte > &stream, std::vector< T > &vec)
write the vector into the bytestream
std::optional< std::string > getenv_str(const char *env_var)
Get the content of the environment variable if it exist.
bool is_ci_github_actions()
Check if the environment variable GITHUB_ACTIONS is set.
i32 world_rank()
Gives the rank of the current process in the MPI communicator.
i32 world_size()
Gives the size of the MPI communicator.
implementation details of the test library
std::vector< Test > static_init_vec_tests
Static init vector containing the list of all the tests in the code see : programming guide : Static ...
std::string make_test_report_tex(std::vector< TestResult > &results, bool mark_fail)
Make the tex report.
namespace containing stuff related to the test library
std::string gen_fail_log(details::TestResult &res)
Generate a failure log at the end of the tests.
void gen_test_list(std::string_view outfile)
output test list to a file
bool is_full_output_mode
Is in full output mode.
std::vector< details::TestResult > gather_tests(std::vector< details::TestResult > rank_result, usize &gather_bytecount)
Gather test results from all MPI ranks.
void write_json_report(std::vector< details::TestResult > &results, std::string outfile)
Write the JSON report.
bool is_run_only
Is in run only mode.
bool is_test_failed(details::TestResult &res)
check is a test is failed
int run_all_tests(int argc, char *argv[], TestConfig cfg)
run all the tests
void _start_test_print(details::Test &test, u32 test_num, u32 test_count)
print the line in terminal when a test start
void print_test_list()
print all the available tests
void write_tex_report(std::vector< details::TestResult > &results, bool mark_fail)
Write the tex report.
void _end_test_print(std::vector< details::TestResult > &rank_results, shambase::Timer &timer)
print the line in terminal when a test ends
void _print_summary(std::vector< details::TestResult > &results)
Print summary of the test run.
Pybind11 include and definitions.
void raw_ln(Types... var2)
Prints a log message with multiple arguments followed by a newline.
void raw(Types... var2)
Prints a log message with multiple arguments without newline.
void info_ln(std::string module_name, Types... var2)
Prints a log message with multiple arguments followed by a newline.
void print_faint_row()
Prints a faint separator line to the log.
main include file for testing
This file contains the definition for the stacktrace related functionality.
shambase::details::BasicStackEntry StackEntry
Alias for shambase::details::BasicStackEntry.
void modify_py_sys_path(bool do_print)
Modify Python sys.path to point to one detected during cmake invocation.
void set_sys_argv(int argc, char *argv[])
set the value of sys.argv
Configuration of the test runner.
std::optional< std::string > run_only
Run only regex to select tests.
bool run_long_tests
run also long tests
bool run_benchmark
run benchmarks
bool run_unittest
run unittests
bool full_output
Should display all logs including all asserts.
std::optional< std::string > json_output
Should output a json report.
bool run_validation
run validation tests
std::vector< TestAssert > asserts
List of assertion held by the class.
Informations about a test.
i32 world_size
Node count of the test.
std::string name
Name of the test.
TestType type
Type of test.
header file to manage sycl
const std::string reset()
Get the reset terminal escape char.
const std::string bold()
Get the bold terminal escape char.
Functions related to the MPI communicator.
#define ON_RANK_0(x)
Macro to execute code only on rank 0.
void Test(MPI_Request *request, int *flag, MPI_Status *status)
MPI wrapper for MPI_Test.