Loading testing/adios2/engine/bp/TestBPWriteReadVector.cpp +0 −322 Original line number Diff line number Diff line Loading @@ -342,328 +342,6 @@ TEST_F(BPWriteReadVector, ADIOS2BPWriteRead1D8) } } //****************************************************************************** // 1D 1x8 test data non-template //****************************************************************************** TEST_F(BPWriteReadVector, ADIOS2BPWriteRead1D8NT) { // Each process would write a 1x8 array and all processes would // form a mpiSize * Nx 1D array const std::string fname("ADIOS2BPWriteReadVector1D8NT.bp"); int mpiRank = 0, mpiSize = 1; // Number of rows const size_t Nx = 8; // Number of steps const size_t NSteps = 3; #if ADIOS2_USE_MPI MPI_Comm_rank(MPI_COMM_WORLD, &mpiRank); MPI_Comm_size(MPI_COMM_WORLD, &mpiSize); #endif // Write test data using BP #if ADIOS2_USE_MPI adios2::ADIOS adios(MPI_COMM_WORLD); #else adios2::ADIOS adios; #endif { adios2::IO io = adios.DeclareIO("TestIO"); // Declare 1D variables (NumOfProcesses * Nx) // The local process' part (start, count) can be defined now or later // before Write(). { const adios2::Dims shape{static_cast<size_t>(Nx * mpiSize)}; const adios2::Dims start{static_cast<size_t>(Nx * mpiRank)}; const adios2::Dims count{Nx}; auto var_iString = io.DefineVariable(adios2::DataType::String, "iString"); EXPECT_TRUE(var_iString); auto var_i8 = io.DefineVariable(adios2::DataType::Int8, "i8", shape, start, count); EXPECT_TRUE(var_i8); auto var_i16 = io.DefineVariable(adios2::DataType::Int16, "i16", shape, start, count); EXPECT_TRUE(var_i16); auto var_i32 = io.DefineVariable(adios2::DataType::Int32, "i32", shape, start, count); EXPECT_TRUE(var_i32); auto var_i64 = io.DefineVariable(adios2::DataType::Int64, "i64", shape, start, count); EXPECT_TRUE(var_i64); auto var_u8 = io.DefineVariable(adios2::DataType::UInt8, "u8", shape, start, count); EXPECT_TRUE(var_u8); auto var_u16 = io.DefineVariable<uint16_t>("u16", shape, start, count); EXPECT_TRUE(var_u16); auto var_u32 = io.DefineVariable<uint32_t>("u32", shape, start, count); EXPECT_TRUE(var_u32); auto var_u64 = io.DefineVariable<uint64_t>("u64", shape, start, count); EXPECT_TRUE(var_u64); auto var_r32 = io.DefineVariable(adios2::DataType::Float, "r32", shape, start, count); EXPECT_TRUE(var_r32); auto var_r64 = io.DefineVariable(adios2::DataType::Double, "r64", shape, start, count); EXPECT_TRUE(var_r64); } if (!engineName.empty()) { io.SetEngine(engineName); } else { // Create the BP Engine io.SetEngine("BPFile"); } io.AddTransport("file"); // QUESTION: It seems that BPFilterWriter cannot overwrite existing // files // Ex. if you tune Nx and NSteps, the test would fail. But if you clear // the cache in // ${adios2Build}/testing/adios2/engine/bp/ADIOS2BPWriteRead1D8.bp.dir, // then it works adios2::Engine bpWriter = io.Open(fname, adios2::Mode::Write); for (size_t step = 0; step < NSteps; ++step) { // Generate test data for each process uniquely SmallTestData currentTestData = generateNewSmallTestData( m_TestData, static_cast<int>(step), mpiRank, mpiSize); // Retrieve the variables that previously went out of scope auto var_iString = io.InquireVariable("iString"); auto var_i8 = io.InquireVariable<int8_t>("i8"); auto var_i16 = io.InquireVariable("i16"); auto var_i32 = io.InquireVariable("i32"); auto var_i64 = io.InquireVariable("i64"); auto var_u8 = io.InquireVariable<uint8_t>("u8"); auto var_u16 = io.InquireVariable("u16"); auto var_u32 = io.InquireVariable("u32"); auto var_u64 = io.InquireVariable("u64"); auto var_r32 = io.InquireVariable("r32"); auto var_r64 = io.InquireVariable("r64"); // Make a 1D selection to describe the local dimensions of the // variable we write and its offsets in the global spaces adios2::Box<adios2::Dims> sel({mpiRank * Nx}, {Nx}); EXPECT_THROW(var_iString.SetSelection(sel), std::invalid_argument); var_i8.SetSelection(sel); var_i16.SetSelection(sel); var_i32.SetSelection(sel); var_i64.SetSelection(sel); var_u8.SetSelection(sel); var_u16.SetSelection(sel); var_u32.SetSelection(sel); var_u64.SetSelection(sel); var_r32.SetSelection(sel); var_r64.SetSelection(sel); // Write each one // fill in the variable with values from starting index to // starting index + count bpWriter.BeginStep(); bpWriter.Put(var_iString, currentTestData.S1); bpWriter.Put(var_i8, currentTestData.I8.data()); bpWriter.Put(var_i16, currentTestData.I16.data()); bpWriter.Put(var_i32, currentTestData.I32.data()); bpWriter.Put(var_i64, currentTestData.I64.data()); bpWriter.Put(var_u8, currentTestData.U8.data()); bpWriter.Put(var_u16, currentTestData.U16.data()); bpWriter.Put(var_u32, currentTestData.U32.data()); bpWriter.Put(var_u64, currentTestData.U64.data()); bpWriter.Put(var_r32, currentTestData.R32.data()); bpWriter.Put(var_r64, currentTestData.R64.data()); bpWriter.EndStep(); } // Close the file bpWriter.Close(); } { adios2::IO io = adios.DeclareIO("ReadIO"); if (!engineName.empty()) { io.SetEngine(engineName); } adios2::Engine bpReader = io.Open(fname, adios2::Mode::ReadRandomAccess); auto var_iString = io.InquireVariable("iString"); EXPECT_TRUE(var_iString); ASSERT_EQ(var_iString.Shape().size(), 0); ASSERT_EQ(var_iString.Steps(), NSteps); auto var_i8 = io.InquireVariable<int8_t>("i8"); EXPECT_TRUE(var_i8); ASSERT_EQ(var_i8.ShapeID(), adios2::ShapeID::GlobalArray); ASSERT_EQ(var_i8.Steps(), NSteps); ASSERT_EQ(var_i8.Shape()[0], mpiSize * Nx); auto var_i16 = io.InquireVariable("i16"); EXPECT_TRUE(var_i16); ASSERT_EQ(var_i16.ShapeID(), adios2::ShapeID::GlobalArray); ASSERT_EQ(var_i16.Steps(), NSteps); ASSERT_EQ(var_i16.Shape()[0], mpiSize * Nx); auto var_i32 = io.InquireVariable<int32_t>("i32"); EXPECT_TRUE(var_i32); ASSERT_EQ(var_i32.ShapeID(), adios2::ShapeID::GlobalArray); ASSERT_EQ(var_i32.Steps(), NSteps); ASSERT_EQ(var_i32.Shape()[0], mpiSize * Nx); auto var_i64 = io.InquireVariable("i64"); EXPECT_TRUE(var_i64); ASSERT_EQ(var_i64.ShapeID(), adios2::ShapeID::GlobalArray); ASSERT_EQ(var_i64.Steps(), NSteps); ASSERT_EQ(var_i64.Shape()[0], mpiSize * Nx); auto var_u8 = io.InquireVariable<uint8_t>("u8"); EXPECT_TRUE(var_u8); ASSERT_EQ(var_u8.ShapeID(), adios2::ShapeID::GlobalArray); ASSERT_EQ(var_u8.Steps(), NSteps); ASSERT_EQ(var_u8.Shape()[0], mpiSize * Nx); auto var_u16 = io.InquireVariable("u16"); EXPECT_TRUE(var_u16); ASSERT_EQ(var_u16.ShapeID(), adios2::ShapeID::GlobalArray); ASSERT_EQ(var_u16.Steps(), NSteps); ASSERT_EQ(var_u16.Shape()[0], mpiSize * Nx); auto var_u32 = io.InquireVariable<uint32_t>("u32"); EXPECT_TRUE(var_u32); ASSERT_EQ(var_u32.ShapeID(), adios2::ShapeID::GlobalArray); ASSERT_EQ(var_u32.Steps(), NSteps); ASSERT_EQ(var_u32.Shape()[0], mpiSize * Nx); auto var_u64 = io.InquireVariable("u64"); EXPECT_TRUE(var_u64); ASSERT_EQ(var_u64.ShapeID(), adios2::ShapeID::GlobalArray); ASSERT_EQ(var_u64.Steps(), NSteps); ASSERT_EQ(var_u64.Shape()[0], mpiSize * Nx); auto var_r32 = io.InquireVariable<float>("r32"); EXPECT_TRUE(var_r32); ASSERT_EQ(var_r32.ShapeID(), adios2::ShapeID::GlobalArray); ASSERT_EQ(var_r32.Steps(), NSteps); ASSERT_EQ(var_r32.Shape()[0], mpiSize * Nx); auto var_r64 = io.InquireVariable("r64"); EXPECT_TRUE(var_r64); ASSERT_EQ(var_r64.ShapeID(), adios2::ShapeID::GlobalArray); ASSERT_EQ(var_r64.Steps(), NSteps); ASSERT_EQ(var_r64.Shape()[0], mpiSize * Nx); SmallTestData testData; std::string IString; std::vector<int8_t> I8; std::vector<int16_t> I16; std::vector<int32_t> I32; std::vector<int64_t> I64; std::vector<uint8_t> U8; std::vector<uint16_t> U16; std::vector<uint32_t> U32; std::vector<uint64_t> U64; std::vector<float> R32; std::vector<double> R64; const adios2::Dims start{mpiRank * Nx}; const adios2::Dims count{Nx}; const adios2::Box<adios2::Dims> sel(start, count); var_i8.SetSelection(sel); var_i16.SetSelection(sel); var_i32.SetSelection(sel); var_i64.SetSelection(sel); var_u8.SetSelection(sel); var_u16.SetSelection(sel); var_u32.SetSelection(sel); var_u64.SetSelection(sel); var_r32.SetSelection(sel); var_r64.SetSelection(sel); for (size_t t = 0; t < NSteps; ++t) { var_i8.SetStepSelection({t, 1}); var_i16.SetStepSelection({t, 1}); var_i32.SetStepSelection({t, 1}); var_i64.SetStepSelection({t, 1}); var_u8.SetStepSelection({t, 1}); var_u16.SetStepSelection({t, 1}); var_u32.SetStepSelection({t, 1}); var_u64.SetStepSelection({t, 1}); var_r32.SetStepSelection({t, 1}); var_r64.SetStepSelection({t, 1}); // Generate test data for each rank uniquely SmallTestData currentTestData = generateNewSmallTestData( m_TestData, static_cast<int>(t), mpiRank, mpiSize); bpReader.Get(var_iString, IString); bpReader.Get(var_i8, I8, adios2::Mode::Sync); bpReader.Get(var_i16, I16, adios2::Mode::Sync); bpReader.Get(var_i32, I32); bpReader.Get(var_i64, I64); bpReader.Get(var_u8, U8); bpReader.Get(var_u16, U16); bpReader.Get(var_u32, U32); bpReader.Get(var_u64, U64); bpReader.Get(var_r32, R32); bpReader.Get(var_r64, R64); bpReader.PerformGets(); EXPECT_EQ(IString, currentTestData.S1); for (size_t i = 0; i < Nx; ++i) { std::stringstream ss; ss << "t=" << t << " i=" << i << " rank=" << mpiRank; std::string msg = ss.str(); EXPECT_EQ(I8[i], currentTestData.I8[i]) << msg; EXPECT_EQ(I16[i], currentTestData.I16[i]) << msg; EXPECT_EQ(I32[i], currentTestData.I32[i]) << msg; EXPECT_EQ(I64[i], currentTestData.I64[i]) << msg; EXPECT_EQ(U8[i], currentTestData.U8[i]) << msg; EXPECT_EQ(U16[i], currentTestData.U16[i]) << msg; EXPECT_EQ(U32[i], currentTestData.U32[i]) << msg; EXPECT_EQ(U64[i], currentTestData.U64[i]) << msg; EXPECT_EQ(R32[i], currentTestData.R32[i]) << msg; EXPECT_EQ(R64[i], currentTestData.R64[i]) << msg; } } bpReader.Close(); } } //****************************************************************************** // 2D 2x4 test data //****************************************************************************** Loading Loading
testing/adios2/engine/bp/TestBPWriteReadVector.cpp +0 −322 Original line number Diff line number Diff line Loading @@ -342,328 +342,6 @@ TEST_F(BPWriteReadVector, ADIOS2BPWriteRead1D8) } } //****************************************************************************** // 1D 1x8 test data non-template //****************************************************************************** TEST_F(BPWriteReadVector, ADIOS2BPWriteRead1D8NT) { // Each process would write a 1x8 array and all processes would // form a mpiSize * Nx 1D array const std::string fname("ADIOS2BPWriteReadVector1D8NT.bp"); int mpiRank = 0, mpiSize = 1; // Number of rows const size_t Nx = 8; // Number of steps const size_t NSteps = 3; #if ADIOS2_USE_MPI MPI_Comm_rank(MPI_COMM_WORLD, &mpiRank); MPI_Comm_size(MPI_COMM_WORLD, &mpiSize); #endif // Write test data using BP #if ADIOS2_USE_MPI adios2::ADIOS adios(MPI_COMM_WORLD); #else adios2::ADIOS adios; #endif { adios2::IO io = adios.DeclareIO("TestIO"); // Declare 1D variables (NumOfProcesses * Nx) // The local process' part (start, count) can be defined now or later // before Write(). { const adios2::Dims shape{static_cast<size_t>(Nx * mpiSize)}; const adios2::Dims start{static_cast<size_t>(Nx * mpiRank)}; const adios2::Dims count{Nx}; auto var_iString = io.DefineVariable(adios2::DataType::String, "iString"); EXPECT_TRUE(var_iString); auto var_i8 = io.DefineVariable(adios2::DataType::Int8, "i8", shape, start, count); EXPECT_TRUE(var_i8); auto var_i16 = io.DefineVariable(adios2::DataType::Int16, "i16", shape, start, count); EXPECT_TRUE(var_i16); auto var_i32 = io.DefineVariable(adios2::DataType::Int32, "i32", shape, start, count); EXPECT_TRUE(var_i32); auto var_i64 = io.DefineVariable(adios2::DataType::Int64, "i64", shape, start, count); EXPECT_TRUE(var_i64); auto var_u8 = io.DefineVariable(adios2::DataType::UInt8, "u8", shape, start, count); EXPECT_TRUE(var_u8); auto var_u16 = io.DefineVariable<uint16_t>("u16", shape, start, count); EXPECT_TRUE(var_u16); auto var_u32 = io.DefineVariable<uint32_t>("u32", shape, start, count); EXPECT_TRUE(var_u32); auto var_u64 = io.DefineVariable<uint64_t>("u64", shape, start, count); EXPECT_TRUE(var_u64); auto var_r32 = io.DefineVariable(adios2::DataType::Float, "r32", shape, start, count); EXPECT_TRUE(var_r32); auto var_r64 = io.DefineVariable(adios2::DataType::Double, "r64", shape, start, count); EXPECT_TRUE(var_r64); } if (!engineName.empty()) { io.SetEngine(engineName); } else { // Create the BP Engine io.SetEngine("BPFile"); } io.AddTransport("file"); // QUESTION: It seems that BPFilterWriter cannot overwrite existing // files // Ex. if you tune Nx and NSteps, the test would fail. But if you clear // the cache in // ${adios2Build}/testing/adios2/engine/bp/ADIOS2BPWriteRead1D8.bp.dir, // then it works adios2::Engine bpWriter = io.Open(fname, adios2::Mode::Write); for (size_t step = 0; step < NSteps; ++step) { // Generate test data for each process uniquely SmallTestData currentTestData = generateNewSmallTestData( m_TestData, static_cast<int>(step), mpiRank, mpiSize); // Retrieve the variables that previously went out of scope auto var_iString = io.InquireVariable("iString"); auto var_i8 = io.InquireVariable<int8_t>("i8"); auto var_i16 = io.InquireVariable("i16"); auto var_i32 = io.InquireVariable("i32"); auto var_i64 = io.InquireVariable("i64"); auto var_u8 = io.InquireVariable<uint8_t>("u8"); auto var_u16 = io.InquireVariable("u16"); auto var_u32 = io.InquireVariable("u32"); auto var_u64 = io.InquireVariable("u64"); auto var_r32 = io.InquireVariable("r32"); auto var_r64 = io.InquireVariable("r64"); // Make a 1D selection to describe the local dimensions of the // variable we write and its offsets in the global spaces adios2::Box<adios2::Dims> sel({mpiRank * Nx}, {Nx}); EXPECT_THROW(var_iString.SetSelection(sel), std::invalid_argument); var_i8.SetSelection(sel); var_i16.SetSelection(sel); var_i32.SetSelection(sel); var_i64.SetSelection(sel); var_u8.SetSelection(sel); var_u16.SetSelection(sel); var_u32.SetSelection(sel); var_u64.SetSelection(sel); var_r32.SetSelection(sel); var_r64.SetSelection(sel); // Write each one // fill in the variable with values from starting index to // starting index + count bpWriter.BeginStep(); bpWriter.Put(var_iString, currentTestData.S1); bpWriter.Put(var_i8, currentTestData.I8.data()); bpWriter.Put(var_i16, currentTestData.I16.data()); bpWriter.Put(var_i32, currentTestData.I32.data()); bpWriter.Put(var_i64, currentTestData.I64.data()); bpWriter.Put(var_u8, currentTestData.U8.data()); bpWriter.Put(var_u16, currentTestData.U16.data()); bpWriter.Put(var_u32, currentTestData.U32.data()); bpWriter.Put(var_u64, currentTestData.U64.data()); bpWriter.Put(var_r32, currentTestData.R32.data()); bpWriter.Put(var_r64, currentTestData.R64.data()); bpWriter.EndStep(); } // Close the file bpWriter.Close(); } { adios2::IO io = adios.DeclareIO("ReadIO"); if (!engineName.empty()) { io.SetEngine(engineName); } adios2::Engine bpReader = io.Open(fname, adios2::Mode::ReadRandomAccess); auto var_iString = io.InquireVariable("iString"); EXPECT_TRUE(var_iString); ASSERT_EQ(var_iString.Shape().size(), 0); ASSERT_EQ(var_iString.Steps(), NSteps); auto var_i8 = io.InquireVariable<int8_t>("i8"); EXPECT_TRUE(var_i8); ASSERT_EQ(var_i8.ShapeID(), adios2::ShapeID::GlobalArray); ASSERT_EQ(var_i8.Steps(), NSteps); ASSERT_EQ(var_i8.Shape()[0], mpiSize * Nx); auto var_i16 = io.InquireVariable("i16"); EXPECT_TRUE(var_i16); ASSERT_EQ(var_i16.ShapeID(), adios2::ShapeID::GlobalArray); ASSERT_EQ(var_i16.Steps(), NSteps); ASSERT_EQ(var_i16.Shape()[0], mpiSize * Nx); auto var_i32 = io.InquireVariable<int32_t>("i32"); EXPECT_TRUE(var_i32); ASSERT_EQ(var_i32.ShapeID(), adios2::ShapeID::GlobalArray); ASSERT_EQ(var_i32.Steps(), NSteps); ASSERT_EQ(var_i32.Shape()[0], mpiSize * Nx); auto var_i64 = io.InquireVariable("i64"); EXPECT_TRUE(var_i64); ASSERT_EQ(var_i64.ShapeID(), adios2::ShapeID::GlobalArray); ASSERT_EQ(var_i64.Steps(), NSteps); ASSERT_EQ(var_i64.Shape()[0], mpiSize * Nx); auto var_u8 = io.InquireVariable<uint8_t>("u8"); EXPECT_TRUE(var_u8); ASSERT_EQ(var_u8.ShapeID(), adios2::ShapeID::GlobalArray); ASSERT_EQ(var_u8.Steps(), NSteps); ASSERT_EQ(var_u8.Shape()[0], mpiSize * Nx); auto var_u16 = io.InquireVariable("u16"); EXPECT_TRUE(var_u16); ASSERT_EQ(var_u16.ShapeID(), adios2::ShapeID::GlobalArray); ASSERT_EQ(var_u16.Steps(), NSteps); ASSERT_EQ(var_u16.Shape()[0], mpiSize * Nx); auto var_u32 = io.InquireVariable<uint32_t>("u32"); EXPECT_TRUE(var_u32); ASSERT_EQ(var_u32.ShapeID(), adios2::ShapeID::GlobalArray); ASSERT_EQ(var_u32.Steps(), NSteps); ASSERT_EQ(var_u32.Shape()[0], mpiSize * Nx); auto var_u64 = io.InquireVariable("u64"); EXPECT_TRUE(var_u64); ASSERT_EQ(var_u64.ShapeID(), adios2::ShapeID::GlobalArray); ASSERT_EQ(var_u64.Steps(), NSteps); ASSERT_EQ(var_u64.Shape()[0], mpiSize * Nx); auto var_r32 = io.InquireVariable<float>("r32"); EXPECT_TRUE(var_r32); ASSERT_EQ(var_r32.ShapeID(), adios2::ShapeID::GlobalArray); ASSERT_EQ(var_r32.Steps(), NSteps); ASSERT_EQ(var_r32.Shape()[0], mpiSize * Nx); auto var_r64 = io.InquireVariable("r64"); EXPECT_TRUE(var_r64); ASSERT_EQ(var_r64.ShapeID(), adios2::ShapeID::GlobalArray); ASSERT_EQ(var_r64.Steps(), NSteps); ASSERT_EQ(var_r64.Shape()[0], mpiSize * Nx); SmallTestData testData; std::string IString; std::vector<int8_t> I8; std::vector<int16_t> I16; std::vector<int32_t> I32; std::vector<int64_t> I64; std::vector<uint8_t> U8; std::vector<uint16_t> U16; std::vector<uint32_t> U32; std::vector<uint64_t> U64; std::vector<float> R32; std::vector<double> R64; const adios2::Dims start{mpiRank * Nx}; const adios2::Dims count{Nx}; const adios2::Box<adios2::Dims> sel(start, count); var_i8.SetSelection(sel); var_i16.SetSelection(sel); var_i32.SetSelection(sel); var_i64.SetSelection(sel); var_u8.SetSelection(sel); var_u16.SetSelection(sel); var_u32.SetSelection(sel); var_u64.SetSelection(sel); var_r32.SetSelection(sel); var_r64.SetSelection(sel); for (size_t t = 0; t < NSteps; ++t) { var_i8.SetStepSelection({t, 1}); var_i16.SetStepSelection({t, 1}); var_i32.SetStepSelection({t, 1}); var_i64.SetStepSelection({t, 1}); var_u8.SetStepSelection({t, 1}); var_u16.SetStepSelection({t, 1}); var_u32.SetStepSelection({t, 1}); var_u64.SetStepSelection({t, 1}); var_r32.SetStepSelection({t, 1}); var_r64.SetStepSelection({t, 1}); // Generate test data for each rank uniquely SmallTestData currentTestData = generateNewSmallTestData( m_TestData, static_cast<int>(t), mpiRank, mpiSize); bpReader.Get(var_iString, IString); bpReader.Get(var_i8, I8, adios2::Mode::Sync); bpReader.Get(var_i16, I16, adios2::Mode::Sync); bpReader.Get(var_i32, I32); bpReader.Get(var_i64, I64); bpReader.Get(var_u8, U8); bpReader.Get(var_u16, U16); bpReader.Get(var_u32, U32); bpReader.Get(var_u64, U64); bpReader.Get(var_r32, R32); bpReader.Get(var_r64, R64); bpReader.PerformGets(); EXPECT_EQ(IString, currentTestData.S1); for (size_t i = 0; i < Nx; ++i) { std::stringstream ss; ss << "t=" << t << " i=" << i << " rank=" << mpiRank; std::string msg = ss.str(); EXPECT_EQ(I8[i], currentTestData.I8[i]) << msg; EXPECT_EQ(I16[i], currentTestData.I16[i]) << msg; EXPECT_EQ(I32[i], currentTestData.I32[i]) << msg; EXPECT_EQ(I64[i], currentTestData.I64[i]) << msg; EXPECT_EQ(U8[i], currentTestData.U8[i]) << msg; EXPECT_EQ(U16[i], currentTestData.U16[i]) << msg; EXPECT_EQ(U32[i], currentTestData.U32[i]) << msg; EXPECT_EQ(U64[i], currentTestData.U64[i]) << msg; EXPECT_EQ(R32[i], currentTestData.R32[i]) << msg; EXPECT_EQ(R64[i], currentTestData.R64[i]) << msg; } } bpReader.Close(); } } //****************************************************************************** // 2D 2x4 test data //****************************************************************************** Loading