diff --git a/testing/adios2/engine/ssc/CMakeLists.txt b/testing/adios2/engine/ssc/CMakeLists.txt index ea6ef940e8..ceb4b8f1f2 100644 --- a/testing/adios2/engine/ssc/CMakeLists.txt +++ b/testing/adios2/engine/ssc/CMakeLists.txt @@ -9,6 +9,12 @@ if(ADIOS2_HAVE_MPI) gtest_add_tests_helper(Base MPI_ONLY Ssc Engine.SSC. "") SetupTestPipeline(Engine.SSC.SscEngineTest.TestSscBase.MPI "" TRUE) + gtest_add_tests_helper(BaseUnlocked MPI_ONLY Ssc Engine.SSC. "") + SetupTestPipeline(Engine.SSC.SscEngineTest.TestSscBaseUnlocked.MPI "" TRUE) + + gtest_add_tests_helper(LockBeforeEndStep MPI_ONLY Ssc Engine.SSC. "") + SetupTestPipeline(Engine.SSC.SscEngineTest.TestSscLockBeforeEndStep.MPI "" TRUE) + gtest_add_tests_helper(OnlyOneStep MPI_ONLY Ssc Engine.SSC. "") SetupTestPipeline(Engine.SSC.SscEngineTest.TestSscOnlyOneStep.MPI "" TRUE) diff --git a/testing/adios2/engine/ssc/TestSscBaseUnlocked.cpp b/testing/adios2/engine/ssc/TestSscBaseUnlocked.cpp new file mode 100644 index 0000000000..bc89f2a108 --- /dev/null +++ b/testing/adios2/engine/ssc/TestSscBaseUnlocked.cpp @@ -0,0 +1,278 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + */ + +#include "TestSscCommon.h" +#include +#include +#include +#include +#include + +using namespace adios2; +int mpiRank = 0; +int mpiSize = 1; +MPI_Comm mpiComm; + +class SscEngineTest : public ::testing::Test +{ +public: + SscEngineTest() = default; +}; + +void Writer(const Dims &shape, const Dims &start, const Dims &count, + const size_t steps, const adios2::Params &engineParams, + const std::string &name) +{ + size_t datasize = + std::accumulate(count.begin(), count.end(), static_cast(1), + std::multiplies()); + adios2::ADIOS adios(mpiComm); + adios2::IO dataManIO = adios.DeclareIO("WAN"); + dataManIO.SetEngine("ssc"); + dataManIO.SetParameters(engineParams); + std::vector myChars(datasize); + std::vector myUChars(datasize); + std::vector myShorts(datasize); + std::vector myUShorts(datasize); + std::vector myInts(datasize); + std::vector myUInts(datasize); + std::vector myFloats(datasize); + std::vector myDoubles(datasize); + std::vector> myComplexes(datasize); + std::vector> myDComplexes(datasize); + auto bpChars = + dataManIO.DefineVariable("bpChars", shape, start, count); + auto bpUChars = dataManIO.DefineVariable("bpUChars", shape, + start, count); + auto bpShorts = + dataManIO.DefineVariable("bpShorts", shape, start, count); + auto bpUShorts = dataManIO.DefineVariable( + "bpUShorts", shape, start, count); + auto bpInts = dataManIO.DefineVariable("bpInts", shape, start, count); + auto bpUInts = + dataManIO.DefineVariable("bpUInts", shape, start, count); + auto bpFloats = + dataManIO.DefineVariable("bpFloats", shape, start, count); + auto bpDoubles = + dataManIO.DefineVariable("bpDoubles", shape, start, count); + auto bpComplexes = dataManIO.DefineVariable>( + "bpComplexes", shape, start, count); + auto bpDComplexes = dataManIO.DefineVariable>( + "bpDComplexes", shape, start, count); + auto scalarInt = dataManIO.DefineVariable("scalarInt"); + auto stringVar = dataManIO.DefineVariable("stringVar"); + dataManIO.DefineAttribute("AttInt", 110); + adios2::Engine engine = dataManIO.Open(name, adios2::Mode::Write); + for (int i = 0; i < steps; ++i) + { + engine.BeginStep(); + GenData(myChars, i, start, count, shape); + GenData(myUChars, i, start, count, shape); + GenData(myShorts, i, start, count, shape); + GenData(myUShorts, i, start, count, shape); + GenData(myInts, i, start, count, shape); + GenData(myUInts, i, start, count, shape); + GenData(myFloats, i, start, count, shape); + GenData(myDoubles, i, start, count, shape); + GenData(myComplexes, i, start, count, shape); + GenData(myDComplexes, i, start, count, shape); + engine.Put(bpChars, myChars.data(), adios2::Mode::Sync); + engine.Put(bpUChars, myUChars.data(), adios2::Mode::Sync); + engine.Put(bpShorts, myShorts.data(), adios2::Mode::Sync); + engine.Put(bpUShorts, myUShorts.data(), adios2::Mode::Sync); + engine.Put(bpInts, myInts.data(), adios2::Mode::Sync); + engine.Put(bpUInts, myUInts.data(), adios2::Mode::Sync); + engine.Put(bpFloats, myFloats.data(), adios2::Mode::Sync); + engine.Put(bpDoubles, myDoubles.data(), adios2::Mode::Sync); + engine.Put(bpComplexes, myComplexes.data(), adios2::Mode::Sync); + engine.Put(bpDComplexes, myDComplexes.data(), adios2::Mode::Sync); + engine.Put(scalarInt, i); + std::string s = "sample string sample string sample string"; + engine.Put(stringVar, s); + engine.EndStep(); + } + engine.Close(); +} + +void Reader(const Dims &shape, const Dims &start, const Dims &count, + const size_t steps, const adios2::Params &engineParams, + const std::string &name) +{ + adios2::ADIOS adios(mpiComm); + adios2::IO dataManIO = adios.DeclareIO("Test"); + dataManIO.SetEngine("ssc"); + dataManIO.SetParameters(engineParams); + adios2::Engine engine = dataManIO.Open(name, adios2::Mode::Read); + + size_t datasize = + std::accumulate(count.begin(), count.end(), static_cast(1), + std::multiplies()); + std::vector myChars(datasize); + std::vector myUChars(datasize); + std::vector myShorts(datasize); + std::vector myUShorts(datasize); + std::vector myInts(datasize); + std::vector myUInts(datasize); + std::vector myFloats(datasize); + std::vector myDoubles(datasize); + std::vector> myComplexes(datasize); + std::vector> myDComplexes(datasize); + + while (true) + { + adios2::StepStatus status = engine.BeginStep(StepMode::Read, 5); + if (status == adios2::StepStatus::OK) + { + auto scalarInt = dataManIO.InquireVariable("scalarInt"); + auto blocksInfo = + engine.BlocksInfo(scalarInt, engine.CurrentStep()); + + for (const auto &bi : blocksInfo) + { + ASSERT_EQ(bi.IsValue, true); + ASSERT_EQ(bi.Value, engine.CurrentStep()); + ASSERT_EQ(scalarInt.Min(), engine.CurrentStep()); + ASSERT_EQ(scalarInt.Max(), engine.CurrentStep()); + } + + const auto &vars = dataManIO.AvailableVariables(); + ASSERT_EQ(vars.size(), 12); + size_t currentStep = engine.CurrentStep(); + adios2::Variable bpChars = + dataManIO.InquireVariable("bpChars"); + adios2::Variable bpUChars = + dataManIO.InquireVariable("bpUChars"); + adios2::Variable bpShorts = + dataManIO.InquireVariable("bpShorts"); + adios2::Variable bpUShorts = + dataManIO.InquireVariable("bpUShorts"); + adios2::Variable bpInts = + dataManIO.InquireVariable("bpInts"); + adios2::Variable bpUInts = + dataManIO.InquireVariable("bpUInts"); + adios2::Variable bpFloats = + dataManIO.InquireVariable("bpFloats"); + adios2::Variable bpDoubles = + dataManIO.InquireVariable("bpDoubles"); + adios2::Variable> bpComplexes = + dataManIO.InquireVariable>("bpComplexes"); + adios2::Variable> bpDComplexes = + dataManIO.InquireVariable>("bpDComplexes"); + adios2::Variable stringVar = + dataManIO.InquireVariable("stringVar"); + + bpChars.SetSelection({start, count}); + bpUChars.SetSelection({start, count}); + bpShorts.SetSelection({start, count}); + bpUShorts.SetSelection({start, count}); + bpInts.SetSelection({start, count}); + bpUInts.SetSelection({start, count}); + bpFloats.SetSelection({start, count}); + bpDoubles.SetSelection({start, count}); + bpComplexes.SetSelection({start, count}); + bpDComplexes.SetSelection({start, count}); + + engine.Get(bpChars, myChars.data(), adios2::Mode::Sync); + engine.Get(bpUChars, myUChars.data(), adios2::Mode::Sync); + engine.Get(bpShorts, myShorts.data(), adios2::Mode::Sync); + engine.Get(bpUShorts, myUShorts.data(), adios2::Mode::Sync); + engine.Get(bpInts, myInts.data(), adios2::Mode::Sync); + engine.Get(bpUInts, myUInts.data(), adios2::Mode::Sync); + engine.Get(bpFloats, myFloats.data(), adios2::Mode::Sync); + engine.Get(bpDoubles, myDoubles.data(), adios2::Mode::Sync); + engine.Get(bpComplexes, myComplexes.data(), adios2::Mode::Sync); + engine.Get(bpDComplexes, myDComplexes.data(), adios2::Mode::Sync); + std::string s; + engine.Get(stringVar, s); + ASSERT_EQ(s, "sample string sample string sample string"); + ASSERT_EQ(stringVar.Min(), + "sample string sample string sample string"); + ASSERT_EQ(stringVar.Max(), + "sample string sample string sample string"); + + VerifyData(myChars.data(), currentStep, start, count, shape, + mpiRank); + VerifyData(myUChars.data(), currentStep, start, count, shape, + mpiRank); + VerifyData(myShorts.data(), currentStep, start, count, shape, + mpiRank); + VerifyData(myUShorts.data(), currentStep, start, count, shape, + mpiRank); + VerifyData(myInts.data(), currentStep, start, count, shape, + mpiRank); + VerifyData(myUInts.data(), currentStep, start, count, shape, + mpiRank); + VerifyData(myFloats.data(), currentStep, start, count, shape, + mpiRank); + VerifyData(myDoubles.data(), currentStep, start, count, shape, + mpiRank); + VerifyData(myComplexes.data(), currentStep, start, count, shape, + mpiRank); + VerifyData(myDComplexes.data(), currentStep, start, count, shape, + mpiRank); + engine.EndStep(); + } + else if (status == adios2::StepStatus::EndOfStream) + { + std::cout << "[Rank " + std::to_string(mpiRank) + + "] SscTest reader end of stream!" + << std::endl; + break; + } + } + auto attInt = dataManIO.InquireAttribute("AttInt"); + std::cout << "[Rank " + std::to_string(mpiRank) + "] Attribute received " + << attInt.Data()[0] << ", expected 110" << std::endl; + ASSERT_EQ(110, attInt.Data()[0]); + ASSERT_NE(111, attInt.Data()[0]); + engine.Close(); +} + +TEST_F(SscEngineTest, TestSscBaseUnlocked) +{ + std::string filename = "TestSscBaseUnlocked"; + adios2::Params engineParams = {}; + + int worldRank, worldSize; + MPI_Comm_rank(MPI_COMM_WORLD, &worldRank); + MPI_Comm_size(MPI_COMM_WORLD, &worldSize); + int mpiGroup = worldRank / (worldSize / 2); + MPI_Comm_split(MPI_COMM_WORLD, mpiGroup, worldRank, &mpiComm); + + MPI_Comm_rank(mpiComm, &mpiRank); + MPI_Comm_size(mpiComm, &mpiSize); + + Dims shape = {10, (size_t)mpiSize * 2}; + Dims start = {2, (size_t)mpiRank * 2}; + Dims count = {5, 2}; + size_t steps = 10; + + if (mpiGroup == 0) + { + Writer(shape, start, count, steps, engineParams, filename); + } + + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + + if (mpiGroup == 1) + { + Reader(shape, start, count, steps, engineParams, filename); + } + + MPI_Barrier(MPI_COMM_WORLD); +} + +int main(int argc, char **argv) +{ + MPI_Init(&argc, &argv); + int worldRank, worldSize; + MPI_Comm_rank(MPI_COMM_WORLD, &worldRank); + MPI_Comm_size(MPI_COMM_WORLD, &worldSize); + ::testing::InitGoogleTest(&argc, argv); + int result = RUN_ALL_TESTS(); + + MPI_Finalize(); + return result; +} diff --git a/testing/adios2/engine/ssc/TestSscLockBeforeEndStep.cpp b/testing/adios2/engine/ssc/TestSscLockBeforeEndStep.cpp new file mode 100644 index 0000000000..f0107e9b1e --- /dev/null +++ b/testing/adios2/engine/ssc/TestSscLockBeforeEndStep.cpp @@ -0,0 +1,284 @@ +/* + * Distributed under the OSI-approved Apache License, Version 2.0. See + * accompanying file Copyright.txt for details. + */ + +#include "TestSscCommon.h" +#include +#include +#include +#include +#include + +using namespace adios2; +int mpiRank = 0; +int mpiSize = 1; +MPI_Comm mpiComm; + +class SscEngineTest : public ::testing::Test +{ +public: + SscEngineTest() = default; +}; + +void Writer(const Dims &shape, const Dims &start, const Dims &count, + const size_t steps, const adios2::Params &engineParams, + const std::string &name) +{ + size_t datasize = + std::accumulate(count.begin(), count.end(), static_cast(1), + std::multiplies()); + adios2::ADIOS adios(mpiComm); + adios2::IO dataManIO = adios.DeclareIO("WAN"); + dataManIO.SetEngine("ssc"); + dataManIO.SetParameters(engineParams); + std::vector myChars(datasize); + std::vector myUChars(datasize); + std::vector myShorts(datasize); + std::vector myUShorts(datasize); + std::vector myInts(datasize); + std::vector myUInts(datasize); + std::vector myFloats(datasize); + std::vector myDoubles(datasize); + std::vector> myComplexes(datasize); + std::vector> myDComplexes(datasize); + auto bpChars = + dataManIO.DefineVariable("bpChars", shape, start, count); + auto bpUChars = dataManIO.DefineVariable("bpUChars", shape, + start, count); + auto bpShorts = + dataManIO.DefineVariable("bpShorts", shape, start, count); + auto bpUShorts = dataManIO.DefineVariable( + "bpUShorts", shape, start, count); + auto bpInts = dataManIO.DefineVariable("bpInts", shape, start, count); + auto bpUInts = + dataManIO.DefineVariable("bpUInts", shape, start, count); + auto bpFloats = + dataManIO.DefineVariable("bpFloats", shape, start, count); + auto bpDoubles = + dataManIO.DefineVariable("bpDoubles", shape, start, count); + auto bpComplexes = dataManIO.DefineVariable>( + "bpComplexes", shape, start, count); + auto bpDComplexes = dataManIO.DefineVariable>( + "bpDComplexes", shape, start, count); + auto scalarInt = dataManIO.DefineVariable("scalarInt"); + auto stringVar = dataManIO.DefineVariable("stringVar"); + dataManIO.DefineAttribute("AttInt", 110); + adios2::Engine engine = dataManIO.Open(name, adios2::Mode::Write); + for (int i = 0; i < steps; ++i) + { + engine.BeginStep(); + GenData(myChars, i, start, count, shape); + GenData(myUChars, i, start, count, shape); + GenData(myShorts, i, start, count, shape); + GenData(myUShorts, i, start, count, shape); + GenData(myInts, i, start, count, shape); + GenData(myUInts, i, start, count, shape); + GenData(myFloats, i, start, count, shape); + GenData(myDoubles, i, start, count, shape); + GenData(myComplexes, i, start, count, shape); + GenData(myDComplexes, i, start, count, shape); + engine.Put(bpChars, myChars.data(), adios2::Mode::Sync); + engine.Put(bpUChars, myUChars.data(), adios2::Mode::Sync); + engine.Put(bpShorts, myShorts.data(), adios2::Mode::Sync); + engine.Put(bpUShorts, myUShorts.data(), adios2::Mode::Sync); + engine.Put(bpInts, myInts.data(), adios2::Mode::Sync); + engine.Put(bpUInts, myUInts.data(), adios2::Mode::Sync); + engine.Put(bpFloats, myFloats.data(), adios2::Mode::Sync); + engine.Put(bpDoubles, myDoubles.data(), adios2::Mode::Sync); + engine.Put(bpComplexes, myComplexes.data(), adios2::Mode::Sync); + engine.Put(bpDComplexes, myDComplexes.data(), adios2::Mode::Sync); + engine.Put(scalarInt, i); + std::string s = "sample string sample string sample string"; + engine.Put(stringVar, s); + engine.LockWriterDefinitions(); + engine.EndStep(); + } + engine.Close(); +} + +void Reader(const Dims &shape, const Dims &start, const Dims &count, + const size_t steps, const adios2::Params &engineParams, + const std::string &name) +{ + adios2::ADIOS adios(mpiComm); + adios2::IO dataManIO = adios.DeclareIO("Test"); + dataManIO.SetEngine("ssc"); + dataManIO.SetParameters(engineParams); + adios2::Engine engine = dataManIO.Open(name, adios2::Mode::Read); + + size_t datasize = + std::accumulate(count.begin(), count.end(), static_cast(1), + std::multiplies()); + std::vector myChars(datasize); + std::vector myUChars(datasize); + std::vector myShorts(datasize); + std::vector myUShorts(datasize); + std::vector myInts(datasize); + std::vector myUInts(datasize); + std::vector myFloats(datasize); + std::vector myDoubles(datasize); + std::vector> myComplexes(datasize); + std::vector> myDComplexes(datasize); + + while (true) + { + adios2::StepStatus status = engine.BeginStep(StepMode::Read, 5); + if (status == adios2::StepStatus::OK) + { + auto scalarInt = dataManIO.InquireVariable("scalarInt"); + auto blocksInfo = + engine.BlocksInfo(scalarInt, engine.CurrentStep()); + + for (const auto &bi : blocksInfo) + { + ASSERT_EQ(bi.IsValue, true); + ASSERT_EQ(bi.Value, engine.CurrentStep()); + ASSERT_EQ(scalarInt.Min(), engine.CurrentStep()); + ASSERT_EQ(scalarInt.Max(), engine.CurrentStep()); + } + + const auto &vars = dataManIO.AvailableVariables(); + ASSERT_EQ(vars.size(), 12); + size_t currentStep = engine.CurrentStep(); + adios2::Variable bpChars = + dataManIO.InquireVariable("bpChars"); + adios2::Variable bpUChars = + dataManIO.InquireVariable("bpUChars"); + adios2::Variable bpShorts = + dataManIO.InquireVariable("bpShorts"); + adios2::Variable bpUShorts = + dataManIO.InquireVariable("bpUShorts"); + adios2::Variable bpInts = + dataManIO.InquireVariable("bpInts"); + adios2::Variable bpUInts = + dataManIO.InquireVariable("bpUInts"); + adios2::Variable bpFloats = + dataManIO.InquireVariable("bpFloats"); + adios2::Variable bpDoubles = + dataManIO.InquireVariable("bpDoubles"); + adios2::Variable> bpComplexes = + dataManIO.InquireVariable>("bpComplexes"); + adios2::Variable> bpDComplexes = + dataManIO.InquireVariable>("bpDComplexes"); + adios2::Variable stringVar = + dataManIO.InquireVariable("stringVar"); + + bpChars.SetSelection({start, count}); + bpUChars.SetSelection({start, count}); + bpShorts.SetSelection({start, count}); + bpUShorts.SetSelection({start, count}); + bpInts.SetSelection({start, count}); + bpUInts.SetSelection({start, count}); + bpFloats.SetSelection({start, count}); + bpDoubles.SetSelection({start, count}); + bpComplexes.SetSelection({start, count}); + bpDComplexes.SetSelection({start, count}); + + engine.Get(bpChars, myChars.data(), adios2::Mode::Sync); + engine.Get(bpUChars, myUChars.data(), adios2::Mode::Sync); + engine.Get(bpShorts, myShorts.data(), adios2::Mode::Sync); + engine.Get(bpUShorts, myUShorts.data(), adios2::Mode::Sync); + engine.Get(bpInts, myInts.data(), adios2::Mode::Sync); + engine.Get(bpUInts, myUInts.data(), adios2::Mode::Sync); + engine.Get(bpFloats, myFloats.data(), adios2::Mode::Sync); + engine.Get(bpDoubles, myDoubles.data(), adios2::Mode::Sync); + engine.Get(bpComplexes, myComplexes.data(), adios2::Mode::Sync); + engine.Get(bpDComplexes, myDComplexes.data(), adios2::Mode::Sync); + std::string s; + engine.Get(stringVar, s); + ASSERT_EQ(s, "sample string sample string sample string"); + ASSERT_EQ(stringVar.Min(), + "sample string sample string sample string"); + ASSERT_EQ(stringVar.Max(), + "sample string sample string sample string"); + + int i; + engine.Get(scalarInt, &i); + ASSERT_EQ(i, currentStep); + + VerifyData(myChars.data(), currentStep, start, count, shape, + mpiRank); + VerifyData(myUChars.data(), currentStep, start, count, shape, + mpiRank); + VerifyData(myShorts.data(), currentStep, start, count, shape, + mpiRank); + VerifyData(myUShorts.data(), currentStep, start, count, shape, + mpiRank); + VerifyData(myInts.data(), currentStep, start, count, shape, + mpiRank); + VerifyData(myUInts.data(), currentStep, start, count, shape, + mpiRank); + VerifyData(myFloats.data(), currentStep, start, count, shape, + mpiRank); + VerifyData(myDoubles.data(), currentStep, start, count, shape, + mpiRank); + VerifyData(myComplexes.data(), currentStep, start, count, shape, + mpiRank); + VerifyData(myDComplexes.data(), currentStep, start, count, shape, + mpiRank); + engine.LockReaderSelections(); + engine.EndStep(); + } + else if (status == adios2::StepStatus::EndOfStream) + { + std::cout << "[Rank " + std::to_string(mpiRank) + + "] SscTest reader end of stream!" + << std::endl; + break; + } + } + auto attInt = dataManIO.InquireAttribute("AttInt"); + std::cout << "[Rank " + std::to_string(mpiRank) + "] Attribute received " + << attInt.Data()[0] << ", expected 110" << std::endl; + ASSERT_EQ(110, attInt.Data()[0]); + ASSERT_NE(111, attInt.Data()[0]); + engine.Close(); +} + +TEST_F(SscEngineTest, TestSscLockBeforeEndStep) +{ + std::string filename = "TestSscLockBeforeEndStep"; + adios2::Params engineParams = {}; + + int worldRank, worldSize; + MPI_Comm_rank(MPI_COMM_WORLD, &worldRank); + MPI_Comm_size(MPI_COMM_WORLD, &worldSize); + int mpiGroup = worldRank / (worldSize / 2); + MPI_Comm_split(MPI_COMM_WORLD, mpiGroup, worldRank, &mpiComm); + + MPI_Comm_rank(mpiComm, &mpiRank); + MPI_Comm_size(mpiComm, &mpiSize); + + Dims shape = {10, (size_t)mpiSize * 2}; + Dims start = {2, (size_t)mpiRank * 2}; + Dims count = {5, 2}; + size_t steps = 100; + + if (mpiGroup == 0) + { + Writer(shape, start, count, steps, engineParams, filename); + } + + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + + if (mpiGroup == 1) + { + Reader(shape, start, count, steps, engineParams, filename); + } + + MPI_Barrier(MPI_COMM_WORLD); +} + +int main(int argc, char **argv) +{ + MPI_Init(&argc, &argv); + int worldRank, worldSize; + MPI_Comm_rank(MPI_COMM_WORLD, &worldRank); + MPI_Comm_size(MPI_COMM_WORLD, &worldSize); + ::testing::InitGoogleTest(&argc, argv); + int result = RUN_ALL_TESTS(); + + MPI_Finalize(); + return result; +}