From cafd866ecb6705d29b65b64b886f1c3320599c46 Mon Sep 17 00:00:00 2001 From: Chen Nuo <49788094+Cstandardlib@users.noreply.github.com> Date: Sat, 13 Dec 2025 18:20:09 +0800 Subject: [PATCH 01/13] Add and refactor unittests for ParaGlobal --- source/source_base/parallel_global.cpp | 6 +- .../test_parallel/parallel_global_test.cpp | 118 ++++++++++++++++-- 2 files changed, 109 insertions(+), 15 deletions(-) diff --git a/source/source_base/parallel_global.cpp b/source/source_base/parallel_global.cpp index dcfea10d30..b20a98c096 100644 --- a/source/source_base/parallel_global.cpp +++ b/source/source_base/parallel_global.cpp @@ -328,7 +328,7 @@ void Parallel_Global::divide_pools(const int& NPROC, // and MY_BNDGROUP will be the same as well. if(BNDPAR > 1 && NPROC %(BNDPAR * KPAR) != 0) { - std::cout << "Error: When BNDPAR = " << BNDPAR << " > 1, number of processes (" << NPROC << ") must be divisible by the number of groups (" + std::cerr << "Error: When BNDPAR = " << BNDPAR << " > 1, number of processes (" << NPROC << ") must be divisible by the number of groups (" << BNDPAR * KPAR << ")." << std::endl; exit(1); } @@ -385,6 +385,8 @@ void Parallel_Global::divide_mpi_groups(const int& procs, { if (num_groups == 0) { + std::cerr << "Error: Number of groups must be greater than 0." << std::endl; + // note that WARNING_QUIT writes to stdout ModuleBase::WARNING_QUIT( "Parallel_Global::divide_mpi_groups", "Number of groups must be greater than 0." @@ -392,7 +394,7 @@ void Parallel_Global::divide_mpi_groups(const int& procs, } if (procs < num_groups) { - std::cout << "Error: Number of processes (" << procs << ") must be greater than the number of groups (" + std::cerr << "Error: Number of processes (" << procs << ") must be greater than the number of groups (" << num_groups << ")." << std::endl; ModuleBase::WARNING_QUIT( "Parallel_Global::divide_mpi_groups", diff --git a/source/source_base/test_parallel/parallel_global_test.cpp b/source/source_base/test_parallel/parallel_global_test.cpp index 9b8799a0c6..47f8062125 100644 --- a/source/source_base/test_parallel/parallel_global_test.cpp +++ b/source/source_base/test_parallel/parallel_global_test.cpp @@ -9,7 +9,7 @@ #include #include -#include "source_base/tool_quit.h" +#include "source_base/global_variable.h" /************************************************ * unit test of functions in parallel_global.cpp @@ -66,6 +66,7 @@ class MPIContext int _size; }; +// --- Normal Test --- class ParaGlobal : public ::testing::Test { protected: @@ -162,8 +163,58 @@ TEST_F(ParaGlobal, MyProd) EXPECT_EQ(inout[1], std::complex(-3.0, -3.0)); } -TEST_F(ParaGlobal, InitPools) + + +TEST_F(ParaGlobal, DivideMPIPools) +{ + this->nproc = 12; + mpi.kpar = 3; + this->my_rank = 5; + Parallel_Global::divide_mpi_groups(this->nproc, + mpi.kpar, + this->my_rank, + mpi.nproc_in_pool, + mpi.my_pool, + mpi.rank_in_pool); + EXPECT_EQ(mpi.nproc_in_pool, 4); + EXPECT_EQ(mpi.my_pool, 1); + EXPECT_EQ(mpi.rank_in_pool, 1); +} + + +// --- DeathTest: Single thread --- +class ParaGlobalDeathTest : public ::testing::Test +{ + protected: + MPIContext mpi; + int nproc; + int my_rank; + + // DeathTest SetUp: + // Init variable, single thread + void SetUp() override + { + // Only master process runs death test (avoid multi-process conflict) + if (mpi.GetRank() != 0) {return;} + + // init log file + GlobalV::ofs_warning.open("warning.log"); + // needed by WARNING_QUIT + } + + // clean log file + void TearDown() override + { + if (mpi.GetRank() != 0) {return;} + + GlobalV::ofs_warning.close(); + remove("warning.log"); + } +}; + +TEST_F(ParaGlobalDeathTest, InitPools) { + GTEST_FLAG_SET(death_test_style, "threadsafe"); nproc = 12; mpi.kpar = 3; mpi.nstogroup = 3; @@ -178,26 +229,67 @@ TEST_F(ParaGlobal, InitPools) mpi.MY_BNDGROUP, mpi.nproc_in_pool, mpi.rank_in_pool, - mpi.my_pool), ::testing::ExitedWithCode(1), ""); - std::string output = testing::internal::GetCapturedStdout(); - EXPECT_THAT(output, testing::HasSubstr("Error:")); + mpi.my_pool), ::testing::ExitedWithCode(1), "Error:"); } - -TEST_F(ParaGlobal, DivideMPIPools) +TEST_F(ParaGlobalDeathTest, DivideMPIPoolsNgEqZero) { + GTEST_FLAG_SET(death_test_style, "threadsafe"); + // test for num_groups == 0, + // Num_group Equals 0 + // WARNING_QUIT this->nproc = 12; - mpi.kpar = 3; + mpi.kpar = 0; this->my_rank = 5; - Parallel_Global::divide_mpi_groups(this->nproc, + EXPECT_EXIT( + Parallel_Global::divide_mpi_groups(this->nproc, mpi.kpar, this->my_rank, mpi.nproc_in_pool, mpi.my_pool, - mpi.rank_in_pool); - EXPECT_EQ(mpi.nproc_in_pool, 4); - EXPECT_EQ(mpi.my_pool, 1); - EXPECT_EQ(mpi.rank_in_pool, 1); + mpi.rank_in_pool), + ::testing::ExitedWithCode(1), + "Number of groups must be greater than 0." + ); + // should WARNING_QUIT inside! + std::string output; + std::ifstream ifs; + ifs.open("warning.log"); + getline(ifs,output); + // test output in warning.log file + EXPECT_THAT(output,testing::HasSubstr("warning")); + EXPECT_THAT(output,testing::HasSubstr("Number of groups must be greater than 0.")); + ifs.close(); +} + +TEST_F(ParaGlobalDeathTest, DivideMPIPoolsNgGtProc) +{ + GTEST_FLAG_SET(death_test_style, "threadsafe"); + // test for procs < num_groups + // Num_group GreaterThan Processors + // WARNING_QUIT + this->nproc = 12; + mpi.kpar = 24; + this->my_rank = 5; + EXPECT_EXIT( + Parallel_Global::divide_mpi_groups(this->nproc, + mpi.kpar, + this->my_rank, + mpi.nproc_in_pool, + mpi.my_pool, + mpi.rank_in_pool) + ,testing::ExitedWithCode(1), + "Error: Number of processes.*must be greater than the number of groups" + ); + // should WARNING_QUIT inside! + std::string output; + std::ifstream ifs; + ifs.open("warning.log"); + getline(ifs,output); + // test output in warning.log file + EXPECT_THAT(output,testing::HasSubstr("warning")); + EXPECT_THAT(output,testing::HasSubstr("Number of processes must be greater than the number of groups.")); + ifs.close(); } int main(int argc, char** argv) From 20448df80590cf4fd5fbb3e21972e9c26b51611a Mon Sep 17 00:00:00 2001 From: Chen Nuo <49788094+Cstandardlib@users.noreply.github.com> Date: Sat, 13 Dec 2025 18:45:07 +0800 Subject: [PATCH 02/13] Move a little comma --- source/source_base/test_parallel/parallel_global_test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/source_base/test_parallel/parallel_global_test.cpp b/source/source_base/test_parallel/parallel_global_test.cpp index 47f8062125..cb8a808eb7 100644 --- a/source/source_base/test_parallel/parallel_global_test.cpp +++ b/source/source_base/test_parallel/parallel_global_test.cpp @@ -277,8 +277,8 @@ TEST_F(ParaGlobalDeathTest, DivideMPIPoolsNgGtProc) this->my_rank, mpi.nproc_in_pool, mpi.my_pool, - mpi.rank_in_pool) - ,testing::ExitedWithCode(1), + mpi.rank_in_pool), + testing::ExitedWithCode(1), "Error: Number of processes.*must be greater than the number of groups" ); // should WARNING_QUIT inside! From 30b1c3e15ee809686348a6846aea04850cdee7bd Mon Sep 17 00:00:00 2001 From: Chen Nuo <49788094+Cstandardlib@users.noreply.github.com> Date: Sat, 13 Dec 2025 18:59:09 +0800 Subject: [PATCH 03/13] Use standard setting style for gtest_death_test_style --- source/source_base/test_parallel/parallel_global_test.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/source/source_base/test_parallel/parallel_global_test.cpp b/source/source_base/test_parallel/parallel_global_test.cpp index cb8a808eb7..82e276e041 100644 --- a/source/source_base/test_parallel/parallel_global_test.cpp +++ b/source/source_base/test_parallel/parallel_global_test.cpp @@ -214,7 +214,6 @@ class ParaGlobalDeathTest : public ::testing::Test TEST_F(ParaGlobalDeathTest, InitPools) { - GTEST_FLAG_SET(death_test_style, "threadsafe"); nproc = 12; mpi.kpar = 3; mpi.nstogroup = 3; @@ -234,7 +233,6 @@ TEST_F(ParaGlobalDeathTest, InitPools) TEST_F(ParaGlobalDeathTest, DivideMPIPoolsNgEqZero) { - GTEST_FLAG_SET(death_test_style, "threadsafe"); // test for num_groups == 0, // Num_group Equals 0 // WARNING_QUIT @@ -264,7 +262,6 @@ TEST_F(ParaGlobalDeathTest, DivideMPIPoolsNgEqZero) TEST_F(ParaGlobalDeathTest, DivideMPIPoolsNgGtProc) { - GTEST_FLAG_SET(death_test_style, "threadsafe"); // test for procs < num_groups // Num_group GreaterThan Processors // WARNING_QUIT @@ -296,6 +293,7 @@ int main(int argc, char** argv) { MPI_Init(&argc, &argv); + testing::FLAGS_gtest_death_test_style = "threadsafe"; testing::InitGoogleTest(&argc, argv); int result = RUN_ALL_TESTS(); MPI_Finalize(); From 42431e78e2172a8eceaf03ba412ad415202b7690 Mon Sep 17 00:00:00 2001 From: Chen Nuo <49788094+Cstandardlib@users.noreply.github.com> Date: Sat, 13 Dec 2025 19:13:42 +0800 Subject: [PATCH 04/13] Add nproc and my_rank for ParaGlobalDeathTest SetUp --- source/source_base/test_parallel/parallel_global_test.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/source_base/test_parallel/parallel_global_test.cpp b/source/source_base/test_parallel/parallel_global_test.cpp index 82e276e041..5869410d03 100644 --- a/source/source_base/test_parallel/parallel_global_test.cpp +++ b/source/source_base/test_parallel/parallel_global_test.cpp @@ -194,6 +194,8 @@ class ParaGlobalDeathTest : public ::testing::Test // Init variable, single thread void SetUp() override { + nproc = mpi.GetSize(); + my_rank = mpi.GetRank(); // Only master process runs death test (avoid multi-process conflict) if (mpi.GetRank() != 0) {return;} From ce78fbe6cfc2e4f8a370f3acb10909de1a631365 Mon Sep 17 00:00:00 2001 From: Chen Nuo <49788094+Cstandardlib@users.noreply.github.com> Date: Sat, 13 Dec 2025 19:30:17 +0800 Subject: [PATCH 05/13] Put InitPools in ParaGlobal --- .../test_parallel/parallel_global_test.cpp | 37 ++++++++++--------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/source/source_base/test_parallel/parallel_global_test.cpp b/source/source_base/test_parallel/parallel_global_test.cpp index 5869410d03..bffae814f1 100644 --- a/source/source_base/test_parallel/parallel_global_test.cpp +++ b/source/source_base/test_parallel/parallel_global_test.cpp @@ -80,6 +80,25 @@ class ParaGlobal : public ::testing::Test } }; +TEST_F(ParaGlobal, InitPools) +{ + nproc = 12; + mpi.kpar = 3; + mpi.nstogroup = 3; + my_rank = 5; + testing::internal::CaptureStdout(); + EXPECT_EXIT(Parallel_Global::init_pools(nproc, + my_rank, + mpi.nstogroup, + mpi.kpar, + mpi.nproc_in_stogroup, + mpi.rank_in_stogroup, + mpi.MY_BNDGROUP, + mpi.nproc_in_pool, + mpi.rank_in_pool, + mpi.my_pool), ::testing::ExitedWithCode(1), "Error:"); +} + TEST_F(ParaGlobal, SplitGrid) { // NPROC is set to 4 in parallel_global_test.sh @@ -214,24 +233,6 @@ class ParaGlobalDeathTest : public ::testing::Test } }; -TEST_F(ParaGlobalDeathTest, InitPools) -{ - nproc = 12; - mpi.kpar = 3; - mpi.nstogroup = 3; - my_rank = 5; - testing::internal::CaptureStdout(); - EXPECT_EXIT(Parallel_Global::init_pools(nproc, - my_rank, - mpi.nstogroup, - mpi.kpar, - mpi.nproc_in_stogroup, - mpi.rank_in_stogroup, - mpi.MY_BNDGROUP, - mpi.nproc_in_pool, - mpi.rank_in_pool, - mpi.my_pool), ::testing::ExitedWithCode(1), "Error:"); -} TEST_F(ParaGlobalDeathTest, DivideMPIPoolsNgEqZero) { From 4058573d5fc29aeec2d56dbfc2f8b3a49cb78d19 Mon Sep 17 00:00:00 2001 From: Chen Nuo <49788094+Cstandardlib@users.noreply.github.com> Date: Sat, 13 Dec 2025 19:37:53 +0800 Subject: [PATCH 06/13] Put InitPools in ParaGlobalDeathTest, switch off CaptureStdout --- .../test_parallel/parallel_global_test.cpp | 36 +++++++++---------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/source/source_base/test_parallel/parallel_global_test.cpp b/source/source_base/test_parallel/parallel_global_test.cpp index bffae814f1..0891d82407 100644 --- a/source/source_base/test_parallel/parallel_global_test.cpp +++ b/source/source_base/test_parallel/parallel_global_test.cpp @@ -80,25 +80,6 @@ class ParaGlobal : public ::testing::Test } }; -TEST_F(ParaGlobal, InitPools) -{ - nproc = 12; - mpi.kpar = 3; - mpi.nstogroup = 3; - my_rank = 5; - testing::internal::CaptureStdout(); - EXPECT_EXIT(Parallel_Global::init_pools(nproc, - my_rank, - mpi.nstogroup, - mpi.kpar, - mpi.nproc_in_stogroup, - mpi.rank_in_stogroup, - mpi.MY_BNDGROUP, - mpi.nproc_in_pool, - mpi.rank_in_pool, - mpi.my_pool), ::testing::ExitedWithCode(1), "Error:"); -} - TEST_F(ParaGlobal, SplitGrid) { // NPROC is set to 4 in parallel_global_test.sh @@ -233,6 +214,23 @@ class ParaGlobalDeathTest : public ::testing::Test } }; +TEST_F(ParaGlobalDeathTest, InitPools) +{ + nproc = 12; + mpi.kpar = 3; + mpi.nstogroup = 3; + my_rank = 5; + EXPECT_EXIT(Parallel_Global::init_pools(nproc, + my_rank, + mpi.nstogroup, + mpi.kpar, + mpi.nproc_in_stogroup, + mpi.rank_in_stogroup, + mpi.MY_BNDGROUP, + mpi.nproc_in_pool, + mpi.rank_in_pool, + mpi.my_pool), ::testing::ExitedWithCode(1), "Error:"); +} TEST_F(ParaGlobalDeathTest, DivideMPIPoolsNgEqZero) { From 18ac9e306a97632229cd9ea81aaa739b74ac41a6 Mon Sep 17 00:00:00 2001 From: Chen Nuo <49788094+Cstandardlib@users.noreply.github.com> Date: Sat, 13 Dec 2025 19:42:04 +0800 Subject: [PATCH 07/13] Put InitPools in ParaGlobal --- .../test_parallel/parallel_global_test.cpp | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/source/source_base/test_parallel/parallel_global_test.cpp b/source/source_base/test_parallel/parallel_global_test.cpp index 0891d82407..da4ff95e37 100644 --- a/source/source_base/test_parallel/parallel_global_test.cpp +++ b/source/source_base/test_parallel/parallel_global_test.cpp @@ -80,6 +80,24 @@ class ParaGlobal : public ::testing::Test } }; +TEST_F(ParaGlobal, InitPools) +{ + nproc = 12; + mpi.kpar = 3; + mpi.nstogroup = 3; + my_rank = 5; + EXPECT_EXIT(Parallel_Global::init_pools(nproc, + my_rank, + mpi.nstogroup, + mpi.kpar, + mpi.nproc_in_stogroup, + mpi.rank_in_stogroup, + mpi.MY_BNDGROUP, + mpi.nproc_in_pool, + mpi.rank_in_pool, + mpi.my_pool), ::testing::ExitedWithCode(1), "Error:"); +} + TEST_F(ParaGlobal, SplitGrid) { // NPROC is set to 4 in parallel_global_test.sh @@ -214,24 +232,6 @@ class ParaGlobalDeathTest : public ::testing::Test } }; -TEST_F(ParaGlobalDeathTest, InitPools) -{ - nproc = 12; - mpi.kpar = 3; - mpi.nstogroup = 3; - my_rank = 5; - EXPECT_EXIT(Parallel_Global::init_pools(nproc, - my_rank, - mpi.nstogroup, - mpi.kpar, - mpi.nproc_in_stogroup, - mpi.rank_in_stogroup, - mpi.MY_BNDGROUP, - mpi.nproc_in_pool, - mpi.rank_in_pool, - mpi.my_pool), ::testing::ExitedWithCode(1), "Error:"); -} - TEST_F(ParaGlobalDeathTest, DivideMPIPoolsNgEqZero) { // test for num_groups == 0, From 417056c733d0dbcfba6bdd8ea50ee2bfad0592bf Mon Sep 17 00:00:00 2001 From: Chen Nuo <49788094+Cstandardlib@users.noreply.github.com> Date: Sat, 13 Dec 2025 20:13:03 +0800 Subject: [PATCH 08/13] Fix DeathTest so that it only runs on rank 0 --- .../test_parallel/parallel_global_test.cpp | 81 ++++++++++++++++--- 1 file changed, 71 insertions(+), 10 deletions(-) diff --git a/source/source_base/test_parallel/parallel_global_test.cpp b/source/source_base/test_parallel/parallel_global_test.cpp index da4ff95e37..644aeeb03c 100644 --- a/source/source_base/test_parallel/parallel_global_test.cpp +++ b/source/source_base/test_parallel/parallel_global_test.cpp @@ -95,7 +95,7 @@ TEST_F(ParaGlobal, InitPools) mpi.MY_BNDGROUP, mpi.nproc_in_pool, mpi.rank_in_pool, - mpi.my_pool), ::testing::ExitedWithCode(1), "Error:"); + mpi.my_pool), ::testing::ExitedWithCode(1), "Error"); } TEST_F(ParaGlobal, SplitGrid) @@ -200,22 +200,71 @@ TEST_F(ParaGlobal, DivideMPIPools) } +class FakeMPIContext +{ + public: + FakeMPIContext() + { + _rank = 0; + _size = 1; + } + + int GetRank() const + { + return _rank; + } + int GetSize() const + { + return _size; + } + + int drank; + int dsize; + int dcolor; + + int grank; + int gsize; + + int kpar; + int nproc_in_pool; + int my_pool; + int rank_in_pool; + + int nstogroup; + int MY_BNDGROUP; + int rank_in_stogroup; + int nproc_in_stogroup; + + private: + int _rank; + int _size; +}; + // --- DeathTest: Single thread --- class ParaGlobalDeathTest : public ::testing::Test { protected: - MPIContext mpi; + FakeMPIContext mpi; int nproc; int my_rank; + int real_rank; // DeathTest SetUp: // Init variable, single thread void SetUp() override { + int is_init = 0; + MPI_Initialized(&is_init); + if (is_init) { + MPI_Comm_rank(MPI_COMM_WORLD, &real_rank); + } else { + real_rank = 0; + } + + if (real_rank != 0) return; + nproc = mpi.GetSize(); my_rank = mpi.GetRank(); - // Only master process runs death test (avoid multi-process conflict) - if (mpi.GetRank() != 0) {return;} // init log file GlobalV::ofs_warning.open("warning.log"); @@ -225,7 +274,7 @@ class ParaGlobalDeathTest : public ::testing::Test // clean log file void TearDown() override { - if (mpi.GetRank() != 0) {return;} + if (real_rank != 0) return; GlobalV::ofs_warning.close(); remove("warning.log"); @@ -234,12 +283,11 @@ class ParaGlobalDeathTest : public ::testing::Test TEST_F(ParaGlobalDeathTest, DivideMPIPoolsNgEqZero) { + if (real_rank != 0) return; // test for num_groups == 0, // Num_group Equals 0 // WARNING_QUIT - this->nproc = 12; mpi.kpar = 0; - this->my_rank = 5; EXPECT_EXIT( Parallel_Global::divide_mpi_groups(this->nproc, mpi.kpar, @@ -263,6 +311,7 @@ TEST_F(ParaGlobalDeathTest, DivideMPIPoolsNgEqZero) TEST_F(ParaGlobalDeathTest, DivideMPIPoolsNgGtProc) { + if (real_rank != 0) return; // test for procs < num_groups // Num_group GreaterThan Processors // WARNING_QUIT @@ -292,12 +341,24 @@ TEST_F(ParaGlobalDeathTest, DivideMPIPoolsNgGtProc) int main(int argc, char** argv) { + bool is_death_test_child = false; + for (int i = 0; i < argc; ++i) { + if (std::string(argv[i]).find("gtest_internal_run_death_test") != std::string::npos) { + is_death_test_child = true; + break; + } + } + + if (!is_death_test_child) { + MPI_Init(&argc, &argv); + } - MPI_Init(&argc, &argv); - testing::FLAGS_gtest_death_test_style = "threadsafe"; testing::InitGoogleTest(&argc, argv); int result = RUN_ALL_TESTS(); - MPI_Finalize(); + + if (!is_death_test_child) { + MPI_Finalize(); + } return result; } #endif // __MPI From eada646423ccaa0c94ac4c443a5fbae82e4be536 Mon Sep 17 00:00:00 2001 From: Chen Nuo <49788094+Cstandardlib@users.noreply.github.com> Date: Sat, 13 Dec 2025 20:17:20 +0800 Subject: [PATCH 09/13] Put InitPools in ParaGlobalDeathTest --- .../test_parallel/parallel_global_test.cpp | 35 ++++++++++--------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/source/source_base/test_parallel/parallel_global_test.cpp b/source/source_base/test_parallel/parallel_global_test.cpp index 644aeeb03c..d6eeb7cc03 100644 --- a/source/source_base/test_parallel/parallel_global_test.cpp +++ b/source/source_base/test_parallel/parallel_global_test.cpp @@ -80,23 +80,6 @@ class ParaGlobal : public ::testing::Test } }; -TEST_F(ParaGlobal, InitPools) -{ - nproc = 12; - mpi.kpar = 3; - mpi.nstogroup = 3; - my_rank = 5; - EXPECT_EXIT(Parallel_Global::init_pools(nproc, - my_rank, - mpi.nstogroup, - mpi.kpar, - mpi.nproc_in_stogroup, - mpi.rank_in_stogroup, - mpi.MY_BNDGROUP, - mpi.nproc_in_pool, - mpi.rank_in_pool, - mpi.my_pool), ::testing::ExitedWithCode(1), "Error"); -} TEST_F(ParaGlobal, SplitGrid) { @@ -281,6 +264,24 @@ class ParaGlobalDeathTest : public ::testing::Test } }; +TEST_F(ParaGlobalDeathTest, InitPools) +{ + nproc = 12; + mpi.kpar = 3; + mpi.nstogroup = 3; + my_rank = 5; + EXPECT_EXIT(Parallel_Global::init_pools(nproc, + my_rank, + mpi.nstogroup, + mpi.kpar, + mpi.nproc_in_stogroup, + mpi.rank_in_stogroup, + mpi.MY_BNDGROUP, + mpi.nproc_in_pool, + mpi.rank_in_pool, + mpi.my_pool), ::testing::ExitedWithCode(1), "Error"); +} + TEST_F(ParaGlobalDeathTest, DivideMPIPoolsNgEqZero) { if (real_rank != 0) return; From e63b1f7c9c62a6d2baca7e7081f46cff5e914c3d Mon Sep 17 00:00:00 2001 From: Chen Nuo <49788094+Cstandardlib@users.noreply.github.com> Date: Sat, 13 Dec 2025 23:28:02 +0800 Subject: [PATCH 10/13] Remove cerr, use warning_quit only --- source/source_base/parallel_global.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/source/source_base/parallel_global.cpp b/source/source_base/parallel_global.cpp index b20a98c096..09e75c2714 100644 --- a/source/source_base/parallel_global.cpp +++ b/source/source_base/parallel_global.cpp @@ -385,8 +385,6 @@ void Parallel_Global::divide_mpi_groups(const int& procs, { if (num_groups == 0) { - std::cerr << "Error: Number of groups must be greater than 0." << std::endl; - // note that WARNING_QUIT writes to stdout ModuleBase::WARNING_QUIT( "Parallel_Global::divide_mpi_groups", "Number of groups must be greater than 0." @@ -394,8 +392,6 @@ void Parallel_Global::divide_mpi_groups(const int& procs, } if (procs < num_groups) { - std::cerr << "Error: Number of processes (" << procs << ") must be greater than the number of groups (" - << num_groups << ")." << std::endl; ModuleBase::WARNING_QUIT( "Parallel_Global::divide_mpi_groups", "Number of processes must be greater than the number of groups." From 4fbffdb19f904d27578d2b57157b51224ff0f646 Mon Sep 17 00:00:00 2001 From: Chen Nuo <49788094+Cstandardlib@users.noreply.github.com> Date: Sat, 13 Dec 2025 23:31:16 +0800 Subject: [PATCH 11/13] Use cout for proc/kpar prompt --- source/source_base/parallel_global.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/source_base/parallel_global.cpp b/source/source_base/parallel_global.cpp index 09e75c2714..9c03fdd52d 100644 --- a/source/source_base/parallel_global.cpp +++ b/source/source_base/parallel_global.cpp @@ -392,6 +392,8 @@ void Parallel_Global::divide_mpi_groups(const int& procs, } if (procs < num_groups) { + std::cerr << "Error: Number of processes (" << procs << ") must be greater than the number of groups (" + << num_groups << ")." << std::endl; ModuleBase::WARNING_QUIT( "Parallel_Global::divide_mpi_groups", "Number of processes must be greater than the number of groups." From f2d914b56c973721d91dc75173c754966f311c94 Mon Sep 17 00:00:00 2001 From: Chen Nuo <49788094+Cstandardlib@users.noreply.github.com> Date: Sun, 14 Dec 2025 00:27:13 +0800 Subject: [PATCH 12/13] Fix Test to run for cout --- source/source_base/parallel_global.cpp | 7 ++- .../test_parallel/parallel_global_test.cpp | 56 ++++++++++--------- 2 files changed, 33 insertions(+), 30 deletions(-) diff --git a/source/source_base/parallel_global.cpp b/source/source_base/parallel_global.cpp index 9c03fdd52d..1b04711490 100644 --- a/source/source_base/parallel_global.cpp +++ b/source/source_base/parallel_global.cpp @@ -328,9 +328,10 @@ void Parallel_Global::divide_pools(const int& NPROC, // and MY_BNDGROUP will be the same as well. if(BNDPAR > 1 && NPROC %(BNDPAR * KPAR) != 0) { - std::cerr << "Error: When BNDPAR = " << BNDPAR << " > 1, number of processes (" << NPROC << ") must be divisible by the number of groups (" + std::cout<< "Error: When BNDPAR = " << BNDPAR << " > 1, number of processes (" << NPROC << ") must be divisible by the number of groups (" << BNDPAR * KPAR << ")." << std::endl; - exit(1); + ModuleBase::WARNING_QUIT("ParallelGlobal::divide_pools", + "When BNDPAR > 1, number of processes NPROC must be divisible by the number of groups BNDPAR * KPAR."); } // k-point parallelization MPICommGroup kpar_group(MPI_COMM_WORLD); @@ -392,7 +393,7 @@ void Parallel_Global::divide_mpi_groups(const int& procs, } if (procs < num_groups) { - std::cerr << "Error: Number of processes (" << procs << ") must be greater than the number of groups (" + std::cout << "Error: Number of processes (" << procs << ") must be greater than the number of groups (" << num_groups << ")." << std::endl; ModuleBase::WARNING_QUIT( "Parallel_Global::divide_mpi_groups", diff --git a/source/source_base/test_parallel/parallel_global_test.cpp b/source/source_base/test_parallel/parallel_global_test.cpp index d6eeb7cc03..30a1f5ac26 100644 --- a/source/source_base/test_parallel/parallel_global_test.cpp +++ b/source/source_base/test_parallel/parallel_global_test.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include "source_base/global_variable.h" @@ -249,9 +250,10 @@ class ParaGlobalDeathTest : public ::testing::Test nproc = mpi.GetSize(); my_rank = mpi.GetRank(); - // init log file + // init log file needed by WARNING_QUIT GlobalV::ofs_warning.open("warning.log"); - // needed by WARNING_QUIT + + } // clean log file @@ -266,11 +268,16 @@ class ParaGlobalDeathTest : public ::testing::Test TEST_F(ParaGlobalDeathTest, InitPools) { + if (real_rank != 0) return; nproc = 12; mpi.kpar = 3; mpi.nstogroup = 3; my_rank = 5; - EXPECT_EXIT(Parallel_Global::init_pools(nproc, + EXPECT_EXIT( + { + // redirect stdout to stderr to capture WARNING_QUIT output + dup2(STDERR_FILENO, STDOUT_FILENO); + Parallel_Global::init_pools(nproc, my_rank, mpi.nstogroup, mpi.kpar, @@ -279,7 +286,10 @@ TEST_F(ParaGlobalDeathTest, InitPools) mpi.MY_BNDGROUP, mpi.nproc_in_pool, mpi.rank_in_pool, - mpi.my_pool), ::testing::ExitedWithCode(1), "Error"); + mpi.my_pool); + }, + ::testing::ExitedWithCode(1), + "Error"); } TEST_F(ParaGlobalDeathTest, DivideMPIPoolsNgEqZero) @@ -288,26 +298,22 @@ TEST_F(ParaGlobalDeathTest, DivideMPIPoolsNgEqZero) // test for num_groups == 0, // Num_group Equals 0 // WARNING_QUIT + this->nproc = 12; mpi.kpar = 0; EXPECT_EXIT( - Parallel_Global::divide_mpi_groups(this->nproc, + { + // redirect stdout to stderr to capture WARNING_QUIT output + dup2(STDERR_FILENO, STDOUT_FILENO); + Parallel_Global::divide_mpi_groups(this->nproc, mpi.kpar, this->my_rank, mpi.nproc_in_pool, mpi.my_pool, - mpi.rank_in_pool), + mpi.rank_in_pool); + }, ::testing::ExitedWithCode(1), "Number of groups must be greater than 0." ); - // should WARNING_QUIT inside! - std::string output; - std::ifstream ifs; - ifs.open("warning.log"); - getline(ifs,output); - // test output in warning.log file - EXPECT_THAT(output,testing::HasSubstr("warning")); - EXPECT_THAT(output,testing::HasSubstr("Number of groups must be greater than 0.")); - ifs.close(); } TEST_F(ParaGlobalDeathTest, DivideMPIPoolsNgGtProc) @@ -320,24 +326,18 @@ TEST_F(ParaGlobalDeathTest, DivideMPIPoolsNgGtProc) mpi.kpar = 24; this->my_rank = 5; EXPECT_EXIT( - Parallel_Global::divide_mpi_groups(this->nproc, + { + dup2(STDERR_FILENO, STDOUT_FILENO); + Parallel_Global::divide_mpi_groups(this->nproc, mpi.kpar, this->my_rank, mpi.nproc_in_pool, mpi.my_pool, - mpi.rank_in_pool), + mpi.rank_in_pool); + }, testing::ExitedWithCode(1), "Error: Number of processes.*must be greater than the number of groups" ); - // should WARNING_QUIT inside! - std::string output; - std::ifstream ifs; - ifs.open("warning.log"); - getline(ifs,output); - // test output in warning.log file - EXPECT_THAT(output,testing::HasSubstr("warning")); - EXPECT_THAT(output,testing::HasSubstr("Number of processes must be greater than the number of groups.")); - ifs.close(); } int main(int argc, char** argv) @@ -350,11 +350,13 @@ int main(int argc, char** argv) } } - if (!is_death_test_child) { + if (!is_death_test_child) + { MPI_Init(&argc, &argv); } testing::InitGoogleTest(&argc, argv); + testing::FLAGS_gtest_death_test_style = "threadsafe"; int result = RUN_ALL_TESTS(); if (!is_death_test_child) { From 8c023ec585267dea554251ce2acc116ca9e0acb0 Mon Sep 17 00:00:00 2001 From: Chen Nuo <49788094+Cstandardlib@users.noreply.github.com> Date: Sun, 14 Dec 2025 10:07:27 +0800 Subject: [PATCH 13/13] Add descriptions of test block --- source/source_base/parallel_global.cpp | 4 ++-- source/source_base/test_parallel/parallel_global_test.cpp | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/source/source_base/parallel_global.cpp b/source/source_base/parallel_global.cpp index 1b04711490..f227e6518f 100644 --- a/source/source_base/parallel_global.cpp +++ b/source/source_base/parallel_global.cpp @@ -328,8 +328,8 @@ void Parallel_Global::divide_pools(const int& NPROC, // and MY_BNDGROUP will be the same as well. if(BNDPAR > 1 && NPROC %(BNDPAR * KPAR) != 0) { - std::cout<< "Error: When BNDPAR = " << BNDPAR << " > 1, number of processes (" << NPROC << ") must be divisible by the number of groups (" - << BNDPAR * KPAR << ")." << std::endl; + std::cout << "Error: When BNDPAR = " << BNDPAR << " > 1, number of processes (" << NPROC + << ") must be divisible by the number of groups (" << BNDPAR * KPAR << ")." << std::endl; ModuleBase::WARNING_QUIT("ParallelGlobal::divide_pools", "When BNDPAR > 1, number of processes NPROC must be divisible by the number of groups BNDPAR * KPAR."); } diff --git a/source/source_base/test_parallel/parallel_global_test.cpp b/source/source_base/test_parallel/parallel_global_test.cpp index 30a1f5ac26..3b6bf8491f 100644 --- a/source/source_base/test_parallel/parallel_global_test.cpp +++ b/source/source_base/test_parallel/parallel_global_test.cpp @@ -225,6 +225,10 @@ class FakeMPIContext }; // --- DeathTest: Single thread --- +// Since these precondition checks cause the processes to die, we call such tests death tests. +// convention of naming the test suite: *DeathTest +// Death tests should be run in a single-threaded context. +// Such DeathTest will be run before all other tests. class ParaGlobalDeathTest : public ::testing::Test { protected: @@ -274,6 +278,9 @@ TEST_F(ParaGlobalDeathTest, InitPools) mpi.nstogroup = 3; my_rank = 5; EXPECT_EXIT( + // This gtest Macro expect that a given `statement` causes the program to exit, with an + // integer exit status that satisfies `predicate`(Here ::testing::ExitedWithCode(1)), + // and emitting error output that matches `matcher`(Here "Error"). { // redirect stdout to stderr to capture WARNING_QUIT output dup2(STDERR_FILENO, STDOUT_FILENO); @@ -327,6 +334,7 @@ TEST_F(ParaGlobalDeathTest, DivideMPIPoolsNgGtProc) this->my_rank = 5; EXPECT_EXIT( { + // redirect stdout to stderr to capture WARNING_QUIT output dup2(STDERR_FILENO, STDOUT_FILENO); Parallel_Global::divide_mpi_groups(this->nproc, mpi.kpar,