1 #include <libgeodecomp.h> 2 #include <libgeodecomp/geometry/partitions/zcurvepartition.h> 3 #include <libgeodecomp/io/mocksteerer.h> 4 #include <libgeodecomp/io/mockwriter.h> 5 #include <libgeodecomp/io/teststeerer.h> 6 #include <libgeodecomp/io/parallelmemorywriter.h> 7 #include <libgeodecomp/io/paralleltestwriter.h> 8 #include <libgeodecomp/io/testinitializer.h> 9 #include <libgeodecomp/loadbalancer/mockbalancer.h> 10 #include <libgeodecomp/misc/nonpodtestcell.h> 11 #include <libgeodecomp/misc/testcell.h> 12 #include <libgeodecomp/misc/testhelper.h> 13 #include <libgeodecomp/parallelization/hiparsimulator.h> 14 15 #include <boost/shared_ptr.hpp> 16 #include <cxxtest/TestSuite.h> 17 #include <sstream> 18 19 using namespace LibGeoDecomp; 20 using namespace HiParSimulator; 21 22 namespace LibGeoDecomp { 23 namespace HiParSimulator { 24 25 class HiParSimulatorTest : public CxxTest::TestSuite 26 { 27 public: 28 typedef GridBase<TestCell<2>, 2> GridBaseType; 29 typedef HiParSimulator<TestCell<2>, ZCurvePartition<2> > SimulatorType; 30 typedef ParallelMemoryWriter<TestCell<2> > MemoryWriterType; 31 typedef MockSteerer<TestCell<2> > MockSteererType; 32 typedef TestSteerer<2 > TestSteererType; 33 34 static const unsigned NANO_STEPS = APITraits::SelectNanoSteps<TestCell<2> >::VALUE; 35 setUp()36 void setUp() 37 { 38 int width = 131; 39 int height = 241; 40 dim = Coord<2>(width, height); 41 maxSteps = 101; 42 firstStep = 20; 43 firstCycle = firstStep * NANO_STEPS; 44 TestInitializer<TestCell<2> > *init = new TestInitializer<TestCell<2> >( 45 dim, maxSteps, firstStep); 46 47 outputPeriod = 4; 48 loadBalancingPeriod = 31; 49 ghostZoneWidth = 10; 50 sim.reset(new SimulatorType( 51 init, 52 new MockBalancer(), 53 loadBalancingPeriod, 54 ghostZoneWidth)); 55 mockWriter = new MockWriter(); 56 memoryWriter = new MemoryWriterType(outputPeriod); 57 sim->addWriter(mockWriter); 58 sim->addWriter(memoryWriter); 59 } 60 tearDown()61 void tearDown() 62 { 63 sim.reset(); 64 } 65 testStep()66 void testStep() 67 { 68 sim->step(); 69 TS_ASSERT_EQUALS((31 - 1) * 27, sim->timeToNextEvent()); 70 TS_ASSERT_EQUALS((101 - 20 - 1) * 27, sim->timeToLastEvent()); 71 sim->step(); 72 sim->step(); 73 sim->step(); 74 75 TS_ASSERT_EQUALS((31 - 4) * 27, sim->timeToNextEvent()); 76 TS_ASSERT_EQUALS((101 - 20 - 4) * 27, sim->timeToLastEvent()); 77 78 std::size_t rank = MPILayer().rank(); 79 MockWriter::EventVec expectedEvents; 80 expectedEvents << MockWriterHelpers::MockWriterEvent(20, WRITER_INITIALIZED, rank, false) 81 << MockWriterHelpers::MockWriterEvent(20, WRITER_INITIALIZED, rank, true); 82 for (int t = 21; t < 25; t += 1) { 83 expectedEvents << MockWriterHelpers::MockWriterEvent(t, WRITER_STEP_FINISHED, rank, false) 84 << MockWriterHelpers::MockWriterEvent(t, WRITER_STEP_FINISHED, rank, true); 85 } 86 TS_ASSERT_EQUALS(expectedEvents, mockWriter->events()); 87 88 for (int t = 20; t < 25; t += outputPeriod) { 89 int globalNanoStep = t * NANO_STEPS; 90 MemoryWriterType::GridMap grids = memoryWriter->getGrids(); 91 TS_ASSERT_TEST_GRID( 92 MemoryWriterType::GridType, 93 grids[t], 94 globalNanoStep); 95 TS_ASSERT_EQUALS(dim, grids[t].getDimensions()); 96 } 97 } 98 testRun()99 void testRun() 100 { 101 sim->run(); 102 103 for (unsigned t = firstStep; t < maxSteps; t += outputPeriod) { 104 unsigned globalNanoStep = t * NANO_STEPS; 105 MemoryWriterType::GridMap grids = memoryWriter->getGrids(); 106 TS_ASSERT_TEST_GRID( 107 MemoryWriterType::GridType, 108 grids[t], 109 globalNanoStep); 110 TS_ASSERT_EQUALS(dim, grids[t].getDimensions()); 111 } 112 113 // check last step, too 114 unsigned t = maxSteps; 115 unsigned globalNanoStep = t * NANO_STEPS; 116 MemoryWriterType::GridMap grids = memoryWriter->getGrids(); 117 TS_ASSERT_TEST_GRID( 118 MemoryWriterType::GridType, 119 grids[t], 120 globalNanoStep); 121 TS_ASSERT_EQUALS(dim, grids[t].getDimensions()); 122 123 if (MPILayer().rank() == 0) { 124 std::string expectedEvents; 125 for (int i = 0; i < 2; ++i) { 126 expectedEvents += "balance() [7892, 7893, 7893, 7893] [1, 1, 1, 1]\n"; 127 } 128 129 TS_ASSERT_EQUALS(expectedEvents, MockBalancer::events); 130 } 131 } 132 testSteererCallback()133 void testSteererCallback() 134 { 135 std::stringstream events; 136 sim->addSteerer(new MockSteererType(5, &events)); 137 sim->run(); 138 sim.reset(); 139 140 std::stringstream expected; 141 expected << "created, period = 5\n"; 142 for (int i = 25; i < 101; i += 5) { 143 expected << "nextStep(" << i << ", STEERER_NEXT_STEP, " << MPILayer().rank() << ", " << "0)\n" 144 << "nextStep(" << i << ", STEERER_NEXT_STEP, " << MPILayer().rank() << ", " << "1)\n"; 145 } 146 147 expected << "nextStep(101, STEERER_ALL_DONE, " << MPILayer().rank() << ", " << "0)\n" 148 << "nextStep(101, STEERER_ALL_DONE, " << MPILayer().rank() << ", " << "1)\n" 149 << "deleted\n"; 150 151 TS_ASSERT_EQUALS(events.str(), expected.str()); 152 } 153 testSteererFunctionality()154 void testSteererFunctionality() 155 { 156 sim->addSteerer(new TestSteererType(5, 25, 4711 * 27)); 157 sim->run(); 158 159 const Region<2> *region = &sim->updateGroup->partitionManager->innerSet(ghostZoneWidth); 160 const GridBaseType *grid = &sim->updateGroup->grid(); 161 int cycle = 101 * 27 + 4711 * 27; 162 163 TS_ASSERT_TEST_GRID_REGION( 164 GridBaseType, 165 *grid, 166 *region, 167 cycle); 168 } 169 testParallelWriterInvocation()170 void testParallelWriterInvocation() 171 { 172 unsigned period = 4; 173 std::vector<unsigned> expectedSteps; 174 std::vector<WriterEvent> expectedEvents; 175 expectedSteps << 20 176 << 24 177 << 28 178 << 32 179 << 36 180 << 40 181 << 44 182 << 48 183 << 52 184 << 56 185 << 60 186 << 64 187 << 68 188 << 72 189 << 76 190 << 80 191 << 84 192 << 88 193 << 92 194 << 96 195 << 100 196 << 101; 197 expectedEvents << WRITER_INITIALIZED 198 << WRITER_STEP_FINISHED 199 << WRITER_STEP_FINISHED 200 << WRITER_STEP_FINISHED 201 << WRITER_STEP_FINISHED 202 << WRITER_STEP_FINISHED 203 << WRITER_STEP_FINISHED 204 << WRITER_STEP_FINISHED 205 << WRITER_STEP_FINISHED 206 << WRITER_STEP_FINISHED 207 << WRITER_STEP_FINISHED 208 << WRITER_STEP_FINISHED 209 << WRITER_STEP_FINISHED 210 << WRITER_STEP_FINISHED 211 << WRITER_STEP_FINISHED 212 << WRITER_STEP_FINISHED 213 << WRITER_STEP_FINISHED 214 << WRITER_STEP_FINISHED 215 << WRITER_STEP_FINISHED 216 << WRITER_STEP_FINISHED 217 << WRITER_STEP_FINISHED 218 << WRITER_ALL_DONE; 219 220 sim->addWriter(new ParallelTestWriter(period, expectedSteps, expectedEvents)); 221 sim->run(); 222 } 223 224 testNonPoDCell()225 void testNonPoDCell() 226 { 227 #ifdef LIBGEODECOMP_WITH_BOOST_SERIALIZATION 228 229 ghostZoneWidth = 3; 230 231 HiParSimulator<NonPoDTestCell, ZCurvePartition<2> > sim( 232 new NonPoDTestCell::Initializer(), 233 new MockBalancer(), 234 loadBalancingPeriod, 235 ghostZoneWidth); 236 sim.run(); 237 238 #endif 239 } 240 241 private: 242 boost::shared_ptr<SimulatorType> sim; 243 Coord<2> dim; 244 unsigned maxSteps; 245 unsigned firstStep; 246 unsigned firstCycle; 247 unsigned outputPeriod; 248 unsigned loadBalancingPeriod; 249 unsigned ghostZoneWidth; 250 MockWriter *mockWriter; 251 MemoryWriterType *memoryWriter; 252 }; 253 254 } 255 } 256