1 #include <cxxtest/TestSuite.h> 2 #include <sstream> 3 #include <libgeodecomp/io/writer.h> 4 #include <libgeodecomp/io/memorywriter.h> 5 #include <libgeodecomp/io/mockinitializer.h> 6 #include <libgeodecomp/io/mockwriter.h> 7 #include <libgeodecomp/io/mocksteerer.h> 8 #include <libgeodecomp/io/testinitializer.h> 9 #include <libgeodecomp/io/teststeerer.h> 10 #include <libgeodecomp/io/testwriter.h> 11 #include <libgeodecomp/misc/stringops.h> 12 #include <libgeodecomp/misc/testcell.h> 13 #include <libgeodecomp/misc/testhelper.h> 14 #include <libgeodecomp/parallelization/serialsimulator.h> 15 16 using namespace LibGeoDecomp; 17 18 namespace LibGeoDecomp { 19 20 class SerialSimulatorTest : public CxxTest::TestSuite 21 { 22 public: 23 static const int NANO_STEPS_2D = APITraits::SelectNanoSteps<TestCell<2> >::VALUE; 24 static const int NANO_STEPS_3D = APITraits::SelectNanoSteps<TestCell<3> >::VALUE; 25 typedef MockSteerer<TestCell<2> > SteererType; 26 typedef GridBase<TestCell<2>, 2> GridBaseType; 27 setUp()28 void setUp() 29 { 30 dim = Coord<2>(17, 12); 31 maxSteps = 21; 32 startStep = 13; 33 34 init.reset(createInitializer()); 35 simulator.reset(new SerialSimulator<TestCell<2> >(createInitializer())); 36 } 37 tearDown()38 void tearDown() 39 { 40 simulator.reset(); 41 init.reset(); 42 } 43 testInitialization()44 void testInitialization() 45 { 46 TS_ASSERT_EQUALS(simulator->getGrid()->dimensions().x(), 17); 47 TS_ASSERT_EQUALS(simulator->getGrid()->dimensions().y(), 12); 48 TS_ASSERT_TEST_GRID(GridBaseType, *simulator->getGrid(), startStep * NANO_STEPS_2D); 49 } 50 testStep()51 void testStep() 52 { 53 TS_ASSERT_EQUALS(startStep, simulator->getStep()); 54 55 simulator->step(); 56 const GridBase<TestCell<2>, 2> *grid = simulator->getGrid(); 57 TS_ASSERT_TEST_GRID(GridBaseType, *grid, 58 (startStep + 1) * NANO_STEPS_2D); 59 TS_ASSERT_EQUALS(startStep + 1, simulator->getStep()); 60 } 61 testRun()62 void testRun() 63 { 64 simulator->run(); 65 TS_ASSERT_EQUALS(init->maxSteps(), simulator->getStep()); 66 TS_ASSERT_TEST_GRID( 67 GridBaseType, 68 *simulator->getGrid(), 69 init->maxSteps() * NANO_STEPS_2D); 70 } 71 testWriterInvocation()72 void testWriterInvocation() 73 { 74 unsigned period = 4; 75 std::vector<unsigned> expectedSteps; 76 std::vector<WriterEvent> expectedEvents; 77 expectedSteps << 13 78 << 16 79 << 20 80 << 21; 81 expectedEvents << WRITER_INITIALIZED 82 << WRITER_STEP_FINISHED 83 << WRITER_STEP_FINISHED 84 << WRITER_ALL_DONE; 85 86 simulator->addWriter(new TestWriter(period, expectedSteps, expectedEvents)); 87 simulator->run(); 88 } 89 testDeleteInitializer()90 void testDeleteInitializer() 91 { 92 MockInitializer::events = ""; 93 { 94 SerialSimulator<TestCell<2> > foo(new MockInitializer); 95 } 96 TS_ASSERT_EQUALS( 97 MockInitializer::events, 98 "created, configString: ''\ndeleted\n"); 99 } 100 testRegisterWriter()101 void testRegisterWriter() 102 { 103 MockWriter *w = new MockWriter(); 104 simulator->addWriter(w); 105 SerialSimulator<TestCell<2> >::WriterVector writers = simulator->writers; 106 TS_ASSERT_EQUALS(std::size_t(1), writers.size()); 107 TS_ASSERT_EQUALS(w, writers[0].get()); 108 } 109 testSerialSimulatorShouldCallBackWriter()110 void testSerialSimulatorShouldCallBackWriter() 111 { 112 MockWriter *w = new MockWriter(3); 113 simulator->addWriter(w); 114 simulator->run(); 115 116 MockWriter::EventVec expectedEvents; 117 expectedEvents << MockWriterHelpers::MockWriterEvent(startStep, WRITER_INITIALIZED, 0, true); 118 119 for (unsigned i = startStep + 2; i <= init->maxSteps(); i += 3) { 120 expectedEvents << MockWriterHelpers::MockWriterEvent(i, WRITER_STEP_FINISHED, 0, true); 121 } 122 123 expectedEvents << MockWriterHelpers::MockWriterEvent(init->maxSteps(), WRITER_ALL_DONE, 0, true); 124 125 TS_ASSERT_EQUALS(expectedEvents, w->events()); 126 } 127 testRunMustResetGridPriorToSimulation()128 void testRunMustResetGridPriorToSimulation() 129 { 130 MockWriter *eventWriter1 = new MockWriter(); 131 MemoryWriter<TestCell<2> > *gridWriter1 = 132 new MemoryWriter<TestCell<2> >(); 133 simulator->addWriter(eventWriter1); 134 simulator->addWriter(gridWriter1); 135 136 simulator->run(); 137 MockWriter::EventVec events1 = eventWriter1->events(); 138 std::vector<Grid<TestCell<2> > > grids1 = gridWriter1->getGrids(); 139 140 MockWriter *eventWriter2 = new MockWriter(); 141 MemoryWriter<TestCell<2> > *gridWriter2 = 142 new MemoryWriter<TestCell<2> >(); 143 simulator->addWriter(eventWriter2); 144 simulator->addWriter(gridWriter2); 145 simulator->run(); 146 MockWriter::EventVec events2 = eventWriter2->events(); 147 std::vector<Grid<TestCell<2> > > grids2 = gridWriter2->getGrids(); 148 149 TS_ASSERT_EQUALS(events1, events2); 150 TS_ASSERT_EQUALS(grids1, grids2); 151 } 152 153 typedef APITraits::SelectTopology<TestCell<3> >::Value Topology; 154 typedef Grid<TestCell<3>, Topology> Grid3D; 155 typedef GridBase<TestCell<3>, 3> GridBase3D; 156 test3D()157 void test3D() 158 { 159 SerialSimulator<TestCell<3> > sim(new TestInitializer<TestCell<3> >()); 160 TS_ASSERT_TEST_GRID(GridBase3D, *sim.getGrid(), 0); 161 162 sim.step(); 163 TS_ASSERT_TEST_GRID(GridBase3D, *sim.getGrid(), 164 NANO_STEPS_3D); 165 166 sim.nanoStep(0); 167 TS_ASSERT_TEST_GRID(GridBase3D, *sim.getGrid(), 168 NANO_STEPS_3D + 1); 169 170 sim.run(); 171 TS_ASSERT_TEST_GRID(GridBase3D, *sim.getGrid(), 172 21 * NANO_STEPS_3D); 173 } 174 testSteererCallback()175 void testSteererCallback() 176 { 177 std::stringstream events; 178 simulator->addSteerer(new SteererType(5, &events)); 179 std::stringstream expected; 180 expected << "created, period = 5\n"; 181 TS_ASSERT_EQUALS(events.str(), expected.str()); 182 183 simulator->run(); 184 unsigned i = startStep; 185 if (i % 5) { 186 i += 5 - (i % 5); 187 } 188 for (; i < maxSteps; i += 5) { 189 expected << "nextStep(" << i << ", STEERER_NEXT_STEP, 0, 1)\n"; 190 } 191 expected << "deleted\n"; 192 193 simulator.reset(); 194 TS_ASSERT_EQUALS(events.str(), expected.str()); 195 } 196 testSteererCanTerminateSimulation()197 void testSteererCanTerminateSimulation() 198 { 199 unsigned eventStep = 15; 200 unsigned endStep = 19; 201 unsigned jumpSteps = 2; 202 simulator->addSteerer(new TestSteerer<2>(1, eventStep, NANO_STEPS_2D * jumpSteps, endStep)); 203 simulator->run(); 204 205 // simulators are allowed to run past the end signal of the 206 // steerer b/c of issues with updating ghost zones first. 207 TS_ASSERT_TEST_GRID( 208 GridBaseType, 209 *simulator->getGrid(), 210 (endStep + 1 + jumpSteps) * NANO_STEPS_2D); 211 } 212 testSoA()213 void testSoA() 214 { 215 typedef GridBase<TestCellSoA, 3> GridBaseType; 216 SerialSimulator<TestCellSoA> sim(new TestInitializer<TestCellSoA>()); 217 TS_ASSERT_TEST_GRID(GridBaseType, *sim.getGrid(), 0); 218 219 sim.step(); 220 TS_ASSERT_TEST_GRID(GridBaseType, *sim.getGrid(), 221 NANO_STEPS_3D); 222 223 sim.nanoStep(0); 224 TS_ASSERT_TEST_GRID(GridBaseType, *sim.getGrid(), 225 NANO_STEPS_3D + 1); 226 227 sim.run(); 228 TS_ASSERT_TEST_GRID(GridBaseType, *sim.getGrid(), 229 21 * NANO_STEPS_3D); 230 } 231 232 private: 233 boost::shared_ptr<SerialSimulator<TestCell<2> > > simulator; 234 boost::shared_ptr<Initializer<TestCell<2> > > init; 235 unsigned maxSteps; 236 unsigned startStep; 237 Coord<2> dim; 238 createInitializer()239 Initializer<TestCell<2> > *createInitializer() 240 { 241 return new TestInitializer<TestCell<2> >(dim, maxSteps, startStep); 242 } 243 }; 244 245 } 246