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